Exemple #1
0
    def _match_tags(parent_model,
                    child_model,
                    term,
                    options,
                    capture=db.model_name(db.Taggable)):
        get_model = database_cmd.GetModelClass()
        parent_model = get_model.run(parent_model)
        child_model = get_model.run(child_model)

        match_string = PartialModelFilter._match_string_column
        term = ParseTerm().run(term)
        ids = set()

        col_on_parent = db.relationship_column(parent_model, child_model)
        col_on_child = db.relationship_column(child_model, db.NamespaceTags)
        col_tag = db.relationship_column(db.NamespaceTags, db.Tag)
        s = constants.db_session()
        q = s.query(parent_model.id)
        if term.namespace:
            col_ns = db.relationship_column(db.NamespaceTags, db.Namespace)
            items = q.join(col_on_parent).join(col_on_child).join(col_ns).join(
                col_tag).filter(
                    db.and_op(
                        match_string(db.Namespace.name,
                                     term.namespace,
                                     options,
                                     whole=True),
                        match_string(db.Tag.name, term.tag, options))).all()
        else:
            items = q.join(col_on_parent).join(col_on_child).join(
                col_tag).filter(match_string(db.Tag.name, term.tag,
                                             options)).all()

        ids.update(x[0] for x in items)
        return ids
Exemple #2
0
def get_related_count(item_type: enums.ItemType = enums.ItemType.Gallery,
                      item_id: int = 0,
                      related_type: enums.ItemType = enums.ItemType.Page):
    """
    Get count of items related to given item

    Args:
        item_type: parent item
        item_id: id of parent item
        related_type: child item

    Returns:
        ```
        { 'id': int, 'count': int }
        ```
    """
    item_type = enums.ItemType.get(item_type)
    related_type = enums.ItemType.get(related_type)

    _, parent_model = item_type._msg_and_model()
    child_msg, child_model = related_type._msg_and_model()

    col = db.relationship_column(parent_model, child_model)
    if not col:
        raise exceptions.APIError(
            utils.this_function(),
            "{} has no relationship with {}".format(related_type, item_type))

    s = constants.db_session()
    count = s.query(
        child_model.id).join(col).filter(parent_model.id == item_id).count()
    return message.Identity('count', {'id': item_id, 'count': count})
Exemple #3
0
    def _match_parody(parent_model, child_model, term, options,
                      capture=db.model_name(db.Parody)):
        get_model = database_cmd.GetModelClass()
        parent_model = get_model.run(parent_model)
        child_model = get_model.run(child_model)

        match_string = PartialModelFilter._match_string_column
        term = ParseTerm().run(term)
        ids = set()

        if term.namespace.lower() == 'parody' or not term.namespace:
            col_on_parent = db.relationship_column(parent_model, child_model)

            s = constants.db_session()
            q = s.query(parent_model.id)
            if col_on_parent:
                q = q.join(col_on_parent)
            ids.update(
                x[0] for x in q.join(
                    child_model.names).filter(
                    match_string(
                        db.ParodyName.name,
                        term.tag,
                        options)).all())
        return ids
Exemple #4
0
    def _match_gallery(parent_model, child_model, term,
                       options, capture=db.model_name(db.Gallery)):
        get_model = database_cmd.GetModelClass()
        parent_model = get_model.run(parent_model)
        child_model = get_model.run(child_model)

        match_string = PartialModelFilter._match_string_column
        match_int = PartialModelFilter._match_integer_column
        term = ParseTerm().run(term)
        ids = set()

        col_on_parent = db.relationship_column(parent_model, child_model)
        s = constants.db_session()
        q = s.query(parent_model.id)
        if col_on_parent:
            q = q.join(col_on_parent)
        if term.namespace:
            lower_ns = term.namespace.lower()
            if lower_ns == 'path':
                ids.update(x[0] for x in q.filter(match_string(db.Gallery.path,
                                                               term.tag,
                                                               options)).all())
            elif lower_ns in ("rating", "stars"):
                ids.update(x[0] for x in q.filter(match_int(db.Gallery.rating,
                                                            term.tag,
                                                            options)).all())

        return ids
