7 from tinydb import TinyDB,Query,where
8 from tinydb.storages import MemoryStorage
9 from tinydb.operations import delete
10 from datetime import datetime
12 class BaseHandler(tornado.web.RequestHandler):
13 def get_current_user(self):
14 user = self.get_secure_cookie('admin_user')
15 return tornado.escape.utf8(user)
17 def set_current_user(self,username):
18 self.set_secure_cookie('admin_user',username)
20 def clear_current_user(self):
21 self.clear_cookie('admin_user')
23 class IndexHandler(BaseHandler):
24 def get(self,dbname,page='0'):
25 params = self.application.db.get(where('kinds') == 'conf')
26 if params['mentenance'] == True:
27 self.render('mentenance.htm',title=params['title'],db=dbname)
28 if self.application.collection(dbname) == False:
29 if self.current_user == b'admin':
30 self.application.db.table(dbname)
32 raise tornado.web.HTTPError(404)
35 na = tornado.escape.url_unescape(self.get_cookie("username",u"誰かさん"))
36 pos = self.application.gpos(dbname,page)
37 table = self.application.db.table(dbname)
43 rec = sorted(table.all(),key=lambda x: x['number'])[start:start+i]
44 if len(table) >= 10*i:
45 self.render('modules/full.htm',position=pos,records=rec,data=params,db=dbname)
47 self.render('modules/index.htm',position=pos,records=rec,data=params,username=na,db=dbname)
49 class LoginHandler(BaseHandler):
51 self.render('login.htm')
54 pw = self.application.db.get(where('kinds') == 'conf')
55 if self.get_argument('password') == pw['password']:
56 self.set_current_user('admin')
57 dbname = self.get_argument('record')
58 self.redirect('/'+dbname+'/admin/0/')
60 class LogoutHandler(BaseHandler):
62 self.clear_current_user()
63 self.redirect('/login')
65 class NaviHandler(tornado.web.RequestHandler):
67 self.render('top.htm',coll=sorted(self.name()),full=self.full)
70 for x in self.application.db.tables():
74 def full(self,dbname):
75 if dbname in self.application.db.tables():
76 i = 10*self.application.db.get(where('kinds') == 'conf')['count']
77 table = self.application.db.table(dbname)
82 class TitleHandler(NaviHandler):
84 self.render('title.htm',coll=self.name(),full=self.full,
85 count=self.count,title=self.title,update=self.update)
87 def count(self,dbname):
88 if dbname in self.application.db.tables():
89 return len(self.application.db.table(dbname))
93 def title(self,dbname):
94 if dbname in self.application.db.tables():
95 table = self.application.db.table(dbname)
96 if table.contains(where('number') == 1) == True:
97 dic = table.get(where('number') == 1)
102 def update(self,dbname):
103 if dbname in self.application.db.tables():
104 table = self.application.db.table(dbname)
109 rec = sorted(table.all(),key=lambda x: x['number'])
110 return rec[i-1]['date']
112 class RegistHandler(tornado.web.RequestHandler):
113 def post(self,dbname):
114 if self.application.collection(dbname) == False:
115 raise tornado.web.HTTPError(404)
117 rec = self.application.db.get(where('kinds') == 'conf')
118 words = rec['bad_words']
119 out = rec['out_words']
120 na = self.get_argument('name')
121 sub = self.get_argument('title')
122 com = self.get_argument('comment')
128 error = error + u'禁止ワード.'
130 for line in com.splitlines(True):
133 error = error + u'タグ違反.('+word+')'
135 text = text+'<p>'+self.link(line)+'<br></p>'
136 pw = self.get_argument('password')
140 error = error + u'本文がありません.'
142 error = error +u'文字数が1,000をこえました.'
143 article = self.application.db.table(dbname)
144 if len(article) == 0:
147 item = sorted(article.all(),key=lambda x: x['number'])[len(article)-1]
148 no = item['number']+1
150 reg = {'number':no,'name':na,'title':sub,'comment':text,'raw':com,'password':pw,'date':datetime.now().strftime('%Y/%m/%d %H:%M')}
153 self.set_cookie('username',tornado.escape.url_escape(na))
154 self.redirect('/'+dbname+'#article')
156 self.render('regist.htm',content=error)
158 def link(self,command):
162 for x in command.split():
163 if (y == '>>')and(x.isdecimal() == True):
164 s = '<a href=#'+x+'>'+x+'</a>'
165 while -1 < command.find(x,i):
166 j = command.find(x,i)
169 k = tmp.rsplit(None,1)
170 if ((len(k) > 1)and(k[1] == y))or(k[0] == y):
180 return text+command[i:]
184 class AdminHandler(BaseHandler):
185 @tornado.web.authenticated
186 def get(self,dbname,page='0'):
188 dbname = self.get_argument('record','')
189 if self.application.collection(dbname) == False:
190 raise tornado.web.HTTPError(404)
192 table = self.application.db.table(dbname)
193 rec = sorted(table.all(),key=lambda x: x['number'])
194 mente = self.application.db.get(where('kinds') == 'conf')
195 if mente['mentenance'] == True:
196 check = 'checked=checked'
199 pos = self.application.gpos(dbname,page)
207 self.application.db = TinyDB(st.json)
208 self.render('modules/admin.htm',position=pos,records=rec[start:start+i],mente=check,password=mente['password'],db=dbname)
210 class AdminConfHandler(BaseHandler):
211 @tornado.web.authenticated
212 def post(self,dbname,func):
214 param = self.application.db.get(where('kinds') == 'conf')['mentenance']
215 if self.get_argument('mente','') == 'on':
223 word = self.get_argument('pass','')
225 self.render('regist.htm',content='パスワードを設定してください')
228 self.application.db.update({'mentenance':mente,'password':word},where('kinds') == 'conf')
230 table = self.application.db.table(dbname)
231 for x in self.get_arguments('item'):
232 table.remove(where('number') == int(x))
234 self.redirect('/'+dbname+'/admin/0/')
237 self.application.db.close()
238 shutil.copy(st.json,st.bak)
239 self.application.db = TinyDB(st.json)
242 database = self.application.db
244 for x in database.tables():
245 if self.application.collection(x) == True:
246 database.purge_table(x)
247 if x in bak.tables():
248 table = database.table(x)
249 table.insert_multiple(bak.table(x).all())
252 class UserHandler(tornado.web.RequestHandler):
253 def post(self,dbname):
254 num = int(self.get_argument('number'))
255 pas = self.get_argument('password')
256 table = self.application.db.table(dbname)
258 obj = table.get(qwr.number == num)
259 if obj and(obj['password'] == pas):
260 table.remove(qwr.number == num)
261 self.redirect('/'+dbname)
263 class SearchHandler(tornado.web.RequestHandler):
264 def post(self,dbname):
265 self.word = tornado.escape.url_unescape(self.get_argument('word1'))
266 self.radiobox = self.get_argument('filter')
267 self.set_cookie('search',tornado.escape.url_escape(self.word))
268 rec = self.search(dbname)
269 self.render('modules/search.htm',records=rec,word1=self.word,db=dbname)
271 def get(self,dbname):
272 if self.application.collection(dbname) == False:
273 raise tornado.web.HTTPError(404)
275 word = tornado.escape.url_unescape(self.get_cookie('search'))
276 self.render('modules/search.htm',records=[],word1=word,db=dbname)
278 def search(self,name):
279 table = self.application.db.table(name)
280 element = self.word.split()
281 if len(element) == 0:
283 while len(element) < 3:
284 element.append(element[0])
285 if self.radiobox == 'comment':
286 query = (Query().raw.search(element[0])) | (Query().raw.search(element[1])) | (Query().raw.search(element[2]))
288 query = (Query().name == element[0]) | (Query().name == element[1]) | (Query().name == element[2])
289 if self.radiobox == 'comment':
291 mem = TinyDB(storage=MemoryStorage)
292 for x in table.search(query):
294 for text in x['raw'].splitlines(True):
295 for word in self.word.split():
296 if text.find(word) > -1:
297 result = result+'<p style=background-color:yellow>'+text+'<br></p>'
300 result = result+'<p>'+text+'<br></p>'
302 mem.update({'comment':result},eids=[i])
303 rec = sorted(mem.all(),key=lambda x: x['number'])
307 rec = table.search(query)
308 return sorted(rec,key=lambda x: x['number'])
310 class FooterModule(tornado.web.UIModule):
311 def render(self,number,url,link):
312 return self.render_string('modules/footer.htm',index=number,url=url,link=link)
314 class Application(tornado.web.Application):
316 self.db = TinyDB(st.json)
317 handlers = [(r'/',NaviHandler),(r'/login',LoginHandler),(r'/logout',LogoutHandler),(r'/title',TitleHandler),
318 (r'/([a-zA-Z0-9_]+)',IndexHandler),(r'/([a-zA-Z0-9_]+)/([0-9]+)/',IndexHandler),
319 (r'/([a-zA-Z0-9_]+)/admin/([0-9]+)/',AdminHandler),(r'/([a-zA-Z0-9_]+)/admin/([a-z]+)/',AdminConfHandler),(r'/([a-zA-Z0-9_]+)/userdel',UserHandler),
320 (r'/([a-zA-Z0-9_]+)/search',SearchHandler),(r'/([a-zA-Z0-9_]+)/regist',RegistHandler)]
321 settings = {'template_path':os.path.join(os.path.dirname(__file__),'pybbs'),
322 'static_path':os.path.join(os.path.dirname(__file__),'static'),
323 'ui_modules':{'Footer':FooterModule},
324 'cookie_secret':'bZJc2sWbQLKos6GkHn/VB9oXwQt8SOROkRvJ5/xJ89E=',
329 tornado.web.Application.__init__(self,handlers,**settings)
331 def gpos(self,dbname,page):
332 params = self.db.get(where('kinds') == 'conf')
336 elif (pos-1)*params['count'] >= len(self.db.table(dbname)):
340 def collection(self,name):
341 for x in self.db.tables():
348 json = 'static/db/db.json'
349 bak = 'static/db/bak.json'
357 #app.db = TinyDB(st.json)