OSDN Git Service

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