-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
impl: adding a function to download the anime
- Loading branch information
1 parent
e168a3a
commit ff73a34
Showing
1 changed file
with
186 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
package network | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"io" | ||
"net/http" | ||
"os" | ||
"os/exec" | ||
"path/filepath" | ||
"regexp" | ||
"strings" | ||
"time" | ||
|
||
"github.com/PuerkitoBio/goquery" | ||
"github.com/cavaliergopher/grab/v3" | ||
"gopkg.in/cheggaaa/pb.v1" | ||
|
||
"animatic-v2/internal/Message" | ||
"animatic-v2/internal/Structures" | ||
) | ||
|
||
func downloadFolderFormatter(str string) string { | ||
regex := regexp.MustCompile(`https://animefire\.plus/video/([^/?]+)`) | ||
match := regex.FindStringSubmatch(str) | ||
if len(match) > 1 { | ||
finalStep := match[1] | ||
return finalStep | ||
} | ||
return "" | ||
} | ||
|
||
func dirExists(path string) bool { | ||
if _, err := os.Stat(path); os.IsNotExist(err) { | ||
os.MkdirAll(path, os.ModePerm) | ||
return false | ||
} | ||
|
||
return true | ||
} | ||
|
||
func isBloggerURL(videoURL string) bool { | ||
return strings.Contains(videoURL, "blogger.com") | ||
} | ||
|
||
func isYTDLPAvailable() bool { | ||
cmd := exec.Command("which", "yt-dlp") // Use "where" em vez de "which" no Windows | ||
if err := cmd.Run(); err != nil { | ||
return false | ||
} | ||
return true | ||
} | ||
|
||
func downloadBloggerVideo(videoURL, episodePath string) { | ||
if isYTDLPAvailable() { | ||
fmt.Println("Using yt-dlp to download Blogger video...") | ||
cmd := exec.Command("yt-dlp", "-o", episodePath, videoURL) | ||
if err := cmd.Run(); err != nil { | ||
message.ErrorMessage(fmt.Sprintf("Failed to download video using yt-dlp: %s\n", err.Error())) | ||
} | ||
} | ||
} | ||
|
||
func ExtractActualVideoLabel(videoSrc string) string { | ||
var videoResponse Structures.VideoResponse | ||
response, err := http.Get(videoSrc) | ||
if err != nil { | ||
message.ErrorMessage(err.Error()) | ||
} | ||
|
||
defer response.Body.Close() | ||
|
||
if response.StatusCode != http.StatusOK { | ||
message.ErrorMessage("Status Code is different from StatusOK") | ||
} | ||
|
||
body, err := io.ReadAll(response.Body) | ||
if err != nil { | ||
message.ErrorMessage(err.Error()) | ||
return "" | ||
} | ||
|
||
err = json.Unmarshal(body, &videoResponse) | ||
if err != nil { | ||
message.ErrorMessage(err.Error()) | ||
return "" | ||
} | ||
|
||
if len(videoResponse.Data) == 0 { | ||
message.ErrorMessage("No Video Found") | ||
return "" | ||
} | ||
|
||
return videoResponse.Data[len(videoResponse.Data)-1].Src | ||
} | ||
|
||
func ExtractVideoURL(url string) string { | ||
value, err := checkUrlStatus(url) | ||
|
||
if !value || err != nil { | ||
message.ErrorMessage("Can't access video website") | ||
} | ||
|
||
response, err := http.Get(url) | ||
if err != nil { | ||
message.ErrorMessage(err.Error()) | ||
return "" | ||
} | ||
|
||
doc, _ := goquery.NewDocumentFromReader(response.Body) | ||
|
||
videoElements := doc.Find("video") | ||
|
||
if videoElements.Length() > 0 { | ||
oldDataVideo, _ := videoElements.Attr("data-video-src") | ||
return oldDataVideo | ||
} else { | ||
videoElements = doc.Find("div") | ||
if videoElements.Length() > 0 { | ||
oldDataVideo, _ := videoElements.Attr("data-video-src") | ||
return oldDataVideo | ||
} | ||
} | ||
|
||
message.ErrorMessage("Can't find video element in html") | ||
return "" | ||
} | ||
|
||
func downloadStandardVideo(URL, episodePath string) { | ||
fmt.Println("Using standard download method...") | ||
|
||
startUrl := ExtractVideoURL(URL) | ||
videoUrl := ExtractActualVideoLabel(startUrl) | ||
|
||
client := grab.NewClient() | ||
req, _ := grab.NewRequest(episodePath, videoUrl) | ||
req.HTTPRequest.Header.Set("Connection", "keep-alive") | ||
|
||
resp := client.Do(req) | ||
|
||
maxSizeInMB := int(resp.Size() / (1024 * 1024)) | ||
minSizeInMB := 10 | ||
|
||
if maxSizeInMB < minSizeInMB { | ||
maxSizeInMB = minSizeInMB | ||
} | ||
|
||
bar := pb.StartNew(maxSizeInMB) | ||
|
||
fmt.Printf("Episode URL: %s \n", videoUrl) | ||
for !resp.IsComplete() { | ||
completedInMB := int(resp.Progress() * float64(maxSizeInMB)) | ||
bar.Set(completedInMB) | ||
time.Sleep(time.Millisecond * 500) | ||
} | ||
|
||
bar.Finish() | ||
} | ||
|
||
func downloadEp(path string, ep Structures.Episode) { | ||
episodePath := filepath.Join(path, ep.Number+".mp4") | ||
|
||
if _, err := os.Stat(episodePath); os.IsNotExist(err) { | ||
fmt.Println("Downloading the video...") | ||
if isBloggerURL(ep.URL) { | ||
downloadBloggerVideo(ep.URL, episodePath) | ||
} else { | ||
downloadStandardVideo(ep.URL, episodePath) | ||
} | ||
fmt.Println("Video downloaded successfully!") | ||
} else { | ||
fmt.Println("Video already downloaded.") | ||
} | ||
} | ||
|
||
func Download(anime Structures.Anime, eplist []Structures.Episode, Debug bool, Gac bool) { | ||
var path string | ||
if Gac { | ||
path = filepath.Join(os.Getenv("HOME"), ".local", "goanime", "downloads", "anime", downloadFolderFormatter(anime.Url)) | ||
dirExists(path) | ||
} | ||
|
||
for _, ep := range eplist { | ||
downloadEp(path, ep) | ||
} | ||
} |