Exemplo n.º 1
0
def pprint_row(serie_name, lang, mode, index=False, remove=False):
    if index and remove:
        return paint(f"[!red][#] {serie_name} [{mode}]")
    if index and not remove:
        ret_str = paint(f"[#green][>] {serie_name}")
    else:
        ret_str = f"[ ] {serie_name}"
    return ret_str + paint(f" [#cyan]({lang}) [#blue][{mode}]")
Exemplo n.º 2
0
def pprint_settings():
    config = get_config()
    labels = ("Current path", "Backup", "Telegram")
    path_str = paint(config.get("path"), c_settings)
    backup = get_last_backup()
    backup_str = paint(backup, c_settings)
    telegram_str = ((paint(config.get("telegram-bot-token"), c_settings) +
                     paint(":", style=Style.BOLD) +
                     paint(config.get("telegram-chat-id"), c_settings))
                    if config.get("telegram-bot-token") else "")
    values = (path_str, backup_str, telegram_str)
    return "\n".join(f"{paint(lab,style=Style.BOLD)}: {val}"
                     for lab, val in zip(labels, values))
Exemplo n.º 3
0
def get_spotify_songs(playlist_link):
    config = get_config()
    try:
        client = Spotify(client_credentials_manager=SpotifyClientCredentials(
            config.get("spotify-id"), config.get("spotify-secret-id")))
        playlist = client.playlist(playlist_link)
    except SpotifyOauthError:
        print("\n" + paint("Error! ", Color.RED) +
              "Please run the configuration once.")
        print("Run " + paint("saberio --config", Color.BLUE))
        exit(-1)
    return [(
        sanitize_song_name(song.get("track").get("name")),
        song.get("track").get("artists")[0].get("name"),
    ) for song in playlist.get("tracks").get("items")]
Exemplo n.º 4
0
def download(action):
    serie_list = [list(serie.values()) for serie in CONFIG.get("serie")]
    for name, url, folder, lang, mode in serie_list:
        SPINNER.start(paint(f"Scanning [#blue]{name}"))
        eurostreaming_url = path.join(get_eurostreaming_site(), url)
        page = LinkFinder(eurostreaming_url, sub=lang == "eng")
        eps_to_download = episodes_to_download(folder, page, mode)
        for se, ep in eps_to_download:
            spinner(SPINNER.start, "Finding link for", name, se, ep)
            try:
                link = page.get_direct_links(se, ep)
            except ValueError:
                spinner(SPINNER.fail, "Fail to get the link for", name, se, ep)
                if action != "test":
                    send_telegram_log(name, se, ep, success=False)
                continue
            if action == "run":
                basepath = path.join(CONFIG.get("path"), folder,
                                     f"Stagione {se}")
                if not path.exists(basepath):
                    makedirs(basepath)
                filename = path.join(
                    basepath,
                    f"{sanitize_name(name)}_s{int(se):02d}e{ep:02d}.mp4")
                spinner(SPINNER.start, "Downloading", name, se, ep)
                try:
                    download_video(link, name, filename)
                except Exception:
                    spinner(SPINNER.fail, "Fail to download", name, se, ep)
                    send_telegram_log(name, se, ep, success=False)
                    continue
                spinner(SPINNER.succeed, "Downloaded", name, se, ep)
                send_telegram_log(name, se, ep)
            elif action == "test":
                spinner(SPINNER.info, "Found", name, se, ep)
Exemplo n.º 5
0
def pprint_actions(mode=None):
    if mode == "confirm":
        actions = {"y": "confirm", "n": "back"}
    elif mode == "add":
        actions = {"ws": "move", "c": "confirm", "b": "back"}
    elif mode == "back":
        actions = {"b": "back"}
    elif mode == "settings":
        actions = {
            "u": "backup",
            "r": "restore",
            "p": "path",
            "t": "telegram",
            "e": "eurostreaming",
            "b": "back",
        }
    elif mode == "path":
        actions = {"e": "edit", "b": "back"}
    else:
        actions = {
            "ws": "move",
            "a": "add",
            "r": "remove",
            "e": "settings",
            "q": "quit",
        }
    return ("-" * sum(len(action) + 5
                      for action in actions.values()) + "\n" + " ".join(
                          paint(f"[[@bold]{key}[/@]]:[#magenta]{action}")
                          for key, action in actions.items()))
