auth.wiki() is much better, supports autolinks
This commit is contained in:
@@ -1 +1 @@
|
|||||||
Version 2.00.0 (2012-08-01 17:04:35) dev
|
Version 2.00.0 (2012-08-01 23:49:50) dev
|
||||||
|
|||||||
@@ -44,9 +44,13 @@ viddler.com
|
|||||||
|
|
||||||
import re, cgi, sys
|
import re, cgi, sys
|
||||||
from simplejson import loads
|
from simplejson import loads
|
||||||
from BeautifulSoup import BeautifulSoup, Comment
|
|
||||||
import urllib
|
import urllib
|
||||||
import uuid
|
import uuid
|
||||||
|
try:
|
||||||
|
from BeautifulSoup import BeautifulSoup, Comment
|
||||||
|
have_soup = True
|
||||||
|
except ImportError:
|
||||||
|
have_soup = False
|
||||||
|
|
||||||
regex_link = re.compile('https?://\S+')
|
regex_link = re.compile('https?://\S+')
|
||||||
|
|
||||||
@@ -160,6 +164,8 @@ def expand_one(url,cdict):
|
|||||||
return '<a href="%(u)s">%(u)s</a>' % dict(u=url)
|
return '<a href="%(u)s">%(u)s</a>' % dict(u=url)
|
||||||
|
|
||||||
def expand_html(html,cdict=None):
|
def expand_html(html,cdict=None):
|
||||||
|
if not have_soup:
|
||||||
|
raise RuntimeError, "Missing BeautifulSoup"
|
||||||
soup = BeautifulSoup(html)
|
soup = BeautifulSoup(html)
|
||||||
comments = soup.findAll(text=lambda text:isinstance(text, Comment))
|
comments = soup.findAll(text=lambda text:isinstance(text, Comment))
|
||||||
[comment.extract() for comment in comments]
|
[comment.extract() for comment in comments]
|
||||||
|
|||||||
@@ -537,7 +537,7 @@ def markmin_escape(text):
|
|||||||
""" insert \\ before markmin control characters: '`:*~[]{}@$ """
|
""" insert \\ before markmin control characters: '`:*~[]{}@$ """
|
||||||
return regex_markmin_escape.sub(lambda m: '\\'+m.group(0).replace('\\','\\\\'), text)
|
return regex_markmin_escape.sub(lambda m: '\\'+m.group(0).replace('\\','\\\\'), text)
|
||||||
|
|
||||||
def autolinks(url):
|
def autolinks_simple(url):
|
||||||
"""
|
"""
|
||||||
it automatically converts the url to link,
|
it automatically converts the url to link,
|
||||||
image, video or audio tag
|
image, video or audio tag
|
||||||
@@ -551,7 +551,7 @@ def autolinks(url):
|
|||||||
return '<audio src="%s" controls></audio>' % url
|
return '<audio src="%s" controls></audio>' % url
|
||||||
return '<a href="%s">%s</a>' % (url,url)
|
return '<a href="%s">%s</a>' % (url,url)
|
||||||
|
|
||||||
def protolinks(proto, url):
|
def protolinks_simple(proto, url):
|
||||||
"""
|
"""
|
||||||
it converts url to html-string using appropriate proto-prefix:
|
it converts url to html-string using appropriate proto-prefix:
|
||||||
Uses for construction "proto:url", e.g.:
|
Uses for construction "proto:url", e.g.:
|
||||||
@@ -575,8 +575,8 @@ def render(text,
|
|||||||
URL=None,
|
URL=None,
|
||||||
environment=None,
|
environment=None,
|
||||||
latex='google',
|
latex='google',
|
||||||
autolinks=autolinks,
|
autolinks='default',
|
||||||
protolinks=protolinks,
|
protolinks='default',
|
||||||
class_prefix='',
|
class_prefix='',
|
||||||
id_prefix='markmin_'):
|
id_prefix='markmin_'):
|
||||||
"""
|
"""
|
||||||
@@ -791,6 +791,8 @@ def render(text,
|
|||||||
'<p><a name="markmin_id1">span <strong>messag</strong> in markmin</a> ... <a href="#markmin_mark1" title="link\\\'s title"><strong>link</strong> to id</a></p>'
|
'<p><a name="markmin_id1">span <strong>messag</strong> in markmin</a> ... <a href="#markmin_mark1" title="link\\\'s title"><strong>link</strong> to id</a></p>'
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
if autolinks=="default": autolinks = autolinks_simple
|
||||||
|
if protolinks=="default": protolinks = protolinks_simple
|
||||||
text = str(text or '')
|
text = str(text or '')
|
||||||
text = regex_backslash.sub(lambda m: m.group(1).translate(ttab_in), text)
|
text = regex_backslash.sub(lambda m: m.group(1).translate(ttab_in), text)
|
||||||
|
|
||||||
@@ -1256,8 +1258,10 @@ def render(text,
|
|||||||
text = text.translate(ttab_out)
|
text = text.translate(ttab_out)
|
||||||
return text
|
return text
|
||||||
|
|
||||||
def markmin2html(text, extra={}, allowed={}, sep='p', autolinks=autolinks, protolinks=protolinks):
|
def markmin2html(text, extra={}, allowed={}, sep='p',
|
||||||
return render(text, extra, allowed, sep, autolinks=autolinks, protolinks=protolinks)
|
autolinks='default',protolinks='default'):
|
||||||
|
return render(text, extra, allowed, sep,
|
||||||
|
autolinks=autolinks, protolinks=protolinks)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
+12
-2
@@ -2382,7 +2382,11 @@ class MARKMIN(XmlComponent):
|
|||||||
For documentation: http://web2py.com/examples/static/markmin.html
|
For documentation: http://web2py.com/examples/static/markmin.html
|
||||||
"""
|
"""
|
||||||
def __init__(self, text, extra=None, allowed=None, sep='p',
|
def __init__(self, text, extra=None, allowed=None, sep='p',
|
||||||
url=None, environment=None, latex='google'):
|
url=None, environment=None, latex='google',
|
||||||
|
autolinks='default',
|
||||||
|
protolinks='default',
|
||||||
|
class_prefix='',
|
||||||
|
id_prefix='markmin_'):
|
||||||
self.text = text
|
self.text = text
|
||||||
self.extra = extra or {}
|
self.extra = extra or {}
|
||||||
self.allowed = allowed or {}
|
self.allowed = allowed or {}
|
||||||
@@ -2390,6 +2394,10 @@ class MARKMIN(XmlComponent):
|
|||||||
self.url = URL if url==True else url
|
self.url = URL if url==True else url
|
||||||
self.environment = environment
|
self.environment = environment
|
||||||
self.latex = latex
|
self.latex = latex
|
||||||
|
self.autolinks = autolinks
|
||||||
|
self.protolinks = protolinks
|
||||||
|
self.class_prefix = class_prefix
|
||||||
|
self.id_prefix = id_prefix
|
||||||
|
|
||||||
def xml(self):
|
def xml(self):
|
||||||
"""
|
"""
|
||||||
@@ -2398,7 +2406,9 @@ class MARKMIN(XmlComponent):
|
|||||||
from contrib.markmin.markmin2html import render
|
from contrib.markmin.markmin2html import render
|
||||||
return render(self.text,extra=self.extra,
|
return render(self.text,extra=self.extra,
|
||||||
allowed=self.allowed,sep=self.sep,latex=self.latex,
|
allowed=self.allowed,sep=self.sep,latex=self.latex,
|
||||||
URL=self.url, environment=self.environment)
|
URL=self.url, environment=self.environment,
|
||||||
|
autolinks=self.autolinks,protolinks=self.protolinks,
|
||||||
|
class_prefix=self.class_prefix,id_prefix=self.id_prefix)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.xml()
|
return self.xml()
|
||||||
|
|||||||
+59
-22
@@ -30,6 +30,7 @@ from storage import Storage, StorageList, Settings, Messages
|
|||||||
from utils import web2py_uuid
|
from utils import web2py_uuid
|
||||||
from fileutils import read_file
|
from fileutils import read_file
|
||||||
from gluon import *
|
from gluon import *
|
||||||
|
from gluon.contrib.autolinks import expand_one
|
||||||
|
|
||||||
import serializers
|
import serializers
|
||||||
|
|
||||||
@@ -4393,12 +4394,13 @@ class Wiki(object):
|
|||||||
everybody = 'everybody'
|
everybody = 'everybody'
|
||||||
rows_page = 25
|
rows_page = 25
|
||||||
regex_redirect = re.compile('redirect\s+(\w+\://\S+)\s*')
|
regex_redirect = re.compile('redirect\s+(\w+\://\S+)\s*')
|
||||||
|
def markmin_render(self,page):
|
||||||
|
return MARKMIN(page.body,url=True,environment=self.env,
|
||||||
|
autolinks=lambda link: expand_one(link,{})).xml()
|
||||||
def __init__(self,auth,env=None,automenu=True,render='markmin',
|
def __init__(self,auth,env=None,automenu=True,render='markmin',
|
||||||
manage_permissions=False,force_prefix=''):
|
manage_permissions=False,force_prefix=''):
|
||||||
self.env = env or {}
|
self.env = env or {}
|
||||||
if render == 'markmin':
|
if render == 'markmin': render=self.markmin_render
|
||||||
render = lambda t,env=self.env: \
|
|
||||||
MARKMIN(t.body,url=True,environment=env).xml()
|
|
||||||
self.auth = auth
|
self.auth = auth
|
||||||
self.automenu = automenu
|
self.automenu = automenu
|
||||||
if self.auth.user:
|
if self.auth.user:
|
||||||
@@ -4479,6 +4481,8 @@ class Wiki(object):
|
|||||||
request.function)
|
request.function)
|
||||||
if request.args(0)=='_edit':
|
if request.args(0)=='_edit':
|
||||||
return self.edit(request.args(1) or 'index')
|
return self.edit(request.args(1) or 'index')
|
||||||
|
elif request.args(0)=='_editmedia':
|
||||||
|
return self.editmedia(request.args(1) or 'index')
|
||||||
elif request.args(0)=='_pages':
|
elif request.args(0)=='_pages':
|
||||||
return self.pages()
|
return self.pages()
|
||||||
elif request.args(0)=='_media':
|
elif request.args(0)=='_media':
|
||||||
@@ -4557,26 +4561,43 @@ class Wiki(object):
|
|||||||
db.wiki_page.menu.default = slug
|
db.wiki_page.menu.default = slug
|
||||||
db.wiki_page.body.default = '## %s\n\npage content' % title_guess
|
db.wiki_page.body.default = '## %s\n\npage content' % title_guess
|
||||||
form = SQLFORM(db.wiki_page,page,deletable=True,showid=False).process()
|
form = SQLFORM(db.wiki_page,page,deletable=True,showid=False).process()
|
||||||
if form.accepted:
|
if form.deleted:
|
||||||
|
current.session.flash = 'page deleted'
|
||||||
|
redirect(URL())
|
||||||
|
elif form.accepted:
|
||||||
current.session.flash = 'page created'
|
current.session.flash = 'page created'
|
||||||
redirect(URL(args=slug))
|
redirect(URL(args=slug))
|
||||||
elif form.deleted:
|
|
||||||
redirect(URL())
|
|
||||||
return dict(content=form)
|
return dict(content=form)
|
||||||
|
|
||||||
|
def editmedia(self,slug):
|
||||||
|
auth = self.auth
|
||||||
|
db = auth.db
|
||||||
|
page = db.wiki_page(slug=slug)
|
||||||
|
if not (page and self.can_edit(page)): return self.not_authorized(page)
|
||||||
|
self.auth.db.wiki_media.wiki_page.default = page.id
|
||||||
|
self.auth.db.wiki_media.wiki_page.writable = False
|
||||||
|
content = SQLFORM.grid(
|
||||||
|
self.auth.db.wiki_media.wiki_page==page.id,
|
||||||
|
orderby = self.auth.db.wiki_media.title,
|
||||||
|
args=['_editmedia',slug],
|
||||||
|
user_signature=False)
|
||||||
|
return dict(content=content)
|
||||||
|
|
||||||
def pages(self):
|
def pages(self):
|
||||||
if not self.can_manage(): return self.not_authorized()
|
if not self.can_manage(): return self.not_authorized()
|
||||||
self.auth.db.wiki_page.title.represent = lambda title,row: \
|
self.auth.db.wiki_page.title.represent = lambda title,row: \
|
||||||
A(title,_href=URL(args=row.slug))
|
A(title,_href=URL(args=row.slug))
|
||||||
content=SQLFORM.smartgrid(
|
content=SQLFORM.grid(
|
||||||
self.auth.db.wiki_page,
|
self.auth.db.wiki_page,
|
||||||
linked_tables = 'wiki_media',
|
links = [
|
||||||
details={'wiki_page':False,'wiki_media':True},
|
lambda row: \
|
||||||
editable={'wiki_page':False,'wiki_media':True},
|
A('edit',_href=URL(args=('_edit',row.slug))),
|
||||||
deletable={'wiki_page':False,'wiki_media':True},
|
lambda row: \
|
||||||
orderby = {'wiki_page':self.auth.db.wiki_page.title,
|
A('media',_href=URL(args=('_editmedia',row.slug)))],
|
||||||
'wiki_media':self.auth.db.wiki_media.title},
|
details=False,editable=False,deletable=False,
|
||||||
|
orderby=self.auth.db.wiki_page.title,
|
||||||
args=['_pages'],
|
args=['_pages'],
|
||||||
user_signature=True)
|
user_signature=False)
|
||||||
return dict(content=content)
|
return dict(content=content)
|
||||||
def media(self, id):
|
def media(self, id):
|
||||||
request, db = current.request, self.auth.db
|
request, db = current.request, self.auth.db
|
||||||
@@ -4612,19 +4633,34 @@ class Wiki(object):
|
|||||||
if True:
|
if True:
|
||||||
submenu = []
|
submenu = []
|
||||||
menu.append((current.T('[Wiki]'),None,None,submenu))
|
menu.append((current.T('[Wiki]'),None,None,submenu))
|
||||||
if URL() == URL(controller,function) and \
|
if URL() == URL(controller,function):
|
||||||
not str(request.args(0)).startswith('_'):
|
if not str(request.args(0)).startswith('_'):
|
||||||
submenu.append((current.T('Edit'),None,
|
slug = request.args(0) or 'index'
|
||||||
URL(controller,function,
|
mode=1
|
||||||
args=('_edit',request.args(0) or 'index'))))
|
elif request.args(0)=='_edit':
|
||||||
|
slug = request.args(1) or 'index'
|
||||||
|
mode=2
|
||||||
|
elif request.args(0)=='_editmedia':
|
||||||
|
slug = request.args(1) or 'index'
|
||||||
|
mode=3
|
||||||
|
else:
|
||||||
|
mode=0
|
||||||
|
if mode in (2,3):
|
||||||
|
submenu.append((current.T('View Page'),None,
|
||||||
|
URL(controller,function,args=slug)))
|
||||||
|
if mode in (1,3):
|
||||||
|
submenu.append((current.T('Edit Page'),None,
|
||||||
|
URL(controller,function,args=('_edit',slug))))
|
||||||
|
if mode in (1,2):
|
||||||
|
submenu.append((current.T('Edit Page Media'),None,
|
||||||
|
URL(controller,function,args=('_editmedia',slug))))
|
||||||
|
|
||||||
# if self.can_manage():
|
# if self.can_manage():
|
||||||
submenu.append((current.T('Manage Pages'),None,
|
submenu.append((current.T('Manage Pages'),None,
|
||||||
URL(controller,function,args=('_pages'))))
|
URL(controller,function,args=('_pages'))))
|
||||||
# if self.can_search():
|
# if self.can_search():
|
||||||
submenu.append((current.T('Search Pages'),None,
|
submenu.append((current.T('Search Pages'),None,
|
||||||
URL(controller,function,args=('_search'))))
|
URL(controller,function,args=('_search'))))
|
||||||
submenu.append((current.T('Tag Cloud'),None,
|
|
||||||
URL(controller,function,args=('_cloud'))))
|
|
||||||
return menu
|
return menu
|
||||||
def search(self,tags=None,query=None,cloud=True,preview=True,
|
def search(self,tags=None,query=None,cloud=True,preview=True,
|
||||||
limitby=(0,100),orderby=None):
|
limitby=(0,100),orderby=None):
|
||||||
@@ -4643,7 +4679,8 @@ class Wiki(object):
|
|||||||
db = self.auth.db
|
db = self.auth.db
|
||||||
count = db.wiki_tag.wiki_page.count()
|
count = db.wiki_tag.wiki_page.count()
|
||||||
fields = [db.wiki_page.id,db.wiki_page.slug,
|
fields = [db.wiki_page.id,db.wiki_page.slug,
|
||||||
db.wiki_page.title,db.wiki_page.tags]
|
db.wiki_page.title,db.wiki_page.tags,
|
||||||
|
db.wiki_page.can_read]
|
||||||
if preview:
|
if preview:
|
||||||
fields.append(db.wiki_page.body)
|
fields.append(db.wiki_page.body)
|
||||||
if query is None:
|
if query is None:
|
||||||
|
|||||||
Reference in New Issue
Block a user