def testTypeOfListReferenceMultiple(self): """ Test resolution of __typeof queries, for list:reference, with multiple values """ db = current.db uids = self.uids resource = current.s3db.resource("test_hierarchy_reference") # Test with multiple values expr = FS("test_hierarchy_multi_id").typeof((uids["HIERARCHY1-2"], uids["HIERARCHY2-1"])) query = expr.query(resource) table = resource.table expected = set(uids[uid] for uid in ("HIERARCHY1-2", "HIERARCHY1-2-1", "HIERARCHY1-2-2", "HIERARCHY2-1", "HIERARCHY2-1-1", "HIERARCHY2-1-2", )) found = self.inspect_multi_query(query, field = table.test_hierarchy_multi_id, conjunction = db._adapter.OR, op = db._adapter.CONTAINS) self.assertEqual(found, expected)
def testTypeOfLookupTableMultipleWildcard(self): """ Test resolution of __typeof queries, for field in lookup table, with multiple values with wildcards """ db = current.db uids = self.uids resource = current.s3db.resource("test_hierarchy_reference") # Test with field in hierarchy table, with wildcard expr = FS("test_hierarchy_id$name").typeof(("Type 1-1-*", "Type 2-1*")) query = expr.query(resource) table = db.test_hierarchy expected = set(uids[uid] for uid in ("HIERARCHY1-1-1", "HIERARCHY1-1-2", "HIERARCHY2-1", "HIERARCHY2-1-1", "HIERARCHY2-1-2", )) expected_query = table.id.belongs(expected) self.assertEquivalent(query, expected_query)
def testTypeOfReferenceMultiple(self): """ Test resolution of __typeof queries, for field in referencing table, with multiple values """ db = current.db uids = self.uids resource = current.s3db.resource("test_hierarchy_reference") # Test with field in referencing table expr = FS("test_hierarchy_id").typeof((uids["HIERARCHY1-2"], uids["HIERARCHY2-1"], )) query = expr.query(resource) table = resource.table expected = set(uids[uid] for uid in ("HIERARCHY1-2", "HIERARCHY1-2-1", "HIERARCHY1-2-2", "HIERARCHY2-1", "HIERARCHY2-1-1", "HIERARCHY2-1-2", )) expected_query = table.test_hierarchy_id.belongs(expected) self.assertEquivalent(query, expected_query)
def vol(): """ VOL / Volunteer Management """ pending_label = current.T("Pending Requests") if current.auth.s3_has_role("COORDINATOR"): from s3 import FS query = (FS("end_date") >= current.request.utcnow) & \ (FS("status") == "REQ") resource = current.s3db.resource( "hrm_delegation", filter=query, ) num_pending_requests = resource.count() if num_pending_requests: pending_label = "%s (%s)" % (pending_label, num_pending_requests) return M(c=("vol", "hrm"))( M("Volunteers", c="vol", f="person")( M("Create", m="create", t="pr_person"), M( "Currently Deployed", vars={"deployed_now": 1}, ), M( "Archive", vars={"active": "0"}, restrict="COORDINATOR", ), ), M("Deployments", c="hrm", f="delegation")( M( pending_label, vars={"workflow": "p"}, translate=False, ), M( "Processed Requests", vars={"workflow": "d"}, ), M( "Archive", vars={"workflow": "o"}, ), M("Organizer", m="organize", restrict="HRMANAGER"), ), M("Statistics", link=False)(M("Deployments", c="hrm", f="delegation", m="report"), ), M("Administration", link=False, restrict="ADMIN")( M("Occupation Types", c="pr", f="occupation_type"), M("Skills / Resources", c="hrm", f="skill"), #M("Competency Levels", c="hrm", f="competency_rating"), ))
def testTypeOfLookupTableNone(self): """ Test resolution of __typeof queries, for field in lookup table, with None value """ db = current.db uids = self.uids resource = current.s3db.resource("test_hierarchy_reference") # Test with None expr = FS("test_hierarchy_id$name").typeof(None) query = expr.query(resource) table = db.test_hierarchy expected_query = table.id.belongs(set()) self.assertEquivalent(query, expected_query) # Test with list expr = FS("test_hierarchy_id$name").typeof([None]) query = expr.query(resource) #table = db.test_hierarchy expected_query = table.id.belongs(set()) self.assertEquivalent(query, expected_query) # Test with multiple values expr = FS("test_hierarchy_id$name").typeof([None, "Type 1-1-2"]) query = expr.query(resource) #table = db.test_hierarchy expected_query = (table.id == uids["HIERARCHY1-1-2"]) self.assertEquivalent(query, expected_query)
def custom_prep(r): # Call standard prep if callable(standard_prep): result = standard_prep(r) if workflow == "issue": # Filter to Unassigned Assets from s3db.asset import ASSET_LOG_ASSIGN available_assets = [] aappend = available_assets.append seen = [] sappend = seen.append ltable = current.s3db.asset_log logs = current.db(ltable.deleted == False).select( ltable.asset_id, ltable.status, orderby=~ltable.date, ) for log in logs: asset_id = log.asset_id if asset_id in seen: continue sappend(asset_id) if log.status != ASSET_LOG_ASSIGN: aappend(asset_id) from s3 import FS r.resource.add_filter(FS("~.id").belongs(available_assets)) elif workflow == "return": # Filter to Assets with log status == ASSET_LOG_ASSIGN from s3db.asset import ASSET_LOG_ASSIGN assigned_assets = [] aappend = assigned_assets.append seen = [] sappend = seen.append ltable = current.s3db.asset_log logs = current.db(ltable.deleted == False).select( ltable.asset_id, ltable.status, orderby=~ltable.date, ) for log in logs: asset_id = log.asset_id if asset_id in seen: continue sappend(asset_id) if log.status == ASSET_LOG_ASSIGN: aappend(asset_id) from s3 import FS r.resource.add_filter(FS("~.id").belongs(assigned_assets)) return result
def template(): """ RESTful CRUD controller """ from s3 import FS s3.filter = FS("master") == "dc_response" def prep(r): if r.record and r.component_name == "question": # If the template has responses then we should make the Questions read-only # @ToDo: Allow Editing unanswered questions? rtable = s3db.dc_response query = (rtable.template_id == r.id) & \ (rtable.deleted == False) if db(query).select(rtable.id, limitby=(0, 1)): s3db.configure( "dc_question", deletable=False, editable=False, ) # Sections for this template only f = s3db.dc_question.section_id f.requires = IS_EMPTY_OR( IS_ONE_OF( db, "dc_section.id", f.represent, filterby="template_id", filter_opts=[r.id], )) # Add JS scripts_append = s3.scripts.append if s3.debug: scripts_append("/%s/static/scripts/tag-it.js" % appname) scripts_append("/%s/static/scripts/S3/s3.dc_question.js" % appname) else: scripts_append("/%s/static/scripts/tag-it.min.js" % appname) scripts_append("/%s/static/scripts/S3/s3.dc_question.min.js" % appname) # Add CSS s3.stylesheets.append("plugins/jquery.tagit.css") # Open in native controller to access Translations tabs s3db.configure( "dc_question", linkto=lambda record_id: URL(f="question", args=[record_id, "read"]), linkto_update=lambda record_id: URL( f="question", args=[record_id, "update"]), ) return True s3.prep = prep return s3_rest_controller(rheader=s3db.dc_rheader)
def shelter_list(self): """ Provide a dropdown of links to shelters """ T = current.T s3db = current.s3db resource = s3db.resource("cr_shelter", filter = FS("status") .belongs([2, None])) data = resource.select(["id", "name"]) shelter_list = UL(_id = "shelter_list", _class = "f-dropdown", data = {"dropdown-content": ""}) rows = data["rows"] if rows: for row in rows: shelter_list.append(LI(A(row["cr_shelter.name"], _href=URL(c="cr", f="shelter", args=[row["cr_shelter.id"]]) ) ) ) return LI(A(T("Shelters"), _class="button dropdown", data = {"dropdown": "shelter_list"}), shelter_list ) else: # @todo: check permission and provide an "Add Shelter" button # if not shelters are yet registered return ""
def group(): """ RESTful CRUD controller """ FS = s3base.S3FieldSelector s3.filter = (FS("group.system") == False) # do not show system groups # Modify list_fields for the component tab table = s3db.pr_group_membership s3db.configure("pr_group_membership", list_fields = ["id", "person_id", "group_head", "comments" ], ) rheader = lambda r: \ s3db.pr_rheader(r, tabs = [(T("Group Details"), None), (T("Address"), "address"), (T("Contact Data"), "contact"), (T("Members"), "group_membership") ]) output = s3_rest_controller(rheader = rheader) return output
def testFilteringAnyNode(self): """ Test filtering of the tree with leafonly=False """ uids = self.uids h = S3Hierarchy("test_hierarchy", filter = FS("type") == "C", leafonly = False) # Check nodes nodes = h.nodes expected = ["HIERARCHY1", "HIERARCHY1-1", "HIERARCHY1-2", "HIERARCHY1-2-2", "HIERARCHY2", "HIERARCHY2-1", "HIERARCHY2-1-1"] self.assertEqual(len(nodes), len(expected)) self.assertTrue(all(uids[uid] in nodes for uid in expected)) # Check consistency for node in nodes.values(): for child_id in node["s"]: self.assertTrue(child_id in nodes) parent_id = node["p"] if parent_id: self.assertTrue(parent_id in nodes)
def apply_filter(resource, get_vars): """ Filter out volunteers who have a confirmed deployment during selected date interval """ parse_dt = current.calendar.parse_date from_date = parse_dt(get_vars.get("$$available__ge")) to_date = parse_dt(get_vars.get("$$available__le")) if from_date or to_date: db = current.db s3db = current.s3db # Must pre-query to bypass realm limits dtable = s3db.hrm_delegation query = rlp_active_deployments(dtable, from_date, to_date) rows = db(query).select(dtable.person_id, cache = s3db.cache, ) if rows: unavailable = {row.person_id for row in rows} resource.add_filter(~FS("id").belongs(unavailable))
def prep(r): # @todo: limit organisation types? # @todo: hide unwanted form fields? # Filter for just referral agencies query = FS("organisation_id:po_referral_organisation.id") != None r.resource.add_filter(query) # Create referral_organisation record onaccept onaccept = s3db.get_config("org_organisation", "onaccept") s3db.configure("org_organisation", onaccept = (onaccept, s3db.po_organisation_onaccept), ) # Filter households to areas served (if any areas defined) # @todo: suppress this filter per deployment setting if r.record and r.component_name == "organisation_household": atable = s3db.po_organisation_area query = (atable.organisation_id == r.id) & \ (atable.deleted != True) rows = db(query).select(atable.area_id) if rows: area_ids = [row.area_id for row in rows] area_ids.append(None) table = r.component.table table.household_id.requires.set_filter(filterby="area_id", filter_opts=area_ids, ) elif not r.component: list_fields = ["name", "name", (T("Type"), "organisation_organisation_type.organisation_type_id"), (T("Areas"), "organisation_area.area_id"), "website", ] s3db.configure("org_organisation", list_fields = list_fields, ) if r.interactive: # Adapt CRUD Strings s3.crud_strings["org_organisation"].update( {"label_create": T("Create Agency"), "title_list": T("Referral Agencies"), "title_display": T("Agency Details"), "title_update": T("Edit Agency Details"), "label_delete_button": T("Delete Agency"), } ) if r.component_name == "area": s3.crud_strings["po_organisation_area"].update( {"label_create": T("Add Area"), } ) return True
def testTypeOfLookupTableSingleUnresolvable(self): """ Test resolution of __typeof queries, for field in lookup table, with unresolvable value """ db = current.db uids = self.uids resource = current.s3db.resource("test_hierarchy_reference") # Test with field in hierarchy table, with wildcard, no match expr = FS("test_hierarchy_id$name").typeof("Type 1-3*") query = expr.query(resource) table = db.test_hierarchy expected_query = table.id.belongs(set()) self.assertEquivalent(query, expected_query)
def __call__(self): """ Main entry point """ # Authorization (user must be logged in) auth = current.auth permissions = auth.permission if not auth.user: permissions.fail() fmt = permissions.format if current.request.env.request_method == "POST" and fmt != "dl": return self.update() pe_id = auth.user.pe_id s3 = current.response.s3 # Filter from s3 import S3FieldSelector as FS f = FS("pe_id") == pe_id s3.filter = f # List Fields current.s3db.configure( "pr_filter", list_fields=["title", "resource", "url", "query"], list_layout=self.render_filter, orderby="resource") # Page length s3.dl_pagelength = 10 # Data list current.request.args = ["datalist.%s" % fmt] output = current.rest_controller("pr", "filter", list_ajaxurl=URL(f="index", args="filters.dl")) # Title and view T = current.T if fmt != "dl": output["title"] = T("Saved Filters") self._view(THEME, "filters.html") # Script for inline-editing of filter title options = { "cssclass": "jeditable-input", "tooltip": str(T("Click to edit")) } script = """$('.jeditable').editable('%s', %s);""" % \ (URL(args="filters"), json.dumps(options)) s3.jquery_ready.append(script) return output
def apply_filter(resource, get_vars): """ Include volunteers who have marked themselves available on the selected days of week, or have not chosen any days """ days, matchall = get_vars.get("$$weekly__anyof"), False if not days: days, matchall = get_vars.get("$$weekly__contains"), True if days: days = [int(d) for d in days.split(",") if d.isdigit()] weekly = sum(2**d for d in days) if days else 0b1111111 if matchall: subset = [i for i in range(weekly, 128) if (i & weekly) == weekly] query = FS("availability.weekly").belongs(subset) else: subset = [i for i in range(128) if not (i & weekly)] query = ~(FS("availability.weekly").belongs(subset)) resource.add_filter(query)
def apply_filter(resource, get_vars): """ Include volunteers who have marked themselves available at the selected sites, or have not chosen any sites """ sites = get_vars.get("$$sites__belongs") if sites: sites = [int(site_id) for site_id in sites.split(",") if site_id.isdigit()] if sites: query = FS("availability_sites.site_id").belongs(sites) resource.add_filter(query)
def template(): """ RESTful CRUD controller """ from s3 import FS s3.filter = FS("master") == "event_sitrep" s3db.dc_template.master.default = "event_sitrep" from s3db.dc import dc_rheader return s3_rest_controller("dc", "template", rheader = dc_rheader, )
def apply_filter(resource, get_vars): """ Filter out offers that - become available only after a start date, or - become unavailable before an end date (reversed logic compared to a normal range filter) """ parse_dt = current.calendar.parse_date from_date = parse_dt(get_vars.get("$$available__ge")) to_date = parse_dt(get_vars.get("$$available__le")) if from_date: query = (FS("date") == None) | (FS("date") <= from_date) resource.add_filter(query) if to_date: query = (FS("end_date") == None) | (FS("end_date") >= to_date) resource.add_filter(query)
def testTypeOfReferenceNoHierarchy(self): """ Test resolution of __typeof queries, for field in referencing table, with no hierarchy configured """ db = current.db uids = self.uids # Remove hierarchy setting current.s3db.clear_config("test_hierarchy", "hierarchy") resource = current.s3db.resource("test_hierarchy_reference") # Test with field in referencing table, single value expr = FS("test_hierarchy_id").typeof(uids["HIERARCHY1-2"]) query = expr.query(resource) expected = uids["HIERARCHY1-2"] expected_query = resource.table.test_hierarchy_id == expected self.assertEquivalent(query, expected_query) # Test with field in referencing table, multiple values expr = FS("test_hierarchy_id").typeof((uids["HIERARCHY1-2"], uids["HIERARCHY2-1"] )) query = expr.query(resource) expected = set(uids[uid] for uid in ("HIERARCHY1-2", "HIERARCHY2-1", )) expected_query = resource.table.test_hierarchy_id.belongs(expected) self.assertEquivalent(query, expected_query)
def prep(r): if auth.s3_has_role("ADMIN"): # No restrictions return True from s3 import FS if r.id: if r.method == "join": # Only possible for Public Groups filter_ = FS("forum_type") == 1 elif r.method == "request": # Only possible for Private Groups filter_ = FS("forum_type") == 2 else: # Can only see Public Groups filter_ = FS("forum_type") == 1 user = auth.user if user: # unless the User is a Member of them filter_ |= FS( "forum_membership.person_id$pe_id") == user.pe_id else: # Cannot see Seceret Groups filter_ = FS("forum_type") != 3 user = auth.user if user: # unless the User is a Member of them filter_ |= FS("forum_membership.person_id$pe_id") == user.pe_id r.resource.add_filter(filter_) return True
def prep(r): # Call standard prep if callable(standard_prep): result = standard_prep(r) else: result = True if r.method == "datalist": # Filter out Draft Surveys from s3 import FS r.resource.add_filter(FS("status") != 1) return result
def site_location(): """ RESTful CRUD controller """ from s3 import FS s3.filter = (FS("site_id$instance_type") == "police_station") table = s3db.org_site_location table.site_id.label = T("Police Station") table.site_id.represent = s3db.org_SiteRepresent(show_type=False) table.location_id.label = T("Beat") return s3_rest_controller("org", "site_location", )
def testTypeOfLookupTableNoHierarchy(self): """ Test resolution of __typeof queries, for field in lookup table, with no hierarchy configured """ db = current.db uids = self.uids # Remove hierarchy setting current.s3db.clear_config("test_hierarchy", "hierarchy") resource = current.s3db.resource("test_hierarchy_reference") # Test with field in lookup table, single value expr = FS("test_hierarchy_id$name").typeof("Type 1-2") query = expr.query(resource) table = db.test_hierarchy expected_query = (table.name == "Type 1-2") self.assertEquivalent(query, expected_query) # Test with field in lookup table expr = FS("test_hierarchy_id$name").typeof(("Type 1-2", "Type 2-1")) query = expr.query(resource) table = db.test_hierarchy expected_query = table.name.belongs(("Type 1-2", "Type 2-1")) self.assertEquivalent(query, expected_query) # Test with field in lookup table, multiple values + wildcards expr = FS("test_hierarchy_id$name").typeof(("Type 1-*", "Type 2-1")) query = expr.query(resource) table = db.test_hierarchy expected_query = (table.name.like("Type 1-%")) | \ (table.name == "Type 2-1") self.assertEquivalent(query, expected_query)
def job_title(): """ Job Titles Controller """ table = s3db.hrm_job_title s3.crud_strings["hrm_job_title"] = Storage( label_create=T("Add Position"), title_display=T("Position Details"), title_list=T("Positions"), title_update=T("Edit Position"), label_list_button=T("List Positions"), label_delete_button=T("Remove Position"), msg_record_created=T("Position added"), msg_record_modified=T("Position updated"), msg_record_deleted=T("Position removed"), msg_list_empty=T("No Positions currently registered"), ) def prep(r): # Default / Hide type f = table.type f.default = 4 # Deployment f.readable = f.writable = False # Positions are never org-specific f = table.organisation_id f.readable = f.writable = False if r.representation == "xls": # Export format should match Import format current.messages["NONE"] = "" #f.represent = \ # s3db.org_OrganisationRepresent(acronym = False, # parent = False) #f.label = None table.comments.label = None table.comments.represent = lambda v: v or "" return True s3.prep = prep s3.filter = FS("type").belongs((4, )) if not auth.s3_has_role("ADMIN"): s3.filter &= auth.filter_by_root_org(table) return s3_rest_controller("hrm")
def customise_cap_alert_controller(**attr): s3 = current.response.s3 auth = current.auth if not auth.user: # For notifications for group r = current.request if not r.function == "public": if r.get_vars.format == "msg": # This is called by notification # The request from web looks like r.extension s3.filter = (FS("scope") != "Private") else: auth.permission.fail() # Custom prep standard_prep = s3.prep def custom_prep(r): # Call standard prep if callable(standard_prep): result = standard_prep(r) else: result = True if r.representation == "msg": # Notification table = r.table table.scope.represent = None table.status.represent = None table.msg_type.represent = None itable = current.s3db.cap_info itable.severity.represent = None itable.urgency.represent = None itable.certainty.represent = None return result s3.prep = custom_prep return attr
def prep(r): if not r.record: query = (FS("followup_date") <= datetime.datetime.utcnow().date()) & \ (FS("completed") != True) r.resource.add_filter(query) return True
def index(): """ Module's Home Page """ # Page title module_name = settings.modules[c].get("name_nice") response.title = module_name output = {"module_name": module_name} # Extract summary information from s3 import FS define_resource = s3db.resource # => Number of households total_households = define_resource("po_household").count() # => Number of referrals total_referrals = define_resource("po_organisation_household").count() # => Number of agencies involved # This version shows all agencies for all Branches (only master query is filtered) #filter = (FS("organisation_id") == s3db.po_organisation_household.organisation_id) #total_agencies = define_resource("po_referral_organisation", # filter=filter).count(distinct=True) total_agencies = define_resource("po_organisation_household").select(fields=["organisation_id"]) total_agencies = len({o["po_organisation_household.organisation_id"] for o in total_agencies.rows}) # => Number of follow ups (broken down into pending/completed) # Option 1 # Minimum Time: 0.042s # Maximum Time: 0.103s # Mean Time: 0.047s # Option 2 # Minimum Time: 0.002s # Maximum Time: 0.03s # Mean Time: 0.002s #rows = define_resource("po_household_followup").select(fields=["completed"], # as_rows=True) #follow_ups_pending, follow_ups_completed = 0, 0 #for row in rows: # if row.completed: # follow_ups_completed += 1 # else: # follow_ups_pending += 1 filter = (FS("completed") == False) follow_ups_pending = define_resource("po_household_followup", filter=filter).count() filter = (FS("completed") == True) follow_ups_completed = define_resource("po_household_followup", filter=filter).count() total_follow_ups = follow_ups_pending + follow_ups_completed # => Number of attempted visits # @ToDo: Support sum() in S3Resource areas = define_resource("po_area").select(fields=["attempted_visits"], as_rows=True) total_attempted_visits = 0 for row in areas: attempted_visits = row.attempted_visits if attempted_visits: total_attempted_visits += attempted_visits # Summary output["summary"] = DIV(DIV(LABEL("%s: " % T("Total Households Visited")), SPAN(total_households), _class="po-summary-info", ), DIV(LABEL("%s: " % T("Attempted Visits")), SPAN(total_attempted_visits), _class="po-summary-info", ), DIV(LABEL("%s: " % T("Follow-ups")), SPAN(total_follow_ups), SPAN("(%s %s, %s %s)" % (follow_ups_completed, T("completed"), follow_ups_pending, T("pending"), ) ), _class="po-summary-info", ), DIV(LABEL("%s: " % T("Total Referrals Made")), SPAN(total_referrals), _class="po-summary-info", ), DIV(LABEL("%s: " % T("Agencies Involved")), SPAN(total_agencies), _class="po-summary-info", ), _class="po-summary", ) # Map of areas covered ftable = s3db.gis_layer_feature query = (ftable.controller == "po") & \ (ftable.function == "area") layer = db(query).select(ftable.layer_id, limitby=(0, 1)).first() if layer: # We can take advantage of per-feature styling layer_id = layer.layer_id areas = {"name": T("Areas Covered"), "id": "areas", "active": True, "layer_id": layer_id, } else: # All features will be styled the same areas = {"name": T("Areas Covered"), "id": "areas", "active": True, "tablename": "po_area", "url": "area.geojson", "style": '{"fill":"2288CC"}', "opacity": 0.5, } map_wrapper = gis.show_map(feature_resources=(areas,), #catalogue_layers = True, collapsed = True, ) #map_wrapper["_style"] = "width:100%" output["map"] = map_wrapper return output
def __call__(self): T = current.T db = current.db s3db = current.s3db request = current.request response = current.response s3 = response.s3 output = {} output["title"] = response.title = current.deployment_settings.get_system_name() # Map auth = current.auth is_logged_in = auth.is_logged_in() callback = None if is_logged_in: # Show the User's Coalition's Polygon org_group_id = auth.user.org_group_id if org_group_id: # Lookup Coalition Name table = s3db.org_group row = db(table.id == org_group_id).select(table.name, limitby=(0, 1) ).first() if row: callback = '''S3.gis.show_map(); var layer,layers=S3.gis.maps.default_map.layers; for(var i=0,len=layers.length;i<len;i++){ layer=layers[i]; if(layer.name=='%s'){layer.setVisibility(true)}}''' % row.name if not callback: # Show all Coalition Polygons callback = '''S3.gis.show_map(); var layer,layers=S3.gis.maps.default_map.layers; for(var i=0,len=layers.length;i<len;i++){ layer=layers[i]; if(layer.name=='All Coalitions'){layer.setVisibility(true)}} ''' gis = current.gis config = gis.get_config() config.zoom = 8 map = gis.show_map(width=770, height=295, callback=callback, catalogue_layers=True, collapsed=True, save=False, ) output["map"] = map # Description of available data from s3db.cms import S3CMS for item in response.menu: item["cms"] = S3CMS.resource_content(module = item["c"], resource = item["f"]) # Site Activity Log resource = s3db.resource("s3_audit") resource.add_filter(FS("~.method") != "delete") orderby = "s3_audit.timestmp desc" list_fields = ["id", "method", "timestmp", "user_id", "tablename", "record_id", ] #current.deployment_settings.ui.customise_s3_audit() db.s3_audit.user_id.represent = s3_auth_user_represent_name list_id = "log" datalist, numrows, ids = resource.datalist(fields=list_fields, start=None, limit=4, list_id=list_id, orderby=orderby, layout=s3.render_log) # Placeholder filter_form = DIV(_class="filter_form") if numrows == 0: # Empty table or just no match? from s3 import S3CRUD table = resource.table if "deleted" in table: available_records = db(table.deleted != True) else: available_records = db(table._id > 0) if available_records.select(table._id, limitby=(0, 1)).first(): msg = DIV(S3CRUD.crud_string(resource.tablename, "msg_no_match"), _class="empty") else: msg = DIV(S3CRUD.crud_string(resource.tablename, "msg_list_empty"), _class="empty") data = msg else: # Render the list ajaxurl = URL(c="default", f="audit", args="datalist_f.dl") popup_url = URL(c="default", f="audit", args="datalist.popup") dl = datalist.html(ajaxurl=ajaxurl, pagesize=4, popup_url=popup_url, popup_title=T("Updates"), ) data = dl if is_logged_in and org_group_id: # Add a Filter filter_widgets = [S3OptionsFilter("user_id$org_group_id", label = "", # Can't just use "" as this is then omitted from rendering options = {"*": T("All"), org_group_id: T("My Community"), }, cols = 2, multiple = False, ), ] filter_submit_url = URL(c="default", f="index") filter_ajax_url = URL(c="default", f="audit", args=["filter.options"]) filter_form = S3FilterForm(filter_widgets, filter_manager = False, formstyle = filter_formstyle, clear = False, submit = True, ajax = True, url = filter_submit_url, ajaxurl = filter_ajax_url, _class = "filter-form", _id = "%s-filter-form" % list_id ) filter_form = filter_form.html(resource, request.get_vars, target=list_id, ) output["updates"] = data output["filter_form"] = filter_form # Add JavaScript appname = request.application debug = s3.debug scripts_append = s3.scripts.append if debug: # Infinite Scroll doesn't make sense here, but currently required by dataLists.js scripts_append("/%s/static/scripts/jquery.infinitescroll.js" % appname) scripts_append("/%s/static/scripts/jquery.viewport.js" % appname) scripts_append("/%s/static/scripts/S3/s3.dataLists.js" % appname) else: scripts_append("/%s/static/scripts/S3/s3.dataLists.min.js" % appname) self._view(THEME, "index.html") return output
def person(): """ Missing Persons Registry (Match Finder) """ table = s3db.pr_person s3.crud_strings["pr_person"].update( title_display=T("Missing Person Details"), title_list=T("Missing Persons"), label_list_button=T("List Missing Persons"), msg_list_empty=T("No Persons found"), msg_no_match=T("No Persons currently reported missing")) s3db.configure( "pr_group_membership", list_fields=["id", "group_id", "group_head", "comments"], ) s3db.configure( "pr_person", deletable=False, editable=False, listadd=False, list_fields=[ "id", "first_name", "middle_name", "last_name", "picture", "gender", "age_group" ], ) def prep(r): if not r.id and not r.method and not r.component: body_id = r.get_vars.get("match", None) body = db(db.dvi_body.id == body_id).select(db.dvi_body.pe_label, limitby=(0, 1)).first() label = body and body.pe_label or "#%s" % body_id if body_id: query = dvi_match_query(body_id) r.resource.add_filter(query) s3.crud_strings["pr_person"].update( #subtitle_list = T("Candidate Matches for Body %s" % label), msg_no_match=T("No matching records found")) return True s3.prep = prep # @ToDo: Add to crud_fields field = s3db.pr_person_details.missing.default = True table.age_group.readable = True table.age_group.writable = True # Show only missing persons in list views if len(request.args) == 0: from s3 import FS s3.filter = (FS("person_details.missing") == True) mpr_tabs = [ (T("Missing Report"), "missing_report"), (T("Person Details"), None), (T("Physical Description"), "physical_description"), (T("Images"), "image"), (T("Identity"), "identity"), (T("Address"), "address"), (T("Contact Data"), "contact"), (T("Journal"), "note"), ] rheader = lambda r: s3db.pr_rheader(r, tabs=mpr_tabs) return s3_rest_controller( "pr", "person", main="first_name", extra="last_name", rheader=rheader, )
def __call__(self): response = current.response s3 = response.s3 s3db = current.s3db output = {} self._view(THEME, "index.html") # Map # Enable Layers by default callback = '''S3.gis.show_map() var layer,layers=S3.gis.maps.default_map.layers for(var i=0,len=layers.length;i<len;i++){ layer=layers[i] layer_name=layer.name if((layer_name=='Alerts')||(layer_name=='Incidents')||(layer_name=='Tasks')){layer.setVisibility(true)}}''' gis = current.gis #config = gis.get_config() #config.zoom = 8 map = gis.show_map(width=600, height=600, callback=callback, catalogue_layers=True, collapsed=True, save=False, ) output["map"] = map # Alerts Data List resource = s3db.resource("cms_post") # Only show Alerts #resource.add_filter(FS("series_id$name").belongs(["Alert"])) #resource.add_filter(FS("post.series_id") != None) # Only show Open Alerts resource.add_filter(FS("expired") == False) # Only show Alerts which are linked to Open Incidents or not linked to any Incident resource.add_filter((FS("incident.closed") == False) | (FS("incident.id") == None)) list_id = "cms_post_datalist" list_fields = [#"series_id", "location_id", "date", "body", "created_by", "created_by$organisation_id", "document.file", "event_post.event_id", "event_post.incident_id", ] # Order with most recent Alert first orderby = "cms_post.date desc" datalist, numrows, ids = resource.datalist(fields = list_fields, #start = None, limit = 5, list_id = list_id, orderby = orderby, layout = s3db.cms_post_list_layout ) ajax_url = URL(c="cms", f="post", args="datalist.dl", vars={"list_id": list_id}) output[list_id] = datalist.html(ajaxurl = ajax_url, pagesize = 5 ) # Incidents Data List resource = s3db.resource("event_incident") # Only show Open Incidents resource.add_filter(FS("closed") == False) list_id = "event_incident_datalist" list_fields = ["name", "location_id", "date", "modified_by", "organisation_id", "comments", ] # Order with most recent Incident first orderby = "event_incident.date desc" datalist, numrows, ids = resource.datalist(fields = list_fields, #start = None, limit = 5, list_id = list_id, orderby = orderby, layout = s3db.event_incident_list_layout ) ajax_url = URL(c="event", f="incident", args="datalist.dl", vars={"list_id": list_id}) output[list_id] = datalist.html(ajaxurl = ajax_url, pagesize = 5 ) # Tasks Data List resource = s3db.resource("project_task") # Only show Active Tasks active_statuses = s3db.project_task_active_statuses resource.add_filter(FS("status").belongs(active_statuses)) # Only show Tasks which are linked to Open Incidents or not linked to any Incident resource.add_filter((FS("incident.incident_id$closed") == False) | (FS("incident.id") == None)) list_id = "project_task_datalist" list_fields = ["name", "description", "comments", "location_id", "priority", "status", "date_due", "pe_id", "task_project.project_id", #"organisation_id$logo", "modified_by", "source_url" ] # Order with most urgent Task first orderby = "project_task.date_due asc" datalist, numrows, ids = resource.datalist(fields = list_fields, #start = None, limit = 5, list_id = list_id, orderby = orderby, layout = s3db.project_task_list_layout ) ajax_url = URL(c="project", f="task", args="datalist.dl", vars={"list_id": list_id}) output[list_id] = datalist.html(ajaxurl = ajax_url, pagesize = 5 ) # MCOP RSS News Feed #s3.external_stylesheets.append("//www.google.com/uds/solutions/dynamicfeed/gfdynamicfeedcontrol.css") s3.scripts.append("//www.google.com/jsapi?key=notsupplied-wizard") s3.scripts.append("//www.google.com/uds/solutions/dynamicfeed/gfdynamicfeedcontrol.js") # feedCycleTime: milliseconds before feed is reloaded (5 minutes) s3.js_global.append( """ function LoadDynamicFeedControl(){ var feeds=[{title:'News', url:'http://psmcop.org/?feed=rss2'}] var options={ feedCycleTime:300000, numResults:5, stacked:true, horizontal:false, } new GFdynamicFeedControl(feeds,'feed-control',options); } google.load('feeds','1'); google.setOnLoadCallback(LoadDynamicFeedControl); """ ) # Data Buttons # Description of available data from s3db.cms import S3CMS resource_content = S3CMS.resource_content for item in response.menu: item["cms"] = resource_content(module = item["c"], resource = item["f"]) return output