def parse_item(self, item): ep = Storage() title_and_size = re.search(r'alt="([^"]*)" class="epinfo"',item) if not title_and_size: return None title_and_size = title_and_size.group(1) size = re.search(r'\(([^)]*)\)$', title_and_size) if size: size = size.group(0).replace('(', '').replace(')', '').strip() if 'MB' in size: size = size.replace('MB', '') multiplier = 1024 elif 'GB' in size: size = size.replace('GB', '') multiplier = 1024*1024 try: size = float(size.strip())*multiplier except: size = 300*1024*1024 else: size = 300*1024*1024 ep.title = title_and_size.rsplit('(', 1)[0] info = self.parse_title(ep.title) ep.update(info) magnet = re.search(r'href="magnet:\?xt([^"]*)"', item) if magnet: ep.magnet = 'magnet:?xt%s' % magnet.groups(1) ep.filename = ep.title ep.pubdate = datetime.datetime.utcnow() ep.filterwith = ep.title ep.size = size * 1024 ep.guid = ep.magnet return ep
def index(): C = Storage() C.escuela = db.escuela(1) menu_migas.append(T("Tipos de pagos")) C.titulo = T("Registro de tipos de pago") # permisos puede_editar = auth.has_membership(role=myconf.take('roles.admin')) # puede_borrar = auth.has_membership(role=myconf.take('roles.admin')) puede_crear = auth.has_membership(role=myconf.take('roles.admin')) tbl = db.tipo_pago query = (tbl.id > 0) tbl.id.readable = False if 'edit' in request.args: tbl.nombre.writable = False text_lengths = {'tipo_pago.nombre': 50} C.grid = grid_simple(query, maxtextlengths=text_lengths, create=puede_crear, editable=puede_editar) return dict(C=C)
def show_responsibles(): oprofesor = obies.Profesor(db, session) profesores = oprofesor.dame_profesores_curso() responsables = [] for profesor in profesores: #comprobemos si el usuario existe en la tabla auth_user usuario = db(db.auth_user.username == profesor.profesor.usuario_rayuela).select(db.auth_user.ALL).first() if usuario: db(db.auth_user.id==usuario.id).select().first().update_record(first_name=profesor.profesor.nombre, last_name=profesor.profesor.apellidos) if auth.has_membership(role = 'Responsables', user_id = usuario.id): usu = Storage(usuario.as_dict()) usua = db(usuario.username == db.profesor.usuario_rayuela).select(db.profesor.ALL).first() usu.idprofesor = usua.id responsables.append(usu) else: #no existe usuario autentificación asociado al profesor id = db.auth_user.insert(username=profesor.profesor.usuario_rayuela, first_name=profesor.profesor.nombre, last_name=profesor.profesor.apellidos) auth.add_membership(role = 'Profesores', user_id = id) form = FORM(TABLE(TR(T('Teacher')+':', SELECT(_name='profe', *[OPTION(p.profesor.apellidos+', '+p.profesor.nombre, _value=p.profesor.usuario_rayuela) for p in profesores])), TR("", INPUT(_type="submit",_value=T("Add responsible"))))) if form.accepts(request.vars, session): #debemos insertar al profesor en el grupo responsables usuario = db(db.auth_user.username==form.vars.profe).select(db.auth_user.id).first() if auth.has_membership(user_id=usuario, role='Responsables'): session.flash = T('Responsible already defined') else: auth.add_membership(role='Responsables', user_id=usuario) session.flash = T('new responsible inserted') redirect(URL('show_responsibles')) return dict(form=form, responsables=responsables)
def phylogramConfig( session ): """ This function returns the 'phylogram' renderType default config. 'phylogram' is a little of a misnomer, its simply the initial way this application rendered a tree using svg and raphael.js """ config = Storage( verticalTipBuffer = 20, branchLength = 20, branchLengthStyle = 'smooth', scaledBranchMultiplier = 0, maxTips = 50, verticalPadding = 50, horizontalPadding = 50, tipLabelBuffer = 5, treeColor = 'black', pathWidth = 3, collapsedCladeColor = 'grey', nonTipLabelBuffer = -5, nodeSelectorRadius = 5, nodeSelectorColor = 'blue' ) if( session.TreeViewer.type == 'grafted' ): config.primaryShowEditColor = 'red' config.secondaryShowEditColor = 'blue' config.tertiaryShowEditColor = 'yellow' return config
def index(): """Carga la UI para la realización de los pagos""" C = Storage() C.evento = db.evento(request.args(0)) C.persona = db.persona(request.args(1)) return dict(C=C)
def url(self, extension=None, **kwargs): """ Return the target URL for this item, doesn't check permissions @param extension: override the format extension @param kwargs: override URL query vars """ if not self.link: return None args = self.args if self.vars: vars = Storage(self.vars) vars.update(kwargs) else: vars = Storage(kwargs) if extension is None: extension = self.extension a = self.get("application") if a is None: a = current.request.application c = self.get("controller") if c is None: c = "default" f = self.get("function") if f is None: f = "index" f, args = self.__format(f, args, extension) return URL(a=a, c=c, f=f, args=args, vars=vars)
def wiki(): wiki = auth.shotwiki() wiki_ctrl = Storage() if str(request.args(0)).startswith('_'): wiki_ctrl.cmd = request.args(0) wiki_ctrl.slug = request.args(1) wiki_ctrl.render = auth.get_wiki_rendering(wiki_ctrl.slug ) response.flash_custom_display = True # hide default wiki flash messages else: wiki_ctrl.slug = request.args(0) if wiki_ctrl.slug == 'start': if config.display_flash_schedule: response.flash = auth.get_shotwiki_page(slug_base = 'market-schedule') if str(request.args(0)) != '_preview': wiki['wiki_ctrl'] = wiki_ctrl if wiki_ctrl.slug and str.lower(wiki_ctrl.slug) == 'zwillingsmarkt': #response.b_noindex = True redirect(URL('main','wiki', args = ['start'])) return wiki
def testMobilePhoneNumberValidationInternational(self): """ Test that validator for mobile phone number is applied """ current.deployment_settings \ .msg.require_international_phone_numbers = True from s3db.pr import PRContactModel onvalidation = PRContactModel.pr_contact_onvalidation form = Storage( vars = Storage( contact_method = "SMS", ) ) # valid form.errors = Storage() form.vars.value = "+46-73-3847589" onvalidation(form) self.assertEqual(form.vars.value, "+46733847589") self.assertFalse("value" in form.errors) # invalid form.errors = Storage() form.vars.value = "0368172634" onvalidation(form) self.assertEqual(form.vars.value, "0368172634") self.assertTrue("value" in form.errors)
def accessible_url(self, extension=None, **kwargs): """ Return the target URL for this item if accessible by the current user, otherwise False @param extension: override the format extension @param kwargs: override URL query vars """ auth = current.auth aURL = auth.permission.accessible_url if not self.link: return None args = self.args if self.vars: vars = Storage(self.vars) vars.update(kwargs) else: vars = Storage(kwargs) if extension is None: extension = self.extension a = self.get("application") if a is None: a = current.request.application c = self.get("controller") if c is None: c = "default" f = self.get("function") if f is None: f = "index" p = self.p f, args = self.__format(f, args, extension) return aURL(p=p, a=a, c=c, f=f, args=args, vars=vars)
def draw(self, output="xml"): """ Output the chart as a PNG embedded in an IMG tag - used by the Delphi module """ fig = self.fig if not fig: return "Matplotlib not installed" # For interactive shell tests #plt.show() # For web response #savefig(response.body) chart = Storage() chart.body = StringIO() chart.headers = Storage() chart.headers["Content-Type"] = "image/png" canvas = self.FigureCanvas(fig) canvas.print_figure(chart.body) #return response.body.getvalue() image = chart.body.getvalue() if output == "xml": base64Img = base64.b64encode(image) image = IMG(_src="data:image/png;base64,%s" % base64Img) else: current.response.headers["Content-Type"] = "image/png" return image
def select(self): if self.op == 'eq' and self.field == 'id' and self.value: #means that someone wants to retrieve the key self.value rtn = self.db.hgetall("%s:%s" % (self.keyprefix, self.value)) if rtn == dict(): #return an empty resultset for non existing key return [] else: return [Storage(rtn)] elif self.op == 'ge' and self.field == 'id' and self.value == 0: #means that someone wants the complete list rtn = [] id_idx = "%s:id_idx" % self.keyprefix #find all session keys of this app allkeys = self.db.smembers(id_idx) for sess in allkeys: val = self.db.hgetall(sess) if val == dict(): if self.session_expiry: #clean up the idx, because the key expired self.db.srem(id_idx, sess) continue else: continue val = Storage(val) #add a delete_record method (necessary for sessions2trash.py) val.delete_record = RecordDeleter( self.db, sess, self.keyprefix) rtn.append(val) return rtn else: raise Exception("Operation not supported")
def select(self): if self.op == 'eq' and self.field == 'id' and self.value: #means that someone wants to retrieve the key self.value key = self.keyprefix + ':' + str(self.value) if self.with_lock: acquire_lock(self.db, key + ':lock', self.value) rtn = self.db.hgetall(key) rtn['update_record'] = self.update # update record support return [Storage(rtn)] if rtn else [] elif self.op == 'ge' and self.field == 'id' and self.value == 0: #means that someone wants the complete list rtn = [] id_idx = "%s:id_idx" % self.keyprefix #find all session keys of this app allkeys = self.db.smembers(id_idx) for sess in allkeys: val = self.db.hgetall(sess) if not val: if self.session_expiry: #clean up the idx, because the key expired self.db.srem(id_idx, sess) continue val = Storage(val) #add a delete_record method (necessary for sessions2trash.py) val.delete_record = RecordDeleter( self.db, sess, self.keyprefix) rtn.append(val) return rtn else: raise Exception("Operation not supported")
def __call__(self, name=None, **attr): if not name: name = self.name ia = Storage(self.attr) if attr: if not attr.get("empty", True): requires = ia.requires if requires: if not isinstance(requires, (list, tuple)): requires = [requires] if requires: r = requires[0] if isinstance(r, IS_EMPTY_OR): requires = r.other ia.update(requires=requires) if "empty" in attr: del attr["empty"] ia.update(**attr) if ia.sortby is not None: return FieldS3(name, self.__type, **ia) else: return Field(name, self.__type, **ia)
def s3_lx_update(table, record_id): """ Write the Lx fields from the Location - used by hrm_human_resource & pr_address @ToDo: Allow the reverse operation. If these fields are populated then create/update the location """ if "location_id" in table: db = current.db ltable = current.s3db.gis_location query = (table.id == record_id) & (ltable.id == table.location_id) location = ( db(query).select(ltable.id, ltable.name, ltable.level, ltable.parent, ltable.path, limitby=(0, 1)).first() ) if location: vars = Storage() if location.level == "L0": vars.L0 = location.name elif location.level == "L1": vars.L1 = location.name if location.parent: query = ltable.id == location.parent country = db(query).select(ltable.name, limitby=(0, 1)).first() if country: vars.L0 = country.name else: # Get Names of ancestors at each level vars = current.gis.get_parent_per_level(vars, location.id, feature=location, ids=False, names=True) # Update record db(table.id == record_id).update(**vars)
def job_data(self): """Return the data representing job to be queued. Returns: Storage: representing job (equivalent to db.job Row.as_dict()) """ db = current.app.db attributes = Storage(dict(self.default_job_options)) if self.job_options: attributes.update(self.job_options) for k in sorted(attributes.keys()): if k not in self.tbl.fields: raise InvalidJobOptionError( 'Invalid job option: {opt}'.format(opt=k)) now = datetime.datetime.now() job_queuer = None if self.class_factory_id: query = (db.job_queuer.code == self.class_factory_id) job_queuer = db(query).select().first() attributes['job_queuer_id'] = job_queuer.id if job_queuer else 0 if 'command' not in attributes: attributes['command'] = self.command() if 'start' not in attributes: attributes['start'] = now if self.delay_seconds: attributes['start'] = attributes['start'] + \ datetime.timedelta(seconds=self.delay_seconds) attributes['queued_time'] = now return attributes
def info(): if not have_uwsgi: return "you aren't running web2py with uwsgi" info = Storage() info.masterpid = uwsgi.masterpid() info.version = uwsgi.version info.started_on = time.ctime(uwsgi.started_on) info.buffer_size = uwsgi.buffer_size info.total_requests = uwsgi.total_requests() info.logsize = uwsgi.logsize() info.numproc = uwsgi.numproc try: info.mode = uwsgi.mode except: pass try: info.pidfile = uwsgi.pidfile except: pass workers = uwsgi.workers() total_load = time.time() - uwsgi.started_on for w in workers: w['load'] = (100 * (w['running_time']/1000))/total_load w['last_spawn_str'] = time.ctime(w['last_spawn']) w['vsz_str'] = do_filesizeformat(w['vsz']) w['rss_str'] = do_filesizeformat(w['rss']) context = dict(info=info, workers=workers) template = template_view('info') return response.render(template, context)
def testTypeConversionFeature(self): """ Check that values get converted into the field type during validation """ s3db = current.s3db # Create a fake request resource = s3db.resource("project_organisation") request = Storage(prefix="project", name="organisation", resource=resource, table=resource.table, tablename=resource.tablename, method="validate", get_vars=Storage(), representation="json", http="GET") crud = resource.crud jsonstr = """{"organisation_id":"1", "role":"1"}""" request.body = StringIO(jsonstr) output = crud.validate(request) self.assertTrue(isinstance(output, basestring)) from gluon.contrib import simplejson as json data = json.loads(output) self.assertTrue(isinstance(data, dict)) self.assertEqual(len(data), 2) self.assertTrue("role" in data) role = data["role"] self.assertTrue(isinstance(role, dict)) self.assertTrue("value" in role) self.assertTrue(isinstance(role["value"], int))
def test__set_port(self): port_1 = '1111' port_2 = '2222' port_3 = '3333' local_mysql = LocalMySQL(port=port_1) self.assertTrue(local_mysql.port, port_1) # Provided port is used save_env_port = os.environ.get('MYSQL_TCP_PORT') del os.environ['MYSQL_TCP_PORT'] local_mysql = LocalMySQL() # No port, no http env var, no uses env var, not set self.assertFalse(local_mysql.port) os.environ['MYSQL_TCP_PORT'] = port_2 local_mysql = LocalMySQL() # No port, no http env var, uses env var self.assertTrue(local_mysql.port, port_2) request = Storage() request.env = Storage() request.env.web2py_mysql_tcp_port = port_3 local_mysql = LocalMySQL() self.assertTrue(local_mysql.port, port_3) # No port, uses http env var os.environ['MYSQL_TCP_PORT'] = save_env_port return
def carreras_me(): C = Storage() C.escuela = db.escuela(1) menu_migas.append(T("Descripciones de carreras")) tbl = db.descripcion_carrera query = (tbl.id > 0) tbl.id.readable = False text_lengths = {'descripcion_carrera.nombre': 50} C.titulo = T("Registro de carreras del Ministerio de Educación") puede_editar = auth.has_membership(role=myconf.take('roles.admin')) # puede_borrar = auth.has_membership(role=myconf.take('roles.admin')) puede_crear = auth.has_membership(role=myconf.take('roles.admin')) C.grid = grid_simple(query, editable=puede_editar, create=puede_crear, maxtextlengths=text_lengths, orderby=[tbl.nombre], args=request.args[:1]) return dict(C=C)
def historial(): C = Storage() C.escuela = db.escuela(1) menu_migas.append(T("Control de cambios")) tbl_n = request.args(0) r_id = int(request.args(1)) C.titulo = T("Historial de cambios TABLA: {} REGISTRO ID: {}").format(tbl_n, r_id) tbl = db["{}_archive".format(tbl_n)] query = (tbl.current_record == r_id) for f in tbl: f.readable = True tbl.current_record.readable = False C.current_record = SQLTABLE(db(db[tbl_n].id == r_id).select(), headers="labels", _class="table") C.grid = SQLFORM.grid(query, args=request.args[:2], orderby=[~tbl.modified_on], create=False, searchable=False, editable=False, deletable=False, details=False, csv=False) return dict(C=C)
def asignaturas(): '''registro general de asigaturas''' C = Storage() C.escuela = db.escuela(1) menu_migas.append(T("Registro de asignaturas")) # -- construir el grid tbl = db.asignatura query = (tbl.id > 0) # permisos puede_crear = auth.has_membership(role=myconf.take('roles.admin')) puede_editar, puede_borrar = (puede_crear, puede_crear) tbl.id.readable = False text_lengths = {'asignatura.nombre': 50} C.grid = grid_simple(query, create=puede_crear, editable=puede_editar, maxtextlengths=text_lengths, deletable=puede_borrar) return dict(C=C)
def labels(): """ args: [items] vars: [id_purchase, id_layout] """ expiration_redirect() from_purchase = False page_layout = None if request.vars.id_layout: page_layout = db.labels_page_layout(request.vars.id_layout) else: page_layout = db(db.labels_page_layout).select().first() if not page_layout: redirect(URL('labels_page_layout', 'index')) layout = Storage({ 'id': page_layout.id, 'width': page_layout.id_paper_size.width, 'height': page_layout.id_paper_size.height, 'margin_top': page_layout.margin_top, 'margin_right': page_layout.margin_right, 'margin_bottom': page_layout.margin_bottom, 'margin_left': page_layout.margin_left, 'space_x': page_layout.space_x or 0, 'space_y': page_layout.space_y or 0, 'cols': page_layout.label_cols, 'rows': page_layout.label_rows, 'show_item_name': page_layout.show_name, 'show_price': page_layout.show_price }) layout.label_width = (layout.width - (layout.margin_left + layout.margin_right + layout.space_x * (layout.cols - 1))) / layout.cols layout.label_height = (layout.height - (layout.margin_top + layout.margin_bottom + layout.space_y * (layout.rows - 1))) / layout.rows if request.vars.id_purchase and request.vars.id_purchase != 'None': from_purchase = True purchase = db((db.purchase.id == request.vars.id_purchase) & (db.purchase.is_done == True)).select().first() if not purchase: raise HTTP(404) purchase_items = db( db.stock_item.id_purchase == purchase.id ).iterselect() if not purchase_items: raise HTTP(404) return dict(items=purchase_items, layout=layout) if request.args: items_ids = request.args(0).split('_') query = (db.item.id < 0) for item_id in items_ids: query |= (db.item.id == int(item_id)) items = db( (query) & (db.item.is_active == True) ).select() return dict(items=items, layout=layout) redirect(URL('default', 'index'))
def test_URL(self): self.assertEqual(URL('a', 'c', 'f', args='1'), '/a/c/f/1') self.assertEqual(URL('a', 'c', 'f', args=('1', '2')), '/a/c/f/1/2') self.assertEqual(URL('a', 'c', 'f', args=['1', '2']), '/a/c/f/1/2') self.assertEqual(URL('a', 'c', '/f'), '/a/c/f') self.assertEqual(URL('a', 'c', 'f.json'), '/a/c/f.json') from gluon.globals import current current.request = None self.assertRaises(SyntaxError, URL, *['a']) request = Storage() request.application = 'a' request.controller = 'c' request.function = 'f' request.env = {} from gluon.globals import current # Can't be moved with other import current.request = request must_return = '/a/c/f' self.assertEqual(URL(), must_return) self.assertEqual(URL('f'), must_return) self.assertEqual(URL('c', 'f'), must_return) self.assertEqual(URL('a', 'c', 'f'), must_return) self.assertEqual(URL('a', 'c', 'f', extension='json'), '/a/c/f.json') def weird(): pass self.assertEqual(URL('a', 'c', weird), '/a/c/weird') self.assertRaises(SyntaxError, URL, *['a', 'c', 1]) # test signature rtn = URL(a='a', c='c', f='f', args=['x', 'y', 'z'], vars={'p': (1, 3), 'q': 2}, anchor='1', hmac_key='key') self.assertEqual(rtn, '/a/c/f/x/y/z?p=1&p=3&q=2&_signature=a32530f0d0caa80964bb92aad2bedf8a4486a31f#1') # test _signature exclusion rtn = URL(a='a', c='c', f='f', args=['x', 'y', 'z'], vars={'p': (1, 3), 'q': 2, '_signature': 'abc'}, anchor='1', hmac_key='key') self.assertEqual(rtn, '/a/c/f/x/y/z?p=1&p=3&q=2&_signature=a32530f0d0caa80964bb92aad2bedf8a4486a31f#1') # emulate user_signature current.session = Storage(auth=Storage(hmac_key='key')) self.assertEqual(URL(user_signature=True), '/a/c/f?_signature=c4aed53c08cff08f369dbf8b5ba51889430cf2c2') # hash_vars combination rtn = URL('a', 'c', 'f', args=['x', 'y', 'z'], vars={'p': (1, 3), 'q': 2}, hmac_key='key') self.assertEqual(rtn, '/a/c/f/x/y/z?p=1&p=3&q=2&_signature=a32530f0d0caa80964bb92aad2bedf8a4486a31f') rtn = URL('a', 'c', 'f', args=['x', 'y', 'z'], vars={'p': (1, 3), 'q': 2}, hmac_key='key', hash_vars=True) self.assertEqual(rtn, '/a/c/f/x/y/z?p=1&p=3&q=2&_signature=a32530f0d0caa80964bb92aad2bedf8a4486a31f') rtn = URL('a', 'c', 'f', args=['x', 'y', 'z'], vars={'p': (1, 3), 'q': 2}, hmac_key='key', hash_vars=False) self.assertEqual(rtn, '/a/c/f/x/y/z?p=1&p=3&q=2&_signature=0b5a0702039992aad23c82794b8496e5dcd59a5b') rtn = URL('a', 'c', 'f', args=['x', 'y', 'z'], vars={'p': (1, 3), 'q': 2}, hmac_key='key', hash_vars=['p']) self.assertEqual(rtn, '/a/c/f/x/y/z?p=1&p=3&q=2&_signature=5d01b982fd72b39674b012e0288071034e156d7a') rtn = URL('a', 'c', 'f', args=['x', 'y', 'z'], vars={'p': (1, 3), 'q': 2}, hmac_key='key', hash_vars='p') self.assertEqual(rtn, '/a/c/f/x/y/z?p=1&p=3&q=2&_signature=5d01b982fd72b39674b012e0288071034e156d7a') # test CRLF detection self.assertRaises(SyntaxError, URL, *['a\n', 'c', 'f']) self.assertRaises(SyntaxError, URL, *['a\r', 'c', 'f']) # test url_encode rtn = URL('a', 'c', 'f', args=['x', 'y', 'z'], vars={'maï': (1, 3), 'lié': 2}, url_encode=True) self.assertEqual(rtn, '/a/c/f/x/y/z?li%C3%A9=2&ma%C3%AF=1&ma%C3%AF=3')
def s3_popup_comment(c=None, f=None, t=None, vars=None, label=None, info=None, title=None, tooltip=None): """ Generate a ADD-popup comment, return an empty DIV if the user is not permitted to add records to the referenced table @param c: the target controller @param f: the target function @param t: the target table (defaults to c_f) @param vars: the request vars (format="popup" will be added automatically) @param label: the link label @param info: hover-title for the label @param title: the tooltip title @param tooltip: the tooltip text @todo: replace by S3NavigationItem """ auth = current.auth if title is None: return None if label is None: label = title if info is None: info = title if vars is not None: _vars = Storage(vars) else: _vars = Storage() _vars.update(format="popup") popup = "" ttip = "" if c and f and auth is not None: _href = auth.permission.accessible_url(c=c, f=f, t=t, p="create", args="create", vars=_vars) if _href is not False: popup = A(label, _class="colorbox", _href=_href, _target="top", _title=info) if tooltip is not None: ttip = DIV(_class="tooltip", _title="%s|%s" % (title, tooltip)) comment = DIV(popup, ttip) return comment
def document_onvalidation(form, document=True): """ Form validation for both, documents and images """ form_vars = form.vars doc = form_vars.file if doc is None: # If this is a prepop, then file not in form # Interactive forms with empty doc has this as "" not None return if not document: encoded_file = form_vars.get("imagecrop-data", None) if encoded_file: # S3ImageCropWidget import base64 import uuid metadata, encoded_file = encoded_file.split(",") #filename, datatype, enctype = metadata.split(";") filename = metadata.split(";", 1)[0] f = Storage() f.filename = uuid.uuid4().hex + filename import cStringIO f.file = cStringIO.StringIO(base64.decodestring(encoded_file)) doc = form_vars.file = f if not form_vars.name: form_vars.name = filename if not hasattr(doc, "file"): # Record update without new file upload => keep existing record_id = current.request.post_vars.id if record_id: db = current.db if document: tablename = "doc_document" else: tablename = "doc_image" table = db[tablename] record = db(table.id == record_id).select(table.file, limitby = (0, 1), ).first() if record: doc = record.file if not hasattr(doc, "file") and not doc and not form_vars.url: if document: msg = current.T("Either file upload or document URL required.") else: msg = current.T("Either file upload or image URL required.") if "file" in form_vars: form.errors.file = msg if "url" in form_vars: form.errors.url = msg if hasattr(doc, "file"): name = form_vars.name if not name: # Use filename as document/image title form_vars.name = doc.filename
def __init__( self, db=None, tablename='web2py_ticket' ): Storage.__init__(self) self.db = db self.tablename = tablename
def test_getlist(self): # usually used with request.vars a = Storage() a.x = 'abc' a.y = ['abc', 'def'] self.assertEqual(a.getlist('x'), ['abc']) self.assertEqual(a.getlist('y'), ['abc', 'def']) self.assertEqual(a.getlist('z'), [])
def test_getlast(self): # usually with request.vars a = Storage() a.x = 'abc' a.y = ['abc', 'def'] self.assertEqual(a.getlast('x'), 'abc') self.assertEqual(a.getlast('y'), 'def') self.assertEqual(a.getlast('z'), None)
def member_onaccept(form): """ On-accept for Member records """ db = current.db s3db = current.s3db utable = current.auth.settings.table_user ptable = s3db.pr_person ltable = s3db.pr_person_user mtable = s3db.member_membership # Get the full record id = form.vars.id if id: query = (mtable.id == id) record = db(query).select(mtable.id, mtable.person_id, mtable.organisation_id, mtable.deleted, limitby=(0, 1)).first() else: return data = Storage() # Affiliation s3db.pr_update_affiliations(mtable, record) # Update the location ID from the Home Address atable = s3db.pr_address query = (atable.pe_id == ptable.pe_id) & \ (ptable.id == record.person_id) & \ (atable.type == 1) & \ (atable.deleted == False) address = db(query).select(atable.location_id, limitby=(0, 1)).first() if address: data.location_id = address.location_id # Add record owner (user) query = (ptable.id == record.person_id) & \ (ltable.pe_id == ptable.pe_id) & \ (utable.id == ltable.user_id) user = db(query).select(utable.id, utable.organisation_id, utable.site_id, limitby=(0, 1)).first() if user: user_id = user.id data.owned_by_user = user.id if not data: return record.update_record(**data) if data.location_id: # Populate the Lx fields current.response.s3.lx_update(mtable, record.id)
def user(): from gluon.storage import Storage objects = Storage() if request.args(0) in ['register', 'login']: objects.login = auth.login() objects.register = auth.register() else: objects.form = auth() return dict(objects=objects)
def config(settings): """ Template settings: 'Skeleton' designed to be copied to quickly create custom templates All settings which are to configure a specific template are located here. Deployers should ideally not need to edit any other files outside of their template folder. """ T = current.T #settings.base.system_name = T("Sahana Skeleton") #settings.base.system_name_short = T("Sahana") # PrePopulate data settings.base.prepopulate = ("skeleton", "default/users") # Theme (folder to use for views/layout.html) settings.base.theme = "skeleton" # Authentication settings # Should users be allowed to register themselves? #settings.security.self_registration = False # Do new users need to verify their email address? #settings.auth.registration_requires_verification = True # Do new users need to be approved by an administrator prior to being able to login? #settings.auth.registration_requires_approval = True #settings.auth.registration_requests_organisation = True # Approval emails get sent to all admins settings.mail.approver = "ADMIN" # Restrict the Location Selector to just certain countries # NB This can also be over-ridden for specific contexts later # e.g. Activities filtered to those of parent Project #settings.gis.countries = ("US",) # Uncomment to display the Map Legend as a floating DIV settings.gis.legend = "float" # Uncomment to Disable the Postcode selector in the LocationSelector #settings.gis.postcode_selector = False # @ToDo: Vary by country (include in the gis_config!) # Uncomment to show the Print control: # http://eden.sahanafoundation.org/wiki/UserGuidelines/Admin/MapPrinting #settings.gis.print_button = True # L10n settings # Languages used in the deployment (used for Language Toolbar & GIS Locations) # http://www.loc.gov/standards/iso639-2/php/code_list.php #settings.L10n.languages = OrderedDict([ # ("ar", "العربية"), # ("bs", "Bosanski"), # ("en", "English"), # ("fr", "Français"), # ("de", "Deutsch"), # ("el", "ελληνικά"), # ("es", "Español"), # ("it", "Italiano"), # ("ja", "日本語"), # ("km", "ភាសាខ្មែរ"), # ("ko", "한국어"), # ("ne", "नेपाली"), # Nepali # ("prs", "دری"), # Dari # ("ps", "پښتو"), # Pashto # ("pt", "Português"), # ("pt-br", "Português (Brasil)"), # ("ru", "русский"), # ("tet", "Tetum"), # ("tl", "Tagalog"), # ("tr", "Türkçe"), # ("ur", "اردو"), # ("vi", "Tiếng Việt"), # ("zh-cn", "中文 (简体)"), # ("zh-tw", "中文 (繁體)"), #]) # Default language for Language Toolbar (& GIS Locations in future) #settings.L10n.default_language = "en" # Uncomment to Hide the language toolbar #settings.L10n.display_toolbar = False # Default timezone for users #settings.L10n.utc_offset = "UTC +0100" # Number formats (defaults to ISO 31-0) # Decimal separator for numbers (defaults to ,) settings.L10n.decimal_separator = "." # Thousands separator for numbers (defaults to space) settings.L10n.thousands_separator = "," # Uncomment this to Translate Layer Names #settings.L10n.translate_gis_layer = True # Uncomment this to Translate Location Names #settings.L10n.translate_gis_location = True # Uncomment this to Translate Organisation Names/Acronyms #settings.L10n.translate_org_organisation = True # Finance settings #settings.fin.currencies = { # "EUR" : T("Euros"), # "GBP" : T("Great British Pounds"), # "USD" : T("United States Dollars"), #} #settings.fin.currency_default = "USD" # Security Policy # http://eden.sahanafoundation.org/wiki/S3AAA#System-widePolicy # 1: Simple (default): Global as Reader, Authenticated as Editor # 2: Editor role required for Update/Delete, unless record owned by session # 3: Apply Controller ACLs # 4: Apply both Controller & Function ACLs # 5: Apply Controller, Function & Table ACLs # 6: Apply Controller, Function, Table ACLs and Entity Realm # 7: Apply Controller, Function, Table ACLs and Entity Realm + Hierarchy # 8: Apply Controller, Function, Table ACLs, Entity Realm + Hierarchy and Delegations # #settings.security.policy = 7 # Organisation-ACLs # RSS feeds #settings.frontpage.rss = [ # {"title": "Eden", # # Trac timeline # "url": "http://eden.sahanafoundation.org/timeline?ticket=on&changeset=on&milestone=on&wiki=on&max=50&daysback=90&format=rss" # }, # {"title": "Twitter", # # @SahanaFOSS # #"url": "https://search.twitter.com/search.rss?q=from%3ASahanaFOSS" # API v1 deprecated, so doesn't work, need to use 3rd-party service, like: # "url": "http://www.rssitfor.me/getrss?name=@SahanaFOSS" # # Hashtag # #url: "http://search.twitter.com/search.atom?q=%23eqnz" # API v1 deprecated, so doesn't work, need to use 3rd-party service, like: # #url: "http://api2.socialmention.com/search?q=%23eqnz&t=all&f=rss" # } #] # ------------------------------------------------------------------------- # Comment/uncomment modules here to disable/enable them # Modules menu is defined in modules/eden/menu.py settings.modules = OrderedDict([ # Core modules which shouldn't be disabled ("default", Storage( name_nice = T("Home"), restricted = False, # Use ACLs to control access to this module access = None, # All Users (inc Anonymous) can see this module in the default menu & access the controller module_type = None # This item is not shown in the menu )), ("admin", Storage( name_nice = T("Administration"), #description = "Site Administration", restricted = True, access = "|1|", # Only Administrators can see this module in the default menu & access the controller module_type = None # This item is handled separately for the menu )), ("appadmin", Storage( name_nice = T("Administration"), #description = "Site Administration", restricted = True, module_type = None # No Menu )), ("errors", Storage( name_nice = T("Ticket Viewer"), #description = "Needed for Breadcrumbs", restricted = False, module_type = None # No Menu )), #("sync", Storage( # name_nice = T("Synchronization"), # #description = "Synchronization", # restricted = True, # access = "|1|", # Only Administrators can see this module in the default menu & access the controller # module_type = None # This item is handled separately for the menu #)), #("tour", Storage( # name_nice = T("Guided Tour Functionality"), # module_type = None, #)), #("translate", Storage( # name_nice = T("Translation Functionality"), # #description = "Selective translation of strings based on module.", # module_type = None, #)), ("gis", Storage( name_nice = T("Map"), #description = "Situation Awareness & Geospatial Analysis", restricted = True, module_type = 6, # 6th item in the menu )), ("pr", Storage( name_nice = T("Person Registry"), #description = "Central point to record details on People", restricted = True, access = "|1|", # Only Administrators can see this module in the default menu (access to controller is possible to all still) module_type = 10 )), ("org", Storage( name_nice = T("Organizations"), #description = 'Lists "who is doing what & where". Allows relief agencies to coordinate their activities', restricted = True, module_type = 1 )), #("hrm", Storage( # name_nice = T("Staff"), # #description = "Human Resources Management", # restricted = True, # module_type = 2, #)), #("vol", Storage( # name_nice = T("Volunteers"), # #description = "Human Resources Management", # restricted = True, # module_type = 2, #)), #("cms", Storage( # name_nice = T("Content Management"), # #description = "Content Management System", # restricted = True, # module_type = 10, #)), #("doc", Storage( # name_nice = T("Documents"), # #description = "A library of digital resources, such as photos, documents and reports", # restricted = True, # module_type = 10, #)), #("msg", Storage( # name_nice = T("Messaging"), # #description = "Sends & Receives Alerts via Email & SMS", # restricted = True, # # The user-visible functionality of this module isn't normally required. Rather it's main purpose is to be accessed from other modules. # module_type = None, #)), #("supply", Storage( # name_nice = T("Supply Chain Management"), # #description = "Used within Inventory Management, Request Management and Asset Management", # restricted = True, # module_type = None, # Not displayed #)), #("inv", Storage( # name_nice = T("Warehouses"), # #description = "Receiving and Sending Items", # restricted = True, # module_type = 4 #)), #("asset", Storage( # name_nice = T("Assets"), # #description = "Recording and Assigning Assets", # restricted = True, # module_type = 5, #)), # Vehicle depends on Assets #("vehicle", Storage( # name_nice = T("Vehicles"), # #description = "Manage Vehicles", # restricted = True, # module_type = 10, #)), #("req", Storage( # name_nice = T("Requests"), # #description = "Manage requests for supplies, assets, staff or other resources. Matches against Inventories where supplies are requested.", # restricted = True, # module_type = 10, #)), #("project", Storage( # name_nice = T("Projects"), # #description = "Tracking of Projects, Activities and Tasks", # restricted = True, # module_type = 2 #)), #("cr", Storage( # name_nice = T("Shelters"), # #description = "Tracks the location, capacity and breakdown of victims in Shelters", # restricted = True, # module_type = 10 #)), #("hms", Storage( # name_nice = T("Hospitals"), # #description = "Helps to monitor status of hospitals", # restricted = True, # module_type = 10 #)), #("dvr", Storage( # name_nice = T("Disaster Victim Registry"), # #description = "Allow affected individuals & households to register to receive compensation and distributions", # restricted = True, # module_type = 10, #)), #("event", Storage( # name_nice = T("Events"), # #description = "Activate Events (e.g. from Scenario templates) for allocation of appropriate Resources (Human, Assets & Facilities).", # restricted = True, # module_type = 10, #)), #("transport", Storage( # name_nice = T("Transport"), # restricted = True, # module_type = 10, #)), #("stats", Storage( # name_nice = T("Statistics"), # #description = "Manages statistics", # restricted = True, # module_type = None, #)), ]) # END =========================================================================
table.purchase_price.readable = table.purchase_price.writable = False table.purchase_currency.readable = table.purchase_currency.writable = False settings.customise_asset_asset_resource = customise_asset_asset_resource # ----------------------------------------------------------------------------- # Comment/uncomment modules here to disable/enable them # Modules menu is defined in modules/eden/menu.py settings.modules = OrderedDict([ # Core modules which shouldn't be disabled ( "default", Storage( name_nice=T("Home"), restricted=False, # Use ACLs to control access to this module access= None, # All Users (inc Anonymous) can see this module in the default menu & access the controller module_type=None # This item is not shown in the menu )), ( "admin", Storage( name_nice=T("Administration"), #description = "Site Administration", restricted=True, access= "|1|", # Only Administrators can see this module in the default menu & access the controller module_type=None # This item is handled separately for the menu )), ( "appadmin",
__author__ = 'smrutim' import socket from gluon.storage import Storage settings = Storage() settings.migrate = True settings.title = 'RIP' settings.subtitle = 'Rest In Peak' settings.author = 'Smruti Mohanty' settings.author_email = '*****@*****.**' settings.app_uri = socket.gethostname() settings.keywords = '' settings.description = '' settings.layout_theme = 'Default' #settings.database_uri = 'postgres://*****:*****@localhost:5432/mydb' settings.database_uri = 'sqlite://storage.sqlite' settings.security_key = 'bb05dd73-42f2-4ad2-a1f7-589476f6a904' settings.email_server = 'smtp.vmware.com' settings.email_sender = '*****@*****.**' settings.email_login = '' settings.login_method = '' settings.login_config = '' settings.plugins = []
def model(self): T = current.T db = current.db request = current.request s3 = current.response.s3 messages = current.messages UNKNOWN_OPT = messages.UNKNOWN_OPT NONE = messages["NONE"] crud_strings = s3.crud_strings define_table = self.define_table add_components = self.add_components configure = self.configure set_method = self.set_method s3_datetime_represent = lambda dt: \ S3DateTime.datetime_represent(dt, utc=True) # ------------------------------------------------------------------------- # Configuration # ------------------------------------------------------------------------- tablename = "sync_config" define_table(tablename, Field("proxy", label=T("Proxy Server URL"), requires=IS_EMPTY_OR(IS_URL(mode="generic"))), *s3_meta_fields()) # Field configuration # @todo: make in-line table = db[tablename] table.uuid.readable = True table.uuid.label = "UUID" table.uuid.comment = DIV(_class="tooltip", _title="%s|%s" % ( T("UUID"), T("Unique identifier which THIS repository identifies itself with when sending synchronization requests."))) table.proxy.comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Proxy Server URL"), T("URL of the default proxy server to connect to remote repositories (if required). If only some of the repositories require the use of a proxy server, you can configure this in the respective repository configurations."))) # CRUD Strings crud_strings[tablename] = Storage( title_display = T("Synchronization Settings"), title_update = T("Edit Synchronization Settings"), msg_record_modified = T("Synchronization settings updated")) # Resource Configuration configure(tablename, insertable=False, deletable=False, update_next=URL(c="sync", f="config", args=["1", "update"])) # ------------------------------------------------------------------------- # Status # ------------------------------------------------------------------------- tablename = "sync_status" define_table(tablename, Field("running", "boolean", default=False, readable=False, writable=False), Field("manual", "boolean", default=False, readable=False, writable=False), Field("timestmp", "datetime", readable=False, writable=False)) # ------------------------------------------------------------------------- # Repository # ------------------------------------------------------------------------- sync_repository_types = { "eden": "Sahana Eden", "ccrm": "CiviCRM", "wrike": "Wrike", "mcb": "Mariner CommandBridge", } password_widget = S3PasswordWidget() tablename = "sync_repository" define_table(tablename, Field("name", length=64, notnull=True, comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Repository Name"), T("Name of the repository (for you own reference)"))), ), Field("apitype", label=T("Repository Type"), requires = IS_IN_SET(sync_repository_types), default = "eden", represent = lambda opt: \ NONE if not opt else \ sync_repository_types.get(opt, NONE), ), Field("url", label="URL", requires = IS_EMPTY_OR( IS_NOT_IN_DB(db, "sync_repository.url")), comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Repository Base URL"), T("Base URL of the remote Sahana Eden instance including application path, e.g. http://www.example.org/eden"))), ), Field("username", comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Username"), T("Username to use for authentication at the remote site."))), ), Field("password", "password", widget = password_widget, comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Password"), T("Password to use for authentication at the remote site."))), ), Field("client_id", label = T("Client ID"), comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Client ID"), T("The client ID to use for authentication at the remote site (if required for this type of repository)."))), ), Field("client_secret", "password", widget = password_widget, label = T("Client Secret"), comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Client Secret"), T("The client secret to use for authentication at the remote site (if required for this type of repository)."))), ), Field("site_key", label = T("Site Key"), comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Site Key"), T("Site Key which this site uses to authenticate at the remote site (if required for this type of repository)."))), ), Field("refresh_token", readable = False, writable = False, ), Field("proxy", label=T("Proxy Server URL"), requires=IS_EMPTY_OR(IS_URL(mode="generic")), comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Proxy Server URL"), T("URL of the proxy server to connect to the repository (leave empty for default proxy)"))), ), Field("last_status", readable=False, writable=False, label=T("Last status"), ), Field("accept_push", "boolean", represent = s3_yes_no_represent, default=False, label=T("Accept Push"), comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Accept Push"), T("Accept unsolicited data transmissions from the repository."))), ), Field.Method("last_pull_time", self.sync_repository_last_pull_time), Field.Method("last_push_time", self.sync_repository_last_push_time), *s3_meta_fields()) # CRUD Strings ADD_REPOSITORY = T("Create Repository") crud_strings[tablename] = Storage( label_create = ADD_REPOSITORY, title_display = T("Repository Configuration"), title_list = T("Repositories"), title_update = T("Edit Repository Configuration"), label_list_button = T("List Repositories"), msg_record_created = T("Repository configured"), msg_record_modified = T("Repository configuration updated"), msg_record_deleted = T("Repository configuration deleted"), msg_list_empty = T("No repositories configured")) # Resource Configuration configure(tablename, list_fields=["name", "uuid", "accept_push", (T("Last Pull"), "last_pull_time"), (T("Last Push"), "last_push_time"), ], onaccept=self.sync_repository_onaccept, ondelete=self.sync_repository_ondelete, create_next=URL(c="sync", f="repository", args=["[id]", "task"], ), update_next=URL(c="sync", f="repository", args=["[id]"], ) ) set_method("sync", "repository", method="now", action=sync_now) # Reusable Fields repository_id = S3ReusableField("repository_id", "reference %s" % tablename, requires = IS_ONE_OF(db, "sync_repository.id", "%(name)s"), represent = self.sync_repository_represent, label = T("Repository")) # Components add_components(tablename, sync_task="repository_id", sync_log="repository_id", #sync_conflict="repository_id", **{# Scheduler Jobs S3Task.TASK_TABLENAME: {"name": "job", "joinby": "repository_id", "link": "sync_job", "key": "scheduler_task_id", "actuate": "replace", }, } ) # ------------------------------------------------------------------------- # Task # ------------------------------------------------------------------------- # Synchronization mode sync_mode = { 1: T("pull"), # pull only 2: T("push"), # push only 3: T("pull and push"), # pull & push 4: T("none") # do not synchronize this resource } # Strategy (allowed import methods) sync_strategy = S3ImportItem.METHOD sync_strategy_represent = lambda opt: opt and \ ", ".join([o for o in sync_strategy.values() if o in opt]) or NONE # Update method sync_update_method = { 1: T("update"), # update the existing record 2: T("replace"), # replace the existing record } # Update/conflict resolution policy sync_policies = S3ImportItem.POLICY sync_policy = { sync_policies.OTHER: T("always update"), sync_policies.NEWER: T("update if newer"), sync_policies.MASTER: T("update if master"), sync_policies.THIS: T("never update") } sync_policy_represent = lambda opt: \ opt and sync_policy.get(opt, UNKNOWN_OPT) or NONE tablename = "sync_task" define_table(tablename, repository_id(), Field("resource_name", notnull=True), Field("last_pull", "datetime", readable=True, writable=False, label=T("Last pull on")), Field("last_push", "datetime", readable=True, writable=False, label=T("Last push on")), Field("mode", "integer", requires = IS_IN_SET(sync_mode, zero=None), default = 3, label = T("Mode"), represent = lambda opt: \ sync_mode.get(opt, NONE)), Field("strategy", "list:string", requires = IS_IN_SET(sync_strategy.values(), multiple=True, zero=None), default = sync_strategy.values(), label = T("Strategy"), represent = sync_strategy_represent, widget = CheckboxesWidgetS3.widget), Field("update_method", "integer", # hide while not implemented readable=False, writable=False, requires = IS_IN_SET(sync_update_method, zero=None), default = 1, label = T("Update Method"), represent = lambda opt: \ sync_update_method.get(opt, NONE)), Field("update_policy", requires = IS_IN_SET(sync_policies, zero=None), default = sync_policies.NEWER, label = T("Update Policy"), represent = sync_policy_represent), Field("conflict_policy", requires = IS_IN_SET(sync_policies, zero=None), default = sync_policies.NEWER, label = T("Conflict Policy"), represent = sync_policy_represent), *s3_meta_fields()) # Field configuration # @todo: make in-line table = db[tablename] table.resource_name.comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Resource Name"), T("Table name of the resource to synchronize"))) table.mode.comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Synchronization mode"), T("How data shall be transferred"))) table.strategy.comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Strategy"), T("Which methods to apply when importing data to the local repository"))) table.update_method.comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Update Method"), T("How local records shall be updated"))) table.update_policy.comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Update Policy"), T("Under which conditions local records shall be updated"))) table.conflict_policy.comment = DIV(_class="tooltip", _title="%s|%s" % ( T("Conflict Policy"), T("Under which condition a local record shall be updated if it also has been modified locally since the last synchronization"))) # CRUD Strings ADD_TASK = T("Create Resource") crud_strings[tablename] = Storage( label_create = ADD_TASK, title_display = T("Resource Configuration"), title_list = T("Resources"), title_update = T("Edit Resource Configuration"), label_list_button = T("List Resources"), msg_record_created = T("Resource configured"), msg_record_modified = T("Resource configuration updated"), msg_record_deleted = T("Resource configuration deleted"), msg_list_empty = T("No resources configured yet")) # Resource Configuration configure(tablename, create_onvalidation=self.sync_task_onvalidation) # Reusable Field task_represent = self.sync_task_represent task_id = S3ReusableField("task_id", "reference %s" % tablename, requires = IS_ONE_OF(db, "sync_task.id", task_represent), represent = task_represent, label = T("Task")) # Components add_components(tablename, sync_resource_filter="task_id", ) # ------------------------------------------------------------------------- # Filters # ------------------------------------------------------------------------- tablename = "sync_resource_filter" define_table(tablename, task_id(), Field("tablename", label = T("Table"), requires = IS_NOT_EMPTY()), Field("filter_string", label = T("Filter"), requires = IS_NOT_EMPTY()), *s3_meta_fields()) onaccept = self.sync_resource_filter_onaccept configure(tablename, list_fields = ["id", "task_id$repository_id", "task_id$resource_name", "tablename", "filter_string"], onaccept = onaccept, ondelete = onaccept) # ------------------------------------------------------------------------- # Job # ------------------------------------------------------------------------- tablename = "sync_job" define_table(tablename, repository_id(), s3.scheduler_task_id(), *s3_meta_fields()) # CRUD Strings ADD_JOB = T("Create Job") crud_strings[tablename] = Storage( label_create = ADD_JOB, title_display = T("Synchronization Job"), title_list = T("Synchronization Schedule"), title_update = T("Edit Job"), label_list_button = T("List Jobs"), msg_record_created = T("Job added"), msg_record_modified = T("Job updated"), msg_record_deleted = T("Job deleted"), msg_list_empty = T("No jobs configured yet"), msg_no_match = T("No jobs configured")) # Resource Configuration set_method("sync", "repository", component_name="job", method="reset", action=sync_job_reset) # ------------------------------------------------------------------------- # Log # ------------------------------------------------------------------------- tablename = "sync_log" define_table(tablename, Field("timestmp", "datetime", represent=s3_datetime_represent, label=T("Date/Time")), repository_id(), Field("resource_name"), # Synchronization mode: PULL/PUSH, IN/OUT Field("mode"), Field("action"), Field("result"), Field("remote", "boolean", default=False, label=T("Remote Error"), represent=lambda opt: opt and T("yes") or ("no")), Field("message", "text", represent=s3_strip_markup), *s3_meta_fields()) # CRUD Strings crud_strings[tablename] = Storage( title_display = T("Log Entry"), title_list = T("Synchronization Log"), label_list_button = T("List All Entries"), msg_record_deleted = T("Log Entry Deleted"), msg_list_empty = T("No entries found"), msg_no_match = T("No entries found")) # Resource Configuration configure(tablename, editable=False, insertable=False, deletable=True, orderby="sync_log.timestmp desc") # --------------------------------------------------------------------- # Return global names to s3.* # return Storage()
def model(self): T = current.T db = current.db auth = current.auth s3 = current.response.s3 settings = current.deployment_settings organisation_id = self.org_organisation_id ADMIN = current.session.s3.system_roles.ADMIN is_admin = auth.s3_has_role(ADMIN) add_components = self.add_components configure = self.configure crud_strings = s3.crud_strings define_table = self.define_table root_org = auth.root_org() if is_admin: filter_opts = () elif root_org: filter_opts = (root_org, None) else: filter_opts = (None, ) types = settings.get_member_membership_types() # --------------------------------------------------------------------- # Membership Types # tablename = "member_membership_type" define_table( tablename, Field( "name", notnull=True, length=64, label=T("Name"), requires=[ IS_NOT_EMPTY(), IS_LENGTH(64), ], ), # Only included in order to be able to set # realm_entity to filter appropriately organisation_id( default=root_org, readable=is_admin, writable=is_admin, ), s3_comments( label=T("Description"), comment=None, ), *s3_meta_fields()) ADD_MEMBERSHIP_TYPE = T("Create Membership Type") crud_strings[tablename] = Storage( label_create=ADD_MEMBERSHIP_TYPE, title_display=T("Membership Type Details"), title_list=T("Membership Types"), title_update=T("Edit Membership Type"), title_upload=T("Import Membership Types"), label_list_button=T("List Membership Types"), label_delete_button=T("Delete Membership Type"), msg_record_created=T("Membership Type added"), msg_record_modified=T("Membership Type updated"), msg_record_deleted=T("Membership Type deleted"), msg_list_empty=T("No membership types currently registered")) represent = S3Represent(lookup=tablename, translate=True) membership_type_id = S3ReusableField( "membership_type_id", "reference %s" % tablename, label=T("Type"), ondelete="SET NULL", readable=types, represent=represent, requires=IS_EMPTY_OR( IS_ONE_OF(db, "member_membership_type.id", represent, filterby="organisation_id", filter_opts=filter_opts)), sortby="name", writable=types, comment=S3PopupLink( f="membership_type", label=ADD_MEMBERSHIP_TYPE, title=ADD_MEMBERSHIP_TYPE, tooltip=T("Add a new membership type to the catalog."), ), ) configure( tablename, deduplicate=S3Duplicate( primary=( "name", "organisation_id", ), ignore_deleted=True, ), ) # --------------------------------------------------------------------- # Members # tablename = "member_membership" define_table(tablename, organisation_id( empty = False, requires = self.org_organisation_requires( updateable = True, ), ), Field("code", label = T("Member ID"), #readable = False, #writable = False, ), self.pr_person_id( comment = None, ondelete = "CASCADE", widget = S3AddPersonWidget(controller="member"), empty = False, ), membership_type_id(), # History s3_date("start_date", label = T("Date Joined"), set_min = "#member_membership_end_date", ), s3_date("end_date", label = T("Date Resigned"), set_max = "#member_membership_start_date", start_field = "member_membership_start_date", default_interval = 12, ), Field("leaving_reason", label = T("Reason for Leaving"), # Enable in template as-required readable = False, writable = False, ), s3_date("restart_date", label = T("Date Rejoined"), # Enable in template as-required readable = False, set_max = "#member_membership_end_date", writable = False, ), Field("membership_fee", "double", label = T("Membership Fee"), represent = lambda v: \ IS_FLOAT_AMOUNT.represent(v, precision=2), requires = IS_EMPTY_OR( IS_FLOAT_AMOUNT(minimum=0.0) ), ), s3_date("membership_paid", label = T("Membership Paid"), ), s3_date("membership_due", label = T("Membership Fee Due Date"), ), Field("fee_exemption", "boolean", label = T("Exempted from Membership Fee"), default = False, # Expose in templates as needed: readable = False, writable = False, ), Field("election", label = T("Participation in the Election as a"), # Expose in templates as needed: readable = False, writable = False, ), Field("trainings", label = T("Trainings"), # Expose in templates as needed: readable = False, writable = False, ), s3_comments(), # Location (from pr_address component) self.gis_location_id(readable = False, writable = False, ), Field.Method("paid", self.member_membership_paid), *s3_meta_fields()) crud_strings[tablename] = Storage( label_create=T("Create Member"), title_display=T("Member Details"), title_list=T("Members"), title_update=T("Edit Member"), title_upload=T("Import Members"), label_list_button=T("List Members"), label_delete_button=T("Delete Member"), msg_record_created=T("Member added"), msg_record_modified=T("Member updated"), msg_record_deleted=T("Member deleted"), msg_list_empty=T("No Members currently registered")) # Which levels of Hierarchy are we using? levels = current.gis.get_relevant_hierarchy_levels() list_fields = [ "person_id", "organisation_id", ] if types: list_fields.append("membership_type_id") list_fields += [ "start_date", #"membership_paid", (T("Paid"), "paid"), (T("Email"), "email.value"), (T("Phone"), "phone.value"), ] report_fields = [ "organisation_id", "person_id", ] if types: report_fields.append("membership_type_id") default_col = "membership.membership_type_id" else: default_col = "membership.paid" report_fields.append((T("Paid"), "paid")) text_fields = [ "organisation_id$name", "organisation_id$acronym", "person_id$first_name", "person_id$middle_name", "person_id$last_name", ] if types: text_fields.append("membership_type_id") for level in levels: lfield = "location_id$%s" % level list_fields.append(lfield) report_fields.append(lfield) text_fields.append(lfield) if settings.get_org_branches(): org_filter = S3HierarchyFilter( "organisation_id", # Can be unhidden in customise_xx_resource if there is a need to use a default_filter hidden=True, leafonly=False, ) report_fields.insert(1, (settings.get_hrm_root_organisation_label(), "organisation_id$root_organisation")) else: org_filter = S3OptionsFilter( "organisation_id", search=True, header="", # Can be unhidden in customise_xx_resource if there is a need to use a default_filter hidden=True, ) filter_widgets = [ S3TextFilter( text_fields, label=T("Search"), ), org_filter, ] if types: filter_widgets.append( S3OptionsFilter( "membership_type_id", cols=3, hidden=True, )) filter_widgets += [ S3OptionsFilter( "paid", cols=3, label=T("Paid"), options={ T("paid"): T("paid"), T("overdue"): T("overdue"), T("expired"): T("expired"), #T("exempted"): T("exempted"), }, hidden=True, ), S3LocationFilter( "location_id", label=T("Location"), levels=levels, hidden=True, ), ] report_options = Storage(rows=report_fields, cols=report_fields, facts=report_fields, defaults=Storage( cols=default_col, rows="membership.organisation_id", fact="count(membership.person_id)", totals=True, )) configure( tablename, create_next=URL(f="person", args="address", vars={"membership.id": "[id]"}), deduplicate=S3Duplicate( primary=( "person_id", "organisation_id", ), ignore_deleted=True, ), extra_fields=( "start_date", "membership_paid", "fee_exemption", ), filter_widgets=filter_widgets, list_fields=list_fields, onaccept=self.member_onaccept, report_options=report_options, # Default summary summary=[ { "name": "addform", "common": True, "widgets": [{ "method": "create" }], }, { "name": "table", "label": "Table", "widgets": [{ "method": "datatable" }] }, { "name": "report", "label": "Report", "widgets": [{ "method": "report", "ajax_init": True }] }, { "name": "map", "label": "Map", "widgets": [{ "method": "map", "ajax_init": True }], }, ], update_realm=True, ) # Components self.add_components( tablename, # Contact Information pr_contact=( # Email { "name": "email", "link": "pr_person", "joinby": "id", "key": "pe_id", "fkey": "pe_id", "pkey": "person_id", "filterby": { "contact_method": "EMAIL", }, }, # Phone { "name": "phone", "link": "pr_person", "joinby": "id", "key": "pe_id", "fkey": "pe_id", "pkey": "person_id", "filterby": { "contact_method": ( "SMS", "HOME_PHONE", "WORK_PHONE", ), }, }, ), hrm_programme={ "link": "member_membership_programme", "joinby": "membership_id", "key": "programme_id", }, ) represent = S3Represent(lookup=tablename, fields=["code"]) membership_id = S3ReusableField( "membership_id", "reference %s" % tablename, label=T("Member"), ondelete="CASCADE", represent=represent, requires=IS_ONE_OF( db, "member_membership.id", represent, ), ) # --------------------------------------------------------------------- # Pass names back to global scope (s3.*) # return dict(member_membership_id=membership_id)
def configure_tasktable_crud(self, task=None, function=None, args=[], vars={}): """ Configure the task table for interactive CRUD, setting defaults, widgets and hiding unnecessary fields @param task: the task name (will use a UUID if omitted) @param function: the function name (won't hide if omitted) @param args: the function position arguments @param vars: the function named arguments """ T = current.T db = current.db tablename = self.TASK_TABLENAME table = db[tablename] if not task: import uuid task = str(uuid.uuid4()) table.task_name.default = task table.task_name.readable = False table.task_name.writable = False if function: table.function_name.default = function table.function_name.readable = False table.function_name.writable = False table.args.default = json.dumps(args) table.args.readable = False table.args.writable = False table.repeats.label = T("Repeat") table.repeats.comment = T("times (0 = unlimited)") table.repeats.default = 0 table.repeats.represent = lambda opt: opt and "%s %s" % (opt, T("times")) or \ opt == 0 and T("unlimited") or \ "-" table.period.label = T("Run every") table.period.widget = S3TimeIntervalWidget.widget table.period.requires = IS_TIME_INTERVAL_WIDGET(table.period) table.period.represent = S3TimeIntervalWidget.represent table.period.comment = None table.timeout.default = 600 table.timeout.represent = lambda opt: opt and "%s %s" % (opt, T("seconds")) or \ opt == 0 and T("unlimited") or \ "-" table.vars.default = json.dumps(vars) table.vars.readable = False table.vars.writable = False table.application_name.readable = False table.application_name.writable = False table.group_name.readable = False table.group_name.writable = False table.status.readable = False table.status.writable = False table.next_run_time.readable = False table.next_run_time.writable = False table.times_run.readable = False table.times_run.writable = False table.assigned_worker_name.readable = False table.assigned_worker_name.writable = False current.s3db.configure(tablename, list_fields=[ "id", "enabled", "start_time", "repeats", "period", (T("Last run"), "last_run_time"), (T("Last status"), "status"), (T("Next run"), "next_run_time"), "stop_time" ]) response = current.response if response: response.s3.crud_strings[tablename] = Storage( title_create=T("Add Job"), title_display=T("Scheduled Jobs"), title_list=T("Job Schedule"), title_update=T("Edit Job"), title_search=T("Search for Job"), subtitle_create=T("Add Job"), label_list_button=T("List Jobs"), label_create_button=T("Add Job"), msg_record_created=T("Job added"), msg_record_modified=T("Job updated updated"), msg_record_deleted=T("Job deleted"), msg_list_empty=T("No jobs configured yet"), msg_no_match=T("No jobs configured")) return
def model(self): T = current.T db = current.db request = current.request s3 = current.response.s3 settings = current.deployment_settings currency_type = s3.currency_type person_id = self.pr_person_id location_id = self.gis_location_id organisation_id = self.org_organisation_id human_resource_id = self.hrm_human_resource_id UNKNOWN_OPT = current.messages.UNKNOWN_OPT s3_date_format = settings.get_L10n_date_format() s3_datetime_represent = lambda dt: S3DateTime.datetime_represent(dt, utc=True) s3_date_represent = lambda dt: S3DateTime.date_represent(dt, utc=True) super_link = self.super_link define_table = self.define_table configure = self.configure add_component = self.add_component # --------------------------------------------------------------------- # Hospitals # # Use government-assigned UUIDs instead of internal UUIDs HMS_HOSPITAL_USE_GOVUUID = True hms_facility_type_opts = { 1: T("Hospital"), 2: T("Field Hospital"), 3: T("Specialized Hospital"), 11: T("Health center"), 12: T("Health center with beds"), 13: T("Health center without beds"), 21: T("Dispensary"), 98: T("Other"), 99: T("Unknown type of facility"), } #: Facility Type Options hms_facility_status_opts = { 1: T("Normal"), 2: T("Compromised"), 3: T("Evacuating"), 4: T("Closed") } #: Facility Status Options hms_clinical_status_opts = { 1: T("Normal"), 2: T("Full"), 3: T("Closed") } #: Clinical Status Options hms_morgue_status_opts = { 1: T("Open"), 2: T("Full"), 3: T("Exceeded"), 4: T("Closed") } #: Morgue Status Options hms_security_status_opts = { 1: T("Normal"), 2: T("Elevated"), 3: T("Restricted Access"), 4: T("Lockdown"), 5: T("Quarantine"), 6: T("Closed") } #: Security Status Options hms_resource_status_opts = { 1: T("Adequate"), 2: T("Insufficient") } #: Resource Status Options hms_ems_traffic_opts = { 1: T("Normal"), 2: T("Advisory"), 3: T("Closed"), 4: T("Not Applicable") } #: EMS Traffic Options hms_or_status_opts = { 1: T("Normal"), #2: T("Advisory"), 3: T("Closed"), 4: T("Not Applicable") } #: Operating Room Status Options tablename = "hms_hospital" table = define_table(tablename, super_link("doc_id", "doc_entity"), super_link("pe_id", "pr_pentity"), super_link("site_id", "org_site"), Field("paho_uuid", unique=True, length=128, requires = IS_NULL_OR(IS_NOT_ONE_OF(db, "%s.paho_uuid" % tablename)), label = T("PAHO UID")), # UID assigned by Local Government Field("gov_uuid", unique=True, length=128, requires = IS_NULL_OR(IS_NOT_ONE_OF(db, "%s.gov_uuid" % tablename)), label = T("Government UID")), # Alternate ids found in data feeds Field("other_ids", length=128), # Mayon compatibility #Field("code", # length=10, # notnull=True, # unique=True, label=T("Code")), # Name of the facility Field("name", notnull=True, length=64, # Mayon compatibility label = T("Name")), # Alternate name, or name in local language Field("aka1", label = T("Other Name")), # Alternate name, or name in local language Field("aka2",label = T("Other Name")), Field("facility_type", "integer", requires = IS_NULL_OR(IS_IN_SET( hms_facility_type_opts)), default = 1, label = T("Facility Type"), represent = lambda opt: \ hms_facility_type_opts.get(opt, T("not specified"))), organisation_id(), location_id(), # Address fields: # @todo: Deprecate these & use location_id in HAVE export Field("address", label = T("Address")), Field("postcode", label = settings.get_ui_label_postcode()), Field("city"), Field("phone_exchange", label = T("Phone/Exchange (Switchboard)"), requires = IS_NULL_OR(s3_phone_requires)), Field("phone_business", label = T("Phone/Business"), requires = IS_NULL_OR(s3_phone_requires)), Field("phone_emergency", label = T("Phone/Emergency"), requires = IS_NULL_OR(s3_phone_requires)), Field("website", label=T("Website"), requires = IS_NULL_OR(IS_URL()), represent = s3_url_represent), Field("email", label = T("Email"), requires = IS_NULL_OR(IS_EMAIL())), Field("fax", label = T("Fax"), requires = IS_NULL_OR(s3_phone_requires)), Field("total_beds", "integer", readable = False, writable = False, requires = IS_NULL_OR(IS_INT_IN_RANGE(0, 9999)), label = T("Total Beds")), Field("available_beds", "integer", readable = False, writable = False, requires = IS_NULL_OR(IS_INT_IN_RANGE(0, 9999)), label = T("Available Beds")), # Emergency Room Status Field("ems_status", "integer", requires = IS_NULL_OR(IS_IN_SET( hms_ems_traffic_opts)), label = T("ER Status"), represent = lambda opt: \ hms_ems_traffic_opts.get(opt, UNKNOWN_OPT)), # Reason for EMS Status Field("ems_reason", length=128, label = T("ER Status Reason")), # Operating Room Status Field("or_status", "integer", requires = IS_NULL_OR(IS_IN_SET( hms_or_status_opts)), label = T("OR Status"), represent = lambda opt: \ hms_or_status_opts.get(opt, UNKNOWN_OPT)), # Reason for OR Status Field("or_reason", length=128, label = T("OR Status Reason")), Field("facility_status", "integer", requires = IS_NULL_OR(IS_IN_SET( hms_facility_status_opts)), label = T("Facility Status"), represent = lambda opt: \ hms_facility_status_opts.get(opt, UNKNOWN_OPT)), Field("clinical_status", "integer", requires = IS_NULL_OR(IS_IN_SET( hms_clinical_status_opts)), label = T("Clinical Status"), represent = lambda opt: \ hms_clinical_status_opts.get(opt, UNKNOWN_OPT)), Field("morgue_status", "integer", requires = IS_NULL_OR(IS_IN_SET( hms_morgue_status_opts)), label = T("Morgue Status"), represent = lambda opt: \ hms_clinical_status_opts.get(opt, UNKNOWN_OPT)), # Number of available/vacant morgue units Field("morgue_units", "integer", requires = IS_NULL_OR( IS_INT_IN_RANGE(0, 9999)), label = T("Morgue Units Available"), represent = lambda v, row=None: IS_INT_AMOUNT.represent(v)), Field("security_status", "integer", requires = IS_NULL_OR(IS_IN_SET( hms_security_status_opts)), label = T("Security Status"), represent = lambda opt: \ hms_security_status_opts.get(opt, UNKNOWN_OPT)), Field("doctors", "integer", label = T("Number of doctors"), requires = IS_NULL_OR( IS_INT_IN_RANGE(0, 9999)), represent = lambda v, row=None: IS_INT_AMOUNT.represent(v)), Field("nurses", "integer", label = T("Number of nurses"), requires = IS_NULL_OR( IS_INT_IN_RANGE(0, 9999)), represent = lambda v, row=None: IS_INT_AMOUNT.represent(v)), Field("non_medical_staff", "integer", requires = IS_NULL_OR( IS_INT_IN_RANGE(0, 9999)), label = T("Number of non-medical staff"), represent = lambda v, row=None: IS_INT_AMOUNT.represent(v)), # Staffing status Field("staffing", "integer", requires = IS_NULL_OR(IS_IN_SET( hms_resource_status_opts)), label = T("Staffing"), represent = lambda opt: \ hms_resource_status_opts.get(opt, UNKNOWN_OPT)), # Facility Operations Status Field("facility_operations", "integer", requires = IS_NULL_OR(IS_IN_SET( hms_resource_status_opts)), label = T("Facility Operations"), represent = lambda opt: \ hms_resource_status_opts.get(opt, UNKNOWN_OPT)), # Clinical Operations Status Field("clinical_operations", "integer", requires = IS_NULL_OR(IS_IN_SET( hms_resource_status_opts)), label = T("Clinical Operations"), represent = lambda opt: \ hms_resource_status_opts.get(opt, UNKNOWN_OPT)), Field("access_status", label = T("Road Conditions")), s3.comments(), *s3.meta_fields()) # CRUD Strings ADD_HOSPITAL = T("Add Hospital") s3.crud_strings[tablename] = Storage( title_create = ADD_HOSPITAL, title_display = T("Hospital Details"), title_list = T("Hospitals"), title_update = T("Edit Hospital"), title_search = T("Find Hospital"), title_map = T("Map of Hospitals"), subtitle_create = T("Add New Hospital"), label_list_button = T("List Hospitals"), label_create_button = ADD_HOSPITAL, label_delete_button = T("Delete Hospital"), msg_record_created = T("Hospital information added"), msg_record_modified = T("Hospital information updated"), msg_record_deleted = T("Hospital information deleted"), msg_list_empty = T("No Hospitals currently registered")) # Search method hms_hospital_search = S3Search( #name="hospital_search_simple", #label=T("Name and/or ID"), #comment=T("To search for a hospital, enter any of the names or IDs of the hospital, separated by spaces. You may use % as wildcard. Press 'Search' without input to list all hospitals."), #field=["gov_uuid", "name", "aka1", "aka2"], advanced=(S3SearchSimpleWidget( name="hospital_search_advanced", label=T("Name, Org and/or ID"), comment=T("To search for a hospital, enter any of the names or IDs of the hospital, or the organisation name or acronym, separated by spaces. You may use % as wildcard. Press 'Search' without input to list all hospitals."), field=["gov_uuid", "name", "aka1", "aka2", "organisation_id$name", "organisation_id$acronym"] ), # for testing: S3SearchOptionsWidget( name="hospital_facility_type", label=T("Facility Type"), field="facility_type" ), # for testing: S3SearchMinMaxWidget( name="hospital_search_bedcount", method="range", label=T("Total Beds"), comment=T("Select a range for the number of total beds"), field="total_beds" ), )) # Resource configuration configure(tablename, super_entity=("org_site", "doc_entity", "pr_pentity"), search_method=hms_hospital_search, list_fields=["id", "gov_uuid", "name", "facility_type", "organisation_id", "location_id", "phone_exchange", "ems_status", "facility_status", "clinical_status", "security_status", "total_beds", "available_beds"]) # Reusable field hms_hospital_id_comment = S3AddResourceLink(c="hms", f="hospital", label=ADD_HOSPITAL, title=T("Hospital"), tooltip=T("If you don't see the Hospital in the list, you can add a new one by clicking link 'Add Hospital'.")) hospital_id = S3ReusableField("hospital_id", db.hms_hospital, sortby="name", requires = IS_NULL_OR(IS_ONE_OF(db, "hms_hospital.id", "%(name)s")), represent = lambda id: \ (id and [db(db.hms_hospital.id == id).select(db.hms_hospital.name, limitby=(0, 1)).first().name] or ["None"])[0], label = T("Hospital"), comment = hms_hospital_id_comment, ondelete = "RESTRICT") # Components single = dict(joinby="hospital_id", multiple=False) multiple = "hospital_id" add_component("hms_contact", hms_hospital=multiple) add_component("hms_bed_capacity", hms_hospital=multiple) add_component("hms_activity", hms_hospital=multiple) add_component("hms_services", hms_hospital=single) add_component("hms_ctc_capability", hms_hospital=single) add_component("hms_resources", hms_hospital=multiple) # --------------------------------------------------------------------- # Contacts # tablename = "hms_contact" table = define_table(tablename, hospital_id(ondelete="CASCADE"), person_id(label = T("Contact"), requires = IS_ONE_OF(db, "pr_person.id", self.pr_person_represent, orderby="pr_person.first_name", sort=True)), Field("title", label = T("Job Title")), Field("phone", label = T("Phone"), requires = IS_NULL_OR(s3_phone_requires)), Field("mobile", label = T("Mobile"), requires = IS_NULL_OR(s3_phone_requires)), Field("email", label = T("Email"), requires = IS_NULL_OR(IS_EMAIL())), Field("fax", label = T("Fax"), requires = IS_NULL_OR(s3_phone_requires)), Field("skype", label = T("Skype ID")), Field("website", label=T("Website")), *s3.meta_fields()) # CRUD Strings s3.crud_strings[tablename] = Storage( title_create = T("Add Contact"), title_display = T("Contact Details"), title_list = T("Contacts"), title_update = T("Edit Contact"), title_search = T("Search Contacts"), subtitle_create = T("Add New Contact"), label_list_button = T("List Contacts"), label_create_button = T("Add Contact"), msg_record_created = T("Contact information added"), msg_record_modified = T("Contact information updated"), msg_record_deleted = T("Contact information deleted"), msg_list_empty = T("No contacts currently registered")) # Resource configuration configure(tablename, mark_required = ["person_id"], list_fields=["id", "person_id", "title", "phone", "mobile", "email", "fax", "skype"], main="person_id", extra="title") # --------------------------------------------------------------------- # Activity # tablename = "hms_activity" table = define_table(tablename, hospital_id(ondelete="CASCADE"), Field("date", "datetime", unique=True, # Date&Time the entry applies to requires = IS_UTC_DATETIME(allow_future=False), represent = s3_datetime_represent, widget = S3DateTimeWidget(future=0), label = T("Date & Time")), Field("patients", "integer", # Current Number of Patients requires = IS_NULL_OR(IS_INT_IN_RANGE(0, 9999)), default = 0, label = T("Number of Patients"), represent = lambda v, row=None: IS_INT_AMOUNT.represent(v)), Field("admissions24", "integer", # Admissions in the past 24 hours requires = IS_NULL_OR(IS_INT_IN_RANGE(0, 9999)), default = 0, label = T("Admissions/24hrs"), represent = lambda v, row=None: IS_INT_AMOUNT.represent(v)), Field("discharges24", "integer", # Discharges in the past 24 hours requires = IS_NULL_OR(IS_INT_IN_RANGE(0, 9999)), default = 0, label = T("Discharges/24hrs"), represent = lambda v, row=None: IS_INT_AMOUNT.represent(v)), Field("deaths24", "integer", # Deaths in the past 24 hours requires = IS_NULL_OR(IS_INT_IN_RANGE(0, 9999)), default = 0, label = T("Deaths/24hrs"), represent = lambda v, row=None: IS_INT_AMOUNT.represent(v)), Field("comment", length=128), *s3.meta_fields()) # CRUD Strings s3.crud_strings[tablename] = Storage( title_create = T("Add Activity Report"), title_display = T("Activity Report"), title_list = T("Activity Reports"), title_update = T("Update Activity Report"), title_search = T("Search Activity Report"), subtitle_create = T("Add Activity Report"), label_list_button = T("List Activity Reports"), label_create_button = T("Add Report"), label_delete_button = T("Delete Report"), msg_record_created = T("Report added"), msg_record_modified = T("Report updated"), msg_record_deleted = T("Report deleted"), msg_list_empty = T("No reports currently available")) # Resource configuration configure(tablename, onaccept = self.hms_activity_onaccept, list_fields=["id", "date", "patients", "admissions24", "discharges24", "deaths24", "comment"], main="hospital_id", extra="id") # --------------------------------------------------------------------- # Bed Capacity # hms_bed_type_opts = { 1: T("Adult ICU"), 2: T("Pediatric ICU"), 3: T("Neonatal ICU"), 4: T("Emergency Department"), 5: T("Nursery Beds"), 6: T("General Medical/Surgical"), 7: T("Rehabilitation/Long Term Care"), 8: T("Burn ICU"), 9: T("Pediatrics"), 10: T("Adult Psychiatric"), 11: T("Pediatric Psychiatric"), 12: T("Negative Flow Isolation"), 13: T("Other Isolation"), 14: T("Operating Rooms"), 15: T("Cholera Treatment"), 99: T("Other") } tablename = "hms_bed_capacity" table = define_table(tablename, hospital_id(ondelete="CASCADE"), Field("unit_id", length=128, unique=True, readable=False, writable=False), Field("bed_type", "integer", requires = IS_IN_SET(hms_bed_type_opts, zero=None), default = 6, label = T("Bed Type"), represent = lambda opt: \ hms_bed_type_opts.get(opt, UNKNOWN_OPT)), Field("date", "datetime", requires = IS_UTC_DATETIME(allow_future=False), represent = s3_datetime_represent, widget = S3DateTimeWidget(future=0), label = T("Date of Report")), Field("beds_baseline", "integer", default = 0, requires = IS_NULL_OR(IS_INT_IN_RANGE(0, 9999)), label = T("Baseline Number of Beds"), represent = lambda v, row=None: IS_INT_AMOUNT.represent(v)), Field("beds_available", "integer", default = 0, requires = IS_NULL_OR(IS_INT_IN_RANGE(0, 9999)), label = T("Available Beds"), represent = lambda v, row=None: IS_INT_AMOUNT.represent(v)), Field("beds_add24", "integer", default = 0, requires = IS_NULL_OR(IS_INT_IN_RANGE(0, 9999)), label = T("Additional Beds / 24hrs"), represent = lambda v, row=None: IS_INT_AMOUNT.represent(v)), s3.comments(), *s3.meta_fields()) # Field configuration # CRUD Strings s3.crud_strings[tablename] = Storage( title_create = T("Add Bed Type"), title_display = T("Bed Capacity"), title_list = T("Bed Capacity"), title_update = T("Update Unit"), title_search = T("Search Units"), subtitle_create = T("Add Unit"), label_list_button = T("List Units"), label_create_button = T("Add Unit"), label_delete_button = T("Delete Unit"), msg_record_created = T("Unit added"), msg_record_modified = T("Unit updated"), msg_record_deleted = T("Unit deleted"), msg_list_empty = T("No units currently registered")) # Resource configuration configure(tablename, onvalidation = self.hms_bed_capacity_onvalidation, onaccept = self.hms_bed_capacity_onaccept, ondelete = self.hms_bed_capacity_onaccept, list_fields=["id", "unit_name", "bed_type", "date", "beds_baseline", "beds_available", "beds_add24"], main="hospital_id", extra="id") # --------------------------------------------------------------------- # Services # tablename = "hms_services" table = define_table(tablename, hospital_id(ondelete="CASCADE"), Field("burn", "boolean", default=False, label = T("Burn")), Field("card", "boolean", default=False, label = T("Cardiology")), Field("dial", "boolean", default=False, label = T("Dialysis")), Field("emsd", "boolean", default=False, label = T("Emergency Department")), Field("infd", "boolean", default=False, label = T("Infectious Diseases")), Field("neon", "boolean", default=False, label = T("Neonatology")), Field("neur", "boolean", default=False, label = T("Neurology")), Field("pedi", "boolean", default=False, label = T("Pediatrics")), Field("surg", "boolean", default=False, label = T("Surgery")), Field("labs", "boolean", default=False, label = T("Clinical Laboratory")), Field("tran", "boolean", default=False, label = T("Ambulance Service")), Field("tair", "boolean", default=False, label = T("Air Transport Service")), Field("trac", "boolean", default=False, label = T("Trauma Center")), Field("psya", "boolean", default=False, label = T("Psychiatrics/Adult")), Field("psyp", "boolean", default=False, label = T("Psychiatrics/Pediatric")), Field("obgy", "boolean", default=False, label = T("Obstetrics/Gynecology")), *s3.meta_fields()) # CRUD Strings s3.crud_strings[tablename] = Storage( title_create = T("Add Service Profile"), title_display = T("Services Available"), title_list = T("Services Available"), title_update = T("Update Service Profile"), title_search = T("Search Service Profiles"), subtitle_create = T("Add Service Profile"), label_list_button = T("List Service Profiles"), label_create_button = T("Add Service Profile"), label_delete_button = T("Delete Service Profile"), msg_record_created = T("Service profile added"), msg_record_modified = T("Service profile updated"), msg_record_deleted = T("Service profile deleted"), msg_list_empty = T("No service profile available")) # Resource configuration configure(tablename, list_fields = ["id"], main="hospital_id", extra="id") # --------------------------------------------------------------------- # Cholera Treatment Capability # hms_problem_types = { 1: T("Security problems"), 2: T("Hygiene problems"), 3: T("Sanitation problems"), 4: T("Improper handling of dead bodies"), 5: T("Improper decontamination"), 6: T("Understaffed"), 7: T("Lack of material"), 8: T("Communication problems"), 9: T("Information gaps") } tablename = "hms_ctc_capability" table = define_table(tablename, hospital_id(ondelete="CASCADE"), Field("ctc", "boolean", default=False, represent = lambda opt: \ opt and T("yes") or T("no"), label = T("Cholera-Treatment-Center")), Field("number_of_patients", "integer", default=0, requires = IS_NULL_OR(IS_INT_IN_RANGE(0, 999999)), label = T("Current number of patients"), represent = lambda v, row=None: IS_INT_AMOUNT.represent(v)), Field("cases_24", "integer", default=0, requires = IS_NULL_OR(IS_INT_IN_RANGE(0, 999999)), label = T("New cases in the past 24h"), represent = lambda v, row=None: IS_INT_AMOUNT.represent(v)), Field("deaths_24", "integer", default=0, requires = IS_NULL_OR(IS_INT_IN_RANGE(0, 999999)), label = T("Deaths in the past 24h"), represent = lambda v, row=None: IS_INT_AMOUNT.represent(v)), #Field("staff_total", "integer", default=0), Field("icaths_available", "integer", default=0, requires = IS_NULL_OR(IS_INT_IN_RANGE(0, 99999999)), label = T("Infusion catheters available"), represent = lambda v, row=None: IS_INT_AMOUNT.represent(v)), Field("icaths_needed_24", "integer", default=0, requires = IS_NULL_OR(IS_INT_IN_RANGE(0, 99999999)), label = T("Infusion catheters needed per 24h"), represent = lambda v, row=None: IS_INT_AMOUNT.represent(v)), Field("infusions_available", "integer", default=0, requires = IS_NULL_OR(IS_INT_IN_RANGE(0, 99999999)), label = T("Infusions available"), represent = lambda v, row=None: IS_INT_AMOUNT.represent(v)), Field("infusions_needed_24", "integer", default=0, requires = IS_NULL_OR(IS_INT_IN_RANGE(0, 99999999)), label = T("Infusions needed per 24h"), represent = lambda v, row=None: IS_INT_AMOUNT.represent(v)), #Field("infset_available", "integer", default=0), #Field("infset_needed_24", "integer", default=0), Field("antibiotics_available", "integer", default=0, requires = IS_NULL_OR(IS_INT_IN_RANGE(0, 99999999)), label = T("Antibiotics available"), represent = lambda v, row=None: IS_INT_AMOUNT.represent(v)), Field("antibiotics_needed_24", "integer", default=0, requires = IS_NULL_OR(IS_INT_IN_RANGE(0, 99999999)), label = T("Antibiotics needed per 24h"), represent = lambda v, row=None: IS_INT_AMOUNT.represent(v)), Field("problem_types", "list:integer", requires = IS_EMPTY_OR(IS_IN_SET(hms_problem_types, zero=None, multiple=True)), represent = lambda optlist: \ optlist and ", ".join(map(str,optlist)) or T("N/A"), label = T("Current problems, categories")), Field("problem_details", "text", label = T("Current problems, details")), s3.comments(), *s3.meta_fields()) # Field configuration table.modified_on.label = T("Last updated on") table.modified_on.readable = True table.modified_by.label = T("Last updated by") table.modified_by.readable = True # CRUD Strings s3.crud_strings[tablename] = Storage( title_create = T("Add Cholera Treatment Capability Information"), title_display = T("Cholera Treatment Capability"), title_list = T("Cholera Treatment Capability"), title_update = T("Update Cholera Treatment Capability Information"), title_search = T("Search Status"), subtitle_create = T("Add Status"), label_list_button = T("List Statuses"), label_create_button = T("Add Status"), label_delete_button = T("Delete Status"), msg_record_created = T("Status added"), msg_record_modified = T("Status updated"), msg_record_deleted = T("Status deleted"), msg_list_empty = T("No status information available")) # Resource configuration configure(tablename, list_fields = ["id"], subheadings = { "Activities": "ctc", "Medical Supplies Availability": "icaths_available", "Current Problems": "problem_types", "Comments": "comments" }) # --------------------------------------------------------------------- # Resources (multiple) - @todo: to be completed! # tablename = "hms_resources" table = define_table(tablename, hospital_id(ondelete="CASCADE"), Field("type"), Field("description"), Field("quantity"), s3.comments(), *s3.meta_fields()) # CRUD Strings s3.crud_strings[tablename] = Storage( title_create = T("Report Resource"), title_display = T("Resource Details"), title_list = T("Resources"), title_update = T("Edit Resource"), title_search = T("Search Resources"), subtitle_create = T("Add New Resource"), label_list_button = T("List Resources"), label_create_button = T("Add Resource"), label_delete_button = T("Delete Resource"), msg_record_created = T("Resource added"), msg_record_modified = T("Resource updated"), msg_record_deleted = T("Resource deleted"), msg_list_empty = T("No resources currently reported")) # Resource configuration configure(tablename, list_fields=["id"], main="hospital_id", extra="id") # --------------------------------------------------------------------- # Return global names to s3db # return Storage(hms_hospital_id=hospital_id)
def defaults(self): """ Safe defaults if the module is disabled """ return Storage()
# Uncomment this to enable `auto-reloading # <http://web2py.com/books/default/chapter/29/04/the-core?search=import+module#Sharing-the-global-scope-with-modules-using-the-current-object>`_ # of code in the ``modules/`` subdirectory. This is helpful when doing # development; otherwise, the web2py server must be restarted to reload any # changes made to ``modules/``. #from gluon.custom_import import track_changes; track_changes(True) from gluon.storage import Storage import logging from os import environ settings = Storage() settings.migrate = True settings.migprefix = 'runestonebeta_' settings.title = 'Runestone Interactive' settings.subtitle = 'eBooks for Python' settings.author = 'Brad Miller' settings.author_email = '*****@*****.**' settings.keywords = '' settings.description = '' settings.layout_theme = 'Default' settings.security_key = '0b734ebc-7a50-4167-99b1-2df09062fde8' settings.email_server = 'smtp.webfaction.com' settings.email_sender = '*****@*****.**' settings.email_login = '******' settings.login_method = 'local' settings.login_config = '' settings.course_id = 'devcourse' settings.plugins = [] settings.server_type = "http://"
##--------------------------------------# """ import socket import platform import os try: import yaml from yaml.parser import ParserError except ImportError: raise ImportError('PyYAML required. Please install it before continuing') from gluon.storage import Storage settings = Storage() settings.kvasir_config = {} kv_cfg_filename = os.path.join(os.environ.get('HOME'), '.kvasir', 'kvasir.yaml') try: settings.kvasir_config = yaml.load(open(kv_cfg_filename, 'r')) except IOError as e: kv_cfg_filename = os.environ.get('KVASIR_CONFIG', 'kvasir.yaml') try: settings.kvasir_config = yaml.load(open(kv_cfg_filename, 'r')) except IOError as e: kv_cfg_filename = os.path.join('applications', request.application, 'kvasir.yaml') try: settings.kvasir_config = yaml.load(open(kv_cfg_filename, 'r'))
use_username=True, reset_password=False, register=True) if db(db.auth_user.id > 0).count() > 0: auth.settings.actions_disabled.append('register') response.ns_menu = create_menu() ui.control.create_cmd(response, T, "b") _editable = True if session.auth: if session.auth.user.has_key("username"): if session.auth.user.username == "demo": _editable = False if request.post_vars: request.post_vars = Storage() response.flash = T("Demo user: This action is not allowed!") else: _editable = True @auth.requires(session.alias == 'nas_admin', requires_login=True) def index(): response.view = 'nas/index.html' response.subtitle = T("Home") gform = DIV( P("Nervatura NAS Admin", _style="font-weight: bold;"), P(SPAN(T("Username: "******"font-weight: bold;"), session.auth.user.username), P(SPAN("Ver.No: " + response.verNo, _class="vernum")), TABLE(
def __call__(self): T = current.T response = current.response response.title = current.deployment_settings.get_system_name() view = path.join(current.request.folder, "private", "templates", "IFRC", "views", "index.html") try: # Pass view as file not str to work in compiled mode response.view = open(view, "rb") except IOError: from gluon.http import HTTP raise HTTP(404, "Unable to open Custom View: %s" % view) script = ''' $('.marker').mouseover(function(){$(this).children('.marker-window').show()}) $('.marker').mouseout(function(){$(this).children('.marker-window').hide()}) $('#single-col').css('padding', 0)''' response.s3.jquery_ready.append(script) markers = [ Storage(name="Afghan Red Crescent Society", direction="right", top=109, left=271), Storage(name="Australian Red Cross", direction="right", top=349, left=478), Storage(name="Bangladesh Red Crescent Society", direction="right", top=142, left=326), Storage(name="Brunei Darussalam Red Crescent Society", direction="right", top=205, left=402), Storage(name="Cambodian Red Cross Society", direction="right", top=181, left=374), Storage(name="Cook Islands Red Cross", direction="right", top=291, left=652), Storage(name="Fiji Red Cross Society", direction="right", top=278, left=590), Storage(name="Hong Kong Red Cross Society", direction="right", top=146, left=398), Storage(name="Indian Red Cross Society", direction="right", top=129, left=287), Storage(name="Indonesian Red Cross Society", direction="right", top=235, left=378), Storage(name="Japanese Red Cross Society", direction="right", top=94, left=463), Storage(name="Kiribati Red Cross Society", direction="left", top=214, left=564), Storage(name="Lao Red Cross Society", direction="right", top=159, left=366), Storage(name="Malaysian Red Crescent Society", direction="right", top=207, left=367), Storage(name="Maldivian Red Crescent", direction="right", top=205, left=278), Storage(name="Marshall Islands Red Cross Society", direction="left", top=200, left=561), Storage(name="Micronesia Red Cross Society", direction="left", top=200, left=532), Storage(name="Mongolian Red Cross Society", direction="right", top=54, left=372), Storage(name="Myanmar Red Cross Society", direction="right", top=165, left=349), Storage(name="Nepal Red Cross Society", direction="right", top=133, left=308), Storage(name="New Zealand Red Cross", direction="right", top=368, left=562), Storage(name="Pakistan Red Crescent Society", direction="right", top=115, left=278), Storage(name="Palau Red Cross Society", direction="right", top=197, left=463), Storage(name="Papua New Guinea Red Cross Society", direction="right", top=247, left=504), Storage(name="Philippine National Red Cross", direction="right", top=170, left=421), Storage(name="Red Cross of Viet Nam", direction="right", top=150, left=373), Storage(name="Red Cross Society of China", direction="right", top=81, left=399), Storage( name= "Red Cross Society of the Democratic People's Republic of Korea", direction="right", top=82, left=423), Storage(name="Republic of Korea National Red Cross", direction="right", top=87, left=426), Storage(name="Samoa Red Cross Society", direction="left", top=261, left=621), Storage(name="Singapore Red Cross Society", direction="right", top=214, left=376), Storage(name="Solomon Islands Red Cross", direction="right", top=247, left=537), Storage(name="Sri Lanka Red Cross Society", direction="right", top=197, left=303), Storage(name="Thai Red Cross Society", direction="right", top=172, left=360), Storage(name="Timor-Leste Red Cross Society", direction="right", top=245, left=435), Storage(name="Tonga Red Cross Society", direction="right", top=291, left=563), Storage(name="Tuvalu Red Cross Society", direction="right", top=245, left=591), Storage(name="Vanuatu Red Cross Society", direction="right", top=276, left=559), ] map = DIV(A(T("Go to Functional Map"), _href=URL(c="gis", f="index"), _class="map-click"), _id="map-home") append = map.append for marker in markers: append( DIV(A("", _href=URL(c="org", f="organisation", args="read", vars={"organisation.name": marker.name})), DIV(SPAN(marker.name), SPAN(_class="marker-plus"), _class="marker-window %s" % marker.direction), _class="marker", _style="top:%ipx;left:%ipx;" % (marker.top, marker.left))) append( DIV(SPAN(T("Click anywhere on the map for full functionality")), _class="map-tip")) current.menu.breadcrumbs = None return dict(map=map)
from reportlab.platypus.frames import Frame from reportlab.platypus import Spacer, PageBreak, FrameBreak, Paragraph from reportlab.platypus import Table, TableStyle from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.units import inch from reportlab.lib.units import cm from reportlab.lib import colors from reportlab.lib.colors import Color from reportlab.lib.pagesizes import A4, LETTER, landscape, portrait from reportlab.platypus.flowables import Flowable reportLabImported = True except ImportError: reportLabImported = False BaseDocTemplate = object inch = 72.0 canvas = Storage() canvas.Canvas = None PDF_WIDTH = 0 PDF_HEIGHT = 1 # ============================================================================= class S3RL_PDF(S3Codec): """ Simple Report Labs PDF format codec """ def __init__(self): """ Constructor """
response.static_version = '1.3.16' db = DAL("sqlite://storage.db", migrate=MIGRATE, attempts=10, lazy_tables=LAZY_TABLES, driver_args={'timeout': 30}) db2 = DAL("sqlite://storage_scheduler.db", migrate=MIGRATE, attempts=10, lazy_tables=LAZY_TABLES, driver_args={'timeout': 30}) from gluon.storage import Storage from gluon import current current.w2p_tvseries = Storage(database=db, database2=db2) from gluon.tools import Auth, Crud, Service, PluginManager, prettydate crud, service, plugins = Crud(db), Service(), PluginManager() STATIC_FOLDER = os.path.join(request.folder, 'static', 'deposit') #from gluon.custom_import import track_changes; track_changes(True) db.define_table("series", Field("seriesid", "integer"), Field("language", length=3), Field("overview", 'text'), Field("name"), Field("genre", "list:string"), Field("status"),
# -*- coding: utf-8 -*- ''' Copyright (c) 2015 Heidelberg University Library Distributed under the GNU GPL v3. For full terms see the file LICENSE.md ''' from gluon.storage import Storage from gluon.custom_import import track_changes settings = Storage() settings.migrate = True settings.title = 'Heidelberg University Publishing - heiUP' settings.subtitle = '' settings.author_email = '*****@*****.**' settings.keywords = 'heiUP, Heidelberg University Publishing, Universitätsverlag Heidelberg, Universitätsbibliothek Heidelberg, Universität Heidelberg, digitales Publizieren, Open Access, omp, python, mysql, knv, onix' settings.description = 'Heidelberg University Publishing ist ein Open-Access-Verlag für wissenschaftliche Publikationen - qualitätsgeprüft und in mehreren Formaten.' settings.layout_theme = 'Default' # settings.database_uri = 'sqlite://storage.sqlite' # settings.database_uri = 'mysql://*****:*****@localhost:3306/omptest' settings.security_key = '1228409b-a1fc-4868-92b1-a973a607d3f1' settings.email_server = 'login' settings.email_sender = 'login' settings.email_login = '' settings.login_method = 'local' settings.login_config = '' settings.plugins = [] track_changes(True)
def __send(self, r, **attr): """ Respond to an incoming pull @param r: the S3Request @param attr: the controller attributes """ mixed = attr.get("mixed", False) get_vars = r.get_vars resource = r.resource # Identify the requesting repository repository_uuid = get_vars.get("repository") connector = None if repository_uuid: rtable = current.s3db.sync_repository query = rtable.uuid == repository_uuid row = current.db(query).select(limitby=(0, 1)).first() if row: connector = S3SyncRepository(row) if connector is None: # Use a dummy repository with Eden API connector = S3SyncRepository( Storage( id=None, name="unknown", apitype="eden", )) current.log.debug("S3Sync PULL from %s (%s)" % (connector.name, connector.apitype)) # Additional export parameters start = get_vars.get("start", None) if start is not None: try: start = int(start) except ValueError: start = None limit = get_vars.get("limit", None) if limit is not None: try: limit = int(limit) except ValueError: limit = None msince = get_vars.get("msince", None) if msince is not None: msince = s3_parse_datetime(msince) # Sync filters from peer filters = {} for k, v in get_vars.items(): if k[0] == "[" and "]" in k: tablename, urlvar = k[1:].split("]", 1) if urlvar: if not tablename or tablename == "~": tablename = resource.tablename f = filters.get(tablename, {}) u = f.get(urlvar, None) if u: u = "%s&%s" % (u, v) else: u = v f[urlvar] = u filters[tablename] = f if not filters: filters = None try: result = connector.send( resource, start=start, limit=limit, msince=msince, filters=filters, mixed=mixed, ) except NotImplementedError: r.error(405, "Synchronization method not supported for repository") log = self.log log.write( repository_id=connector.id, resource_name="mixed" if mixed else resource.tablename, transmission=log.IN, mode=log.PULL, action="send", remote=result.get("remote", False), result=result.get("status", log.NONE), message=result.get("message", ""), ) return result.get("response")
def member_onaccept(form): """ On-accept for Member records """ db = current.db s3db = current.s3db auth = current.auth settings = current.deployment_settings utable = current.auth.settings.table_user ptable = s3db.pr_person ltable = s3db.pr_person_user mtable = db.member_membership # Get the full record _id = form.vars.id if _id: query = (mtable.id == _id) record = db(query).select(mtable.id, mtable.person_id, mtable.organisation_id, mtable.deleted, limitby=(0, 1)).first() else: return data = Storage() # Affiliation, record ownership and component ownership # @ToDo #s3db.pr_update_affiliations(mtable, record) # realm_entity for the pr_person record person_id = record.person_id person = Storage(id=person_id) if settings.get_auth_person_realm_member_org(): # Set pr_person.realm_entity to the human_resource's organisation pe_id organisation_id = record.organisation_id entity = s3db.pr_get_pe_id("org_organisation", organisation_id) if entity: auth.set_realm_entity(ptable, person, entity=entity, force_update=True) # Update the location ID from the Home Address atable = s3db.pr_address query = (atable.pe_id == ptable.pe_id) & \ (ptable.id == record.person_id) & \ (atable.type == 1) & \ (atable.deleted == False) address = db(query).select(atable.location_id, limitby=(0, 1)).first() if address: data.location_id = address.location_id # Add record owner (user) query = (ptable.id == record.person_id) & \ (ltable.pe_id == ptable.pe_id) & \ (utable.id == ltable.user_id) user = db(query).select(utable.id, utable.organisation_id, utable.site_id, limitby=(0, 1)).first() if user: data.owned_by_user = user.id if not data: return record.update_record(**data)
"CAD": T("Canadian Dollars"), "EUR": T("Euros"), "GBP": T("Great British Pounds"), "CHF": T("Swiss Francs"), "USD": T("United States Dollars"), } # Comment/uncomment modules here to disable/enable them settings.modules = OrderedDict([ # Core modules which shouldn't be disabled ( "default", Storage( name_nice=T("Home"), restricted=False, # Use ACLs to control access to this module access= None, # All Users (inc Anonymous) can see this module in the default menu & access the controller module_type=None # This item is not shown in the menu )), ( "admin", Storage( name_nice=T("Administration"), #description = "Site Administration", restricted=True, access= "|1|", # Only Administrators can see this module in the default menu & access the controller module_type=None # This item is handled separately for the menu )), ( "appadmin",
import logging from gluon.contrib.appconfig import AppConfig from gluon.storage import Storage from tbox_interface import TBoxInterface from abox_interface import ABoxInterface # Doesn't work well anyway even for dev/testing # from gluon.custom_import import track_changes # track_changes(True) SETTINGS = Storage() MYCONF = AppConfig(reload=False) # read values from private/config.ini SETTINGS.app_view_name = MYCONF.take('app.view_name', cast=str) SETTINGS.app_name = MYCONF.take('app.app_name', cast=str) SETTINGS.maintainer_eml = MYCONF.take('app.maintainer_eml', cast=str) SETTINGS.base_url = MYCONF.take('app.base_url', cast=str) SETTINGS.document_endpoint = MYCONF.take('app.document_endpoint', cast=str) SETTINGS.id_gen_endpoint = MYCONF.take('app.id_gen_endpoint', cast=str) SETTINGS.inheritance_query_endpoint = MYCONF.take( 'app.inheritance_query_endpoint', cast=str) SETTINGS.create_activity_endpoint = MYCONF.take('app.create_activity_endpoint', cast=str) SETTINGS.db_url_login = MYCONF.take('auth_db.db_url_login', cast=str) SETTINGS.migrate = MYCONF.take('auth_db.migrate', cast=bool) SETTINGS.fake_migrate_all = MYCONF.take('auth_db.fake_migrate_all', cast=bool) SETTINGS.admn_grp = MYCONF.take('auth_db.admn_grp', cast=str)
from gluon.storage import Storage settings = Storage() settings.migrate = True settings.title = 'FFlock Distributed Cluster Transcoding' settings.subtitle = '' settings.author = 'Eric Griffin' settings.author_email = '*****@*****.**' settings.keywords = 'fflock, transcoding, cluster' settings.description = '' settings.layout_theme = 'Default' settings.database_uri = 'sqlite://storage.sqlite' settings.security_key = '89465294-76ab-4323-90d7-f157bd412ffc' settings.email_server = 'localhost' settings.email_sender = '*****@*****.**' settings.email_login = '' settings.login_method = 'local' settings.login_config = '' settings.plugins = []
from unittest.case import SkipTest, _ExpectedFailure, _UnexpectedSuccess from dateutil.relativedelta import relativedelta from selenium.common.exceptions import NoSuchElementException, TimeoutException from selenium.webdriver.support.ui import Select, WebDriverWait from gluon import current from gluon.storage import Storage from s3.s3resource import S3FieldSelector from s3.s3utils import s3_unicode from s3.s3widgets import * from tests.core import * current.data = Storage() current.data["auth"] = { "normal": { "email": "*****@*****.**", "password": "******", "first_name": "Test", "last_name": "User", }, "admin": { "email": "*****@*****.**", "password": "******", "first_name": "Admin", "last_name": "User", }, }
def html(self, widget_id=None, formkey=None): """ Render the organizer container and instantiate the UI widget @param widget_id: the container's DOM ID """ T = current.T settings = current.deployment_settings if not widget_id: widget_id = "organizer" # Parse resource configuration resources = self.resources if not isinstance(resources, (list, tuple)): resources = [resources] resource_configs = [] use_time = False for resource_config in resources: resource_use_time = resource_config.get("useTime") if resource_use_time: use_time = True resource_configs.append(resource_config) # Inject script and widget instantiation script_opts = {"resources": resource_configs, "useTime": use_time, "labelEdit": s3_str(T("Edit")), "labelDelete": s3_str(T("Delete")), "deleteConfirmation": s3_str(T("Do you want to delete this entry?")), "firstDay": settings.get_L10n_firstDOW(), } # Options from settings bhours = settings.get_ui_organizer_business_hours() if bhours: script_opts["businessHours"] = bhours tformat = settings.get_ui_organizer_time_format() if tformat: script_opts["timeFormat"] = tformat snap_duration = settings.get_ui_organizer_snap_duration() if snap_duration: script_opts["snapDuration"] = snap_duration self.inject_script(widget_id, script_opts) # Add a datepicker to navigate to arbitrary dates picker = S3DateWidget()(Storage(name="date_select"), None, _type="hidden", _id="%s-date-picker" % widget_id, ) # Generate and return the HTML for the widget container return DIV(INPUT(_name = "_formkey", _type = "hidden", _value = str(formkey) if formkey else "", ), picker, _id = widget_id, _class = "s3-organizer", )
def _create_popup(r, widget, list_id, resource, context, numrows): """ Render an action link for a create-popup (used in data lists and data tables). @param r: the S3Request instance @param widget: the widget definition as dict @param list_id: the list ID @param resource: the target resource @param context: the context filter @param numrows: the total number of rows in the list/table """ create = "" widget_get = widget.get insert = widget_get("insert", True) if not insert: return create table = resource.table tablename = resource.tablename # Default to primary REST controller for the resource being added c, f = tablename.split("_", 1) create_controller = widget_get("create_controller") if create_controller: c = create_controller create_function = widget_get("create_function") if create_function: f = create_function permit = current.auth.s3_has_permission create_ok = permit("create", table, c=c, f=f) if create_ok: if not create_controller or not create_function: # Assume not component context create_ok = permit("update", r.table, record_id=r.id, c=c, f=f) if create_ok: #if tablename = "org_organisation": # @ToDo: Special check for creating resources on Organisation profile # URL-serialize the widget filter widget_filter = widget_get("filter") if widget_filter: url_vars = widget_filter.serialize_url(resource) else: url_vars = Storage() # URL-serialize the context filter if context: filters = context.serialize_url(resource) for selector in filters: url_vars[selector] = filters[selector] # URL-serialize the widget default default = widget_get("default") if default: k, v = default.split("=", 1) url_vars[k] = v # URL-serialize the list ID (refresh-target of the popup) url_vars.refresh = list_id # Indicate that popup comes from profile (and which) url_vars.profile = r.tablename # CRUD string label_create = widget_get("label_create", None) # Activate if-required #if label_create and isinstance(label_create, basestring): if label_create: label_create = current.T(label_create) else: label_create = S3CRUD.crud_string(tablename, "label_create") # Popup URL component = widget_get("create_component", None) if component: args = [r.id, component, "create.popup"] else: args = ["create.popup"] add_url = URL(c=c, f=f, args=args, vars=url_vars) if callable(insert): # Custom widget create = insert(r, list_id, label_create, add_url) elif current.deployment_settings.ui.formstyle == "bootstrap": # Bootstrap-style action icon create = A( ICON("plus-sign", _class="small-add"), _href=add_url, _class="s3_modal", _title=label_create, ) else: # Standard action button create = A( label_create, _href=add_url, _class="action-btn profile-add-btn s3_modal", ) if widget_get("type") == "datalist": # If this is a multiple=False widget and we already # have a record, we hide the create-button multiple = widget_get("multiple", True) if not multiple and hasattr(create, "update"): if numrows: create.update(_style="display:none") else: create.update(_style="display:block") # Script to hide/unhide the create-button on Ajax # list updates createid = create["_id"] if not createid: createid = "%s-add-button" % list_id create.update(_id=createid) script = \ '''$('#%(list_id)s').on('listUpdate',function(){ $('#%(createid)s').css({display:$(this).datalist('getTotalItems')?'none':'block'}) })''' % dict(list_id=list_id, createid=createid) current.response.s3.jquery_ready.append(script) return create
def model(self): T = current.T db = current.db crud_strings = current.response.s3.crud_strings define_table = self.define_table location_id = self.gis_location_id # ----------------------------------------------------------- # Security Levels # - according to the UN Security Level System (SLS) # http://ictemergency.wfp.org/c/document_library/get_file?uuid=c025cb98-2297-4208-bcc6-76ba02719c02&groupId=10844 # http://geonode.wfp.org/layers/geonode:wld_bnd_securitylevel_wfp # level_opts = { 1: T("Minimal"), 2: T("Low"), 3: T("Moderate"), 4: T("Substantial"), 5: T("High"), 6: T("Extreme"), } tablename = "security_level" define_table( tablename, location_id( #label = T("Security Level Area"), widget=S3LocationSelector(show_map=False), ), # Overall Level Field( "level", "integer", label=T("Security Level"), represent=lambda v: level_opts.get( v, current.messages.UNKNOWN_OPT), requires=IS_IN_SET(level_opts), ), # Categories Field( "armed_conflict", "integer", label=T("Armed Conflict"), represent=lambda v: level_opts.get( v, current.messages.UNKNOWN_OPT), requires=IS_IN_SET(level_opts), ), Field( "terrorism", "integer", label=T("Terrorism"), represent=lambda v: level_opts.get( v, current.messages.UNKNOWN_OPT), requires=IS_IN_SET(level_opts), ), Field( "crime", "integer", label=T("Crime"), represent=lambda v: level_opts.get( v, current.messages.UNKNOWN_OPT), requires=IS_IN_SET(level_opts), ), Field( "civil_unrest", "integer", label=T("Civil Unrest"), represent=lambda v: level_opts.get( v, current.messages.UNKNOWN_OPT), requires=IS_IN_SET(level_opts), ), Field( "hazards", "integer", label=T("Hazards"), represent=lambda v: level_opts.get( v, current.messages.UNKNOWN_OPT), requires=IS_IN_SET(level_opts), comment=T("e.g. earthquakes or floods"), ), s3_comments(), *s3_meta_fields()) # CRUD strings crud_strings[tablename] = Storage( label_create=T("Classify Area"), title_display=T("Security Level Details"), title_list=T("Security Levels"), title_update=T("Edit Security Level"), title_upload=T("Import Security Levels"), label_list_button=T("List Security Levels"), label_delete_button=T("Delete Security Level"), msg_record_created=T("Security Area classified"), msg_record_modified=T("Security Level updated"), msg_record_deleted=T("Security Level deleted"), msg_list_empty=T("No Security Areas currently classified")) # ----------------------------------------------------------- # Security Zone Types # tablename = "security_zone_type" define_table(tablename, Field( "name", label=T("Name"), ), s3_comments(), *s3_meta_fields()) # CRUD strings ADD_ZONE_TYPE = T("Create Zone Type") crud_strings[tablename] = Storage( label_create=ADD_ZONE_TYPE, title_display=T("Zone Type Details"), title_list=T("Zone Types"), title_update=T("Edit Zone Type"), title_upload=T("Import Zone Types"), label_list_button=T("List Zone Types"), label_delete_button=T("Delete Zone Type"), msg_record_created=T("Zone Type added"), msg_record_modified=T("Zone Type updated"), msg_record_deleted=T("Zone Type deleted"), msg_list_empty=T("No Zone Types currently registered")) zone_type_represent = S3Represent(lookup=tablename) self.configure( tablename, deduplicate=self.security_zone_type_duplicate, ) # ----------------------------------------------------------- # Security Zones # tablename = "security_zone" define_table( tablename, Field( "name", label=T("Name"), ), Field( "zone_type_id", db.security_zone_type, label=T("Type"), represent=zone_type_represent, requires=IS_EMPTY_OR( IS_ONE_OF(db, "security_zone_type.id", zone_type_represent, sort=True)), comment=S3AddResourceLink( c="security", f="zone_type", label=ADD_ZONE_TYPE, tooltip= T("Select a Zone Type from the list or click 'Add Zone Type'" )), ), location_id(widget=S3LocationSelector( catalog_layers=True, points=False, polygons=True, ), ), s3_comments(), *s3_meta_fields()) # CRUD strings ADD_ZONE = T("Create Zone") crud_strings[tablename] = Storage( label_create=ADD_ZONE, title_display=T("Zone Details"), title_list=T("Zones"), title_update=T("Edit Zone"), title_upload=T("Import Zones"), label_list_button=T("List Zones"), label_delete_button=T("Delete Zone"), msg_record_created=T("Zone added"), msg_record_modified=T("Zone updated"), msg_record_deleted=T("Zone deleted"), msg_list_empty=T("No Zones currently registered")) zone_represent = S3Represent(lookup=tablename) # ----------------------------------------------------------- # Security Staff Types # tablename = "security_staff_type" define_table(tablename, Field("name", label=T("Name")), s3_comments(), *s3_meta_fields()) # CRUD strings ADD_STAFF = T("Add Staff Type") crud_strings[tablename] = Storage( label_create=ADD_STAFF, title_display=T("Staff Type Details"), title_list=T("Staff Types"), title_update=T("Edit Staff Type"), title_upload=T("Import Staff Types"), label_list_button=T("List Staff Types"), label_delete_button=T("Delete Staff Type"), msg_record_created=T("Staff Type added"), msg_record_modified=T("Staff Type updated"), msg_record_deleted=T("Staff Type deleted"), msg_list_empty=T("No Staff Types currently registered")) staff_type_represent = S3Represent(lookup=tablename) # ----------------------------------------------------------- # Security Staff # tablename = "security_staff" define_table( tablename, self.hrm_human_resource_id(), Field( "staff_type_id", "list:reference security_staff_type", label=T("Type"), represent=self.security_staff_type_multirepresent, requires=IS_EMPTY_OR( IS_ONE_OF(db, "security_staff_type.id", staff_type_represent, sort=True, multiple=True)), comment=S3AddResourceLink( c="security", f="staff_type", label=ADD_STAFF, tooltip= T("Select a Staff Type from the list or click 'Add Staff Type'" )), ), Field( "zone_id", db.security_zone, label=T("Zone"), represent=zone_represent, requires=IS_EMPTY_OR( IS_ONE_OF(db, "security_zone.id", zone_represent, sort=True)), comment=S3AddResourceLink( c="security", f="zone", label=ADD_ZONE, tooltip= T("For wardens, select a Zone from the list or click 'Add Zone'" )), ), self.super_link( "site_id", "org_site", label=T("Facility"), represent=self.org_site_represent, readable=True, writable=True, ), s3_comments(), *s3_meta_fields()) # CRUD strings crud_strings[tablename] = Storage( label_create=T("Add Security-Related Staff"), title_display=T("Security-Related Staff Details"), title_list=T("Security-Related Staff"), title_update=T("Edit Security-Related Staff"), title_upload=T("Import Security-Related Staff"), label_list_button=T("List Security-Related Staff"), label_delete_button=T("Delete Security-Related Staff"), msg_record_created=T("Security-Related Staff added"), msg_record_modified=T("Security-Related Staff updated"), msg_record_deleted=T("Security-Related Staff deleted"), msg_list_empty=T("No Security-Related Staff currently registered")) # --------------------------------------------------------------------- # Pass names back to global scope (s3.*) # return dict()
#!/usr/bin/env python # -*- coding: utf-8 -*- """ | This file is part of the web2py Web Framework | Copyrighted by Massimo Di Pierro <*****@*****.**> | License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) """ import os import sys import platform from gluon.storage import Storage from pydal._compat import PY2 global_settings = Storage() settings = global_settings # legacy compatibility if not hasattr(os, 'mkdir'): global_settings.db_sessions = True if global_settings.db_sessions is not True: global_settings.db_sessions = set() global_settings.gluon_parent = \ os.environ.get('web2py_path', os.getcwd()) global_settings.applications_parent = global_settings.gluon_parent global_settings.app_folders = set() global_settings.debugging = False
class LoginRadiusAccount(object): """ from gluon.contrib.login_methods.loginradius_account import LoginRadiusAccount auth.settings.actions_disabled=['register','change_password', 'request_reset_password'] auth.settings.login_form = LoginRadiusAccount(request, api_key="...", api_secret="...", url = "http://localhost:8000/%s/default/user/login" % request.application) """ def __init__(self, request, api_key="", api_secret="", url=None, on_login_failure=None): self.request = request self.api_key = api_key self.api_secret = api_secret self.url = url self.auth_base_url = "https://hub.loginradius.com/UserProfile.ashx/" self.profile = None self.on_login_failure = on_login_failure self.mappings = Storage() def defaultmapping(profile): first_name = profile.get('FirstName') last_name = profile.get('LastName') email = profile.get('Email', [{}])[0].get('Value') reg_id = profile.get('ID', '') username = profile.get('ProfileName', email) return dict(registration_id=reg_id, username=username, email=email, first_name=first_name, last_name=last_name) self.mappings.default = defaultmapping def get_user(self): request = self.request user = None if request.vars.token: try: auth_url = self.auth_base_url + self.api_secret + "/" + request.vars.token json_data = fetch( auth_url, headers={'User-Agent': "LoginRadius - Python - SDK"}) self.profile = json.loads(json_data) provider = self.profile['Provider'] mapping = self.mappings.get(provider, self.mappings['default']) user = mapping(self.profile) except (JSONDecodeError, KeyError): pass if user is None and self.on_login_failure: redirect(self.on_login_failure) return user def login_form(self): loginradius_url = "https://hub.loginradius.com/include/js/LoginRadius.js" loginradius_lib = SCRIPT(_src=loginradius_url, _type='text/javascript') container = DIV(_id="interfacecontainerdiv", _class='interfacecontainerdiv') widget = SCRIPT("""var options={}; options.login=true; LoginRadius_SocialLogin.util.ready(function () { $ui = LoginRadius_SocialLogin.lr_login_settings; $ui.interfacesize = "";$ui.apikey = "%s"; $ui.callback=""; $ui.lrinterfacecontainer ="interfacecontainerdiv"; LoginRadius_SocialLogin.init(options); });""" % self.api_key) form = DIV(container, loginradius_lib, widget) return form
# This script is designed to be run as a Web2Py application: # python web2py.py -S eden -M -R applications/eden/modules/tests/suite.py # or # python web2py.py -S eden -M -R applications/eden/modules/tests/suite.py -A testscript import argparse import unittest from gluon import current from gluon.storage import Storage current.data = Storage() # @ToDo: Load these only when running Selenium tests # (shouldn't be required for Smoke tests) # (means removing the *) from selenium import webdriver from tests.asset import * from tests.inv import * from tests.member import * from tests.org import * from tests.project import * from tests.staff import * from tests.volunteer import * def loadAllTests(): # Create Organisation loadTests = unittest.TestLoader().loadTestsFromTestCase suite = loadTests(CreateOrganisation)
def model(self): T = current.T UNKNOWN_OPT = current.messages.UNKNOWN_OPT # --------------------------------------------------------------------- # Case # dvr_damage_opts = { 1: T("Very High"), 2: T("High"), 3: T("Medium"), 4: T("Low"), } dvr_status_opts = { 1: T("Open"), 2: T("Accepted"), 3: T("Rejected"), } tablename = "dvr_case" self.define_table(tablename, # @ToDo: Option to autogenerate these, like Waybills, et al Field("reference", label = T("Case Number")), self.pr_person_id( # @ToDo: Modify this to update location_id if the selected person has a Home Address already comment=None, requires=IS_ADD_PERSON_WIDGET2(), widget=S3AddPersonWidget2(controller="pr"), ), self.gis_location_id(label = T("Home Address")), Field("damage", "integer", requires = IS_EMPTY_OR(IS_IN_SET(dvr_damage_opts)), represent = lambda opt: \ dvr_damage_opts.get(opt, UNKNOWN_OPT), label= T("Damage Assessment")), Field("insurance", "boolean", represent = s3_yes_no_represent, label = T("Insurance")), Field("status", "integer", default = 1, requires = IS_EMPTY_OR(IS_IN_SET(dvr_status_opts)), represent = lambda opt: \ dvr_status_opts.get(opt, UNKNOWN_OPT), label= T("Status")), s3_comments(), *s3_meta_fields()) # CRUD Strings ADD_CASE = T("Create Case") current.response.s3.crud_strings[tablename] = Storage( label_create=ADD_CASE, title_display=T("Case Details"), title_list=T("Cases"), title_update=T("Edit Case"), label_list_button=T("List Cases"), label_delete_button=T("Delete Case"), msg_record_created=T("Case added"), msg_record_modified=T("Case updated"), msg_record_deleted=T("Case deleted"), msg_list_empty=T("No Cases found")) self.configure( tablename, onaccept=self.dvr_case_onaccept, ) # --------------------------------------------------------------------- # Pass names back to global scope (s3.*) # return Storage()
return form settings.ui.formstyle_row = formstyle_row settings.ui.formstyle = formstyle_row # ----------------------------------------------------------------------------- # Comment/uncomment modules here to disable/enable them settings.modules = OrderedDict([ # Core modules which shouldn't be disabled ( "default", Storage( name_nice=T("Home"), restricted=False, # Use ACLs to control access to this module access= None, # All Users (inc Anonymous) can see this module in the default menu & access the controller module_type=None # This item is not shown in the menu )), ( "admin", Storage( name_nice=T("Administration"), #description = "Site Administration", restricted=True, access= "|1|", # Only Administrators can see this module in the default menu & access the controller module_type=None # This item is handled separately for the menu )), ( "appadmin",
def model(self): T = current.T db = current.db s3 = current.response.s3 person_comment = self.pr_person_comment person_id = self.pr_person_id location_id = self.gis_location_id organisation_id = self.org_organisation_id messages = current.messages NONE = messages.NONE UNKNOWN_OPT = messages.UNKNOWN_OPT # Shortcuts add_component = self.add_component configure = self.configure crud_strings = s3.crud_strings define_table = self.define_table super_key = self.super_key super_link = self.super_link # --------------------------------------------------------------------- # Document-referencing entities # entity_types = Storage( asset_asset=T("Asset"), irs_ireport=T("Incident Report"), project_project=T("Project"), project_activity=T("Project Activity"), project_task=T("Task"), hms_hospital=T("Hospital"), ) tablename = "doc_entity" doc_entity = self.super_entity(tablename, "doc_id", entity_types) # Components add_component("doc_document", doc_entity=super_key(doc_entity)) add_component("doc_image", doc_entity=super_key(doc_entity)) # --------------------------------------------------------------------- # Documents # tablename = "doc_document" table = define_table(tablename, # Instance super_link("source_id", "stats_source"), # Component not instance super_link("site_id", "org_site"), super_link("doc_id", doc_entity), Field("file", "upload", autodelete=True), Field("name", length=128, # Allow Name to be added onvalidation requires = IS_NULL_OR(IS_LENGTH(128)), label=T("Name")), Field("url", label=T("URL"), requires = IS_NULL_OR(IS_URL()), represent = lambda url: \ url and A(url,_href=url) or NONE), person_id(label=T("Author"), comment=person_comment(T("Author"), T("The Author of this Document (optional)"))), organisation_id( widget = S3OrganisationAutocompleteWidget(default_from_profile=True) ), s3_date(label = T("Date Published")), location_id(), self.stats_group_type_id(), s3_comments(), #Field("entered", "boolean", label=T("Entered")), Field("checksum", readable=False, writable=False), *s3_meta_fields()) # Field configuration table.file.represent = lambda file, table=table: \ self.doc_file_represent(file, table) #table.location_id.readable = False #table.location_id.writable = False #table.entered.comment = DIV(_class="tooltip", # _title="%s|%s" % (T("Entered"), # T("Has data from this Reference Document been entered into Sahana?"))) # CRUD Strings ADD_DOCUMENT = T("Add Reference Document") crud_strings[tablename] = Storage( title_create=ADD_DOCUMENT, title_display=T("Document Details"), title_list=T("Documents"), title_update=T("Edit Document"), title_search=T("Search Documents"), subtitle_create=T("Add New Document"), label_list_button=T("List Documents"), label_create_button=ADD_DOCUMENT, label_delete_button=T("Delete Document"), msg_record_created=T("Document added"), msg_record_modified=T("Document updated"), msg_record_deleted=T("Document deleted"), msg_list_empty=T("No Documents found")) # Search Method # Resource Configuration configure(tablename, super_entity="stats_source", deduplicate=self.document_duplicate, onvalidation=self.document_onvalidation) # --------------------------------------------------------------------- # Images # # @ToDo: Field to determine which is the default image to use for # e.g. a Map popup (like the profile picture) # readable/writable=False except in the cases where-needed # doc_image_type_opts = { 1: T("Photograph"), 2: T("Map"), 3: T("Document Scan"), 99: T("other") } tablename = "doc_image" table = define_table( tablename, # Instance super_link("source_id", "stats_source"), # Component not instance super_link("site_id", "org_site"), super_link("pe_id", "pr_pentity"), super_link("doc_id", doc_entity), Field( "file", "upload", autodelete=True, requires=IS_NULL_OR( IS_IMAGE(extensions=(s3.IMAGE_EXTENSIONS))), # upload folder needs to be visible to the download() function as well as the upload uploadfolder=os.path.join(current.request.folder, "uploads", "images")), Field( "name", length=128, # Allow Name to be added onvalidation requires=IS_NULL_OR(IS_LENGTH(128)), label=T("Name")), Field("url", label=T("URL"), requires=IS_NULL_OR(IS_URL())), Field("type", "integer", requires=IS_IN_SET(doc_image_type_opts, zero=None), default=1, label=T("Image Type"), represent=lambda opt: doc_image_type_opts.get( opt, UNKNOWN_OPT)), person_id(label=T("Author")), organisation_id(widget=S3OrganisationAutocompleteWidget( default_from_profile=True)), s3_date(label=T("Date Taken")), location_id(), self.stats_group_type_id(), s3_comments(), Field("checksum", readable=False, writable=False), *s3_meta_fields()) # Field configuration table.file.represent = doc_image_represent # CRUD Strings ADD_IMAGE = T("Add Photo") crud_strings[tablename] = Storage( title_create=ADD_IMAGE, title_display=T("Photo Details"), title_list=T("Photos"), title_update=T("Edit Photo"), title_search=T("Search Photos"), subtitle_create=T("Add New Photo"), label_list_button=T("List Photos"), label_create_button=ADD_IMAGE, label_delete_button=T("Delete Photo"), msg_record_created=T("Photo added"), msg_record_modified=T("Photo updated"), msg_record_deleted=T("Photo deleted"), msg_list_empty=T("No Photos found")) # Search Method # Resource Configuration configure(tablename, super_entity = "stats_source", deduplicate=self.document_duplicate, onvalidation=lambda form: \ self.document_onvalidation(form, document=False)) # --------------------------------------------------------------------- # Pass model-global names to response.s3 # return Storage()