Beispiel #1
0
def build_related_works(
    work: Work, relations: List[Tuple[AniListEntry, AniListRelationType]]
) -> List[RelatedWork]:
    related_works = [
        insert_work_into_database_from_anilist(work_related)
        for work_related, relation_type in relations
    ]

    existing_relations = RelatedWork.objects.filter(
        parent_work=work, child_work__in=related_works)
    existing_child_works = set(
        existing_relations.values_list('child_work__pk', flat=True))
    existing_parent_works = set(
        existing_relations.values_list('parent_work__pk', flat=True))

    new_relations = [
        RelatedWork(parent_work=work,
                    child_work=related_works[index],
                    type=relation_type.value)
        for index, (entry, relation_type) in enumerate(relations)
        if related_works[index] is not None and related_works[index].pk not in
        existing_child_works and work.pk not in existing_parent_works
    ]

    RelatedWork.objects.bulk_create(new_relations)

    return new_relations
Beispiel #2
0
def build_related_works(work: Work, relations: List[AniListRelation],
                        ignored_related_ids: Set, ignored_works_ids: Set,
                        ignore_duplicates: bool) -> List[RelatedWork]:
    """
    Insert RelatedWork objects for a given Work when required into Mangaki's database.
    This also inserts the related works into the database when they don't exist.
    :param work: a work
    :param relations: a list of related works, with their AniList ID and the relation type
    :type work: Work
    :type relations: List[Tuple[int, AniListRelationType]]
    :return: a list of RelatedWork objects that were inserted in Mangaki's database
    :rtype: List[RelatedWork]
    """

    if not relations:
        return []

    # It's okay here to create an instance, it'll be shared due to the Singleton pattern used on AniList.
    client = AniList()
    new_ids = {relation.related_id for relation in relations}
    related_works = {
        relation.related_id: insert_work_into_database_from_anilist(
            client.get_work(search_id=relation.related_id),
            ignored_related_ids=ignored_related_ids | new_ids,
            ignored_works_ids=ignored_works_ids,
            ignore_duplicates=ignore_duplicates)
        if relation.related_id not in ignored_related_ids else None
        for relation in relations
    }

    existing_relations = RelatedWork.objects.filter(
        parent_work=work, child_work__in=filter(None, related_works.values()))
    existing_child_works = set(
        existing_relations.values_list('child_work__pk', flat=True))
    existing_parent_works = set(
        existing_relations.values_list('parent_work__pk', flat=True))

    new_relations = {
        (work.id, related_works[relation.related_id].id,
         relation.relation_type.name.lower()):
        RelatedWork(parent_work=work,
                    child_work=related_works[relation.related_id],
                    type=relation.relation_type.name.lower())
        for relation in relations
        if related_works[relation.related_id] is not None
        and related_works[relation.related_id].pk not in existing_child_works
        and work.pk not in existing_parent_works and
        work.pk != related_works[relation.related_id].pk  # no self reference.
    }

    RelatedWork.objects.bulk_create(list(new_relations.values()))

    return list(new_relations.values())
Beispiel #3
0
    def _build_related_animes(self,
                              work: Work,
                              related_animes: Dict[int, Dict[str, str]]) -> List[RelatedWork]:
        anidb_aids = related_animes.keys()

        # Fill the Work database with missing work items and retrieve existing ones
        # Note : these works won't be filled with data, they'll have to be updated afterwards
        existing_works = Work.objects.filter(anidb_aid__in=anidb_aids)
        existing_anidb_aids = set(existing_works.values_list('anidb_aid', flat=True))

        new_works = []
        for anidb_aid in anidb_aids:
            if anidb_aid not in existing_anidb_aids:
                new_works.append(
                    Work(
                        title=related_animes[anidb_aid]['title'],
                        category=self.anime_category,
                        anidb_aid=anidb_aid
                    )
                )

        works = [work for work in existing_works]
        works.extend(Work.objects.bulk_create(new_works))

        # Add relations between works if they don't yet exist
        existing_relations = RelatedWork.objects.filter(child_work__in=works, parent_work=work)
        existing_child_works = set(existing_relations.values_list('child_work__pk', flat=True))
        existing_parent_works = set(existing_relations.values_list('parent_work__pk', flat=True))

        new_relations = []
        for child_work in works:
            if child_work.pk not in existing_child_works and work.pk not in existing_parent_works:
                new_relations.append(
                    RelatedWork(
                        parent_work=work,
                        child_work=child_work,
                        type=related_animes[child_work.anidb_aid]['type']
                    )
                )

        RelatedWork.objects.bulk_create(new_relations)

        return new_relations
Beispiel #4
0
def build_related_works(
        work: Work,
        relations: List[Tuple[int, AniListRelationType]]) -> List[RelatedWork]:
    """
    Insert RelatedWork objects for a given Work when required into Mangaki's database.
    This also inserts the related works into the database when they don't exist.
    :param work: a work
    :param relations: a list of related works, with their AniList ID and the relation type
    :type work: Work
    :type relations: List[Tuple[int, AniListRelationType]]
    :return: a list of RelatedWork objects that were inserted in Mangaki's database
    :rtype: List[RelatedWork]
    """

    if not relations:
        return []

    related_works = [
        insert_work_into_database_from_anilist(
            client.get_work(search_id=related_id))
        for related_id, relation_type in relations
    ]

    existing_relations = RelatedWork.objects.filter(
        parent_work=work, child_work__in=related_works)
    existing_child_works = set(
        existing_relations.values_list('child_work__pk', flat=True))
    existing_parent_works = set(
        existing_relations.values_list('parent_work__pk', flat=True))

    new_relations = [
        RelatedWork(parent_work=work,
                    child_work=related_works[index],
                    type=relation_type.value)
        for index, (entry, relation_type) in enumerate(relations)
        if related_works[index] is not None and related_works[index].pk not in
        existing_child_works and work.pk not in existing_parent_works
    ]

    RelatedWork.objects.bulk_create(new_relations)

    return new_relations