Ejemplo n.º 1
0
 def search_results(s):
     all_res = s.find('ul', {'class': 'items'})
     for list_item in all_res.find_all('li'):
         an = list_item.p.a['href'].split('/')[-1]
         utils.write_cache(an, append=True)
         outputs.normal_info(an, end='  \t')
         outputs.normal_info(list_item.p.a.text)
Ejemplo n.º 2
0
def download_file(url, filepath, replace=False):
    if os.path.exists(filepath) and not replace:
        outputs.warning_info('File already downloaded, skipping.')
        return
    part_file = f'{filepath}.part'

    c = pycurl.Curl()
    c.setopt(pycurl.URL, url)
    c.setopt(pycurl.NOPROGRESS, 0)

    curl_header = [f'{k}: {v}' for k, v in config.down_headers.items()]

    if os.path.exists(part_file) and not replace:
        outputs.normal_info('Previously Downloaded part found.')
        wmode = 'ab'
        curl_header.append(
            config.resume_t.substitute(size=os.path.getsize(part_file)))
    else:
        wmode = 'wb'
    c.setopt(pycurl.HTTPHEADER, curl_header)
    try:
        with open(part_file, wmode) as writer:
            c.setopt(pycurl.WRITEDATA, writer)
            c.perform()
            c.close()
    except (KeyboardInterrupt, pycurl.error) as e:
        c.close()
        outputs.error_info(f"Download Failed {e}")
        raise SystemExit

    os.rename(part_file, filepath)
Ejemplo n.º 3
0
def download_m3u8(url, filepath, replace=False):
    if os.path.exists(filepath) and not replace:
        outputs.warning_info('File already downloaded, skipping.')
        return
    part_file = f'{filepath}.part'
    media = m3u8.load(url)
    total = len(media.segments)
    with open(part_file, 'wb') as writer:
        c = pycurl.Curl()
        curl_header = [f'{k}: {v}' for k, v in config.down_headers.items()]
        c.setopt(pycurl.HTTPHEADER, curl_header)
        c.setopt(pycurl.WRITEDATA, writer)
        try:
            for i, f in enumerate(media.segments):
                uri = f.absolute_uri
                c.setopt(pycurl.URL, uri)
                c.perform()
                outputs.normal_info('\rDownloaded :',
                                    f'{(i+1)*100//total}% ({i+1} of {total})',
                                    end="")
            c.close()
        except (KeyboardInterrupt, pycurl.error) as e:
            c.close()
            raise SystemExit(f"Download Failed {e}")
    outputs.normal_info()
    os.rename(part_file, filepath)
Ejemplo n.º 4
0
 def search_results(s):
     all_res = s.find("ul", {"class": "items"})
     for list_item in all_res.find_all("li"):
         an = list_item.p.a["href"].split("/")[-1]
         utils.write_cache(an, append=True)
         outputs.normal_info(an, end="  \t")
         outputs.normal_info(list_item.p.a.text)
Ejemplo n.º 5
0
def anime_log(args):
    log_args = dict()
    if len(args) == 0:
        pass
    elif args[0].isnumeric():
        log_args["number"] = int(args[0])
    else:
        log_args["pattern"] = re.compile(args[0])
        if len(args) == 2:
            log_args["number"] = int(args[1])
    logs = utils.read_log(**log_args)
    ongoing = utils.read_log(logfile=config.ongoingfile)
    if len(logs) == 0:
        if len(args) == 0:
            outputs.warning_info("No log entries found.")
        else:
            outputs.prompt_val("Log entries not found for arguments", args[0],
                               "error")
        return
    outputs.bold_info("Watched\t\tAnime Name")
    for k, log in logs.items():
        outputs.normal_info(utils.Log(log).show(), end=" ")
        if k in ongoing:
            outputs.warning_tag("TRACKED", end="")
        outputs.normal_info()
Ejemplo n.º 6
0
def anime_info(args):
    name, _ = read_args(args, episodes=False)
    soup = utils.get_soup(anime_source_module.get_anime_url(name))
    info = soup.find("div", {"class": "anime_info_body"})
    h = html2text.HTML2Text()
    h.ignore_links = True
    for t in info.find_all("p", {"class": "type"}):
        outputs.normal_info(h.handle(t.decode_contents()), end="")