Exemplo n.º 6
0
def download_song(song_name, link, filename):
    colored_song_name = paint(song_name, Color.BLUE)
    if not link:
        SPINNER.fail(f"No link working for {colored_song_name}")
    SPINNER.start(f"Downloading {colored_song_name}")
    zip_song = get(link, headers=HEADERS)
    open(filename, "wb").write(zip_song.content)
    SPINNER.succeed(f"Downloaded {colored_song_name}")
Exemplo n.º 7
0
def pprint_settings():
    config = get_config()
    labels = ("Eurostreaming", "Current path", "Backup", "Telegram")
    eurostreaming_url = f"[#blue]{config.get('eurostreaming')}"
    path_str = f"[#blue]{config.get('path')}"
    backup_str = f"[#blue]{get_last_backup()}"
    telegram_str = (f"[#blue]{config.get('telegram-bot-token')}[/# @bold]:"
                    f"[/@ #blue]{config.get('telegram-chat-id')}")
    telegram_str = config.get("telegram-bot-token") and telegram_str or ""
    values = (eurostreaming_url, path_str, backup_str, telegram_str)
    return "\n".join(
        paint(f"[@bold]{lab}[/]: {val}") for lab, val in zip(labels, values))
Exemplo n.º 8
0
def pprint_row(anime_name, season, mode, index=False, remove=False):
    if index and remove:
        return paint(f"[#] {anime_name} [{mode}]", background=Background.RED)
    if index and not remove:
        ret_str = paint("[>] ", c_anime_menu) + paint(anime_name, c_anime_menu)
    else:
        ret_str = "[ ] " + paint(anime_name)
    return (ret_str + paint(f" (s{season}) ", c_season_menu) +
            paint(f"[{mode}]", c_mode_menu))
Exemplo n.º 9
0
def retrieve_params(args):
    spotify_playlist_link = None
    if not args.file and not args.song:
        spotify_playlist_link = input(
            paint("> ", Color.WHITE) + paint("Spotify", Color.GREEN) +
            paint(" playlist link: ", Color.WHITE))
        while not search("https://open.spotify.com/playlist/",
                         spotify_playlist_link):
            spotify_playlist_link = input(
                paint("Bad link!", Color.RED) + paint(" Retry: ", Color.WHITE))
    if not args.p:
        playlist_name = input(
            paint("> Choose a name for the playlist: ", Color.WHITE))
    else:
        playlist_name = args.p
    if not args.auto and not args.list and not args.test:
        while (automatic := input(
                paint("> Choose mode: ", Color.WHITE) +
                paint("[auto|list|test] ", Color.WHITE, style=Style.BOLD)).
               lower()) not in ("auto", "list", "test"):
            pass
        auto = automatic != "list"
        test = automatic == "test"
Exemplo n.º 10
0
def songs_table(songs):
    headers = [
        paint(h, style=Style.BOLD) for h in
        ["", "Code", "Song", "Mapper", "Up", "Down", "Difficulty", "Date"]
    ]
    entries = [(
        i,
        paint(code, Color.MAGENTA),
        lines_splitting(name),
        paint(mapper, Color.BLUE),
        paint(up, Color.GREEN),
        paint(down, Color.RED),
        paint(difficulties, Color.YELLOW),
        paint(f"{date:%d.%m.%Y}", Color.GRAY),
    ) for i, (code, name, _, difficulties, up, down, mapper,
              date) in enumerate(songs, 1)]
    return tabulate(entries,
                    headers=headers,
                    tablefmt="fancy_grid",
                    disable_numparse=True)
