Move work command
[yt-mango.git] / cmd / channeldump.go
blobb1b843c0b40b09a4b2a4581c1e5f1c326b4c434e
1 package cmd
3 import (
4 "github.com/spf13/cobra"
5 "net/url"
6 "fmt"
7 "os"
8 "strings"
9 "time"
10 "bufio"
11 "log"
12 "github.com/terorie/yt-mango/api"
15 var channelDumpCmd = cobra.Command{
16 Use: "dumpurls <channel ID> <file>",
17 Short: "Get all public video URLs from channel",
18 Long: "Write all videos URLs of a channel to a file",
19 Args: cobra.ExactArgs(2),
20 Run: func(cmd *cobra.Command, args []string) {
21 channelID := args[0]
22 fileName := args[1]
24 if !matchChannelID.MatchString(channelID) {
25 // Check if youtube.com domain
26 _url, err := url.Parse(channelID)
27 if err != nil || (_url.Host != "www.youtube.com" && _url.Host != "youtube.com") {
28 fmt.Fprintln(os.Stderr, "Not a channel ID:", channelID)
29 os.Exit(1)
32 // Check if old /user/ URL
33 if strings.HasPrefix(_url.Path, "/user/") {
34 // TODO Implement extraction of channel ID
35 fmt.Fprintln(os.Stderr, "New /channel/ link is required!\n" +
36 "The old /user/ links do not work.")
37 os.Exit(1)
40 // Remove /channel/ path
41 channelID = strings.TrimPrefix(_url.Path, "/channel/")
42 if len(channelID) == len(_url.Path) {
43 // No such prefix to be removed
44 fmt.Fprintln(os.Stderr, "Not a channel ID:", channelID)
45 os.Exit(1)
48 // Remove rest of path from channel ID
49 slashIndex := strings.IndexRune(channelID, '/')
50 if slashIndex != -1 {
51 channelID = channelID[:slashIndex]
55 log.Printf("Starting work on channel ID \"%s\".", channelID)
56 startTime := time.Now()
58 var flags int
59 if force {
60 flags = os.O_WRONLY | os.O_CREATE | os.O_TRUNC
61 } else {
62 flags = os.O_WRONLY | os.O_CREATE | os.O_EXCL
65 file, err := os.OpenFile(fileName, flags, 0640)
66 defer file.Close()
67 writer := bufio.NewWriter(file)
68 defer writer.Flush()
70 if err != nil {
71 fmt.Fprintln(os.Stderr, err)
72 os.Exit(1)
75 totalURLs := 0
76 for i := offset; true; i++ {
77 channelURLs, err := api.DefaultAPI.GetChannelVideoURLs(channelID, uint(i))
78 if err != nil {
79 log.Printf("Aborting on error %v.", err)
80 break
82 if len(channelURLs) == 0 {
83 log.Printf("Page %d returned no videos.", i)
84 break
86 totalURLs += len(channelURLs)
87 log.Printf("Received page %d: %d videos.", i, len(channelURLs))
89 for _, _url:= range channelURLs {
90 _, err := writer.WriteString(_url + "\n")
91 if err != nil { panic(err) }
95 duration := time.Since(startTime)
96 log.Printf("Got %d URLs in %s.", totalURLs, duration.String())