Ejemplo n.º 7
0
def anime_info(args):
    name = read_args(args, episodes=False)
    soup = utils.get_soup(gogoanime.get_anime_url(name))
    info = soup.find('div', {'class': 'anime_info_body'})
    h = html2text.HTML2Text()
    h.ignore_links = True
    for t in info.find_all('p', {'class': 'type'}):
        outputs.normal_info(h.handle(t.decode_contents()), end="")
Ejemplo n.º 8
0
def set_quality(quality):
    if quality.isnumeric():
        config.QUALITY_PREFERENCE = int(quality)
    elif quality.isalnum():
        if re.match(r'[0-9]+p', quality):
            config.QUALITY_PREFERENCE = int(quality[:-1])
        else:
            outputs.prompt_val('Invalid quality format', quality, 'error')
    else:
        outputs.normal_info(f'Current quality: {quality}')
Ejemplo n.º 9
0
def set_quality(quality):
    if quality.isnumeric():
        config.video_quality = int(quality)
    elif quality.isalnum():
        if re.match(r"[0-9]+p", quality):
            config.video_quality = int(quality[:-1])
        else:
            outputs.prompt_val("Invalid quality format", quality, "error")
    else:
        outputs.normal_info(f"Current quality: {quality}")
Ejemplo n.º 10
0
 def onecmd(self, ind):
     if ind == 'EOF':
         outputs.normal_info()
         return
     try:
         return super().onecmd(ind)
     except (SystemExit, KeyboardInterrupt):
         outputs.normal_info()
     except (ConnectionError, ConnectTimeout):
         outputs.error_info('Slow or no Internet connection. Try again.')
Ejemplo n.º 11
0
 def do_history(self, inp):
     """show the history of the commands.
     """
     try:
         import readline
         for j in range(1, readline.get_current_history_length() + 1):
             h = readline.get_history_item(j)
             if re.match(inp, h):
                 outputs.normal_info(f'{j:3d}:  {h}')
     except ImportError:
         pass
Ejemplo n.º 12
0
def anime_log(args):
    outputs.bold_info('Watched\t\tAnime Name')
    log_args = dict()
    if len(args) == 0:
        pass
    elif args[0].isnumeric():
        log_args['number'] = int(args[0])
    else:
        log_args['pattern'] = re.compile(args[0])
        if len(args) == 2:
            log_args['number'] = int(args[1])
    logs = utils.read_log(**log_args).items()
    for k, v in logs:
        outputs.normal_info(f'{v}\t\t{k}')
Ejemplo n.º 13
0
 def default(self, inp):
     try:
         if 'import' in inp:
             return self.import_mod(inp)
         if '=' in inp:
             exec(inp, {}, shell_commands)
         else:
             retval = eval(inp, {}, shell_commands)
             outputs.success_tag('RET:', end=' ')
             outputs.normal_info(retval)
     except Exception as e:
         outputs.error_tag('ERR:', end=' ')
         outputs.normal_info(e)
         traceback.print_exc(chain=False)
Ejemplo n.º 14
0
def list_episodes(args):
    name, _ = read_args(args, episodes=False)
    available_rng = anime_source_module.get_episodes_range(anime_source_module.get_anime_url(name))
    if len(args) == 2:
        _, episodes = read_args(args)
        eps = set(episodes)
        avl_eps = set(utils.extract_range(available_rng))
        res = eps.intersection(avl_eps)
        available_rng = utils.compress_range(res)
    outputs.prompt_val("Available episodes", available_rng)
    log = utils.Log(utils.read_log(name))
    outputs.prompt_val("Watched episodes", log.eps, "success", end=' ')
    outputs.normal_info(log.last_updated_fmt)
    utils.write_cache(name)
Ejemplo n.º 15
0
 def do_history(self, inp):
     """show the history of the commands.
     """
     if not self.in_cmdloop:
         for j, h in enumerate(open(config.historyfile), start=1):
             h = h.strip()
             if re.match(inp, h):
                 outputs.normal_info(f'{j:3d}:  {h}')
         return
     try:
         import readline
         for j in range(1, readline.get_current_history_length() + 1):
             h = readline.get_history_item(j)
             if re.match(inp, h):
                 outputs.normal_info(f'{j:3d}:  {h}')
     except ImportError:
         pass
