Skip to content

Commit ccf9b51

Browse files
authored
Refactor (#26)
fixes #23 and #22
1 parent 9f298a0 commit ccf9b51

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+3738
-2833
lines changed

README.md

Lines changed: 87 additions & 126 deletions
Large diffs are not rendered by default.

cmd/batch.go

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"strings"
7+
8+
"github.com/goccy/go-yaml"
9+
"github.com/spf13/cobra"
10+
"github.com/tanq16/danzo/internal/scheduler"
11+
"github.com/tanq16/danzo/internal/utils"
12+
)
13+
14+
type BatchEntry struct {
15+
OutputPath string `yaml:"op,omitempty"`
16+
Link string `yaml:"link"`
17+
}
18+
19+
type BatchFile map[string][]BatchEntry
20+
21+
func newBatchCmd() *cobra.Command {
22+
cmd := &cobra.Command{
23+
Use: "batch [YAML_FILE] [OPTIONS]",
24+
Short: "Process multiple downloads from a YAML file",
25+
Args: cobra.ExactArgs(1),
26+
Run: func(cmd *cobra.Command, args []string) {
27+
yamlFile := args[0]
28+
data, err := os.ReadFile(yamlFile)
29+
if err != nil {
30+
fmt.Fprintf(os.Stderr, "Error reading YAML file: %v\n", err)
31+
os.Exit(1)
32+
}
33+
var batchFile BatchFile
34+
if err := yaml.Unmarshal(data, &batchFile); err != nil {
35+
fmt.Fprintf(os.Stderr, "Error parsing YAML file: %v\n", err)
36+
os.Exit(1)
37+
}
38+
jobs := buildJobsFromBatch(batchFile)
39+
if len(jobs) == 0 {
40+
fmt.Fprintf(os.Stderr, "No valid jobs found in the batch file\n")
41+
os.Exit(1)
42+
}
43+
scheduler.Run(jobs, workers, fileLog)
44+
},
45+
}
46+
return cmd
47+
}
48+
49+
func buildJobsFromBatch(batchFile BatchFile) []utils.DanzoJob {
50+
var jobs []utils.DanzoJob
51+
for jobType, entries := range batchFile {
52+
normalizedType := normalizeJobType(jobType)
53+
if normalizedType == "" {
54+
fmt.Fprintf(os.Stderr, "Warning: Unknown job type '%s', skipping...\n", jobType)
55+
continue
56+
}
57+
for _, entry := range entries {
58+
if entry.Link == "" {
59+
fmt.Fprintf(os.Stderr, "Warning: Empty link found in %s section, skipping...\n", jobType)
60+
continue
61+
}
62+
job := utils.DanzoJob{
63+
JobType: normalizedType,
64+
URL: entry.Link,
65+
OutputPath: entry.OutputPath,
66+
HTTPClientConfig: globalHTTPConfig,
67+
Metadata: make(map[string]any),
68+
}
69+
switch normalizedType {
70+
case "http", "gdrive", "ghrelease", "m3u8":
71+
job.Connections = connections
72+
job.ProgressType = "progress"
73+
case "s3":
74+
job.Connections = connections
75+
job.ProgressType = "progress"
76+
job.Metadata["profile"] = "default"
77+
case "youtube", "ytmusic", "gitclone":
78+
job.ProgressType = "stream"
79+
default:
80+
job.ProgressType = "progress"
81+
}
82+
addJobTypeSpecificMetadata(&job, normalizedType)
83+
jobs = append(jobs, job)
84+
}
85+
}
86+
return jobs
87+
}
88+
89+
func normalizeJobType(jobType string) string {
90+
typeMap := map[string]string{
91+
"http": "http",
92+
"https": "http",
93+
"s3": "s3",
94+
"gdrive": "gdrive",
95+
"googledrive": "gdrive",
96+
"google-drive": "gdrive",
97+
"gitclone": "gitclone",
98+
"git-clone": "gitclone",
99+
"git": "gitclone",
100+
"ghrelease": "ghrelease",
101+
"gh-release": "ghrelease",
102+
"github": "ghrelease",
103+
"github-release": "ghrelease",
104+
"m3u8": "m3u8",
105+
"hls": "m3u8",
106+
"youtube": "youtube",
107+
"yt": "youtube",
108+
"ytmusic": "ytmusic",
109+
"youtube-music": "ytmusic",
110+
"yt-music": "ytmusic",
111+
}
112+
normalized := ""
113+
for key, value := range typeMap {
114+
if key == jobType || key == strings.ToLower(jobType) {
115+
normalized = value
116+
break
117+
}
118+
}
119+
return normalized
120+
}
121+
122+
func addJobTypeSpecificMetadata(job *utils.DanzoJob, jobType string) {
123+
switch jobType {
124+
case "youtube":
125+
if _, ok := job.Metadata["format"]; !ok {
126+
job.Metadata["format"] = "decent"
127+
}
128+
case "ghrelease":
129+
job.Metadata["manual"] = false
130+
case "gitclone":
131+
if _, ok := job.Metadata["depth"]; !ok {
132+
job.Metadata["depth"] = 0
133+
}
134+
}
135+
}

