OSDN Git Service

Merge branch 'mongodb'
[pybbs/pybbs.git] / index.py
1
2 import os
3 import re
4 import tornado.escape
5 import tornado.web
6 import pymongo
7 from datetime import datetime
8
9 class BaseHandler(tornado.web.RequestHandler):
10     def get_current_user(self):
11         user = self.get_secure_cookie('admin_user')
12         return tornado.escape.utf8(user)
13     
14     def set_current_user(self,username):
15         self.set_secure_cookie('admin_user',username)
16         
17     def clear_current_user(self):
18         self.clear_cookie('admin_user')
19
20 class IndexHandler(BaseHandler):
21     def get(self,dbname,page='0'):
22         params = self.application.db['params'].find_one()
23         if params['mentenance'] == True:
24             self.render('mentenance.htm',title=params['title'],db=dbname)
25         if self.application.collection(dbname) == False:
26             if self.current_user == b'admin':
27                 self.application.db[dbname]
28             else:
29                 raise tornado.web.HTTPError(404)
30                 return
31         i = params['count']      
32         na = tornado.escape.url_unescape(self.get_cookie("username",u"誰かさん"))
33         pos = self.application.gpos(dbname,page)
34         table = self.application.db[dbname]
35         start = (pos-1)*i
36         if start < 0:
37             start = table.count()-i
38             if start < 0:
39                 start = 0
40         rec = table.find()
41         rec.sort('number')
42         rec.skip(start).limit(i)
43         if table.count() >= 10*i:
44             self.render('modules/full.htm',position=pos,records=rec,data=params,db=dbname)
45             return
46         self.render('modules/index.htm',position=pos,records=rec,data=params,username=na,db=dbname)
47         
48 class LoginHandler(BaseHandler):
49     def get(self):
50         self.render('login.htm')
51         
52     def post(self):
53         pw = self.application.db['params'].find_one()
54         if self.get_argument('password') == pw['password']:
55             self.set_current_user('admin')
56         dbname = self.get_argument('record')
57         self.redirect('/'+dbname+'/admin/0/')
58         
59 class LogoutHandler(BaseHandler):
60     def get(self):
61         self.clear_current_user()
62         self.redirect('/login')
63         
64 class NaviHandler(tornado.web.RequestHandler):
65     def get(self):
66         coll = self.application.db.collection_names()
67         del coll[0:3]           
68         coll.remove('params')                 
69         self.render('top.htm',coll=coll,full=self.full)
70                       
71     def full(self,dbname):
72         if dbname in self.application.db.collection_names():
73             i = 10*self.application.db['params'].find_one()['count']
74             table = self.application.db[dbname]
75             if table.count() >= i:
76                 return True
77         return False
78
79 class TitleHandler(NaviHandler):
80     def get(self):
81         rec = sorted(self.title(),key=lambda x: x['date2'])
82         self.render('title.htm',coll=rec,full=self.full)  
83         
84     def title(self):
85         name = self.application.db.collection_names()
86         del name[0:3]
87         name.remove('params')
88         for x in name:
89             item = {}
90             item['name'] = x
91             table = self.application.db[x]
92             i = table.count()
93             item['count'] = i            
94             tmp = table.find_one({'number':1})
95             if tmp:
96                 s = tmp['title']
97             else:
98                 s = ''
99             item['title'] = s   
100             if i == 0:
101                 item['date'] = ''
102                 item['date2'] = 0
103             else:
104                 rec = table.find().sort('number')
105                 s = rec[i-1]['date']
106                 item['date'] = s
107                 i = datetime.strptime(s,'%Y/%m/%d %H:%M')
108                 year = datetime.now().year-i.year
109                 if year == 0:
110                     j = 800
111                 elif year == 1:
112                     j = 400
113                 else:
114                     j = 0
115                 item['date2'] = j+31*(i.month-1)+i.day
116             yield item
117         
118 class RegistHandler(tornado.web.RequestHandler):
119     def post(self,dbname):
120         if self.application.collection(dbname) == False:
121             raise tornado.web.HTTPError(404)
122             return
123         rec = self.application.db[dbname].find_one()
124         words = rec['bad_words']
125         out = rec['out_words']
126         na = self.get_argument('name')
127         sub = self.get_argument('title')
128         com = self.get_argument('comment')
129         text = ''
130         i = 0
131         error = ''
132         for word in out:
133             if word in com:
134                 error = error + u'禁止ワード.'
135                 break
136         for line in com.splitlines(True):
137             for word in words:
138                 if word in line.lower():
139                     error = error + u'タグ違反.('+word+')'       
140             i += len(line)
141             text = text+'<p>'+self.link(line)+'<br></p>'
142         pw = self.get_argument('password')
143         if sub == '':
144             sub = u'タイトルなし.'
145         if i == 0:
146             error = error + u'本文がありません.'
147         elif i > 1000:
148             error = error +u'文字数が1,000をこえました.'
149         article = self.application.db[dbname]
150         if article.count() == 0:
151             no = 1
152         else:            
153             items = article.find()
154             item = items.sort('number')[article.count()-1]
155             no = item['number']+1
156         if error == '':
157             s = datetime.now()
158             reg = {'number':no,'name':na,'title':sub,'comment':text,'raw':com,'password':pw,'date':s.strftime('%Y/%m/%d %H:%M')}
159             article.insert(reg)
160             self.set_cookie('username',tornado.escape.url_escape(na))
161             self.redirect('/'+dbname+'#article')
162         else:
163             self.render('regist.htm',content=error)
164     
165     def link(self,command):
166         y = ''
167         i = 0
168         text = ''
169         for x in command.split():
170             if (y == '>>')and(x.isdecimal() == True):
171                 s = '<a href=#'+x+'>'+x+'</a>'
172                 while -1 < command.find(x,i):
173                     j = command.find(x,i)
174                     tmp = command[i:j]
175                     i = j+len(x)
176                     k = tmp.rsplit(None,1)
177                     if ((len(k) > 1)and(k[1] == y))or(k[0] == y):
178                         text = text+tmp+s                                                                       
179                         break
180                     else:
181                         text = text+tmp+x                        
182             y = x    
183         if text == '':
184             return command
185         else:
186             if len(command) > i:
187                 return text+command[i:]
188             else:
189                 return text
190     
191 class AdminHandler(BaseHandler):
192     @tornado.web.authenticated               
193     def get(self,dbname,page='0'):
194         if dbname == '':
195             dbname = self.get_argument('record','')
196         if self.application.collection(dbname) == False:
197             raise tornado.web.HTTPError(404)
198             return
199         table = self.application.db[dbname] 
200         rec = table.find().sort('number')                   
201         mente = self.application.db['params'].find_one()
202         if mente['mentenance'] == True:
203             check = 'checked=checked'
204         else:
205             check = ''
206         pos = self.application.gpos(dbname,page)
207         i = mente['count']
208         start = (pos-1)*i
209         if start < 0:
210             start = table.count()-i
211             if start < 0:
212                 start = 0
213         rec.skip(start).limit(i)
214         self.render('modules/admin.htm',position=pos,records=rec,mente=check,password=mente['password'],db=dbname)
215
216 class AdminConfHandler(BaseHandler):
217     @tornado.web.authenticated
218     def post(self,dbname,func):
219         if func == 'set':
220             param = self.application.db['params'].find_one()
221             if self.get_argument('mente','') == 'on':
222                 mente = True
223             else:
224                 mente = False  
225             word = self.get_argument('pass','')
226             if word == '':
227                 self.render('regist.htm',content='パスワードを設定してください')
228                 return
229             else:
230                 param['mentenance']=mente
231                 param['password']=word  
232                 self.application.db['params'].save(param)
233         elif func == 'del':
234             table = self.application.db[dbname]
235             for x in self.get_arguments('item'):
236                 table.remove({'number':int(x)})
237         self.redirect('/'+dbname+'/admin/0/')
238           
239 class UserHandler(tornado.web.RequestHandler):
240     def post(self,dbname):
241         num = int(self.get_argument('number'))
242         pas = self.get_argument('password')
243         table = self.application.db[dbname]
244         obj = table.find_one({'number':num})
245         if obj and(obj['password'] == pas):
246             table.remove({'number':num})
247         self.redirect('/'+dbname)
248       
249 class SearchHandler(tornado.web.RequestHandler):       
250     def post(self,dbname):
251         self.word = tornado.escape.url_unescape(self.get_argument('word1'))
252         self.radiobox = self.get_argument('filter')
253         self.set_cookie('search',tornado.escape.url_escape(self.word))         
254         rec = sorted(self.search(dbname),key=lambda x: x['number'])
255         self.render('modules/search.htm',records=rec,word1=self.word,db=dbname)
256     
257     def get(self,dbname):
258         if self.application.collection(dbname) == False:
259             raise tornado.web.HTTPError(404)
260             return
261         word = self.get_cookie('search','')
262         word = tornado.escape.url_unescape(word)
263         self.render('modules/search.htm',records=[],word1=word,db=dbname)
264         
265     def search(self,dbname):
266         table = self.application.db[dbname]    
267         element = self.word.split()
268         if len(element) == 0:
269             element = ['']
270         while len(element) < 3:
271             element.append(element[0])
272         if self.radiobox == 'comment':    
273             for x in table.find({'$or':[{'name':re.compile(element[0])},{'name':re.compile(element[1])},{'name':re.compile(element[2])}]}):
274                 com = ''
275                 for text in x['raw'].splitlines(True):                  
276                     for word in self.word.split():                        
277                         if text.find(word) > -1:
278                             com = com +'<p style=background-color:yellow>'+text+'<br></p>'  
279                             break                          
280                     else:
281                         com = com+'<p>'+text+'<br></p>'
282                 x['comment'] = com
283                 yield x       
284         else:
285             for x in table.find({'$or':[{'name':element[0]},{'name':element[1]},{'name':element[2]}]}):
286                 yield x    
287                                         
288 class FooterModule(tornado.web.UIModule):
289     def render(self,number,url,link):
290         return self.render_string('modules/footer.htm',index=number,url=url,link=link)
291     
292 class Application(tornado.web.Application):    
293     def __init__(self):
294         handlers = [(r'/',NaviHandler),(r'/login',LoginHandler),(r'/logout',LogoutHandler),(r'/title',TitleHandler),
295                     (r'/([a-zA-Z0-9_]+)',IndexHandler),(r'/([a-zA-Z0-9_]+)/([0-9]+)/',IndexHandler),
296                     (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),
297                     (r'/([a-zA-Z0-9_]+)/search',SearchHandler),(r'/([a-zA-Z0-9_]+)/regist',RegistHandler)]
298         settings = {'template_path':os.path.join(os.path.dirname(__file__),'pybbs'),
299                         'static_path':os.path.join(os.path.dirname(__file__),'static'),
300                         'ui_modules':{'Footer':FooterModule},
301                         'cookie_secret':'bZJc2sWbQLKos6GkHn/VB9oXwQt8SOROkRvJ5/xJ89E=',
302                         'xsrf_cookies':True,
303                         #'debug':True,
304                         'login_url':'/login'
305                         }
306         tornado.web.Application.__init__(self,handlers,**settings)
307  
308     def gpos(self,dbname,page):
309         params = self.db['params'].find_one()
310         pos = int(page)
311         if pos <= 0:
312             pos = 0
313         elif (pos-1)*params['count'] >= self.db[dbname].count():
314             pos = 0
315         return pos
316     
317     def collection(self,name):
318         if name in self.db.collection_names():
319             return True
320         else:
321             return False
322
323 app = Application()
324 MONGOLAB_URI = 'mongodb://kainushi:1234abcd@ds113678.mlab.com:13678/heroku_n905jfw2'
325 conn = pymongo.MongoClient(MONGOLAB_URI,13678)
326 app.db = conn.heroku_n905jfw2