diff --git a/VERSION b/VERSION index e60c0c696a..a64e8a0421 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4bcacee (2015-09-30 13:34:55) \ No newline at end of file +nursix-1.1.0-devel-2841-gdd96e92 (2015-09-30 15:09:43) diff --git a/controllers/cap.py b/controllers/cap.py index b9260e896f..0ee71a9cdd 100644 --- a/controllers/cap.py +++ b/controllers/cap.py @@ -105,7 +105,7 @@ def alert(): tablename = "cap_alert" def prep(r): - + if r.representation == "dl": # DataList: match list_layout list_fields = ["info.headline", @@ -129,8 +129,8 @@ def prep(r): "scope", "info.event_type_id", ] - - s3db.configure(tablename, + + s3db.configure(tablename, list_fields = list_fields, ) @@ -536,7 +536,7 @@ def custom_widget_fn_3(r, **attr): # Do not show for the actual area field = atable[f] field.writable = field.readable = False - + # Auto assign the info_id to area if only one info segment itable = s3db.cap_info rows = db(itable.alert_id == r.record.id).select(itable.id) @@ -544,7 +544,7 @@ def custom_widget_fn_3(r, **attr): field = atable.info_id field.default = rows.first().id field.writable = field.readable = False - + elif r.component_name == "resource": atable = r.component.table # Limit to those for this Alert @@ -554,7 +554,7 @@ def custom_widget_fn_3(r, **attr): filterby="alert_id", filter_opts=(r.id,), )) - + # Auto assign the info_id to area if only one info segment itable = s3db.cap_info rows = db(itable.alert_id == r.record.id).select(itable.id) @@ -625,7 +625,7 @@ def postp(r, output): # First get the info_id itable = s3db.cap_info rows = db(itable.alert_id == lastid).select(itable.id) - + rtable = s3db.cap_resource r_unwanted_fields = set(("deleted_rb", "owned_by_user", @@ -758,7 +758,7 @@ def template(): viewing = request.vars["viewing"] tablename = "cap_alert" - + if viewing: table, _id = viewing.strip().split(".") if table == tablename: @@ -771,11 +771,11 @@ def prep(r): "incidents", "info.category", ] - + s3db.configure(tablename, list_fields = list_fields, ) - + for f in ("identifier", "msg_type"): field = atable[f] field.writable = False @@ -809,10 +809,10 @@ def prep(r): filterby="alert_id", filter_opts=(r.id,), )) - + # Set is_template to true as only accessed by template rtable.is_template.default = True - + # Auto assign the info_id to area if only one info segment itable = s3db.cap_info rows = db(itable.alert_id == r.record.id).select(itable.id) @@ -820,7 +820,7 @@ def prep(r): field = rtable.info_id field.default = rows.first().id field.writable = field.readable = False - + s3.crud_strings[tablename] = Storage( label_create = T("Create Template"), title_display = T("Template"), @@ -868,19 +868,19 @@ def area(): Should only be accessed for defining area template """ - def prep(r): + def prep(r): artable = s3db.cap_area for f in ("alert_id", "info_id"): field = artable[f] field.writable = False field.readable = False - + # Area create from this controller is template artable.is_template.default = True - + return True s3.prep = prep - + def postp(r, output): if r.interactive and r.component and r.component_name == "area_location": # Modify action button to open cap/area_location directly. @@ -908,7 +908,7 @@ def warning_priority(): # ----------------------------------------------------------------------------- def priority_get(): - + try: event_type_id = request.args[0] except: @@ -919,7 +919,7 @@ def priority_get(): except: result = current.xml.json_message(False, 400, "Invalid Event Type!") else: - # Get Event Name for Event ID + # Get Event Name for Event ID etable = s3db.event_event_type item = db(etable.id == event_type_id).select(etable.name, limitby=(0, 1) @@ -931,7 +931,7 @@ def priority_get(): else: wptable = s3db.cap_warning_priority query = (wptable.event_type == event_type_name) - + rows = db(query).select(wptable.id, wptable.name, orderby = wptable.id) @@ -942,26 +942,26 @@ def priority_get(): [{"id": "", "name": T("Undefined")}] result = jsons(row_dict) else: - rows = db(wptable.event_type == "others").select(wptable.id, + rows = db(wptable.event_type == "others").select(wptable.id, wptable.name, orderby = wptable.id) - + row_dict = [{"id": r.id, "name": T(r.name)} for r in rows] + \ [{"id": "", "name": T("Undefined")}] result = jsons(row_dict) finally: response.headers["Content-Type"] = "application/json" return result - + # ----------------------------------------------------------------------------- def compose(): """ Send message to the people with role of Alert Approval """ - + # For SAMBRO, permission is checked by the Authentication Roles but the permission # should be checked if CAP module is enabled - if settings.has_module("msg"): + if settings.has_module("msg"): # Notify People with the role of Alert Approval via email and SMS pe_ids = get_vars.get("pe_ids") alert_id = get_vars.get("cap_alert.id") @@ -972,7 +972,7 @@ def compose(): msg.send_by_pe_id(pe_ids, subject, message) msg.send_by_pe_id(pe_ids, subject, message, contact_method = "SMS") session.confirmation = T("Alert Approval Notified") - + redirect(URL(c="cap", f="alert")) # ----------------------------------------------------------------------------- @@ -1270,19 +1270,19 @@ def set_priority_js(): """ Output json for priority field """ wptable = s3db.cap_warning_priority - - rows = db(wptable).select(wptable.name, - wptable.urgency, + + rows = db(wptable).select(wptable.name, + wptable.urgency, wptable.severity, - wptable.certainty, + wptable.certainty, wptable.color_code, orderby = wptable.name, ) - + from gluon.serializers import json as jsons p_settings = [(T(r.name), r.urgency, r.severity, r.certainty, r.color_code)\ for r in rows] - + priority_conf = '''S3.cap_priorities=%s''' % jsons(p_settings) js_global = s3.js_global if not priority_conf in js_global: diff --git a/controllers/project.py b/controllers/project.py index de26aef089..b62b8918e2 100644 --- a/controllers/project.py +++ b/controllers/project.py @@ -230,7 +230,7 @@ def prep(r): filter_opts=[r.id], ) # @ToDo: end_date cannot be before Project Start - #ctable.end_date.requires = + #ctable.end_date.requires = # Have a filter for indicator in indicator data report #if r.method == "report": @@ -1101,7 +1101,7 @@ def dt_row_actions(component): field.readable = field.writable = False return True - s3.prep = prep + s3.prep = prep return s3_rest_controller() diff --git a/controllers/req.py b/controllers/req.py index f923351fc9..1b981712ba 100644 --- a/controllers/req.py +++ b/controllers/req.py @@ -318,7 +318,7 @@ def prep(r): else: if r.id: table.is_template.readable = table.is_template.writable = False - + method = r.method if method in (None, "create"): # Hide fields which don't make sense in a Create form @@ -644,7 +644,7 @@ def postp(r, output): # Create form # @ToDo: DRY if not settings.get_req_inline_forms(): - form_vars = output["form"].vars + form_vars = output["form"].vars type = form_vars.type if type == "1": # Stock: Open Tab for Items @@ -786,7 +786,7 @@ def postp(r, output): # Create form # @ToDo: DRY if not settings.get_req_inline_forms(): - form_vars = output["form"].vars + form_vars = output["form"].vars req_type = form_vars.type if req_type == "1": # Stock: Open Tab for Items diff --git a/models/tasks.py b/models/tasks.py index 1e81a84d7c..db634f1754 100644 --- a/models/tasks.py +++ b/models/tasks.py @@ -43,24 +43,24 @@ def maintenance(period="daily"): # ----------------------------------------------------------------------------- if settings.has_module("cap"): - + # ----------------------------------------------------------------------------- def cap_ftp_sync(user_id=None): """ Get all the ftp repository and synchronize them """ - + if user_id: # Authenticate auth.s3_impersonate(user_id) - + rows = db(s3db.sync_repository.apitype == "ftp").select() - + if rows: sync = current.sync for row in rows: sync.synchronize(row) - + tasks["cap_ftp_sync"] = cap_ftp_sync - + # ----------------------------------------------------------------------------- if settings.has_module("doc"): diff --git a/modules/s3/s3gis.py b/modules/s3/s3gis.py index d3e28d13b9..8fc32f26e4 100644 --- a/modules/s3/s3gis.py +++ b/modules/s3/s3gis.py @@ -4684,7 +4684,7 @@ def propagate(parent): @param parent: gis_location id of parent """ - # No need to filter out deleted since the parent FK is None for these records + # No need to filter out deleted since the parent FK is None for these records query = (table.parent == parent) & \ (table.inherited == True) rows = db(query).select(*fields) diff --git a/modules/s3/s3grouped.py b/modules/s3/s3grouped.py index a514654763..31bcdb8da5 100644 --- a/modules/s3/s3grouped.py +++ b/modules/s3/s3grouped.py @@ -1364,6 +1364,14 @@ def check_label(colname): if key: output["k"] = key + representations = None + renderer = represent.get(key) if represent else None + + # Bulk represent? + if renderer and hasattr(renderer, "bulk"): + values = [group[key] for group in self.groups] + representations = renderer.bulk(values) + data = [] add_group = data.append for group in self.groups: @@ -1376,12 +1384,11 @@ def check_label(colname): # Add subgroup attribute value value = group[key] - renderer = represent.get(key) if represent else None - if renderer is None: - value = s3_unicode(value).encode("utf-8") - else: - # @todo: call bulk-represent if available - value = s3_unicode(renderer(value)).encode("utf-8") + if representations is not None: + value = representations.get(value) + elif renderer is not None: + value = renderer(value) + value = s3_unicode(value).encode("utf-8") gdict["v"] = value add_group(gdict) diff --git a/modules/s3/s3msg.py b/modules/s3/s3msg.py index cc6176d335..25892fb174 100644 --- a/modules/s3/s3msg.py +++ b/modules/s3/s3msg.py @@ -661,7 +661,7 @@ def dispatch_to_pe_id(pe_id, ptable.on((ptable.id == ttable.person_id) & \ (ptable.deleted != True)), ] - + atable = s3db.table("deploy_alert") if atable: ltable = db.deploy_alert_recipient @@ -2061,7 +2061,7 @@ def poll_twitter(channel_id): Function to call to fetch tweets into msg_twitter table - called via Scheduler or twitter_inbox controller - http://tweepy.readthedocs.org/en/v3.3.0/api.html + http://tweepy.readthedocs.org/en/v3.3.0/api.html """ try: diff --git a/modules/s3/s3translate.py b/modules/s3/s3translate.py index a07ffb8d91..a688770131 100644 --- a/modules/s3/s3translate.py +++ b/modules/s3/s3translate.py @@ -872,7 +872,7 @@ def get_database_strings(all_template_flag): reusable_field = s3db.get(fieldname) # Excludes lambdas which are in defaults() # i.e. reusable fields in disabled modules - if reusable_field and isinstance(reusable_field, S3ReusableField): + if reusable_field and isinstance(reusable_field, S3ReusableField): represent = reusable_field.attr.represent if hasattr(represent, "translate"): translate = represent.translate diff --git a/modules/s3/sync_adapter/ftp.py b/modules/s3/sync_adapter/ftp.py index f5566c49d0..42412f9a76 100644 --- a/modules/s3/sync_adapter/ftp.py +++ b/modules/s3/sync_adapter/ftp.py @@ -41,7 +41,7 @@ from cStringIO import StringIO # Faster, where available except: from StringIO import StringIO - + # ============================================================================= class S3SyncAdapter(S3SyncBaseAdapter): """ @@ -49,7 +49,7 @@ class S3SyncAdapter(S3SyncBaseAdapter): currently used by CAP """ - + # ------------------------------------------------------------------------- def register(self): """ @@ -60,7 +60,7 @@ def register(self): # No registration required return True - + # ------------------------------------------------------------------------- def login(self): """ @@ -68,15 +68,15 @@ def login(self): @return: None if successful, otherwise the error """ - + repository = self.repository url = repository.url error = None - + if not url: error = "Remote URL required for FTP Push" - else: - import ftplib + else: + import ftplib try: ftp_connection = ftplib.FTP(url) except ftplib.all_errors: @@ -86,13 +86,13 @@ def login(self): ftp_connection.login(repository.username, repository.password) except ftplib.error_perm: error = sys.exc_info()[1] - + self.ftp_connection = ftp_connection - + if error: current.log.debug(error) return error - + # ------------------------------------------------------------------------- def pull(self, task, onconflict=None): """ @@ -137,28 +137,28 @@ def push(self, task): log = repository.log remote = False output = None - + current.log.debug("S3SyncRepository.push(%s, %s)" % (repository.url, resource_name)) - + # Define the resource resource = current.s3db.resource(resource_name, # FTP remote deletion is not supported yet #include_deleted=True, ) - + # Apply sync filters for this task filters = current.sync.get_filters(task.id) table = resource.table tablename = resource.tablename - + if filters: queries = S3URLQuery.parse(resource, filters[tablename]) [resource.add_filter(q) for a in queries for q in queries[a]] # Filter to records after last push msince = task.last_push - + if msince: strategy = task.strategy created = "create" in strategy @@ -172,19 +172,19 @@ def push(self, task): (table.modified_on > msince) else: mtime_filter = None - + if mtime_filter: resource.add_filter(mtime_filter) - - mtime = resource.muntil + + mtime = resource.muntil # Get the ID of the resource after filter and msince resource_ids = resource.get_id() - + # No Changes since last push? if resource_ids is None: message = "No Changes since last push" result = log.WARNING - else: + else: # Filename settings = current.deployment_settings # Placeholders for filename @@ -193,32 +193,32 @@ def push(self, task): "resource": resource_name, "public_url": settings.get_base_public_url(), } - + from string import Template filename = resource.get_config("upload_filename") if not filename: filename = settings.get_sync_upload_filename() filename = Template(filename).safe_substitute(s="%(systemname_short)s", r="%(resource)s") - filename = filename % placeholders + filename = filename % placeholders # Get Representation representation = task.representation filename = ("%s.%s") % (filename, representation) - + # FTP Transfer remote = True import ftplib - ftp_connection = self.ftp_connection + ftp_connection = self.ftp_connection if task.multiple_file: if type(resource_ids) is not list: - resource_ids = [resource_ids] - + resource_ids = [resource_ids] + for resource_id in resource_ids: resource.clear_query() resource.add_filter(FS("id") == resource_id) data = self._get_data(resource, representation) - - try: + + try: ftp_connection.storbinary("STOR %s" % filename, StringIO(data)) except ftplib.error_perm: @@ -228,12 +228,12 @@ def push(self, task): else: message = "FTP Transfer Successful" result = log.SUCCESS - + current.log.debug(message) else: data = self._get_data(resource, representation) - - try: + + try: ftp_connection.storbinary("STOR %s" % filename, StringIO(data)) except ftplib.error_perm: @@ -243,12 +243,12 @@ def push(self, task): else: message = "FTP Transfer Successful" result = log.SUCCESS - + current.log.debug(message) - + # Quit the connection here ftp_connection.quit() - + # Log the operation log.write(repository_id = repository.id, resource_name = resource_name, @@ -263,39 +263,39 @@ def push(self, task): if output is not None: mtime = None return output, mtime - + # ------------------------------------------------------------------------- # Internal methods: # ------------------------------------------------------------------------- def _get_data(self, resource, representation): """ Returns the representation data for the resource """ - + request = S3Request(prefix = resource.prefix, name = resource.name, extension = representation, ) - + if request.transformable(): return resource.export_xml(stylesheet = request.stylesheet(), pretty_print = True, ) - - else: + + else: if representation == "csv": exporter = S3Exporter().csv - - # @ToDo use CRUD + + # @ToDo use CRUD #elif representation == "html": - + elif representation == "pdf": exporter = S3Exporter().pdf - + elif representation == "xls": exporter = S3Exporter().xls - + elif representation == "json": exporter = S3Exporter().json - + return exporter(resource) - + # End ========================================================================= diff --git a/modules/s3db/cap.py b/modules/s3db/cap.py index bdbf08be85..ada1ca5b05 100644 --- a/modules/s3db/cap.py +++ b/modules/s3db/cap.py @@ -390,7 +390,7 @@ def model(self): writable = False, ), *s3_meta_fields()) - + list_fields = [(T("Sent"), "sent"), "scope", "info.priority", @@ -482,7 +482,7 @@ def model(self): self.set_method("cap", "alert", method = "import_feed", action = CAPImportFeed()) - + self.set_method("cap", "alert", method = "assign", action = self.cap_AssignArea()) @@ -560,7 +560,7 @@ def model(self): # --------------------------------------------------------------------- # Warning Priorities for CAP - + tablename = "cap_warning_priority" define_table(tablename, Field("priority_rank", "integer", @@ -592,9 +592,9 @@ def model(self): label = T("Color Code"), ), *s3_meta_fields()) - + priority_represent = S3Represent(lookup=tablename) - + crud_strings[tablename] = Storage( label_create = T("Create Warning Priority"), title_display = T("Warning Priority Details"), @@ -608,11 +608,11 @@ def model(self): msg_record_deleted = T("Warning Priority removed"), msg_list_empty = T("No Warning Priorities currently registered") ) - + configure(tablename, deduplicate = S3Duplicate(primary=("event_type", "name")), ) - + # --------------------------------------------------------------------- # CAP info priority # @ToDo: i18n: Need label=T("") @@ -665,7 +665,7 @@ def model(self): 'trigger':'event_type_id', 'target':'priority', 'lookupURL':S3.Ap.concat('/cap/priority_get/'), - 'lookupResource':'event_type' + 'lookupResource':'event_type' })''' ), Field("response_type", "list:string", # 0 or more allowed @@ -694,14 +694,14 @@ def model(self): Field("severity", represent = lambda opt: \ cap_info_severity_opts.get(opt, UNKNOWN_OPT), - # Empty For Template, checked onvalidation hook + # Empty For Template, checked onvalidation hook requires = IS_EMPTY_OR( IS_IN_SET(cap_info_severity_opts)), ), Field("certainty", represent = lambda opt: \ cap_info_certainty_opts.get(opt, UNKNOWN_OPT), - # Empty For Template, checked onvalidation hook + # Empty For Template, checked onvalidation hook requires = IS_EMPTY_OR( IS_IN_SET(cap_info_certainty_opts)), ), @@ -859,7 +859,7 @@ def model(self): ], ), ) - configure(tablename, + configure(tablename, # Shouldn't be required if all UI actions go through alert controller & XSLT configured appropriately create_onaccept = update_alert_id(tablename), crud_form = crud_form, @@ -923,17 +923,17 @@ def model(self): ), Field("altitude", "integer", # Feet above Sea-level in WGS84 (Specific or Minimum is using a range) label = T("Altitude"), - ), + ), Field("ceiling", "integer", # Feet above Sea-level in WGS84 (Maximum) label = T("Ceiling"), - ), + ), # Only used for Templates self.event_type_id(script = ''' $.filterOptionsS3({ 'trigger':'event_type_id', 'target':'priority', 'lookupURL':S3.Ap.concat('/cap/priority_get/'), - 'lookupResource':'event_type' + 'lookupResource':'event_type' })''' ), # Only used for Templates @@ -1158,27 +1158,27 @@ def generate_sender(): return "" return "%s/%d" % (current.xml.domain, user_id) - + # ------------------------------------------------------------------------- @staticmethod def generate_source(): """ Generate a source for CAP alert """ - return "%s@%s" % (current.xml.domain, + return "%s@%s" % (current.xml.domain, current.deployment_settings.get_base_public_url()) # ------------------------------------------------------------------------- - @staticmethod + @staticmethod def get_expirydate(): """ Default Expiry date based on the expire offset """ - + return current.request.utcnow + \ datetime.timedelta(days = current.deployment_settings.\ get_cap_expire_offset()) - + # ------------------------------------------------------------------------- @staticmethod def cap_template_represent(id, row=None): @@ -1302,20 +1302,20 @@ def cap_info_onvalidation(form): current.T("'Severity' field is mandatory") if not form_vars.get("certainty"): form.errors["certainty"] = \ - current.T("'Certainty' field is mandatory") - + current.T("'Certainty' field is mandatory") + # ------------------------------------------------------------------------- @staticmethod def cap_alert_approve(record=None): """ Update the approved_on field when alert gets approved """ - + if not record: return - - alert_id = record["id"] - + + alert_id = record["id"] + # Update approved_on at the time the alert is approved if alert_id: db = current.db @@ -1328,15 +1328,15 @@ class S3CAPAreaNameModel(S3Model): CAP Name Model: -local names for CAP Area """ - + names = ("cap_area_name", ) - + def model(self): - + T = current.T l10n_languages = current.deployment_settings.get_L10n_languages() - + # --------------------------------------------------------------------- # Local Names # @@ -1356,11 +1356,11 @@ def model(self): ), s3_comments(), *s3_meta_fields()) - + self.configure(tablename, deduplicate = S3Duplicate(primary=("area_id", "language")), ) - + # Pass names back to global scope (s3.*) return {} @@ -1462,7 +1462,7 @@ def cap_rheader(r): _target="_blank", ) - # Display 'Submit for Approval' based on permission + # Display 'Submit for Approval' based on permission # and deployment settings if not current.request.get_vars.get("_next") and \ not r.record.approved_by and \ @@ -1478,13 +1478,13 @@ def cap_rheader(r): group_members = current.auth.s3_group_members user_pe_id = current.auth.s3_user_pe_id for group_row in group_rows: - group_id = group_row.id + group_id = group_row.id user_ids = group_members(group_id) # List of user_ids pe_ids = [] # List of pe_ids pe_append = pe_ids.append for user_id in user_ids: pe_append(user_pe_id(int(user_id))) - + submit_btn = A(T("Submit for Approval"), _href = URL(f = "compose", vars = {"cap_alert.id": record.id, @@ -1513,12 +1513,12 @@ def cap_rheader(r): artable = s3db.cap_area query = (artable.is_template == True) & \ (artable.deleted == False) - + template_area_rows = current.db(query)._select(artable.id, limitby=(0, 1)) if template_area_rows: tabs.insert(2, (T("Predefined Areas"), "assign")) - + # Display "Copy" Button to copy record from the opened info if r.component_name == "info" and \ r.component_id: @@ -1534,7 +1534,7 @@ def cap_rheader(r): copy_btn = None else: copy_btn = None - + rheader_tabs = s3_rheader_tabs(r, tabs) rheader = DIV(TABLE(TR(TH("%s: " % T("Alert")), @@ -1549,7 +1549,7 @@ def cap_rheader(r): ) if copy_btn: rheader.insert(1, TR(TD(copy_btn))) - + if submit_btn: rheader.insert(1, TR(TD(submit_btn))) @@ -1557,10 +1557,10 @@ def cap_rheader(r): # Used only for Area Templates tabs = [(T("Area"), None), ] - + if current.deployment_settings.get_L10n_translate_cap_area(): tabs.insert(1, (T("Local Names"), "name")) - + rheader_tabs = s3_rheader_tabs(r, tabs) rheader = DIV(TABLE(TR(TH("%s: " % T("Alert")), TD(A(s3db.cap_alert_represent(record.alert_id), @@ -2010,7 +2010,7 @@ def cap_alert_list_layout(list_id, item_id, resource, rfields, record): _href = URL(c="cap", f="alert", args=[record_id, "profile"]) else: _href = URL(c="cap", f="public", args=[record_id, "profile"]) - + headline = A(headline, _href = _href, _target = "_blank", @@ -2067,7 +2067,7 @@ def add_area_from_template(area_id, alert_id): """ Add an area from a Template along with its components Location and Tag """ - + afieldnames = ("name", "altitude", "ceiling", @@ -2078,32 +2078,32 @@ def add_area_from_template(area_id, alert_id): "value", "comments", ) - + db = current.db s3db = current.s3db atable = s3db.cap_area itable = s3db.cap_info ltable = s3db.cap_area_location ttable = s3db.cap_area_tag - + # Create Area Record from Template atemplate = db(atable.id == area_id).select(*afieldnames, limitby=(0, 1)).first() rows = db(itable.alert_id == alert_id).select(itable.id) - + if len(rows) == 1: info_id = rows.first().id else: info_id = "" - + adata = {"is_template": False, "alert_id": alert_id, "info_id": info_id, } for field in afieldnames: adata[field] = atemplate[field] - aid = atable.insert(**adata) - + aid = atable.insert(**adata) + # Add Area Location Components of Template ltemplate = db(ltable.area_id == area_id).select(*lfieldnames) for rows in ltemplate: @@ -2113,9 +2113,9 @@ def add_area_from_template(area_id, alert_id): for field in lfieldnames: ldata[field] = rows[field] lid = ltable.insert(**ldata) - + # Add Area Tag Components of Template - ttemplate = db(ttable.area_id == area_id).select(*tfieldnames) + ttemplate = db(ttable.area_id == area_id).select(*tfieldnames) for row in ttemplate: tdata = {"area_id": aid, "alert_id": alert_id, @@ -2123,7 +2123,7 @@ def add_area_from_template(area_id, alert_id): for field in tfieldnames: tdata[field] = row[field] tid = ttable.insert(**tdata) - + return aid # ============================================================================= @@ -2251,20 +2251,20 @@ def apply_method(self, r, **attr): # The record ID of the alert the method is called for alert_id = r.id - + # Requires permission to update this alert - authorised = current.auth.s3_has_permission("update", "cap_alert", + authorised = current.auth.s3_has_permission("update", "cap_alert", record_id=alert_id) if not authorised: - r.unauthorised() - - T = current.T + r.unauthorised() + + T = current.T s3db = current.s3db response = current.response - + # Filter to limit the selection of areas area_filter = (FS("is_template") == True) - + if r.http == "POST": # Template areas have been selected @@ -2288,7 +2288,7 @@ def apply_method(self, r, **attr): else: filters = None - query = area_filter & (~(FS("id").belongs(selected))) + query = area_filter & (~(FS("id").belongs(selected))) aresource = s3db.resource("cap_area", filter = query, vars = filters) @@ -2458,11 +2458,11 @@ def apply_method(self, r, **attr): # ----------------------------------------------------------------------------- class cap_AreaRepresent(S3Represent): """ Representation of CAP Area """ - + def __init__(self, show_link=False, multiple=False): - + settings = current.deployment_settings # Translation using cap_area_name & not T() translate = settings.get_L10n_translate_cap_area() @@ -2470,28 +2470,28 @@ def __init__(self, language = current.session.s3.language if language == settings.get_L10n_default_language(): translate = False - + super(cap_AreaRepresent, self).__init__(lookup="cap_area", show_link=show_link, translate=translate, multiple=multiple ) - + # ------------------------------------------------------------------------- def lookup_rows(self, key, values, fields=None): """ Custom lookup method for Area(CAP) rows.Parameters key and fields are not used, but are kept for API compatibility reasons. - + @param values: the cap_area IDs """ - + db = current.db s3db = current.s3db artable = s3db.cap_area - + count = len(values) if count == 1: query = (artable.id == values[0]) @@ -2509,7 +2509,7 @@ def lookup_rows(self, key, values, fields=None): left = [ltable.on((ltable.area_id == artable.id) & \ (ltable.language == current.session.s3.language)), ] - + else: left = None @@ -2522,18 +2522,18 @@ def lookup_rows(self, key, values, fields=None): def represent_row(self, row): """ Represent a single Row - + @param row: the cap_area Row """ - + if self.translate: name = row["cap_area_name.name_l10n"] or row["cap_area.name"] else: name = row["cap_area.name"] - + if not name: return self.default - + return s3_unicode(name) - + # END ========================================================================= diff --git a/modules/s3db/project.py b/modules/s3db/project.py index 8eb2cc72b6..e6b01dc9a3 100644 --- a/modules/s3db/project.py +++ b/modules/s3db/project.py @@ -3646,7 +3646,7 @@ def project_organisation_onvalidation(form, lead_role=None): # # Check that total budget isn't exceeded # # - either needs knowledge of exchange rates or forcing that org contribnutions are in same currency as total_budget which doesn't match real world # btable = current.s3db.budget_budget - # total_budget = + # total_budget = # form.errors.amount = \ # current.T("Amount contributed cannot be greater than the total budget.") diff --git a/modules/s3db/stats.py b/modules/s3db/stats.py index 995b4f0d5b..94990e29a7 100644 --- a/modules/s3db/stats.py +++ b/modules/s3db/stats.py @@ -525,7 +525,7 @@ def model(self): # Pass names back to global scope (s3.*) # return dict( - stats_demographic_id = demographic_id, + stats_demographic_id = demographic_id, stats_demographic_rebuild_all_aggregates = self.stats_demographic_rebuild_all_aggregates, stats_demographic_update_aggregates = self.stats_demographic_update_aggregates, stats_demographic_update_location_aggregate = self.stats_demographic_update_location_aggregate,