Ejemplo n.º 16
0
def list_local_episodes(args):
    in_dict = utils.get_local_episodes(*args)
    out_dict = dict()
    for anime, eps in in_dict.items():
        new_eps = utils.compress_range(utils.extract_range(eps))
        if new_eps != "":
            out_dict[anime] = new_eps
    empties = set(in_dict).difference(set(out_dict))
    if len(out_dict) == 0:
        outputs.warning_info("No local entries found.")
    else:
        outputs.bold_info("Episodes\tAnime Name")
        for k, v in out_dict.items():
            outputs.normal_info(f"{v}\t\t{k}")
    if len(empties) > 0:
        outputs.warning_info("Directories without Episodes:")
        outputs.warning_info(", ".join(empties))
Ejemplo n.º 17
0
def check_anime(args):
    name, episodes = read_args(args)
    unavail_eps = []
    for e in episodes:
        url = anime_source_module.get_episode_url(name, e)
        outputs.normal_info("Testing:", url)
        durl, ext = anime_source_module.get_direct_video_url(url)
        if not durl:
            raise SystemExit("Url for the file not found")
        if not os.path.exists(
                os.path.join(config.anime_dir, f"./{name}/ep{e:02d}.{ext}")):
            unavail_eps.append(e)
    if len(unavail_eps) == 0:
        outputs.success_info(
            "All episodes in given range are locally available")
    else:
        outputs.prompt_val("Missing episodes",
                           utils.compress_range(unavail_eps), "warning")
Ejemplo n.º 18
0
def check_anime(args):
    name, episodes = read_args(args)
    unavail_eps = []
    for e in episodes:
        url = gogoanime.get_episode_url(name, e)
        outputs.normal_info('Testing:', url)
        durl, ext = gogoanime.get_direct_video_url(url)
        if not durl:
            raise SystemExit('Url for the file not found')
        if not os.path.exists(
                os.path.join(config.anime_dir, f'./{name}/ep{e:02d}.{ext}')):
            unavail_eps.append(e)
    if len(unavail_eps) == 0:
        outputs.success_info(
            'All episodes in given range are locally available')
    else:
        outputs.prompt_val('Missing episodes',
                           utils.compress_range(unavail_eps), 'warning')
Ejemplo n.º 19
0
def display_anime_eps_list(animes_dict):
    tracklist = read_log(logfile=config.ongoingfile)
    log = read_log()
    clear_cache()
    for name, ep in animes_dict:
        outputs.normal_info(f"{name} : ep-{ep}" if ep else name, end=" ")
        write_cache(name, append=True)
        if name in tracklist:
            watched = extract_range(Log(tracklist[name]).eps)
            if not ep:
                outputs.warning_tag("TRACKED", end="")
            elif int(ep) in watched:
                outputs.warning_tag("WATCHED", end="")
            else:
                outputs.success_tag("NEW", end="")
        elif name in log:
            outputs.success_tag("LOGGED", end="")

        outputs.normal_info()
Ejemplo n.º 20
0
def continue_play(args, play_func=play_anime):
    name, _ = read_args(args, episodes=False)
    log = utils.Log(utils.read_log().get(name))
    watch_later = utils.read_log(name, logfile=config.watchlaterfile)
    if watch_later:
        episodes = utils.extract_range(utils.Log(watch_later).eps)
    else:
        _, episodes = read_args(args)
    outputs.prompt_val("Watched",
                       log._eps, "success", end='\t')
    outputs.normal_info(log.last_updated_fmt)
    if not log.eps:
        last = 0
    else:
        last = int(re.split('-|,', log.eps)[-1])
    to_play = utils.compress_range(filter(lambda e: e > last, episodes))
    if to_play.strip():
        play_func([name, to_play])
    else:
        unsave_anime(name)
