ABOUT 0000644 0000765 0000024 00000000066 11223012025 011516 0 ustar mdipierro staff Write something about this app.
Developed with web2py. LICENSE 0000644 0000765 0000024 00000000207 11223012025 011723 0 ustar mdipierro staff This is a sample license. You can write here anything you want
as long as you do not violate web2py copyright, trademark and license.
__init__.py 0000644 0000765 0000024 00000000000 11223012025 013016 0 ustar mdipierro staff cache/ 0000755 0000765 0000024 00000000000 11223546024 011775 5 ustar mdipierro staff cache/cache.lock 0000644 0000765 0000024 00000000000 11223546024 013700 0 ustar mdipierro staff controllers/ 0000755 0000765 0000024 00000000000 11223547246 013307 5 ustar mdipierro staff controllers/appadmin.py 0000644 0000765 0000024 00000017506 11223012025 015441 0 ustar mdipierro staff # coding: utf8
# ##########################################################
# ## make sure administrator is on localhost
# ###########################################################
import os
import socket
import datetime
import copy
import gluon.contenttype
import gluon.fileutils
# ## crytical --- make a copy of the environment
global_env = copy.copy(globals())
global_env['datetime'] = datetime
http_host = request.env.http_host.split(':')[0]
remote_addr = request.env.remote_addr
try:
hosts = (http_host, socket.gethostbyname(remote_addr))
except:
hosts = (http_host, )
if remote_addr not in hosts:
raise HTTP(400)
if not gluon.fileutils.check_credentials(request):
redirect('/admin')
ignore_rw = True
response.view = 'appadmin.html'
response.menu = [[T('design'), False, URL('admin', 'default', 'design',
args=[request.application])], [T('db'), False,
URL(r=request, f='index')], [T('state'), False,
URL(r=request, f='state')]]
# ##########################################################
# ## auxiliary functions
# ###########################################################
def get_databases(request):
dbs = {}
for (key, value) in global_env.items():
cond = False
try:
cond = isinstance(value, GQLDB)
except:
cond = isinstance(value, SQLDB)
if cond:
dbs[key] = value
return dbs
databases = get_databases(None)
def eval_in_global_env(text):
exec ('_ret=%s' % text, {}, global_env)
return global_env['_ret']
def get_database(request):
if request.args and request.args[0] in databases:
return eval_in_global_env(request.args[0])
else:
session.flash = T('invalid request')
redirect(URL(r=request, f='index'))
def get_table(request):
db = get_database(request)
if len(request.args) > 1 and request.args[1] in db.tables:
return (db, request.args[1])
else:
session.flash = T('invalid request')
redirect(URL(r=request, f='index'))
def get_query(request):
try:
return eval_in_global_env(request.vars.query)
except Exception:
return None
# ##########################################################
# ## list all databases and tables
# ###########################################################
def index():
return dict(databases=databases)
# ##########################################################
# ## insert a new record
# ###########################################################
def insert():
(db, table) = get_table(request)
form = SQLFORM(db[table], ignore_rw=ignore_rw)
if form.accepts(request.vars, session):
response.flash = T('new record inserted')
return dict(form=form)
# ##########################################################
# ## list all records in table and insert new record
# ###########################################################
def download():
import os
db = get_database(request)
return response.download(request,db)
def csv():
import gluon.contenttype
response.headers['Content-Type'] = \
gluon.contenttype.contenttype('.csv')
db = get_database(request)
query = get_query(request)
if not query:
return None
response.headers['Content-disposition'] = 'attachment; filename=%s_%s.csv'\
% tuple(request.vars.query.split('.')[:2])
return str(db(query).select())
def import_csv(table, file):
table.import_from_csv_file(file)
def select():
import re
db = get_database(request)
dbname = request.args[0]
regex = re.compile('(?P
\w+)\.(?P\w+)=(?P\d+)')
if request.vars.query:
match = regex.match(request.vars.query)
if match:
request.vars.query = '%s.%s.%s==%s' % (request.args[0],
match.group('table'), match.group('field'),
match.group('value'))
else:
request.vars.query = session.last_query
query = get_query(request)
if request.vars.start:
start = int(request.vars.start)
else:
start = 0
nrows = 0
stop = start + 100
table = None
rows = []
orderby = request.vars.orderby
if orderby:
orderby = dbname + '.' + orderby
if orderby == session.last_orderby:
if orderby[0] == '~':
orderby = orderby[1:]
else:
orderby = '~' + orderby
session.last_orderby = orderby
session.last_query = request.vars.query
form = FORM(TABLE(TR(T('Query:'), '', INPUT(_style='width:400px',
_name='query', _value=request.vars.query or '',
requires=IS_NOT_EMPTY(error_message=T("Cannot be empty")))), TR(T('Update:'),
INPUT(_name='update_check', _type='checkbox',
value=False), INPUT(_style='width:400px',
_name='update_fields', _value=request.vars.update_fields
or '')), TR(T('Delete:'), INPUT(_name='delete_check',
_class='delete', _type='checkbox', value=False), ''),
TR('', '', INPUT(_type='submit', _value='submit'))),
_action=URL(r=request,args=request.args))
if request.vars.csvfile != None:
try:
import_csv(db[request.vars.table],
request.vars.csvfile.file)
response.flash = T('data uploaded')
except:
response.flash = T('unable to parse csv file')
if form.accepts(request.vars, formname=None):
regex = re.compile(request.args[0] + '\.(?P
\w+)\.id\>0')
match = regex.match(form.vars.query.strip())
if match:
table = match.group('table')
try:
nrows = db(query).count()
if form.vars.update_check and form.vars.update_fields:
db(query).update(**eval_in_global_env('dict(%s)'
% form.vars.update_fields))
response.flash = T('%s rows updated', nrows)
elif form.vars.delete_check:
db(query).delete()
response.flash = T('%s rows deleted', nrows)
nrows = db(query).count()
if orderby:
rows = db(query).select(limitby=(start, stop),
orderby=eval_in_global_env(orderby))
else:
rows = db(query).select(limitby=(start, stop))
except:
(rows, nrows) = ([], 0)
response.flash = T('Invalid Query')
return dict(
form=form,
table=table,
start=start,
stop=stop,
nrows=nrows,
rows=rows,
query=request.vars.query,
)
# ##########################################################
# ## edit delete one record
# ###########################################################
def update():
(db, table) = get_table(request)
try:
id = int(request.args[2])
record = db(db[table].id == id).select()[0]
except:
session.flash = T('record does not exist')
redirect(URL(r=request, f='select', args=request.args[:1],
vars=dict(query='%s.%s.id>0'
% tuple(request.args[:2]))))
form = SQLFORM(db[table], record, deletable=True, delete_label=T('Check to delete'), ignore_rw=ignore_rw,
linkto=URL(r=request, f='select',
args=request.args[:1]), upload=URL(r=request,
f='download', args=request.args[:1]))
if form.accepts(request.vars, session):
response.flash = T('done!')
redirect(URL(r=request, f='select', args=request.args[:1],
vars=dict(query='%s.%s.id>0'
% tuple(request.args[:2]))))
return dict(form=form)
# ##########################################################
# ## get global variables
# ###########################################################
def state():
return dict()
controllers/default.py 0000644 0000765 0000024 00000001065 11223547243 015304 0 ustar mdipierro staff try:
from gluon.contrib.spreadsheet import Sheet
except:
exec('from applications.%s.modules.sheet import Sheet' % request.application)
def index():
if request.args:
sheet = Sheet.loads(session.psheet)
jquery=sheet.process(request)
session.psheet=sheet.dumps()
return jquery
else:
sheet=Sheet(10,10,URL(r=request))
sheet = Sheet.loads(session.psheet)
#sheet.cell('r0c3' % i,value='=r0c0+r0c1+r0c2',readonly=True)
session.psheet = sheet.dumps()
return dict(sheet=sheet)
cron/ 0000755 0000765 0000024 00000000000 11223012025 011660 5 ustar mdipierro staff databases/ 0000755 0000765 0000024 00000000000 11223547264 012670 5 ustar mdipierro staff errors/ 0000755 0000765 0000024 00000000000 11223547262 012253 5 ustar mdipierro staff languages/ 0000755 0000765 0000024 00000000000 11223012025 012665 5 ustar mdipierro staff languages/fr-fr.py 0000644 0000765 0000024 00000005434 11223012025 014261 0 ustar mdipierro staff {
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN',
'%Y-%m-%d': '%Y-%m-%d',
'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
'%s rows deleted': '%s rang\xc3\xa9es effac\xc3\xa9es',
'%s rows updated': '%s rang\xc3\xa9es mises \xc3\xa0 jour',
'Available databases and tables': 'Available databases and tables',
'Cannot be empty': 'Cannot be empty',
'Check to delete': 'Check to delete',
'Current request': 'Current request',
'Current response': 'Current response',
'Current session': 'Current session',
'Delete:': 'Delete:',
'Edit current record': 'Edit current record',
'Hello World': 'Bonjour Monde',
'Import/Export': 'Import/Export',
'Internal State': 'Internal State',
'Invalid Query': 'Requ\xc3\xaate Invalide',
'New Record': 'New Record',
'No databases in this application': 'No databases in this application',
'Query:': 'Query:',
'Rows in table': 'Rows in table',
'Rows selected': 'Rows selected',
'Sure you want to delete this object?': 'Souhaitez vous vraiment effacercet objet?',
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.',
'Update:': 'Update:',
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.',
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.',
'Welcome to web2py': 'Bienvenue sur web2py',
'click here for online examples': 'cliquez ici pour voir des exemples enligne',
'click here for the administrative interface': "cliquez ici pour aller\xc3\xa0 l'interface d'administration",
'data uploaded': 'donn\xc3\xa9es t\xc3\xa9l\xc3\xa9charg\xc3\xa9es',
'database': 'database',
'database %s select': 'database %s select',
'db': 'db',
'design': 'design',
'done!': 'fait!',
'export as csv file': 'export as csv file',
'insert new': 'insert new',
'insert new %s': 'insert new %s',
'invalid request': 'requ\xc3\xaate invalide',
'new record inserted': 'nouvelle archive ins\xc3\xa9r\xc3\xa9e',
'next 100 rows': 'next 100 rows',
'or import from csv file': 'or import from csv file',
'previous 100 rows': 'previous 100 rows',
'record does not exist': "l'archive n'existe pas",
'record id': 'record id',
'selected': 'selected',
'state': '\xc3\xa9tat',
'table': 'table',
'unable to parse csv file': "incapable d'analyser le fichier cvs",
}
languages/it-it.py 0000644 0000765 0000024 00000005220 11223012025 014264 0 ustar mdipierro staff {
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN',
'%Y-%m-%d': '%Y-%m-%d',
'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
'%s rows deleted': '%s records cancellati',
'%s rows updated': '*** %s records modificati',
'Available databases and tables': 'Available databases and tables',
'Cannot be empty': 'Cannot be empty',
'Check to delete': 'Check to delete',
'Current request': 'Current request',
'Current response': 'Current response',
'Current session': 'Current session',
'Delete:': 'Delete:',
'Edit current record': 'Edit current record',
'Hello World': 'Salve Mondo',
'Import/Export': 'Import/Export',
'Internal State': 'Internal State',
'Invalid Query': 'Query invalida',
'New Record': 'New Record',
'No databases in this application': 'No databases in this application',
'Query:': 'Query:',
'Rows in table': 'Rows in table',
'Rows selected': 'Rows selected',
'Sure you want to delete this object?': 'Sicuro che vuoi cancellare questo oggetto?',
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.',
'Update:': 'Update:',
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.',
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.',
'Welcome to web2py': 'Ciao da wek2py',
'click here for online examples': 'clicca per vedere gli esempi',
'click here for the administrative interface': "clicca per l'interfaccia administrativa",
'data uploaded': 'dati caricati',
'database': 'database',
'database %s select': 'database %s select',
'db': 'db',
'design': 'progetta',
'done!': 'fatto!',
'export as csv file': 'export as csv file',
'insert new': 'insert new',
'insert new %s': 'insert new %s',
'invalid request': 'richiesta invalida!',
'new record inserted': 'nuovo record inserito',
'next 100 rows': 'next 100 rows',
'or import from csv file': 'or import from csv file',
'previous 100 rows': 'previous 100 rows',
'record does not exist': 'il record non esiste',
'record id': 'record id',
'selected': 'selected',
'state': 'stato',
'table': 'table',
'unable to parse csv file': 'non so leggere questo csv file',
}
languages/it.py 0000644 0000765 0000024 00000005220 11223012025 013652 0 ustar mdipierro staff {
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN',
'%Y-%m-%d': '%Y-%m-%d',
'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
'%s rows deleted': '%s records cancellati',
'%s rows updated': '*** %s records modificati',
'Available databases and tables': 'Available databases and tables',
'Cannot be empty': 'Cannot be empty',
'Check to delete': 'Check to delete',
'Current request': 'Current request',
'Current response': 'Current response',
'Current session': 'Current session',
'Delete:': 'Delete:',
'Edit current record': 'Edit current record',
'Hello World': 'Salve Mondo',
'Import/Export': 'Import/Export',
'Internal State': 'Internal State',
'Invalid Query': 'Query invalida',
'New Record': 'New Record',
'No databases in this application': 'No databases in this application',
'Query:': 'Query:',
'Rows in table': 'Rows in table',
'Rows selected': 'Rows selected',
'Sure you want to delete this object?': 'Sicuro che vuoi cancellare questo oggetto?',
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.',
'Update:': 'Update:',
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.',
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.',
'Welcome to web2py': 'Ciao da wek2py',
'click here for online examples': 'clicca per vedere gli esempi',
'click here for the administrative interface': "clicca per l'interfaccia administrativa",
'data uploaded': 'dati caricati',
'database': 'database',
'database %s select': 'database %s select',
'db': 'db',
'design': 'progetta',
'done!': 'fatto!',
'export as csv file': 'export as csv file',
'insert new': 'insert new',
'insert new %s': 'insert new %s',
'invalid request': 'richiesta invalida!',
'new record inserted': 'nuovo record inserito',
'next 100 rows': 'next 100 rows',
'or import from csv file': 'or import from csv file',
'previous 100 rows': 'previous 100 rows',
'record does not exist': 'il record non esiste',
'record id': 'record id',
'selected': 'selected',
'state': 'stato',
'table': 'table',
'unable to parse csv file': 'non so leggere questo csv file',
}
languages/pl-pl.py 0000644 0000765 0000024 00000006172 11223012025 014271 0 ustar mdipierro staff {
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"Uaktualnij" jest dodatkowym wyra\xc5\xbceniem postaci "pole1=\'nowawarto\xc5\x9b\xc4\x87\'". Nie mo\xc5\xbcesz uaktualni\xc4\x87 lub usun\xc4\x85\xc4\x87 wynik\xc3\xb3w z JOIN:',
'%Y-%m-%d': '%Y-%m-%d',
'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
'%s rows deleted': 'Wierszy usuni\xc4\x99tych: %s',
'%s rows updated': 'Wierszy uaktualnionych: %s',
'Available databases and tables': 'Dost\xc4\x99pne bazy danych i tabele',
'Cannot be empty': 'Nie mo\xc5\xbce by\xc4\x87 puste',
'Change Password': 'Change Password',
'Check to delete': 'Zaznacz aby usun\xc4\x85\xc4\x87',
'Current request': 'Aktualne \xc5\xbc\xc4\x85danie',
'Current response': 'Aktualna odpowied\xc5\xba',
'Current session': 'Aktualna sesja',
'Delete:': 'Usu\xc5\x84:',
'Edit Profile': 'Edit Profile',
'Edit current record': 'Edytuj aktualny rekord',
'Hello World': 'Witaj \xc5\x9awiecie',
'Import/Export': 'Importuj/eksportuj',
'Internal State': 'Stan wewn\xc4\x99trzny',
'Invalid Query': 'B\xc5\x82\xc4\x99dne zapytanie',
'Login': 'Zaloguj',
'Logout': 'Logout',
'Lost Password': 'Przypomnij has\xc5\x82o',
'New Record': 'Nowy rekord',
'No databases in this application': 'Brak baz danych w tej aplikacji',
'Query:': 'Zapytanie:',
'Register': 'Zarejestruj',
'Rows in table': 'Wiersze w tabeli',
'Rows selected': 'Wybrane wiersze',
'Sure you want to delete this object?': 'Czy na pewno chcesz usun\xc4\x85\xc4\x87 ten obiekt?',
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"Zapytanie" jest warunkiem postaci "db.tabela1.pole1==\'warto\xc5\x9b\xc4\x87\'". Takie co\xc5\x9b jak "db.tabela1.pole1==db.tabela2.pole2" oznacza SQL JOIN.',
'Update:': 'Uaktualnij:',
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'U\xc5\xbcyj (...)&(...) jako AND, (...)|(...) jako OR oraz ~(...) jako NOT do tworzenia bardziej skomplikowanych zapyta\xc5\x84.',
'Welcome to web2py': 'Witaj w web2py',
'click here for online examples': 'Kliknij aby przej\xc5\x9b\xc4\x87 do interaktywnych przyk\xc5\x82ad\xc3\xb3w',
'click here for the administrative interface': 'Kliknij aby przej\xc5\x9b\xc4\x87 do panelu administracyjnego',
'customize me!': 'dostosuj mnie!',
'data uploaded': 'dane wys\xc5\x82ane',
'database': 'baza danych',
'database %s select': 'wyb\xc3\xb3r z bazy danych %s',
'db': 'baza danych',
'design': 'projektuj',
'done!': 'zrobione!',
'export as csv file': 'eksportuj jako plik csv',
'insert new': 'wstaw nowy rekord tabeli',
'insert new %s': 'wstaw nowy rekord do tabeli %s',
'invalid request': 'B\xc5\x82\xc4\x99dne \xc5\xbc\xc4\x85danie',
'new record inserted': 'nowy rekord zosta\xc5\x82 wstawiony',
'next 100 rows': 'nast\xc4\x99pne 100 wierszy',
'or import from csv file': 'lub zaimportuj z pliku csv',
'previous 100 rows': 'poprzednie 100 wierszy',
'record does not exist': 'rekord nie istnieje',
'record id': 'id rekordu',
'selected': 'wybranych',
'state': 'stan',
'table': 'tabela',
'unable to parse csv file': 'nie mo\xc5\xbcna sparsowa\xc4\x87 pliku csv',
}
languages/pl.py 0000644 0000765 0000024 00000006172 11223012025 013660 0 ustar mdipierro staff {
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"Uaktualnij" jest dodatkowym wyra\xc5\xbceniem postaci "pole1=\'nowawarto\xc5\x9b\xc4\x87\'". Nie mo\xc5\xbcesz uaktualni\xc4\x87 lub usun\xc4\x85\xc4\x87 wynik\xc3\xb3w z JOIN:',
'%Y-%m-%d': '%Y-%m-%d',
'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
'%s rows deleted': 'Wierszy usuni\xc4\x99tych: %s',
'%s rows updated': 'Wierszy uaktualnionych: %s',
'Available databases and tables': 'Dost\xc4\x99pne bazy danych i tabele',
'Cannot be empty': 'Nie mo\xc5\xbce by\xc4\x87 puste',
'Change Password': 'Change Password',
'Check to delete': 'Zaznacz aby usun\xc4\x85\xc4\x87',
'Current request': 'Aktualne \xc5\xbc\xc4\x85danie',
'Current response': 'Aktualna odpowied\xc5\xba',
'Current session': 'Aktualna sesja',
'Delete:': 'Usu\xc5\x84:',
'Edit Profile': 'Edit Profile',
'Edit current record': 'Edytuj aktualny rekord',
'Hello World': 'Witaj \xc5\x9awiecie',
'Import/Export': 'Importuj/eksportuj',
'Internal State': 'Stan wewn\xc4\x99trzny',
'Invalid Query': 'B\xc5\x82\xc4\x99dne zapytanie',
'Login': 'Zaloguj',
'Logout': 'Logout',
'Lost Password': 'Przypomnij has\xc5\x82o',
'New Record': 'Nowy rekord',
'No databases in this application': 'Brak baz danych w tej aplikacji',
'Query:': 'Zapytanie:',
'Register': 'Zarejestruj',
'Rows in table': 'Wiersze w tabeli',
'Rows selected': 'Wybrane wiersze',
'Sure you want to delete this object?': 'Czy na pewno chcesz usun\xc4\x85\xc4\x87 ten obiekt?',
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"Zapytanie" jest warunkiem postaci "db.tabela1.pole1==\'warto\xc5\x9b\xc4\x87\'". Takie co\xc5\x9b jak "db.tabela1.pole1==db.tabela2.pole2" oznacza SQL JOIN.',
'Update:': 'Uaktualnij:',
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'U\xc5\xbcyj (...)&(...) jako AND, (...)|(...) jako OR oraz ~(...) jako NOT do tworzenia bardziej skomplikowanych zapyta\xc5\x84.',
'Welcome to web2py': 'Witaj w web2py',
'click here for online examples': 'Kliknij aby przej\xc5\x9b\xc4\x87 do interaktywnych przyk\xc5\x82ad\xc3\xb3w',
'click here for the administrative interface': 'Kliknij aby przej\xc5\x9b\xc4\x87 do panelu administracyjnego',
'customize me!': 'dostosuj mnie!',
'data uploaded': 'dane wys\xc5\x82ane',
'database': 'baza danych',
'database %s select': 'wyb\xc3\xb3r z bazy danych %s',
'db': 'baza danych',
'design': 'projektuj',
'done!': 'zrobione!',
'export as csv file': 'eksportuj jako plik csv',
'insert new': 'wstaw nowy rekord tabeli',
'insert new %s': 'wstaw nowy rekord do tabeli %s',
'invalid request': 'B\xc5\x82\xc4\x99dne \xc5\xbc\xc4\x85danie',
'new record inserted': 'nowy rekord zosta\xc5\x82 wstawiony',
'next 100 rows': 'nast\xc4\x99pne 100 wierszy',
'or import from csv file': 'lub zaimportuj z pliku csv',
'previous 100 rows': 'poprzednie 100 wierszy',
'record does not exist': 'rekord nie istnieje',
'record id': 'id rekordu',
'selected': 'wybranych',
'state': 'stan',
'table': 'tabela',
'unable to parse csv file': 'nie mo\xc5\xbcna sparsowa\xc4\x87 pliku csv',
}
languages/pt-br.py 0000644 0000765 0000024 00000005634 11223012025 014273 0 ustar mdipierro staff {
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" \xc3\xa9 uma express\xc3\xa3o opcional como "campo1=\'novovalor\'". Voc\xc3\xaa n\xc3\xa3o pode atualizar ou apagar os resultados de um JOIN',
'%Y-%m-%d': '%Y-%m-%d',
'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
'%s rows deleted': '%s linhas apagadas',
'%s rows updated': '%s linhas atualizadas',
'Available databases and tables': 'Bancos de dados e tabelas dispon\xc3\xadveis',
'Cannot be empty': 'N\xc3\xa3o pode ser vazio',
'Check to delete': 'Marque para apagar',
'Current request': 'Requisi\xc3\xa7\xc3\xa3o atual',
'Current response': 'Resposta atual',
'Current session': 'Sess\xc3\xa3o atual',
'Delete:': 'Apagar:',
'Edit current record': 'Editar o registro atual',
'Hello World': 'Ol\xc3\xa1 Mundo',
'Import/Export': 'Importar/Exportar',
'Internal State': 'Estado Interno',
'Invalid Query': 'Consulta Inv\xc3\xa1lida',
'Login': 'Autentique-se',
'Lost Password': 'Esqueceu sua senha?',
'New Record': 'Novo Registro',
'No databases in this application': 'Sem bancos de dados nesta aplica\xc3\xa7\xc3\xa3o',
'Query:': 'Consulta:',
'Register': 'Registre-se',
'Rows in table': 'Linhas na tabela',
'Rows selected': 'Linhas selecionadas',
'Sure you want to delete this object?': 'Est\xc3\xa1 certo(a) que deseja apagar esse objeto ?',
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'Uma "consulta" \xc3\xa9 uma condi\xc3\xa7\xc3\xa3o como "db.tabela1.campo1==\'valor\'". Express\xc3\xb5es como "db.tabela1.campo1==db.tabela2.campo2" resultam em um JOIN SQL.',
'Update:': 'Atualizar:',
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) para AND, (...)|(...) para OR, e ~(...) para NOT para construir consultas mais complexas.',
'Welcome to web2py': 'Bem vindo ao web2py',
'click here for online examples': 'clique aqui para ver alguns exemplos',
'click here for the administrative interface': 'clique aqui para acessar a interface administrativa',
'customize me!': 'Personalize-me!',
'data uploaded': 'dados enviados',
'database': 'banco de dados',
'database %s select': 'Selecionar banco de dados %s',
'db': 'db',
'design': 'design',
'done!': 'conclu\xc3\xaddo!',
'export as csv file': 'exportar como um arquivo csv',
'insert new': 'inserir novo',
'insert new %s': 'inserir novo %s',
'invalid request': 'requisi\xc3\xa7\xc3\xa3o inv\xc3\xa1lida',
'new record inserted': 'novo registro inserido',
'next 100 rows': 'pr\xc3\xb3ximas 100 linhas',
'or import from csv file': 'ou importar de um arquivo csv',
'previous 100 rows': '100 linhas anteriores',
'record does not exist': 'registro n\xc3\xa3o existe',
'record id': 'id do registro',
'selected': 'selecionado',
'state': 'estado',
'table': 'tabela',
'unable to parse csv file': 'n\xc3\xa3o foi poss\xc3\xadvel analisar arquivo csv',
}
languages/pt-pt.py 0000644 0000765 0000024 00000005417 11223012025 014312 0 ustar mdipierro staff {
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN',
'%Y-%m-%d': '%Y-%m-%d',
'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
'%s rows deleted': '%s linhas eliminadas',
'%s rows updated': '%s linhas actualizadas',
'Available databases and tables': 'Available databases and tables',
'Cannot be empty': 'Cannot be empty',
'Check to delete': 'Check to delete',
'Current request': 'Current request',
'Current response': 'Current response',
'Current session': 'Current session',
'Delete:': 'Delete:',
'Edit current record': 'Edit current record',
'Hello World': 'Ol\xc3\xa1 Mundo',
'Import/Export': 'Import/Export',
'Internal State': 'Internal State',
'Invalid Query': 'Consulta Inv\xc3\xa1lida',
'New Record': 'New Record',
'No databases in this application': 'No databases in this application',
'Query:': 'Query:',
'Rows in table': 'Rows in table',
'Rows selected': 'Rows selected',
'Sure you want to delete this object?': 'Tem a certeza que deseja eliminar este objecto?',
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.',
'Update:': 'Update:',
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.',
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.',
'Welcome to Gluonization': 'Bem vindo ao Web2py',
'Welcome to web2py': 'Welcome to web2py',
'click here for online examples': 'Clique aqui para exemplos online',
'click here for the administrative interface': 'Clique aqui para o painel administrativo',
'data uploaded': 'informa\xc3\xa7\xc3\xa3o enviada',
'database': 'database',
'database %s select': 'database %s select',
'db': 'bd',
'design': 'design',
'done!': 'conclu\xc3\xaddo!',
'export as csv file': 'export as csv file',
'insert new': 'insert new',
'insert new %s': 'insert new %s',
'invalid request': 'Pedido Inv\xc3\xa1lido',
'new record inserted': 'novo registo inserido',
'next 100 rows': 'next 100 rows',
'or import from csv file': 'or import from csv file',
'previous 100 rows': 'previous 100 rows',
'record does not exist': 'registo inexistente',
'record id': 'record id',
'selected': 'selected',
'state': 'estado',
'table': 'table',
'unable to parse csv file': 'n\xc3\xa3o foi poss\xc3\xadvel carregar ficheiro csv',
}
languages/pt.py 0000644 0000765 0000024 00000005417 11223012025 013671 0 ustar mdipierro staff {
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN',
'%Y-%m-%d': '%Y-%m-%d',
'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
'%s rows deleted': '%s linhas eliminadas',
'%s rows updated': '%s linhas actualizadas',
'Available databases and tables': 'Available databases and tables',
'Cannot be empty': 'Cannot be empty',
'Check to delete': 'Check to delete',
'Current request': 'Current request',
'Current response': 'Current response',
'Current session': 'Current session',
'Delete:': 'Delete:',
'Edit current record': 'Edit current record',
'Hello World': 'Ol\xc3\xa1 Mundo',
'Import/Export': 'Import/Export',
'Internal State': 'Internal State',
'Invalid Query': 'Consulta Inv\xc3\xa1lida',
'New Record': 'New Record',
'No databases in this application': 'No databases in this application',
'Query:': 'Query:',
'Rows in table': 'Rows in table',
'Rows selected': 'Rows selected',
'Sure you want to delete this object?': 'Tem a certeza que deseja eliminar este objecto?',
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.',
'Update:': 'Update:',
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.',
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.',
'Welcome to Gluonization': 'Bem vindo ao Web2py',
'Welcome to web2py': 'Welcome to web2py',
'click here for online examples': 'Clique aqui para exemplos online',
'click here for the administrative interface': 'Clique aqui para o painel administrativo',
'data uploaded': 'informa\xc3\xa7\xc3\xa3o enviada',
'database': 'database',
'database %s select': 'database %s select',
'db': 'bd',
'design': 'design',
'done!': 'conclu\xc3\xaddo!',
'export as csv file': 'export as csv file',
'insert new': 'insert new',
'insert new %s': 'insert new %s',
'invalid request': 'Pedido Inv\xc3\xa1lido',
'new record inserted': 'novo registo inserido',
'next 100 rows': 'next 100 rows',
'or import from csv file': 'or import from csv file',
'previous 100 rows': 'previous 100 rows',
'record does not exist': 'registo inexistente',
'record id': 'record id',
'selected': 'selected',
'state': 'estado',
'table': 'table',
'unable to parse csv file': 'n\xc3\xa3o foi poss\xc3\xadvel carregar ficheiro csv',
}
models/ 0000755 0000765 0000024 00000000000 11223012025 012202 5 ustar mdipierro staff models/db.py 0000644 0000765 0000024 00000006133 11223012025 013144 0 ustar mdipierro staff # coding: utf8
#########################################################################
## This scaffolding model makes your app work on Google App Engine too
#########################################################################
if request.env.web2py_runtime_gae: # if running on Google App Engine
from gluon.contrib.gql import *
### connect to Google BigTable
db = GQLDB()
## and store sessions and tickets there
session.connect(request, response, db=db)
### or use the following lines to store sessions in Memcache
# from gluon.contrib.memdb import MEMDB
# from google.appengine.api.memcache import Client
# session.connect(request, response, db=MEMDB(Client()))
else: # else use a normal relational database
# if not, use SQLite or other DB
db = SQLDB('sqlite://storage.sqlite')
#########################################################################
## uncomment the following line if you do not want sessions
#session.forget()
#########################################################################
#########################################################################
## Define your tables below, for example
##
## >>> db.define_table('mytable',SQLField('myfield','string'))
##
## Fields can be 'string','text','password','integer','double','boolean'
## 'date','time','datetime','blob','upload', 'reference TABLENAME'
## There is an implicit 'id integer autoincrement' field
## Consult manual for more options, validators, etc.
##
## More API examples for controllers:
##
## >>> db.mytable.insert(myfield='value')
## >>> rows=db(db.mytbale.myfield=='value).select(db.mytable.ALL)
## >>> for row in rows: print row.id, row.myfield
#########################################################################
#########################################################################
## Here is sample code if you need:
## - email capabilities
## - authentication (registration, login, logout, ... )
## - authorization (role based authorization)
## - services (xml, csv, json, xmlrpc, jsonrpc, amf, rss)
## - crud actions
## comment/uncomment as needed
#########################################################################
from gluon.tools import *
auth=Auth(globals(),db) # authentication/authorization
auth.define_tables() # creates all needed tables
crud=Crud(globals(),db) # for CRUD helpers using auth
service=Service(globals()) # for json, xml, jsonrpc, xmlrpc, amfrpc
## uncomment as necessary or consult docs for more options
#crud.settings.auth=auth # (optional) enforces authorization on crud
#mail=Mail() # mailer
#mail.settings.server='smtp.gmail.com:587' # your SMTP server
#mail.settings.sender='you@gmail.com' # your email
#mail.settings.login='username:password' # your credentials
#auth.settings.mailer=mail # for user email verification
#auth.settings.registration_requires_verification = True
#auth.settings.registration_requires_approval = True
#auth.messages.verify_email = \
# 'Click on the link http://.../verify_email/%(key)s to verify your email'
models/menu.py 0000644 0000765 0000024 00000005533 11223012025 013526 0 ustar mdipierro staff # coding: utf8
#########################################################################
## Customize your APP title, subtitle and menus here
#########################################################################
response.title = request.application
response.subtitle = T('customize me!')
##########################################
## this is the authentication menu
## remove if not necessary
##########################################
if 'auth' in globals():
if not auth.is_logged_in():
response.menu_auth = [
[T('Login'), False, auth.settings.login_url,
[
[T('Register'), False,
URL(request.application,'default','user/register')],
[T('Lost Password'), False,
URL(request.application,'default','user/retrieve_password')]]
],
]
else:
response.menu_auth = [
['User: '+auth.user.first_name,False,None,
[
[T('Logout'), False,
URL(request.application,'default','user/logout')],
[T('Edit Profile'), False,
URL(request.application,'default','user/profile')],
[T('Change Password'), False,
URL(request.application,'default','user/change_password')]]
],
]
##########################################
## this is the main applicaiton menu
## add/remove items as required
##########################################
response.menu = [
['Index', False,
URL(request.application,'default','index'), []],
]
##########################################
## this is here to provide shortcuts
## during development. remove in production
##########################################
response.menu_edit=[
['Edit', False, URL('admin', 'default', 'design/%s' % request.application),
[
['Controller', False,
URL('admin', 'default', 'edit/%s/controllers/default.py' \
% request.application)],
['View', False,
URL('admin', 'default', 'edit/%s/views/%s' \
% (request.application,response.view))],
['Layout', False,
URL('admin', 'default', 'edit/%s/views/layout.html' \
% request.application)],
['Stylesheet', False,
URL('admin', 'default', 'edit/%s/static/base.css' \
% request.application)],
['DB Model', False,
URL('admin', 'default', 'edit/%s/models/db.py' \
% request.application)],
['Menu Model', False,
URL('admin', 'default', 'edit/%s/models/menu.py' \
% request.application)],
['Database', False,
URL(request.application, 'appadmin', 'index')],
]
],
]
modules/ 0000755 0000765 0000024 00000000000 11223513775 012411 5 ustar mdipierro staff modules/__init__.py 0000644 0000765 0000024 00000000000 11223012025 014466 0 ustar mdipierro staff modules/sheet.py 0000644 0000765 0000024 00000017535 11223547113 014077 0 ustar mdipierro staff """
Developed by Massimo Di Pierro, optional component of web2py, GPL2 license.
"""
import re
import pickle
import copy
def quote(text):
return str(text).replace('\\','\\\\').replace("'","\\'")
class Node:
"""
Example::
# controller
from gluon.contrib.spreadsheet import Sheet
def index():
if request.args:
sheet = Sheet.loads(session.psheet)
jquery=sheet.process(request)
session.psheet=sheet.dumps()
return jquery
else:
sheet=Sheet(10,10,URL(r=request))
#sheet = Sheet.loads(session.psheet)
sheet.cell('r0c3',value='=r0c0+r0c1+r0c2',readonly=True)
session.psheet = sheet.dumps()
return dict(sheet=sheet)
# view
{{extend 'layout.html'}}
"""
def __init__(self,name,value,url='.',readonly=False,active=True,onchange=None):
self.url=url
self.name=name
self.value=value
self.computed_value=''
self.incoming={}
self.outcoming={}
self.readonly=readonly
self.active=active
self.onchange=onchange
self.size=6
self.locked=False
def xml(self):
return """
""" % (self.name,self.name,self.computed_value,self.size,
self.url,self.name,self.url,self.name,self.url,self.name,
(self.readonly and 'readonly ') or '')
def __repr__(self):
return '%s:%s' % (self.name,self.computed_value)
class Sheet:
regex=re.compile('(?'
+ r"[uU]?[rR]?'''([^']+|'{1,2}(?!'))*'''|"
+ r"'([^'\\]|\\.)*'|"
+ r'"""([^"]|"{1,2}(?!"))*"""|'
+ r'"([^"\\]|\\.)*")', re.DOTALL)
def dumps(self):
dump=pickle.dumps(self)
return dump
@staticmethod
def loads(data):
sheet=pickle.loads(data)
return sheet
def process(self,request):
"""
call this in action that creates table, it will handle ajax callbacks
"""
cell=request.vars.keys()[0]
if request.args(0)=='focus':
return "jQuery('#%s').val('%s');" % (cell,quote(self[cell].value))
value = request.vars[cell]
self[cell]=value
if request.args(0)=='blur':
return "jQuery('#%s').val('%s');" % (cell,quote(self[cell].computed_value))
elif request.args(0)=='keyup':
jquery=''
for other_key in self.modified:
if other_key!=cell:
jquery+="jQuery('#%s').val('%s');" % \
(other_key,quote(self[other_key].computed_value))
return jquery
def __init__(self,rows,cols,url='.'):
self.rows=rows
self.cols=cols
self.url=url
self.nodes={}
self.error='ERROR: %(error)s'
self.allowed_keywords=['for','in','if','else','and','or','not',
'i','j','k','x','y','z','sum']
self.environment={}
[self.cell('r%sc%s'%(k/cols,k%cols),'0.0') for k in xrange(rows*cols)]
exec('from math import *',{},self.environment)
def delete_from(self,other_list):
indices = [k for (k,node) in enumerate(other_list) if k==node]
if indices: del other_list[indices[0]]
def changed(self,node,changed_nodes=[]):
for other_node in node.outcoming:
if not other_node in changed_nodes:
changed_nodes.append(other_node)
self.changed(other_node,changed_nodes)
return changed_nodes
def define(self,name,obj):
self.environment[name]=obj
def cell(self,key,value,readonly=False,active=True,onchange=None):
"""
key is the name of the cell
value is the initial value of the cell. It can be a formula "=1+3"
a cell is active if it evaluates formuls
"""
if not self.regex.match(key): raise SyntaxError, "Invalid cell name"
node=Node(key,value,self.url,readonly,active,onchange)
self.nodes[key]=node
self[key]=value
def __setitem__(self,key,value):
node=self.nodes[key]
node.value=value
if value[:1]=='=' and node.active:
# clear all edges involving current node
for other_node in node.incoming:
del other_node.outcoming[node]
node.incoming.clear()
# build new edges
command = self.re_strings.sub("''",value[1:])
node.locked=False
for match in self.regex.finditer(command):
other_key=match.group()
if other_key==key:
self.computed_value=self.error % dict(error='cycle')
self.modified={}
break
if other_key in self.nodes:
other_node=self.nodes[other_key]
other_node.outcoming[node]=True
node.incoming[other_node]=True
elif not other_key in self.allowed_keywords and \
not other_key in self.environment:
node.locked=True
node.computed_value=self.error % dict(error='invalid keyword: '+other_key)
self.modified={}
break
self.compute(node)
else:
try:
node.computed_value=int(node.value)
except:
try:
node.computed_value=float(node.value)
except:
node.computed_value=node.value
self.environment[key]=node.computed_value
if node.onchange: node.onchange()
self.modified=self.iterate(node)
def compute(self,node):
if node.value[:1]=='=' and not node.locked:
try:
exec('__value__='+node.value[1:],{},self.environment)
node.computed_value=self.environment['__value__']
del self.environment['__value__']
except Exception,e:
node.computed_value=self.error % dict(error=str(e))
self.environment[node.name]=node.computed_value
if node.onchange: node.onchange()
def iterate(self,node):
output={node.name:node.computed_value}
changed_nodes = self.changed(node)
while changed_nodes:
ok=False
set_changed_nodes=set(changed_nodes)
for (k,other_node) in enumerate(changed_nodes):
#print other_node, changed_nodes
if not set(other_node.incoming.keys()).intersection(set_changed_nodes):
#print 'ok'
self.compute(other_node)
output[other_node.name]=other_node.computed_value
#print other_node
del changed_nodes[k]
ok=True
break
if not ok: return {}
return output
def __getitem__(self,key):
return self.nodes[key]
if __name__=='__main__':
s=Sheet(0,0)
s.cell('a',value="2")
s.cell('b',value="=sin(a)")
s.cell('c',value="=cos(a)**2+b*b")
print s['c'].computed_value
private/ 0000755 0000765 0000024 00000000000 11223257320 012402 5 ustar mdipierro staff private/sheet.py 0000644 0000765 0000024 00000007130 11223034301 014055 0 ustar mdipierro staff import re
class Sheet:
regex = re.compile('\{\d+x\d+\}')
class Node:
def __init__(self,name):
self.name=name
self.value=''
self.computed_value=''
self.incoming={}
self.outcoming={}
self.changed=False
self.count=0
def __init__(self,rows,cols):
self.rows=rows
self.cols=cols
names=['{%sx%s}'%(k/cols,k%cols) for k in xrange(rows*cols)]
self.nodes=dict([(name,Sheet.Node(name)) for name in names])
print self.nodes
def delete_from(self,other_list):
indices = [k for (k,node) in enumerate(other_list) if k==node]
if indices: del other_list[indices[0]]
def changed(self,node,changed_nodes=[]):
for other_node in node.outcoming:
if not other_node in changed_nodes:
changed_nodes.append(other_node)
self.changed(other_node,changed_nodes)
return changed_nodes
def set(self,key,value):
node=self.nodes[key]
node.value=value
if value[:1]=='=':
# clear all edges involving current node
for other_node in node.incoming:
del node.outcoming[me]
node.incoming.clear()
# build new edges
for match in self.regex.finditer(value[1:]):
other_key=match.group()
other_node=self.nodes[other_key]
other_node.outcoming[node]=True
node.incoming[other_node]=True
self.calculate(node)
else:
try:
node.computed_value=int(node.value)
except:
try:
node.computed_value=float(node.value)
except:
node.computed_value=node.value
return self.iterate(node)
def calculate(self,node):
if node.value[:1]=='=':
command=node.value[1:]
for match in self.regex.finditer(command):
other_key=match.group()
other_value=self.nodes[other_key].computed_value or 0.0
command=command.replace(other_key,repr(other_value))
print 'computing',node.name,command
try:
node.computed_value=eval(command)
except:
node.computed_value='ERROR'
print node.name,node.computed_value
def iterate(self,node):
output={node.name:node.computed_value}
changed_nodes = self.changed(node)
while changed_nodes:
ok=False
for (k,other_node) in enumerate(changed_nodes):
if not set(other_node.incoming.keys()).intersection(set(changed_nodes)):
self.calculate(other_node)
output[other_node.name]=other_node.computed_value
del changed_nodes[k]
ok=True
break
if not ok: raise SynataxError
return output
"""
L = Empty list that will contain the sorted elements
S = Set of all nodes with no incoming edges
while S is non-empty do
remove a node n from S
insert n into L
for each node m with an edge e from n to m do
remove edge e from the graph
if m has no other incoming edges then
insert m into S
if graph has edges then
output error message (graph has at least one cycle)
else
output message (proposed topologically sorted order: L)
"""
s=Sheet(4,4)
s.set('{1x2}','={0x0}')
s.set('{0x0}','=5+{1x1}+{2x2}')
s.set('{1x1}','6')
print s.set('{2x2}',"3")
sessions/ 0000755 0000765 0000024 00000000000 11223547257 012611 5 ustar mdipierro staff static/ 0000755 0000765 0000024 00000000000 11223012025 012206 5 ustar mdipierro staff static/base.css 0000644 0000765 0000024 00000021133 11223012025 013632 0 ustar mdipierro staff @charset "UTF-8";
* {
background: transparent;
border: 0;
margin: 0;
outline: 0;
padding: 0;
color: inherit;
font-weight: inherit;
font-style: inherit;
font-family: inherit;
vertical-align: baseline;
font-size: 100%;
}
body {
width:100%;
min-width: 600px;
}
table {
border-spacing: 0;
border-collapse: collapse;
}
label,
th,
td {
text-align: left;
vertical-align: top;
padding-left: 0.5em;
padding-right: 0.5em;
padding-top: 0.3em;
padding-bottom: 0.2em;
}
th,
thead td,
tfoot td {
font-weight: bold;
text-align: center;
}
b {
font-weight: bold;
}
i {
font-style: italic;
}
pre {
font-size: 0.8em;
font-family: monospace,
courier;
padding-left: 2em;
padding-top: 1em;
}
tt {
font-size: 0.8em;
font-family: monospace,
courier;
}
h1 {
padding-top: 0.5em;
font-size: 2em;
}
h2 {
padding-top: 0.4em;
font-size: 1.5em;
}
h3 {
padding-top: 0.3em;
font-size: 1em;
}
p {
padding-top: 0.2em;
text-align: justify;
}
ol,
ul {
padding-top: 0.3em;
padding-left: 1.5em;
}
label {
font-weight: bold;
}
a {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
input,
textarea {
border: 1px #666666 solid;
}
input:focus,
textarea:focus {
background: #ffcccc;
}
html {
font-size: 10pt;
font-family: Georgia, Times new Roman;
color: #333333;
background: #cccccc;
}
a {
color: #FF5C1F;
}
.flash {
z-index: 2;
position: absolute;
top: 0px;
right: 20%;
width: 60%;
height: 50px;
opacity: 0.75;
margin: 0 auto;
text-align: center;
clear: both;
border: 1px #000000 solid;
color: black;
font-size: 12pt;
padding: 100px 10px 10px 10px;
cursor: pointer;
background: white;
/*
margin: 0 auto;
text-align: center;
clear: both;
border: 1px solid #99f;
background-color: #ddf;
cursor: pointer;
margin-top: 0.0em;
margin-bottom: 1.0em;
padding-top: 1.0em;
padding-bottom: 1.0em;
*/
}
div.error {
background-color: red;
color: white;
padding: 3px;
}
.warn {
background-color: yellow;
color: black;
padding: 5px;
}
.info {
background-color: #E5FFE5;
color: black;
padding: 5px;
}
.error {
background-color: red;
color: white; padding: 5px;
}
.wrapper {
padding-top: 20px;
padding-left: 20px;
}
.layout {
width: 95%;
padding: 0;
border: 1px #99f solid;
border-spacing: 0;
background: #fff;
z-index: 1;
}
.header {
border-bottom: 1px #99f solid;
}
.statusbar {
background: #ddf;
border-bottom: 1px #99f solid;
}
.footer {
border-top: 1px #99f solid;
}
.width10em {
width: 10em;
background: transparent;
}
.expandable {
background: transparent;
}
ul.web2py-menu,
ul.web2py-menu ul,
ul.web2py-menu li,
ul.web2py-menu a
{
display: block;
margin: 0;
padding: 0;
}
ul.web2py-menu,
ul.web2py-menu li,
ul.web2py-menu ul
{
list-style: none;
}
ul.web2py-menu ul
{
display: none;
}
ul.web2py-menu li
{
position: relative;
z-index: 1;
}
ul.web2py-menu li:hover
{
z-index: 999;
}
ul.web2py-menu li:hover > ul
{
display: block;
position: absolute;
}
ul.web2py-menu-horizontal li
{
float: left;
width: auto;
}
ul.web2py-menu-hRight li
{
float: right;
}
ul.web2py-menu-vertical li
{
float: none;
}
ul.web2py-menu-vertical,
ul.web2py-menu-vertical ul
{
width: 10em;
}
ul.web2py-menu-wide
{
width: 100%;
}
ul.web2py-menu-vRight
{
float: right;
}
ul.web2py-menu-lFloat
{
float: left;
}
ul.web2py-menu-noFloat
{
float: none;
}
div.web2py-menu-center ul.web2py-menu
{
float: left;
position: relative;
left: 50%;
}
div.web2py-menu-center ul.web2py-menu li
{
position: relative;
left: -50%;
}
div.web2py-menu-center ul.web2py-menu li li
{
left: auto;
}
ul.web2py-menu-horizontal ul
{
top: auto;
right: auto;
left: auto;
margin-top: -1px;
}
ul.web2py-menu-vertical ul
{
left: 60%;
right: auto;
top: auto;
margin-top: -0.5em;
}
ul.web2py-menu-vRight ul,
ul.web2py-menu-hRight ul.web2py-menu-vertical ul,
ul.web2py-menu-dRight,
ul.web2py-menu-dRight ul
{
left: -60%;
right: auto;
top: auto;
margin-top: -0.5em;
}
ul.web2py-menu-hRight ul
{
left: auto;
right: 0;
top: auto;
margin-top: -1px;
}
ul.web2py-menu li a
{
border: solid 1px #99f
}
ul.web2py-menu-horizontal li
{
margin-bottom: -1px;
margin-left: -1px;
}
ul.web2py-menu-horizontal
{
padding-left: 1px ;
}
ul.web2py-menu-vertical li
{
margin-left: 0;
margin-top: -1px;
}
ul.web2py-menu-vertical
{
border-top: solid 1px #fff;
}
ul.web2py-menu li a
{
padding: 2px 5px 3px;
}
ul.web2py-menu li a:link,
ul.web2py-menu li a:hover,
ul.web2py-menu li a:visited,
ul.web2py-menu li a:active
{
text-decoration: none;
}
ul.web2py-menu li.sfhover a:active,
ul.web2py-menu li:hover a:active
{
color: #fff;
background-color: #c00;
}
ul.web2py-menu li
{
background-color: #ddf;
}
ul.web2py-menu li:hover,
ul.web2py-menu li.sfhover
{
background-color: #eda;
}
ul.web2py-menu li a:hover
{
background-color: #ffc;
}
ul.web2py-menu li.web2py-menu-expand a,
ul.web2py-menu li.web2py-menu-expand li.web2py-menu-expand a,
ul.web2py-menu li.web2py-menu-expand li.web2py-menu-expand li.web2py-menu-expand a
{
padding-right: 25px;
// background-image: url("expand-right.gif");
// background-repeat: no-repeat;
// background-position: 100% 50%;
}
ul.web2py-menu-vRight li.web2py-menu-expand a,
ul.web2py-menu-vRight li.web2py-menu-expand li.web2py-menu-expand a,
ul.web2py-menu-vRight li.web2py-menu-expand li.web2py-menu-expand li.web2py-menu-expand a,
ul.web2py-menu-hRight li.web2py-menu-expand a,
ul.web2py-menu-hRight li.web2py-menu-expand li.web2py-menu-expand a,
ul.web2py-menu-hRight li.web2py-menu-expand li.web2py-menu-expand li.web2py-menu-expand a
{
padding-right: 5px;
padding-left: 20px;
// background-image: url("expand-left.gif");
// background-repeat: no-repeat;
// background-position: -5px 50%;
}
ul.web2py-menu-horizontal li.web2py-menu-expand a
{
padding-left: 5px;
padding-right: 15px;
// background-image: url("expand-down.gif");
// background-position: 100% 50%;
}
ul.web2py-menu li.web2py-menu-expand li a,
ul.web2py-menu li.web2py-menu-expand li.web2py-menu-expand li a,
ul.web2py-menu li.web2py-menu-expand li.web2py-menu-expand li.web2py-menu-expand li a
{
background-image: none;
padding-right: 5px;
padding-left: 5px;
}
* html ul.web2py-menu
{
display: inline-block;
display: block;
position: relative;
position: static;
}
* html ul.web2py-menu ul
{
float: left;
float: none;
}
ul.web2py-menu ul
{
background-color: #fff;
}
* html ul.web2py-menu-vertical li,
* html ul.web2py-menu-horizontal li ul.web2py-menu-vertical li
{
width: 100%;
float: left;
clear: left;
}
*:first-child+html ul.web2py-menu-vertical > li:hover ul
{
min-width: 0;
}
ul.web2py-menu li a
{
position: relative;
min-width: 0;
}
* html ul.web2py-menu-horizontal li
{
width: 6em;
width: auto;
}
* html div.web2py-menu-center
{
position: relative;
z-index: 1;
}
html:not([lang*=""]) div.web2py-menu-center ul.web2py-menu li a:hover {
height: 100%;
}
html:not([lang*=""]) div.web2py-menu-center ul.web2py-menu li a:hover {
height: auto;
}
* html ul.web2py-menu ul
{
display: block;
position: absolute;
}
* html ul.web2py-menu ul,
* html ul.web2py-menu-horizontal ul,
* html ul.web2py-menu-vertical ul,
* html ul.web2py-menu-vRight ul,
* html ul.web2py-menu-hRight ul.web2py-menu-vertical ul,
* html ul.web2py-menu-hRight ul
{
left: -10000px;
}
* html ul.web2py-menu li.sfhover
{
z-index: 999;
}
* html ul.web2py-menu li.sfhover ul
{
left: auto;
}
* html ul.web2py-menu li.sfhover ul ul,
* html ul.web2py-menu li.sfhover ul ul ul
{
display: none;
}
* html ul.web2py-menu li.sfhover ul,
* html ul.web2py-menu li li.sfhover ul,
* html ul.web2py-menu li li li.sfhover ul
{
display: block;
}
* html ul.web2py-menu-vertical li.sfhover ul
{
left: 60%;
}
* html ul.web2py-menu-vRight li.sfhover ul,
* html ul.web2py-menu-hRight ul.web2py-menu-vertical li.sfhover ul
{
left: -60%;
}
* html ul.web2py-menu iframe
{
position: absolute;
left: 0;
top: 0;
z-index: -1;
}
.clearfix:after
{
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.clearfix
{
min-width: 0;
display: inline-block;
display: block;
}
* html .clearfix
{
height: 1%;
}
static/calendar.css 0000755 0000765 0000024 00000010550 11223012025 014475 0 ustar mdipierro staff .calendar{position:relative;display:none;border-top:2px solid #fff;border-right:2px solid #000;border-bottom:2px solid #000;border-left:2px solid #fff;font-size:11px;color:#000;cursor:default;background:#d4d0c8;font-family:tahoma,verdana,sans-serif;}.calendar table{border-top:1px solid #000;border-right:1px solid #fff;border-bottom:1px solid #fff;border-left:1px solid #000;font-size:11px;color:#000;cursor:default;background:#d4d0c8;font-family:tahoma,verdana,sans-serif;}.calendar .button{text-align:center;padding:1px;border-top:1px solid #fff;border-right:1px solid #000;border-bottom:1px solid #000;border-left:1px solid #fff;}.calendar .nav{background:transparent}.calendar thead .title{font-weight:bold;padding:1px;border:1px solid #000;background:#848078;color:#fff;text-align:center;}.calendar thead .name{border-bottom:1px solid #000;padding:2px;text-align:center;background:#f4f0e8;}.calendar thead .weekend{color:#f00;}.calendar thead .hilite{border-top:2px solid #fff;border-right:2px solid #000;border-bottom:2px solid #000;border-left:2px solid #fff;padding:0;background-color:#e4e0d8;}.calendar thead .active{padding:2px 0 0 2px;border-top:1px solid #000;border-right:1px solid #fff;border-bottom:1px solid #fff;border-left:1px solid #000;background-color:#c4c0b8;}.calendar tbody .day{width:2em;text-align:right;padding:2px 4px 2px 2px;}.calendar tbody .day.othermonth{font-size:80%;color:#aaa;}.calendar tbody .day.othermonth.oweekend{color:#faa;}.calendar table .wn{padding:2px 3px 2px 2px;border-right:1px solid #000;background:#f4f0e8;}.calendar tbody .rowhilite td{background:#e4e0d8;}.calendar tbody .rowhilite td.wn{background:#d4d0c8;}.calendar tbody td.hilite{padding:1px 3px 1px 1px;border-top:1px solid #fff;border-right:1px solid #000;border-bottom:1px solid #000;border-left:1px solid #fff;}.calendar tbody td.active{padding:2px 2px 0 2px;border-top:1px solid #000;border-right:1px solid #fff;border-bottom:1px solid #fff;border-left:1px solid #000;}.calendar tbody td.selected{font-weight:bold;border-top:1px solid #000;border-right:1px solid #fff;border-bottom:1px solid #fff;border-left:1px solid #000;padding:2px 2px 0 2px;background:#e4e0d8;}.calendar tbody td.weekend{color:#f00;}.calendar tbody td.today{font-weight:bold;color:#00f;}.calendar tbody .disabled{color:#999;}.calendar tbody .emptycell{visibility:hidden;}.calendar tbody .emptyrow{display:none;}.calendar tfoot .ttip{background:#f4f0e8;padding:1px;border:1px solid #000;background:#848078;color:#fff;text-align:center;}.calendar tfoot .hilite{border-top:1px solid #fff;border-right:1px solid #000;border-bottom:1px solid #000;border-left:1px solid #fff;padding:1px;background:#e4e0d8;}.calendar tfoot .active{padding:2px 0 0 2px;border-top:1px solid #000;border-right:1px solid #fff;border-bottom:1px solid #fff;border-left:1px solid #000;}.calendar .combo{position:absolute;display:none;width:4em;top:0;left:0;cursor:default;border-top:1px solid #fff;border-right:1px solid #000;border-bottom:1px solid #000;border-left:1px solid #fff;background:#e4e0d8;font-size:90%;padding:1px;z-index:100;}.calendar .combo .label,.calendar .combo .label-IEfix{text-align:center;padding:1px;}.calendar .combo .label-IEfix{width:4em;}.calendar .combo .active{background:#c4c0b8;padding:0;border-top:1px solid #000;border-right:1px solid #fff;border-bottom:1px solid #fff;border-left:1px solid #000;}.calendar .combo .hilite{background:#048;color:#fea;}.calendar td.time{border-top:1px solid #000;padding:1px 0;text-align:center;background-color:#f4f0e8;}.calendar td.time .hour,.calendar td.time .minute,.calendar td.time .ampm{padding:0 3px 0 4px;border:1px solid #889;font-weight:bold;background-color:#fff;}.calendar td.time .ampm{text-align:center;}.calendar td.time .colon{padding:0 2px 0 3px;font-weight:bold;}.calendar td.time span.hilite{border-color:#000;background-color:#766;color:#fff;}.calendar td.time span.active{border-color:#f00;background-color:#000;color:#0f0;}#CP_hourcont{padding:0;position:absolute;border:1px dashed #666;background-color:#eee;display:none;}#CP_minutecont{background-color:#ddd;padding:1px;position:absolute;width:45px;display:none;}.floatleft{float:left;}.CP_hour{padding:1px;font-family:Arial,Helvetica,sans-serif;font-size:9px;white-space:nowrap;cursor:pointer;width:35px;}.CP_minute{padding:1px;font-family:Arial,Helvetica,sans-serif;font-size:9px;white-space:nowrap;cursor:pointer;width:auto;}.CP_over{background-color:#fff;} static/calendar.js 0000755 0000765 0000024 00000135404 11223012025 014327 0 ustar mdipierro staff /* Copyright Notice for Dynarch Date Time Picker */
/* Copyright Mihai Bazon, 2002-2005 | www.bazon.net/mishoo
* -----------------------------------------------------------
*
* The DHTML Calendar, version 1.0 "It is happening again"
*
* Details and latest version at:
* www.dynarch.com/projects/calendar
*
* This script is developed by Dynarch.com. Visit us at www.dynarch.com.
*
* This script is distributed under the GNU Lesser General Public License.
* Read the entire license text here: http://www.gnu.org/licenses/lgpl.html
*/
// Calendar EN language
// Author: Mihai Bazon,
// Encoding: any
// Distributed under the same terms as the calendar itself.
/* End Copyright Notice for Dynarch Date Time Picker */
/*
ClockPick, by Josh Nathanson
Version 1.2.4
Timepicker plugin for jQuery
See copyright at end of file
Complete documentation at http://www.oakcitygraphics.com/jquery/clockpick/trunk/ClockPick.cfm
name clockpick
type jQuery
param options hash object containing config options
param options[starthour] int starting hour (use military int)
param options[endhour] int ending hour (use military int)
param options[showminutes] bool show minutes
param options[minutedivisions] int number of divisions, i.e. 4 = :00, :15, :30, :45
param options[military] bool use 24hr time if true
param options[event] string mouse event to trigger plugin
param options[layout] string set div layout to vertical or horizontal
('vertical','horizontal')
param options[valuefield] string field to insert time value, if not same as click field
(name of input field)
param options[useBgiframe] bool set true if using bgIframe plugin
param options[hoursopacity] float set opacity of hours container
param options[minutesopacity] float set opacity of minutes container
param callback function callback function - gets passed back the time value as a
string
*/
/* Copyright Notice for jQuery Clockpick */
/*
+-----------------------------------------------------------------------+
| Copyright (c) 2007 Josh Nathanson |
| All rights reserved. |
| |
| Redistribution and use in source and binary forms, with or without |
| modification, are permitted provided that the following conditions |
| are met: |
| |
| o Redistributions of source code must retain the above copyright |
| notice, this list of conditions and the following disclaimer. |
| o Redistributions in binary form must reproduce the above copyright |
| notice, this list of conditions and the following disclaimer in the |
| documentation and/or other materials provided with the distribution.|
| |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
+-----------------------------------------------------------------------+
*/
/* End Copyright Notice for jQuery Clockpick below */
Calendar=function(J,K,H,G){this.activeDiv=null;this.currentDateEl=null;this.getDateStatus=null;this.getDateToolTip=null;this.getDateText=null;this.timeout=null;this.onSelected=H||null;this.onClose=G||null;this.dragging=false;this.hidden=false;this.minYear=1970;this.maxYear=2050;this.dateFormat=Calendar._TT.DEF_DATE_FORMAT;this.ttDateFormat=Calendar._TT.TT_DATE_FORMAT;this.isPopup=true;this.weekNumbers=true;this.firstDayOfWeek=typeof J=="number"?J:Calendar._FD;this.showsOtherMonths=false;this.dateStr=K;this.ar_days=null;this.showsTime=false;this.time24=true;this.yearStep=2;this.hiliteToday=true;this.multiple=null;this.table=null;this.element=null;this.tbody=null;this.firstdayname=null;this.monthsCombo=null;this.yearsCombo=null;this.hilitedMonth=null;this.activeMonth=null;this.hilitedYear=null;this.activeYear=null;this.dateClicked=false;if(typeof Calendar._SDN=="undefined"){if(typeof Calendar._SDN_len=="undefined"){Calendar._SDN_len=3}var L=new Array();for(var I=8;I>0;){L[--I]=Calendar._DN[I].substr(0,Calendar._SDN_len)}Calendar._SDN=L;if(typeof Calendar._SMN_len=="undefined"){Calendar._SMN_len=3}L=new Array();for(var I=12;I>0;){L[--I]=Calendar._MN[I].substr(0,Calendar._SMN_len)}Calendar._SMN=L}};Calendar._C=null;Calendar.is_ie=(/msie/i.test(navigator.userAgent)&&!/opera/i.test(navigator.userAgent));Calendar.is_ie5=(Calendar.is_ie&&/msie 5\.0/i.test(navigator.userAgent));Calendar.is_opera=/opera/i.test(navigator.userAgent);Calendar.is_khtml=/Konqueror|Safari|KHTML/i.test(navigator.userAgent);Calendar.getAbsolutePos=function(I){var G=0,J=0;var K=/^div$/i.test(I.tagName);if(K&&I.scrollLeft){G=I.scrollLeft}if(K&&I.scrollTop){J=I.scrollTop}var H={x:I.offsetLeft-G,y:I.offsetTop-J};if(I.offsetParent){var L=this.getAbsolutePos(I.offsetParent);H.x+=L.x;H.y+=L.y}return H};Calendar.isRelated=function(G,E){var F=E.relatedTarget;if(!F){var H=E.type;if(H=="mouseover"){F=E.fromElement}else{if(H=="mouseout"){F=E.toElement}}}while(F){if(F==G){return true}F=F.parentNode}return false};Calendar.removeClass=function(G,H){if(!(G&&G.className)){return }var F=G.className.split(" ");var J=new Array();for(var I=F.length;I>0;){if(F[--I]!=H){J[J.length]=F[I]}}G.className=J.join(" ")};Calendar.addClass=function(D,C){Calendar.removeClass(D,C);D.className+=" "+C};Calendar.getElement=function(C){var D=Calendar.is_ie?window.event.srcElement:C.currentTarget;while(D.nodeType!=1||/^div$/i.test(D.tagName)){D=D.parentNode}return D};Calendar.getTargetElement=function(C){var D=Calendar.is_ie?window.event.srcElement:C.target;while(D.nodeType!=1){D=D.parentNode}return D};Calendar.stopEvent=function(B){B||(B=window.event);if(Calendar.is_ie){B.cancelBubble=true;B.returnValue=false}else{B.preventDefault();B.stopPropagation()}return false};Calendar.addEvent=function(D,E,F){if(D.attachEvent){D.attachEvent("on"+E,F)}else{if(D.addEventListener){D.addEventListener(E,F,true)}else{D["on"+E]=F}}};Calendar.removeEvent=function(D,E,F){if(D.detachEvent){D.detachEvent("on"+E,F)}else{if(D.removeEventListener){D.removeEventListener(E,F,true)}else{D["on"+E]=null}}};Calendar.createElement=function(E,F){var D=null;if(document.createElementNS){D=document.createElementNS("http://www.w3.org/1999/xhtml",E)}else{D=document.createElement(E)}if(typeof F!="undefined"){F.appendChild(D)}return D};Calendar._add_evs=function(el){with(Calendar){addEvent(el,"mouseover",dayMouseOver);addEvent(el,"mousedown",dayMouseDown);addEvent(el,"mouseout",dayMouseOut);if(is_ie){addEvent(el,"dblclick",dayMouseDblClick);el.setAttribute("unselectable",true)}}};Calendar.findMonth=function(B){if(typeof B.month!="undefined"){return B}else{if(typeof B.parentNode.month!="undefined"){return B.parentNode}}return null};Calendar.findYear=function(B){if(typeof B.year!="undefined"){return B}else{if(typeof B.parentNode.year!="undefined"){return B.parentNode}}return null};Calendar.showMonthsCombo=function(){var I=Calendar._C;if(!I){return false}var I=I;var H=I.activeDiv;var J=I.monthsCombo;if(I.hilitedMonth){Calendar.removeClass(I.hilitedMonth,"hilite")}if(I.activeMonth){Calendar.removeClass(I.activeMonth,"active")}var K=I.monthsCombo.getElementsByTagName("div")[I.date.getMonth()];Calendar.addClass(K,"active");I.activeMonth=K;var L=J.style;L.display="block";if(H.navtype<0){L.left=H.offsetLeft+"px"}else{var G=J.offsetWidth;if(typeof G=="undefined"){G=50}L.left=(H.offsetLeft+H.offsetWidth-G)+"px"}L.top=(H.offsetTop+H.offsetHeight)+"px"};Calendar.showYearsCombo=function(K){var N=Calendar._C;if(!N){return false}var N=N;var L=N.activeDiv;var S=N.yearsCombo;if(N.hilitedYear){Calendar.removeClass(N.hilitedYear,"hilite")}if(N.activeYear){Calendar.removeClass(N.activeYear,"active")}N.activeYear=null;var M=N.date.getFullYear()+(K?1:-1);var P=S.firstChild;var Q=false;for(var T=12;T>0;--T){if(M>=N.minYear&&M<=N.maxYear){P.innerHTML=M;P.year=M;P.style.display="block";Q=true}else{P.style.display="none"}P=P.nextSibling;M+=K?N.yearStep:-N.yearStep}if(Q){var O=S.style;O.display="block";if(L.navtype<0){O.left=L.offsetLeft+"px"}else{var R=S.offsetWidth;if(typeof R=="undefined"){R=50}O.left=(L.offsetLeft+L.offsetWidth-R)+"px"}O.top=(L.offsetTop+L.offsetHeight)+"px"}};Calendar.tableMouseUp=function(ev){var cal=Calendar._C;if(!cal){return false}if(cal.timeout){clearTimeout(cal.timeout)}var el=cal.activeDiv;if(!el){return false}var target=Calendar.getTargetElement(ev);ev||(ev=window.event);Calendar.removeClass(el,"active");if(target==el||target.parentNode==el){Calendar.cellClick(el,ev)}var mon=Calendar.findMonth(target);var date=null;if(mon){date=new Date(cal.date);if(mon.month!=date.getMonth()){date.setMonth(mon.month);cal.setDate(date);cal.dateClicked=false;cal.callHandler()}}else{var year=Calendar.findYear(target);if(year){date=new Date(cal.date);if(year.year!=date.getFullYear()){date.setFullYear(year.year);cal.setDate(date);cal.dateClicked=false;cal.callHandler()}}}with(Calendar){removeEvent(document,"mouseup",tableMouseUp);removeEvent(document,"mouseover",tableMouseOver);removeEvent(document,"mousemove",tableMouseOver);cal._hideCombos();_C=null;return stopEvent(ev)}};Calendar.tableMouseOver=function(X){var T=Calendar._C;if(!T){return }var R=T.activeDiv;var b=Calendar.getTargetElement(X);if(b==R||b.parentNode==R){Calendar.addClass(R,"hilite active");Calendar.addClass(R.parentNode,"rowhilite")}else{if(typeof R.navtype=="undefined"||(R.navtype!=50&&(R.navtype==0||Math.abs(R.navtype)>2))){Calendar.removeClass(R,"active")}Calendar.removeClass(R,"hilite");Calendar.removeClass(R.parentNode,"rowhilite")}X||(X=window.event);if(R.navtype==50&&b!=R){var Y=Calendar.getAbsolutePos(R);var V=R.offsetWidth;var W=X.clientX;var U;var Z=true;if(W>Y.x+V){U=W-Y.x-V;Z=false}else{U=Y.x-W}if(U<0){U=0}var e=R._range;var c=R._current;var d=Math.floor(U/10)%e.length;for(var f=e.length;--f>=0;){if(e[f]==c){break}}while(d-->0){if(Z){if(--f<0){f=e.length-1}}else{if(++f>=e.length){f=0}}}var S=e[f];R.innerHTML=S;T.onUpdateTime()}var Q=Calendar.findMonth(b);if(Q){if(Q.month!=T.date.getMonth()){if(T.hilitedMonth){Calendar.removeClass(T.hilitedMonth,"hilite")}Calendar.addClass(Q,"hilite");T.hilitedMonth=Q}else{if(T.hilitedMonth){Calendar.removeClass(T.hilitedMonth,"hilite")}}}else{if(T.hilitedMonth){Calendar.removeClass(T.hilitedMonth,"hilite")}var a=Calendar.findYear(b);if(a){if(a.year!=T.date.getFullYear()){if(T.hilitedYear){Calendar.removeClass(T.hilitedYear,"hilite")}Calendar.addClass(a,"hilite");T.hilitedYear=a}else{if(T.hilitedYear){Calendar.removeClass(T.hilitedYear,"hilite")}}}else{if(T.hilitedYear){Calendar.removeClass(T.hilitedYear,"hilite")}}}return Calendar.stopEvent(X)};Calendar.tableMouseDown=function(B){if(Calendar.getTargetElement(B)==Calendar.getElement(B)){return Calendar.stopEvent(B)}};Calendar.calDragIt=function(J){var I=Calendar._C;if(!(I&&I.dragging)){return false}var G;var H;if(Calendar.is_ie){H=window.event.clientY+document.body.scrollTop;G=window.event.clientX+document.body.scrollLeft}else{G=J.pageX;H=J.pageY}I.hideShowCovered();var F=I.element.style;F.left=(G-I.xOffs)+"px";F.top=(H-I.yOffs)+"px";return Calendar.stopEvent(J)};Calendar.calDragEnd=function(ev){var cal=Calendar._C;if(!cal){return false}cal.dragging=false;with(Calendar){removeEvent(document,"mousemove",calDragIt);removeEvent(document,"mouseup",calDragEnd);tableMouseUp(ev)}cal.hideShowCovered()};Calendar.dayMouseDown=function(ev){var el=Calendar.getElement(ev);if(el.disabled){return false}var cal=el.calendar;cal.activeDiv=el;Calendar._C=cal;if(el.navtype!=300){with(Calendar){if(el.navtype==50){el._current=el.innerHTML;addEvent(document,"mousemove",tableMouseOver)}else{addEvent(document,Calendar.is_ie5?"mousemove":"mouseover",tableMouseOver)}addClass(el,"hilite active");addEvent(document,"mouseup",tableMouseUp)}}else{if(cal.isPopup){cal._dragStart(ev)}}if(el.navtype==-1||el.navtype==1){if(cal.timeout){clearTimeout(cal.timeout)}cal.timeout=setTimeout("Calendar.showMonthsCombo()",250)}else{if(el.navtype==-2||el.navtype==2){if(cal.timeout){clearTimeout(cal.timeout)}cal.timeout=setTimeout((el.navtype>0)?"Calendar.showYearsCombo(true)":"Calendar.showYearsCombo(false)",250)}else{cal.timeout=null}}return Calendar.stopEvent(ev)};Calendar.dayMouseDblClick=function(B){Calendar.cellClick(Calendar.getElement(B),B||window.event);if(Calendar.is_ie){document.selection.empty()}};Calendar.dayMouseOver=function(D){var C=Calendar.getElement(D);if(Calendar.isRelated(C,D)||Calendar._C||C.disabled){return false}if(C.ttip){if(C.ttip.substr(0,1)=="_"){C.ttip=C.caldate.print(C.calendar.ttDateFormat)+C.ttip.substr(1)}C.calendar.tooltips.innerHTML=C.ttip}if(C.navtype!=300){Calendar.addClass(C,"hilite");if(C.caldate){Calendar.addClass(C.parentNode,"rowhilite")}}return Calendar.stopEvent(D)};Calendar.dayMouseOut=function(ev){with(Calendar){var el=getElement(ev);if(isRelated(el,ev)||_C||el.disabled){return false}removeClass(el,"hilite");if(el.caldate){removeClass(el.parentNode,"rowhilite")}if(el.calendar){el.calendar.tooltips.innerHTML=_TT.SEL_DATE}return stopEvent(ev)}};Calendar.cellClick=function(d,U){var Q=d.calendar;var a=false;var X=false;var c=null;if(typeof d.navtype=="undefined"){if(Q.currentDateEl){Calendar.removeClass(Q.currentDateEl,"selected");Calendar.addClass(d,"selected");a=(Q.currentDateEl==d);if(!a){Q.currentDateEl=d}}Q.date.setDateOnly(d.caldate);c=Q.date;var R=!(Q.dateClicked=!d.otherMonth);if(!R&&!Q.currentDateEl){Q._toggleMultipleDate(new Date(c))}else{X=!d.disabled}if(R){Q._init(Q.firstDayOfWeek,c)}}else{if(d.navtype==200){Calendar.removeClass(d,"hilite");Q.callCloseHandler();return }c=new Date(Q.date);if(d.navtype==0){c.setDateOnly(new Date())}Q.dateClicked=false;var V=c.getFullYear();var b=c.getMonth();function S(B){var A=c.getDate();var C=c.getMonthDays(B);if(A>C){c.setDate(C)}c.setMonth(B)}switch(d.navtype){case 400:Calendar.removeClass(d,"hilite");var T=Calendar._TT.ABOUT;if(typeof T!="undefined"){T+=Q.showsTime?Calendar._TT.ABOUT_TIME:""}else{T='Help and about box text is not translated into this language.\nIf you know this language and you feel generous please update\nthe corresponding file in "lang" subdir to match calendar-en.js\nand send it back to to get it into the distribution ;-)\n\nThank you!\nhttp://dynarch.com/mishoo/calendar.epl\n'}alert(T);return ;case -2:if(V>Q.minYear){c.setFullYear(V-1)}break;case -1:if(b>0){S(b-1)}else{if(V-->Q.minYear){c.setFullYear(V);S(11)}}break;case 1:if(b<11){S(b+1)}else{if(V=0;){if(Y[Z]==W){break}}if(U&&U.shiftKey){if(--Z<0){Z=Y.length-1}}else{if(++Z>=Y.length){Z=0}}var P=Y[Z];d.innerHTML=P;Q.onUpdateTime();return ;case 0:if((typeof Q.getDateStatus=="function")&&Q.getDateStatus(c,c.getFullYear(),c.getMonth(),c.getDate())){return false}break}if(!c.equalsTo(Q.date)){Q.setDate(c);X=true}else{if(d.navtype==0){X=a=true}}}if(X){U&&Q.callHandler()}if(a){Calendar.removeClass(d,"hilite");U&&Q.callCloseHandler()}};Calendar.prototype.create=function(Y){var Z=null;if(!Y){Z=document.getElementsByTagName("body")[0];this.isPopup=true}else{Z=Y;this.isPopup=false}this.date=this.dateStr?new Date(this.dateStr):new Date();var V=Calendar.createElement("table");this.table=V;V.cellSpacing=0;V.cellPadding=0;V.calendar=this;Calendar.addEvent(V,"mousedown",Calendar.tableMouseDown);var T=Calendar.createElement("div");this.element=T;T.className="calendar";if(this.isPopup){T.style.position="absolute";T.style.display="none"}T.appendChild(V);var b=Calendar.createElement("thead",V);var X=null;var U=null;var S=this;var f=function(A,B,C){X=Calendar.createElement("td",U);X.colSpan=B;X.className="button";if(C!=0&&Math.abs(C)<=2){X.className+=" nav"}Calendar._add_evs(X);X.calendar=S;X.navtype=C;X.innerHTML="
{{if table:}}
[ {{=A(str(T('insert new %s'))%table,_href=URL(r=request,f='insert',args=[request.args[0],table]))}} ]
{{=T("Rows in table")}}
{{else:}}
{{=T("Rows selected")}}
{{pass}}
{{=form}}
{{=T('The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.')}}
{{=T('Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.')}}
{{=T('"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN')}}
{{=form}}
{{if request.args[0]=='login':}}
register lost password
{{pass}}
views/generic.html 0000644 0000765 0000024 00000001411 11223012025 014353 0 ustar mdipierro staff {{extend 'layout.html'}}
{{"""
You should not modify this file.
It is used as default when a view is not provided for your controllers
"""}}
{{=BEAUTIFY(response._vars)}}
request
{{=BEAUTIFY(request)}}
session
{{=BEAUTIFY(session)}}
response
{{=BEAUTIFY(response)}}
views/generic.json 0000644 0000765 0000024 00000000416 11223012025 014364 0 ustar mdipierro staff {{
###
# response._vars contains the dictionary returned by the controller action
###
try:
from gluon.serializers import json
response.write(json(response._vars),escape=False)
response.headers['Content-Type']='text/json'
except:
raise HTTP(405,'no json')
}}
views/generic.rss 0000644 0000765 0000024 00000000754 11223012025 014227 0 ustar mdipierro staff {{
###
# response._vars contains the dictionary returned by the controller action
# for this to work the action must return something like
#
# dict(title=...,link=...,description=...,created_on='...',items=...)
#
# items is a list of dictionaries each with title, link, description, pub_date.
###
try:
from gluon.serializers import rss
response.write(rss(response._vars),escape=False)
response.headers['Content-Type']='application/rss+xml'
except:
raise HTTP(405,'no rss')
}} views/generic.xml 0000644 0000765 0000024 00000000411 11223012025 014206 0 ustar mdipierro staff {{
###
# response._vars contains the dictionary returned by thecontroller action
###
try:
from gluon.serializers import xml
response.write(xml(response._vars),escape=False)
response.headers['Content-Type']='text/xml'
except:
raise HTTP(405,'no xml')
}}
views/layout.html 0000644 0000765 0000024 00000004035 11223012025 014261 0 ustar mdipierro staff
{{=response.title or 'response.title'}}
{{include 'web2py_ajax.html'}}