diff --git a/Makefile b/Makefile
index f38e1bc3..77d99f49 100644
--- a/Makefile
+++ b/Makefile
@@ -54,20 +54,19 @@ src:
### build web2py_src.zip
echo '' > NEWINSTALL
mv web2py_src.zip web2py_src_old.zip | echo 'no old'
- cd ..; zip -r web2py/web2py_src.zip web2py/gluon/*.py web2py/gluon/contrib/* web2py/splashlogo.gif web2py/*.py web2py/README.markdown web2py/LICENSE web2py/CHANGELOG web2py/NEWINSTALL web2py/VERSION web2py/Makefile web2py/epydoc.css web2py/epydoc.conf web2py/app.example.yaml web2py/logging.example.conf web2py_exe.conf web2py/queue.example.yaml MANIFEST.in w2p_apps w2p_clone w2p_run startweb2py web2py/scripts/*.sh web2py/scripts/*.py web2py/applications/admin web2py/applications/examples/ web2py/applications/welcome web2py/applications/__init__.py web2py/site-packages/__init__.py web2py/gluon/tests/*.sh web2py/gluon/tests/*.py
+ cd ..; zip -r web2py/web2py_src.zip web2py/gluon/*.py web2py/gluon/contrib/* web2py/splashlogo.gif web2py/*.py web2py/README.markdown web2py/LICENSE web2py/CHANGELOG web2py/NEWINSTALL web2py/VERSION web2py/Makefile web2py/epydoc.css web2py/epydoc.conf web2py/app.example.yaml web2py/logging.example.conf web2py/queue.example.yaml MANIFEST.in w2p_apps w2p_clone w2p_run web2py/scripts/*.sh web2py/scripts/*.py web2py/applications/admin web2py/applications/examples/ web2py/applications/welcome web2py/applications/__init__.py web2py/site-packages/__init__.py web2py/gluon/tests/*.sh web2py/gluon/tests/*.py
mdp:
make src
make app
make win
app:
- echo 'did you uncomment import_all in gluon/main.py?'
- python2.5 -c 'import compileall; compileall.compile_dir("gluon/")'
+ python2.7 -c 'import compileall; compileall.compile_dir("gluon/")'
#python web2py.py -S welcome -R __exit__.py
#cd ../web2py_osx/site-packages/; unzip ../site-packages.zip
find gluon -path '*.pyc' -exec cp {} ../web2py_osx/site-packages/{} \;
cd ../web2py_osx/site-packages/; zip -r ../site-packages.zip *
- mv ../web2py_osx/site-packages.zip ../web2py_osx/web2py/web2py.app/Contents/Resources/lib/python2.5
+ mv ../web2py_osx/site-packages.zip ../web2py_osx/web2py/web2py.app/Contents/Resources/lib/python2.7
cp README.markdown ../web2py_osx/web2py/web2py.app/Contents/Resources
cp NEWINSTALL ../web2py_osx/web2py/web2py.app/Contents/Resources
cp LICENSE ../web2py_osx/web2py/web2py.app/Contents/Resources
@@ -86,7 +85,6 @@ app:
cd ../web2py_osx; zip -r web2py_osx.zip web2py
mv ../web2py_osx/web2py_osx.zip .
win:
- echo 'did you uncomment import_all in gluon/main.py?'
python2.7 -c 'import compileall; compileall.compile_dir("gluon/")'
#cd ../web2py_win/library/; unzip ../library.zip
find gluon -path '*.pyc' -exec cp {} ../web2py_win/library/{} \;
@@ -110,7 +108,7 @@ win:
cd ../web2py_win; zip -r web2py_win.zip web2py
mv ../web2py_win/web2py_win.zip .
run:
- python2.5 web2py.py -a hello
+ python2.7 web2py.py -a hello
commit:
python web2py.py --run_system_tests
make src
diff --git a/VERSION b/VERSION
index fb34ff20..c986fead 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-Version 2.4.1-alpha.2+timestamp.2013.01.23.08.48.16
+Version 2.4.1-alpha.2+timestamp.2013.02.08.12.41.08
diff --git a/applications/admin/controllers/appadmin.py b/applications/admin/controllers/appadmin.py
index 99a0186d..a2b2c6ab 100644
--- a/applications/admin/controllers/appadmin.py
+++ b/applications/admin/controllers/appadmin.py
@@ -469,10 +469,10 @@ def ccache():
def table_template(table):
from gluon.html import TR, TD, TABLE, TAG
-
+
def FONT(*args, **kwargs):
return TAG.font(*args, **kwargs)
-
+
def types(field):
f_type = field.type
if not isinstance(f_type,str):
@@ -480,7 +480,7 @@ def table_template(table):
elif f_type == 'string':
return field.length
elif f_type == 'id':
- return B('pk')
+ return B('pk')
elif f_type.startswith('reference') or \
f_type.startswith('list:reference'):
return B('fk')
@@ -495,7 +495,7 @@ def table_template(table):
face = "Helvetica"
face_bold = "Helvetica Bold"
border = 0
-
+
rows.append(TR(TD(FONT(table, _face=face_bold, _color=bgcolor),
_colspan=3, _cellpadding=cellpadding,
_align="center", _bgcolor=color)))
@@ -515,10 +515,31 @@ def table_template(table):
def bg_graph_model():
- graph = pgv.AGraph(layout='dot', directed=True, strict=False, rankdir='LR')
+ graph = pgv.AGraph(layout='dot', directed=True, strict=False, rankdir='LR')
+
+ subgraphs = dict()
for tablename in db.tables:
- graph.add_node(tablename, name=tablename, shape='plaintext',
+ if hasattr(db[tablename],'_meta_graphmodel'):
+ meta_graphmodel = db[tablename]._meta_graphmodel
+ else:
+ meta_graphmodel = dict(group='Undefined', color='#ECECEC')
+
+ group = meta_graphmodel['group'].replace(' ', '')
+ if not subgraphs.has_key(group):
+ subgraphs[group] = dict(meta=meta_graphmodel, tables=[])
+ subgraphs[group]['tables'].append(tablename)
+ else:
+ subgraphs[group]['tables'].append(tablename)
+
+ graph.add_node(tablename, name=tablename, shape='plaintext',
label=table_template(tablename))
+
+ for n, key in enumerate(subgraphs.iterkeys()):
+ graph.subgraph(nbunch=subgraphs[key]['tables'],
+ name='cluster%d' % n,
+ style='filled',
+ color=subgraphs[key]['meta']['color'],
+ label=subgraphs[key]['meta']['group'])
for tablename in db.tables:
for field in db[tablename]:
@@ -532,7 +553,15 @@ def bg_graph_model():
graph.add_edge(n1, n2, color="#4C4C4C", label='')
graph.layout()
- return graph.draw(format='png', prog='dot')
+ #return graph.draw(format='png', prog='dot')
+ if not request.args:
+ return graph.draw(format='png', prog='dot')
+ else:
+ response.headers['Content-Disposition']='attachment;filename=graph.%s'%request.args(0)
+ if request.args(0) == 'dot':
+ return graph.string()
+ else:
+ return graph.draw(format=request.args(0), prog='dot')
-def graph_model():
+def graph_model():
return dict(databases=databases, pgv=pgv)
diff --git a/applications/admin/controllers/default.py b/applications/admin/controllers/default.py
index caeb5d83..618b9ff6 100644
--- a/applications/admin/controllers/default.py
+++ b/applications/admin/controllers/default.py
@@ -565,6 +565,7 @@ def edit():
# Load json only if it is ajax edited...
app = get_app(request.vars.app)
filename = '/'.join(request.args)
+ response.title = request.args[-1]
if request.vars.app:
path = abspath(filename)
else:
@@ -645,6 +646,7 @@ def edit():
code = request.vars.data.rstrip().replace('\r\n', '\n') + '\n'
compile(code, path, "exec", _ast.PyCF_ONLY_AST)
except Exception, e:
+ # offset calculation is only used for textarea (start/stop)
start = sum([len(line) + 1 for l, line
in enumerate(request.vars.data.split("\n"))
if l < e.lineno - 1])
@@ -654,7 +656,7 @@ def edit():
else:
offset = 0
highlight = {'start': start, 'end': start +
- offset + 1, 'lineno': e.lineno}
+ offset + 1, 'lineno': e.lineno, 'offset': offset}
try:
ex_name = e.__class__.__name__
except:
@@ -811,6 +813,7 @@ def edit_language():
""" Edit language file """
app = get_app()
filename = '/'.join(request.args)
+ response.title = request.args[-1]
strings = read_dict(apath(filename, r=request))
if '__corrupted__' in strings:
diff --git a/applications/admin/languages/it.py b/applications/admin/languages/it.py
index 957fe0bf..98bc43b6 100644
--- a/applications/admin/languages/it.py
+++ b/applications/admin/languages/it.py
@@ -23,6 +23,7 @@
'Admin language': 'Admin language',
'administrative interface': 'administrative interface',
'Administrator Password:': 'Password Amministratore:',
+'An error occured, please %s the page': 'An error occured, please %s the page',
'and rename it (required):': 'e rinominala (obbligatorio):',
'and rename it:': 'e rinominala:',
'appadmin': 'appadmin ',
@@ -144,8 +145,10 @@
'Get from URL:': 'Get from URL:',
'Git Pull': 'Git Pull',
'Git Push': 'Git Push',
+'graph model': 'graph model',
'Hello World': 'Salve Mondo',
'Help': 'aiuto',
+'Hide/Show Translated strings': 'Hide/Show Translated strings',
'htmledit': 'modifica come html',
'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.',
'Import/Export': 'Importa/Esporta',
@@ -195,6 +198,8 @@
'NO': 'NO',
'No databases in this application': 'Nessun database presente in questa applicazione',
'no match': 'nessuna corrispondenza',
+'or alternatively': 'or alternatively',
+'Or Get from URL:': 'Or Get from URL:',
'or import from csv file': 'oppure importa da file CSV',
'or provide app url:': "oppure fornisci url dell'applicazione:",
'Original/Translation': 'Originale/Traduzione',
@@ -219,6 +224,7 @@
'record does not exist': 'il record non esiste',
'record id': 'ID del record',
'register': 'registrazione',
+'reload': 'reload',
'Remove compiled': 'rimozione codice compilato',
'request': 'request',
'Resolve Conflict file': 'File di risoluzione conflitto',
@@ -242,6 +248,7 @@
'Start wizard': 'start wizard',
'state': 'stato',
'static': 'statico',
+'Static': 'Static',
'Static files': 'Files statici',
'Stylesheet': 'Foglio di stile (stylesheet)',
'submit': 'invia',
@@ -261,6 +268,7 @@
'There are no models': 'Non ci sono modelli',
'There are no modules': 'Non ci sono moduli',
'There are no plugins': 'There are no plugins',
+'There are no private files': 'There are no private files',
'There are no static files': 'Non ci sono file statici',
'There are no translators, only default language is supported': 'Non ci sono traduzioni, viene solo supportato il linguaggio di base',
'There are no views': 'Non ci sono viste ("view")',
@@ -280,6 +288,7 @@
'Translation strings for the application': 'Translation strings for the application',
'try': 'prova',
'try something like': 'prova qualcosa come',
+'Try the mobile interface': 'Try the mobile interface',
'try view': 'try view',
'Unable to check for upgrades': 'Impossibile controllare presenza di aggiornamenti',
'unable to create application "%s"': 'impossibile creare applicazione "%s"',
@@ -298,6 +307,7 @@
'Update:': 'Aggiorna:',
'upgrade web2py now': 'upgrade web2py now',
'upload': 'upload',
+'Upload': 'Upload',
'Upload & install packed application': 'Carica ed installa pacchetto con applicazione',
'Upload a package:': 'Upload a package:',
'Upload and install packed application': 'Upload and install packed application',
@@ -308,6 +318,7 @@
'Use an url:': 'Use an url:',
'variables': 'variables',
'Version': 'Versione',
+'Version %s.%s.%s %s (%s)': 'Version %s.%s.%s %s (%s)',
'Version %s.%s.%s (%s) %s': 'Version %s.%s.%s (%s) %s',
'versioning': 'sistema di versioni',
'Versioning': 'Versioning',
diff --git a/applications/admin/static/js/ajax_editor.js b/applications/admin/static/js/ajax_editor.js
index 44d5de7d..d2d733ee 100644
--- a/applications/admin/static/js/ajax_editor.js
+++ b/applications/admin/static/js/ajax_editor.js
@@ -43,8 +43,9 @@ function doHighlight(highlight) {
if (window.ace_editor) {
window.ace_editor.gotoLine(highlight.lineno);
} else if (window.mirror) {
- window.mirror.setSelection({line:highlight.lineno,ch:0},
- {line:highlight.end,ch:0});
+ // Put the cursor at the offending line:
+ window.mirror.setCursor({line:highlight.lineno-1,
+ ch:highlight.offset+1});
} else if (window.eamy) {
// not implemented
} else if (window.textarea) {
diff --git a/applications/admin/views/appadmin.html b/applications/admin/views/appadmin.html
index a9f6dab8..95c60ecf 100644
--- a/applications/admin/views/appadmin.html
+++ b/applications/admin/views/appadmin.html
@@ -229,7 +229,21 @@
{{=T('pygraphviz library not found')}}
{{elif not databases:}}
{{=T("No databases in this application")}}
- {{else:}}
+ {{else:}}
+
+
{{=IMG(_src=URL('appadmin', 'bg_graph_model'))}}
{{pass}}
{{pass}}
diff --git a/applications/admin/views/default/edit_language.html b/applications/admin/views/default/edit_language.html
index e1f9f4de..ebfa7ed7 100644
--- a/applications/admin/views/default/edit_language.html
+++ b/applications/admin/views/default/edit_language.html
@@ -22,4 +22,5 @@ function hideShowTranslated(){
{{=form}}
-
\ No newline at end of file
+
+
diff --git a/applications/examples/controllers/appadmin.py b/applications/examples/controllers/appadmin.py
index 99a0186d..a2b2c6ab 100644
--- a/applications/examples/controllers/appadmin.py
+++ b/applications/examples/controllers/appadmin.py
@@ -469,10 +469,10 @@ def ccache():
def table_template(table):
from gluon.html import TR, TD, TABLE, TAG
-
+
def FONT(*args, **kwargs):
return TAG.font(*args, **kwargs)
-
+
def types(field):
f_type = field.type
if not isinstance(f_type,str):
@@ -480,7 +480,7 @@ def table_template(table):
elif f_type == 'string':
return field.length
elif f_type == 'id':
- return B('pk')
+ return B('pk')
elif f_type.startswith('reference') or \
f_type.startswith('list:reference'):
return B('fk')
@@ -495,7 +495,7 @@ def table_template(table):
face = "Helvetica"
face_bold = "Helvetica Bold"
border = 0
-
+
rows.append(TR(TD(FONT(table, _face=face_bold, _color=bgcolor),
_colspan=3, _cellpadding=cellpadding,
_align="center", _bgcolor=color)))
@@ -515,10 +515,31 @@ def table_template(table):
def bg_graph_model():
- graph = pgv.AGraph(layout='dot', directed=True, strict=False, rankdir='LR')
+ graph = pgv.AGraph(layout='dot', directed=True, strict=False, rankdir='LR')
+
+ subgraphs = dict()
for tablename in db.tables:
- graph.add_node(tablename, name=tablename, shape='plaintext',
+ if hasattr(db[tablename],'_meta_graphmodel'):
+ meta_graphmodel = db[tablename]._meta_graphmodel
+ else:
+ meta_graphmodel = dict(group='Undefined', color='#ECECEC')
+
+ group = meta_graphmodel['group'].replace(' ', '')
+ if not subgraphs.has_key(group):
+ subgraphs[group] = dict(meta=meta_graphmodel, tables=[])
+ subgraphs[group]['tables'].append(tablename)
+ else:
+ subgraphs[group]['tables'].append(tablename)
+
+ graph.add_node(tablename, name=tablename, shape='plaintext',
label=table_template(tablename))
+
+ for n, key in enumerate(subgraphs.iterkeys()):
+ graph.subgraph(nbunch=subgraphs[key]['tables'],
+ name='cluster%d' % n,
+ style='filled',
+ color=subgraphs[key]['meta']['color'],
+ label=subgraphs[key]['meta']['group'])
for tablename in db.tables:
for field in db[tablename]:
@@ -532,7 +553,15 @@ def bg_graph_model():
graph.add_edge(n1, n2, color="#4C4C4C", label='')
graph.layout()
- return graph.draw(format='png', prog='dot')
+ #return graph.draw(format='png', prog='dot')
+ if not request.args:
+ return graph.draw(format='png', prog='dot')
+ else:
+ response.headers['Content-Disposition']='attachment;filename=graph.%s'%request.args(0)
+ if request.args(0) == 'dot':
+ return graph.string()
+ else:
+ return graph.draw(format=request.args(0), prog='dot')
-def graph_model():
+def graph_model():
return dict(databases=databases, pgv=pgv)
diff --git a/applications/examples/views/appadmin.html b/applications/examples/views/appadmin.html
index a9f6dab8..95c60ecf 100644
--- a/applications/examples/views/appadmin.html
+++ b/applications/examples/views/appadmin.html
@@ -229,7 +229,21 @@
{{=T('pygraphviz library not found')}}
{{elif not databases:}}
{{=T("No databases in this application")}}
- {{else:}}
+ {{else:}}
+
+
{{=IMG(_src=URL('appadmin', 'bg_graph_model'))}}
{{pass}}
{{pass}}
diff --git a/applications/welcome/controllers/appadmin.py b/applications/welcome/controllers/appadmin.py
index 99a0186d..a2b2c6ab 100644
--- a/applications/welcome/controllers/appadmin.py
+++ b/applications/welcome/controllers/appadmin.py
@@ -469,10 +469,10 @@ def ccache():
def table_template(table):
from gluon.html import TR, TD, TABLE, TAG
-
+
def FONT(*args, **kwargs):
return TAG.font(*args, **kwargs)
-
+
def types(field):
f_type = field.type
if not isinstance(f_type,str):
@@ -480,7 +480,7 @@ def table_template(table):
elif f_type == 'string':
return field.length
elif f_type == 'id':
- return B('pk')
+ return B('pk')
elif f_type.startswith('reference') or \
f_type.startswith('list:reference'):
return B('fk')
@@ -495,7 +495,7 @@ def table_template(table):
face = "Helvetica"
face_bold = "Helvetica Bold"
border = 0
-
+
rows.append(TR(TD(FONT(table, _face=face_bold, _color=bgcolor),
_colspan=3, _cellpadding=cellpadding,
_align="center", _bgcolor=color)))
@@ -515,10 +515,31 @@ def table_template(table):
def bg_graph_model():
- graph = pgv.AGraph(layout='dot', directed=True, strict=False, rankdir='LR')
+ graph = pgv.AGraph(layout='dot', directed=True, strict=False, rankdir='LR')
+
+ subgraphs = dict()
for tablename in db.tables:
- graph.add_node(tablename, name=tablename, shape='plaintext',
+ if hasattr(db[tablename],'_meta_graphmodel'):
+ meta_graphmodel = db[tablename]._meta_graphmodel
+ else:
+ meta_graphmodel = dict(group='Undefined', color='#ECECEC')
+
+ group = meta_graphmodel['group'].replace(' ', '')
+ if not subgraphs.has_key(group):
+ subgraphs[group] = dict(meta=meta_graphmodel, tables=[])
+ subgraphs[group]['tables'].append(tablename)
+ else:
+ subgraphs[group]['tables'].append(tablename)
+
+ graph.add_node(tablename, name=tablename, shape='plaintext',
label=table_template(tablename))
+
+ for n, key in enumerate(subgraphs.iterkeys()):
+ graph.subgraph(nbunch=subgraphs[key]['tables'],
+ name='cluster%d' % n,
+ style='filled',
+ color=subgraphs[key]['meta']['color'],
+ label=subgraphs[key]['meta']['group'])
for tablename in db.tables:
for field in db[tablename]:
@@ -532,7 +553,15 @@ def bg_graph_model():
graph.add_edge(n1, n2, color="#4C4C4C", label='')
graph.layout()
- return graph.draw(format='png', prog='dot')
+ #return graph.draw(format='png', prog='dot')
+ if not request.args:
+ return graph.draw(format='png', prog='dot')
+ else:
+ response.headers['Content-Disposition']='attachment;filename=graph.%s'%request.args(0)
+ if request.args(0) == 'dot':
+ return graph.string()
+ else:
+ return graph.draw(format=request.args(0), prog='dot')
-def graph_model():
+def graph_model():
return dict(databases=databases, pgv=pgv)
diff --git a/applications/welcome/views/appadmin.html b/applications/welcome/views/appadmin.html
index a9f6dab8..95c60ecf 100644
--- a/applications/welcome/views/appadmin.html
+++ b/applications/welcome/views/appadmin.html
@@ -229,7 +229,21 @@
{{=T('pygraphviz library not found')}}
{{elif not databases:}}
{{=T("No databases in this application")}}
- {{else:}}
+ {{else:}}
+
+
{{=IMG(_src=URL('appadmin', 'bg_graph_model'))}}
{{pass}}
{{pass}}
diff --git a/applications/welcome/views/layout.html b/applications/welcome/views/layout.html
index 55e15b7b..16e5dc28 100644
--- a/applications/welcome/views/layout.html
+++ b/applications/welcome/views/layout.html
@@ -1,3 +1,4 @@
+
@@ -6,16 +7,16 @@
-
+{{=response.title or request.application}}
+
-
-
- {{=response.title or request.application}}
+
+
diff --git a/gluon/contrib/markmin/markmin2html.py b/gluon/contrib/markmin/markmin2html.py
index 0f56b603..cbdcec47 100755
--- a/gluon/contrib/markmin/markmin2html.py
+++ b/gluon/contrib/markmin/markmin2html.py
@@ -609,7 +609,7 @@ def protolinks_simple(proto, url):
#elif proto == 'embed': # NOTE: embed is a synonym to iframe now
# return '%s>'%(url,class_prefix,url)
elif proto == 'qr':
- return '
'%url
+ return '
'%url
return proto+':'+url
def render(text,
@@ -701,7 +701,7 @@ def render(text,
'
'
>>> render('[[this is an image http://example.com left 200px]]')
- '
'
+ '
'
>>> render("[[Your browser doesn't support