def GET(self): days = xutils.get_argument("days", 30, type=int) page = xutils.get_argument("page", 1, type=int) page = max(1, page) db = xtables.get_file_table() where = "is_deleted = 0 AND (creator = $creator OR is_public = 1)" files = db.select(where=where, vars=dict(creator=xauth.get_current_name()), order="mtime DESC", offset=(page - 1) * PAGE_SIZE, limit=PAGE_SIZE) count = db.count(where, vars=dict(creator=xauth.get_current_name())) return xtemplate.render("note/view.html", pathlist=[ Storage(name="最近更新", type="group", url="/file/recent_edit") ], file_type="group", files=list(files), file=Storage(name="最近更新", type="group"), page=page, page_max=math.ceil(count / PAGE_SIZE), show_mdate=True, page_url="/file/recent_edit?page=")
def do_search(self, key, offset, limit): global _rules category = xutils.get_argument("category", "") words = textutil.split_words(key) files = [] start_time = time.time() ctx = SearchContext() ctx.input_text = key ctx.words = words ctx.category = category ctx.search_message = (category == "message") ctx.search_file_full = (category == "content") ctx.search_dict = (category == "dict") ctx.user_name = xauth.get_current_name() if ctx.search_message: ctx.search_file = False ctx.search_file_full = False ctx.search_tool = False if ctx.search_dict: ctx.search_file = False if ctx.search_file_full: ctx.search_tool = False if ctx.category == "book": ctx.search_file = False ctx.search_tool = False xutils.log(" key=%s" % key) xmanager.fire("search.before", ctx) xmanager.fire("search", ctx) for rule in _rules: pattern = rule.pattern func = rule.func # re.match内部已经实现了缓存 m = re.match(pattern, key) if m: try: start_time0 = time.time() results = func(ctx, *m.groups()) cost_time0 = time.time() - start_time0 xutils.log(" >>> %s - %d ms" % (func.modfunc, cost_time0 * 1000)) if results is not None: files += results except Exception as e: xutils.print_exc() cost_time = (time.time() - start_time) * 1000 xutils.log(" === total - %d ms ===" % cost_time) xconfig.search_history.put( Storage(name="#search# %s - %d ms" % (key, cost_time), category=category, user=xauth.get_current_name(), link=web.ctx.fullpath)) xmanager.fire("search.after", ctx) return ctx.tools + files
def GET(self): pagesize = xutils.get_argument("pagesize", xconfig.PAGE_SIZE, type=int) page = xutils.get_argument("page", 1, type=int) status = xutils.get_argument("status") offset = (page - 1) * pagesize db = xtables.get_message_table() user_name = xauth.get_current_name() kw = "1=1" if status == "created": kw = "status = 0" if status == "done": kw = "status = 100" kw += " AND user = $user" vars = dict(user=xauth.get_current_name()) chatlist = list( db.select(where=kw, vars=vars, order="ctime DESC", limit=pagesize, offset=offset)) chatlist.reverse() amount = db.count(where=kw, vars=vars) page_max = math.ceil(amount / pagesize) return dict(code="success", message="", data=chatlist, amount=amount, page_max=page_max, current_user=xauth.get_current_name())
def GET(self): id = xutils.get_argument("id", type=int) db = xtables.get_file_table() db.update(is_public=0, where=dict(id=id, creator=xauth.get_current_name())) tag = xtables.get_file_tag_table() tag.update(is_public=0, where=dict(file_id=id, user=xauth.get_current_name())) raise web.seeother("/note/view?id=%s" % id)
def GET(self): pagesize = xutils.get_argument("pagesize", xconfig.PAGE_SIZE, type=int) page = xutils.get_argument("page", 1, type=int) status = xutils.get_argument("status") key = xutils.get_argument("key") offset = (page - 1) * pagesize db = xtables.get_message_table() user_name = xauth.get_current_name() kw = "1=1" if status == "created": kw = "status = 0" if status == "done": kw = "status = 100" if status == "suspended": kw = "status = 50" kw += " AND user = $user" vars = dict(user=xauth.get_current_name()) if key != "" and key != None: start_time = time.time() for item in key.split(" "): if item == "": continue kw += " AND content LIKE " + fuzzy_item(item) # when find numbers, the sql printed is not correct # eg. LIKE '%1%' will be LIKE '%' # print(kw) chatlist = list( db.select(where=kw, vars=vars, order="ctime DESC", limit=pagesize, offset=offset)) end_time = time.time() cost_time = int((end_time - start_time) * 1000) xutils.log("message search [%s] time %d ms" % (key, cost_time)) if xconfig.search_history is not None: xconfig.search_history.put( Storage(name="#message# %s - %sms" % (key, cost_time), link=web.ctx.fullpath)) else: chatlist = list( db.select(where=kw, vars=vars, order="ctime DESC", limit=pagesize, offset=offset)) chatlist.reverse() amount = db.count(where=kw, vars=vars) page_max = math.ceil(amount / pagesize) chatlist = list(map(process_message, chatlist)) return dict(code="success", message="", data=chatlist, amount=amount, page_max=page_max, current_user=xauth.get_current_name())
def GET(self): sql = "SELECT * FROM file WHERE type = 'group' AND is_deleted = 0 AND creator = $creator ORDER BY name LIMIT 1000" data = list(xtables.get_file_table().query(sql, vars = dict(creator=xauth.get_current_name()))) ungrouped_count = xtables.get_file_table().count(where="creator=$creator AND parent_id=0 AND is_deleted=0 AND type!='group'", vars=dict(creator=xauth.get_current_name())) tools = list(filter(tool_filter, _tools))[:4] return xtemplate.render("index.html", ungrouped_count = ungrouped_count, file_type="group_list", files = data, tools = tools)
def GET(self): id = xutils.get_argument("id", "", type=int) data = xutils.call("note.list_group", xauth.get_current_name()) ungrouped_count = xtables.get_file_table().count( where= "creator=$creator AND parent_id=0 AND is_deleted=0 AND type!='group'", vars=dict(creator=xauth.get_current_name())) return xtemplate.render("note/group_list.html", ungrouped_count=ungrouped_count, file_type="group_list", pseudo_groups=True, show_search_div=True, show_add_group=True, files=data)
def GET(self): days = xutils.get_argument("days", 30, type=int) page = xutils.get_argument("page", 1, type=int) pagesize = xutils.get_argument("pagesize", PAGE_SIZE, type=int) page = max(1, page) db = xtables.get_file_table() t = Timer() t.start() creator = xauth.get_current_name() where = "is_deleted = 0 AND (creator = $creator OR is_public = 1) AND type != 'group'" cache_key = "recent_notes#%s#%s" % (creator, page) files = cacheutil.get(cache_key) if files is None: files = list( db.select( what="name, id, parent_id, ctime, mtime, type, creator", where=where, vars=dict(creator=creator), order="mtime DESC", offset=(page - 1) * pagesize, limit=pagesize)) cacheutil.set(cache_key, files, expire=600) t.stop() xutils.log("list recent edit %s" % t.cost()) t.start() groups = xutils.call("note.list_group") t.stop() xutils.log("list group %s" % t.cost()) count = db.count(where, vars=dict(creator=xauth.get_current_name())) return xtemplate.render("note/view.html", html_title="最近更新", pathlist=[ Storage(name="最近更新", type="group", url="/file/recent_edit") ], file_type="group", files=files, file=Storage(name="最近更新", type="group"), page=page, show_notice=True, page_max=math.ceil(count / PAGE_SIZE), groups=groups, show_mdate=True, show_groups=True, page_url="/file/recent_edit?page=")
def search(ctx, expression=None): words = ctx.words files = [] if ctx.search_file_full: files += full_search(words, xauth.get_current_name()) if ctx.search_file: files += search_name(words, xauth.get_current_name()) # group 放前面 groups = list(filter(lambda x: x.type == "group", files)) text_files = list(filter(lambda x: x.type != "group", files)) files = groups + text_files return files
def GET(self): page = xutils.get_argument("page", 1, type=int) user_name = xauth.get_current_name() pagesize = xconfig.PAGE_SIZE offset = (page - 1) * pagesize files = xutils.call("note.list_note", user_name, 0, offset, pagesize) amount = xutils.call("note.count", user_name, 0) parent = PathNode("智能分类", "/note/types") return xtemplate.render(VIEW_TPL, show_aside=True, file_type="group", pathlist=[ parent, Storage(name="默认分类", type="group", url="/note/default") ], files=files, file=Storage(name="默认分类", type="group"), page=page, page_max=math.ceil(amount / pagesize), groups=xutils.call("note.list_group"), show_mdate=True, page_url="/note/default?page=")
def do_search(self, page_ctx, key, offset, limit): category = xutils.get_argument("category", "") words = textutil.split_words(key) user_name = xauth.get_current_name() start_time = time.time() ctx = build_search_context(user_name, category, key) # 阻断性的搜索,比如特定语法的 xmanager.fire("search.before", ctx) if ctx.stop: return ctx.join_as_files() # 普通的搜索行为 xmanager.fire("search", ctx) ctx.files = apply_search_rules(ctx, key) cost_time = int((time.time() - start_time) * 1000) log_search_history(user_name, key, category, cost_time) if ctx.stop: return ctx.join_as_files() # 慢搜索,如果时间过长,这个服务会被降级 xmanager.fire("search.slow", ctx) xmanager.fire("search.after", ctx) page_ctx.tools = [] return ctx.join_as_files()
def GET(self): page = xutils.get_argument("page", 1, type=int) db = xtables.get_file_table() user_name = xauth.get_current_name() pagesize = xconfig.PAGE_SIZE vars = dict() vars["name"] = user_name vars["offset"] = (page - 1) * pagesize vars["limit"] = pagesize sql = """SELECT a.* FROM file a LEFT JOIN file b ON a.parent_id = b.id WHERE a.is_deleted = 0 AND a.type != 'group' AND a.creator = $name AND (b.id is null OR b.type != 'group') ORDER BY mtime DESC LIMIT $offset, $limit""" files = db.query(sql, vars=vars) count_sql = """SELECT COUNT(1) AS amount FROM file a LEFT JOIN file b ON a.parent_id = b.id WHERE a.is_deleted = 0 AND a.type != 'group' AND a.creator = $name AND (b.id is null OR b.type != 'group')""" amount = db.count(sql=count_sql, vars=vars) return xtemplate.render(VIEW_TPL, file_type="group", files=files, file=Storage(name="未分类", type="group"), page=page, page_max=math.ceil(amount / pagesize), page_url="/file/group/ungrouped?page=")
def POST(self): content = xutils.get_argument("content", "") data = xutils.get_argument("data", "") id = xutils.get_argument("id", "0", type=int) type = xutils.get_argument("type") name = xauth.get_current_name() db = xtables.get_file_table() where = None if xauth.is_admin(): where = dict(id=id) else: where = dict(id=id, creator=name) kw = dict(size=len(content), mtime=xutils.format_datetime(), where=where) if type == "html": kw["data"] = data kw["content"] = data if xutils.bs4 is not None: soup = xutils.bs4.BeautifulSoup(data, "html.parser") content = soup.get_text(separator=" ") kw["content"] = content kw["size"] = len(content) else: kw["content"] = content kw["size"] = len(content) rowcount = db.update(**kw) if rowcount > 0: return dict(code="success") else: return dict(code="fail")
def POST(self): id = xutils.get_argument("id") name = xutils.get_argument("name") if name == "" or name is None: return dict(code="fail", message="名称为空") old = xutils.call("note.get_by_id", id) if old is None: return dict(code="fail", message="笔记不存在") if old.creator != xauth.get_current_name(): return dict(code="fail", message="没有权限") file = xutils.call("note.get_by_name", name) if file is not None and file.is_deleted == 0: return dict(code="fail", message="%r已存在" % name) xutils.call("note.update", dict(id=id), name=name) event_body = dict(action="rename", id=id, name=name, type=old.type) xmanager.fire("note.updated", event_body) xmanager.fire("note.rename", event_body) if old.type == "group": cacheutil.prefix_del("group.list") return dict(code="success")
def update_message_status(id, status): if xconfig.DB_ENGINE == "sqlite": db = xtables.get_message_table() msg = db.select_first(where=dict(id=id)) if msg is None: return dict(code="fail", message="data not exists") if msg.user != xauth.get_current_name(): return dict(code="fail", message="no permission") db.update(status=status, mtime=xutils.format_datetime(), where=dict(id=id)) xmanager.fire( "message.updated", Storage(id=id, status=status, user=msg.user, content=msg.content)) else: user_name = xauth.current_name() data = dbutil.get(id) if data and data.user == user_name: data.status = status data.mtime = xutils.format_datetime() dbutil.put(id, data) xmanager.fire( "message.updated", Storage(id=id, user=user_name, status=status, content=data.content)) return dict(code="success")
def GET(self, path_key=None): """search files by name and content""" load_rules() key = xutils.get_argument("key", "") title = xutils.get_argument("title", "") category = xutils.get_argument("category", "default") page = xutils.get_argument("page", 1, type=int) user_name = xauth.get_current_name() page_url = "/search/search?key=%s&category=%s&page="\ % (key, category) pagesize = xconfig.SEARCH_PAGE_SIZE offset = (page - 1) * pagesize limit = pagesize if path_key: key = xutils.unquote(path_key) if key == "" or key == None: raise web.found("/search/history") key = key.strip() ctx = Storage() files = self.do_search(ctx, key, offset, pagesize) count = len(files) files = files[offset:offset + limit] fill_note_info(files) return xtemplate.render("search/page/search_result.html", show_aside=False, key=key, html_title="Search", category=category, files=files, title=title, page_max=int(math.ceil(count / pagesize)), page_url=page_url, **ctx)
def POST(self): content = xutils.get_argument("content", "") data = xutils.get_argument("data", "") id = xutils.get_argument("id") type = xutils.get_argument("type") version = xutils.get_argument("version", 0, type=int) name = xauth.get_current_name() where = None try: file = check_get_note(id) kw = dict(size = len(content), mtime = xutils.format_datetime(), version = version + 1) if type == "html": kw["data"] = data kw["content"] = data if xutils.bs4 is not None: soup = xutils.bs4.BeautifulSoup(data, "html.parser") content = soup.get_text(separator=" ") kw["content"] = content kw["size"] = len(content) else: kw["content"] = content kw['data'] = '' kw["size"] = len(content) update_and_notify(file, kw) return dict(code = "success") except NoteException as e: return dict(code = "fail", message = e.message)
def GET(self): date = xutils.get_argument("date") db = xtables.get_message_table() data = db.select(where="ctime LIKE $date AND user=$user", vars=dict(date=date + '%', user=xauth.get_current_name())) return dict(code="success", data=list(data))
def POST(self): from . import dao id = xutils.get_argument("file_id", type=int) tags_str = xutils.get_argument("tags") tag_db = xtables.get_file_tag_table() user_name = xauth.get_current_name() if tags_str is None or tags_str == "": tag_db.delete(where=dict(file_id=id, user=user_name)) return dict(code="success") new_tags = set(tags_str.split(" ")) file = dao.get_by_id(id) db = dao.get_file_db() file_db = xtables.get_file_table() # 求出两个差集进行运算 old_tags = tag_db.select(where=dict(file_id=id, user=user_name)) old_tags = set([v.name for v in old_tags]) to_delete = old_tags - new_tags to_add = new_tags - old_tags for item in to_delete: tag_db.delete(where=dict(name=item, file_id=id, user=user_name)) for item in to_add: if item == "": continue tag_db.insert(name=item, file_id=id, user=user_name, is_public=file.is_public) file_db.update(related=tags_str, where=dict(id=id)) return dict(code="", message="", data="OK")
def GET(self, tagname): from . import dao tagname = xutils.unquote(tagname) db = xtables.get_file_table() page = xutils.get_argument("page", 1, type=int) limit = xutils.get_argument("limit", 10, type=int) offset = (page - 1) * limit pagesize = xconfig.PAGE_SIZE if xauth.has_login(): user_name = xauth.get_current_name() else: user_name = "" count_sql = "SELECT COUNT(1) AS amount FROM file_tag WHERE LOWER(name) = $name AND (user=$user OR is_public=1)" sql = "SELECT f.* FROM file f, file_tag ft ON ft.file_id = f.id WHERE LOWER(ft.name) = $name AND (ft.user=$user OR ft.is_public=1) ORDER BY f.ctime DESC LIMIT $offset, $limit" count = db.query(count_sql, vars=dict(name=tagname.lower(), user=user_name))[0].amount files = db.query(sql, vars=dict(name=tagname.lower(), offset=offset, limit=limit, user=user_name)) files = [dao.FileDO.fromDict(f) for f in files] return xtemplate.render("note/tagname.html", show_aside=True, tagname=tagname, files=files, show_mdate=True, page_max=math.ceil(count / pagesize), page=page)
def POST(self): id = xutils.get_argument("id") content = xutils.get_argument("content") user_name = xauth.get_current_name() db = xtables.get_message_table() # 对消息进行语义分析处理,后期优化把所有规则统一管理起来 ctx = Storage(content=content, user=user_name, type="") for rule in rules: rule.match_execute(ctx, content) xmanager.fire('message.update', ctx) if id == "" or id is None: ctime = xutils.get_argument("date", xutils.format_datetime()) inserted_id = db.insert(content=content, user=user_name, ctime=ctime, type=ctx.get("type", "")) return dict(code="success", data=dict(id=inserted_id, content=content, ctime=ctime)) db.update(content=content, mtime=xutils.format_datetime(), type=ctx.get("type", ""), where=dict(id=id, user=user_name)) return dict(code="success")
def rdb_list_recent_edit(parent_id=None, offset=0, limit=None): if limit is None: limit = xconfig.PAGE_SIZE db = xtables.get_file_table() creator = xauth.get_current_name() if creator: where = "is_deleted = 0 AND (creator = $creator) AND type != 'group'" else: # 未登录 where = "is_deleted = 0 AND is_public = 1 AND type != 'group'" cache_key = "[%s]note.recent$%s$%s" % (creator, offset, limit) files = cacheutil.get(cache_key) if files is None: files = list( db.select( what= "name, id, parent_id, ctime, mtime, type, creator, priority", where=where, vars=dict(creator=creator), order="priority DESC, mtime DESC", offset=offset, limit=limit)) fill_parent_name(files) cacheutil.set(cache_key, files, expire=600) return files
def GET(self): page = xutils.get_argument("page", 1, type=int) user_name = xauth.get_current_name() pagesize = xconfig.PAGE_SIZE offset = (page - 1) * pagesize files = NOTE_DAO.list_by_parent(user_name, 0, offset, pagesize) amount = NOTE_DAO.count_by_parent(user_name, 0) parent = NOTE_DAO.get_root() return xtemplate.render(VIEW_TPL, file_type="group", back_url=xconfig.get_user_config( user_name, "HOME_PATH"), pathlist=[ parent, Storage(name="默认分类", type="group", url="/note/default") ], files=files, file=Storage(id=1, name="默认分类", type="group", parent_id=0), page=page, page_max=math.ceil(amount / pagesize), groups=NOTE_DAO.list_group(), show_mdate=True, page_url="/note/default?page=")
def GET(self): shell_list = [] dirname = "scripts" if os.path.exists(dirname): for fname in os.listdir(dirname): fpath = os.path.join(dirname, fname) if os.path.isfile(fpath) and fpath.endswith(".bat"): shell_list.append(fpath) # 自定义链接 customized_items = [] user_config = get_tools_config(xauth.get_current_name()) if user_config is not None: config_list = xutils.parse_config_text(user_config.value) customized_items = map( lambda x: Storage(name=x.get("key"), url=x.get("value")), config_list) return xtemplate.render("system/system.html", show_aside=(xconfig.OPTION_STYLE == "aside"), html_title="系统", Storage=Storage, os=os, user=xauth.get_current_user(), customized_items=customized_items)
def GET(self): page = xutils.get_argument("page", 1, type=int) user_name = xauth.get_current_name() pagesize = xconfig.PAGE_SIZE offset = (page - 1) * pagesize files = NOTE_DAO.list_default_notes(user_name, offset, pagesize) amount = NOTE_DAO.count_by_parent(user_name, 0) parent = NOTE_DAO.get_root() return xtemplate.render(VIEW_TPL, file_type="group", back_url=xuserconfig.get_home_path(user_name), pathlist=[ parent, Storage(name="默认分类", type="group", url="/note/default") ], files=files, file=Storage(id="default", name="默认分类", type="group", parent_id=0), page=page, page_max=math.ceil(amount / pagesize), groups=NOTE_DAO.list_group(), show_mdate=True, show_pagination=True, show_parent_link=False, show_create_option=False, CREATE_BTN_TEXT_DICT=CREATE_BTN_TEXT_DICT, page_url="/note/default?page=")
def GET(self, id): id = int(id) db = xtables.get_file_tag_table() user_name = xauth.get_current_name() sql = "SELECT * FROM file_tag WHERE file_id=$file_id AND (user=$user OR is_public=1)" file_tags = db.query(sql, vars=dict(file_id=id, user=user_name)) return dict(code="", message="", data=list(file_tags))
def POST(self): coords = xutils.get_argument("coords") if coords != "null": db = xtables.get_record_table() db.insert(type="location", key=xauth.get_current_name(), cdate=xutils.format_date(), ctime=xutils.format_datetime(), value=coords) return "{}"
def GET(self): id = xutils.get_argument("id", "") name = xutils.get_argument("name", "") file = None if id == "" and name == "": return dict(code="fail", message="id,name至少一个不为空") db = xtables.get_file_table() if id != "": file = db.select_one(where=dict(id=int(id), is_deleted=0)) elif name != "": file = get_by_name(db, name) if file is None: return dict(code="fail", message="文件不存在") id = file.id if not xauth.is_admin() and file.creator != xauth.get_current_name(): return dict(code="fail", message="没有删除权限") if file.type == "group": children_count = db.count(where="parent_id=%s AND is_deleted=0"%id) if children_count > 0: return dict(code="fail", message="分组不为空") db.update(is_deleted=1, mtime=dateutil.format_time(), where=dict(id=int(id))) db.delete(where="is_deleted=1 AND mtime < $date", vars=dict(date=dateutil.before(days=30,format=True))) xmanager.fire("note.remove", dict(id=id)) return dict(code="success")
def pre_render(kw): """模板引擎预处理过程""" kw["math"] = math kw["_is_admin"] = xauth.is_admin() kw["_has_login"] = xauth.has_login() user_name = xauth.get_current_name() or "" kw["_user_name"] = user_name kw["_user_agent"] = get_user_agent() # 处理首页公告 kw["_top_notice"] = None # 用于渲染其他组件 kw["_render"] = render kw["Storage"] = Storage kw["xutils"] = xutils kw["xconfig"] = xconfig kw["_notice_count"] = get_message_count(user_name) if hasattr(web.ctx, "env"): kw["HOST"] = web.ctx.env.get("HTTP_HOST") if xutils.sqlite3 is None: kw["warn"] = "WARN: sqlite3不可用" # render input _input = web.ctx.get("_xnote.input") if _input is not None: kw.update(_input)
def POST(self): id = xutils.get_argument("id") content = xutils.get_argument("content") status = xutils.get_argument("status") location = xutils.get_argument("location", "") user_name = xauth.get_current_name() db = xtables.get_message_table() # 对消息进行语义分析处理,后期优化把所有规则统一管理起来 ctx = Storage(id=id, content=content, user=user_name, type="") for rule in rules: rule.match_execute(ctx, content) ip = get_remote_ip() if id == "" or id is None: ctime = xutils.get_argument("date", xutils.format_datetime()) inserted_id = xutils.call("message.create", content=content, user=user_name, status=get_status_by_code(status), ip=ip, mtime=ctime, ctime=ctime) id = inserted_id xmanager.fire( 'message.add', dict(id=id, user=user_name, content=content, ctime=ctime)) return dict(code="success", data=dict(id=inserted_id, content=content, ctime=ctime)) else: update_message_content(id, user_name, content) return dict(code="success", data=dict(id=id))