GitBucket
4.20.0
Toggle navigation
Sign in
Files
Branches
1
Tags
Issues
Pull requests
Labels
Priorities
Milestones
Wiki
Forks
frozendragon
/
anime-fetcher
Browse code
Added code to do the request async
master
1 parent
440ae59
commit
73eb6e2189d98cb15af1dbbddb20bc694eeb2fc6
frozendragon
authored
16 hours ago
Patch
Showing
3 changed files
go.mod
go.sum
main.go
Ignore Space
Show notes
View
go.mod
module anime-fetcher go 1.25.0 require ( github.com/PuerkitoBio/goquery v1.12.0 github.com/go-chi/chi/v5 v5.3.0 github.com/google/uuid v1.6.0 ) require ( github.com/andybalholm/cascadia v1.3.3 // indirect golang.org/x/net v0.52.0 // indirect )
module anime-fetcher go 1.25.0 require ( github.com/PuerkitoBio/goquery v1.12.0 github.com/go-chi/chi/v5 v5.3.0 ) require ( github.com/andybalholm/cascadia v1.3.3 // indirect golang.org/x/net v0.52.0 // indirect )
Ignore Space
Show notes
View
go.sum
github.com/PuerkitoBio/goquery v1.12.0 h1:pAcL4g3WRXekcB9AU/y1mbKez2dbY2AajVhtkO8RIBo= github.com/PuerkitoBio/goquery v1.12.0/go.mod h1:802ej+gV2y7bbIhOIoPY5sT183ZW0YFofScC4q/hIpQ= github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM= github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA= github.com/go-chi/chi/v5 v5.3.0 h1:halUjDxhshgXHMrao5bB8eNBXo/rnzwr8m5m36glehM= github.com/go-chi/chi/v5 v5.3.0/go.mod h1:R+tYY2hNuVUUjxoPtqUdgBqevM9s9njzkTLutVsOCto= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
github.com/PuerkitoBio/goquery v1.12.0 h1:pAcL4g3WRXekcB9AU/y1mbKez2dbY2AajVhtkO8RIBo= github.com/PuerkitoBio/goquery v1.12.0/go.mod h1:802ej+gV2y7bbIhOIoPY5sT183ZW0YFofScC4q/hIpQ= github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM= github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA= github.com/go-chi/chi/v5 v5.3.0 h1:halUjDxhshgXHMrao5bB8eNBXo/rnzwr8m5m36glehM= github.com/go-chi/chi/v5 v5.3.0/go.mod h1:R+tYY2hNuVUUjxoPtqUdgBqevM9s9njzkTLutVsOCto= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Ignore Space
Show notes
View
main.go
package main import ( "encoding/json" "errors" "fmt" "github.com/PuerkitoBio/goquery" chi "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" "github.com/google/uuid" "html" "io" "log" "net/http" "net/url" "os" "os/exec" "strings" "sync" "time" ) func main() { m := &sync.Map{} r := chi.NewRouter() r.Use(middleware.Logger) r.Get("/", func(w http.ResponseWriter, r *http.Request) { file, err := os.ReadFile("frontend/index.html") if err != nil { panic(err) } w.Write(file) }) r.Post("/success", func(w http.ResponseWriter, r *http.Request) { file, err := os.ReadFile("frontend/success.html") if err != nil { panic(err) } w.Write(file) }) r.Post("/failed", func(w http.ResponseWriter, r *http.Request) { file, err := os.ReadFile("frontend/failed.html") if err != nil { panic(err) } w.Write(file) }) r.Get("/session", func(w http.ResponseWriter, r *http.Request) { m1 := make(map[string]Request) m.Range(func(key, value any) bool { // Type assertion is required since Range returns 'any' types k := key.(string) v := value.(Request) m1[k] = v return true // Return true to continue iterating }) data, err := json.Marshal(m1) if err != nil { http.Error(w, "Failed to submit request", http.StatusInternalServerError) return } _, err = w.Write(data) if err != nil { http.Error(w, "Failed to submit request", http.StatusInternalServerError) return } w.WriteHeader(http.StatusOK) }) r.Post("/session", func(w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { http.Error(w, "Failed to parse form", http.StatusBadRequest) return } // Retrieve input values by their HTML "name" attribute u := r.FormValue("url") name := r.FormValue("name") season := r.FormValue("season") UUID, err := uuid.NewUUID() if err != nil { http.Error(w, "Failed to submit request", http.StatusInternalServerError) return } m.Store(UUID.String(), Request{ URL: u, Name: name, Season: season, }) http.Redirect(w, r, "/success", http.StatusTemporaryRedirect) }) go processRequest(m) http.ListenAndServe(":3000", r) } type Request struct { URL string `json:"url"` Name string `json:"name"` Season string `json:"season"` } func processRequest(m *sync.Map) { for { m.Range(func(key, value any) bool { // Type assertion is required since Range returns 'any' types //k := key.(int) v := value.(Request) Download(v) return true // Return true to continue iterating }) m.Clear() time.Sleep(time.Second * 30) } } func Download(request Request) { seasonID, err := extractSeasonID(request.URL) if err != nil { log.Printf("%+v\n", err) return } episodeCount, err := getEpisodeList(seasonID) if err != nil { log.Printf("%+v\n", err) return } for i := 1; i < episodeCount+1; i++ { sourceID, err := getAniwaveSourceID(seasonID, i) if err != nil { log.Printf("%+v\n", err) return } sourceUrl, err := getAniwavesSource(request.URL, sourceID) if err != nil { log.Printf("%+v\n", err) return } playEchoVideoSourceeID, err := extractSourceID(sourceUrl) if err != nil { log.Printf("%+v\n", err) return } playEchoVideoSourceUrl, err := getPlayEchoVideoSource(playEchoVideoSourceeID) if err != nil { log.Printf("%+v\n", err) return } playEchoVideoSourceUrl = strings.Replace(playEchoVideoSourceUrl, "hlsx3cdn.burntburst45.store", "hlsx4cdn.burntburst45.store", 1) name := "storage/Download/" + fmt.Sprintf("%s/%s/%s - %d", request.Name, request.Season, request.Name, i) + ".%(ext)s" cmd := exec.Command("./yt-dlp_linux", "-o", name, "--referer", "https://play.echovideo.ru/", "--add-header", "Origin: https://play.echovideo.ru", playEchoVideoSourceUrl) // Redirect binary I/O directly to the terminal cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Stdin = os.Stdin // Run blocks until the command completes if err := cmd.Run(); err != nil { log.Printf("%+v\n", err) return } } } func extractSeasonID(u string) (string, error) { parsed, err := url.Parse(u) if err != nil { return "", nil } path := parsed.Path resource := strings.Split(path, "/") seasonID := resource[2][strings.LastIndex(resource[2], "-")+1:] return seasonID, nil } type GetEpisodeListResponse struct { Status int `json:"status"` Result string `json:"result"` } func getEpisodeList(seasonID string) (int, error) { client := &http.Client{Timeout: 10 * time.Second} req, err := http.NewRequest("GET", fmt.Sprintf("https://aniwaves.ru/ajax/episode/list/%s?vrf=", seasonID), nil) if err != nil { return 0, err } req.Header.Add("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0") response, err := client.Do(req) if err != nil { return 0, err } defer response.Body.Close() // Essential: Close the body body, err := io.ReadAll(response.Body) if err != nil { return 0, err } lsr := GetEpisodeListResponse{} err = json.Unmarshal(body, &lsr) if err != nil { return 0, err } clean := html.UnescapeString(lsr.Result) wrapped := "<html><body>" + clean + "</body></html>" doc, err := goquery.NewDocumentFromReader(strings.NewReader(wrapped)) if err != nil { return 0, err } count := doc.Find("ul[class='ep-range'] li").Length() return count, nil } type ListServersResponse struct { Status int `json:"status"` Result string `json:"result"` } func getAniwaveSourceID(seasonID string, episode int) (string, error) { client := &http.Client{Timeout: 10 * time.Second} req, err := http.NewRequest("GET", fmt.Sprintf("https://aniwaves.ru/ajax/server/list?servers=%s&eps=%d", seasonID, episode), nil) if err != nil { return "", err } req.Header.Add("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0") response, err := client.Do(req) if err != nil { return "", err } defer response.Body.Close() // Essential: Close the body body, err := io.ReadAll(response.Body) if err != nil { return "", err } lsr := ListServersResponse{} err = json.Unmarshal(body, &lsr) if err != nil { return "", err } clean := html.UnescapeString(lsr.Result) wrapped := "<html><body>" + clean + "</body></html>" doc, err := goquery.NewDocumentFromReader(strings.NewReader(wrapped)) if err != nil { return "", err } id, exist := doc.Find("div.type[data-type='dub'] ul li[data-sv-id='4']").Attr("data-link-id") if !exist { return "", errors.New("failed to find") } return id, nil } type SourceResponse struct { Status int `json:"status"` Result struct { Url string `json:"url"` Server int `json:"server"` SkipData struct { Intro []int `json:"intro"` Outro []int `json:"outro"` } `json:"skip_data"` Sources []interface{} `json:"sources"` Tracks []interface{} `json:"tracks"` HtmlGuide string `json:"htmlGuide"` } `json:"result"` } func getAniwavesSource(originalUrl, sourceID string) (string, error) { u := fmt.Sprintf("https://aniwaves.ru/ajax/sources?id=%s&asi=0&autoPlay=0", sourceID) client := &http.Client{Timeout: 10 * time.Second} req, err := http.NewRequest("GET", u, nil) if err != nil { return "", err } //GET /ajax/sources?id=UWxwb05ERkJXU1pUV1ZYT1k1b0FBQXQvLzl4TndCYk85aUtBc2tJeUpJd3d5Yzd3QzBCQzBnaWdVRWdIM2tzb0FnYUFvQUIwT0FBQUFHZ0FBQUFCazB4QWVtVFU5STlKNm1neWVvMEdtUU5BMDBCb0JvTkdnd2pSb1pQS0F5QTBCaHdCQU1NeUFja2pOTkxNcHRicTdmMkp4NFl4UDNFQXRKeUcxc3E0clpNTUl2bmhBdlphVzNJRDA5QTIvT2pqMTdBSmUySzkxVTBrUkVXYURKSmJjb1lXUWtYWUEzQXA0V1VRWFNHSWhoSno4ZnMzb3BTc1o3dnhFMjM2eit1ZnhkeVJUaFFrRlhPWTVvQT0=&asi=0&autoPlay=0 HTTP/2 //Host: aniwaves.ru //User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0 //Accept: application/json, text/javascript, */*; q=0.01 //Accept-Language: en-US,en;q=0.9 //Accept-Encoding: gzip, deflate, br, zstd //Referer: https://aniwaves.ru/watch/re-zero-kara-hajimeru-isekai-seikatsu-4th-season-82570/ep-1 //X-Requested-With: XMLHttpRequest //Sec-Fetch-Dest: empty //Sec-Fetch-Mode: cors //Sec-Fetch-Site: same-origin //Connection: keep-alive //Cookie: cf_clearance=E7EaYC.6t5eW.AiGWFA4dGhrVUHTO7X8IiaRkfJTAco-1780105219-1.2.1.1-MJ0WuQfXydhynpkJCtY1Q719ENTQz4VLOfYm3pIdw7pfD41mgVQaml14Ca3gIw7pb.YmpANb8l5LPr9Boav4XmsH0pr0Ip58lVK5hkowCFzvMSFqJDdu_a43B9Km.FA5Ql3uPbXZeNU3rSlJuJ1wBDvKhhVFo4yIaxaWoIcfsqwNdmwuz81b_yWoIge0K0ciDAVKcwV.8uv9XfHP1T4Rrs_OKdKFRZ6cp0TBYjiLOe4NwFbWBviDIxsR8tDEhxKTof0UEVq9R0mBosRPelxr3YxIxH5QyFrCKdpghW.kDOeLXGfP13cYVkwZFwT0jXVhkLZvCkHEgpEZ9stzMERj0Y2P2xUx9WMKJRQaRyPMJWKUCn9FtZSvHrvuW23TaWOx9ll00D_ZPzmTHdtESQrc8MTgZ5wBDvPaXbyH1ksv2RA; prefered_server_id=4; prefered_server_type=dub; _ga_2BSQBMWMM9=GS2.1.s1780942892$o1$g1$t1780942910$j42$l0$h0; _ga=GA1.1.764185913.1780942893 //Priority: u=0 //Pragma: no-cache //Cache-Control: no-cache //TE: trailers req.Header.Add("Referer", originalUrl) req.Header.Add("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0") resp, err := client.Do(req) if err != nil { return "", err } defer resp.Body.Close() // Essential: Close the body body, err := io.ReadAll(resp.Body) if err != nil { return "", err } sr := SourceResponse{} err = json.Unmarshal(body, &sr) if err != nil { return "", err } return sr.Result.Url, nil } func extractSourceID(u string) (string, error) { parsedURL, err := url.Parse(u) if err != nil { return "", err } path := parsedURL.Path id := path[strings.LastIndex(path, "/")+1:] return id, nil } type PlayEchoVideoSourceResponse struct { Sources string `json:"sources"` Intro struct { Start int `json:"start"` End int `json:"end"` } `json:"intro"` Outro struct { Start int `json:"start"` End int `json:"end"` } `json:"outro"` } func getPlayEchoVideoSource(id string) (string, error) { url := fmt.Sprintf("https://play.echovideo.ru/embed-1/getSources?id=%s", id) //GET /embed-1/getSources?id=KPpOQdEl-krSDv4eXEEESOGQxIyn39hxhDVL-a2XPou3CoyWNh4VQmK3H0rMoVhfkd0GovoHTaEZ6Sm5lyMSpt5yt-Dn2lZCmvH1yzTQSxaKaYl25DzAviI4tquisv4m4sdprfru0X7FRb516Rwgo1lBQipOxMdBWJAVmU3pVFbH-FCBQorpYyUMwrsEZeectZ9x8EhnJ_wYs7Sd2a1lnficzNBqKBC3zWOvZLXKnwY HTTP/2 //Host: play.echovideo.ru //User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0 //Accept: */* //Accept-Language: en-US,en;q=0.9 //Accept-Encoding: gzip, deflate, br, zstd //Referer: https://play.echovideo.ru/embed-1/KPpOQdEl-krSDv4eXEEESOGQxIyn39hxhDVL-a2XPou3CoyWNh4VQmK3H0rMoVhfkd0GovoHTaEZ6Sm5lyMSpt5yt-Dn2lZCmvH1yzTQSxaKaYl25DzAviI4tquisv4m4sdprfru0X7FRb516Rwgo1lBQipOxMdBWJAVmU3pVFbH-FCBQorpYyUMwrsEZeectZ9x8EhnJ_wYs7Sd2a1lnficzNBqKBC3zWOvZLXKnwY?v=1&asi=0&autoPlay=0&ao=0&autostart=true //Connection: keep-alive //Sec-Fetch-Dest: empty //Sec-Fetch-Mode: cors //Sec-Fetch-Site: same-origin //Priority: u=4 //Pragma: no-cache //Cache-Control: no-cache client := &http.Client{Timeout: 10 * time.Second} req, err := http.NewRequest("GET", url, nil) if err != nil { return "", err } req.Header.Add("Referer", fmt.Sprintf("https://play.echovideo.ru/embed-1/%s?v=1&asi=0&autoPlay=0&ao=0&autostart=true", id)) resp, err := client.Do(req) if err != nil { return "", err } defer resp.Body.Close() // Essential: Close the body body, err := io.ReadAll(resp.Body) if err != nil { return "", err } sr := PlayEchoVideoSourceResponse{} err = json.Unmarshal(body, &sr) if err != nil { return "", err } return sr.Sources, nil }
package main import ( "encoding/json" "errors" "fmt" "github.com/PuerkitoBio/goquery" chi "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" "html" "io" "log" "net/http" "net/url" "os" "os/exec" "strings" "time" ) func main() { r := chi.NewRouter() r.Use(middleware.Logger) r.Get("/", func(w http.ResponseWriter, r *http.Request) { file, err := os.ReadFile("frontend/index.html") if err != nil { panic(err) } w.Write(file) }) r.Post("/success", func(w http.ResponseWriter, r *http.Request) { file, err := os.ReadFile("frontend/success.html") if err != nil { panic(err) } w.Write(file) }) r.Post("/failed", func(w http.ResponseWriter, r *http.Request) { file, err := os.ReadFile("frontend/failed.html") if err != nil { panic(err) } w.Write(file) }) r.Post("/session", postSession) http.ListenAndServe(":3000", r) } func postSession(w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { http.Error(w, "Failed to parse form", http.StatusBadRequest) return } // Retrieve input values by their HTML "name" attribute u := r.FormValue("url") name := r.FormValue("name") season := r.FormValue("season") seasonID, err := extractSeasonID(u) if err != nil { log.Printf("%+v\n", err) http.Redirect(w, r, "/failed", http.StatusTemporaryRedirect) return } episodeCount, err := getEpisodeList(seasonID) if err != nil { log.Printf("%+v\n", err) http.Redirect(w, r, "/failed", http.StatusTemporaryRedirect) return } for i := 1; i < episodeCount; i++ { sourceID, err := getAniwaveSourceID(seasonID, i) if err != nil { log.Printf("%+v\n", err) http.Redirect(w, r, "/failed", http.StatusTemporaryRedirect) return } sourceUrl, err := getAniwavesSource(sourceID) if err != nil { log.Printf("%+v\n", err) http.Redirect(w, r, "/failed", http.StatusTemporaryRedirect) return } playEchoVideoSourceeID, err := extractSourceID(sourceUrl) if err != nil { log.Printf("%+v\n", err) http.Redirect(w, r, "/failed", http.StatusTemporaryRedirect) return } playEchoVideoSourceUrl, err := getPlayEchoVideoSource(playEchoVideoSourceeID) if err != nil { log.Printf("%+v\n", err) http.Redirect(w, r, "/failed", http.StatusTemporaryRedirect) return } name := "storage/Download/" + fmt.Sprintf("%s/%s/%s - %d", name, season, name, i) + ".%(ext)s" cmd := exec.Command("./yt-dlp_linux", "-o", name, "--referer", "https://play.echovideo.ru/", "--add-header", "Origin: https://play.echovideo.ru", playEchoVideoSourceUrl) // Redirect binary I/O directly to the terminal cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Stdin = os.Stdin // Run blocks until the command completes if err := cmd.Run(); err != nil { log.Printf("%+v\n", err) http.Redirect(w, r, "/failed", http.StatusTemporaryRedirect) return } http.Redirect(w, r, "/success", http.StatusTemporaryRedirect) } } func extractSeasonID(u string) (string, error) { parsed, err := url.Parse(u) if err != nil { return "", nil } path := parsed.Path resource := strings.Split(path, "/") seasonID := resource[2][strings.LastIndex(resource[2], "-")+1:] return seasonID, nil } type GetEpisodeListResponse struct { Status int `json:"status"` Result string `json:"result"` } func getEpisodeList(seasonID string) (int, error) { client := &http.Client{Timeout: 10 * time.Second} req, err := http.NewRequest("GET", fmt.Sprintf("https://aniwaves.ru/ajax/episode/list/%s?vrf=", seasonID), nil) if err != nil { return 0, err } req.Header.Add("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0") response, err := client.Do(req) if err != nil { return 0, err } defer response.Body.Close() // Essential: Close the body body, err := io.ReadAll(response.Body) if err != nil { return 0, err } lsr := GetEpisodeListResponse{} err = json.Unmarshal(body, &lsr) if err != nil { return 0, err } clean := html.UnescapeString(lsr.Result) wrapped := "<html><body>" + clean + "</body></html>" doc, err := goquery.NewDocumentFromReader(strings.NewReader(wrapped)) if err != nil { return 0, err } count := doc.Find("ul[class='ep-range'] li").Length() return count, nil } type ListServersResponse struct { Status int `json:"status"` Result string `json:"result"` } func getAniwaveSourceID(seasonID string, episode int) (string, error) { client := &http.Client{Timeout: 10 * time.Second} req, err := http.NewRequest("GET", fmt.Sprintf("https://aniwaves.ru/ajax/server/list?servers=%s&eps=%d", seasonID, episode), nil) if err != nil { return "", err } req.Header.Add("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0") response, err := client.Do(req) if err != nil { return "", err } defer response.Body.Close() // Essential: Close the body body, err := io.ReadAll(response.Body) if err != nil { return "", err } lsr := ListServersResponse{} err = json.Unmarshal(body, &lsr) if err != nil { return "", err } clean := html.UnescapeString(lsr.Result) wrapped := "<html><body>" + clean + "</body></html>" doc, err := goquery.NewDocumentFromReader(strings.NewReader(wrapped)) if err != nil { return "", err } id, exist := doc.Find("div.type[data-type='dub'] ul li[data-sv-id='4']").Attr("data-link-id") if !exist { return "", errors.New("failed to find") } return id, nil } type SourceResponse struct { Status int `json:"status"` Result struct { Url string `json:"url"` Server int `json:"server"` SkipData struct { Intro []int `json:"intro"` Outro []int `json:"outro"` } `json:"skip_data"` Sources []interface{} `json:"sources"` Tracks []interface{} `json:"tracks"` HtmlGuide string `json:"htmlGuide"` } `json:"result"` } func getAniwavesSource(sourceID string) (string, error) { url := fmt.Sprintf("https://aniwaves.ru/ajax/sources?id=%s&asi=0&autoPlay=0", sourceID) client := &http.Client{Timeout: 10 * time.Second} req, err := http.NewRequest("GET", url, nil) if err != nil { return "", err } //GET /ajax/sources?id=UWxwb05ERkJXU1pUV1ZYT1k1b0FBQXQvLzl4TndCYk85aUtBc2tJeUpJd3d5Yzd3QzBCQzBnaWdVRWdIM2tzb0FnYUFvQUIwT0FBQUFHZ0FBQUFCazB4QWVtVFU5STlKNm1neWVvMEdtUU5BMDBCb0JvTkdnd2pSb1pQS0F5QTBCaHdCQU1NeUFja2pOTkxNcHRicTdmMkp4NFl4UDNFQXRKeUcxc3E0clpNTUl2bmhBdlphVzNJRDA5QTIvT2pqMTdBSmUySzkxVTBrUkVXYURKSmJjb1lXUWtYWUEzQXA0V1VRWFNHSWhoSno4ZnMzb3BTc1o3dnhFMjM2eit1ZnhkeVJUaFFrRlhPWTVvQT0=&asi=0&autoPlay=0 HTTP/2 //Host: aniwaves.ru //User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0 //Accept: application/json, text/javascript, */*; q=0.01 //Accept-Language: en-US,en;q=0.9 //Accept-Encoding: gzip, deflate, br, zstd //Referer: https://aniwaves.ru/watch/re-zero-kara-hajimeru-isekai-seikatsu-4th-season-82570/ep-1 //X-Requested-With: XMLHttpRequest //Sec-Fetch-Dest: empty //Sec-Fetch-Mode: cors //Sec-Fetch-Site: same-origin //Connection: keep-alive //Cookie: cf_clearance=E7EaYC.6t5eW.AiGWFA4dGhrVUHTO7X8IiaRkfJTAco-1780105219-1.2.1.1-MJ0WuQfXydhynpkJCtY1Q719ENTQz4VLOfYm3pIdw7pfD41mgVQaml14Ca3gIw7pb.YmpANb8l5LPr9Boav4XmsH0pr0Ip58lVK5hkowCFzvMSFqJDdu_a43B9Km.FA5Ql3uPbXZeNU3rSlJuJ1wBDvKhhVFo4yIaxaWoIcfsqwNdmwuz81b_yWoIge0K0ciDAVKcwV.8uv9XfHP1T4Rrs_OKdKFRZ6cp0TBYjiLOe4NwFbWBviDIxsR8tDEhxKTof0UEVq9R0mBosRPelxr3YxIxH5QyFrCKdpghW.kDOeLXGfP13cYVkwZFwT0jXVhkLZvCkHEgpEZ9stzMERj0Y2P2xUx9WMKJRQaRyPMJWKUCn9FtZSvHrvuW23TaWOx9ll00D_ZPzmTHdtESQrc8MTgZ5wBDvPaXbyH1ksv2RA; prefered_server_id=4; prefered_server_type=dub; _ga_2BSQBMWMM9=GS2.1.s1780942892$o1$g1$t1780942910$j42$l0$h0; _ga=GA1.1.764185913.1780942893 //Priority: u=0 //Pragma: no-cache //Cache-Control: no-cache //TE: trailers req.Header.Add("Referer", "https://aniwaves.ru/watch/re-zero-kara-hajimeru-isekai-seikatsu-4th-season-82570/ep-1") req.Header.Add("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0") resp, err := client.Do(req) if err != nil { return "", err } defer resp.Body.Close() // Essential: Close the body body, err := io.ReadAll(resp.Body) if err != nil { return "", err } sr := SourceResponse{} err = json.Unmarshal(body, &sr) if err != nil { return "", err } return sr.Result.Url, nil } func extractSourceID(u string) (string, error) { parsedURL, err := url.Parse(u) if err != nil { return "", err } path := parsedURL.Path id := path[strings.LastIndex(path, "/")+1:] return id, nil } type PlayEchoVideoSourceResponse struct { Sources string `json:"sources"` Intro struct { Start int `json:"start"` End int `json:"end"` } `json:"intro"` Outro struct { Start int `json:"start"` End int `json:"end"` } `json:"outro"` } func getPlayEchoVideoSource(id string) (string, error) { url := fmt.Sprintf("https://play.echovideo.ru/embed-1/getSources?id=%s", id) //GET /embed-1/getSources?id=KPpOQdEl-krSDv4eXEEESOGQxIyn39hxhDVL-a2XPou3CoyWNh4VQmK3H0rMoVhfkd0GovoHTaEZ6Sm5lyMSpt5yt-Dn2lZCmvH1yzTQSxaKaYl25DzAviI4tquisv4m4sdprfru0X7FRb516Rwgo1lBQipOxMdBWJAVmU3pVFbH-FCBQorpYyUMwrsEZeectZ9x8EhnJ_wYs7Sd2a1lnficzNBqKBC3zWOvZLXKnwY HTTP/2 //Host: play.echovideo.ru //User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:151.0) Gecko/20100101 Firefox/151.0 //Accept: */* //Accept-Language: en-US,en;q=0.9 //Accept-Encoding: gzip, deflate, br, zstd //Referer: https://play.echovideo.ru/embed-1/KPpOQdEl-krSDv4eXEEESOGQxIyn39hxhDVL-a2XPou3CoyWNh4VQmK3H0rMoVhfkd0GovoHTaEZ6Sm5lyMSpt5yt-Dn2lZCmvH1yzTQSxaKaYl25DzAviI4tquisv4m4sdprfru0X7FRb516Rwgo1lBQipOxMdBWJAVmU3pVFbH-FCBQorpYyUMwrsEZeectZ9x8EhnJ_wYs7Sd2a1lnficzNBqKBC3zWOvZLXKnwY?v=1&asi=0&autoPlay=0&ao=0&autostart=true //Connection: keep-alive //Sec-Fetch-Dest: empty //Sec-Fetch-Mode: cors //Sec-Fetch-Site: same-origin //Priority: u=4 //Pragma: no-cache //Cache-Control: no-cache client := &http.Client{Timeout: 10 * time.Second} req, err := http.NewRequest("GET", url, nil) if err != nil { return "", err } req.Header.Add("Referer", fmt.Sprintf("https://play.echovideo.ru/embed-1/%s?v=1&asi=0&autoPlay=0&ao=0&autostart=true", id)) resp, err := client.Do(req) if err != nil { return "", err } defer resp.Body.Close() // Essential: Close the body body, err := io.ReadAll(resp.Body) if err != nil { return "", err } sr := PlayEchoVideoSourceResponse{} err = json.Unmarshal(body, &sr) if err != nil { return "", err } return sr.Sources, nil }
Show line notes below