Merge branch 'master' of github.com:web2py/web2py

This commit is contained in:
Michele Comitini committed 2012-07-21 01:02:53 +02:00
commit a7dddda495
13 files changed
+179 -85

No files matched your search

+1 -1
View File
@@ -1 +1 @@
Version 2.00.0 (2012-07-19 16:56:40) dev Version 2.00.0 (2012-07-20 17:37:48) dev
+3 -3
View File
@@ -392,7 +392,7 @@ def peek():
app = get_app(request.vars.app) app = get_app(request.vars.app)
filename = '/'.join(request.args) filename = '/'.join(request.args)
if request.vars.app: if request.vars.app:
path = abspath(filename, gluon=False) path = abspath(filename)
else: else:
path = apath(filename, r=request) path = apath(filename, r=request)
try: try:
@@ -696,7 +696,7 @@ def edit_language():
s = strings[key] s = strings[key]
(prefix, sep, key) = key.partition('\x01') (prefix, sep, key) = key.partition('\x01')
if sep: if sep:
prefix = SPAN(prefix+': ', _style='color: blue;') prefix = SPAN(prefix+': ', _class='tm_ftag')
k = key k = key
else: else:
(k, prefix) = (prefix, '') (k, prefix) = (prefix, '')
@@ -1034,7 +1034,7 @@ def create_file():
anchor='#'+request.vars.id if request.vars.id else '' anchor='#'+request.vars.id if request.vars.id else ''
if request.vars.app: if request.vars.app:
app = get_app(request.vars.app) app = get_app(request.vars.app)
path = abspath(request.vars.location, gluon=False) path = abspath(request.vars.location)
else: else:
app = get_app(name=request.vars.location.split('/')[0]) app = get_app(name=request.vars.location.split('/')[0])
path = apath(request.vars.location, r=request) path = apath(request.vars.location, r=request)
+1
View File
@@ -1248,3 +1248,4 @@ color: #222;
.error, .error a {color:red} .error, .error a {color:red}
.pluralsform thead td {font-weight:bold; font-size:1.2em; padding-bottom:5px} .pluralsform thead td {font-weight:bold; font-size:1.2em; padding-bottom:5px}
.pluralsform td {padding-left:5px} .pluralsform td {padding-left:5px}
.tm_ftag {color:blue}
@@ -13,6 +13,9 @@ def index():
""" """
example action using the internationalization operator T and flash example action using the internationalization operator T and flash
rendered by views/default/index.html or views/generic.html rendered by views/default/index.html or views/generic.html
if you need a simple wiki simple replace the two lines below with:
return auth.wiki()
""" """
response.flash = T("Welcome to web2py!") response.flash = T("Welcome to web2py!")
return dict(message=T('Hello World')) return dict(message=T('Hello World'))
+1 -1
View File
@@ -40,7 +40,7 @@ response.generic_patterns = ['*'] if request.is_local else []
######################################################################### #########################################################################
from gluon.tools import Auth, Crud, Service, PluginManager, prettydate from gluon.tools import Auth, Crud, Service, PluginManager, prettydate
auth = Auth(db, hmac_key=Auth.get_or_create_key(), salt=True) auth = Auth(db)
crud, service, plugins = Crud(db), Service(), PluginManager() crud, service, plugins = Crud(db), Service(), PluginManager()
## create all tables needed by auth if not custom tables ## create all tables needed by auth if not custom tables
+22 -15
View File
@@ -1,17 +1,22 @@
<html><body> <!doctype html>
<style> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
blockquote { background-color: lime; } <head>
thead { color: white; background-color: gray; text-align: center; } <meta http-equiv="content-type" content="text/html; charset=utf-8" />
tfoot { color: white; background-color: gray; } <style>
blockquote { background-color: lime; }
thead { color: white; background-color: gray; text-align: center; }
tfoot { color: white; background-color: gray; }
.tableclass1 { background-color: yellow; }
.tableclass1 thead { color: yellow; background-color: green; }
.tableclass1 tfoot { color: yellow; background-color: green; }
.tableclass1 { background-color: yellow; } td.num { text-align: right; }
.tableclass1 thead { color: yellow; background-color: green; } pre { background-color: #E0E0E0; }
.tableclass1 tfoot { color: yellow; background-color: green; } </style>
<title>Markmin markup language</title>
td.num { text-align: right; } </head>
pre { background-color: #E0E0E0; } <body>
</style> <h1>Markmin markup language</h1><h2>About</h2><p>This is a new markup language that we call markmin designed to produce high quality scientific papers and books and also put them online. We provide serializers for html, latex and pdf. It is implemented in the <code>markmin2html</code> function in the <code>markmin2html.py</code>.</p><p>Example of usage:</p><pre><code>m = "Hello **world** [[link http://web2py.com]]"
<h1>Markmin markup language</h1><h2>About</h2><p>This is a new markup language that we call markmin designed to produce high quality scientific papers and books and also put them online. We provide serializers for html, latex and pdf. It is implemented in the <code>markmin2html</code> function in the <code>markmin2html.py</code>.</p><p>Example of usage:</p><pre><code>m = "Hello **world** [[link http://web2py.com]]"
from markmin2html import markmin2html from markmin2html import markmin2html
print markmin2html(m) print markmin2html(m)
from markmin2latex import markmin2latex from markmin2latex import markmin2latex
@@ -24,7 +29,7 @@ line 2
line 3</code></pre> This item finishes with this paragraph.</li></ol><p>Item in sublevel 3 can be continued with paragraphs.</p><pre><code> this is another line 3</code></pre> This item finishes with this paragraph.</li></ol><p>Item in sublevel 3 can be continued with paragraphs.</p><pre><code> this is another
code block code block
in the in the
sublevel 3 item</code></pre></li></ul><ol><li>The last item in sublevel 3</li></ol><p>This is a continuous paragraph for item 2 in sublevel 2. You can use such structure to create difficult structured documents.</p><li>item 3 in sublevel 2</li></li></li></ol><ul><li>item 1 in sublevel 2 (new unordered list)</li><li>item 2 in sublevel 2</li><li>item 3 in sublevel 2</li></ul><ol><li>item 1 in sublevel 2 (new ordered list)</li><li>item 2 in sublevel 2</li><li>item 3 in sublevle 2</li></ol></li><li>item 2 in level 1</li><li>item 3 in level 1</li></ol><ul><li>new unordered list (item 1 in level 1)</li><li>level 2 in level 1</li><li>level 3 in level 1</li><li>level 4 in level 1</li></ul><h2>This is the last section of the test</h2><p>Single paragraph with '----' in it will be turned into separator:</p><hr /><p>And this is the last paragraph in the test. Be happy!</p><p>====================</p><h2>Why?</h2><p>We wanted a markup language with the following requirements:</p><ul><li>less than 300 lines of functional code</li><li>easy to read</li><li>secure</li><li>support table, ul, ol, code</li><li>support html5 video and audio elements (html serialization only)</li><li>can align images and resize them</li><li>can specify class for tables and code elements</li><li>can add anchors</li><li>does not use _ for markup (since it creates odd behavior)</li><li>automatically links urls</li><li>fast</li><li>easy to extend</li><li>supports latex and pdf including references</li><li>allows to describe the markup in the markup (this document is generated from markmin syntax)</li></ul><p>(results depend on text but in average for text ~100K markmin is 30% faster than markdown, for text ~10K it is 10x faster)</p><p>The <a href="http://www.lulu.com/product/paperback/web2py-%283rd-edition%29/12822827">web2py book</a> published by lulu, for example, was entirely generated with markmin2pdf from the online <a href="http://www.web2py.com/book">web2py wiki</a></p><h2>Download</h2><ul><li><a href="http://web2py.googlecode.com/hg/gluon/contrib/markmin/markmin2html.py">http://web2py.googlecode.com/hg/gluon/contrib/markmin/markmin2html.py</a></li><li><a href="http://web2py.googlecode.com/hg/gluon/contrib/markmin/markmin2latex.py">http://web2py.googlecode.com/hg/gluon/contrib/markmin/markmin2latex.py</a></li><li><a href="http://web2py.googlecode.com/hg/gluon/contrib/markmin/markmin2pdf.py">http://web2py.googlecode.com/hg/gluon/contrib/markmin/markmin2pdf.py</a></li></ul><p>markmin2html.py and markmin2latex.py are single files and have no web2py dependence. Their license is BSD.</p><h2>Examples</h2><h3>Bold, italic, code and links</h3><table><thead><tr><td><strong>SOURCE</strong></td><td><strong>OUTPUT</strong></td></tr></thead><tbody><tr><td><code># title</code></td><td><strong>title</strong></td></tr><tr><td><code>## section</code></td><td><strong>section</strong></td></tr><tr><td><code>### subsection</code></td><td><strong>subsection</strong></td></tr><tr><td><code>**bold**</code></td><td><strong>bold</strong></td></tr><tr><td><code>''italic''</code></td><td><em>italic</em></td></tr><tr><td><code>~~strikeout~~</code></td><td><del>strikeout</del></td></tr><tr><td><code>``verbatim``</code></td><td><code>verbatim</code></td></tr><tr><td><code>``color with **bold**``:red</code></td><td><span style="color: red">color with <strong>bold</strong></span></td></tr><tr><td><code>``many colors``:color[blue:#ffff00]</code></td><td><span style="color: blue;background-color: #ffff00;">many colors</span></td></tr><tr><td><code>http://google.com</code></td><td><a href="http://google.com">http://google.com</a></td></tr><tr><td><code>[[**click** me #myanchor]]</code></td><td><a href="#myanchor"><strong>click</strong> me</a></td></tr><tr><td><code>[[click me [extra info] #myanchor popup]]</code></td><td><a href="#myanchor" title="extra info" target="_blank">click me</a></td></tr></tbody></table><h3>More on links</h3><p>The format is always <code>[[title link]]</code> or <code>[[title [extra] link]]</code>. Notice you can nest bold, italic, strikeout and code inside the link <code>title</code>.</p><h3>Anchors <span id="myanchor"></span></h3><p>You can place an anchor anywhere in the text using the syntax <code>[[name]]</code> where <em>name</em> is the name of the anchor. You can then link the anchor with <a href="#myanchor">link</a>, i.e. <code>[[link #myanchor]]</code> or <a href="#myanchor" title="extra info">link with an extra info</a>, i.e. <code>[[link with an extra info [extra info] #myanchor]]</code>.</p><h3>Images</h3><p><img src="http://www.web2py.com/examples/static/web2py_logo.png" alt="alt-string for the image" title="the image title" style="float:right" width="200px" /> This paragraph has an image aligned to the right with a width of 200px. Its is placed using the code</p><p><code>[[alt-string for the image [the image title] http://www.web2py.com/examples/static/web2py_logo.png right 200px]]</code>.</p><h3>Unordered Lists</h3><pre><code>- Dog sublevel 3 item</code></pre></li></ul><ol><li>The last item in sublevel 3</li></ol><p>This is a continuous paragraph for item 2 in sublevel 2. You can use such structure to create difficult structured documents.</p><li>item 3 in sublevel 2</li></li></li></ol><ul><li>item 1 in sublevel 2 (new unordered list)</li><li>item 2 in sublevel 2</li><li>item 3 in sublevel 2</li></ul><ol><li>item 1 in sublevel 2 (new ordered list)</li><li>item 2 in sublevel 2</li><li>item 3 in sublevle 2</li></ol></li><li>item 2 in level 1</li><li>item 3 in level 1</li></ol><ul><li>new unordered list (item 1 in level 1)</li><li>level 2 in level 1</li><li>level 3 in level 1</li><li>level 4 in level 1</li></ul><h2>This is the last section of the test</h2><p>Single paragraph with '----' in it will be turned into separator:</p><hr /><p>And this is the last paragraph in the test. Be happy!</p><p>====================</p><h2>Why?</h2><p>We wanted a markup language with the following requirements:</p><ul><li>less than 300 lines of functional code</li><li>easy to read</li><li>secure</li><li>support table, ul, ol, code</li><li>support html5 video and audio elements (html serialization only)</li><li>can align images and resize them</li><li>can specify class for tables and code elements</li><li>can add anchors</li><li>does not use _ for markup (since it creates odd behavior)</li><li>automatically links urls</li><li>fast</li><li>easy to extend</li><li>supports latex and pdf including references</li><li>allows to describe the markup in the markup (this document is generated from markmin syntax)</li></ul><p>(results depend on text but in average for text ~100K markmin is 30% faster than markdown, for text ~10K it is 10x faster)</p><p>The <a href="http://www.lulu.com/product/paperback/web2py-%283rd-edition%29/12822827">web2py book</a> published by lulu, for example, was entirely generated with markmin2pdf from the online <a href="http://www.web2py.com/book">web2py wiki</a></p><h2>Download</h2><ul><li><a href="http://web2py.googlecode.com/hg/gluon/contrib/markmin/markmin2html.py">http://web2py.googlecode.com/hg/gluon/contrib/markmin/markmin2html.py</a></li><li><a href="http://web2py.googlecode.com/hg/gluon/contrib/markmin/markmin2latex.py">http://web2py.googlecode.com/hg/gluon/contrib/markmin/markmin2latex.py</a></li><li><a href="http://web2py.googlecode.com/hg/gluon/contrib/markmin/markmin2pdf.py">http://web2py.googlecode.com/hg/gluon/contrib/markmin/markmin2pdf.py</a></li></ul><p>markmin2html.py and markmin2latex.py are single files and have no web2py dependence. Their license is BSD.</p><h2>Examples</h2><h3>Bold, italic, code and links</h3><table><thead><tr><td><strong>SOURCE</strong></td><td><strong>OUTPUT</strong></td></tr></thead><tbody><tr><td><code># title</code></td><td><strong>title</strong></td></tr><tr><td><code>## section</code></td><td><strong>section</strong></td></tr><tr><td><code>### subsection</code></td><td><strong>subsection</strong></td></tr><tr><td><code>**bold**</code></td><td><strong>bold</strong></td></tr><tr><td><code>''italic''</code></td><td><em>italic</em></td></tr><tr><td><code>~~strikeout~~</code></td><td><del>strikeout</del></td></tr><tr><td><code>``verbatim``</code></td><td><code>verbatim</code></td></tr><tr><td><code>``color with **bold**``:red</code></td><td><span style="color: red">color with <strong>bold</strong></span></td></tr><tr><td><code>``many colors``:color[blue:#ffff00]</code></td><td><span style="color: blue;background-color: #ffff00;">many colors</span></td></tr><tr><td><code>http://google.com</code></td><td><a href="http://google.com">http://google.com</a></td></tr><tr><td><code>[[**click** me #myanchor]]</code></td><td><a href="#markmin_myanchor"><strong>click</strong> me</a></td></tr><tr><td><code>[[click me [extra info] #myanchor popup]]</code></td><td><a href="#markmin_myanchor" title="extra info" target="_blank">click me</a></td></tr></tbody></table><h3>More on links</h3><p>The format is always <code>[[title link]]</code> or <code>[[title [extra] link]]</code>. Notice you can nest bold, italic, strikeout and code inside the link <code>title</code>.</p><h3>Anchors <a name="markmin_myanchor"></a></h3><p>You can place an anchor anywhere in the text using the syntax <code>[[name]]</code> where <em>name</em> is the name of the anchor. You can then link the anchor with <a href="#markmin_myanchor">link</a>, i.e. <code>[[link #myanchor]]</code> or <a href="#markmin_myanchor" title="extra info">link with an extra info</a>, i.e. <code>[[link with an extra info [extra info] #myanchor]]</code>.</p><h3>Images</h3><p><img src="http://www.web2py.com/examples/static/web2py_logo.png" alt="alt-string for the image" title="the image title" style="float:right" width="200px" /> This paragraph has an image aligned to the right with a width of 200px. Its is placed using the code</p><p><code>[[alt-string for the image [the image title] http://www.web2py.com/examples/static/web2py_logo.png right 200px]]</code>.</p><h3>UnLine truncated
- Cat - Cat
- Mouse</code></pre><p>is rendered as</p><ul><li>Dog</li><li>Cat</li><li>Mouse</li></ul><p>Two new lines between items break the list in two lists.</p><h3>Ordered Lists</h3><pre><code>+ Dog - Mouse</code></pre><p>is rendered as</p><ul><li>Dog</li><li>Cat</li><li>Mouse</li></ul><p>Two new lines between items break the list in two lists.</p><h3>Ordered Lists</h3><pre><code>+ Dog
+ Cat + Cat
@@ -79,4 +84,6 @@ markmin2html(text,{'latex':lambda code: LATEX % code.replace('"','\"')})</code><
## References ## References
- [[mdipierro]] web2py Manual, 3rd Edition, lulu.com</code></pre><h3>Caveats</h3><p><code>&lt;ul/&gt;</code>, <code>&lt;ol/&gt;</code>, <code>&lt;code/&gt;</code>, <code>&lt;table/&gt;</code>, <code>&lt;blockquote/&gt;</code>, <code>&lt;h1/&gt;</code>, ..., <code>&lt;h6/&gt;</code> do not have <code>&lt;p&gt;...&lt;/p&gt;</code> around them.</p></body></html> - [[mdipierro]] web2py Manual, 3rd Edition, lulu.com</code></pre><h3>Caveats</h3><p><code>&lt;ul/&gt;</code>, <code>&lt;ol/&gt;</code>, <code>&lt;code/&gt;</code>, <code>&lt;table/&gt;</code>, <code>&lt;blockquote/&gt;</code>, <code>&lt;h1/&gt;</code>, ..., <code>&lt;h6/&gt;</code> do not have <code>&lt;p&gt;...&lt;/p&gt;</code> around them.</p>
</body>
</html>
+49 -21
View File
@@ -667,19 +667,19 @@ def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='goo
'<p>[[probe]]</p>' '<p>[[probe]]</p>'
>>> render(r"\\\\[[probe]]") >>> render(r"\\\\[[probe]]")
'<p>\\\\<span id="probe"></span></p>' '<p>\\\\<a name="markmin_probe"></a></p>'
>>> render(r"\\\\\\[[probe]]") >>> render(r"\\\\\\[[probe]]")
'<p>\\\\[[probe]]</p>' '<p>\\\\[[probe]]</p>'
>>> render(r"\\\\\\\\[[probe]]") >>> render(r"\\\\\\\\[[probe]]")
'<p>\\\\\\\\<span id="probe"></span></p>' '<p>\\\\\\\\<a name="markmin_probe"></a></p>'
>>> render(r"\\\\\\\\\[[probe]]") >>> render(r"\\\\\\\\\[[probe]]")
'<p>\\\\\\\\[[probe]]</p>' '<p>\\\\\\\\[[probe]]</p>'
>>> render(r"\\\\\\\\\\\[[probe]]") >>> render(r"\\\\\\\\\\\[[probe]]")
'<p>\\\\\\\\\\\\<span id="probe"></span></p>' '<p>\\\\\\\\\\\\<a name="markmin_probe"></a></p>'
>>> render("``[[ [\\[[probe\]\\]] URL\\[x\\]]]``:red[dummy_params]") >>> render("``[[ [\\[[probe\]\\]] URL\\[x\\]]]``:red[dummy_params]")
'<span style="color: red"><a href="URL[x]" title="[[probe]]">URL[x]</a></span>' '<span style="color: red"><a href="URL[x]" title="[[probe]]">URL[x]</a></span>'
@@ -725,6 +725,10 @@ def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='goo
>>> render("**@{probe}**", environment=dict(probe="this is a test")) >>> render("**@{probe}**", environment=dict(probe="this is a test"))
'<p><strong>this is a test</strong></p>' '<p><strong>this is a test</strong></p>'
>>> render('[[id1 [span **messag** in ''markmin''] ]] ... [[**link** to id [link\\\'s title] #mark1]]')
'<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>'
""" """
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)
@@ -855,7 +859,7 @@ def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='goo
""" paragraphs in lists """ """ paragraphs in lists """
lent=len(t) lent=len(t)
if lent>lev: if lent>lev:
return parse_list(t, '.', s, 'ul', lev, mtag) return parse_list(t, '.', s, 'ul', lev, mtag, lineno)
elif lent<lev: elif lent<lev:
while ltags[-1]>lent: while ltags[-1]>lent:
ltags.pop() ltags.pop()
@@ -986,7 +990,9 @@ def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='goo
URL, URL,
environment, environment,
latex, latex,
auto) auto,
class_prefix,
id_prefix)
) )
mtag='q' mtag='q'
else: else:
@@ -1100,7 +1106,8 @@ def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='goo
elif p in ('left','right'): elif p in ('left','right'):
style = ' style="float:%s"' % p style = ' style="float:%s"' % p
if p in ('video','audio'): if p in ('video','audio'):
t = render(t, {}, {}, 'br', URL, environment, latex, auto) t = render(t, {}, {}, 'br', URL, environment, latex,
auto, class_prefix, id_prefix)
return '<%(p)s controls="controls"%(title)s%(width)s><source src="%(k)s" />%(t)s</%(p)s>' \ return '<%(p)s controls="controls"%(title)s%(width)s><source src="%(k)s" />%(t)s</%(p)s>' \
% dict(p=p, title=title, width=width, k=k, t=t) % dict(p=p, title=title, width=width, k=k, t=t)
alt = ' alt="%s"'%escape(t).replace(META, DISABLED_META) if t else '' alt = ' alt="%s"'%escape(t).replace(META, DISABLED_META) if t else ''
@@ -1115,13 +1122,19 @@ def render(text,extra={},allowed={},sep='p',URL=None,environment=None,latex='goo
t = t or '' t = t or ''
a = escape(a) if a else '' a = escape(a) if a else ''
if k: if k:
if k.startswith('#'):
k = '#'+id_prefix+k[1:]
k = escape(k) k = escape(k)
title = ' title="%s"' % a.replace(META, DISABLED_META) if a else '' title = ' title="%s"' % a.replace(META, DISABLED_META) if a else ''
target = ' target="_blank"' if p == 'popup' else '' target = ' target="_blank"' if p == 'popup' else ''
t = render(t, {}, {}, 'br', URL, environment, latex, auto) if t else k t = render(t, {}, {}, 'br', URL, environment, latex, auto,
class_prefix, id_prefix) if t else k
return '<a href="%(k)s"%(title)s%(target)s>%(t)s</a>' \ return '<a href="%(k)s"%(title)s%(target)s>%(t)s</a>' \
% dict(k=k, title=title, target=target, t=t) % dict(k=k, title=title, target=target, t=t)
return '<span id="%s">%s</span>' % (escape(t),a) return '<a name="%s">%s</a>' % (escape(id_prefix+t),
render(a, {},{},'br', URL,
environment, latex, auto,
class_prefix, id_prefix))
parts = text.split(LINK) parts = text.split(LINK)
text = parts[0] text = parts[0]
@@ -1183,21 +1196,36 @@ def markmin2html(text, extra={}, allowed={}, sep='p', auto=True):
if __name__ == '__main__': if __name__ == '__main__':
import sys import sys
import doctest import doctest
from textwrap import dedent
html=dedent("""
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
%(style)s
<title>%(title)s</title>
</head>
<body>
%(body)s
</body>
</html>""")[1:]
if sys.argv[1:2] == ['-h']: if sys.argv[1:2] == ['-h']:
print """<html><body> style=dedent("""
<style> <style>
blockquote { background-color: lime; } blockquote { background-color: lime; }
thead { color: white; background-color: gray; text-align: center; } thead { color: white; background-color: gray; text-align: center; }
tfoot { color: white; background-color: gray; } tfoot { color: white; background-color: gray; }
.tableclass1 { background-color: yellow; }
.tableclass1 thead { color: yellow; background-color: green; }
.tableclass1 tfoot { color: yellow; background-color: green; }
.tableclass1 { background-color: yellow; } td.num { text-align: right; }
.tableclass1 thead { color: yellow; background-color: green; } pre { background-color: #E0E0E0; }
.tableclass1 tfoot { color: yellow; background-color: green; } </style>""")[1:]
td.num { text-align: right; } print html % dict(title="Markmin markup language", style=style, body=markmin2html(__doc__))
pre { background-color: #E0E0E0; }
</style>
"""+markmin2html(__doc__)+'</body></html>'
elif sys.argv[1:2] == ['-t']: elif sys.argv[1:2] == ['-t']:
from timeit import Timer from timeit import Timer
loops=1000 loops=1000
@@ -1208,7 +1236,7 @@ if __name__ == '__main__':
elif len(sys.argv) > 1: elif len(sys.argv) > 1:
fargv = open(sys.argv[1],'r') fargv = open(sys.argv[1],'r')
try: try:
print '<html><body>'+markmin2html(fargv.read())+'</body></html>' print html % dict(title=sys.argv[1], style='', body=markmin2html(fargv.read()))
finally: finally:
fargv.close() fargv.close()
else: else:
+5 -1
View File
@@ -1800,6 +1800,7 @@ class BaseAdapter(ConnectionPool):
query = query & newquery query = query & newquery
return query return query
################################################################################### ###################################################################################
# List of all the available adapters; they all extend BaseAdapter. # List of all the available adapters; they all extend BaseAdapter.
################################################################################### ###################################################################################
@@ -8593,7 +8594,10 @@ class Rows(object):
""" """
returns a list of sorted elements (not sorted in place) returns a list of sorted elements (not sorted in place)
""" """
return Rows(self.db,sorted(self,key=f,reverse=reverse),self.colnames) rows = Rows(self.db,[],self.colnames,compact=False)
rows.records = sorted(self,key=f,reverse=reverse)
return rows
def group_by_value(self, field): def group_by_value(self, field):
""" """
+4 -4
View File
@@ -880,7 +880,7 @@ class Auth(object):
def here(self): def here(self):
return URL(args=current.request.args,vars=current.request.vars) return URL(args=current.request.args,vars=current.request.vars)
def __init__(self, environment=None, db=None, mailer=True, salt = False, def __init__(self, environment=None, db=None, mailer=True,
hmac_key=None, controller='default', function='user', cas_provider=None): hmac_key=None, controller='default', function='user', cas_provider=None):
""" """
auth=Auth(db) auth=Auth(db)
@@ -922,7 +922,6 @@ class Auth(object):
settings.hideerror = False settings.hideerror = False
settings.password_min_length = 4 settings.password_min_length = 4
settings.salt = salt
settings.cas_domains = [request.env.http_host] settings.cas_domains = [request.env.http_host]
settings.cas_provider = cas_provider settings.cas_provider = cas_provider
settings.cas_actions = {'login':'login', settings.cas_actions = {'login':'login',
@@ -1198,7 +1197,8 @@ class Auth(object):
if URL() == action: if URL() == action:
next = '' next = ''
else: else:
next = '?_next=' + urllib.quote(URL(args=request.args, vars=request.get_vars)) next = '?_next=' + urllib.quote(URL(args=request.args,
vars=request.get_vars))
href = lambda function: '%s/%s%s' % (action, function, href = lambda function: '%s/%s%s' % (action, function,
next if referrer_actions is DEFAULT or function in referrer_actions else '') next if referrer_actions is DEFAULT or function in referrer_actions else '')
@@ -1409,7 +1409,7 @@ class Auth(object):
table.last_name.requires = \ table.last_name.requires = \
IS_NOT_EMPTY(error_message=self.messages.is_empty) IS_NOT_EMPTY(error_message=self.messages.is_empty)
table[passfield].requires = [ table[passfield].requires = [
CRYPT(key=settings.hmac_key,salt=settings.salt, CRYPT(key=settings.hmac_key,
min_length=settings.password_min_length)] min_length=settings.password_min_length)]
table.email.requires = \ table.email.requires = \
[IS_EMAIL(error_message=self.messages.invalid_email), [IS_EMAIL(error_message=self.messages.invalid_email),
+24 -23
View File
@@ -15,7 +15,7 @@ import __builtin__
__all__ = ['Utf8'] __all__ = ['Utf8']
repr_escape_tab={} repr_escape_tab={}
for i in xrange(1,32): repr_escape_tab[i]=ur'\x%02i'%i for i in range(1,32): repr_escape_tab[i]=ur'\x%02x'%i
repr_escape_tab[7]=u'\\a' repr_escape_tab[7]=u'\\a'
repr_escape_tab[8]=u'\\b' repr_escape_tab[8]=u'\\b'
repr_escape_tab[9]=u'\\t' repr_escape_tab[9]=u'\\t'
@@ -71,6 +71,24 @@ def size(string):
""" """
return Utf8(string).__size__() return Utf8(string).__size__()
def truncate(string, length, dots='...'):
""" returns string of length < *length* or truncate
string with adding *dots* suffix to the string's end
args:
length (int): max length of string
dots (str or unicode): string suffix, when string is cutted
returns:
(utf8-str): original or cutted string
"""
text = unicode(string, 'utf-8')
dots = unicode(dots, 'utf-8') if isinstance(dots, str) else dots
if len(text) > length:
text = text[:length-len(dots)] + dots
return str.__new__(Utf8, text.encode('utf-8'))
class Utf8(str): class Utf8(str):
""" """
Class for utf8 string storing and manipulations Class for utf8 string storing and manipulations
@@ -131,23 +149,6 @@ class Utf8(str):
else: else:
return "'"+unicode(self, 'utf-8').translate(repr_escape_tab2).encode('utf-8')+"'" return "'"+unicode(self, 'utf-8').translate(repr_escape_tab2).encode('utf-8')+"'"
def truncate(self, length, dots='...'):
""" returns string of length < *length* or truncate
string with adding *dots* suffix to the string's end
args:
length (int): max length of string
dots (str or unicode): string suffix, when string is cutted
returns:
(utf8-str): original or cutted string
"""
text = unicode(self, 'utf-8')
dots = unicode(dots, 'utf-8') if isinstance(dots, str) else dots
if len(text) > length:
text = text[:length-len(dots)] + dots
return str.__new__(Utf8, text.encode('utf-8'))
def __size__(self): def __size__(self):
""" length of utf-8 string in bytes """ """ length of utf-8 string in bytes """
return str.__len__(self) return str.__len__(self)
@@ -419,15 +420,15 @@ if __name__ == '__main__':
'прОБА є prOBE' 'прОБА є prOBE'
>>> type(s.swapcase()) >>> type(s.swapcase())
<class '__main__.Utf8'> <class '__main__.Utf8'>
>>> s.truncate(10) >>> truncate(s, 10)
'ПРоба Є...' 'ПРоба Є...'
>>> s.truncate(20) >>> truncate(s, 20)
'ПРоба Є PRobe' 'ПРоба Є PRobe'
>>> s.truncate(10, '•••') # utf-8 string as *dots* >>> truncate(s, 10, '•••') # utf-8 string as *dots*
'ПРоба Є•••' 'ПРоба Є•••'
>>> s.truncate(10, u'®') # you can use unicode string as *dots* >>> truncate(s, 10, u'®') # you can use unicode string as *dots*
'ПРоба Є P®' 'ПРоба Є P®'
>>> type(s.truncate(10)) >>> type(truncate(s, 10))
<class '__main__.Utf8'> <class '__main__.Utf8'>
>>> Utf8(s.encode('koi8-u'), 'koi8-u') >>> Utf8(s.encode('koi8-u'), 'koi8-u')
'ПРоба Є PRobe' 'ПРоба Є PRobe'
+8 -8
View File
@@ -16,7 +16,7 @@ import random
import time import time
import os import os
import logging import logging
from gluon.contrib.pbkdf2 import pbkdf2_hex from contrib.pbkdf2 import pbkdf2_hex
logger = logging.getLogger("web2py") logger = logging.getLogger("web2py")
@@ -69,15 +69,15 @@ def get_digest(value):
elif value == "sha512": elif value == "sha512":
return hashlib.sha512 return hashlib.sha512
else: else:
raise ValueError("Invalid digest algorithm") raise ValueError("Invalid digest algorithm: %s" % value)
DIGEST_ALG_BY_SIZE = { DIGEST_ALG_BY_SIZE = {
128/16: 'md5', 128/4: 'md5',
160/16: 'sha1', 160/4: 'sha1',
224/16: 'sha224', 224/4: 'sha224',
256/16: 'sha256', 256/4: 'sha256',
384/16: 'sha384', 384/4: 'sha384',
512/16: 'sha512', 512/4: 'sha512',
} }
def hmac_hash(value, salt, digest_alg='md5'): def hmac_hash(value, salt, digest_alg='md5'):
+56 -7
View File
@@ -130,7 +130,7 @@ class IS_MATCH(Validator):
('hello', None) ('hello', None)
>>> IS_MATCH('hell')('hello') >>> IS_MATCH('hell')('hello')
('hello', 'invalid expression') ('hello', None)
>>> IS_MATCH('hell.*', strict=False)('hello') >>> IS_MATCH('hell.*', strict=False)('hello')
('hello', None) ('hello', None)
@@ -139,10 +139,10 @@ class IS_MATCH(Validator):
('shello', 'invalid expression') ('shello', 'invalid expression')
>>> IS_MATCH('hello', search=True)('shello') >>> IS_MATCH('hello', search=True)('shello')
('hello', None) ('shello', None)
>>> IS_MATCH('hello', search=True, strict=False)('shellox') >>> IS_MATCH('hello', search=True, strict=False)('shellox')
('hello', None) ('shellox', None)
>>> IS_MATCH('.*hello.*', search=True, strict=False)('shellox') >>> IS_MATCH('.*hello.*', search=True, strict=False)('shellox')
('shellox', None) ('shellox', None)
@@ -2579,7 +2579,13 @@ class LazyCrypt(object):
""" """
compares the current lazy crypted password with a stored password compares the current lazy crypted password with a stored password
""" """
key = self.crypt.key.split(':')[1] if ':' in self.crypt.key else '' if self.crypt.key:
if ':' in self.crypt.key:
key = self.crypt.key.split(':')[1]
else:
key = self.crypt.key
else:
key = ''
if stored_password.count('$')==2: if stored_password.count('$')==2:
(digest_alg, salt, hash) = stored_password.split('$') (digest_alg, salt, hash) = stored_password.split('$')
masterkey = key+salt masterkey = key+salt
@@ -2629,13 +2635,55 @@ class CRYPT(object):
Important: hashed password is returned as a LazyCrypt object and computed only if needed. Important: hashed password is returned as a LazyCrypt object and computed only if needed.
The LasyCrypt object also knows how to compare itself with an existing salted password The LasyCrypt object also knows how to compare itself with an existing salted password
Supports standard algorithms
>>> for alg in ('md5','sha1','sha256','sha384','sha512'):
... print str(CRYPT(digest_alg=alg,salt=True)('test')[0])
md5$...$...
sha1$...$...
sha256$...$...
sha384$...$...
sha512$...$...
The syntax is always alg$salt$hash
Supports for pbkdf2
>>> alg = 'pbkdf2(1000,20,sha512)'
>>> print str(CRYPT(digest_alg=alg,salt=True)('test')[0])
pbkdf2(1000,20,sha512)$...$...
An optional hmac_key can be specified and it is used as salt prefix
>>> a = str(CRYPT(digest_alg='md5',key='mykey',salt=True)('test')[0])
>>> print a
md5$...$...
Even if the algorithm changes the hash can still be validated
>>> CRYPT(digest_alg='sha1',key='mykey',salt=True)('test')[0] == a
True
If no salt is specified CRYPT can guess the algorithms from length:
>>> a = str(CRYPT(digest_alg='sha1',salt=False)('test')[0])
>>> a
'sha1$$a94a8fe5ccb19ba61c4c0873d391e987982fbbd3'
>>> CRYPT(digest_alg='sha1',salt=False)('test')[0] == a
True
>>> CRYPT(digest_alg='sha1',salt=False)('test')[0] == a[6:]
True
>>> CRYPT(digest_alg='md5',salt=False)('test')[0] == a
True
>>> CRYPT(digest_alg='md5',salt=False)('test')[0] == a[6:]
True
""" """
def __init__(self, def __init__(self,
key=None, key=None,
digest_alg='md5', digest_alg='pbkdf2(1000,20,sha512)',
min_length=0, min_length=0,
error_message='too short', salt=None): error_message='too short', salt=True):
""" """
important, digest_alg='md5' is not the default hashing algorithm for important, digest_alg='md5' is not the default hashing algorithm for
web2py. This is only an example of usage of this function. web2py. This is only an example of usage of this function.
@@ -3093,7 +3141,8 @@ class IS_IPV4(Validator):
if __name__ == '__main__': if __name__ == '__main__':
import doctest import doctest
doctest.testmod() doctest.testmod(optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS)
+2 -1
View File
@@ -9,6 +9,7 @@ License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
The widget is called from web2py. The widget is called from web2py.
""" """
import datetime
import sys import sys
import cStringIO import cStringIO
import time import time
@@ -41,7 +42,7 @@ except NameError:
BaseException = Exception BaseException = Exception
ProgramName = 'web2py Web Framework' ProgramName = 'web2py Web Framework'
ProgramAuthor = 'Created by Massimo Di Pierro, Copyright 2007-2011' ProgramAuthor = 'Created by Massimo Di Pierro, Copyright 2007-' + str(datetime.datetime.now().year)
ProgramVersion = read_file('VERSION').strip() ProgramVersion = read_file('VERSION').strip()
ProgramInfo = '''%s ProgramInfo = '''%s