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
def _generate_collection(model, item_id, size, capture=db.model_name(db.Collection)): im_path = "" model = GetModelClass().run(model) page = GetSession().run().query(db.Page.path).join( db.Collection.galleries).join(db.Gallery.pages).filter( db.and_op(db.Collection.id == item_id, db.Page.number == 1)).first() # gallery sorted by insertion: # page = GetSession().run().query( # db.Page.path, db.gallery_collections.c.timestamp.label("timestamp")).join(db.Collection.galleries).join(db.Gallery.pages).filter( # db.and_op( # db.Collection.id == item_id, # db.Page.number == 1)).sort_by("timestamp").first() if page: im_path = page[0] if im_path: im_props = io_cmd.ImageProperties(size, 0, constants.dir_thumbs) im_path = io_cmd.ImageItem(im_path, im_props).main() return im_path
def _generate(model, item_id, size, capture=db.model_name(db.Gallery)): im_path = "" page = GetSession().run().query(db.Page.path).filter( db.and_op(db.Page.gallery_id == item_id, db.Page.number == 1)).one_or_none() if page: im_props = io_cmd.ImageProperties(size, 0, constants.dir_thumbs) im_path = io_cmd.ImageItem(None, page[0], im_props).main() return im_path
def main(self, model: db.Base, item_id: int, image_size: enums.ImageSize) -> db.Profile: self.model = model if image_size == enums.ImageSize.Original: image_size = utils.ImageSize(0, 0) else: image_size = utils.ImageSize( *constants.image_sizes[image_size.name.lower()]) with self.models.call() as plg: for p in plg.all(default=True): self._supported_models.update(p) if self.model not in self._supported_models: raise exceptions.CommandError( utils.this_command(self), "Model '{}' is not supported".format(model)) img_hash = io_cmd.ImageItem.gen_hash(model, image_size, item_id) generate = True sess = constants.db_session() profile_size = str(tuple(image_size)) self.cover = sess.query(db.Profile).filter( db.and_op(db.Profile.data == img_hash, db.Profile.size == profile_size)).first() old_img_hash = None if self.cover: if io_cmd.CoreFS(self.cover.path).exists: generate = False else: old_img_hash = self.cover.data self.next_progress() if not generate: model_name = db.model_name(model) with self.invalidate.call_capture(model_name, model_name, item_id, image_size) as plg: if plg.first_or_default(): generate = True self.next_progress() if generate: constants.task_command.thumbnail_cleaner.wake_up() self.cover = self.run_native(self._generate_and_add, img_hash, old_img_hash, generate, model, item_id, image_size, profile_size).get() self.cover_event.emit(self.cover) return self.cover
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()
def get_context(self, user=None, password=None): "Creates or retrieves existing context object for this client" s = constants.db_session() user_obj = None if user or password: log.d("Client provided credentials, authenticating...") user_obj = s.query( db.User).filter(db.User.name == user).one_or_none() if user_obj: if not user_obj.password == password: raise exceptions.AuthError(utils.this_function(), "Wrong credentials") else: raise exceptions.AuthError(utils.this_function(), "Wrong credentials") else: log.d("Client did not provide credentials") if not constants.disable_default_user: log.d("Authenticating with default user") user_obj = s.query(db.User).filter( db.User.role == db.User.Role.default).one() else: if not constants.allow_guests: log.d("Guests are disallowed on this server") raise exceptions.AuthRequiredError(utils.this_function()) log.d("Authencticating as guest") user_obj = s.query(db.User).filter( db.and_op( db.User.address == self._ip, db.User.role == db.User.Role.guest)).one_or_none() if not user_obj: user_obj = db.User(role=db.User.Role.guest) s.add(user_obj) self.context = user_obj self.context.address = self._ip if not self.context.context_id: self.context.context_id = uuid.uuid4().hex self.context.config = None log.d("Client accepted") self._accepted = True s.commit()
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
def _generate(model, item_id, size, capture=[db.model_name(x) for x in (db.Page, db.Gallery)]): im_path = "" model = GetModelClass().run(model) if model == db.Gallery: page = GetSession().run().query(db.Page.path).filter( db.and_op(db.Page.gallery_id == item_id, db.Page.number == 1)).one_or_none() else: page = GetSession().run().query( db.Page.path).filter(db.Page.id == item_id).one_or_none() if page: im_path = page[0] if im_path: im_props = io_cmd.ImageProperties(size, 0, constants.dir_thumbs) im_path = io_cmd.ImageItem(None, im_path, im_props).main() return im_path
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