cmd/clean.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package cmd
2+
3+
import (
4+
"path/filepath"
5+
6+
"github.com/spf13/cobra"
7+
"github.com/tanq16/danzo/internal/utils"
8+
)
9+
10+
func newCleanCmd() *cobra.Command {
11+
return &cobra.Command{
12+
Use: "clean [path]",
13+
Short: "Clean up temporary files",
14+
Args: cobra.MaximumNArgs(1),
15+
Run: func(cmd *cobra.Command, args []string) {
16+
if len(args) == 0 {
17+
utils.CleanLocal()
18+
} else {
19+
utils.CleanFunction(filepath.Dir(args[0]))
20+
}
21+
},
22+
}
23+
}

cmd/gdrive.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package cmd
2+
3+
import (
4+
"github.com/spf13/cobra"
5+
"github.com/tanq16/danzo/internal/scheduler"
6+
"github.com/tanq16/danzo/internal/utils"
7+
)
8+
9+
func newGDriveCmd() *cobra.Command {
10+
var outputPath string
11+
var apiKey string
12+
var credentialsFile string
13+
14+
cmd := &cobra.Command{
15+
Use: "gdrive [URL] [--output OUTPUT_PATH] [--api-key YOUR_KEY] [--creds creds.json]",
16+
Short: "Download files or folders from Google Drive",
17+
Args: cobra.ExactArgs(1),
18+
Run: func(cmd *cobra.Command, args []string) {
19+
job := utils.DanzoJob{
20+
JobType: "gdrive",
21+
URL: args[0],
22+
OutputPath: outputPath,
23+
Connections: connections,
24+
ProgressType: "progress",
25+
HTTPClientConfig: globalHTTPConfig,
26+
Metadata: make(map[string]any),
27+
}
28+
if apiKey != "" {
29+
job.Metadata["apiKey"] = apiKey
30+
}
31+
if credentialsFile != "" {
32+
job.Metadata["credentialsFile"] = credentialsFile
33+
}
34+
jobs := []utils.DanzoJob{job}
35+
scheduler.Run(jobs, workers, fileLog)
36+
},
37+
}
38+
39+
cmd.Flags().StringVarP(&outputPath, "output", "o", "", "Output path")
40+
cmd.Flags().StringVar(&apiKey, "api-key", "", "Google Drive API key")
41+
cmd.Flags().StringVar(&credentialsFile, "creds", "", "OAuth credentials JSON file")
42+
return cmd
43+
}

cmd/ghrelease.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package cmd
2+
3+
import (
4+
"github.com/spf13/cobra"
5+
"github.com/tanq16/danzo/internal/scheduler"
6+
"github.com/tanq16/danzo/internal/utils"
7+
)
8+
9+
func newGHReleaseCmd() *cobra.Command {
10+
var outputPath string
11+
var manual bool
12+
13+
cmd := &cobra.Command{
14+
Use: "ghrelease [USER/REPO or URL] [--output OUTPUT_PATH] [--manual]",
15+
Short: "Download a release asset for a GitHub repository",
16+
Args: cobra.ExactArgs(1),
17+
Run: func(cmd *cobra.Command, args []string) {
18+
job := utils.DanzoJob{
19+
JobType: "ghrelease",
20+
URL: args[0],
21+
OutputPath: outputPath,
22+
Connections: connections,
23+
ProgressType: "progress",
24+
HTTPClientConfig: globalHTTPConfig,
25+
Metadata: make(map[string]any),
26+
}
27+
job.Metadata["manual"] = manual
28+
jobs := []utils.DanzoJob{job}
29+
scheduler.Run(jobs, workers, fileLog)
30+
},
31+
}
32+
33+
cmd.Flags().StringVarP(&outputPath, "output", "o", "", "Output file path")
34+
cmd.Flags().BoolVar(&manual, "manual", false, "Manually select release version and asset")
35+
return cmd
36+
}

