diff --git a/extractors/pornhub/pornhub.go b/extractors/pornhub/pornhub.go new file mode 100644 index 000000000..e7a9eb3a6 --- /dev/null +++ b/extractors/pornhub/pornhub.go @@ -0,0 +1,74 @@ +package pornhub + +import ( + "encoding/json" + + "github.com/iawia002/annie/downloader" + "github.com/iawia002/annie/request" + "github.com/iawia002/annie/utils" +) + +type pornhubData struct { + DefaultQuality bool `json:"defaultQuality"` + Format string `json:"format"` + Quality string `json:"quality"` + VideoURL string `json:"videoUrl"` +} + +// Extract is the main function for extracting data +func Extract(url string) ([]downloader.Data, error) { + var err error + html, err := request.Get(url, url, nil) + if err != nil { + return downloader.EmptyList, err + } + var title string + desc := utils.MatchOneOf(html, `(.+?)`) + if desc != nil { + title = desc[1] + } else { + title = "pornhub video" + } + + realURLs := utils.MatchOneOf(html, `"mediaDefinitions":(.+?),"isVertical"`) + + var pornhubs []pornhubData + err = json.Unmarshal([]byte(realURLs[1]), &pornhubs) + if err != nil { + return downloader.EmptyList, err + } + + //TODO add support for different quality + var realURL string + for _, downloadlink := range(pornhubs) { + if downloadlink.VideoURL != "" { + realURL = downloadlink.VideoURL + break + } + } + + size, err := request.Size(realURL, url) + if err != nil { + return downloader.EmptyList, err + } + urlData := downloader.URL{ + URL: realURL, + Size: size, + Ext: "mp4", + } + streams := map[string]downloader.Stream{ + "default": { + URLs: []downloader.URL{urlData}, + Size: size, + }, + } + return []downloader.Data{ + { + Site: "Pornhub", + Title: title, + Type: "video", + Streams: streams, + URL: url, + }, + }, nil +} \ No newline at end of file diff --git a/extractors/pornhub/pornhub_test.go b/extractors/pornhub/pornhub_test.go new file mode 100644 index 000000000..5b877cf3d --- /dev/null +++ b/extractors/pornhub/pornhub_test.go @@ -0,0 +1,34 @@ +package pornhub + +import ( + "testing" + + "github.com/iawia002/annie/config" + "github.com/iawia002/annie/test" +) + + +func TestYoutube(t *testing.T) { + config.InfoOnly = true + config.RetryTimes = 10 + tests := []struct { + name string + args test.Args + }{ + { + name: "normal test", + args: test.Args{ + URL: "https://www.pornhub.com/view_video.php?viewkey=ph5cb5fc41c6ebd", + Title: "Must Watch MILF Drilled by the Fireplace", + Size: 158868371, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + data, err := Extract(tt.args.URL) + test.CheckError(t, err) + test.Check(t, tt.args, data[0]) + }) + } +} \ No newline at end of file diff --git a/main.go b/main.go index 65c16ee9b..97984f59f 100644 --- a/main.go +++ b/main.go @@ -25,6 +25,7 @@ import ( "github.com/iawia002/annie/extractors/miaopai" "github.com/iawia002/annie/extractors/netease" "github.com/iawia002/annie/extractors/pixivision" + "github.com/iawia002/annie/extractors/pornhub" "github.com/iawia002/annie/extractors/qq" "github.com/iawia002/annie/extractors/tumblr" "github.com/iawia002/annie/extractors/twitter" @@ -152,6 +153,8 @@ func download(videoURL string) { data, err = yinyuetai.Extract(videoURL) case "geekbang": data, err = geekbang.Extract(videoURL) + case "pornhub": + data, err = pornhub.Extract(videoURL) default: data, err = universal.Extract(videoURL) }