def members(): org = db.organization(request.args(0)) if not request.args(1): fld_email = Field('email', 'string', label=T("Email")) fld_email.requires = IS_EMAIL() form = SQLFORM.factory( fld_email, formstyle='bootstrap3_inline', submit_button=T("Add user"), table_name='members') if form.process().accepted: u = db.auth_user(email=form.vars.email) if u is not None: # create new share if u.id in org.users: form.errors.email = T( "The user is already in the organization") else: user_list = org.users user_list.insert(0, u.id) org.update_record(users=user_list) g_id = auth.user_group(u.id) auth.add_permission(g_id, 'read', db.organization, org.id) else: # no user with that email response.flash = "" form.errors.email = T("The user don't exists on this system") elif request.args(1) == 'delete': # remove the user on args(2) from the org members list # TODO: remove else any perms on the org desks user_to_remove = db.auth_user(request.args(2)) if user_to_remove is not None: user_list = org.users user_list.remove(user_to_remove.id) org.update_record(users=user_list) # remove perms over the org auth.del_permission( auth.user_group(user_to_remove.id), 'read', db.organization, org.id) # remove, also, all rights over the desks in the org. desk_perms = [ 'read_desk', 'update_items', 'push_items', 'update_desk'] for desk_id in org.desks: for perm in desk_perms: auth.del_permission( auth.user_group(user_to_remove.id), perm, db.desk, desk_id ) redirect(URL('org', 'members', args=[org.id])) return locals()
def share(): """ Show the user's who has access to this item """ item = application.getItemByUUID(request.args(0)) if item is None: raise HTTP(404) fld_email = Field('email', 'string', default='') fld_perms = Field('perms', 'string', default='owner') fld_email.requires = IS_EMAIL() form = SQLFORM.factory( fld_email, fld_perms, formstyle='bootstrap3_inline', submit_button=T("Share this item"), table_name='share') if form.process().accepted: # search a user by his email addr u = db.auth_user(email=form.vars.email) if u is not None: # create new share ct = application.getContentType(item.item_type) ct.shareItem(item.unique_id, u, perms=form.vars.perms) # notify users subject = T("Share of %s", (item.headline,)) message = response.render( 'share_email.txt', dict( item=item, user=auth.user, t_user=db.auth_user(email=form.vars.email) ) ) application.notifyCollaborators( item.unique_id, subject, message ) # -- # close the dialog response.js = "$('#metaModal').modal('hide');" else: # no user with that email response.flash = T("The user don't exists on this system") form.errors.email = T("The user don't exists on this system") return locals()
#!/usr/bin/env python # -*- coding: utf-8 -*- import sys, os, telnetlib, time, datetime import PIL, Image, ImageDraw, ImageFont sys.path.append('/home/www-data/web2py') from gluon import DAL, Field db=DAL('sqlite://storage.sqlite', folder='/home/www-data/web2py/applications/tgmonitor/databases') db.define_table('tg_load', Field('check_date','datetime'), Field('tg_number',length=17), Field('busy', 'integer'), Field('installed', 'integer') ) t3 = datetime.datetime.now() - datetime.timedelta(3) db(db.tg_load.check_date < t3).delete() db.commit() if os.path.isfile('/home/www-data/web2py/applications/tgmonitor/static/group1.png')==True: os.remove('/home/www-data/web2py/applications/tgmonitor/static/group1.png') if os.path.isfile('/home/www-data/web2py/applications/tgmonitor/static/group2.png')==True: os.remove('/home/www-data/web2py/applications/tgmonitor/static/group2.png') if os.path.isfile('/home/www-data/web2py/applications/tgmonitor/static/group3.png')==True: os.remove('/home/www-data/web2py/applications/tgmonitor/static/group3.png') if os.path.isfile('/home/www-data/web2py/applications/tgmonitor/static/group4.png')==True: os.remove('/home/www-data/web2py/applications/tgmonitor/static/group4.png')
def users(): desk = db.desk(request.args(0)) session.desk_id = desk.id org = db.organization(session.org_id) if request.args(1): my_user = db.auth_user(request.args(1)) fld_read_desk = Field('read_desk', 'boolean') fld_read_desk.label = T("Read '%s' content", (desk.name,)) fld_read_desk.comment = T( "Allow the user read only access to the desk item list.") fld_read_desk.default = auth.has_permission( 'read', db.desk, desk.id, my_user.id) fld_update_items = Field('update_items', 'boolean') fld_update_items.label = T("Read/Update items in '%s'", (desk.name,)) fld_update_items.comment = T( "Allow the user make modifications to the items in the desk.") fld_update_items.default = auth.has_permission( 'update_items', db.desk, desk.id, my_user.id) fld_push_items = Field('push_items', 'boolean') fld_push_items.label = T("Push items into '%s'", (desk.name,)) fld_push_items.comment = T( """Allow the user move items into the desk.""" ) fld_push_items.default = auth.has_permission( 'push_items', db.desk, desk.id, my_user.id) fld_update_desk = Field('update_desk', 'boolean') fld_update_desk.label = T("Update/Manage '%s'", (desk.name,)) fld_update_desk.comment = T( """ Allow the user to manage/administrate this desk. Use with caution. """ ) fld_update_desk.default = auth.has_permission( 'update', db.desk, desk.id, my_user.id) form = SQLFORM.factory( fld_read_desk, fld_update_items, fld_push_items, fld_update_desk, table_name='desk_perms' ) if form.process().accepted: if form.vars.read_desk: # give perm auth.add_permission( auth.user_group(my_user.id), 'read', db.desk, desk.id) else: auth.del_permission( auth.user_group(my_user.id), 'read', db.desk, desk.id) if form.vars.update_items: # give perm auth.add_permission( auth.user_group(my_user.id), 'update_items', db.desk, desk.id) else: auth.del_permission( auth.user_group(my_user.id), 'update_items', db.desk, desk.id) if form.vars.push_items: # give perm auth.add_permission( auth.user_group(my_user.id), 'push_items', db.desk, desk.id) else: auth.del_permission( auth.user_group(my_user.id), 'push_items', db.desk, desk.id) if form.vars.update_desk: # give perm auth.add_permission( auth.user_group(my_user.id), 'update_desk', db.desk, desk.id) else: auth.del_permission( auth.user_group(my_user.id), 'update_desk', db.desk, desk.id) redirect(URL('desk', 'users', args=[desk.id])) response.view = "desk/user_perms.html" else: # select user view query = (db.auth_user.id > 0) query &= (db.auth_user.id.belongs(org.users)) my_users = db(query).select() return locals()
def define_tables(self, db, migrate): from gluon import current logging.debug('defining tables (migrate=%s)' % migrate) now = datetime.datetime.now() db.define_table('scheduler_task', Field('application_name', requires=IS_NOT_EMPTY(), default=None, writable=False), Field('task_name', requires=IS_NOT_EMPTY()), Field('group_name', default='main', writable=False), Field('status', requires=IS_IN_SET(TASK_STATUS), default=QUEUED, writable=False), Field('function_name', requires=IS_IN_SET(sorted(self.tasks.keys()))), Field('args', 'text', default='[]', requires=TYPE(list)), Field('vars', 'text', default='{}', requires=TYPE(dict)), Field('enabled', 'boolean', default=True), Field('start_time', 'datetime', default=now), Field('next_run_time', 'datetime', default=now), Field('stop_time', 'datetime', default=None), Field('repeats', 'integer', default=1, comment="0=unlimted"), Field('period', 'integer', default=60, comment='seconds'), Field('timeout', 'integer', default=60, comment='seconds'), Field('times_run', 'integer', default=0, writable=False), Field('last_run_time', 'datetime', writable=False, readable=False), Field('assigned_worker_name', default='', writable=False), migrate=migrate, format='%(task_name)s') if hasattr(current, 'request'): db.scheduler_task.application_name.default = current.request.application db.define_table('scheduler_run', Field('scheduler_task', 'reference scheduler_task'), Field('status', requires=IS_IN_SET(RUN_STATUS)), Field('start_time', 'datetime'), Field('stop_time', 'datetime'), Field('output', 'text'), Field('result', 'text'), Field('traceback', 'text'), Field('worker_name', default=self.worker_name), migrate=migrate) db.define_table('scheduler_worker', Field('worker_name'), Field('first_heartbeat', 'datetime'), Field('last_heartbeat', 'datetime'), Field('status', requires=IS_IN_SET(WORKER_STATUS)), Field('is_ticker', 'boolean', default=False), migrate=migrate) db.commit()
def subscription_status(self, r, **attr): """ Default page for the subscriber (!) to view and manage their subscription - standard CRUD methods are for the merchant - can be replaced in template to include further fulfillment details / management options: customise_fin_subscription_resource() to override the "status" method with a custom REST method handler """ T = current.T settings = current.deployment_settings record = r.record if not record or not record.service_id: r.error(405, "Invalid record") output = {"title": T("Subscription Status")} # Subscription/fulfillment details to be shown to the subscriber # TODO show current status formfields = [ Field( "plan", label=T("Subscription Plan"), writable=False, ), Field( "subscriber", label=T("Subscriber"), writable=False, ), Field( "date", label=T("Created on"), writable=False, ), ] table = r.table data = { "id": "", "plan": table.plan_id.represent(record.plan_id), "subscriber": table.pe_id.represent(record.pe_id), "date": S3DateTime.datetime_represent(record.created_on), } # Subscriber actions status = record.status if status == "NEW": buttons = [ A( T("Approve"), _href=r.url( method="approve", vars={"subscription_id": record.refno}, ), _class="action-btn", ), ] elif status == "APPROVED": buttons = [ A( T("Activate"), _href=r.url( method="confirm", vars={"subscription_id": record.refno}, ), _class="action-btn", ), ] elif status == "ACTIVE": buttons = [ A( T("Cancel"), _href=r.url( method="cancel", vars={"subscription_id": record.refno}, ), _class="action-btn", ), ] else: buttons = [] resourcename = r.resource.name # Generate the form and add it to the output formstyle = settings.get_ui_formstyle() form = SQLFORM.factory( record=data, showid=False, formstyle=formstyle, table_name=resourcename, buttons=buttons, #hidden = hidden, #_id = widget_id, *formfields) output["item"] = form current.response.view = self._view(r, "display.html") return output
from gluon import DAL, Field #db = DAL('sqlite://storage.sqlite') db = DAL('postgres://*****:*****@db/postgres') db.define_table('ipligence2', Field('ip_from', 'integer', 10, '0000000000'), Field('ip_to', 'integer', 10, '0000000000'), Field('country_code', 'string', 10), Field('country_name', 'string', 255), Field('continent_code', 'string', 10), Field('continent_name', 'string', 255), Field('time_zone', 'string', 10), Field('region_code', 'string', 10), Field('region_name', 'string', 255), Field('the_owner', 'string', 255), Field('city_name', 'string', 255), Field('county_name', 'string', 255), Field('latitude', 'double'), Field('longitude', 'double')) db.ipligence2.import_from_csv_file( open( '/home/www-data/web2py/applications/TrackR/private/ipligence-max.mysqldump.sql' ), 'rb') db.commit()
def define_tables(self, db, migrate): from gluon.dal import DEFAULT logger.debug('defining tables (migrate=%s)', migrate) now = self.now db.define_table('scheduler_task', Field('application_name', requires=IS_NOT_EMPTY(), default=None, writable=False), Field('task_name', default=None), Field('group_name', default='main'), Field('status', requires=IS_IN_SET(TASK_STATUS), default=QUEUED, writable=False), Field('function_name', requires=IS_IN_SET(sorted(self.tasks.keys())) if self.tasks else DEFAULT), Field('uuid', requires=IS_NOT_IN_DB(db, 'scheduler_task.uuid'), unique=True, default=web2py_uuid), Field('args', 'text', default='[]', requires=TYPE(list)), Field('vars', 'text', default='{}', requires=TYPE(dict)), Field('enabled', 'boolean', default=True), Field('start_time', 'datetime', default=now, requires=IS_DATETIME()), Field('next_run_time', 'datetime', default=now), Field('stop_time', 'datetime'), Field('repeats', 'integer', default=1, comment="0=unlimited", requires=IS_INT_IN_RANGE(0, None)), Field('retry_failed', 'integer', default=0, comment="-1=unlimited", requires=IS_INT_IN_RANGE(-1, None)), Field('period', 'integer', default=60, comment='seconds', requires=IS_INT_IN_RANGE(0, None)), Field('timeout', 'integer', default=60, comment='seconds', requires=IS_INT_IN_RANGE(0, None)), Field('sync_output', 'integer', default=0, comment="update output every n sec: 0=never", requires=IS_INT_IN_RANGE(0, None)), Field('times_run', 'integer', default=0, writable=False), Field('times_failed', 'integer', default=0, writable=False), Field('last_run_time', 'datetime', writable=False, readable=False), Field('assigned_worker_name', default='', writable=False), on_define=self.set_requirements, migrate=migrate, format='%(task_name)s') db.define_table('scheduler_run', Field('task_id', 'reference scheduler_task'), Field('status', requires=IS_IN_SET(RUN_STATUS)), Field('start_time', 'datetime'), Field('stop_time', 'datetime'), Field('run_output', 'text'), Field('run_result', 'text'), Field('traceback', 'text'), Field('worker_name', default=self.worker_name), migrate=migrate) db.define_table( 'scheduler_worker', Field('worker_name', unique=True), Field('first_heartbeat', 'datetime'), Field('last_heartbeat', 'datetime'), Field('status', requires=IS_IN_SET(WORKER_STATUS)), Field('is_ticker', 'boolean', default=False, writable=False), Field( 'group_names', 'list:string', default=self.group_names ), #FIXME writable=False or give the chance to update dinamically the groups? migrate=migrate) if migrate: db.commit()
except NameError: print "s3db not defined" ''' globals().update(**old_env) exec old_str in globals(), locals() database_string = "sqlite://storage.db" old_database_folder = "%s/applications/%s/databases" % (WEB2PY_PATH, APP) temp_db = DAL(database_string, folder=old_database_folder, migrate_enabled=True, migrate=True) # Migration Script list_of_fields = [] list_of_fields.append(Field(new_field, "integer")) list_of_new_table_fields = [] list_of_new_table_fields.append(Field(new_table_field, "integer")) try: db[changed_table]._primarykey except KeyError: db[changed_table]._primarykey = None temp_db.define_table(changed_table, db[changed_table], *list_of_fields, primarykey=db[changed_table]._primarykey) temp_db.define_table(new_table, *list_of_new_table_fields)
def invite(self, r, **attr): """ Prepare and process invitation form @param r: the S3Request instance @param attr: controller attributes """ T = current.T db = current.db s3db = current.s3db response = current.response request = current.request session = current.session settings = current.deployment_settings auth = current.auth auth_settings = auth.settings auth_messages = auth.messages output = { "title": T("Invite Organisation"), } # Get all accounts that are linked to this org utable = auth_settings.table_user oltable = s3db.org_organisation_user pltable = s3db.pr_person_user organisation_id = r.record.id join = oltable.on((oltable.user_id == utable.id) & \ (oltable.deleted == False)) left = pltable.on((pltable.user_id == utable.id) & \ (pltable.deleted == False)) query = (oltable.organisation_id == organisation_id) rows = db(query).select( utable.id, utable.first_name, utable.last_name, utable.email, utable.registration_key, pltable.pe_id, join=join, left=left, ) active, disabled, invited = [], [], [] for row in rows: user = row[utable] person_link = row.pr_person_user if person_link.pe_id: if user.registration_key: disabled.append(user) else: active.append(user) else: invited.append(user) if active or disabled: response.error = T( "There are already user accounts registered for this organization" ) from gluon import UL, LI, H4, DIV from s3 import s3_format_fullname fullname = lambda user: s3_format_fullname( fname=user.first_name, lname=user.last_name, truncate=False, ) account_list = DIV(_class="org-account-list") if active: account_list.append(H4(T("Active Accounts"))) accounts = UL() for user in active: accounts.append( LI("%s <%s>" % (fullname(user), user.email))) account_list.append(accounts) if disabled: account_list.append(H4(T("Disabled Accounts"))) accounts = UL() for user in disabled: accounts.append( LI("%s <%s>" % (fullname(user), user.email))) account_list.append(accounts) output["item"] = account_list response.view = self._view(r, "display.html") return output account = invited[0] if invited else None # Look up existing invite-account email = None if account: email = account.email else: ctable = s3db.pr_contact query = (ctable.pe_id == r.record.pe_id) & \ (ctable.contact_method == "EMAIL") & \ (ctable.deleted == False) contact = db(query).select( ctable.value, orderby=ctable.priority, limitby=(0, 1), ).first() if contact: email = contact.value # Form Fields dbset = db(utable.id != account.id) if account else db formfields = [ Field("email", default=email, requires=[ IS_EMAIL(error_message=auth_messages.invalid_email), IS_LOWER(), IS_NOT_IN_DB( dbset, "%s.email" % utable._tablename, error_message=auth_messages.duplicate_email, ), ]), ] # Generate labels (and mark required fields in the process) labels, has_required = s3_mark_required(formfields, ) response.s3.has_required = has_required # Form buttons SEND_INVITATION = T("Send New Invitation") if account else T( "Send Invitation") buttons = [ INPUT( _type="submit", _value=SEND_INVITATION, ), # TODO cancel-button? ] # Construct the form response.form_label_separator = "" form = SQLFORM.factory( table_name="invite", record=None, hidden={"_next": request.vars._next}, labels=labels, separator="", showid=False, submit_button=SEND_INVITATION, #delete_label = auth_messages.delete_label, formstyle=settings.get_ui_formstyle(), buttons=buttons, *formfields) # Identify form for CSS & JS Validation form.add_class("send_invitation") if form.accepts( request.vars, session, formname="invite", #onvalidation = auth_settings.register_onvalidation, ): error = self.invite_account(r.record, form.vars.email, account=account) if error: response.error = T( "Could not send invitation (%(reason)s)") % { "reason": error } else: response.confirmation = T("Invitation sent") else: if account: response.warning = T( "This organisation has been invited before!") output["form"] = form response.view = self._view(r, "update.html") return output
# -*- coding: utf-8 -*- import datetime from collections import defaultdict # for ide if False: from gluon import Field, auth from gluon.validators import IS_IN_SET from db import db from fuente_datos import marcadas_tunel_latix from util import datetime_sp dias_semana = ['Lunes', 'Martes', 'Miercoles', 'Jueves', 'Viernes', 'Sabado'] db.define_table('marcadas', Field('id_reg'), Field('user_code'), Field('datetime'), Field('bkp_type'), Field('type_code'), Field('huella', unique=True, length=40)) db.define_table( 'empleado', Field('nombre', length=255), Field('apellido', length=255), Field('user_code', 'integer', unique=True, length=4), Field('dias'), Field('entrada', 'time'), Field('salida', 'time'), Field('descanso', 'time'), auth.signature, format='%(Nombre)s %(Apellido)', ) db.empleado.dias.requires = IS_IN_SET(dias_semana, multiple=True)
def __call__(self): request = current.request response = current.response if request.env.request_method == "POST": # Processs Form vars = request.post_vars result = current.msg.send_email( to=current.deployment_settings.get_mail_approver(), subject=vars.subject, message=vars.message, reply_to=vars.address, ) if result: response.confirmation = "Thankyou for your message - we'll be in touch shortly" from gluon import Field, SQLFORM from s3 import s3_mark_required, S3StringWidget T = current.T formstyle = current.deployment_settings.get_ui_formstyle() fields = [ Field( "name", label=T("Your name"), required=True, ), Field( "address", label=T("Your e-mail address"), required=True, #widget = S3StringWidget(placeholder="*****@*****.**"), ), Field( "subject", label=T("Subject"), required=True, ), Field( "message", "text", label=T("Message"), required=True, ), ] labels, required = s3_mark_required(fields) response.form_label_separator = "" form = SQLFORM.factory(formstyle=formstyle, labels=labels, submit_button=T("Send Message"), *fields) form["_id"] = "mailform" form = DIV( H4("Contact Us", _style="background-color:#f7f8f9;padding:0.1rem 0.3rem"), P("You can leave a message using the contact form below."), form, _class="form-container", ) appname = request.application s3 = response.s3 sappend = s3.scripts.append if s3.cdn: if s3.debug: sappend( "http://ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.js" ) else: sappend( "http://ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js" ) else: if s3.debug: sappend("/%s/static/scripts/jquery.validate.js" % appname) else: sappend("/%s/static/scripts/jquery.validate.min.js" % appname) if s3.debug: sappend("/%s/static/themes/AidIQ/js/contact.js" % appname) else: sappend("/%s/static/themes/AidIQ/js/contact.min.js" % appname) response.title = "Contact | AidIQ.com" self._view(THEME, "contact.html") return dict(form=form)
def __call__(self): """ The userstats controller """ # Require ORG_GROUP_ADMIN auth = current.auth if not auth.s3_has_role("ORG_GROUP_ADMIN"): auth.permission.fail() from s3 import S3CRUD, s3_get_extension, s3_request request = current.request args = request.args # Create an S3Request r = s3_request( "org", "organisation", c="default", f="index/%s" % args[0], args=args[1:], extension=s3_get_extension(request), ) # Filter to root organisations resource = r.resource resource.add_filter(FS("id").belongs(self.root_orgs)) # Configure field methods from gluon import Field table = resource.table table.total_accounts = Field.Method("total_accounts", self.total_accounts) table.active_accounts = Field.Method("active_accounts", self.active_accounts) table.disabled_accounts = Field.Method("disabled_accounts", self.disabled_accounts) table.active30 = Field.Method("active30", self.active30) # Labels for field methods T = current.T TOTAL = T("Total User Accounts") ACTIVE = T("Active") DISABLED = T("Inactive") ACTIVE30 = T("Logged-in Last 30 Days") # Configure list_fields list_fields = ( "id", "name", (TOTAL, "total_accounts"), (ACTIVE, "active_accounts"), (DISABLED, "disabled_accounts"), (ACTIVE30, "active30"), ) # Configure form from s3 import S3SQLCustomForm, S3SQLVirtualField crud_form = S3SQLCustomForm( "name", S3SQLVirtualField( "total_accounts", label=TOTAL, ), S3SQLVirtualField( "active_accounts", label=ACTIVE, ), S3SQLVirtualField( "disabled_accounts", label=DISABLED, ), S3SQLVirtualField( "active30", label=ACTIVE30, ), ) # Configure read-only resource.configure( insertable=False, editable=False, deletable=False, crud_form=crud_form, filter_widgets=None, list_fields=list_fields, ) output = r(rheader=self.rheader) if isinstance(output, dict): output["title"] = T("User Statistics") # URL to open the resource open_url = resource.crud._linkto(r, update=False)("[id]") # Add action button for open action_buttons = S3CRUD.action_buttons action_buttons( r, deletable=False, copyable=False, editable=False, read_url=open_url, ) return output
def get_db(self): """ Return the connected db """ if not os.path.exists(self.get_option('dbmetadata')): os.makedirs(self.get_option('dbmetadata')) db=DAL(self.get_option('database'),lazy_tables=True,folder=self.get_option("dbmetadata")) db.define_table('storages', Field('storagename','string'), Field('creation_ts','datetime', default=datetime.datetime.now()), Field('modified_ts','datetime', default=datetime.datetime.now(), update=datetime.datetime.now()), ) db.define_table('files', Field('storages_id',db.storages), Field('parent_id','reference files'), Field('filename','string'), Field('description','string'), Field('mime','string'), Field('ftype','string'), Field('mode','integer'), Field('inode','integer'), Field('dev','string'), Field('nlink','integer'), Field('uid','integer'), Field('gid','integer'), Field('size','double'), Field('ctime','datetime'), Field('mtime','datetime'), Field('atime','datetime'), ) return db
# -*- coding: utf8 -*- import datetime # from plugin_ajaxselect import AjaxSelect if 0: from gluon import db, Field, auth, IS_EMPTY_OR, IS_IN_DB, current, URL response = current.response response.files.insert(5, URL('static', 'plugin_ajaxselect/plugin_ajaxselect.js')) #response.files.append(URL('static', 'plugin_ajaxselect/plugin_ajaxselect.css')) response.files.append( URL('static', 'plugin_listandedit/plugin_listandedit.css')) db.define_table('genres', Field('genre', 'string'), format='%(genre)s') db.define_table('biblical_figures', Field('figure', 'string'), format='%(figure)s') db.define_table('draftdocs', Field('name'), Field('filename'), Field('editor', db.auth_user), Field('editor2', db.auth_user), Field('editor3', db.auth_user), Field('editor4', db.auth_user), Field('assistant_editor', db.auth_user), Field('assistant_editor2', db.auth_user), Field('assistant_editor3', db.auth_user),
def share(): """ Show the list of desk to with the item can be push """ item = application.getItemByUUID(request.args(0)) if item is None: raise HTTP(404) query = (db.desk.id != session.desk_id) query &= auth.accessible_query('push_items', db.desk) posible_desk = db(query).select() fld_to_desk = Field('to_desk', 'integer') fld_to_desk.label = T("Push to organization desk") fld_to_desk.comment = T("Select where to push the item") fld_to_desk.requires = IS_EMPTY_OR(IS_IN_SET( [(desk.id, desk.name) for desk in posible_desk] )) fld_personal_desk = Field('to_person_desk', 'integer') fld_personal_desk.label = T("Push to other person desk") fld_personal_desk.comment = T("Select a person from the list.") # list of person on orgs persons = [] # search up all the persons orgs = db(db.organization.users.contains(auth.user.id)).select() for org in orgs: x = [db.auth_user(id=y) for y in org.users if y != auth.user.id] persons.extend(x) persons = list(set(persons)) fld_personal_desk.requires = IS_EMPTY_OR(IS_IN_SET( [(per.id, "{} {}".format(per.first_name, per.last_name)) for per in persons] )) fld_cond = Field('cond', 'boolean', default=False) fld_cond.label = T('To other person?') form = SQLFORM.factory( fld_to_desk, fld_personal_desk, fld_cond, submit_button=T("Send"), table_name='share') if form.process().accepted: src = session.desk_id if form.vars.cond: # send the item to other user other_user = db.auth_user(form.vars.to_person_desk) target = application.getUserDesk(other_user).id else: # send the item to the selected desk target = form.vars.to_desk if target: ct = application.getContentType(item.item_type) ct.shareItem(item.unique_id, src, target) response.js = "$('#metaModal').modal('hide');" response.flash = None return locals()
def __init__(self, table, db=None): self.table = table self.db = db or table._db self.idx = self.db.define_table('haystack_%s' % table._tablename, Field('fieldname'), Field('keyword'), Field('record_id', 'integer'))
pass # directory already created for img in listdir(repo_img_dir): if splitext(img)[1] == '.jpg': copy(join(repo_img_dir, img), wa_img_dir) # Connect to database db_dir = abspath(join(dirname(__file__), pardir, 'databases')) try: makedirs(db_dir) except os.error: pass db = DAL('sqlite://../databases/storage.db', folder=db_dir) # Create images table. db.define_table('images', Field('represent', type='string', length=100, required=True), Field('file_name', type='string', length=100, required=True)) # Insert image file names and meanings. img_pattern = re.compile(r'(\D+?)\d*\.') for img in listdir(wa_img_dir): match = img_pattern.match(img) if match is not None: db.images.insert(represent=match.group(1).capitalize(), file_name=img) # Create scores table. db.define_table('scores', Field('mode', type='string', length=6, required=True), Field('difficulty', type='string', length=6, required=True), Field('name', type='string', length=100, required=True), Field('score', type='integer', required=True),
def __call__(self, field, value, **attributes): """ Widget renderer for the input field; to be set as widget=self for the field returned by the resolve()-method. @param field: the input field @param value: the value to populate the widget @param attributes: attributes for the widget @return: the widget for this form element as HTML helper """ T = current.T settings = current.deployment_settings # Check current value if isinstance(value, str): try: value = json.loads(value) if value else {} except JSONERRORS: value = {} elif not value: value = {} delegation_id = value.get("delegationID") if value else None # Form name and widget ID formname = self._formname() widget_id = attributes.get("_id") if not widget_id: widget_id = str(field).replace(".", "_") # Ajax parameters if delegation_id: ajax_args = [delegation_id, "notifications.json"] ajax_vars = {} else: ajax_args = ["notifications.json"] dtable = current.s3db.hrm_delegation person_id = dtable.person_id.default ajax_vars = { "viewing": "pr_person.%s" % person_id } if person_id else {} # Sender and recipient types sender = self.options.get("sender") if sender: ajax_vars["sender"] = sender notifications = DeploymentNotifications(delegation_id, sender=sender) recipients = list(notifications.recipients.keys()) # Selectable organisations organisations = self.options.get("organisations") # Inject script options = { "ajaxURL": URL( c="hrm", f="delegation", args=ajax_args, vars=ajax_vars, ), "formName": formname, "recipients": recipients, "organisations": organisations, } self.inject_js(widget_id, options) # The widget widget = DIV( INPUT( _type="hidden", _name=field.name, _value=json.dumps(value), _class="notification-data", ), _id=widget_id, ) # Add field set per recipient type labels = { "organisation": T("Requesting Organisation"), "volunteer": T("Volunteer"), "office": T("Office##gov"), } formstyle = settings.get_ui_formstyle() for recipient in recipients: input_name = "%s_%s" % (formname, recipient) formfields = [ Field( "%s_email" % input_name, label=T("Email"), ), Field( "%s_subject" % input_name, label=T("Subject"), widget=self.subject_widget, ), Field( "%s_message" % input_name, "text", label=T("Message"), widget=self.message_widget, ), ] form = SQLFORM.factory(record=None, showid=False, formstyle=formstyle, buttons=[], table_name="sub", *formfields) toggle_name = "%s_notify_%s" % (formname, recipient) toggle_edit = DIV( A( T("Preview"), _class="preview-toggle action-lnk", _style="display:none", ), A( T("Edit"), _class="preview-toggle action-lnk", ), _class="preview-toggles", ) subform = DIV( FIELDSET( LEGEND( LABEL( INPUT( _type="checkbox", _class="notify-toggle", value=True, _name=toggle_name, _id=toggle_name, ), labels.get(recipient, "?"), ), ), form[0], toggle_edit, ), _class="notification", ) widget.append(subform) return widget
f['slugline'] = slugify(f['headline']) return None def _update_slugline(s, f): if 'headline' in f.keys(): f['slugline'] = slugify(f['headline']) return None db.define_table( 'item', # content metadata Field('headline', 'string', length=512, default=''), Field('slugline', 'string', length=512, default=''), Field('keywords', 'list:string', default=''), Field('located', 'string', length=200, default=''), Field('genre', 'string', length=100, default=''), Field('section_page', 'string', length=100, default=''), # language of the item it self not the lenguage of the content Field( 'language_tag', 'string', default=T.accepted_language.split('-')[0], length=2), # item metadata Field('provider', 'string', length=100, default=''), Field('provider_service', 'string', default=''), Field('pubstatus', 'string', length=10, default='usable'),
def register(self, r, **attr): """ Register a test result @param r: the S3Request instance @param attr: controller attributes """ if r.http not in ("GET", "POST"): r.error(405, current.ERROR.BAD_METHOD) if not r.interactive: r.error(415, current.ERROR.BAD_FORMAT) T = current.T db = current.db s3db = current.s3db auth = current.auth request = current.request response = current.response s3 = response.s3 settings = current.deployment_settings # Page title and intro text title = T("Register Test Result") # Get intro text from CMS ctable = s3db.cms_post ltable = s3db.cms_post_module join = ltable.on((ltable.post_id == ctable.id) & \ (ltable.module == "disease") & \ (ltable.resource == "case_diagnostics") & \ (ltable.deleted == False)) query = (ctable.name == "TestResultRegistrationIntro") & \ (ctable.deleted == False) row = db(query).select( ctable.body, join=join, cache=s3db.cache, limitby=(0, 1), ).first() intro = row.body if row else None # Instantiate Consent Tracker consent = s3db.auth_Consent( processing_types=["CWA_ANONYMOUS", "CWA_PERSONAL"]) table = s3db.disease_case_diagnostics # Configure disease_id field = table.disease_id if field.writable: default_disease = None offset = 1 else: default_disease = field.default field.readable = False offset = 0 # Probe date is mandatory field = table.probe_date requires = field.requires if isinstance(requires, IS_EMPTY_OR): field.requires = requires.other # Configure device_id field = table.device_id field.readable = field.writable = True dtable = s3db.disease_testing_device query = (dtable.device_class == "RAT") & \ (dtable.approved == True) & \ (dtable.available == True) if default_disease: query = (dtable.disease_id == default_disease) & query field.requires = IS_ONE_OF( db(query), "disease_testing_device.id", field.represent, ) cwa_options = ( ("NO", T("Do not report")), ("ANONYMOUS", T("Issue anonymous contact tracing code")), ("PERSONAL", T("Issue personal test certificate")), ) formfields = [ # -- Test Result -- table.site_id, table.disease_id, table.probe_date, table.device_id, table.result, # -- Report to CWA -- Field( "report_to_cwa", "string", requires=IS_IN_SET(cwa_options, sort=False, zero=""), default="NO", label=T("Report test result to %(system)s") % CWA, ), Field( "last_name", label=T("Last Name"), ), Field( "first_name", label=T("First Name"), ), s3_date( "date_of_birth", label=T("Date of Birth"), month_selector=True, ), Field( "dcc_option", "boolean", default=False, label=T("Provide Digital %(title)s Certificate") % {"title": "COVID-19 Test"}, ), Field( "consent", label="", widget=consent.widget, ), ] # Required fields required_fields = [] # Subheadings subheadings = ( (0, T("Test Result")), (4 + offset, CWA["system"]), ) # Generate labels (and mark required fields in the process) labels, has_required = s3_mark_required( formfields, mark_required=required_fields, ) s3.has_required = has_required # Form buttons REGISTER = T("Submit") buttons = [ INPUT( _type="submit", _value=REGISTER, ), ] # Construct the form response.form_label_separator = "" form = SQLFORM.factory(table_name="test_result", record=None, hidden={"_next": request.vars._next}, labels=labels, separator="", showid=False, submit_button=REGISTER, delete_label=auth.messages.delete_label, formstyle=settings.get_ui_formstyle(), buttons=buttons, *formfields) # Identify form for CSS & JS Validation form.add_class("result-register") # Add Subheadings if subheadings: for pos, heading in subheadings[::-1]: form[0].insert(pos, DIV(heading, _class="subheading")) # Inject scripts script = "/%s/static/themes/RLP/js/testresult.js" % r.application if script not in s3.scripts: s3.scripts.append(script) s3.jquery_ready.append("S3EnableNavigateAwayConfirm()") if form.accepts( request.vars, current.session, formname="register", onvalidation=self.validate, ): formvars = form.vars # Create disease_case_diagnostics record testresult = { "result": formvars.get("result"), } if "site_id" in formvars: testresult["site_id"] = formvars["site_id"] if "disease_id" in formvars: testresult["disease_id"] = formvars["disease_id"] if "probe_date" in formvars: testresult["probe_date"] = formvars["probe_date"] if "device_id" in formvars: testresult["device_id"] = formvars["device_id"] record_id = table.insert(**testresult) if not record_id: raise RuntimeError("Could not create testresult record") testresult["id"] = record_id # Set record owner auth = current.auth auth.s3_set_record_owner(table, record_id) auth.s3_make_session_owner(table, record_id) # Onaccept s3db.onaccept(table, testresult, method="create") response.confirmation = T("Test Result registered") report_to_cwa = formvars.get("report_to_cwa") if report_to_cwa == "NO": # Do not report to CWA, just forward to read view self.next = r.url(id=record_id, method="read") else: # Report to CWA and show test certificate dcc_option = False if report_to_cwa == "ANONYMOUS": processing_type = "CWA_ANONYMOUS" cwa_report = CWAReport(record_id) elif report_to_cwa == "PERSONAL": dcc_option = formvars.get("dcc_option") processing_type = "CWA_PERSONAL" cwa_report = CWAReport( record_id, anonymous=False, first_name=formvars.get("first_name"), last_name=formvars.get("last_name"), dob=formvars.get("date_of_birth"), dcc=dcc_option, ) else: processing_type = cwa_report = None if cwa_report: # Register consent if processing_type: cwa_report.register_consent( processing_type, formvars.get("consent"), ) # Send to CWA success = cwa_report.send() if success: response.information = T( "Result reported to %(system)s") % CWA retry = False else: response.error = T("Report to %(system)s failed") % CWA retry = True # Store DCC data if dcc_option: cwa_data = cwa_report.data from .dcc import DCC try: hcert = DCC.from_result( cwa_data.get("hash"), record_id, cwa_data.get("fn"), cwa_data.get("ln"), cwa_data.get("dob"), ) except ValueError as e: hcert = None response.warning = str(e) if hcert: hcert.save() else: # Remove DCC flag if hcert could not be generated cwa_report.dcc = False S3CustomController._view("RLPPTM", "certificate.html") # Title field = table.disease_id if cwa_report.disease_id and field.represent: disease = field.represent(cwa_report.disease_id) title = "%s %s" % (disease, T("Test Result")) else: title = T("Test Result") return { "title": title, "intro": None, # TODO "form": cwa_report.formatted(retry=retry), } else: response.information = T( "Result not reported to %(system)s") % CWA self.next = r.url(id=record_id, method="read") return None elif form.errors: current.response.error = T( "There are errors in the form, please check your input") # Custom View S3CustomController._view("RLPPTM", "testresult.html") return { "title": title, "intro": intro, "form": form, }
def users(): desk = db.desk(request.args(0)) session.desk_id = desk.id org = db.organization(session.org_id) if request.args(1): my_user = db.auth_user(request.args(1)) fld_read_desk = Field('read_desk', 'boolean') fld_read_desk.label = T("Read '%s' content", (desk.name, )) fld_read_desk.comment = T( "Allow the user read only access to the desk item list.") fld_read_desk.default = auth.has_permission('read', db.desk, desk.id, my_user.id) fld_update_items = Field('update_items', 'boolean') fld_update_items.label = T("Read/Update items in '%s'", (desk.name, )) fld_update_items.comment = T( "Allow the user make modifications to the items in the desk.") fld_update_items.default = auth.has_permission('update_items', db.desk, desk.id, my_user.id) fld_push_items = Field('push_items', 'boolean') fld_push_items.label = T("Push items into '%s'", (desk.name, )) fld_push_items.comment = T( """Allow the user move items into the desk.""") fld_push_items.default = auth.has_permission('push_items', db.desk, desk.id, my_user.id) fld_update_desk = Field('update_desk', 'boolean') fld_update_desk.label = T("Update/Manage '%s'", (desk.name, )) fld_update_desk.comment = T(""" Allow the user to manage/administrate this desk. Use with caution. """) fld_update_desk.default = auth.has_permission('update', db.desk, desk.id, my_user.id) form = SQLFORM.factory(fld_read_desk, fld_update_items, fld_push_items, fld_update_desk, table_name='desk_perms') if form.process().accepted: if form.vars.read_desk: # give perm auth.add_permission(auth.user_group(my_user.id), 'read', db.desk, desk.id) else: auth.del_permission(auth.user_group(my_user.id), 'read', db.desk, desk.id) if form.vars.update_items: # give perm auth.add_permission(auth.user_group(my_user.id), 'update_items', db.desk, desk.id) else: auth.del_permission(auth.user_group(my_user.id), 'update_items', db.desk, desk.id) if form.vars.push_items: # give perm auth.add_permission(auth.user_group(my_user.id), 'push_items', db.desk, desk.id) else: auth.del_permission(auth.user_group(my_user.id), 'push_items', db.desk, desk.id) if form.vars.update_desk: # give perm auth.add_permission(auth.user_group(my_user.id), 'update_desk', db.desk, desk.id) else: auth.del_permission(auth.user_group(my_user.id), 'update_desk', db.desk, desk.id) redirect(URL('desk', 'users', args=[desk.id])) response.view = "desk/user_perms.html" else: # select user view query = (db.auth_user.id > 0) query &= (db.auth_user.id.belongs(org.users)) my_users = db(query).select() return locals()
def cancel_subscription(self, r, **attr): """ Cancel a subscription and trigger automated cancelation actions - interactive user confirmation is required - URL query must include the reference number ("subscription_id") @param r: the S3Request instance @param attr: controller attributes """ T = current.T settings = current.deployment_settings record = r.record if not record or not record.service_id: r.error(405, "Invalid record") onerror = r.url(method="status") try: adapter = S3PaymentService.adapter(record.service_id) except (KeyError, ValueError): r.error(405, "Invalid payment service", next=onerror) if not adapter.verify_reference(r): r.error(405, "Invalid reference", next=onerror) output = {"title": T("Cancel subscription")} # Dialog to confirm cancellation CONFIRM = T("Please check this box to confirm") formfields = [ Field( "plan", label=T("Subscription Plan"), writable=False, ), Field( "subscriber", label=T("Subscriber"), writable=False, ), Field( "date", label=T("Created on"), writable=False, ), Field("cancel", "boolean", label=T("Yes, cancel this subscription"), default=False, requires=lambda cb, record_id=None: (cb, (CONFIRM if not cb else None))), ] table = r.table data = { "id": "", "plan": table.plan_id.represent(record.plan_id), "subscriber": table.pe_id.represent(record.pe_id), "date": S3DateTime.datetime_represent(record.created_on), "cancel": False, } buttons = [ INPUT( _class="tiny primary button submit-btn", _name="submit", _type="submit", _value=T("Cancel Subscription"), ), A( T("Return"), _href=r.url(method="status"), _class="cancel-action action-lnk", ), ] resourcename = r.resource.name # Generate the form and add it to the output formstyle = settings.get_ui_formstyle() form = SQLFORM.factory( record=data, showid=False, formstyle=formstyle, table_name=resourcename, buttons=buttons, #hidden = hidden, #_id = widget_id, *formfields) output["form"] = form # Process the form formname = "%s/cancel" % resourcename if form.accepts( r.post_vars, current.session, formname=formname, keepvalues=False, hideerror=False, ): if adapter.cancel_subscription(record.id): current.response.confirmation = T("Subscription cancelled") else: current.response.error = T("Cancellation failed") self.next = r.url(method="status") current.response.view = self._view(r, "update.html") return output
def share(): """ Show the list of desk to with the item can be push """ item = application.getItemByUUID(request.args(0)) if item is None: raise HTTP(404) query = (db.desk.id != session.desk_id) query &= auth.accessible_query('push_items', db.desk) posible_desk = db(query).select() fld_to_desk = Field('to_desk', 'integer') fld_to_desk.label = T("Push to organization desk") fld_to_desk.comment = T("Select where to push the item") fld_to_desk.requires = IS_EMPTY_OR( IS_IN_SET([(desk.id, desk.name) for desk in posible_desk])) fld_personal_desk = Field('to_person_desk', 'integer') fld_personal_desk.label = T("Push to other person desk") fld_personal_desk.comment = T("Select a person from the list.") # list of person on orgs persons = [] # search up all the persons orgs = db(db.organization.users.contains(auth.user.id)).select() for org in orgs: x = [db.auth_user(id=y) for y in org.users if y != auth.user.id] persons.extend(x) persons = list(set(persons)) fld_personal_desk.requires = IS_EMPTY_OR( IS_IN_SET([(per.id, "{} {}".format(per.first_name, per.last_name)) for per in persons])) fld_cond = Field('cond', 'boolean', default=False) fld_cond.label = T('To other person?') form = SQLFORM.factory(fld_to_desk, fld_personal_desk, fld_cond, submit_button=T("Send"), table_name='share') if form.process().accepted: src = session.desk_id if form.vars.cond: # send the item to other user other_user = db.auth_user(form.vars.to_person_desk) target = application.getUserDesk(other_user).id else: # send the item to the selected desk target = form.vars.to_desk if target: ct = application.getContentType(item.item_type) ct.shareItem(item.unique_id, src, target) response.js = "$('#metaModal').modal('hide');" response.flash = None return locals()
def customise_req_organisation_needs_resource(r, tablename): s3db = current.s3db CASH = T("Cash Donations needed") if r.tablename == "req_organisation_needs": # Allow only organisations which do not have a needs record # yet (single component): table = r.table field = table.organisation_id from s3 import IS_ONE_OF dbset = current.db(table.id == None) left = table.on( table.organisation_id == current.s3db.org_organisation.id) field.requires = IS_ONE_OF( dbset, "org_organisation.id", field.represent, left=left, orderby="org_organisation.name", sort=True, ) if r.representation in ("html", "aadata", "iframe"): # Structured lists for interactive views from gluon import Field table = current.s3db.req_organisation_needs table.needs_skills = Field.Method(lambda row: \ organisation_needs(row, need_type="skills")) table.needs_items = Field.Method(lambda row: \ organisation_needs(row, need_type="items")) current.response.s3.stylesheets.append("../themes/RW/needs.css") needs_skills = (T("Volunteers needed"), "needs_skills") needs_items = (T("Supplies needed"), "needs_items") # Filter widgets from s3 import S3TextFilter, S3OptionsFilter filter_widgets = [ #S3TextFilter(["organisation_id$name", # ], # label = T("Search"), # ), S3OptionsFilter("organisation_id"), S3OptionsFilter( "organisation_needs_skill.skill_id", label=T("Skills sought"), ), S3OptionsFilter( "organisation_needs_item.item_id", label=T("Supplies sought"), ), ] # CRUD form from s3 import S3SQLCustomForm, S3SQLInlineComponent crud_form = S3SQLCustomForm( "organisation_id", S3SQLInlineComponent( "organisation_needs_skill", label=T("Volunteers needed"), fields=[ "skill_id", "demand", "comments", ], ), S3SQLInlineComponent( "organisation_needs_item", label=T("Supplies needed"), fields=[ "item_id", "demand", "comments", ], ), (CASH, "money"), "money_details", #"vol", #"vol_details", ) next_page = r.url(method="") \ if r.tablename == "req_organisation_needs" else None s3db.configure( "req_organisation_needs", crud_form=crud_form, filter_widgets=filter_widgets, create_next=next_page, update_next=next_page, ) else: # Simple fields for exports needs_skills = (T("Volunteers needed"), "organisation_needs_skill.skill_id") needs_items = (T("Supplies needed"), "organisation_needs_item.item_id") # List fields (all formats) list_fields = [ "organisation_id", needs_skills, needs_items, (CASH, "money"), (T("Cash Donation Details"), "money_details"), ] s3db.configure( "req_organisation_needs", list_fields=list_fields, )
msg['From'] = '*****@*****.**' msg['To'] = send_email me = 'Emilius<*****@*****.**>' to = '*****@*****.**' mailSrv = smtplib.SMTP("mail.ru", 25) mailSrv.ehlo() mailSrv.login('*****@*****.**', 'passsswordd') mailSrv.sendmail(me, to, msg.as_string()) mailSrv.close() sys.path.append('/home/www-data/web2py') from gluon import DAL, Field db = DAL('sqlite://storage.sqlite', folder='/home/www-data/web2py/applications/tgmonitor/databases') db.define_table('tg_load', Field('check_date', 'datetime'), Field('tg_number', length=17), Field('busy', 'integer'), Field('installed', 'integer')) db.define_table( 'tg_list', Field('tg_group', length=12, default='group1'), Field('tg_number', length=17, notnull=True), Field('tg_descr', length=17), Field('tg_type', length=3, default='sip'), Field('color', length=16, default='black'), Field('alarm', 'integer', default=90), Field('alarm_email', length=20), Field('alarm_call_number', length=32), )
#!/usr/bin/env python # -*- coding: utf-8 -*- import sys, os, telnetlib, time, datetime def get_circuits(s='', find_par=''): pos = s.find(find_par) + 35 return s[pos:pos + 6].strip() sys.path.append('/home/www-data/web2py') from gluon import DAL, Field db = DAL('sqlite://storage.sqlite', folder='/home/www-data/web2py/applications/tgmonitor/databases') db.define_table('tg_load', Field('check_date', 'datetime'), Field('tg_number', length=17), Field('busy', 'integer'), Field('installed', 'integer')) host = '10.200.66.70' port = '6000' tn = telnetlib.Telnet(host, port) tn.write('LGI:op="monitor",PWD ="dspoftk",SER="10.100.100.104---O&M System";') ans = tn.read_until('END') tn.write('DSP OFTK: LT=TG, TG=44, DT=AT;') ans = tn.read_until('END') _busy = get_circuits(ans, 'Busy') _ins_num = get_circuits(ans, 'Installation number')
def _(): plugins = PluginManager('picture', app=None) # this will register the content/type on the application if plugins.picture.app is not None: editor = CKEditor(db=db) plugins.picture.app.registerContentType('picture', ContentPicture()) if not hasattr(db, 'plugin_picture_rendition'): tbl = db.define_table( 'plugin_picture_rendition', Field('picture', 'upload', uploadseparate=True, autodelete=True), Field('purpose', 'string', length=50, default='web'), Field('height', 'integer', default=0, readable=False, writable=False), Field('width', 'integer', default=0, readable=False, writable=False), Field('color', 'string', length=20, readable=False, writable=False), Field('format', 'string', length=10, readable=False, writable=False), Field('thumbnail', 'upload', uploadseparate=True, autodelete=True, default=None), ) tbl.purpose.comment = T(''' It may contain any value but it is recommended to use one of the values: raw, web, thumbnail, print ''') tbl.purpose.label = T('Purpose') tbl.height.label = T('Height') tbl.width.label = T('Width') tbl.color.label = T('Color space') tbl.format.label = T('Format') tbl.format.comment = T('Automatic form PIL') tbl.picture.label = T('Picture') tbl.picture.requires = [IS_IMAGE(), IS_NOT_EMPTY()] if not hasattr(db, 'plugin_picture_info'): # definimos la BD tbl = db.define_table( 'plugin_picture_info', Field('credit_line', 'string', length=250, default=''), Field('description', 'text', label=T('Description'), default=''), Field('caption', 'string', length=250, default=''), Field('renditions', 'list:reference plugin_picture_rendition'), Field('item_id', 'string', length=64), auth.signature, ) tbl.credit_line.label = T("Credit line") tbl.description.label = T('Description') tbl.description.widget = editor.widget tbl.caption.label = T("Caption") tbl.renditions.label = T("Renditions") tbl.item_id.readable = False tbl.item_id.writable = False # enable record versioning tbl._enable_record_versioning() # add callback for item cleanup on delete. def __plugin_picture_item_on_delete(s): item = s.select().first() if item.item_type == 'picture': # cleanup here cnt = db.plugin_picture_info(item_id=item.unique_id) db(db.plugin_picture_rendition.id.belongs( cnt.renditions)).delete() db(db.plugin_picture_info.item_id == item.unique_id).delete() return False # remember to procced db.item._before_delete.insert(0, __plugin_picture_item_on_delete) return