Ejemplo n.º 21
0
def read_args(args, episodes=True, verbose=True):
    if len(args) == 0:
        name = utils.read_cache()
    elif len(args) == 1 and args[0].isnumeric():
        name = utils.read_cache(int(args[0]))
        if verbose:
            outputs.prompt_val("Name", name)
    elif "/" in args[0]:
        name = args[0].strip("/").split("/")[-1]
    else:
        name = anime_source_module.process_anime_name(args[0].strip('"'))
        if not anime_source_module.verify_anime_exists(name):
            outputs.prompt_val("Anime with the name doesn't exist", args[0],
                               "error")
            raise SystemExit

    if not name:
        outputs.error_info("Numbers choice invalid, or invalid context.")
        raise SystemExit

    if len(args) <= 1:
        if episodes:
            if verbose:
                outputs.warning_info("Episodes range not given defaulting to all")
            available_rng = anime_source_module.get_episodes_range(
                anime_source_module.get_anime_url(name))
            if verbose:
                outputs.prompt_val("Available episodes", available_rng)
            eps = utils.extract_range(available_rng)
        else:
            eps = None
    elif len(args) == 2:
        eps = utils.extract_range(args[1])
    else:
        outputs.error_info("Too many arguments.\n")
        outputs.normal_info(__doc__)
        raise SystemExit
    return name, eps
Ejemplo n.º 22
0
def read_args(args, episodes=True, verbose=True):
    if len(args) == 0:
        name = utils.read_cache()
    elif args[0].isnumeric():
        name = utils.read_cache(int(args[0]))
        if verbose:
            outputs.prompt_val('Name', name)
    elif '/' in args[0]:
        name = args[0].strip('/').split('/')[-1]
    else:
        name = gogoanime.process_anime_name(args[0])
        if not gogoanime.verify_anime_exists(name):
            outputs.prompt_val(f'Anime with the name doesn\'t exist', args[0],
                               'error')
            raise SystemExit

    if not name:
        outputs.error_info('Numbers choice invalid, or invalid context.')
        raise SystemExit

    if not episodes:
        return name
    if len(args) <= 1:
        if verbose:
            outputs.warning_info('Episodes range not given defaulting to all')
        available_rng = gogoanime.get_episodes_range(
            gogoanime.get_anime_url(name))
        if verbose:
            outputs.prompt_val('Available episodes', available_rng)
        episodes = utils.extract_range(available_rng)
    elif len(args) == 2:
        episodes = utils.extract_range(args[1])
    else:
        outputs.error_info('Too many arguments.\n')
        outputs.normal_info(__doc__)
        raise SystemExit
    return name, episodes
Ejemplo n.º 23
0
def verify_anime_exists(anime_name, verbose=False):
    if utils.read_log(anime_name) is not None:
        if verbose:
            outputs.normal_info(anime_name, 'LOG', reverse=True)
        return True
    elif anime_name in utils.read_cache(complete=True):
        if verbose:
            outputs.normal_info(anime_name, 'CACHE', reverse=True)
        return True
    elif utils.get_anime_path(anime_name, check=True)[0]:
        if verbose:
            outputs.normal_info(anime_name, 'LOCAL', reverse=True)
        return True
    elif utils.get_soup(get_anime_url(anime_name)) is not None:
        if verbose:
            outputs.normal_info(anime_name, 'SITE', reverse=True)
        return True
    else:
        return False
Ejemplo n.º 24
0
def stream_from_url(url, anime_name=None, episode=None, *, local=False):
    if not anime_name or not episode:
        anime_name, episode = anime_source_module.parse_url(url)
    if local:
        durl = url
        _, ext = os.path.splitext(durl)
    else:
        outputs.normal_info("Getting Streaming Link:", url)
        durl, ext = anime_source_module.get_direct_video_url(url)
        if not durl:
            outputs.error_info("Url for the file not found")
            raise SystemExit
    outputs.prompt_val("Stream link", durl, "success")
    try:
        if config.ext_player_confirm:
            choice = input(f"Open {config.ext_player} Player? <Y/n>")
            if choice == "" or choice.lower() == "y":
                pass
            else:
                raise SystemExit
        else:
            for i in range(11):
                outputs.normal_info(
                    f"\rOpening External Player in: {1-i/10:1.1f} sec.",
                    end="")
                time.sleep(0.1)
            outputs.normal_info()
        retval = player_module.play_media(
            durl, title=f"ANIME:{anime_name}:ep-{episode}{ext}")
        if retval:
            utils.write_log(anime_name, episode)
            utils.update_tracklist(anime_name, episode)
            utils.write_cache(anime_name)
            utils.update_watchlater(anime_name, episode)
            return
    except KeyboardInterrupt:
        outputs.warning_info("\nInturrupted, Exiting...")
        raise SystemExit
    outputs.normal_info()
