Статьи

простая вики с web.py

Здесь попал в web.py , пока он еще не был выпущен и зацепил дизайн API и комментарий, сделанный здесь Аароном.

Третий принцип заключается в том, что web.py по умолчанию должен делать правильные вещи в Интернете. Это означает, что нужно правильно различать GET и POST. Это означает простые канонические URL-адреса, на которые перенаправляются синонимы. Это означает читаемый HTML с правильными заголовками HTTP.

С тех пор web.py был выпущен с начальной реакцией здесь — согласитесь с этими замечаниями, поэтому не нужно повторяться.

Более интересным было взломать что-то вместе с ним — очень простую вики, которая заняла около 2 часов, чтобы добраться туда, где она находится (ниже), при чтении документации и учебника . Обратите внимание, что это не очень красивый код — HTML-код, встроенный напрямую, нарушает принцип Аарона (и я не хотел возиться с Гепардом ), плюс мои навыки Python не самые лучшие, но, возможно, это полезный пример для начинающих.

Чтобы установить и запустить (Linux) файл типа wiki.py выполните следующие действия;

$ wget http://webpy.org/web.py $ wget http://webpy.org/markdown.py $ mkdir pages $ chmod +x wiki.py $ ./wiki.py
$ wget http://webpy.org/web.py $ wget http://webpy.org/markdown.py $ mkdir pages $ chmod +x wiki.py $ ./wiki.py 

Затем, чтобы начать, укажите ваш браузер на http: // localhost: 8080 / page / somepage

Код;

#!/usr/bin/python import web from markdown import Markdown import os, time, re, cgi # For debugging use only web.internalerror = web.debugerror urls = ( '/', 'WikiPages', '/page/([a-zA-Z_]+)', 'WikiPage', '/editor/([a-zA-Z_]+)', 'WikiEditor' ) wikidir = os.path.realpath('./pages') class WikiPages: def GET(self): web.header("Content-Type","text/html; charset=utf-8") t = re.compile('^[a-zA-Z_]+$') wikipages = os.listdir(wikidir) print "<html><head><title>wiki pages</title></head><body>" print "<h1>Wiki Pages:</h1><ul>" for wikipage in wikipages: if os.path.isfile(os.path.join(wikidir, wikipage)) and t.match(wikipage): print "<li><a href="%(path)s/page/%(page)s">%(page)s</a></li>" % {'path':web.ctx.home+web.ctx.path[1:],'page':wikipage} print "</ul></body></html>" class WikiPage: def GET(self, name): page = os.path.join(wikidir,name) web.header("Content-Type","text/html; charset=utf-8") if os.path.exists(page): print "<html><head><title>%s</title></head><body>" % name print "<h1>%s</h1>" % name print "<p>" print "[<a href="%s">Pages</a>] " % (web.ctx.home+"/") print "[<a href="%s">Edit</a>] " % (web.ctx.home+'/editor/'+name) print "</p>" print Markdown(open(page).read()) print "</body></html>" else: web.ctx.status = '404 Not Found' print "<html><head><title>Does not exist: %s</title></head><body>" % name print "<p>Page %s does not yet exist - " % name print "<a href="%s">Create</a>" % (web.ctx.home+'/editor/'+name) def POST(self,name): page = os.path.join(wikidir,name) if os.path.exists(page): newpage = page+'.'+time.strftime("%Y%m%d%H%M%S", time.gmtime()) os.rename(page,newpage) f = open(page, "w") f.write(web.input(page='').page) f.close() web.redirect(web.ctx.home+'/page/'+name) class WikiEditor: def GET(self,name): web.header("Content-Type","text/html; charset=utf-8") print "<html><head><title>Editing %s</title></head><body>" % name; print "<h1>Editing: %s</h1>" % name print "<form method="POST" accept-charset="utf-8" action="%s">" % (web.ctx.home+'/page/'+name) print "<textarea name="page" cols="100" rows="20">" page = os.path.join(wikidir,name) if os.path.exists(page): print cgi.escape(open(page).read()) print "</textarea><br><input type="submit" value="Update"></form>" print "<p><a href="http://daringfireball.net/projects/markdown/syntax">Markdown Syntax</a></p>" print "</body></html>" if __name__ == "__main__": web.run(urls)
#!/usr/bin/python import web from markdown import Markdown import os, time, re, cgi # For debugging use only web.internalerror = web.debugerror urls = ( '/', 'WikiPages', '/page/([a-zA-Z_]+)', 'WikiPage', '/editor/([a-zA-Z_]+)', 'WikiEditor' ) wikidir = os.path.realpath('./pages') class WikiPages: def GET(self): web.header("Content-Type","text/html; charset=utf-8") t = re.compile('^[a-zA-Z_]+$') wikipages = os.listdir(wikidir) print "<html><head><title>wiki pages</title></head><body>" print "<h1>Wiki Pages:</h1><ul>" for wikipage in wikipages: if os.path.isfile(os.path.join(wikidir, wikipage)) and t.match(wikipage): print "<li><a href="%(path)s/page/%(page)s">%(page)s</a></li>" % {'path':web.ctx.home+web.ctx.path[1:],'page':wikipage} print "</ul></body></html>" class WikiPage: def GET(self, name): page = os.path.join(wikidir,name) web.header("Content-Type","text/html; charset=utf-8") if os.path.exists(page): print "<html><head><title>%s</title></head><body>" % name print "<h1>%s</h1>" % name print "<p>" print "[<a href="%s">Pages</a>] " % (web.ctx.home+"/") print "[<a href="%s">Edit</a>] " % (web.ctx.home+'/editor/'+name) print "</p>" print Markdown(open(page).read()) print "</body></html>" else: web.ctx.status = '404 Not Found' print "<html><head><title>Does not exist: %s</title></head><body>" % name print "<p>Page %s does not yet exist - " % name print "<a href="%s">Create</a>" % (web.ctx.home+'/editor/'+name) def POST(self,name): page = os.path.join(wikidir,name) if os.path.exists(page): newpage = page+'.'+time.strftime("%Y%m%d%H%M%S", time.gmtime()) os.rename(page,newpage) f = open(page, "w") f.write(web.input(page='').page) f.close() web.redirect(web.ctx.home+'/page/'+name) class WikiEditor: def GET(self,name): web.header("Content-Type","text/html; charset=utf-8") print "<html><head><title>Editing %s</title></head><body>" % name; print "<h1>Editing: %s</h1>" % name print "<form method="POST" accept-charset="utf-8" action="%s">" % (web.ctx.home+'/page/'+name) print "<textarea name="page" cols="100" rows="20">" page = os.path.join(wikidir,name) if os.path.exists(page): print cgi.escape(open(page).read()) print "</textarea><br><input type="submit" value="Update"></form>" print "<p><a href="http://daringfireball.net/projects/markdown/syntax">Markdown Syntax</a></p>" print "</body></html>" if __name__ == "__main__": web.run(urls) 

Мысли об опыте в другой раз, достаточно сказать, я думаю, Аарон движется в правильном направлении.

Заметьте, я выкинул это из-под PHP, поскольку у Sitepoint (пока) нет категории Python, и, как следует из этого , я решил придерживаться темы PHP.

Обновление: необходимо указать на две проблемы с кодом ниже.

Во-первых, парсер Markdown не предназначен для экранирования специальных символов HTML, поэтому в web.py используется функция web.safemarkdown (). Другими словами, приведенный ниже код подвергает риск эксплойтов XSS.

Во-вторых, при записи на вики-страницы должна выполняться блокировка файлов.