Exemplo n.º 11
0
def spinner(func, action, anime, season, episode):
    func(
        paint(f"{action} ", c_action_download) +
        paint(f"{anime} ", c_anime_download) +
        paint(f"{season}x{episode}", c_episode_download))
Exemplo n.º 12
0
def spinner(func, action, serie, season, episode):
    func(
        paint(f"[#white]{action} [#blue]{serie} [#magenta]{season}x{episode}"))
Exemplo n.º 13
0
def main():
    args = argparsing()

    # spotify config
    if args.config:
        print("To get a key, go to " +
              paint("https://developer.spotify.com/dashboard/applications",
                    Color.MAGENTA) + " and create a new application.")
        client_id = input("Client ID: ")
        secret_id = input("Secret ID: ")
        save_config(client_id, secret_id)
        try:
            client = Spotify(
                client_credentials_manager=SpotifyClientCredentials(
                    client_id, secret_id))
            client.search("test")
            print(paint("Configuration successful!", Color.GREEN))
        except SpotifyOauthError:
            print(paint("Configuration failed.", Color.RED))
        exit(-1)

    # script
    if args.dir and not path.exists(path.join(args.dir)):
        print(
            paint("Path ", Color.RED) +
            paint(args.dir, Color.RED, style=Style.UNDERLINE) +
            paint(" doesn't exist!", Color.RED))
        exit(-1)
    path_to_folder = args.dir or "."
    spotify_playlist_link, playlist_name, automatic, test = retrieve_params(
        args=args)
    if args.file:
        try:
            songs_to_search = [(*special_song_name(lines), None)
                               for lines in open(args.file).read().split("\n")
                               if lines]
        except FileNotFoundError:
            print(
                paint("File ", Color.RED) +
                paint(args.file, Color.RED, style=Style.UNDERLINE) +
                paint(" not found!", Color.RED))
            exit(-1)
        print(
            paint("> Songs list provided via file ", Color.WHITE) +
            paint(args.file, Color.BLUE))
    elif args.song:
        songs_to_search = [(*special_song_name(args.song), None)]
        print(
            paint("> Single song search ", Color.WHITE) +
            paint(args.song, Color.BLUE))
    else:
        songs_to_search = [
            (None, f"{title} {artist}", title)
            for title, artist in get_spotify_songs(spotify_playlist_link)
        ]
        print(
            paint("> Songs list provided via ", Color.WHITE) +
            paint("Spotify playlist", Color.BLUE))
    if not test and not path.exists(path.join(path_to_folder, playlist_name)):
        mkdir(path.join(path_to_folder, playlist_name))
    print()
    # downloading
    for code_song, song_more, song_less in songs_to_search:
        song_to_download = None
        if not code_song:
            bsaber_songs = search_songs(song_more)
            if song_less:
                bsaber_songs = combine_search(bsaber_songs,
                                              search_songs(song_less))
            SPINNER.succeed(f"Searched for {paint(song_more,Color.BLUE)}")
            if bsaber_songs:
                bsaber_songs = sorted(bsaber_songs,
                                      key=lambda x: (-x[4] + 1) / (x[5] + 1))
                if not automatic:
                    print(songs_table(bsaber_songs))
                    n = input(paint("> Choose a song: [0:skip] ", Color.WHITE))
                    while not match(r"\d+", n) or int(n) not in range(
                            len(bsaber_songs) + 1):
                        n = input(
                            paint("Wrong!  ", Color.RED) +
                            paint("> Retry: [0:skip] ", Color.WHITE))
                else:
                    n = 1
                if int(n):
                    song_to_download = bsaber_songs[int(n) - 1]
                else:
                    SPINNER.fail(f"Skipped {paint(song_more,Color.BLUE)}")
            else:
                SPINNER.fail(
                    f"No song found for {paint(song_more,Color.BLUE)}")
        else:
            SPINNER.succeed(f"Searched for {paint(song_more,Color.BLUE)} "
                            f"[{paint(code_song,Color.MAGENTA)}]")
            song_to_download = get_info_by_code(code_song)
        # song downloading
        if song_to_download:
            code_song, song_name, song_link = song_to_download[:3]
            path_to_file = path.join(
                path_to_folder,
                playlist_name,
                multisub({
                    "/": "_",
                    " – ": "_",
                    " ": "_"
                }, song_name),
            )
            filename = f"{path_to_file}.zip" if playlist_name else song_name
            if test:
                SPINNER.succeed(f"Matched with {paint(song_name,Color.BLUE)}")
            elif not path.exists(filename):
                download_song(song_name, song_link, filename)
            else:
                SPINNER.succeed(
                    f"Already downloaded {paint(song_name,Color.BLUE)}")
            open(path.join(path_to_folder, f"{playlist_name}.log"),
                 "a+").write(f"{song_name} #{code_song}\n")
        print("\n")