Exemple #5
0
    def _match_namemixin(parent_model,
                         child_model,
                         term,
                         options,
                         capture=[
                             db.model_name(x) for x in _models()
                             if issubclass(x, (db.NameMixin, db.Url))
                         ]):
        get_model = database_cmd.GetModelClass()
        parent_model = get_model.run(parent_model)
        child_model = get_model.run(child_model)
        match_string = PartialModelFilter._match_string_column
        term = ParseTerm().run(term)
        ids = set()

        if term.namespace.lower() == child_model.__name__.lower(
        ) or not term.namespace:
            col_on_parent = db.relationship_column(parent_model, child_model)
            s = constants.db_session()
            q = s.query(parent_model.id)
            if col_on_parent:
                q = q.join(col_on_parent)
            ids.update(x[0] for x in q.filter(
                match_string(child_model.name, term.tag, options)).all())
        return ids
Exemple #6
0
def get_related_items(
    item_type: enums.ItemType = enums.ItemType.Gallery,
    item_id: int = 0,
    related_type: enums.ItemType = enums.ItemType.Page,
    limit: int = 100,
    offset: int = None,
):
    """
    Get item related to given item

    Args:
        item_type: parent item
        item_id: id of parent item
        related_type: child item
        limit: limit the amount of items returned
        offset: offset the results by n items

    Returns:
        .. code-block:: guess

            [
                related item message object,
                ...
            ]
    """
    if not item_id:
        raise exceptions.APIError(utils.this_function(),
                                  "item_id must be a valid item id")
    item_type = enums.ItemType.get(item_type)
    related_type = enums.ItemType.get(related_type)

    _, parent_model = item_type._msg_and_model()
    child_msg, child_model = related_type._msg_and_model()

    col = db.relationship_column(parent_model, child_model)
    if not col:
        raise exceptions.APIError(
            utils.this_function(),
            "{} has no relationship with {}".format(related_type, item_type))

    s = constants.db_session()
    q = s.query(child_model.id).join(col).filter(parent_model.id == item_id)
    if offset:
        q = q.offset(offset)
    item_ids = q.limit(limit).all()
    items = database_cmd.GetModelItems().run(child_model,
                                             {x[0]
                                              for x in item_ids})

    item_list = message.List(db.model_name(child_model), child_msg)
    [item_list.append(child_msg(x)) for x in items]
    return item_list
Exemple #7
0
    def _update_db(self, stale_cover, item_id, model, old_hash):
        log.d("Updating profile for database item", model)
        s = constants.db_session()
        cover = s.query(db.Profile).filter(
            db.and_op(db.Profile.data == old_hash,
                      db.Profile.size == stale_cover.size)).all()

        if len(cover) > 1:
            cover, *cover_ex = cover
            for x in cover_ex:
                s.delete(x)
        elif cover:
            cover = cover[0]

        new = False

        if cover:
            # sometimes an identical img has already been generated and exists so we shouldnt do anything
            fs = io_cmd.CoreFS(cover.path)
            if (cover.path != stale_cover.path) and fs.exists:
                fs.delete()
        else:
            cover = db.Profile()
            new = True

        cover.data = stale_cover.data
        cover.path = stale_cover.path
        cover.size = stale_cover.size

        if new or not s.query(db.Profile).join(
                db.relationship_column(model, db.Profile)).filter(
                    db.and_op(db.Profile.id == cover.id, model.id
                              == item_id)).scalar():
            log.d("Adding new profile to database item", model,
                  "()".format(item_id))
            i = s.query(model).get(item_id)
            i.profiles.append(cover)

        s.commit()
        self.next_progress()
Exemple #8
0
    def _match_namemixin(parent_model,
                         child_model,
                         term,
                         options,
                         capture=[
                             db.model_name(x) for x in _models()
                             if issubclass(x, db.NameMixin)
                         ]):
        get_model = database_cmd.GetModelClass()
        parent_model = get_model.run(parent_model)
        child_model = get_model.run(child_model)
        match_string = PartialModelFilter._match_string_column
        term = ParseTerm().run(term)
        ids = set()

        s = constants.db_session()

        col = db.relationship_column(parent_model, child_model)

        ids.update(x[0] for x in s.query(parent_model.id).join(col).filter(
            match_string(child_model.name, term, options)).all())

        return ids
Exemple #9
0
def _view_helper(item_type: enums.ItemType=enums.ItemType.Gallery,
                 search_query: str = "",
                 filter_id: int = None,
                 view_filter: enums.ViewType = enums.ViewType.Library,
                 item_id: int = None,
                 related_type: enums.ItemType = None,
                 search_options: dict = {},
                 ):
    if view_filter is not None:
        view_filter = enums.ViewType.get(view_filter)
    if related_type is not None:
        related_type = enums.ItemType.get(related_type)
    item_type = enums.ItemType.get(item_type)

    if search_options:
        search_option_names = [x.name for x in search_cmd._get_search_options()]
        for n in search_options:
            if n not in search_option_names:
                raise exceptions.APIError(utils.this_function(), "Invalid search option name '{}'".format(n))

    filter_op = []
    join_exp = []
    parent_model = None

    db_msg, db_model = item_type._msg_and_model(
        (enums.ItemType.Gallery, enums.ItemType.Collection, enums.ItemType.Grouping))

    if related_type:
        parent_model = db_model
        db_msg, db_model = related_type._msg_and_model(
            (enums.ItemType.Gallery, enums.ItemType.Page))

        col = db.relationship_column(parent_model, db_model)
        if not col:
            raise exceptions.APIError(
                utils.this_function(),
                "{} has no relationship with {}".format(
                    related_type,
                    item_type))

        if item_id is None:
            raise exceptions.APIError(utils.this_function(), "Missing id of parent item")

    if filter_id:
        if db_model != db.Gallery:
            g_col = db.relationship_column(db_model, db.Gallery)
            if not g_col:
                raise exceptions.APIError(
                    utils.this_function(),
                    "Cannot use {} because {} has no relationship with {}".format(
                        enums.ItemType.GalleryFilter,
                        related_type if related_type else item_type,
                        enums.ItemType.Gallery))
            join_exp.append(g_col)
        join_exp.append(db.relationship_column(db.Gallery, db.GalleryFilter))
        filter_op.append(db.GalleryFilter.id == filter_id)

    model_ids = None
    if not db_model == db.Page:
        model_ids = search_cmd.ModelFilter().run(db_model, search_query, search_options)

    metatag_name = None
    if view_filter == enums.ViewType.Favorite:
        metatag_name = db.MetaTag.names.favorite
    elif view_filter == enums.ViewType.Inbox:
        metatag_name = db.MetaTag.names.inbox
    elif view_filter == enums.ViewType.Trash:
        metatag_name = db.MetaTag.names.trash

    if metatag_name:
        if hasattr(db_model, "metatags"):
            filter_op.append(db.MetaTag.name == metatag_name)
            join_exp.append(db_model.metatags)
    elif view_filter == enums.ViewType.Library:
        if hasattr(db_model, "metatags"):
            filter_op.append(~db_model.metatags.any(db.MetaTag.name == db.MetaTag.names.inbox))
            filter_op.append(~db_model.metatags.any(db.MetaTag.name == db.MetaTag.names.trash))
    elif view_filter == enums.ViewType.All:
        if hasattr(db_model, "metatags"):
            filter_op.append(~db_model.metatags.any(db.MetaTag.name == db.MetaTag.names.trash))

    if related_type:
        filter_op.append(parent_model.id == item_id)
        join_exp.append(col)

    if len(filter_op) > 1:
        filter_op = db.and_op(*filter_op)
    elif filter_op:
        filter_op = filter_op[0]
    else:
        filter_op = None

    return view_filter, item_type, db_msg, db_model, model_ids, filter_op, join_exp, metatag_name