cmd/gitclone.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package cmd
2+
3+
import (
4+
"github.com/spf13/cobra"
5+
"github.com/tanq16/danzo/internal/scheduler"
6+
"github.com/tanq16/danzo/internal/utils"
7+
)
8+
9+
func newGitCloneCmd() *cobra.Command {
10+
var outputPath string
11+
var depth int
12+
var token string
13+
var sshKey string
14+
15+
cmd := &cobra.Command{
16+
Use: "gitclone [REPO_URL] [--output OUTPUT_PATH] [--depth DEPTH] [--token GIT_TOKEN] [--ssh SSH_KEY_PATH]",
17+
Short: "Clone a Git repository",
18+
Args: cobra.ExactArgs(1),
19+
Run: func(cmd *cobra.Command, args []string) {
20+
job := utils.DanzoJob{
21+
JobType: "gitclone",
22+
URL: args[0],
23+
OutputPath: outputPath,
24+
ProgressType: "stream",
25+
HTTPClientConfig: globalHTTPConfig,
26+
Metadata: make(map[string]any),
27+
}
28+
if depth > 0 {
29+
job.Metadata["depth"] = depth
30+
}
31+
if token != "" {
32+
job.Metadata["token"] = token
33+
}
34+
if sshKey != "" {
35+
job.Metadata["sshKey"] = sshKey
36+
}
37+
jobs := []utils.DanzoJob{job}
38+
scheduler.Run(jobs, workers, fileLog)
39+
},
40+
}
41+
42+
cmd.Flags().StringVarP(&outputPath, "output", "o", "", "Output directory path")
43+
cmd.Flags().IntVar(&depth, "depth", 0, "Clone depth (0 for full history)")
44+
cmd.Flags().StringVar(&token, "token", "", "Git token for authentication")
45+
cmd.Flags().StringVar(&sshKey, "ssh", "", "SSH key path for authentication")
46+
return cmd
47+
}

cmd/http.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package cmd
2+
3+
import (
4+
"github.com/spf13/cobra"
5+
"github.com/tanq16/danzo/internal/scheduler"
6+
"github.com/tanq16/danzo/internal/utils"
7+
)
8+
9+
func newHTTPCmd() *cobra.Command {
10+
var outputPath string
11+
12+
cmd := &cobra.Command{
13+
Use: "http [URL] [--output OUTPUT_PATH]",
14+
Short: "Download file via HTTP/HTTPS",
15+
Args: cobra.ExactArgs(1),
16+
Run: func(cmd *cobra.Command, args []string) {
17+
url := args[0]
18+
job := utils.DanzoJob{
19+
JobType: "http",
20+
URL: url,
21+
OutputPath: outputPath,
22+
Connections: connections,
23+
ProgressType: "progress",
24+
HTTPClientConfig: globalHTTPConfig,
25+
Metadata: make(map[string]any),
26+
}
27+
jobs := []utils.DanzoJob{job}
28+
scheduler.Run(jobs, workers, fileLog)
29+
},
30+
}
31+
32+
cmd.Flags().StringVarP(&outputPath, "output", "o", "", "Output file path")
33+
return cmd
34+
}

cmd/m3u8.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package cmd
2+
3+
import (
4+
"github.com/spf13/cobra"
5+
"github.com/tanq16/danzo/internal/scheduler"
6+
"github.com/tanq16/danzo/internal/utils"
7+
)
8+
9+
func newM3U8Cmd() *cobra.Command {
10+
var outputPath string
11+
12+
cmd := &cobra.Command{
13+
Use: "m3u8 [URL] [--output OUTPUT_PATH]",
14+
Short: "Download HLS/M3U8 streams",
15+
Args: cobra.ExactArgs(1),
16+
Run: func(cmd *cobra.Command, args []string) {
17+
job := utils.DanzoJob{
18+
JobType: "m3u8",
19+
URL: args[0],
20+
OutputPath: outputPath,
21+
Connections: connections,
22+
ProgressType: "progress",
23+
HTTPClientConfig: globalHTTPConfig,
24+
Metadata: make(map[string]any),
25+
}
26+
jobs := []utils.DanzoJob{job}
27+
scheduler.Run(jobs, workers, fileLog)
28+
},
29+
}
30+
31+
cmd.Flags().StringVarP(&outputPath, "output", "o", "", "Output file path (default: stream_[timestamp].mp4)")
32+
return cmd
33+
}

0 commit comments

Comments
 (0)