コード例 #1
0
 def complete_local(self, text, line, *ignored):
     m = re.match(r'local +([0-9a-z-]+) +', line)
     if m:
         name = m.group(1)
         eps = utils.get_local_episodes(name)[name]
         return [utils.compress_range(utils.extract_range(eps))]
     return self.complete_listlocal(text, line, *ignored)
コード例 #2
0
def anime_updates(anime_name=''):
    """Check and display the updates on the tracked anime list."""
    if anime_name == '':
        anime_list = utils.read_log(logfile=config.ongoingfile)
    else:
        anime_list = {
            anime_name:
            utils.read_log(anime_name=anime_name, logfile=config.ongoingfile)
        }
    updates = {}
    for anime, episodes in anime_list.items():
        new_episodes = gogoanime.get_episodes_range(
            gogoanime.get_anime_url(anime))
        new = set(utils.extract_range(new_episodes)).difference(
            set(utils.extract_range(episodes)))
        if len(new) > 0:
            updates[anime] = new
    return updates
コード例 #3
0
def anime_updates(anime_name=""):
    """Check and display the updates on the tracked anime list."""
    if anime_name == "":
        anime_list = utils.read_log(logfile=config.ongoingfile)
    else:
        anime_list = {
            anime_name:
            utils.read_log(anime_name=anime_name, logfile=config.ongoingfile)
        }
    updates = {}
    for anime, log in anime_list.items():
        episodes = log.split()[1]
        new_episodes = anime_source_module.get_episodes_range(
            anime_source_module.get_anime_url(anime))
        new = set(utils.extract_range(new_episodes)).difference(
            set(utils.extract_range(episodes)))
        if len(new) > 0:
            updates[anime] = new
    return updates
コード例 #4
0
def list_episodes(args):
    name = read_args(args, episodes=False)
    available_rng = gogoanime.get_episodes_range(gogoanime.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(f'Available episodes', available_rng)
    outputs.prompt_val(f'Watched episodes', utils.read_log(name), 'success')
    utils.write_cache(name)
コード例 #5
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
コード例 #6
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)
コード例 #7
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
コード例 #8
0
def get_episodes_range(anime_url):
    soup = utils.get_soup(anime_url)
    if not soup:
        return []
    rngs_obj = soup.find_all('a', ep_end=True, ep_start=True)
    total_rng = []
    for r in rngs_obj:
        rng = r.text
        rngs = rng.split('-')
        if rngs[0] == '0':
            rngs[0] = '1'
        total_rng.append('-'.join(rngs))
    text = ','.join(total_rng)
    parsed_rng = utils.compress_range(utils.extract_range(text))
    return parsed_rng
コード例 #9
0
def save_anime(args):
    """Put the anime into watch later list."""
    anime_name, eps = read_args(args)
    watched = utils.read_log(anime_name)
    if watched:
        watched_eps = utils.extract_range(utils.Log(watched).eps)
    else:
        watched_eps = []
    save_eps = set(eps).difference(set(watched_eps))
    if not save_eps:
        outputs.warning_info('Already watched the provided episodes.')
        return
    utils.write_log(anime_name,
                    utils.compress_range(save_eps),
                    append=True,
                    logfile=config.watchlaterfile)
コード例 #10
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))
コード例 #11
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)
コード例 #12
0
def generate(general_struct,
             filter_chain_list,
             class_id_to_name_dict,
             img_name_to_class_id_dict,
             yolo_version,
             draw_bounding_boxes=False,
             no_yolo_output=False):
    """
        Generate images with given settings in general struct and filter chain list. With the assignment of each object
        image to an object class this method also creates output files for YOLO.

        :param general_struct: object containing general settings
        :param filter_chain_list: list of filter_chain objects containing all settings for every set filter
        :param class_id_to_name_dict: dict assigning object class IDs to its corresponding class name
        :param img_name_to_class_id_dict: dict assigning each image to its object class ID
        :param yolo_version: number of YOLO version for which the YOLO output files should be created
        :param draw_bounding_boxes: boolean value specifying whether bounding boxes should be drawn around object
        :param no_yolo_output: boolean value specifying whether no YOLO output files should be created
        :return:
    """
    # get destination resolution
    dest_res_x = general_struct.output_width
    dest_res_y = general_struct.output_height

    # collect input images
    objects_path = general_struct.object_path
    obj_img_filename_list = utils.list_directory(objects_path,
                                                 [".jpg", ".png"])

    # setup yolo object
    yolo_generator = YoloGenerator(yolo_version=yolo_version)

    # set counter for filename of stored images
    img_counter = 1

    # list of all objects
    obj_list = []

    # do operations for every object
    for filter_chain in filter_chain_list:
        for obj_img_filename in obj_img_filename_list:
            # TODO: following outprint should be in the next upper loop and here should be "Generate image x" or smth
            logging.info("Process filter chain number %d:" % img_counter)
            output_filename = str(img_counter)
            obj_list.clear()  # list of all objects

            # get number of objects which should be placed onto each generated image
            num_obj_per_img_min, num_obj_per_img_max = utils.extract_range(
                filter_chain.num_obj_per_img)
            if num_obj_per_img_min == num_obj_per_img_max:
                num_obj_per_img = int(num_obj_per_img_min)
            else:
                num_obj_per_img = random.randint(num_obj_per_img_min,
                                                 num_obj_per_img_max)
            logging.info(
                "   => %s objects get placed onto each generated image" %
                num_obj_per_img)

            #############################################################
            # BACKGROUND FILTERS
            # get resolution out of resolution filter
            if filter_chain.resolution:
                res_x, res_y = apply_resolution_filter(filter_chain.resolution)
            else:
                res_x = dest_res_x
                res_y = dest_res_y

            # apply all filters aiming on background
            bg_img = apply_filters_on_background(
                general_struct.background_path, filter_chain, res_x, res_y)

            #############################################################
            # OBJECTS FILTERS

            # read in main object image
            obj_img_path = os.path.abspath(
                os.path.join(general_struct.object_path, obj_img_filename))
            category_number = img_name_to_class_id_dict[obj_img_filename]
            main_obj = Object(filename=obj_img_filename,
                              image=img_processing.import_image(obj_img_path),
                              category=category_number)
            obj_list.append(main_obj)
            logging.info("   => object image path \'%s\'" % obj_img_filename)

            # read in other randomly selected object images including their labels
            for x in range(num_obj_per_img - 1):
                random_idx = random.randint(0, len(obj_img_filename_list) - 1)
                obj_img_path = os.path.abspath(
                    os.path.join(general_struct.object_path,
                                 obj_img_filename_list[random_idx]))
                category_number = img_name_to_class_id_dict[
                    obj_img_filename_list[random_idx]]
                obj = Object(filename=obj_img_filename_list[random_idx],
                             image=img_processing.import_image(obj_img_path),
                             category=category_number)
                logging.info("   => random object image path \'%s\'" %
                             obj_img_path)
                obj_list.append(obj)

            # apply all object filters on the generated objects
            merged_img, obj_list = apply_filters_on_objects(
                obj_list, filter_chain, bg_img, res_x, res_y)

            #############################################################
            # OBJECT AND BACKGROUND FILTERS

            # before applying all other filters, insert additional objects in front of objects
            for obj in obj_list:
                # overlap filter applied onto fore- and background
                if filter_chain.overlap:
                    if filter_chain.overlap.type == 1:  # type 1: in front of objects
                        merged_img = apply_overlap_filter(
                            filter_chain.overlap, obj, merged_img)
                    elif filter_chain.overlap.type != 0:
                        logging.error(
                            "ERROR: Unknown overlap filter type (%s)" %
                            filter_chain.overlap.type)
                        sys.exit(-1)

            # apply all filters aiming for object and background
            merged_img = apply_filters_on_objects_and_background(
                merged_img, filter_chain)

            #############################################################

            # draw bounding box
            if draw_bounding_boxes:
                for obj in obj_list:
                    img_processing.draw_bounding_box(merged_img, obj.bbox)

            # save result image
            img_processing.save_image(merged_img, general_struct.output_path,
                                      output_filename + '.jpg')

            # create YOLO information for every generated image with category numbers and bounding boxes of objects
            yolo_generator.generate_yolo_output(obj_list, merged_img.shape[:2],
                                                general_struct.output_path,
                                                output_filename)

            logging.info("... done processing filter chain number %s\n" %
                         img_counter)
            img_counter += 1

    # create text files 'train.txt', 'obj.names' and 'obj.data' for YOLO inside the output directory
    if not no_yolo_output:
        yolo_generator.generate_train_data_file(general_struct.output_path)
        yolo_generator.generate_obj_names_file(general_struct.output_path,
                                               class_id_to_name_dict)
        yolo_generator.generate_obj_data_file(
            general_struct.output_path, len(class_id_to_name_dict.keys()))
        yolo_generator.generate_yolo_obj_cfg(general_struct.output_path,
                                             len(class_id_to_name_dict.keys()))

    return