aboutsummaryrefslogtreecommitdiffstats
path: root/playlist_generator/playlist_generator.py
blob: 1bcc0b7b5b8ef85e058ae5656bc35d567be6b8a7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#!/usr/bin/python3
import argparse
from random import shuffle
import yt_dlp


class PlaylistGenerator:
    def get_urls_from_file(self, path: str) -> list[str]:
        with open(path) as f:
            lines = f.readlines()
            return [line.strip() for line in lines if len(line.strip()) > 0 and not line.startswith("#")]

    def extract(self, urls: list) -> list[dict[str]]:
        info = {}
        ydl_opts = {
        }
        errors = []
        with yt_dlp.YoutubeDL(ydl_opts) as ydl:
            for url in urls:
                try:
                    url_info = ydl.sanitize_info(ydl.extract_info(url, download=False))
                    if url_info["_type"] == "video":
                        info[url_info["id"]] = url_info
                    if url_info["_type"] == "playlist":
                        for entry in url_info["entries"]:
                            info[entry["id"]] = entry
                except yt_dlp.utils.DownloadError:
                    errors.append(url)
        print(f"{errors=}")
        return list(info.values())

    def build_playlist_string(self, video_info: list[dict[str]]) -> str:
        output = ""
        for info in video_info:
            artist = self.escape_quotes(self.get_artist(info))
            title = self.escape_quotes(self.get_title(info))
            output += f'{{ artist: "{artist}", name: "{title}", youtubeId: "{info["id"]}" }},\n'
        return output

    def get_artist(self, info):
        if info.get("artist"):
            return info["artist"]
        elif " - " in info["title"]:
            return info["title"].split(" - ")[0]
        else:
            return info["uploader"]

    def get_title(self, info):
        title = info["title"]
        suffixes = ["(Official Music Video)", "(Official Video)", "(Official Lyric Video)", "(Official Audio)", "(Audio)"]
        for suffix in suffixes:
            title = title.removesuffix(suffix).strip()
        if info.get("track"):
            return info["track"]
        elif " - " in title:
            return title.split(" - ")[1]
        else:
            return title

    def escape_quotes(self, field: str) -> str:
        return field.replace('"', r'\"')


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("urls_file")
    parser.add_argument("output_file")
    args = parser.parse_args()

    generator = PlaylistGenerator()
    urls = generator.get_urls_from_file(args.urls_file)
    video_info = generator.extract(urls)
    shuffle(video_info)
    js_playlist = generator.build_playlist_string(video_info)
    with open(args.output_file, 'w') as f:
        f.write(js_playlist)


if __name__ == "__main__":
    main()
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage