コード例 #1
0
ファイル: database.py プロジェクト: perfectquan/happypandax
def get_items(
    item_type: enums.ItemType = enums.ItemType.Gallery,
    limit: int = 100,
    offset: int = None,
):
    """
    Get a list of items

    Args:
        item_type: type of item to get
        limit: limit the amount of items returned
        offset: offset the results by n items

    Returns:
        .. code-block:: guess

            [
                item message object,
                ...
            ]
    """

    item_type = enums.ItemType.get(item_type)

    db_msg, db_model = item_type._msg_and_model()

    items = database_cmd.GetModelItems().run(db_model,
                                             limit=limit,
                                             offset=offset)

    item_list = message.List(db.model_name(db_model), db_msg)
    [item_list.append(db_msg(i)) for i in items]
    return item_list
コード例 #2
0
ファイル: ui.py プロジェクト: perfectquan/happypandax
def get_view_count(item_type: enums.ItemType=enums.ItemType.Gallery,
                   item_id: int = None,
                   related_type: enums.ItemType = None,
                   search_query: str = "",
                   search_options: dict = {},
                   filter_id: int = None,
                   view_filter: enums.ViewType = enums.ViewType.Library):
    """
    Get count of items in view

    Args:
        item_type: possible items are :py:attr:`.ItemType.Gallery`, :py:attr:`.ItemType.Collection`, :py:attr:`.ItemType.Grouping`
        search_query: filter item by search terms
        search_options: options to apply when filtering, see :ref:`Settings` for available search options
        filter_id: current :py:attr:`.ItemType.GalleryFilter` item id
        view_filter: type of view, set ``None`` to not apply any filter
        related_type: child item
        item_id: id of parent item

    Returns:
        .. code-block:: guess

            {
                'count' : int
            }
    """
    view_filter, item_type, db_msg, db_model, model_ids, filter_op, join_exp, metatag_name = _view_helper(
        item_type, search_query, filter_id, view_filter, item_id, related_type, search_options)

    return message.Identity('count', {'count': database_cmd.GetModelItems().run(
        db_model, model_ids, filter=filter_op, join=join_exp, count=True)})
コード例 #3
0
ファイル: database.py プロジェクト: perfectquan/happypandax
def get_item(item_type: enums.ItemType = enums.ItemType.Gallery,
             item_id: int = 0):
    """
    Get item

    Args:
        item_type: type of item to get
        item_id: id of item

    Returns:
        item message object
    """
    if not item_id:
        raise exceptions.APIError(
            utils.this_function(),
            f"A valid item id is required, not {item_id}")
    item_type = enums.ItemType.get(item_type)

    db_msg, db_model = item_type._msg_and_model()

    item = database_cmd.GetModelItems().run(db_model, {item_id})[0]
    if not item:
        raise exceptions.DatabaseItemNotFoundError(
            utils.this_function(),
            "'{}' with id '{}' was not found".format(item_type.name, item_id))

    return db_msg(item)
コード例 #4
0
    def main(self, gallery_or_id: db.Gallery=None, number: int=None, args=tuple()) -> bool:
        assert isinstance(gallery_or_id, (db.Gallery, int))
        if isinstance(gallery_or_id, int):
            gallery = database_cmd.GetModelItems().run(db.Gallery, {gallery_or_id})
            if gallery:
                gallery = gallery[0]
        else:
            gallery = gallery_or_id
        self.gallery = gallery
        if number is None:
            number = 1
        opened = False
        if self.gallery.pages.count():
            with self._resolve.call(self.gallery, number) as plg:
                r = plg.first_or_default()
                if len(r) == 2:
                    self.path, self.first_file = r

            args = args if args else tuple(x.strip() for x in config.external_image_viewer_args.value.split())

            with self._open.call(self.path, self.first_file, self.gallery, args) as plg:
                try:
                    opened = plg.first_or_default()
                except OSError as e:
                    raise exceptions.CommandError(utils.this_command(self),
                                                  "Failed to open gallery with external viewer: {}".format(e.args[1]))

        else:
            log.w("Error opening gallery (), no page count".format(self.gallery.id))

        if opened:
            self._opened.emit(self.path, self.first_file, self.gallery, number)

        return opened
コード例 #5
0
ファイル: gallery_cmd.py プロジェクト: yihuishou/happypandax
    def _calculate(self, gallery_or_id, all_gallery_tags={}):
        assert isinstance(gallery_or_id, (str, int, db.Gallery))
        sess = constants.db_session()
        with db.no_autoflush(sess):
            data = {}
            g_id = gallery_or_id.id if isinstance(
                gallery_or_id, db.Gallery) else gallery_or_id
            g_id = str(g_id)  # because JSON keys are str
            tag_count = 0
            tag_count_minimum = 3
            if g_id in all_gallery_tags:
                g_tags = all_gallery_tags[g_id]
                for a, b in g_tags.items():
                    tag_count += len(b)
                self.set_max_progress(len(g_tags) + 3)
            else:
                if isinstance(gallery_or_id, db.Gallery):
                    g_tags = gallery_or_id
                else:
                    g_tags = database_cmd.GetModelItems().run(
                        db.Taggable,
                        join=db.Gallery.taggable,
                        filter=db.Gallery.id == int(g_id))
                    if g_tags:
                        g_tags = g_tags[0]
                    tag_count = g_tags.tags.count()
                    if tag_count > tag_count_minimum:
                        g_tags = g_tags.compact_tags(g_tags.tags.all())

            self.next_progress()
            if g_tags and tag_count > tag_count_minimum:
                log.d("Calculating similarity")
                g_tags = self._get_set(g_tags)
                data[g_id] = gl_data = {}
                update_dict = not all_gallery_tags
                max_prog = 3
                for t_id, t in all_gallery_tags.items(
                ) or constants.db_session().query(
                        db.Gallery.id, db.Taggable).join(db.Gallery.taggable):
                    t_id = str(t_id)
                    self.next_progress()
                    if update_dict:
                        all_gallery_tags[t_id] = t.compact_tags(t.tags.all())
                        max_prog += 1
                        self.set_max_progress(max_prog)
                    if t_id == g_id:
                        continue
                    t_tags = self._get_set(all_gallery_tags[t_id])
                    if (math.sqrt(len(g_tags)) * math.sqrt(len(t_tags))) != 0:
                        cos = len(g_tags & t_tags) / (math.sqrt(
                            len(g_tags))) * math.sqrt(len(t_tags))
                    else:
                        cos = 0
                    if cos:
                        gl_data[t_id] = cos
                log.d("Finished calculating similarity")
            self.next_progress()

        return data
コード例 #6
0
def search_tags(
    search_query: str = "",
    search_options: dict = {},
    only_namespace: bool = False,
    only_tag: bool = False,
    sort_by: enums.ItemSort = None,
    sort_desc: bool = False,
    limit: int = 100,
    offset: int = None,
):
    """
    Search for tags

    Args:
        search_query: search string
        search_options: options to apply when filtering, see :ref:`Settings` for available search options
        only_namespace: only search for matching namespace <not implemented yet>
        only_tag: only search for matching tag <not implemented yet>
        sort_by: either a :py:class:`.ItemSort` or a sort index
        sort_desc: order descending (default is ascending)
        limit: limit the amount of items returned
        offset: offset the results by n items

    Returns:
        .. code-block:: guess

            {
                namespace : [ tag message object, ...],
                ...
            }
    """
    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))

    db_model = db.NamespaceTags
    model_ids = search_cmd.ModelFilter().run(db_model, search_query,
                                             search_options)

    order_exp, group_exp, join_exp = helpers._sort_helper(
        sort_by, sort_desc, db_model)

    items = database_cmd.GetModelItems().run(db_model,
                                             model_ids,
                                             limit=limit,
                                             offset=offset,
                                             join=join_exp,
                                             order_by=order_exp,
                                             group_by=group_exp)

    msg = _contruct_tags_msg(items)

    return message.Identity('tags', msg)
コード例 #7
0
def get_page(page_id: int = None,
             gallery_id: int = None,
             number: int = None,
             prev: bool = False):
    """
    Get next/prev page by either gallery or page id

    Args:
        page_id: id of page
        gallery_id: id of gallery
        number: retrieve specific page number
        prev: by default next page is retrieved, to retrieve prev page set this to true

    Returns:
        Page object
    """
    if not (gallery_id or page_id):
        raise exceptions.APIError(
            utils.this_function(),
            "Either a gallery id or page id is required")

    if number is None:
        number = 0

    item = None

    if page_id:
        p = database_cmd.GetModelItems().run(db.Page, {page_id})[0]
        if number and p and number == p.number:
            item = p
        elif p:
            number = number or p.number
            gallery_id = p.gallery_id

    if not item:
        f = db.Page.number < number if prev else db.Page.number == number
        f = db.and_op(f, db.Page.gallery_id == gallery_id)
        item = database_cmd.GetModelItems().run(
            db.Page,
            order_by=db.Page.number.desc() if prev else db.Page.number,
            filter=f,
            limit=1)
        if item:
            item = item[0]

    return message.Page(item) if item else None
コード例 #8
0
ファイル: ui.py プロジェクト: perfectquan/happypandax
def library_view(item_type: enums.ItemType = enums.ItemType.Gallery,
                 item_id: int = None,
                 related_type: enums.ItemType = None,
                 page: int = 0,
                 limit: int = 100,
                 sort_by: enums.ItemSort = None,
                 sort_desc: bool=False,
                 search_query: str = "",
                 search_options: dict = {},
                 filter_id: int = None,
                 view_filter: enums.ViewType = enums.ViewType.Library):
    """
    Fetch items from the database.
    Provides pagination.

    Args:
        item_type: possible items are :py:attr:`.ItemType.Gallery`, :py:attr:`.ItemType.Collection`, :py:attr:`.ItemType.Grouping`
        page: current page (zero-indexed)
        sort_by: either a :py:class:`.ItemSort` or a sort index
        sort_desc: order descending (default is ascending)
        limit: amount of items per page
        search_query: filter item by search terms
        search_options: options to apply when filtering, see :ref:`Settings` for available search options
        filter_id: current :py:attr:`.ItemType.GalleryFilter` item id
        view_filter: type of view, set ``None`` to not apply any filter
        related_type: child item
        item_id: id of parent item

    Returns:
        .. code-block:: guess

            [
                item message object,
                ...
            ]

    .. seealso::

        :func:`.get_sort_indexes`
    """
    view_filter, item_type, db_msg, db_model, model_ids, filter_op, join_exp, metatag_name = _view_helper(
        item_type, search_query, filter_id, view_filter, item_id, related_type, search_options)

    items = message.List(db_model.__name__.lower(), db_msg)

    order_exp, group_exp, sort_joins = helpers._sort_helper(sort_by, sort_desc, db_model)

    if sort_joins:
        join_exp.extend(sort_joins)
        # need unique but ordered results, cannot use set so we make use with this
        join_exp = tuple(OrderedDict([(x, None) for x in join_exp]).keys())

    [items.append(db_msg(x)) for x in database_cmd.GetModelItems().run(
        db_model, model_ids, limit=limit, offset=page * limit,
        filter=filter_op, join=join_exp, order_by=order_exp, group_by=group_exp)]

    return items
コード例 #9
0
def open_gallery(item_id: int = 0,
                 item_type: enums.ItemType = enums.ItemType.Gallery,
                 viewer_args: str = None):
    """
    Open a gallery or page in an external viewer

    Args:
        item_id: id of item
        item_type: possible items are :py:attr:`.ItemType.Gallery`, :py:attr:`.ItemType.Page`
        viewer_args: commandline arguments to supply the viewer, overriding the default viewer arguments specified in settings

    Returns:
        bool indicating if item was successfully opened
    """
    item_type = enums.ItemType.get(item_type)

    _, db_model = item_type._msg_and_model(
        (enums.ItemType.Gallery, enums.ItemType.Page))
    kwargs = {}
    if item_type == enums.ItemType.Page:
        p = database_cmd.GetModelItems().run(db_model, {item_id},
                                             columns=(db_model.gallery_id,
                                                      db_model.number))
    else:
        p = database_cmd.GetModelItems().run(db_model, {item_id})
    if not p:
        raise exceptions.DatabaseItemNotFoundError(
            utils.this_function(),
            "{} with item id '{}' not found".format(item_type, item_id))
    p = p[0]
    if item_type == enums.ItemType.Page:
        kwargs['gallery_or_id'] = p[0]
        kwargs['number'] = p[1]
    else:
        kwargs["gallery_or_id"] = p

    if viewer_args:
        kwargs['args'] = tuple(x.strip() for x in viewer_args.split())

    opened = gallery_cmd.OpenGallery().run(**kwargs)

    return message.Identity("status", opened)
コード例 #10
0
def get_tags(item_type: enums.ItemType = enums.ItemType.Gallery,
             item_id: int = 0,
             raw: bool = False):
    """
    Get tags for item

    Args:
        item_type: possible items are :attr:`.ItemType.Gallery`, :attr:`.ItemType.Page`,
            :attr:`.ItemType.Grouping`, :attr:`.ItemType.Collection`
        item_id: id of item to fetch tags for
        raw: if true, tags from descendant ItemType's will not be included
            (this only makes sense when ItemType is :attr:`.ItemType.Gallery`)

    Returns:
        .. code-block:: guess

            {
                namespace : [ tag 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)

    _, db_item = item_type._msg_and_model(
        (enums.ItemType.Gallery, enums.ItemType.Collection, enums.ItemType.Grouping, enums.ItemType.Page))

    db_obj = database_cmd.GetModelItems().run(db_item, {item_id})
    if db_obj:
        db_obj = db_obj[0]

    nstags = []
    if db_obj:
        g_objs = []
        if issubclass(db_item, db.TaggableMixin):
            nstags = db_obj.tags.all()
            if not raw and isinstance(db_obj, db.Gallery):
                g_objs.append(db_obj)
        else:
            for g in db_obj.galleries.all():
                nstags.extend(g.tags.all())
                if not raw:
                    g_objs.append(g)

        for g_obj in g_objs:
            for p in g_obj.pages.all():  # TODO: we only need tags
                nstags.extend(p.tags.all())

    msg = _contruct_tags_msg(nstags)

    return message.Identity('tags', msg)
コード例 #11
0
ファイル: gallery.py プロジェクト: yihuishou/happypandax
def add_to_filter(gallery_id: int = 0, item_id: int = 0, item: dict = {}):
    """
    Add a gallery to a galleryfilter

    Args:
        gallery_id: id of gallery
        item_id: id of existing galleryfilter, mutually exclusive with ``item`` parameter
        item: filter message object, mutually exclusive with ``item_id`` parameter

    Returns:
        bool whether gallery was added to filter or not

    """

    if not gallery_id:
        raise exceptions.APIError(utils.this_function(),
                                  "gallery_id must be a valid gallery id")

    g = database_cmd.GetModelItems().run(db.Gallery, {gallery_id})
    if not g:
        raise exceptions.DatabaseItemNotFoundError(
            utils.this_function(), "'{}' with id '{}' was not found".format(
                enums.ItemType.Gallery.name, gallery_id))
    g = g[0]

    if item_id:
        p = database_cmd.GetModelItems().run(db.GalleryFilter, {item_id})
        if not p:
            raise exceptions.DatabaseItemNotFoundError(
                utils.this_function(),
                "'{}' with id '{}' was not found".format(
                    enums.ItemType.GalleryFilter.name, item_id))
        p = p[0]
    elif item:
        p = message.GalleryFilter.from_json(item)
    g.filters.append(p)
    s = constants.db_session()
    s.add(g)
    s.commit()
    return message.Identity("status", True)
コード例 #12
0
ファイル: database.py プロジェクト: yihuishou/happypandax
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
コード例 #13
0
def _get_similar(kwargs, similar_items):
    item_list = message.List(db.model_name(kwargs['db_model']),
                             kwargs['db_msg'])
    items = []
    if similar_items:
        similar_items = similar_items[:kwargs['limit']]
        db_items = {}  # needed to sort them the way they came in
        for g in database_cmd.GetModelItems().run(kwargs['db_model'],
                                                  set(similar_items)):
            db_items[g.id] = g
        [items.append(db_items[x]) for x in similar_items if x in db_items]

    [item_list.append(kwargs['db_msg'](x)) for x in items]
    return item_list
コード例 #14
0
ファイル: gallery.py プロジェクト: yihuishou/happypandax
def remove_from_filter(gallery_id: int = 0, item_id: int = 0):
    """
    Remove a gallery from a galleryfilter

    Args:
        gallery_id: id of gallery
        item_id: id of existing galleryfilter

    Returns:
        bool whether gallery was removed from filter or not

    """

    if not gallery_id:
        raise exceptions.APIError(utils.this_function(),
                                  "gallery_id must be a valid gallery id")

    g = database_cmd.GetModelItems().run(db.Gallery, {gallery_id})
    if not g:
        raise exceptions.DatabaseItemNotFoundError(
            utils.this_function(), "'{}' with id '{}' was not found".format(
                enums.ItemType.Gallery.name, gallery_id))
    g = g[0]

    p = database_cmd.GetModelItems().run(db.GalleryFilter, {item_id})
    if not p:
        raise exceptions.DatabaseItemNotFoundError(
            utils.this_function(), "'{}' with id '{}' was not found".format(
                enums.ItemType.GalleryFilter.name, item_id))
    p = p[0]

    g.filters.remove(p)
    s = constants.db_session()
    s.add(g)
    s.commit()
    return message.Identity("status", True)
コード例 #15
0
ファイル: database.py プロジェクト: yihuishou/happypandax
def update_metatags(item_type: enums.ItemType = enums.ItemType.Gallery,
                    item_id: int = 0,
                    metatags: dict = {}):
    """
    Update metatags for an item

    Args:
        item_type: possible items are :py:attr:`.ItemType.Gallery`, :py:attr:`.ItemType.Page`,
            :py:attr:`.ItemType.Artist`, :py:attr:`.ItemType.Collection`
        item_id: id of item
        metatag: a dict of ``{ metatag_name : bool }``

    Returns:
        bool indicating whether metatags were updated
    """
    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)

    _, db_item = item_type._msg_and_model(
        (enums.ItemType.Gallery, enums.ItemType.Collection,
         enums.ItemType.Page, enums.ItemType.Artist))

    t = database_cmd.GetModelItems().run(db_item, {item_id})
    if not t:
        raise exceptions.DatabaseItemNotFoundError(
            utils.this_function(),
            "{} with item id '{}' not found".format(item_type, item_id))
    t = t[0]
    mtags = {}
    anames = db.MetaTag.all_names()
    for m, v in metatags.items():
        if m not in anames:
            raise exceptions.APIError(utils.this_function(),
                                      f"Metatag name '{m}' does not exist")
        mtags[m] = v

    st = True
    if t:
        t.update("metatags", mtags)

        db.object_session(t).commit()
    else:
        st = False

    return message.Identity('status', st)
コード例 #16
0
def get_all_tags(limit: int=100, offset: int=None):
    """
    Get all tags from the db

    Args:
        limit: limit the amount of items returned
        offset: offset the results by n items

    Returns:
        .. code-block:: guess

            {
                namespace : [ tag message object, ...],
                ...
            }
    """
    db_obj = database_cmd.GetModelItems().run(db.NamespaceTags, limit=limit, offset=offset)

    msg = _contruct_tags_msg(db_obj)

    return message.Identity('tags', msg)
コード例 #17
0
def get_items(item_type: enums.ItemType = enums.ItemType.Gallery,
              limit: int = 100):
    """
    Get a list of items

    Args:
        item_type: type of item to get
        limit: limit the amount of items returned

    Returns:
        list of item message objects
    """

    item_type = enums.ItemType.get(item_type)

    db_msg, db_model = item_type._msg_and_model()

    items = database_cmd.GetModelItems().run(db_model, limit=limit)

    item_list = message.List(db.model_name(db_model), db_msg)
    [item_list.append(db_msg(i)) for i in items]
    return item_list
コード例 #18
0
def update_item_tags(item_type: enums.ItemType = enums.ItemType.Gallery,
                     item_id: int=0,
                     tags: dict={}):
    """
    Update tags on an item

    Args:
        item_type: possible items are :attr:`.ItemType.Gallery`, :attr:`.ItemType.Page`,
            :attr:`.ItemType.Grouping`, :attr:`.ItemType.Collection`
        item_id: id of item to update tags for
        tags: tags

    Returns:
        bool whether tags were updated or not

    """

    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)
    _, db_item = item_type._msg_and_model(
        (enums.ItemType.Gallery, enums.ItemType.Collection, enums.ItemType.Grouping, enums.ItemType.Page))

    db_obj = database_cmd.GetModelItems().run(db_item, {item_id})
    if not db_obj:
        raise exceptions.DatabaseItemNotFoundError(utils.this_function(),
                                                   "'{}' with id '{}' was not found".format(item_type.name,
                                                                                            item_id))
    db_obj = db_obj[0]

    tags = _decontruct_tags_msg(tags)
    s = constants.db_session()
    with db.no_autoflush(s):
        s.add(db_obj)
        db_obj.tags = tags
        s.commit()
    return message.Identity("status", True)
コード例 #19
0
ファイル: database.py プロジェクト: perfectquan/happypandax
def search_item(
    item_type: enums.ItemType = enums.ItemType.Gallery,
    search_query: str = "",
    search_options: dict = {},
    sort_by: enums.ItemSort = None,
    sort_desc: bool = False,
    full_search: bool = True,
    limit: int = 100,
    offset: int = None,
):
    """
    Search for item

    Args:
        item_type: all of :py:attr:`.ItemType` except :py:attr:`.ItemType.Page` and :py:attr:`.ItemType.GalleryFilter`
        search_query: filter item by search terms
        search_options: options to apply when filtering, see :ref:`Settings` for available search options
        sort_by: either a :py:class:`.ItemSort` or a sort index
        sort_desc: order descending (default is ascending)
        limit: amount of items
        offset: offset the results by n items

    Returns:
        .. code-block:: guess

            [
                item message object,
                ...
            ]

    .. seealso::

        :func:`.get_sort_indexes`
    """
    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))

    if item_type in (enums.ItemType.Page, enums.ItemType.GalleryFilter):
        raise exceptions.APIError(utils.this_function(),
                                  "Unsupported itemtype {}".format(item_type))
    db_msg, db_model = item_type._msg_and_model()

    model_ids = set()
    if full_search:
        model_ids = search_cmd.ModelFilter().run(db_model, search_query,
                                                 search_options)

    items = message.List("items", db_msg)

    order_exp, group_exp, join_exp = helpers._sort_helper(
        sort_by, sort_desc, db_model)

    [
        items.append(db_msg(x))
        for x in database_cmd.GetModelItems().run(db_model,
                                                  model_ids,
                                                  limit=limit,
                                                  offset=offset,
                                                  join=join_exp,
                                                  order_by=order_exp,
                                                  group_by=group_exp)
    ]

    return items
コード例 #20
0
def source_exists(item_type: enums.ItemType = enums.ItemType.Gallery,
                  item_id: int = 0,
                  check_all: bool = False):
    """
    Check if gallery/page source exists on disk

    Args:
        item_type: possible items are :py:attr:`.ItemType.Gallery`, :py:attr:`.ItemType.Page`
        item_id: id of item
        check_all: goes through all pages and checks them, default behaviour is to only check parent files/folders. Only relevant for :py:attr:`.ItemType.Gallery`

    Returns:
        .. code-block:: guess

            {
                'exists' : bool
                'missing' : [
                    {'id': int, 'item_type': item_type},
                    ...
                    ]
            }

    """

    item_type = enums.ItemType.get(item_type)

    _, db_model = item_type._msg_and_model(
        (enums.ItemType.Gallery, enums.ItemType.Page))

    if item_type == enums.ItemType.Page:
        item = database_cmd.GetModelItems().run(db_model, {item_id},
                                                columns=(db.Page.path, ))
    elif item_type == enums.ItemType.Gallery:
        item = database_cmd.GetModelItems().run(
            db_model, {item_id}, columns=(db.Gallery.single_source, ))

    if not item:
        raise exceptions.DatabaseItemNotFoundError(
            utils.this_function(),
            "'{}' with id '{}' was not found".format(item_type.name, item_id))
    else:
        item = item[0]

    paths = {}
    not_empty = True
    if item_type == enums.ItemType.Page:
        paths[item_id] = (item[0], item_type.value)
    elif item_type == enums.ItemType.Gallery:
        s = constants.db_session()
        if item and not check_all:
            p = s.query(db.Page.path).filter(db.Gallery.id == item_id).first()
            if p:
                paths[item_id] = (os.path.split(p[0])[0], item_type.value)
            else:
                not_empty = True
        else:
            ps = s.query(
                db.Page.id,
                db.Page.path).filter(db.Page.gallery_id == item_id).all()
            for p in ps:
                paths[p[0]] = (p[1], enums.ItemType.Page.value)
            not_empty = bool(ps)

    missing = []
    for t_id in paths:
        src, t_type = paths[t_id]
        try:
            e = io_cmd.CoreFS(src).exists
        except exceptions.ArchiveExistError:
            e = False
        if not e:
            missing.append({'id': t_id, 'item_type': t_type})

    return message.Identity("exists", {
        'exists': not missing and not_empty,
        'missing': missing
    })