def taskeditform(self, id=None, *args, **kwargs): if ormdb == "sqlite": # 為了避免跨執行緒使用 SQLite3, 重新 connect 資料庫 Database.connect() user = self.printuser() password, adsense, anonymous, mail_suffix, site_closed, read_only = self.parse_config(filename="pygroup_config") if read_only == "yes" and user != "admin": return "<a href='/'>Go to main page</a><br /><br />error, site is read only!" if user == "anonymous" and anonymous != "yes": raise cherrypy.HTTPRedirect("login") else: try: query = Task.at(int(id)).select() result = query.execute() data = result.one() output = "user:"******", owner:"+data.owner+"<br /><br />" if user != data.owner: if user != "admin": return output + "error! Not authorized!" else: template_lookup = TemplateLookup(directories=[template_root_dir+"/templates"]) mytemplate = template_lookup.get_template("taskeditform.html") return mytemplate.render(user=user, id=id, data=data) else: template_lookup = TemplateLookup(directories=[template_root_dir+"/templates"]) mytemplate = template_lookup.get_template("taskeditform.html") return mytemplate.render(user=user, id=id, data=data) except: return "error! Not authorized!"
def taskdelete(self, id=None, type=None, name=None, content=None, *args, **kwargs): if ormdb == "sqlite": # 為了避免跨執行緒使用 SQLite3, 重新 connect 資料庫 Database.connect() # check user and data owner user = self.printuser() password, adsense, anonymous, mail_suffix, site_closed, read_only = self.parse_config(filename="pygroup_config") if read_only == "yes" and user != "admin": return "<a href='/'>Go to main page</a><br /><br />error, site is read only!" if user == "anonymous" and anonymous != "yes": raise cherrypy.HTTPRedirect("login") query = Task.at(int(id)).select() result = query.execute() data = result.one() now = strftime("%Y-%m-%d %H:%M:%S", localtime()) output = "user:"******", owner:"+data.owner+"<br /><br />" if user != data.owner: if user != "admin": return "error! Not authorized!" else: # 若資料為主緒則一併刪除子緒, 若為子緒, 則只刪除該子緒 if data.follow == 0: # 表示資料為主緒 # 先刪除主緒 query = Task.at(int(id)).delete() query.execute() # 再刪除所有對應子緒 query = Task.where(follow=int(id)).delete() query.execute() output += "所有序列資料已經刪除!<br />" else: # 表示資料為子緒 query = Task.at(int(id)).delete() query.execute() output += "資料已經刪除!<br />" else: # 若資料為主緒則一併刪除子緒, 若為子緒, 則只刪除該子緒 if data.follow == 0: # 表示資料為主緒 # 先刪除主緒 query = Task.at(int(id)).delete() query.execute() # 再刪除所有對應子緒 query = Task.where(follow=int(id)).delete() query.execute() output += '''所有序列資料已經刪除!<br /><br /> <a href='/'>Go to main page</a><br /> ''' else: # 表示資料為子緒 query = Task.at(int(id)).delete() query.execute() output += '''資料已經刪除!<br /><br /> <a href='/'>Go to main page</a><br /> ''' return output
def taskaction(self, type=None, name=None, follow=0, content=None, ip=None, *args, **kwargs): if content == None or name == "": return "標題與內容都不可空白!<br /><a href='/'>Go to main page</a><br />" else: start_time = time.time() owner = self.printuser() if self.allow_pass(owner) == "no": raise cherrypy.HTTPRedirect("login") ip = self.client_ip() now = datetime.datetime.now(pytz.timezone('Asia/Taipei')).strftime('%Y-%m-%d %H:%M:%S') # user 若帶有 @ 則用 at 代替 if "@" in owner: owner = owner.replace('@', 'at') content = content.replace('\n', '') #invalid_tags = ['table', 'th', 'tr', 'td', 'html', 'body', 'head', 'javascript', 'script', 'tbody', 'thead', 'tfoot', 'div', 'span'] #content = self.clean_html(content, invalid_tags) valid_tags = ['a', 'br', 'h1', 'h2', 'h3', 'p', 'div', 'hr', 'img', 'iframe', 'li', 'ul', 'b', 'ol', 'pre'] tags = '' for tag in valid_tags: tags += tag content = self.strip_tags(content, tags) # 這裡要除掉 </br> 關閉 break 的標註, 否則在部分瀏覽器會產生額外的跳行 content = str(content).replace('</br>', '') time_elapsed = round(time.time() - start_time, 5) if ormdb == "sqlite": # 為了避免跨執行緒使用 SQLite3, 重新 connect 資料庫 Database.connect() # last insert id 為 data.id data = Task.create(owner=owner, name=str(name), type=type, time=str(now), follow=follow, content=content, ip=str(ip)) # 這裡要與 taskedit 相同, 提供回到首頁或繼續編輯按鈕 output = "<a href='/'>Go to main page</a><br />" output +="<a href='/taskeditform?id="+str(data.id)+"'>繼續編輯</a><br /><br />" output += '''以下資料已經更新:<br /><br /> owner:'''+owner+'''<br /> name:'''+name+'''<br /> type:'''+type+'''<br /> time:'''+str(now)+'''<br /> content:'''+str(content)+'''<br /><br /> <a href='/'>Go to main page</a><br /> ''' output +="<a href='/taskeditform?id="+str(data.id)+"'>繼續編輯</a><br /><br />" return output
def test_connect(self): Database.connect() assert Database.conn_is_up()
def taskdeleteform(self, id=None, *args, **kwargs): if ormdb == "sqlite": # 為了避免跨執行緒使用 SQLite3, 重新 connect 資料庫 Database.connect() user = self.printuser() password, adsense, anonymous, mail_suffix, site_closed, read_only = self.parse_config(filename="pygroup_config") if read_only == "yes" and user != "admin": return "<a href='/'>Go to main page</a><br /><br />error, site is read only!" if user == "anonymous" and anonymous != "yes": raise cherrypy.HTTPRedirect("login") else: try: # 這裡要區分刪除子緒或主緒資料 # 若刪除子緒, 則 data 只包含子緒資料, 若為主緒, 則 data 必須包含所有資料 # 先找出資料, 判定是否為主緒 query = Task.at(int(id)).select() result = query.execute() data = result.one() owner = data.owner if user != data.owner: if user != "admin": return output + "error! 非資料擁有者, Not authorized!" else: if data.follow == 0: # 表示該資料為主緒資料 # 資料要重新搜尋, 納入子資料 query = Task.where((Task.id == id) | (Task.follow == id)).select() result = query.execute() data = result.all() output = "資料為主緒資料<br />" # 增加一個資料類型判斷, main 表資料為主緒 type = "main" else: # 表示該資料為子緒資料 # 直接採用 data 資料送到 taskdeleteform.html output = "資料為子緒資料<br />" # 增加一個資料類型判斷, alone 表資料為子緒 type = "alone" output += "user:"******", owner:"+owner+"<br /><br />" template_lookup = TemplateLookup(directories=[template_root_dir+"/templates"]) mytemplate = template_lookup.get_template("taskdeleteform.html") # 這裡的 type 為所要刪除資料的類型, 為 main 或為 alone return mytemplate.render(user=user, id=id, data=data, type=type) else: if data.follow == 0: # 表示該資料為主緒資料 # 資料要重新搜尋, 納入子資料 query = Task.where((Task.id == id) | (Task.follow == id)).select() result = query.execute() data = result.all() output = "資料為主緒資料<br />" # 增加一個資料類型判斷, main 表資料為主緒 type = "main" else: # 表示該資料為子緒資料 # 直接採用 data 資料送到 taskdeleteform.html output = "資料為子緒資料<br />" # 增加一個資料類型判斷, alone 表資料為子緒 type = "alone" output += "user:"******", owner:"+owner+"<br /><br />" template_lookup = TemplateLookup(directories=[template_root_dir+"/templates"]) mytemplate = template_lookup.get_template("taskdeleteform.html") # 這裡的 type 為所要刪除資料的類型, 為 main 或為 alone return mytemplate.render(user=user, id=id, data=data, type=type) except: return "error! 無法正確查詢資料, Not authorized!"
def taskedit(self, id=None, type=None, name=None, content=None, *args, **kwargs): if ormdb == "sqlite": # 為了避免跨執行緒使用 SQLite3, 重新 connect 資料庫 Database.connect() # check user and data owner if id == None: return "error<br /><br /><a href='/'>Go to main page</a><br />" user = self.printuser() password, adsense, anonymous, mail_suffix, site_closed, read_only = self.parse_config(filename="pygroup_config") if read_only == "yes" and user != "admin": return "<a href='/'>Go to main page</a><br /><br />error, site is read only!" if user == "anonymous" and anonymous != "yes": raise cherrypy.HTTPRedirect("login") query = Task.at(int(id)).select() result = query.execute() data = result.one() now = strftime("%Y-%m-%d %H:%M:%S", localtime()) # Python 3.x: #import html.parser #html_parser = html.parser.HTMLParser() #content = html_parser.unescape(content) # 過濾資料 content = content.replace('\n', '') #invalid_tags = ['table', 'th', 'tr', 'td', 'html', 'body', 'head', 'javascript', 'script', 'tbody', 'thead', 'tfoot', 'div', 'span'] #content = self.clean_html(content, invalid_tags) valid_tags = ['a', 'br', 'h1', 'h2', 'h3', 'p', 'div', 'hr', 'img', 'iframe', 'li', 'ul', 'b', 'ol', 'pre'] tags = '' for tag in valid_tags: tags += tag content = self.strip_tags(content, tags) #content = self.html_filter(content, valid_tags) # 這裡要除掉 </br> 關閉 break 的標註, 否則在部分瀏覽器會產生額外的跳行 content = str(content).replace('</br>', '') output = "user:"******", owner:"+data.owner+"<br /><br />" if user != data.owner: if user != "admin": return "error! Not authorized!" else: query = Task.at(int(id)).update(type=type, name=name, content=content, time=str(now)) query.execute() output += "<a href='/'>Go to main page</a><br />" output +="<a href='/taskeditform?id="+str(id)+"'>繼續編輯</a><br /><br />" output += '''以下資料已經更新:<br /><br /> owner:'''+data.owner+'''<br /> name:'''+name+'''<br /> type:'''+type+'''<br /> time:'''+str(now)+'''<br /> content:'''+str(content)+'''<br /><br /> <a href='/'>Go to main page</a><br /> ''' output +="<a href='/taskeditform?id="+str(id)+"'>繼續編輯</a><br />" else: query = Task.at(int(id)).update(type=type, name=name, content=str(content), time=str(now)) query.execute() output += "<a href='/'>Go to main page</a><br />" output +="<a href='/taskeditform?id="+str(id)+"'>繼續編輯</a><br /><br />" output += '''以下資料已經更新:<br /><br /> owner:'''+data.owner+'''<br /> name:'''+name+'''<br /> type:'''+type+'''<br /> time:'''+str(now)+'''<br /> content:'''+str(content)+'''<br /><br /> <a href='/'>Go to main page</a><br /> ''' output +="<a href='/taskeditform?id="+str(id)+"'>繼續編輯</a><br />" return output
def index(self, page=1, item_per_page=5, id=0, flat=0, desc=0, keyword=None, *args, **kwargs): if ormdb == "sqlite": # 為了避免跨執行緒使用 SQLite3, 重新 connect 資料庫 Database.connect() user = self.printuser() # 這裡不用 self.allow_pass 原因在於需要 adsense 變數 saved_password, adsense, anonymous, mail_suffix, site_closed, read_only = self.parse_config(filename="pygroup_config") if user == "anonymous" and anonymous != "yes": if id != 0: raise cherrypy.HTTPRedirect("login?id="+id) else: raise cherrypy.HTTPRedirect("login") if adsense == "yes": filename = data_dir+"adsense_content" with open(filename, encoding="utf-8") as file: adsense_content = file.read() else: adsense_content = "" #ip = cherrypy.request.remote.ip ip = self.client_ip() template_lookup = TemplateLookup(directories=[template_root_dir+"/templates"]) # 必須要從 templates 目錄取出 tasklist2.html mytemplate = template_lookup.get_template("tasklist.html") # 這裡要加入單獨根據 id 號, 列出某一特定資料緒的分支 # 若 id 為 0 表示非指定列出各別主緒資料, 而是列出全部資料 # 這時可再根據各筆資料列印時找出各主緒資料的附屬資料筆數 # 加入 flat = 1 時, 列出所有資料 # 請注意這裡直接從 tasksearchform.html 中的關鍵字查詢, 指定以 tasklist 執行, 但是無法單獨列出具有關鍵字的 task 資料, 而是子緒有關鍵字時, 也是列出主緒資料 if keyword == None: if id == 0: if flat == 0: # 只列出主資料緒 # desc 為 0 表示要 id 由小到大排序列出資料 if desc == 0: method = "?" query = Task.where(Task.follow==0).select() else: # desc 為 1 表示 id 反向排序 method = "?desc=1" query = Task.where(Task.follow==0).orderby(Task.id, desc=True).select() result = query.execute() data = result.all() else: # flat 為 1 表示要列出所有資料 # 原先沒有反向排序, 內建使用正向排序 if desc == 0: method = "?flat=1" query = Task.select() else: method = "?flat=1&desc=1" query = Task.orderby(Task.id, desc=True).select() result = query.execute() data = result.all() else: method = "?id="+str(id) # 設法列出主資料與其下屬資料緒, 這裡是否可以改為 recursive 追蹤多緒資料 # 只列出主緒與下一層子緒資料 query = Task.where((Task.id == id) | (Task.follow == id)).select() result = query.execute() data = result.all() else: # 有關鍵字查詢時(只查 owner, content, type 與 name), 只列出主資料緒 #flat = 1 method = "?keyword="+keyword+"&flat="+str(flat) query = Task.where((Task.content.like('%%%s%%' % (keyword))) | (Task.name.like('%%%s%%' % (keyword))) | \ (Task.owner.like('%%%s%%' % (keyword))) | \ (Task.type.like('%%%s%%' % (keyword))) \ ).select() result = query.execute() data = result.all() follow = [] for task in data: # 改為 mysql query = Task.where((Task.follow == task.id)).select() result = query.execute() follow_data = result.all() follow.append(len(follow_data)) # # 送出 user, id, flat, method 與 data # # 增加傳送 read_only, 若 read_only = yes 則不列出 taskform, 而且所有新增編輯刪除功能均失效 # return mytemplate.render(user=user, id=id, flat=flat, method=method, data=data, \ page=page, item_per_page=item_per_page, ip=ip, follow=follow, keyword=keyword, \ adsense_content=adsense_content, adsense=adsense, anonymous=anonymous, \ site_closed=site_closed, read_only=read_only)