Skip to content

Commit

Permalink
impl: adding a function to download the anime
Browse files Browse the repository at this point in the history
  • Loading branch information
KitsuneSemCalda committed Aug 25, 2024
1 parent e168a3a commit ff73a34
Showing 1 changed file with 186 additions and 0 deletions.
186 changes: 186 additions & 0 deletions internal/Network/Downloader.go
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)
}
}

0 comments on commit ff73a34

Please sign in to comment.