OSDN Git Service

commit from git hub
[pybbs/pybbs.git] / pybbs.py
1 '''
2 Created on 2016/10/23
3
4 @author: fukemasashi
5 '''
6 import os.path
7 import tornado.auth
8 import tornado.escape
9 import tornado.httpserver
10 import tornado.ioloop
11 import tornado.options
12 import tornado.web
13 from tornado.options import define,options
14 import pymongo
15 from datetime import datetime
16
17 define('port',default=8000,help='run on the given port.',type=int)
18
19 class BaseHandler(tornado.web.RequestHandler):
20     def get_current_user(self):
21         user = self.get_secure_cookie('admin_user')
22         return tornado.escape.utf8(user)
23     
24     def set_current_user(self,username):
25         self.set_secure_cookie('admin_user',username)
26         
27     def clear_current_user(self):
28         self.clear_cookie('admin_user')
29
30 class IndexHandler(tornado.web.RequestHandler):
31     def get(self,dbname,page='0'):
32         if self.application.collection(dbname) == False:
33             self.render('regist.htm',content='urlが見つかりません')
34             return
35         params = self.application.db['params'].find_one()  
36         i = params['count']      
37         na = self.get_cookie('username')
38         pos = self.application.gpos(dbname,page)
39         col = self.application.db[dbname]
40         rec = col.find()
41         rec.sort('number')
42         start = (pos-1)*i
43         if start < 0:
44             start = col.count()-i
45             if start < 0:
46                 start = 0
47         rec.limit(i)[start:start+i]
48         if col.count() >= 10*i:
49             self.render('modules/full.htm',position=pos,records=rec,data=params,db=dbname)
50             return  
51         self.render('modules/index.htm',position=pos,records=rec,data=params,username=na,db=dbname)
52         
53 class LoginHandler(BaseHandler):
54     def get(self):
55         self.render('login.htm')
56         
57     def post(self):
58         pw = self.application.db['params'].find_one()
59         if self.get_argument('password') == pw['password']:
60             self.set_current_user('admin')
61         dbname = self.get_argument('record')
62         self.redirect('/'+dbname+'/admin/0/')
63         
64 class LogoutHandler(BaseHandler):
65     def get(self):
66         self.clear_current_user()
67         db = self.get_argument('db')
68         self.redirect('/'+db)
69         
70 class NaviHandler(tornado.web.RequestHandler):
71     def get(self):
72         coll = self.application.db.collection_names(include_system_collections=False)
73         self.render('top.htm',coll=coll)
74
75 class RegistHandler(tornado.web.RequestHandler):
76     def post(self,dbname):
77         if self.application.collection(dbname) == False:
78             self.render('regist.htm',content='urlが存在しません')
79             return 
80         words = ['<link','<script','<style','<img']
81         out = ['ばか','死ね','あほ']
82         na = self.get_argument('name')
83         sub = self.get_argument('title')
84         com = self.get_argument('comment')
85         text = ''
86         i = 0
87         error = ''
88         for line in com.splitlines(True):
89             for word in words:
90                 if word in line:
91                     error = error + u'タグ違反.('+word+')'       
92             text = text+'<p>'+line
93             i += len(line)
94         for word in out:
95             if word in text:
96                 error = error + u'禁止ワード.'
97                 break
98         pw = self.get_argument('password')
99         if na == '':
100             na = u'誰かさん'
101         if sub == '':
102             sub = u'タイトルなし.'
103         if i == 0:
104             error = error + u'本文がありません.'
105         elif i > 1000:
106             error = error +u'文字数が1,000をこえました.'
107         article = self.application.db[dbname]
108         rec = article.find()
109         rec.sort('number',-1)
110         if article.count() == 0:
111             no = 1
112         else:
113             item = rec.limit(1)[0]
114             no = item['number']+1
115         if error == '':
116             reg = {'number':no,'name':na,'title':sub,'comment':text,'password':pw,'date':datetime.now()}
117             article.insert(reg)
118             self.set_cookie('username',na)
119             self.redirect('/'+dbname+'#article')
120         else:
121             self.render('regist.htm',content=error)
122
123 class AdminHandler(BaseHandler):
124     @tornado.web.authenticated               
125     def get(self,dbname,page='0'):
126         if dbname == '':
127             dbname = self.get_argument('record')
128         if self.application.collection(dbname) == False:
129             self.render('regist.htm',content='urlが見つかりません')
130             return
131         self.check_xsrf_cookie()
132         coll = self.application.db[dbname] 
133         rec = coll.find()                   
134         param = self.application.db['params']
135         mente = param.find_one()
136         pos = self.application.gpos(dbname,page)
137         self.render('modules/admin.htm',position=pos,records=rec,mente=mente['mentenance'],password=mente['password'],db=dbname)
138
139 class AdminConfHandler(BaseHandler):
140     @tornado.web.authenticated
141     def post(self,dbname,func):
142         if func == 'set':
143             coll = self.application.db['params']
144             mente = coll.find_one()
145             mente['mentenance'] = self.get_argument('mente')  
146             mente['password'] = self.get_argument('pass')
147             coll.save(mente)     
148         elif func == 'del':
149             coll = self.application.db[dbname]
150             for x in self.get_arguments():
151                 rec = coll.find_one({'number',x})
152                 if rec:
153                     coll.remove(rec)
154         self.redirect('/'+dbname+'/admin/0/')
155           
156 class UserHandler(tornado.web.RequestHandler):
157     def post(self,dbname):
158         num = int(self.get_argument('number'))
159         pas = self.get_argument('password')
160         coll = self.application.db[dbname]
161         obj = coll.find_one({'number':num})
162         if obj and(obj['password'] == pas):
163             coll.remove({'number':num})
164         self.redirect('/'+dbname)
165       
166 class SearchHandler(tornado.web.RequestHandler):       
167     def post(self,dbname):
168         self.word = self.get_argument('word1')
169         self.radiobox = self.get_argument('filter')
170         rec = self.application.db[dbname]
171         self.render('modules/search.htm',records=self.mylist(rec),word1=self.word,db=dbname)
172     
173     def get(self,dbname):
174         word = self.get_cookie('search')
175         self.render('modules/search.htm',records={},word1=word,db=dbname)
176         
177     def mylist(self,rec):
178         for searchrec in rec.find():       
179             if self.radiobox == 'name':
180                 if searchrec['name'].find(self.word) == True:
181                     yield searchrec
182             else:
183                 if searchrec['comment'].find(self.word) == True:
184                     yield searchrec
185         
186 class FooterModule(tornado.web.UIModule):
187     def render(self,number,url,link):
188         return self.render_string('modules/footer.htm',index=number,url=url,link=link)
189     
190 class Applications(tornado.web.Application):    
191     def __init__(self):
192         client = pymongo.MongoClient()
193         self.db = client['mydatabase']
194         handlers = [(r'/',NaviHandler),(r'/login',LoginHandler),(r'/logout',LogoutHandler),(r'/([a-z]+)',IndexHandler),(r'/([a-z]+)/([0-9]+)/',IndexHandler),
195                     (r'/([a-z]+)/admin/([0-9]+)/',AdminHandler),(r'/([a-z]+)/admin/([a-z]+)/',AdminConfHandler),(r'/([a-z]+)/userdel',UserHandler),
196                     (r'/([a-z]+)/search',SearchHandler),(r'/([a-z]+)/regist',RegistHandler)]
197         settings = {'template_path':os.path.join(os.path.dirname(__file__),'pybbs'),
198                         'static_path':os.path.join(os.path.dirname(__file__),'static'),
199                         'ui_modules':{'Footer':FooterModule},
200                         'cookie_secret':'bZJc2sWbQLKos6GkHn/VB9oXwQt8SOROkRvJ5/xJ89E=',
201                         'xsrf_cookies':True,
202                         'debug':True,
203                         'login_url':'/login'
204                         }
205         tornado.web.Application.__init__(self,handlers,**settings)
206  
207     def gpos(self,dbname,page):
208         coll = self.db['params']
209         params = coll.find_one()
210         pos = int(page)
211         if pos <= 0:
212             pos = 0
213         elif (pos-1)*params['count'] >= self.db[dbname].count():
214             pos = 0
215         return pos
216     
217     def collection(self,name):
218         for x in self.db.collection_names():
219             if x == name:
220                 return True
221         else:
222             return False
223         
224 if __name__ == '__main__':
225     tornado.options.parse_command_line()
226     http_server = tornado.httpserver.HTTPServer(Applications())
227     http_server.listen(options.port)
228     tornado.ioloop.IOLoop.instance().start()