Exemplo n.º 14
0
def lines_splitting(name):
    MAX_CHAR = 45
    if len(name) <= MAX_CHAR:
        return paint(name, Color.WHITE)
    return paint(name[:MAX_CHAR], Color.WHITE) + "\n" + lines_splitting(
        name[MAX_CHAR:])
Exemplo n.º 15
0
def manage():
    index = 0
    k = "start"
    while k != "q":
        anime_list = [
            list(anime.values()) for anime in get_config().get("anime")
        ]
        print(pprint_anime(anime_list, index))
        print(pprint_actions())
        k = direct_input(choices=("w", "s", "e", "a", "r", "q"))
        erase(len(anime_list or [0]) + 2)

        if k in ("w", "s"):
            if k == "w" and index:
                index -= 1
            if k == "s" and index < len(anime_list) - 1:
                index += 1

        if k == "e":
            e_k = "start"
            while e_k != "b":
                print(pprint_settings())
                print(pprint_actions(mode="settings"))
                e_k = direct_input(choices=("u", "r", "p", "t", "c", "b"))
                erase(5)
                if e_k == "p":
                    base = paint("Path", style=Style.BOLD) + ": "
                    new_path = strict_input(
                        base,
                        wrong_text=paint("Wrong path! ", Color.RED) + base,
                        check=path.exists,
                        flush=True,
                    )
                    add_new_path(new_path)
                    e_k = ""
                elif e_k == "r":
                    backup_filename = get_last_backup()
                    if backup_filename:
                        backup_dict = load(open(backup_filename))
                        save_config(backup_dict)
                elif e_k == "u":
                    now = datetime.now()
                    config = get_config()
                    dump(
                        config,
                        open(f"{now:%Y-%m-%d}_saturno-backup.json", "w"),
                        indent=4,
                    )
                elif e_k == "t":
                    base = paint("Telegram bot token", style=Style.BOLD) + ": "
                    telegram_bot_token = strict_input(
                        base,
                        wrong_text=paint("Invalid token! ", Color.RED) + base,
                        check=is_bot_valid,
                        flush=True,
                    )
                    base = paint("Telegram chat ID", style=Style.BOLD) + ": "
                    telegram_chat_id = strict_input(
                        base,
                        wrong_text=paint("Invalid chat ID! ", Color.RED) +
                        base,
                        regex=r"\-?\d+$",
                        flush=True,
                    )
                    add_telegram_config(telegram_bot_token, telegram_chat_id)
                elif e_k == "c":
                    print("Color can be:", end="")
                    sample("color")
                    erase(2)
                    color_labels = [
                        "anime name [menu]",
                        "season [menu]",
                        "mode [menu]",
                        "action [download]",
                        "anime name [download]",
                        "episode [download]",
                        "setting",
                        "button legend",
                    ]
                    colors = list()
                    for label in color_labels:
                        base = "Color for " + paint(f"{label}",
                                                    style=Style.BOLD) + ": "
                        color_choose = strict_input(
                            base,
                            wrong_text=paint("Invalid color! ", Color.RED) +
                            base,
                            check=is_color_valid,
                            flush=True,
                        )
                        colors.append(color_choose)
                    erase()
                    add_colors(colors)

        if anime_list and k == "r":
            print(pprint_anime(anime_list, index, remove=True))
            print(pprint_actions(mode="confirm"))
            r_k = direct_input(choices=("y", "b"))
            if r_k == "y":
                remove_anime(index)
                index = 0
            erase(len(anime_list) + 2)

        if k == "a":
            q_index = 0
            q_k = "start"
            # anime search
            query = input(paint("Anime name", style=Style.BOLD) + ": ")
            erase()
            query_list = search_anime(query)
            if not query_list:
                print(f"No anime found with {paint(query,Color.BLUE)}!")
                print(pprint_actions(mode="back"))
                q_k = direct_input(choices=("b", ))
                erase(3)
            while q_k not in ("c", "b"):
                print(pprint_query(query_list, q_index))
                print(pprint_actions(mode="add"))
                q_k = direct_input()
                erase(len(query_list) + 2)
                if q_k in ("w", "s"):
                    if q_k == "w" and q_index:
                        q_index -= 1
                    if q_k == "s" and q_index < len(query_list) - 1:
                        q_index += 1
            # new anime
            if q_k == "c":
                base = paint("Season", style=Style.BOLD) + ": "
                season = strict_input(
                    base,
                    f"{paint('This is not a season!',Color.RED)} {base}",
                    regex=r"\d{1,2}$",
                    flush=True,
                )
                base = paint("Folder name", style=Style.BOLD) + ": "
                name = strict_input(
                    base,
                    f"{paint('Folder name must be unique!', Color.RED)} {base}",
                    check=is_folder_unique,
                    flush=True,
                )
                base = paint("Mode [full|new]", style=Style.BOLD) + ": "
                mode = strict_input(
                    base,
                    f"{paint('Mode must be full or new!', Color.RED)} {base}",
                    choices=("full", "new"),
                    flush=True,
                )
                print(recap_new_anime(*query_list[q_index], season, name,
                                      mode))
                print(pprint_actions(mode="confirm"))
                c_k = direct_input(choices=("y", "n"))
                if c_k == "y":
                    add_anime(*query_list[q_index], season, name, mode)
                erase(7)
                index = 0