Ejemplo n.º 25
0
def get_updates(anime_name=''):
    """Check and display the updates on the tracked anime list."""
    updates = anime_updates(anime_name)
    if len(updates) == 0:
        outputs.normal_info("No new episodes released.")
        return
    if anime_name == '':
        outputs.prompt_val(f'anime(s) has new episodes.',
                           len(updates),
                           'success',
                           sep=" ",
                           reverse=True)
        outputs.normal_info('-' * 50)
    for anime, episodes in updates.items():
        outputs.normal_info(anime, end='\n\t')
        outputs.success_tag(len(episodes), end=' ')
        outputs.prompt_val('new episodes', utils.compress_range(episodes),
                           'success')
Ejemplo n.º 26
0
def get_updates(anime_name=""):
    """Check and display the updates on the tracked anime list."""
    updates = anime_updates(anime_name)
    if len(updates) == 0:
        outputs.normal_info("No new episodes released.")
        return
    if anime_name == "":
        outputs.prompt_val(
            "anime(s) has new episodes.",
            len(updates),
            "success",
            sep=" ",
            reverse=True,
        )
        outputs.normal_info("-" * 50)
    for anime, episodes in updates.items():
        outputs.normal_info(anime, end="\n\t")
        outputs.success_tag(len(episodes), end=" ")
        outputs.prompt_val("new episodes", utils.compress_range(episodes),
                           "success")
Ejemplo n.º 27
0
def stream_from_url(url, anime_name=None, episode=None):
    if not anime_name or not episode:
        anime_name, episode = gogoanime.parse_gogo_url(url)
    outputs.normal_info('Getting Streaming Link:', url)
    durl, ext = gogoanime.get_direct_video_url(url)
    if not durl:
        outputs.error_info('Url for the file not found')
        raise SystemExit
    if ext == 'm3u8':
        durl = utils.get_m3u8_stream(durl)
    outputs.prompt_val(f'Stream link', durl, 'success')
    try:
        for i in range(11):
            outputs.normal_info(
                f'\rOpening External Player in: {1-i/10:1.1f} sec.', end='')
            time.sleep(0.1)
    except KeyboardInterrupt:
        outputs.warning_info('\nInturrupted, Exiting...')
        raise SystemExit
    outputs.normal_info()
    while True:
        t1 = time.time()
        ret_val = subprocess.call(" ".join(config.ext_player_command + [durl]),
                                  shell=True)
        if ret_val == 2:  # mpv error code
            outputs.error_info('Couldn\'t open the stream.')
            if input("retry?<Y/n>") == '':
                continue
            else:
                raise SystemExit
        if (time.time() - t1) > (
                5 * 60
        ):  # 5 minutes watchtime at least, otherwise consider it unwatched.
            # TODO: use direct communication with mpv to know if episode was watched.
            utils.write_log(anime_name, episode)
            utils.update_tracklist(anime_name, episode)
            utils.write_cache(anime_name)
        return
Ejemplo n.º 28
0
 def do_help(self, topic):
     if len(topic) == 0:
         import __init__
         outputs.normal_info(__init__.__doc__)
     super().do_help(topic)
Ejemplo n.º 29
0
def list_saved_anime():
    anime_list = utils.read_log(logfile=config.watchlaterfile)
    for anime, log in anime_list.items():
        outputs.normal_info(utils.Log(log).show())
Ejemplo n.º 30
0
def list_tracked():
    anime_list = utils.read_log(logfile=config.ongoingfile)
    for anime, log in anime_list.items():
        outputs.normal_info(utils.Log(log).show())