def set_properties(self): T = self.db.T self.fields = [ Field("user_id", "reference auth_user"), Field("event_type", "string", notnull=True), Field("way", "list:string", notnull=True), Field("unikey", unique=True, notnull=True) ] self.events = self.db.config.get_list('notification', 'event') self.ways = self.db.config.get_list('notification', 'way') self.validators = { "way": IS_IN_SET(self.ways, multiple=True), "event_type": IS_IN_SET([(key, value % ("", "")) for key, value in self.events]) } self.computations = { "unikey": lambda row: "%(user_id)s_%(event_type)s" % row } self.widgets = {"way": SQLFORM.widgets.checkboxes.widget} self.labels = { "event_type": T("When"), "way": T("You want to be notified by") }
def set_validators(self): config = self.db.config T = self.db.T request = self.db.request self.entity.nickname.requires = [ IS_SLUG(), IS_NOT_IN_DB(self.db, self.entity.nickname) ] self.entity.twitter.requires = IS_EMPTY_OR( IS_NOT_IN_DB(self.db, self.entity.twitter)) self.entity.facebook.requires = IS_EMPTY_OR( IS_NOT_IN_DB(self.db, self.entity.facebook)) self.entity.extra_links.requires = IS_EMPTY_OR( IS_LIST_OF( IS_URL(allowed_schemes=['https', 'http'], prepend_scheme='http'))) self.entity.photo_source.requires = IS_IN_SET( config.get_list('auth', 'photo_source')) self.entity.gender.requires = IS_EMPTY_OR( IS_IN_SET(config.get_list('auth', 'gender'))) self.entity.privacy.requires = IS_IN_SET( config.get_list('auth', 'privacy')) #date format not allowed on gae if not request.env.web2py_runtime_gae: self.entity.birthdate.requires = IS_EMPTY_OR( IS_DATE(format=str(T('%Y-%m-%d')))) self.entity.website.requires = IS_EMPTY_OR(IS_URL())
def set_properties(self): ckeditor = CKEditor() T = current.T self.fields = [ Field("price", "double", notnull=True, default=0), Field("manufacturer", "string", notnull=True), Field("in_stock", "boolean", notnull=True, default=True), Field("info", "text", notnull=True), Field("product_size", "string"), ] self.validators = { "info": IS_NOT_EMPTY(), "manufacturer": IS_NOT_EMPTY(), "product_size": IS_EMPTY_OR( IS_IN_SET([("L", T("Large")), ("M", T("Medium")), ("S", T("Small"))], zero=None)), } self.widgets = {"info": ckeditor.widget} self.labels = { "price": T("Product Price"), "manufacturer": T("Manufacturer name or brand"), "in_stock": T("Available?"), "info": T("Product specs"), "product_size": T("Product size"), }
def set_properties(self): self.fields = [ Field("content_type"), Field("item_id", "integer"), Field("slug"), Field("reason"), Field("details", "text") ] reasons = ["Publicação não é vegana", "Violação de direitos autorais", "Falta de referências/fontes", "Conteúdo ofensivo", "Publicação falsa/mentirosa", "Usuário falso", "Usuário ofensivo", "Usuário desrespeita os termos e condições da rede", "Outro motivo (Justifique abaixo)"] self.validators = { "reason": IS_IN_SET(reasons) } self.labels = { "content_type": self.db.T("Content Type"), "item_id": self.db.T("Item id"), "slug": self.db.T("Item url slug"), "reason": self.db.T("Reason"), "details": self.db.T("Details") }
def custom_prep(r): # Call standard prep if callable(standard_prep): result = standard_prep(r) if not result: return False if r.interactive: # Change the contact methods appearing in adding contact info MOBILE = current.deployment_settings.get_ui_label_mobile_phone() contact_methods = { "SKYPE": T("Skype"), "SMS": MOBILE, "IRC": T("IRC handle"), "GITHUB": T("Github Repo"), "LINKEDIN": T("LinkedIn Profile"), "BLOG": T("Blog"), } s3db.pr_contact.contact_method.requires = IS_IN_SET( contact_methods, zero=None) from s3.s3forms import S3SQLCustomForm crud_form = S3SQLCustomForm( "contact_method", "value", ) s3db.configure( "pr_contact", crud_form=crud_form, ) return True
def axis_options(self, axis, options=None, get_vars=None, widget_id=None): """ Construct an OptionsWidget for rows or cols axis @param axis: "rows" or "cols" @param options: the report options @param get_vars: the GET vars if the request (as dict) @param widget_id: the HTML element ID for the widget """ resource = self.resource prefix = resource.prefix_selector # Get all selectors if options and axis in options: fields = options[axis] else: fields = resource.get_config("list_fields") if not fields: fields = [f.name for f in resource.readable_fields()] # Resolve the selectors pkey = str(resource._id) resolve_selector = resource.resolve_selector rfields = [] append = rfields.append for f in fields: if isinstance(f, (tuple, list)): label, selector = f[:2] else: label, selector = None, f rfield = resolve_selector(selector) if rfield.colname == pkey: continue if label: rfield.label = label append(rfield) # Get current value if get_vars and axis in get_vars: value = get_vars[axis] else: value = "" if value: value = prefix(value) # Dummy field opts = [(prefix(rfield.selector), rfield.label) for rfield in rfields] dummy_field = Storage(name=axis, requires=IS_IN_SET(opts)) # Construct widget return OptionsWidget.widget(dummy_field, value, _id=widget_id, _name=axis, _class="pt-%s" % axis)
def app1_models(db): db.define_table( 'product', #Field('product_id', 'reference auth_user', readable=False, writable=False), Field('manufacturer'), Field('description', 'text'), Field('price'), Field('slug', compute=lambda row: IS_SLUG()(row.manufacturer)[0]), Field('product_type', requires=IS_IN_SET(('Mobilephone', 'Smartphone'))), Field('dual_sim', requires=IS_IN_SET(('Yes', 'No'))), Field('color', requires=IS_IN_SET(('Black', 'White', 'Gray'))), Field('country', requires=IS_IN_SET( ('USA', 'UK', 'EU', 'CRO', 'JAPAN', 'PRC', 'JAR')))), db.define_table('uploads', Field('up_file', 'upload', autodelete=True), Field('filename'))
def set_properties(self): ckeditor = CKEditor() T = current.T self.fields = [ Field("prep_time", "string", notnull=True), Field("cook_time", "string", notnull=True), Field("difficulty", "string", notnull=True), Field("servings", "double", notnull=True), Field("ingredients", "list:string", notnull=True), Field("instructions", "text", notnull=True), Field("credits", "text"), ] self.validators = { "ingredients": IS_NOT_EMPTY(), "instructions": IS_NOT_EMPTY(), "difficulty": IS_IN_SET([("1", T("Easy")), ("2", T("Medium")), ("3", T("Hard"))], zero=None), "prep_time": IS_NOT_EMPTY(), "cook_time": IS_NOT_EMPTY(), "servings": IS_NOT_EMPTY(), } self.widgets = {"instructions": ckeditor.widget} self.labels = { "instructions": T("Preparation instructions"), "ingredients": T("Ingredients"), "prep_time": T("Preparation time"), "cook_time": T("Cooking time"), "difficulty": T("Difficulty"), "servings": T("Servings"), "credits": T("credits"), } self.comments = { "ingredients": T("One item per line. Press enter to wrap. e.g: 3 cups of water<enter>" ), "instructions": T("You can include pictures."), "prep_time": T("The whole time considering ingredients preparation."), "cook_time": T("The time needed after all ingredients are ready."), "servings": T("How many portions, plates, cups etc?"), "credits": T("Include links, names, books etc."), "difficulty": T("Easy, Medium or hard to cook?"), }
def set_validators(self): T = current.T self.db.cookrecipe_data.video_source.requires = IS_EMPTY_OR( IS_IN_SET(["youtube", "vimeo"])) self.db.cookrecipe_data.active_tab.requires = IS_IN_SET( [('photo', T("Picture")), ("video", T("Video"))], zero=None) self.db.cookrecipe_data.active_tab.default = "photo" self.db.cookrecipe_data.instructions.default = T("""<ol> <li> <strong><u>Step 1</u></strong><br /> Instructions for the step 1</li> <li> <strong><u>Step 2</u></strong><br /> Instructions for the step 2</li> <li> <strong><u>Step 3</u></strong><br /> Instructions for the step 3</li> <li> <strong><u>Step 4</u></strong><br /> Instructions for the step 4 (shift+enter to make a new line, enter to add a new step)</li> </ol>""")
def time_options(self, options=None, get_vars=None, widget_id=None): T = current.T resource = self.resource prefix = resource.prefix_selector # Time options: if options and "time" in options: opts = options["time"] else: # (label, start, end, slots) # If you specify a start, then end is relative to that - without start, end is relative to now opts = ( ("All up to now", "", "", ""), ("Last Year", "-1year", "", "months"), ("Last 6 Months", "-6months", "", "weeks"), ("Last Quarter", "-3months", "", "weeks"), ("Last Month", "-1month", "", "days"), ("Last Week", "-1week", "", "days"), ("All/+1 Month", "", "+1month", ""), ("All/+2 Month", "", "+2month", ""), ("-6/+3 Months", "-6months", "+9months", "months"), ("-3/+1 Months", "-3months", "+4months", "weeks"), ("-4/+2 Weeks", "-4weeks", "+6weeks", "weeks"), ("-2/+1 Weeks", "-2weeks", "+3weeks", "days"), ) widget_opts = [] for opt in opts: label, start, end, slots = opt widget_opts.append(("|".join((start, end, slots)), T(label))) # Get current value if get_vars: start = get_vars.get("start", "") end = get_vars.get("end", "") slots = get_vars.get("slots", "") else: start = end = slots = "" value = "|".join((start, end, slots)) # Dummy field dummy_field = Storage(name="time", requires=IS_IN_SET(widget_opts)) # Construct widget return OptionsWidget.widget( dummy_field, value, _id=widget_id, _name="time", _class="tp-time", )
def app2_models(db): db.define_table( 'product', Field('product_id', 'reference auth_user', readable=False, writable=False), Field('name'), Field('description', 'text'), Field('slug', compute=lambda row: IS_SLUG()(row.name)[0]), Field('product_type', requires=IS_IN_SET(('Instruments', 'Software', 'Smartphone'))), Field('country', requires=IS_IN_SET( ('USA', 'UK', 'EU', 'CRO', 'JAPAN', 'PRC', 'JAR')))) db.define_table( 'company', Field('name'), Field('slug', compute=lambda row: IS_SLUG()(row.name)[0]), Field('country', requires=IS_IN_SET(('USA', 'UK', 'EU', 'CRO')))) db.define_table('person', Field('first_name'), Field('last_name'), Field('email'), Field('gender'), Field('ip_address')) db.define_table('doc', Field('title'), Field('body')) db.define_table('files', Field('title', 'string'), Field('uploaded_data', 'upload'))
def customise_pr_group_resource(r, tablename): messages = current.messages field = r.table.group_type pr_group_types = {1 : T("Family"), 2 : T("Tourist Group"), 3 : T("Relief Team"), 4 : T("other"), 5 : T("Mailing Lists"), 6 : T("Society"), } field.represent = lambda opt: pr_group_types.get(opt, messages.UNKNOWN_OPT) field.requires = IS_IN_SET(pr_group_types, zero=None)
def custom_prep(r): # Call standard prep if callable(standard_prep): result = standard_prep(r) else: result = True if vnrc: if r.component_name == "address": settings.gis.building_name = False settings.gis.latlon_selector = False settings.gis.map_selector = False settings.gis.postcode_selector = False elif r.component_name == "identity": table = s3db.pr_identity table.description.readable = False table.description.writable = False pr_id_type_opts = {1: T("Passport"), 2: T("National ID Card"), } from gluon.validators import IS_IN_SET table.type.requires = IS_IN_SET(pr_id_type_opts, zero=None) elif r.component_name == "experience": table = s3db.hrm_experience # Use simple free-text variants table.organisation.readable = True table.organisation.writable = True table.job_title.readable = True table.job_title.writable = True table.comments.label = T("Main Duties") crud_form = S3SQLCustomForm("organisation", "job_title", "comments", "start_date", "end_date", ) s3db.configure("hrm_experience", crud_form=crud_form, list_fields=["id", "organisation", "job_title", "comments", "start_date", "end_date", ], ) return result
def set_properties(self): ckeditor = CKEditor() self.fields = [ Field("title", unique=True), Field("description", "text"), Field("page_content", "text"), Field("picture", "upload"), Field("thumbnail", "upload"), Field("tags", "list:string"), Field("slug"), Field("page_scope", "list:string", default=["public", "sitemap"]), Field("visibility"), Field("text_language", default="pt-br"), Field("redirect_url"), ] self.widgets = { "tags": StringListWidget.widget, "page_content": ckeditor.widget } self.comments = { "page_scope": "public, sitemap, members" } self.computations = { "slug": lambda r: IS_SLUG()(r.title)[0], "thumbnail": lambda r: THUMB2(r.picture, 200, 200) } self.validators = { "title": [IS_NOT_EMPTY(), IS_NOT_IN_DB(self.db, "internal_page.title")], "description": IS_NOT_EMPTY(), "picture": IS_EMPTY_OR(IS_IMAGE()), "tags": COMMA_SEPARATED_LIST(), "text_language": IS_IN_SET(["en", "pt-br", "es"]) }
def create_fieldlist(table): fields_lst = [] # if table=="setting": # table="fieldvalue" fields = ns.db[table].fields for fname in fields: fieldcat=1 if fname in("id","deleted"): continue if ns.db[table][fname].type=="text": ns.db[table][fname].widget=lambda field,value: SQLFORM.widgets.string.widget(field,value) if type(ns.db[table][fname].requires).__name__=="check_boolean": fields_lst.append({"fieldname":fname,"label":ns.db[table][fname].label, "widget":SELECT([OPTION("", _value=""),OPTION(T("YES"), _value="1"),OPTION(T("NO"), _value="0",)], _id=table+"_"+fname, _name=fname), "fieldcat":1}) continue if table in("address","contact"): if fname=="nervatype": ns.db[table].nervatype.requires = IS_IN_SET(('customer', 'employee', 'event', 'place', 'product', 'project', 'tool', 'trans')) fieldcat=0 elif fname=="ref_id": fields_lst.append({"fieldname":"refnumber","label":T('Ref.No.'), "widget":INPUT(_type="text",_value="",_name="refnumber",_id=table+"_refnumber",_class="string"), "fieldcat":0}) fields_lst.append({"fieldname":"rownumber","label":T('Row No.'), "widget":INPUT(_type="text",_value="0",_name="rownumber",_id=table+"_rownumber",_class="integer"), "fieldcat":0}) continue elif table=="barcode": if fname=="code": fields_lst.append({"fieldname":"code","label":T('Barcode'), "widget":INPUT(_type="text",_value="",_name="code",_id=table+"_code",_class="string"), "fieldcat":0}) continue elif fname=="product_id": fields_lst.append({"fieldname":"partnumber","label":T('Product No.'), "widget":INPUT(_type="text",_value="",_name="partnumber",_id=table+"_partnumber",_class="string"), "fieldcat":1}) continue elif fname=="barcodetype": ns.db.barcode.barcodetype.requires = IS_IN_DB(ns.db(ns.db.groups.groupname.like('barcodetype')), ns.db.groups.groupvalue, '%(groupvalue)s') elif table=="currency": if fname=="curr": fieldcat=0 elif table=="customer": if fname=="custnumber": fieldcat=0 elif fname=="custtype": ns.db.customer.custtype.requires = IS_IN_DB(ns.db(ns.db.groups.groupname.like('custtype')&(ns.db.groups.groupvalue!="own")), ns.db.groups.groupvalue, '%(groupvalue)s') elif table=="deffield": if fname=="fieldname": fieldcat=0 elif fname=="nervatype": ns.db[table].nervatype.requires = IS_IN_SET(('address', 'barcode', 'contact', 'currency', 'customer', 'employee', 'event', 'item', 'link', 'log', 'movement', 'payment', 'price', 'place', 'product', 'project', 'rate', 'tax', 'tool', 'trans', 'setting')) elif fname=="subtype": ns.db[table][fname].widget=lambda field,value: SQLFORM.widgets.string.widget(field,value) elif fname=="fieldtype": ns.db.deffield.fieldtype.requires = IS_IN_DB(ns.db((ns.db.groups.groupname.like('fieldtype')) &(ns.db.groups.groupvalue!="checkbox")&(ns.db.groups.groupvalue!="trans")), ns.db.groups.groupvalue, '%(groupvalue)s') elif table=="employee": if fname=="empnumber": fieldcat=0 elif fname=="usergroup": ns.db.employee.usergroup.requires = IS_IN_DB(ns.db((ns.db.groups.groupname.like('usergroup'))&(ns.db.groups.deleted==0)), ns.db.groups.groupvalue, '%(groupvalue)s') elif fname=="department": ns.db.employee.department.requires = IS_EMPTY_OR(IS_IN_DB(ns.db((ns.db.groups.groupname.like('department')) &(ns.db.groups.deleted==0)), ns.db.groups.groupvalue, '%(groupvalue)s')) elif fname in("password","registration_key","reset_password_key","registration_id"): continue elif table=="event": if fname=="calnumber": fieldcat=0 elif fname=="ref_id": fields_lst.append({"fieldname":"refnumber","label":T('Ref. No.'), "widget":INPUT(_type="text",_value="",_name="refnumber",_id=table+"_refnumber",_class="string"), "fieldcat":1}) continue elif fname=="nervatype": ns.db[table].nervatype.requires = IS_IN_SET(('customer', 'employee', 'place', 'product', 'project', 'tool', 'trans')) elif fname=="eventgroup": ns.db[table][fname].widget=lambda field,value: SQLFORM.widgets.string.widget(field,value) elif table=="groups": if fname in("groupname","groupvalue"): fieldcat=0 elif table=="item": if fname=="trans_id": fields_lst.append({"fieldname":"transnumber","label":T('Doc.No.'), "widget":INPUT(_type="text",_value="",_name="transnumber",_id=table+"_transnumber",_class="string"), "fieldcat":0}) fields_lst.append({"fieldname":"rownumber","label":T('Row No.'), "widget":INPUT(_type="text",_value="0",_name="rownumber",_id=table+"_rownumber",_class="integer"), "fieldcat":0}) fields_lst.append({"fieldname":"inputmode","label":T('Input mode'), "widget":SELECT([OPTION("", _value=""),OPTION(T("fxprice"), _value="fxprice"), OPTION(T("netamount"), _value="netamount"),OPTION(T("amount"), _value="amount") ], _id="item_inputmode", _name="inputmode"), "fieldcat":1}) fields_lst.append({"fieldname":"inputvalue","label":T('Input value'), "widget":INPUT(_type="text",_value="0",_name="inputvalue",_id=table+"_inputvalue",_class="double"), "fieldcat":1}) continue elif fname=="product_id": fields_lst.append({"fieldname":"partnumber","label":T('Product No.'), "widget":INPUT(_type="text",_value="",_name="partnumber",_id=table+"_partnumber",_class="string"), "fieldcat":1}) continue elif fname=="tax_id": taxcode = ns.db(ns.db.tax.inactive==0).select(ns.db.tax.taxcode) widget=SELECT(*[OPTION(field.taxcode) for field in taxcode], _id="item_taxcode", _name="taxcode") widget.insert(0, OPTION("")) fields_lst.append({"fieldname":"taxcode","label":T('Tax'), "widget":widget, "fieldcat":1}) continue elif fname in("fxprice","netamount","vatamount","amount"): continue elif table=="link": nervatype_lst=['address', 'barcode', 'contact', 'currency', 'customer', 'employee', 'event', 'groups', 'item', 'movement', 'payment', 'price', 'place', 'product', 'project', 'rate', 'tax', 'tool', 'trans'] if fname == "nervatype_1": widget=SELECT(*[OPTION(nervatype) for nervatype in nervatype_lst], _id="link_nervatype1", _name="nervatype1") widget.insert(0, OPTION("")) fields_lst.append({"fieldname":"nervatype1","label":T('Nervatype 1'), "widget":widget, "fieldcat":0}) continue elif fname == "nervatype_2": widget=SELECT(*[OPTION(nervatype) for nervatype in nervatype_lst], _id="link_nervatype2", _name="nervatype2") widget.insert(0, OPTION("")) fields_lst.append({"fieldname":"nervatype2","label":T('Nervatype 2'), "widget":widget, "fieldcat":0}) continue elif fname=="ref_id_1": fields_lst.append({"fieldname":"refnumber1","label":T('Ref. No. 1'), "widget":INPUT(_type="text",_value="",_name="refnumber1",_id=table+"_refnumber1",_class="string"), "fieldcat":0}) continue elif fname=="ref_id_2": fields_lst.append({"fieldname":"refnumber2","label":T('Ref. No. 2'), "widget":INPUT(_type="text",_value="",_name="refnumber2",_id=table+"_refnumber2",_class="string"), "fieldcat":0}) continue elif table=="log": nervatype_lst=['address', 'barcode', 'contact', 'currency', 'customer', 'employee', 'deffield', 'event', 'groups', 'item', 'link', 'movement', 'payment', 'price', 'place', 'product', 'project', 'rate', 'tax', 'tool', 'trans', 'setting'] if fname=="employee_id": fields_lst.append({"fieldname":"empnumber","label":T('Employee No.'), "widget":INPUT(_type="text",_value="",_name="empnumber",_id=table+"_empnumber",_class="string"), "fieldcat":0}) continue elif fname=="crdate": fieldcat=0 elif fname == "nervatype": widget=SELECT(*[OPTION(nervatype) for nervatype in nervatype_lst], _id="log_nervatype", _name="nervatype") widget.insert(0, OPTION("")) fields_lst.append({"fieldname":"nervatype","label":T('Nervatype'), "widget":widget, "fieldcat":1}) continue elif fname == "logstate": widget=SELECT(*[OPTION(logstate.groupvalue) for logstate in ns.db(ns.db.groups.groupname.like('logstate')).select(ns.db.groups.groupvalue)], _id="log_logstate", _name="logstate") widget.insert(0, OPTION("")) fields_lst.append({"fieldname":"logstate","label":T('State'), "widget":widget, "fieldcat":1}) continue elif fname=="ref_id": fields_lst.append({"fieldname":"refnumber","label":T('Ref.No.'), "widget":INPUT(_type="text",_value="",_name="refnumber",_id=table+"_refnumber",_class="string"), "fieldcat":1}) continue elif table=="movement": if fname=="trans_id": fields_lst.append({"fieldname":"transnumber","label":T('Doc.No.'), "widget":INPUT(_type="text",_value="",_name="transnumber",_id=table+"_transnumber",_class="string"), "fieldcat":0}) fields_lst.append({"fieldname":"rownumber","label":T('Row No.'), "widget":INPUT(_type="text",_value="0",_name="rownumber",_id=table+"_rownumber",_class="integer"), "fieldcat":0}) continue elif fname=="movetype": ns.db.movement.movetype.requires = IS_IN_DB(ns.db(ns.db.groups.groupname.like('movetype') & ns.db.groups.groupvalue.belongs(('inventory', 'store', 'tool')) ), ns.db.groups.groupvalue, '%(groupvalue)s') elif fname=="product_id": fields_lst.append({"fieldname":"partnumber","label":T('Product No.'), "widget":INPUT(_type="text",_value="",_name="partnumber",_id=table+"_partnumber",_class="string"), "fieldcat":1}) continue elif fname=="tool_id": fields_lst.append({"fieldname":"serial","label":T('Serial'), "widget":INPUT(_type="text",_value="",_name="serial",_id=table+"_serial",_class="string"), "fieldcat":1}) continue elif fname=="place_id": fields_lst.append({"fieldname":"planumber","label":T('Place No.'), "widget":INPUT(_type="text",_value="",_name="planumber",_id=table+"_planumber",_class="string"), "fieldcat":1}) continue elif table=="numberdef": if fname=="numberkey": fieldcat=0 elif table=="pattern": if fname=="description": fieldcat=0 elif fname=="transtype": ns.db.pattern.transtype.requires = IS_IN_DB(ns.db(ns.db.groups.groupname.like('transtype')), ns.db.groups.groupvalue, '%(groupvalue)s') elif table=="payment": if fname=="trans_id": fields_lst.append({"fieldname":"transnumber","label":T('Doc.No.'), "widget":INPUT(_type="text",_value="",_name="transnumber",_id=table+"_transnumber",_class="string"), "fieldcat":0}) fields_lst.append({"fieldname":"rownumber","label":T('Row No.'), "widget":INPUT(_type="text",_value="0",_name="rownumber",_id=table+"_rownumber",_class="integer"), "fieldcat":0}) continue elif table=="place": if fname=="planumber": fieldcat=0 elif fname=="place_id": fields_lst.append({"fieldname":"ref_planumber","label":T('Ref. No.'), "widget":INPUT(_type="text",_value="",_name="ref_planumber",_id=table+"_ref_planumber",_class="string"), "fieldcat":1}) continue elif fname=="placetype": ns.db.place.placetype.requires = IS_IN_DB(ns.db(ns.db.groups.groupname.like('placetype')), ns.db.groups.groupvalue, '%(groupvalue)s') elif fname=="storetype": continue elif table=="price": if fname=="product_id": fields_lst.append({"fieldname":"partnumber","label":T('Product No.'), "widget":INPUT(_type="text",_value="",_name="partnumber",_id=table+"_partnumber",_class="string"), "fieldcat":0}) fields_lst.append({"fieldname":"pricetype","label":T('Type'), "widget":SELECT([OPTION("", _value=""),OPTION(T("price"), _value="price"), OPTION(T("discount"), _value="discount") ], _id=table+"_pricetype", _name="pricetype"), "fieldcat":0}) continue elif fname=="validfrom": fieldcat=0 elif fname=="curr": fieldcat=0 elif fname=="qty": fieldcat=0 elif fname=="pricevalue": ns.db.price.pricevalue.label = T("Value/limit") elif fname=="calcmode": ns.db.price.calcmode.requires = IS_IN_DB(ns.db(ns.db.groups.groupname.like('calcmode')), ns.db.groups.groupvalue, '%(description)s') elif table=="product": if fname=="partnumber": fieldcat=0 elif fname=="protype": ns.db.product.protype.requires = IS_IN_DB(ns.db(ns.db.groups.groupname.like('protype')), ns.db.groups.groupvalue, '%(groupvalue)s') elif fname=="tax_id": taxcode = ns.db(ns.db.tax.inactive==0).select(ns.db.tax.taxcode) widget=SELECT(*[OPTION(field.taxcode) for field in taxcode], _id="product_taxcode", _name="taxcode") widget.insert(0, OPTION("")) fields_lst.append({"fieldname":"taxcode","label":T('Tax'), "widget":widget, "fieldcat":1}) continue elif table=="project": if fname=="pronumber": fieldcat=0 elif fname=="customer_id": fields_lst.append({"fieldname":"custnumber","label":T('Customer No.'), "widget":INPUT(_type="text",_value="",_name="custnumber",_id=table+"_custnumber",_class="string"), "fieldcat":1}) continue elif table=="rate": if fname == "ratetype": fieldcat=0 ns.db.rate.ratetype.requires = IS_IN_DB(ns.db(ns.db.groups.groupname.like('ratetype')), ns.db.groups.groupvalue, '%(groupvalue)s') elif fname in("ratedate","curr"): fieldcat=0 elif fname=="place_id": fields_lst.append({"fieldname":"planumber","label":T('Place No.'), "widget":INPUT(_type="text",_value="",_name="planumber",_id=table+"_planumber",_class="string"), "fieldcat":0}) continue elif fname == "rategroup": ns.db.rate.rategroup.requires = IS_EMPTY_OR(IS_IN_DB(ns.db((ns.db.groups.deleted==0) &ns.db.groups.groupname.like('rategroup')), ns.db.groups.groupvalue, '%(groupvalue)s')) elif table=="tax": if fname=="taxcode": fieldcat=0 elif table=="tool": if fname=="serial": fieldcat=0 elif fname=="product_id": fields_lst.append({"fieldname":"partnumber","label":T('Product No.'), "widget":INPUT(_type="text",_value="",_name="partnumber",_id=table+"_partnumber",_class="string"), "fieldcat":1}) continue elif fname == "toolgroup": ns.db.tool.toolgroup.requires = IS_EMPTY_OR(IS_IN_DB(ns.db((ns.db.groups.deleted==0) &ns.db.groups.groupname.like('toolgroup')), ns.db.groups.groupvalue, '%(groupvalue)s')) elif table=="trans": if fname=="transnumber": fieldcat=0 elif fname == "transtype": ns.db.trans.transtype.requires = IS_IN_DB(ns.db(ns.db.groups.groupname.like('transtype')), ns.db.groups.groupvalue, '%(groupvalue)s') elif fname == "direction": ns.db.trans.direction.requires = IS_IN_DB(ns.db(ns.db.groups.groupname.like('direction')), ns.db.groups.groupvalue, '%(groupvalue)s') elif fname == "paidtype": ns.db.trans.paidtype.requires = IS_EMPTY_OR(IS_IN_DB(ns.db((ns.db.groups.deleted==0) &ns.db.groups.groupname.like('paidtype')), ns.db.groups.groupvalue, '%(groupvalue)s')) elif fname == "department": ns.db.trans.department.requires = IS_EMPTY_OR(IS_IN_DB(ns.db((ns.db.groups.deleted==0) &ns.db.groups.groupname.like('department')), ns.db.groups.groupvalue, '%(groupvalue)s')) elif fname == "transtate": ns.db.trans.transtate.requires = IS_IN_DB(ns.db(ns.db.groups.groupname.like('transtate')), ns.db.groups.groupvalue, '%(groupvalue)s') elif fname=="customer_id": fields_lst.append({"fieldname":"custnumber","label":T('Customer No.'), "widget":INPUT(_type="text",_value="",_name="custnumber",_id=table+"_custnumber",_class="string"), "fieldcat":1}) continue elif fname=="employee_id": fields_lst.append({"fieldname":"empnumber","label":T('Employee No.'), "widget":INPUT(_type="text",_value="",_name="empnumber",_id=table+"_empnumber",_class="string"), "fieldcat":1}) continue elif fname=="project_id": fields_lst.append({"fieldname":"pronumber","label":T('Project No.'), "widget":INPUT(_type="text",_value="",_name="pronumber",_id=table+"_pronumber",_class="string"), "fieldcat":1}) continue elif fname=="place_id": fields_lst.append({"fieldname":"planumber","label":T('Place No.'), "widget":INPUT(_type="text",_value="",_name="planumber",_id=table+"_planumber",_class="string"), "fieldcat":1}) continue elif fname=="cruser_id": continue elif table=="fieldvalue": if fname=="fieldname": fields_lst.append({"fieldname":"fieldname","label":T('Fieldname'), "widget":INPUT(_type="text",_value="",_name="fieldname",_id=table+"_fieldname",_class="string"), "fieldcat":0}) continue elif fname=="ref_id": fields_lst.append({"fieldname":"refnumber","label":T('Ref.No.'), "widget":INPUT(_type="text",_value="",_name="refnumber",_id=table+"_refnumber",_class="string"), "fieldcat":0}) fields_lst.append({"fieldname":"rownumber","label":T('Row No.'), "widget":INPUT(_type="text",_value="1",_name="rownumber",_id=table+"_rownumber",_class="integer"), "fieldcat":0}) continue elif fname=="fieldtype": ns.db.fieldvalue.fieldtype.requires = IS_IN_DB(ns.db((ns.db.groups.groupname.like('fieldtype')) &(ns.db.groups.groupvalue!="checkbox")&(ns.db.groups.groupvalue!="trans")), ns.db.groups.id, '%(groupvalue)s') form = SQLFORM(ns.db[table]) fields_lst.append({"fieldname":fname,"label":form.custom.label[fname], "widget":form.custom.widget[fname],"fieldcat":fieldcat}) if table in("address", "barcode", "contact", "currency", "customer", "employee", "event", "groups", "item", "link", "log", "movement", "price", "place", "product", "project", "rate", "tax", "tool", "trans"): nervatype = ns.db((ns.db.groups.groupname=="nervatype")&(ns.db.groups.groupvalue==table)).select().as_list()[0]["id"] deffields = ns.db((ns.db.deffield.deleted==0)&(ns.db.deffield.visible==1)&(ns.db.deffield.nervatype==nervatype) &(ns.db.deffield.readonly==0)&(ns.db.deffield.fieldtype==ns.db.groups.id)).select( ns.db.deffield.fieldname,ns.db.groups.groupvalue,ns.db.deffield.description,ns.db.deffield.valuelist) for deffield in deffields: if deffield.groups.groupvalue=="bool": fields_lst.append({"fieldname":deffield.deffield.fieldname,"label":deffield.deffield.description, "widget":INPUT(_type="checkbox",_value="on",_name=deffield.deffield.fieldname,_id=table+"_"+deffield.deffield.fieldname,_class="boolean"), "fieldcat":2}) elif deffield.groups.groupvalue=="integer": fields_lst.append({"fieldname":deffield.deffield.fieldname,"label":deffield.deffield.description, "widget":INPUT(_type="text",_value="0",_name=deffield.deffield.fieldname,_id=table+"_"+deffield.deffield.fieldname,_class="integer"), "fieldcat":2}) elif deffield.groups.groupvalue=="float": fields_lst.append({"fieldname":deffield.deffield.fieldname,"label":deffield.deffield.description, "widget":INPUT(_type="text",_value="0",_name=deffield.deffield.fieldname,_id=table+"_"+deffield.deffield.fieldname,_class="double"), "fieldcat":2}) elif deffield.groups.groupvalue=="date": fields_lst.append({"fieldname":deffield.deffield.fieldname,"label":deffield.deffield.description, "widget":INPUT(_type="text",_value="",_name=deffield.deffield.fieldname,_id=table+"_"+deffield.deffield.fieldname,_class="date"), "fieldcat":2}) elif deffield.groups.groupvalue=="valuelist": widget = SELECT(*[OPTION(field) for field in deffield.deffield.valuelist.split("|")], _name=deffield.deffield.fieldname,_id=table+"_"+deffield.deffield.fieldname) widget.insert(0, OPTION("", _value="")) fields_lst.append({"fieldname":deffield.deffield.fieldname,"label":deffield.deffield.description,"widget":widget,"fieldcat":2}) else: fields_lst.append({"fieldname":deffield.deffield.fieldname,"label":deffield.deffield.description, "widget":INPUT(_type="text",_value="",_name=deffield.deffield.fieldname,_id=table+"_"+deffield.deffield.fieldname,_class="string"), "fieldcat":2}) return fields_lst
def apply_method(r, **attr): """ Apply method. @param r: the S3Request @param attr: controller options for this request """ if r.representation == "html": from gluon.dal import Field from gluon.html import FORM, INPUT, OPTION, SELECT from gluon.validators import IS_IN_SET, IS_EMPTY_OR from s3fields import s3_datetime from s3validators import IS_LOCATION_SELECTOR2 from s3widgets import S3LocationSelectorWidget2 T = current.T table = r.table response = current.response session = current.session formstyle = current.deployment_settings.get_ui_formstyle() tracker = S3Trackable(table, record_id=r.id) form = FORM() fappend = form.append comment = "" opts = { 1: T("Check-In"), 2: T("Check-Out"), 3: T("Update Base Location"), } id = "action" label = T("Action") widget = SELECT( [OPTION(opts[opt], _value=opt) for opt in opts], _id=id, _name=id, _value=1, requries=IS_IN_SET(opts), ) row = formstyle("%s__row" % id, label, widget, comment) fappend(row) field = s3_datetime() field.tablename = r.tablename id = "timestmp" label = T("Time") value = current.request.utcnow widget = field.widget(field, value) row = formstyle("%s__row" % id, label, widget, comment) fappend(row) field = table.location_id field.requires = IS_EMPTY_OR(IS_LOCATION_SELECTOR2()) value = tracker.get_location(_fields=["id"], as_rows=True).first().id id = "location" label = "" # Replaced by Widget widget = S3LocationSelectorWidget2()(field, value) row = formstyle("%s__row" % id, label, widget, comment) fappend(row) id = "submit" label = "" widget = INPUT(_type="submit", _value=T("Apply")) row = formstyle("%s__row" % id, label, widget, comment) fappend(row) response.view = "create.html" title = T("Update Location") output = dict(title=title, form=form) script = \ '''$("#action").change(function(){ var type=$("#action").val() if(type==2){$('#location__row').hide()}else{$('#location__row').show()}})''' response.s3.jquery_ready.append(script) if form.accepts(current.request.vars, current.session): form_vars = form.vars action = form_vars.get("action", None) if action == "1": # Check-In location_id = form_vars.get("location_id", None) if location_id: # We're not Checking-in in S3Track terms (that's about interlocking with another object) #tracker.check_in() timestmp = form_vars.get("timestmp", None) if timestmp: # @ToDo: Convert from string pass tracker.set_location(location_id, timestmp=timestmp) response.confirmation = T("Checked-In successfully!") elif action == "2": # Check-Out # We're not Checking-out in S3Track terms (that's about removing an interlock with another object) #tracker.check_out() timestmp = form_vars.get("timestmp", None) if timestmp: # @ToDo: Convert from string pass tracker.set_location(r.record.location_id, timestmp=timestmp) response.confirmation = T("Checked-Out successfully!") elif action == "3": # Update Base Location location_id = form_vars.get("location_id", None) if location_id: tracker.set_base_location(location_id) response.confirmation = T("Base Location Updated!") return output else: raise HTTP(501, current.ERROR.BAD_METHOD)
def layer_options(self, options=None, get_vars=None, widget_id=None): """ Construct an OptionsWidget for the fact layer @param options: the report options @param get_vars: the GET vars if the request (as dict) @param widget_id: the HTML element ID for the widget """ resource = self.resource from s3data import S3PivotTable all_methods = S3PivotTable.METHODS # Get all layers layers = None methods = None if options: if "methods" in options: methods = options["methods"] if "fact" in options: layers = options["fact"] if not layers: layers = resource.get_config("list_fields") if not layers: layers = [f.name for f in resource.readable_fields()] if not methods: methods = all_methods # Resolve layers prefix = resource.prefix_selector opts = [] for layer in layers: # Extract layer option if type(layer) is tuple and \ (isinstance(layer[0], lazyT) or layer[1] not in all_methods): opt = [layer] else: opt = list(layer) \ if isinstance(layer, (tuple, list)) else [layer] # Get field label and selector s = opt[0] if isinstance(s, tuple): label, selector = s else: label, selector = None, s selector = prefix(selector) # Resolve the selector rfield = resource.resolve_selector(selector) if not rfield.field and not rfield.virtual: continue if label is not None: rfield.label = label # Autodetect methods? if len(opt) == 1: # Only field given -> auto-detect aggregation methods is_amount = None ftype = rfield.ftype if ftype == "integer": is_amount = True requires = rfield.requires if not isinstance(requires, (list, tuple)): requires = [requires] for r in requires: if isinstance(r, IS_IN_SET) or \ isinstance(r, IS_EMPTY_OR) and \ isinstance(r.other, IS_IN_SET): is_amount = False elif ftype == "double": is_amount = True elif ftype[:9] == "reference" or \ ftype[:5] == "list:" or \ ftype in ("id", "string", "text"): is_amount = False if ftype in ("datetime", "date", "time"): mopts = ["min", "max", "list"] elif is_amount is None: mopts = ["sum", "min", "max", "avg", "count", "list"] elif is_amount: mopts = ["sum", "min", "max", "avg"] else: mopts = ["count", "list"] opts.extend([(rfield, selector, m) for m in mopts if m in methods]) else: # Explicit method specified opt.insert(0, rfield) opts.append(opt) # Construct default labels T = current.T RECORDS = T("Records") layer_opts = [] mname = S3PivotTable._get_method_label for opt in opts: rfield, selector, method = opt[:3] if method not in methods: continue if len(opt) == 4: layer_label = opt[3] else: mlabel = mname(method) flabel = rfield.label if rfield.label != "Id" else RECORDS layer_label = T("%s (%s)") % (flabel, mlabel) layer_opts.append(("%s(%s)" % (method, selector), layer_label)) # Get current value if get_vars and "fact" in get_vars: layer = get_vars["fact"] else: layer = "" if layer: m = layer_pattern.match(layer) if m is None: layer = "" else: selector, method = m.group(2), m.group(1) selector = prefix(selector) layer = "%s(%s)" % (method, selector) # Field is read-only if there is only 1 option if len(layer_opts) == 1: default = layer_opts[0] return default[1], {"fact": default[0]} # Dummy field dummy_field = Storage(name="fact", requires=IS_IN_SET(layer_opts)) # Construct widget widget = OptionsWidget.widget(dummy_field, layer, _id=widget_id, _name="fact", _class="pt-fact") return widget, {}
# create DAL connection (and create DB if not exists) db = DAL('sqlite://guitest.sqlite', folder=None) # define a table 'person' (create/aster as necessary) person = db.define_table( 'person', Field('name', 'string', length=100), Field('sex', 'string', length=1), Field('active', 'boolean', comment="check!"), Field('bio', 'text', comment="resume (CV)"), ) # set sample validator (do not allow empty nor duplicate names) db.person.name.requires = [IS_NOT_EMPTY(), IS_NOT_IN_DB(db, 'person.name')] db.person.sex.requires = IS_IN_SET({'M': 'Male', 'F': 'Female'}) # create the wxPython GUI application instance: app = wx.App(False) # create a testing frame (wx "window"): f = wx.Frame(None, title="web2py/gui2py sample app") # create the web2py FORM based on person table form = SQLFORM(db.person) # create the HTML "browser" window: html = wx.html.HtmlWindow(f, style=wx.html.HW_DEFAULT_STYLE | wx.TAB_TRAVERSAL) # convert the web2py FORM to XML and display it html.SetPage(form.xml())
def layer_options(self, options=None, get_vars=None, widget_id=None): """ Construct an OptionsWidget for the fact layer @param options: the report options @param get_vars: the GET vars if the request (as dict) @param widget_id: the HTML element ID for the widget """ resource = self.resource from s3data import S3PivotTable all_methods = S3PivotTable.METHODS # Get all layers layers = None methods = None if options: if "methods" in options: methods = options["methods"] if "fact" in options: layers = options["fact"] if not layers: layers = resource.get_config("list_fields") if not layers: layers = [f.name for f in resource.readable_fields()] if not methods: methods = all_methods # Resolve layer options T = current.T RECORDS = T("Records") mname = S3PivotTable._get_method_label def layer_label(rfield, method): """ Helper to construct a layer label """ mlabel = mname(method) flabel = rfield.label if rfield.label != "Id" else RECORDS # @ToDo: Exclude this string from admin/translate exports return T("%s (%s)") % (flabel, mlabel) prefix = resource.prefix_selector layer_opts = [] for layer in layers: # Parse option if type(layer) is tuple: label, s = layer else: label, s = None, layer match = layer_pattern.match(s) if match is not None: s, m = match.group(2), match.group(1) else: m = None # Resolve the selector selector = prefix(s) rfield = resource.resolve_selector(selector) if not rfield.field and not rfield.virtual: continue if m is None and label: rfield.label = label if m is None: # Only field given -> auto-detect aggregation methods is_amount = None ftype = rfield.ftype if ftype == "integer": is_amount = True requires = rfield.requires if not isinstance(requires, (list, tuple)): requires = [requires] for r in requires: if isinstance(r, IS_IN_SET) or \ isinstance(r, IS_EMPTY_OR) and \ isinstance(r.other, IS_IN_SET): is_amount = False elif ftype == "double": is_amount = True elif ftype[:9] == "reference" or \ ftype[:5] == "list:" or \ ftype in ("id", "string", "text"): is_amount = False if ftype in ("datetime", "date", "time"): mopts = ["min", "max", "list"] elif is_amount is None: mopts = ["sum", "min", "max", "avg", "count", "list"] elif is_amount: mopts = ["sum", "min", "max", "avg"] else: mopts = ["count", "list"] for method in mopts: if method in methods: label = layer_label(rfield, method) layer_opts.append( ("%s(%s)" % (method, selector), label)) else: # Explicit method specified if label is None: label = layer_label(rfield, m) layer_opts.append(("%s(%s)" % (m, selector), label)) # Get current value if get_vars and "fact" in get_vars: layer = get_vars["fact"] else: layer = "" if layer: match = layer_pattern.match(layer) if match is None: layer = "" else: selector, method = match.group(2), match.group(1) selector = prefix(selector) layer = "%s(%s)" % (method, selector) if len(layer_opts) == 1: # Field is read-only if there is only 1 option default = layer_opts[0] widget = TAG[""](default[1], INPUT(_type="hidden", _id=widget_id, _name=widget_id, _value=default[0])) single = True else: # Render Selector dummy_field = Storage(name="fact", requires=IS_IN_SET(layer_opts)) widget = OptionsWidget.widget(dummy_field, layer, _id=widget_id, _name="fact", _class="pt-fact") single = False return widget, single
def _manage_subscriptions(self, resources, filters): """ Custom form to manage subscriptions @param resources: available resources config @param filters: filter widgets """ # Uses Default Eden formstyle from s3theme import formstyle_foundation as formstyle from gluon.validators import IS_IN_SET from s3.s3widgets import S3GroupedOptionsWidget, S3MultiSelectWidget from s3layouts import S3PopupLink # L10n T = current.T db = current.db s3db = current.s3db response = current.response labels = Storage( #RESOURCES = T("Subscribe To"), #NOTIFY_ON = T("Notify On"), #FREQUENCY = T("Frequency"), NOTIFY_BY = T("Notify By"), #MORE = T("More Options"), #LESS = T("Less Options"), ) messages = Storage( ERROR = T("Error: could not update notification settings"), SUCCESS = T("Notification settings updated"), ) # Get current subscription settings resp. form defaults subscription = self._get_subscription() # Initialize form form = FORM(_id="subscription-form", hidden={"subscription-filters": ""}) # Filters filter_form = S3FilterForm(filters, clear=False) fieldset = FIELDSET(filter_form.fields(None, subscription["get_vars"]), _id="subscription-filter-form") form.append(fieldset) # Notification options rows = [] stable = s3db.pr_subscription selector = S3GroupedOptionsWidget(cols=1) # Deactivated trigger selector #rows.append(("trigger_selector__row", # "%s:" % labels.NOTIFY_ON, # selector(stable.notify_on, # subscription["notify_on"], # _id="trigger_selector"), # "")) #switch = S3GroupedOptionsWidget(cols=1, multiple=False, sort=False) # Deactivated: frequency selector #rows.append(("frequency_selector__row", # "%s:" % labels.FREQUENCY, # switch(stable.frequency, # subscription["frequency"], # _id="frequency_selector"), # "")) methods = [("EMAIL", T("Email")), ("SMS", T("SMS")), ("Sync", T("FTP")), ] method_options = Storage(name = "method", requires = IS_IN_SET(methods)) rows.append(("method_selector__row", "%s:" % labels.NOTIFY_BY, selector(method_options, subscription["method"], _id="method_selector"), "")) # Sync Row properties = subscription["comments"] if properties: properties = json.loads(properties) synctable = s3db.sync_repository query = (synctable.apitype == "ftp") & \ (synctable.deleted != True) & \ (synctable.owned_by_user == current.auth.user.id) ftp_rows = db(query).select(synctable.id, synctable.name, orderby = synctable.id) multiselect = S3MultiSelectWidget(header = False, multiple = False, create = {"c": "sync", "f": "repository", "label": "Create Repository", }, ) if ftp_rows: if properties: user_repository_id = properties["repository_id"] else: user_repository_id = ftp_rows.first().id if current.auth.s3_has_permission("update", "sync_repository", record_id = user_repository_id): repository_comment = S3PopupLink(c = "sync", f = "repository", m = "update", args = [user_repository_id], title = T("Update Repository"), tooltip = T("You can edit your FTP repository here"), ) field = s3db.sync_task.repository_id ftp_ids = [(r.id, T(r.name)) for r in ftp_rows] field.requires = IS_IN_SET(ftp_ids) rows.append(("sync_task_repository_id__row", "", multiselect(field, user_repository_id, _id="sync_task_repository_id"), repository_comment)) else: if current.auth.s3_has_permission("create", "sync_repository"): repository_comment = S3PopupLink(c = "sync", f = "repository", title = T("Create Repository"), tooltip = T("Click on the link to begin creating your FTP repository"), ) rows.append(("sync_task_repository_id__row", "", "", repository_comment)) parent = FIELDSET() for row in rows: parent.append(formstyle(form, [row])) # Deactivated Toggle #parent.insert(0, # DIV(SPAN([I(_class="icon-reorder"), labels.MORE], # _class="toggle-text", # _style="display:none"), # SPAN([I(_class="icon-reorder"), labels.LESS], # _class="toggle-text"), # _id="notification-options", # _class="control-group")) form.append(parent) # Submit button submit_fieldset = FIELDSET(DIV("", INPUT(_type="submit", _value="Update Settings"), _id = "submit__row")) form.append(submit_fieldset) # Script (to extract filters on submit and toggle options visibility) script = URL(c="static", f="scripts", args=["S3", "s3.subscriptions.js"]) response.s3.scripts.append(script) # Script to show/hide the ftp repo row for FTP checkbox on/off repository_script = ''' if($('#method_selector option[value=Sync]').is(':selected')){ $('#sync_task_repository_id__row').show(); } else { $('#sync_task_repository_id__row').hide(); } $('#method_selector').change(function(){ if($(this).val().indexOf('Sync') != -1){ $('#sync_task_repository_id__row').show(); } else { $('#sync_task_repository_id__row').hide(); } }) ''' response.s3.jquery_ready.append(repository_script) # Accept form if form.accepts(current.request.post_vars, current.session, formname="subscription", keepvalues=True): formvars = form.vars listify = lambda x: None if not x else x if type(x) is list else [x] # Fixed resource selection: subscription["subscribe"] = [resources[0]] # Alternatively, with resource selector: #subscribe = listify(formvars.resources) #if subscribe: #subscription["subscribe"] = \ #[r for idx, r in enumerate(resources) #if str(idx) in subscribe] subscription["filters"] = form.request_vars \ .get("subscription-filters", None) # Fixed method subscription["method"] = formvars.method # Fixed Notify On and Frequency subscription["notify_on"] = ["new"] subscription["frequency"] = "immediately" # Alternatively, with notify and frequency selector #subscription["notify_on"] = listify(formvars.notify_on #subscription["frequency"] = formvars.frequency success_subscription = self._update_subscription(subscription) if "Sync" in subscription["method"] and formvars.repository_id: properties = self._update_sync(subscription["subscribe"][0]['resource'], subscription.get("filters"), int(formvars.repository_id), properties) properties = json.dumps(properties) db(stable.pe_id == current.auth.user.pe_id).update(comments=properties) else: self._remove_sync(properties) db(stable.pe_id == current.auth.user.pe_id).update(comments=None) if success_subscription: response.confirmation = messages.SUCCESS else: response.error = messages.ERROR return form
def set_validators(self): self.db.video_data.video_source.requires = IS_IN_SET( ["youtube", "vimeo"])
def set_properties(self): ckeditor = CKEditor() T = current.T self.fields = [ Field("prep_time", "string", notnull=True), Field("cook_time", "string", notnull=True), Field("difficulty", "string", notnull=True), Field("servings", "double", notnull=True), Field("ingredients", "list:string", notnull=True), Field("instructions", "text", notnull=True), Field("credits", "text"), Field("video_source", "string"), Field("video_embed", "string"), Field("active_tab", "string", default="photo"), ] self.validators = { "ingredients": IS_NOT_EMPTY(), "instructions": IS_NOT_EMPTY(), "difficulty": IS_IN_SET([("1", T("Easy")), ("2", T("Medium")), ("3", T("Hard"))], zero=None), "prep_time": IS_NOT_EMPTY(), "cook_time": IS_NOT_EMPTY(), "servings": IS_NOT_EMPTY(), } self.widgets = { "instructions": ckeditor.widget, "ingredients": ListWidget.widget } self.labels = { "instructions": T("Preparation instructions"), "ingredients": T("Ingredients"), "prep_time": T("Preparation time"), "cook_time": T("Cooking time"), "difficulty": T("Difficulty"), "servings": T("Servings"), "credits": T("credits"), "video_source": T("Video source"), "video_embed": T("Video link or code"), "active_tab": T("By default show video or picture"), } self.comments = { "ingredients": T("Include one item then press enter or click in 'add new' to include more" ), "instructions": T("Describe the steps to cook the recipe, also you can include aditional photos and links." ), "prep_time": T("The whole time considering ingredients preparation."), "cook_time": T("The time needed after all ingredients are ready."), "servings": T("This recipe serves how many people?"), "credits": T("Include links, names, books etc."), "difficulty": T("Easy, Medium or hard to cook?"), "video_source": T("Is your video hosted at youtube or vimeo? Leave blank if you have no video." ), "video_embed": T("Please input only the code or link to the video i.e: http://vimeo.com/454545 or only 454545" ), "active_tab": T("Choose what to show or leave photo as default"), }
def __init__(self): T = current.T self.db_options = [ Field("uri", "string", notnull=True, default="sqlite://movuca.sqlite"), Field("migrate", "boolean", notnull=True, default=True), Field("migrate_enabled", "boolean", notnull=True, default=True), Field("pool_size", "integer", notnull=True, default=10), Field("gaeuri", "string", notnull=True, default="google:datastore"), Field("setuptime", "datetime", notnull=True), ] self.mail_options = [ Field("server", "string", notnull=True, default="logging"), Field("sender", "string", notnull=True, default="*****@*****.**"), Field("login", "string", notnull=False, default="teste:1234"), Field("setuptime", "datetime", notnull=True), ] self.auth_options = [ Field("formstyle", "string", notnull=True, default="divs"), Field("photo_source", "list:string", notnull=True, default=[ "1:upload", "2:gravatar", "3:facebook", "4:twitter", "5:no photo", "6:Google" ]), Field("gender", "list:string", notnull=True, default=[ "Male:Male", "Female:Female", "Not specified:Not specified" ]), Field("privacy", "list:string", notnull=True, default=["1:Public", "2:Visible only for contacts"]), Field("use_facebook", "boolean", notnull=True, default=True), Field("facebook", "list:string", notnull=True, default=[ "id:133622423420992", "secret:6b0880726a21a89dfcb07c19c7807817", "admins:1766038844" ]), Field("use_google", "boolean", notnull=True, default=True), Field("google", "list:string", notnull=True, default=[ "id:908928538602.apps.googleusercontent.com", "secret:HH6ITKRWOkhS-prHliD21weA", "xoauth_displayname:Movuca Social CMS", "redirect_scheme:http", "redirect_uri:movu.ca/demo/person/google/login", "approval_prompt:force" ]), Field("use_recaptcha", "boolean", notnull=True, default=True), Field("recaptcha", "list:string", notnull=True, default=[ "public:6Ld9QswSAAAAAN1DlVBEOxFkMGsFytzSZ54v1nur", "private:6Ld9QswSAAAAAIzXZXJQmxKKaDS5AMrCA1Cnq5ut", "theme:clean", "lang:en" ]), Field("use_mailhide", "boolean", notnull=True, default=True), Field("mailhide", "list:string", notnull=True, default=[ "public:01_qmBPgGX5nvV1rYv_bxK4A==", "private:37565e87d8f80bd680afbc31e0d4e3df" ]), Field("registration_requires_verification", "boolean", notnull=True, default=False), Field("registration_requires_approval", "boolean", notnull=True, default=False), Field("registration_requires_invitation", "boolean", notnull=True, default=False), Field("server", "string", notnull=True, default="default"), Field("sender", "string", notnull=True, default="*****@*****.**"), Field("login", "string", notnull=False, default="teste:1234"), Field("setuptime", "datetime", notnull=True), ] self.crud_options = [ Field("formstyle", "string", notnull=True, default="divs"), Field("setuptime", "datetime", notnull=True), ] self.theme_options = [ Field("name", "string", notnull=True, default="bootstrap"), # basic Field("setuptime", "datetime", notnull=True), ] self.article_options = [ Field("license", "list:string", notnull=True, default=[ "1:All rights reserved", "2:Public domain", "3:Creative Commons" ]), Field("setuptime", "datetime", notnull=True), ] self.meta_options = [ Field("title", "string", notnull=True, default="Movuca"), Field("subtitle", "string", notnull=True, default="Free Social CMS Engine"), Field("author", "string", notnull=True, default="Bruno Cezar Rocha at blouweb.com"), Field("keywords", "string", notnull=True, default="web2py, python, cms, social network, CMS"), Field( "description", "string", notnull=True, default= "Free Social CMS Engine built with web2py and Python by blouweb.com" ), Field("generator", "string", notnull=True, default="web2py, Python, Movuca CMS"), Field("copyright", "string", notnull=True, default="Free"), Field("setuptime", "datetime", notnull=True), ] comment_systems = [ ('internal', T("Internal comments")), ('disqus', T("Disqus")), ('intense', T("Intense Debate")), ('facebook', T("Facebook comments")), ('disabled', T("Comments disabled")), ] self.comment_options = [ Field("system", "string", requires=IS_IN_SET(comment_systems), notnull=True, default="internal"), Field("anonymous", "boolean", notnull=True, default=False), Field("disqus_shortname", "string", notnull=True, default="movuca"), Field("disqus_developer", "integer", notnull=True, default=1), Field("intense_acct", "string", notnull=True, default="fe83a2e2af975dd1095a8e4e9ebe1902"), Field("facebook_appid", "string", notnull=True, default="257838757587678"), Field("facebook_numposts", "integer", notnull=True, default=10), Field("setuptime", "datetime", notnull=True), ] notification_events = [ "new_contact:%s followed you %s", "wrote_on_wall:%s wrote in your board %s", "liked:%s liked your publication %s", "shared:%s shared your publication %s", "favorited:%s favorited your publication %s", "disliked:%s disliked your publication %s", "new_article_comment:%s commented your publication %s", "comment_reply:%s replied your comment %s", "board_reply:%s replied your board post %s", "new_article_comment_subscribers:%s comments on publications you are subscribed %s", "update_article_subscribers:%s updates on publications you are subscribed %s", "mention:%s mentioned your name %s", "message:%s you got a new message %s", ] notification_ways = ["site:site notifications", "email:e-mail"] self.notification_options = [ Field("event", "list:string", default=notification_events, notnull=True), Field("way", "list:string", default=notification_ways, notnull=True), Field("worker", "string", default="site", comment="site or scheduler"), Field("setuptime", "datetime", notnull=True), ]
def _manage_subscriptions(self, resources, filters): """ Custom form to manage subscriptions @param resources: available resources config @param filters: filter widgets """ from gluon.sqlhtml import SQLFORM from gluon.validators import IS_IN_SET from s3.s3widgets import S3GroupedOptionsWidget # L10n T = current.T labels = Storage( RESOURCES=T("Subscribe To"), NOTIFY_ON=T("Notify On"), FREQUENCY=T("Frequency"), NOTIFY_BY=T("Notify By"), MORE=T("More Options"), LESS=T("Less Options"), ) messages = Storage( ERROR=T("Error: could not update notification settings"), SUCCESS=T("Notification settings updated"), ) # Get current subscription settings resp. form defaults subscription = self._get_subscription() # Formstyle bootstrap formstyle = SQLFORM.formstyles.bootstrap # Initialize form form = FORM(_id="subscription-form", hidden={"subscription-filters": ""}) # Filters filter_form = S3FilterForm(filters, clear=False) fieldset = FIELDSET(filter_form.fields(None, subscription["get_vars"]), _id="subscription-filter-form") form.append(fieldset) # Notification options rows = [] stable = current.s3db.pr_subscription selector = S3GroupedOptionsWidget(cols=1) rows.append(("trigger_selector__row", "%s:" % labels.NOTIFY_ON, selector(stable.notify_on, subscription["notify_on"], _id="trigger_selector"), "")) switch = S3GroupedOptionsWidget(cols=1, multiple=False, sort=False) rows.append(("frequency_selector__row", "%s:" % labels.FREQUENCY, switch(stable.frequency, subscription["frequency"], _id="frequency_selector"), "")) methods = [("EMAIL", T("Email")), ("SMS", T("SMS"))] method_options = Storage(name="method", requires=IS_IN_SET(methods)) rows.append(("method_selector__row", "%s:" % labels.NOTIFY_BY, selector(method_options, subscription["method"], _id="method_selector"), "")) fieldset = formstyle(form, rows) fieldset.insert( 0, DIV(SPAN([I(_class="icon-reorder"), labels.MORE], _class="toggle-text", _style="display:none"), SPAN([I(_class="icon-reorder"), labels.LESS], _class="toggle-text"), _id="notification-options", _class="control-group")) form.append(fieldset) # Submit button row = ("submit__row", "", INPUT(_type="submit", _value="Update Settings"), "") fieldset = formstyle(form, [row]) form.append(fieldset) # Script (to extract filters on submit and toggle options visibility) script = URL(c="static", f="scripts", args=["S3", "s3.subscriptions.js"]) response = current.response response.s3.scripts.append(script) # Accept form if form.accepts(current.request.post_vars, current.session, formname="subscription", keepvalues=True): formvars = form.vars listify = lambda x: None if not x else x if type( x) is list else [x] # Fixed resource selection: subscription["subscribe"] = [resources[0]] # Alternatively, with resource selector: #subscribe = listify(formvars.resources) #if subscribe: #subscription["subscribe"] = \ #[r for idx, r in enumerate(resources) #if str(idx) in subscribe] subscription["filters"] = form.request_vars \ .get("subscription-filters", None) subscription["notify_on"] = listify(formvars.notify_on) subscription["frequency"] = formvars.frequency subscription["method"] = formvars.method success = self._update_subscription(subscription) if success: response.confirmation = messages.SUCCESS else: response.error = messages.ERROR return form
def customise_pr_person_resource(r, tablename): s3db = current.s3db table = r.resource.table # Disallow "unknown" gender and defaults to "male" evr_gender_opts = dict( (k, v) for k, v in s3db.pr_gender_opts.items() if k in (2, 3)) gender = table.gender gender.requires = IS_IN_SET(evr_gender_opts, zero=None) gender.default = 3 if r.controller == "evr": # Hide evacuees emergency contacts settings.pr.show_emergency_contacts = False # Last name and date of birth mandatory in EVR module table.last_name.requires = IS_NOT_EMPTY( error_message=T("Please enter a last name")) dob_requires = s3_date("dob", future=0, past=1320, empty=False).requires dob_requires.error_message = T("Please enter a date of birth") table.date_of_birth.requires = dob_requires s3db.pr_person_details.place_of_birth.requires = IS_NOT_EMPTY( error_message=T("Please enter a place of birth")) # Disable unneeded physical details pdtable = s3db.pr_physical_description hide_fields = [ "race", "complexion", "height", "weight", "hair_length", "hair_style", "hair_baldness", "hair_comment", "facial_hair_type", "facial_hair_length", "facial_hair_color", "facial_hair_comment", "body_hair", "skin_marks", "medical_conditions" ] for fname in hide_fields: field = pdtable[fname] field.readable = field.writable = False # This set is suitable for Italy ethnicity_opts = ( "Italian", "Chinese", "Albanese", "Philippine", "Pakistani", "English", "African", "Other", "Unknown", ) ethnicity_opts = dict((v, T(v)) for v in ethnicity_opts) ethnicity = pdtable.ethnicity ethnicity.requires = IS_EMPTY_OR(IS_IN_SET(ethnicity_opts, sort=True)) ethnicity.represent = S3Represent(options=ethnicity_opts, translate=True) # Enable place of birth place_of_birth = s3db.pr_person_details.place_of_birth place_of_birth.readable = place_of_birth.writable = True
def __init__(self): T = current.T self.db_options = [ Field("uri", "string", notnull=True, default="sqlite://movuca.sqlite"), Field("migrate", "boolean", notnull=True, default=True), Field("migrate_enabled", "boolean", notnull=True, default=True), Field("pool_size", "integer", notnull=True, default=10), Field("gaeuri", "string", notnull=True, default="google:datastore"), Field("setuptime", "datetime", notnull=True), ] self.mail_options = [ Field("server", "string", notnull=True, default="logging"), Field("sender", "string", notnull=True, default="*****@*****.**"), Field("login", "string", notnull=True, default="teste:1234"), Field("setuptime", "datetime", notnull=True), ] self.auth_options = [ Field("formstyle", "string", notnull=True, default="divs"), Field("photo_source", "list:string", notnull=True, default=[ "1:upload", "2:gravatar", "3:facebook", "4:twitter", "5:no photo" ]), Field("gender", "list:string", notnull=True, default=[ "Male:Male", "Female:Female", "Not specified:Not specified" ]), Field("privacy", "list:string", notnull=True, default=[ "1:Public", "2:Visible only for contacts", "3:Private" ]), Field("use_facebook", "boolean", notnull=True, default=False), Field("facebook", "list:string", notnull=True, default=[ "id:133622423420992", "secret:6b0880726a21a89dfcb07c19c7807817", "admins:1766038844" ]), Field("use_recaptcha", "boolean", notnull=True, default=False), Field("recaptcha", "list:string", notnull=True, default=[ "public:6Ld9QswSAAAAAN1DlVBEOxFkMGsFytzSZ54v1nur", "private:6Ld9QswSAAAAAIzXZXJQmxKKaDS5AMrCA1Cnq5ut", "theme:clean", "lang:en" ]), Field("use_mailhide", "boolean", notnull=True, default=False), Field("mailhide", "list:string", notnull=True, default=[ "public:01_qmBPgGX5nvV1rYv_bxK4A==", "private:37565e87d8f80bd680afbc31e0d4e3df" ]), Field("registration_requires_verification", "boolean", notnull=True, default=False), Field("registration_requires_approval", "boolean", notnull=True, default=False), Field("server", "string", notnull=True, default="default"), Field("sender", "string", notnull=True, default="*****@*****.**"), Field("login", "string", notnull=True, default="teste:1234"), Field("setuptime", "datetime", notnull=True), ] self.crud_options = [ Field("formstyle", "string", notnull=True, default="divs"), Field("setuptime", "datetime", notnull=True), ] self.theme_options = [ Field("name", "string", notnull=True, default="basic"), Field("setuptime", "datetime", notnull=True), ] self.article_options = [ Field("license", "list:string", notnull=True, default=[ "1:All rights reserved", "2:Public domain", "3:Creative Commons" ]), Field("setuptime", "datetime", notnull=True), ] self.meta_options = [ Field("title", "string", notnull=True, default="Movuca"), Field("subtitle", "string", notnull=True, default="Free Social CMS Engine"), Field("author", "string", notnull=True, default="Bruno Cezar Rocha at blouweb.com"), Field("keywords", "string", notnull=True, default="web2py, python, cms, social network, CMS"), Field( "description", "string", notnull=True, default= "Free Social CMS Engine built with web2py and Python by blouweb.com" ), Field("generator", "string", notnull=True, default="web2py, Python, Movuca CMS"), Field("copyright", "string", notnull=True, default="Free"), Field("setuptime", "datetime", notnull=True), ] comment_systems = [ ('internal', T("Internal comments")), ('disqus', T("Disqus")), ('intense', T("Intense Debate")), ('facebook', T("Facebook comments")), ] self.comment_options = [ Field("system", "string", requires=IS_IN_SET([comment_systems]), notnull=True, default="internal"), Field("anonymous", "boolean", notnull=True, default=False), Field("disqus_shortname", "string", notnull=True, default="movuca"), Field("disqus_developer", "integer", notnull=True, default=1), Field("intense_acct", "string", notnull=True, default="fe83a2e2af975dd1095a8e4e9ebe1902"), Field("facebook_appid", "string", notnull=True, default="257838757587678"), Field("facebook_numposts", "integer", notnull=True, default=10), Field("setuptime", "datetime", notnull=True), ]
def reports(): response.subtitle = T("Report templates") response.view = 'nas/reports.html' response.cmd_back = ui.control.get_mobil_button( label=T("Account"), href=URL("account", **{'user_signature': True}), icon="back", ajax="false", theme="a", mini="true") nas_reports = ntool.getReportFiles( os.path.join(ns.request.folder, 'static/resources/report')) frm_filter = SQLFORM.factory( Field('database', db.databases, requires=IS_IN_DB(db((db.databases.deleted == False)), db.databases.id, '%(alias)s'), label=T('Database')), Field('reptype', "string", label=T('Rep.type'), requires=IS_EMPTY_OR(IS_IN_SET(nas_reports["types"]))), Field('label', "string", label=T('Group'), requires=IS_EMPTY_OR(IS_IN_SET(nas_reports["labels"]))), Field('repname', type='string', length=50, label=T('Name/Description')), Field('install', type='boolean', label=T('Installed')), submit_button=T("Load"), table_name="filter", _id="frm_filter") if request.post_vars.has_key("report_labels"): if ns.local.setEngine( database=db.databases(id=request.post_vars["database"]).alias, check_ndi=False, created=False, createdb=False): for label_id in request.post_vars.keys(): if label_id not in ("report_labels", "database"): row_id = ns.connect.updateData( "ui_message", values={ "id": label_id, "msg": request.post_vars[label_id] }, validate=False, insert_row=False) if not row_id: response.flash = str(ns.error_message) ns.db.commit() if session.frm_filter: frm_filter.vars = session.frm_filter else: response.flash = str(ns.error_message) if request.post_vars.has_key("ins_cmd"): if ns.local.setEngine(database=db.databases( id=request.post_vars["ins_database"]).alias, check_ndi=False, created=False, createdb=False): if request.post_vars["ins_cmd"] == "delete": try: report_id = ns.db.ui_report( reportkey=request.post_vars["ins_reportkey"])["id"] ns.db( ns.db.ui_reportfields.report_id == report_id).delete() ns.db(ns.db.ui_reportsources.report_id == report_id).delete() ns.db((ns.db.ui_message.secname.like( request.post_vars["ins_reportkey"] + "%"))).delete() ns.db(ns.db.ui_report.id == report_id).delete() ns.db.commit() except Exception, err: response.flash = str(err) else: load = dbtool.loadReport( fileName=request.post_vars["ins_reportkey"] + ".xml") if load != "OK": response.flash = load if session.frm_filter: frm_filter.vars = session.frm_filter else: response.flash = str(ns.error_message)
def custom_prep(r): # Call standard prep if callable(standard_prep): result = standard_prep(r) else: result = True if r.component_name == "appraisal": atable = r.component.table # Organisation needs to be an NS ns_only( atable.organisation_id, required=True, branches=False, ) field = atable.supervisor_id field.readable = field.writable = False field = atable.job_title_id field.comment = None field.label = T("Sector") from s3.s3validators import IS_ONE_OF field.requires = IS_ONE_OF( db, "hrm_job_title.id", field.represent, filterby="type", filter_opts=(4, ), ) if vnrc: if r.component_name == "address": settings.gis.building_name = False settings.gis.latlon_selector = False settings.gis.map_selector = False settings.gis.postcode_selector = False elif r.component_name == "identity": table = s3db.pr_identity table.description.readable = False table.description.writable = False pr_id_type_opts = { 1: T("Passport"), 2: T("National ID Card"), } from gluon.validators import IS_IN_SET table.type.requires = IS_IN_SET(pr_id_type_opts, zero=None) elif r.method == "cv" or r.component_name == "experience": table = s3db.hrm_experience # Use simple free-text variants table.organisation.readable = True table.organisation.writable = True table.job_title.readable = True table.job_title.writable = True table.comments.label = T("Main Duties") crud_form = S3SQLCustomForm( "organisation", "job_title", "comments", "start_date", "end_date", ) s3db.configure( "hrm_experience", crud_form=crud_form, list_fields=[ "id", "organisation", "job_title", "comments", "start_date", "end_date", ], ) return result
def customise_pr_person_resource(r, tablename): T = current.T s3db = current.s3db table = r.resource.table # Disallow "unknown" gender and defaults to "male" evr_gender_opts = dict( (k, v) for k, v in s3db.pr_gender_opts.items() if k in (2, 3)) gender = table.gender gender.requires = IS_IN_SET(evr_gender_opts, zero=None) gender.default = 3 if r.controller == "evr": # Hide evacuees emergency contacts current.deployment_settings.pr.show_emergency_contacts = False # Last name and date of birth mandatory in EVR module table.last_name.requires = IS_NOT_EMPTY( error_message=T("Please enter a last name")) dob_requires = s3_date("dob", future=0, past=1320, empty=False).requires dob_requires.error_message = T("Please enter a date of birth") table.date_of_birth.requires = dob_requires # Enable Location_id from gluon import DIV from s3 import S3LocationSelector location_id = table.location_id location_id.readable = location_id.writable = True location_id.label = T("Place of Birth") levels = ( "L1", "L2", "L3", ) location_id.widget = S3LocationSelector( levels=levels, lines=True, ) location_id.represent = s3db.gis_LocationRepresent(sep=" | ") # Enable place of birth place_of_birth = s3db.pr_person_details.place_of_birth place_of_birth.label = "Specify a Different Place of Birth" place_of_birth.comment = DIV( _class="tooltip", _title="%s|%s" % (T("Different Place of Birth"), T("Specify a different place of birth (foreign country, village, hamlet)" ))) place_of_birth.readable = place_of_birth.writable = True # Disable religion selection s3db.pr_person_details.religion.readable = False s3db.pr_person_details.religion.writable = False # Disable unneeded physical details pdtable = s3db.pr_physical_description hide_fields = [ "race", "complexion", "height", "weight", "hair_length", "hair_style", "hair_baldness", "hair_comment", "facial_hair_type", "facial_hair_length", "facial_hair_color", "facial_hair_comment", "body_hair", "skin_marks", "medical_conditions" ] for fname in hide_fields: field = pdtable[fname] field.readable = field.writable = False # This set is suitable for Italy ethnicity_opts = ( "Italian", "Chinese", "Albanese", "Philippine", "Pakistani", "English", "African", "Other", "Unknown", ) ethnicity_opts = dict((v, T(v)) for v in ethnicity_opts) ethnicity = pdtable.ethnicity ethnicity.requires = IS_EMPTY_OR(IS_IN_SET(ethnicity_opts, sort=True)) ethnicity.represent = S3Represent(options=ethnicity_opts, translate=True)
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 huella(id_reg, user_code, datetime, bkp_type, type_code): salida = (str(id_reg) + str(user_code) + str(datetime.isoformat()) + str(bkp_type) + str(type_code)) return salida # actualizo marcadas def actualizo_marcadas(): marcadas = marcadas_tunel_latix() for registro in marcadas: huellagen = huella(registro[0], registro[1], registro[2], registro[3], registro[4]) marcada = {