Exemplo n.º 16
0
def pprint_query(query_list, selected):
    return "\n".join(
        paint(f"[#green][>] {name}") if selected == i else f"[ ] {name}"
        for i, (name, _) in enumerate(query_list))
Exemplo n.º 17
0
def manage(eurostreaming_url):
    index = 0
    k = "start"
    while k != "q":
        serie_list = [
            list(serie.values()) for serie in get_config().get("serie")
        ]
        print(pprint_serie(serie_list, index))
        print(pprint_actions())
        k = direct_input(choices=("w", "s", "e", "a", "r", "q"))
        erase(len(serie_list or [0]) + 2)

        if k in ("w", "s"):
            if k == "w" and index:
                index -= 1
            if k == "s" and index < len(serie_list) - 1:
                index += 1

        if k == "e":
            e_k = "start"
            while e_k != "b":
                print(pprint_settings())
                print(pprint_actions(mode="settings"))
                e_k = direct_input(choices=("u", "r", "p", "t", "y", "e", "b"))
                erase(6)
                if e_k == "p":
                    base = paint("[@bold]Path[/]: ")
                    new_path = strict_input(
                        base,
                        wrong_text=paint(f"[#red]Wrong path![/] {base}"),
                        check=lambda x: path.exists(x.strip()),
                        flush=True,
                    )
                    add_new_path(new_path)
                    e_k = ""
                elif e_k == "r":
                    backup_filename = get_last_backup()
                    if backup_filename:
                        backup_dict = load(open(backup_filename))
                        save_config(backup_dict)
                elif e_k == "u":
                    now = datetime.now()
                    config = get_config()
                    dump(
                        config,
                        open(f"{now:%Y-%m-%d}_europlexo-backup.json", "w"),
                        indent=4,
                    )
                elif e_k == "t":
                    base = paint("[@bold]Telegram bot token[/]: ")
                    telegram_bot_token = strict_input(
                        base,
                        wrong_text=paint(f"[#red]Invalid token! {base}"),
                        check=is_bot_valid,
                        flush=True,
                    )
                    base = paint("[@bold]Telegram chat ID[/]: ")
                    telegram_chat_id = strict_input(
                        base,
                        wrong_text=paint(f"[#red]Invalid chat ID![/] {base}"),
                        regex=r"\-?\d+$",
                        flush=True,
                    )
                    add_telegram_config(telegram_bot_token, telegram_chat_id)
                elif e_k == "e":
                    base = paint("[@bold]Eurostreaming site[/]: ")
                    eurostreaming_url = strict_input(
                        base,
                        wrong_text=paint(
                            f"[#red]Wrong site, unreacheable![/] {base}"),
                        check=is_eurostreaming_valid,
                        flush=True,
                    )
                    add_eurostreaming_site(eurostreaming_url)

        if serie_list and k == "r":
            print(pprint_serie(serie_list, index, remove=True))
            print(pprint_actions(mode="confirm"))
            r_k = direct_input(choices=("y", "n"))
            if r_k == "y":
                remove_serie(index)
                index = 0
            erase(len(serie_list) + 2)

        if k == "a":
            q_index = 0
            q_k = "start"
            # serie search
            query = input(paint("[@bold]Serie name[/]: "))
            erase()
            SPINNER.start(paint(f"Searching for [#blue]{query}"))
            query_list = get_suggestion_list(eurostreaming_url, query)
            SPINNER.stop()
            if not query_list:
                ppaint(f"No serie found with [#blue]{query}")
                print(pprint_actions(mode="back"))
                q_k = direct_input(choices=("b", ))
                erase(3)
            while q_k not in ("c", "b"):
                print(pprint_query(query_list, q_index))
                print(pprint_actions(mode="add"))
                q_k = direct_input()
                erase(len(query_list) + 2)
                if q_k in ("w", "s"):
                    if q_k == "w" and q_index:
                        q_index -= 1
                    if q_k == "s" and q_index < len(query_list) - 1:
                        q_index += 1
            # new serie
            if q_k == "c":
                base = paint("[@bold]Folder name[/]: ")
                folder = strict_input(
                    base,
                    paint(f"[#red]Folder name must be unique![/] {base}"),
                    check=is_folder_unique,
                    flush=True,
                )
                base = paint("[@bold]Language [eng|ita][/]: ")
                lang = strict_input(
                    base,
                    paint(f"[#red]Language must be 'eng' or 'ita'![/] {base}"),
                    choices=("eng", "ita"),
                    flush=True,
                )
                base = paint("[@bold]Mode [full|new|last][/]: ")
                mode = strict_input(
                    base,
                    paint(
                        f"[#red]Mode must be 'full', 'new' or 'last'![/] {base}"
                    ),
                    choices=("full", "new", "last"),
                    flush=True,
                )
                print(recap_new_serie(*query_list[q_index], folder, lang,
                                      mode))
                print(pprint_actions(mode="confirm"))
                c_k = direct_input(choices=("y", "n"))
                if c_k == "y":
                    name, link = query_list[q_index]
                    link = multisub({eurostreaming_url: "", "/": ""}, link)
                    add_serie(name, link, folder, lang, mode)
                erase(7)
                index = 0
Exemplo n.º 18
0
def recap_new_serie(name, url, folder, lang, mode):
    return paint(
        f"Name: [#blue]{name}[/]\nLink: [#blue]{url}[/]\nFolder: [#blue]{folder}[/]\n"
        f"Language: [#blue]{lang}[/]\nMode: [#blue]{mode}", )