Function bodies 110 total
list_playlists function · python · L121-L135 (15 LOC)spotify/spotify.py
def list_playlists(client: httpx.Client):
offset = 0
while True:
resp = client.get("/me/playlists", params={"limit": 50, "offset": offset})
resp.raise_for_status()
data = resp.json()
items = data.get("items", [])
if not items:
break
for p in items:
total = (p.get("items") or p.get("tracks") or {}).get("total", -1)
yield p["id"], p["name"], total
offset += 50
if offset >= data.get("total", 0):
breakdelete_playlist function · python · L138-L140 (3 LOC)spotify/spotify.py
def delete_playlist(client: httpx.Client, playlist_id: str):
resp = client.request("DELETE", f"/playlists/{playlist_id}/followers")
resp.raise_for_status()main function · python · L143-L195 (53 LOC)spotify/spotify.py
def main():
if len(sys.argv) < 2:
print("Usage: spotify-playlist <command>")
print("Commands: create, list, cleanup")
sys.exit(1)
cmd = sys.argv[1]
client = authenticate()
if cmd == "create":
if len(sys.argv) < 3:
print('Usage: spotify-playlist create <name> [description] ["Artist:Track" ...]')
sys.exit(1)
name = sys.argv[2]
desc = sys.argv[3] if len(sys.argv) > 3 else ""
tracks = [(a, t) for arg in sys.argv[4:] if ":" in arg for a, t in [arg.split(":", 1)]]
playlist_id, url = create_playlist(client, name, desc)
print(f"Created playlist: {name}")
if tracks:
uris = []
for artist, title in tracks:
uri, found_title, found_artist = search_track(client, artist, title)
if uri:
print(f" + {found_artist} - {found_title}")
uris.append(uri)
else:
expandPath function · go · L49-L58 (10 LOC)youtube-dl/main.go
func expandPath(p string) (string, error) {
if strings.HasPrefix(p, "~/") {
home, err := os.UserHomeDir()
if err != nil {
return "", err
}
return filepath.Join(home, p[2:]), nil
}
return filepath.Abs(p)
}normalizeChannelInput function · go · L60-L75 (16 LOC)youtube-dl/main.go
func normalizeChannelInput(input string) string {
input = strings.TrimSpace(input)
// Already a full URL
if strings.HasPrefix(input, "http://") || strings.HasPrefix(input, "https://") {
// Ensure we're targeting the videos tab
if !strings.HasSuffix(input, "/videos") && !strings.Contains(input, "/videos") {
return strings.TrimSuffix(input, "/") + "/videos"
}
return input
}
// Handle @handle format
if strings.HasPrefix(input, "@") {
return fmt.Sprintf("https://www.youtube.com/%s/videos", input)
}loadExistingData function · go · L86-L101 (16 LOC)youtube-dl/main.go
func loadExistingData(path string) (*ChannelData, error) {
data, err := os.ReadFile(path)
if err != nil {
if os.IsNotExist(err) {
return &ChannelData{Videos: []Video{}}, nil
}
return nil, fmt.Errorf("cannot read file: %w", err)
}
var channelData ChannelData
if err := json.Unmarshal(data, &channelData); err != nil {
return nil, fmt.Errorf("cannot parse JSON: %w", err)
}
return &channelData, nil
}saveData function · go · L103-L126 (24 LOC)youtube-dl/main.go
func saveData(path string, data *ChannelData) error {
jsonData, err := json.MarshalIndent(data, "", " ")
if err != nil {
return fmt.Errorf("cannot marshal JSON: %w", err)
}
// Write to temp file first, then rename for atomicity
dir := filepath.Dir(path)
if err := os.MkdirAll(dir, 0755); err != nil {
return fmt.Errorf("cannot create directory: %w", err)
}
tmpFile := path + ".tmp"
if err := os.WriteFile(tmpFile, jsonData, 0644); err != nil {
return fmt.Errorf("cannot write temp file: %w", err)
}
if err := os.Rename(tmpFile, path); err != nil {
os.Remove(tmpFile)
return fmt.Errorf("cannot rename temp file: %w", err)
}
return nil
}Repobility (the analyzer behind this table) · https://repobility.com
fetchChannelVideos function · go · L128-L192 (65 LOC)youtube-dl/main.go
func fetchChannelVideos(channelURL string) ([]Video, string, string, string, error) {
// Check if yt-dlp is installed
if _, err := exec.LookPath("yt-dlp"); err != nil {
return nil, "", "", "", fmt.Errorf("yt-dlp not found in PATH. Please install it: https://github.com/yt-dlp/yt-dlp")
}
cmd := exec.Command("yt-dlp",
"--flat-playlist",
"--dump-json",
"--ignore-errors",
"--no-warnings",
channelURL,
)
stdout, err := cmd.StdoutPipe()
if err != nil {
return nil, "", "", "", fmt.Errorf("cannot create stdout pipe: %w", err)
}
if err := cmd.Start(); err != nil {
return nil, "", "", "", fmt.Errorf("cannot start yt-dlp: %w", err)
}
var videos []Video
var channelID, channelName, channelURLResult string
scanner := bufio.NewScanner(stdout)
// Increase scanner buffer for long descriptions
buf := make([]byte, 0, 64*1024)
scanner.Buffer(buf, 1024*1024)
for scanner.Scan() {
line := scanner.Text()
if line == "" {
continue
}
var ytVideo ytdlpVideo
if ermergeVideos function · go · L208-L229 (22 LOC)youtube-dl/main.go
func mergeVideos(existing, new []Video) ([]Video, int) {
existingURLs := make(map[string]bool)
for _, v := range existing {
existingURLs[v.URL] = true
}
var merged []Video
newCount := 0
// Add new videos first
for _, v := range new {
if !existingURLs[v.URL] {
merged = append(merged, v)
newCount++
}
}
// Then add existing videos
merged = append(merged, existing...)
return merged, newCount
}main function · go · L231-L308 (78 LOC)youtube-dl/main.go
func main() {
var outputPath string
flag.StringVar(&outputPath, "output", "", "Output file path (required)")
flag.StringVar(&outputPath, "o", "", "Output file path (required)")
flag.Parse()
args := flag.Args()
if len(args) == 0 {
fmt.Fprintln(os.Stderr, "Error: channel URL or handle is required")
fmt.Fprintln(os.Stderr, "Usage: youtube-dl -o <output.json> <channel_url|@handle|channel_id>")
os.Exit(1)
}
if outputPath == "" {
fmt.Fprintln(os.Stderr, "Error: output path is required (-o flag)")
fmt.Fprintln(os.Stderr, "Usage: youtube-dl -o <output.json> <channel_url|@handle|channel_id>")
os.Exit(1)
}
channelInput := args[0]
channelURL := normalizeChannelInput(channelInput)
// Expand output path
outputPath, err := expandPath(outputPath)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: cannot expand output path: %v\n", err)
os.Exit(1)
}
fmt.Printf("Fetching videos from %s...\n", channelURL)
// Load existing data
existingData, err := loadExistingData(outp‹ prevpage 3 / 3