def latest_records(resource, layout, list_id, limit, list_fields, orderby): """ Display a dataList of the latest records for a resource """ # orderby = resource.table[orderby] datalist, numrows, ids = resource.datalist( fields=list_fields, start=None, limit=limit, list_id=list_id, orderby=orderby, layout=layout ) if numrows == 0: # Empty table or just no match? table = resource.table if "deleted" in table: available_records = current.db(table.deleted != True) else: available_records = current.db(table._id > 0) from s3 import S3CRUD 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 dl = datalist.html() data = dl return data
def __init__(self, label = None, c = None, f = None, t = None, m = "create", args = None, vars = None, info = None, title = None, tooltip = None, _id = None, ): """ Args: c: the target controller f: the target function t: the target table (defaults to c_f) m: the URL method (will be appended to args) args: the argument list vars: the request vars (format="popup" will be added automatically) label: the link label (falls back to label_create) info: hover-title for the label title: the tooltip title tooltip: the tooltip text _id: the HTML ID of the button """ if label is None: label = title if info is None: info = title if c is None: # Fall back to current controller c = current.request.controller if label is None: if t is None: t = "%s_%s" % (c, f) if m == "create": # Fall back to label_create label = S3CRUD.crud_string(t, "label_create") elif m == "update": # Fall back to label_update label = S3CRUD.crud_string(t, "label_update") super(S3PopupLink, self).__init__(label, c = c, f = f, t = t, m = m, args = args, vars = vars, info = info, title = title, tooltip = tooltip, mandatory = True, _id = _id, )
def postp(r, output): if isinstance(output, dict): # Inject controller name in dt action buttons if r.component: action_args = [controller, r.id, r.component.alias, '[id]'] else: action_args = [controller, '[id]'] action_url = lambda action: URL(args=action_args + [action], vars={}) S3CRUD.action_buttons( r, read_url=action_url('read'), update_url=action_url('update'), delete_url=action_url('delete'), ) # Inject controller name in CRUD buttons buttons = output.get("buttons") if buttons: path = "%s/%s" % (r.controller, r.function) full = "%s/%s" % (path, controller) for element in buttons.values(): if not hasattr(element, "attributes"): continue url = element.attributes.get("_href") if url: element["_href"] = url.replace(path, full) return output
def latest_records(resource, layout, list_id, limit, list_fields, orderby): """ Display a dataList of the latest records for a resource """ #orderby = resource.table[orderby] datalist, numrows = resource.datalist( fields=list_fields, start=None, limit=limit, list_id=list_id, orderby=orderby, layout=layout, ) # NB If this list has a create function then cannot use this approach as # it won't refresh the page after the 1st record is created! if numrows == 0: # Empty table or just no match? table = resource.table #if "deleted" in table: available_records = current.db(table.deleted != True) #else: # available_records = current.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 data = datalist.html() return data
def postp(r, output): if isinstance(output, dict): # Inject controller name in dt action buttons if r.component: action_args = [controller, r.id, r.component.alias, '[id]'] else: action_args = [controller, '[id]'] action_url = lambda action: URL(args=action_args + [action], vars={}) S3CRUD.action_buttons(r, read_url = action_url('read'), update_url = action_url('update'), delete_url = action_url('delete'), ) # Inject controller name in CRUD buttons buttons = output.get("buttons") if buttons: path = "%s/%s" % (r.controller, r.function) full = "%s/%s" % (path, controller) for element in buttons.values(): if not hasattr(element, "attributes"): continue url = element.attributes.get("_href") if url: element["_href"] = url.replace(path, full) return output
def custom_postp(r, output): # Call standard postp if callable(standard_postp): output = standard_postp(r, output) if r.interactive and isinstance(output, dict): # Modify Open Button url = URL(c="default", f="index", args=["subscriptions"], vars={"subscription_id": "[id]"}) if not (has_role("ALERT_EDITOR") or \ has_role("ALERT_APPROVER")): S3CRUD.action_buttons(r, read_url=url) else: S3CRUD.action_buttons(r, update_url=url) # Modify Add Button if "form" in output: add_btn = A(T("Create Subscription"), _class="action-btn", _href=URL(c="default", f="index", args=["subscriptions"])) output["showadd_btn"] = add_btn return output
def latest_records(resource, layout, list_id, limit, list_fields, orderby): """ Display a dataList of the latest records for a resource """ #orderby = resource.table[orderby] datalist, numrows, ids = resource.datalist(fields=list_fields, start=None, limit=limit, list_id=list_id, orderby=orderby, layout=layout) if numrows == 0: # Empty table or just no match? table = resource.table if "deleted" in table: available_records = current.db(table.deleted != True) else: available_records = current.db(table._id > 0) from s3 import S3CRUD 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 dl = datalist.html() data = dl return data
def custom_postp(r, output): # Call standard postp if callable(standard_postp): output = standard_postp(r, output) if r.interactive and isinstance(output, dict): # Modify Open Button if manage_recipient and role_check: # Admin based subscription S3CRUD.action_buttons( r, update_url=URL(c="default", f="index", args=["subscriptions"], vars={ "option": "manage_recipient", "subscription_id": "[id]" }), delete_url=URL(c="pr", f="subscription", args=["[id]", "delete"], vars={"option": "manage_recipient"})) else: # self subscription S3CRUD.action_buttons( r, update_url=URL(c="default", f="index", args=["subscriptions"], vars={"subscription_id": "[id]"})) if "form" in output: # Modify Add Button if manage_recipient and role_check: # Admin based subscription add_btn = A(T("Create Subscription"), _class="action-btn", _href=URL( c="default", f="index", args=["subscriptions"], vars={"option": "manage_recipient"})) else: # self subscription add_btn = A(T("Create Subscription"), _class="action-btn", _href=URL(c="default", f="index", args=["subscriptions"])) output["showadd_btn"] = add_btn return output
def custom_postp(r, output): # Call standard postp if callable(standard_postp): output = standard_postp(r, output) if r.interactive and isinstance(output, dict): # Modify Open Button if manage_recipient and role_check: # Admin based subscription S3CRUD.action_buttons( r, update_url=URL( c="default", f="index", args=["subscriptions"], vars={"option": "manage_recipient", "subscription_id": "[id]"}, ), delete_url=URL( c="pr", f="subscription", args=["[id]", "delete"], vars={"option": "manage_recipient"} ), ) else: # self subscription S3CRUD.action_buttons( r, update_url=URL( c="default", f="index", args=["subscriptions"], vars={"subscription_id": "[id]"} ), ) if "form" in output: # Modify Add Button if manage_recipient and role_check: # Admin based subscription add_btn = A( T("Create Subscription"), _class="action-btn", _href=URL( c="default", f="index", args=["subscriptions"], vars={"option": "manage_recipient"} ), ) else: # self subscription add_btn = A( T("Create Subscription"), _class="action-btn", _href=URL(c="default", f="index", args=["subscriptions"]), ) output["showadd_btn"] = add_btn return output
def custom_postp(r, output): # Call standard postp if callable(standard_postp): output = standard_postp(r, output) if r.interactive and isinstance(output, dict): if r.method == "assign": # No Top Menu current.menu.main = "" # Custom View to waste less space inside popup import os response.view = os.path.join(r.folder, "modules", "templates", "WACOP", "views", "assign.html") else: # Summary or Profile pages # Additional styles s3.external_stylesheets += [ "https://cdn.knightlab.com/libs/timeline3/latest/css/timeline.css", "https://fonts.googleapis.com/css?family=Merriweather:400,700|Source+Sans+Pro:400,700", ] if r.method == "summary": # Open the Custom profile page instead of the normal one from gluon import URL from s3 import S3CRUD custom_url = URL(args=["[id]", "custom"]) S3CRUD.action_buttons(r, read_url=custom_url, update_url=custom_url) # System-wide Alert if current.auth.s3_has_role("ADMIN"): # Admin user can edit system_wide alert output["ADMIN"] = True else: output["ADMIN"] = False ptable = s3db.cms_post system_wide = current.db( ptable.name == "SYSTEM_WIDE").select( ptable.body, limitby=(0, 1)).first() if system_wide: output["system_wide"] = system_wide.body else: output["system_wide"] = False return output
def postp(r, output): if r.interactive: if r.method == "datalist" and r.representation != "dl": # Hide side menu current.menu.options = None from s3 import S3CRUD response.view = S3CRUD._view(r, "cms/newsfeed.html") return output
def custom_postp(r, output): # Call standard postp if callable(standard_postp): output = standard_postp(r, output) if r.interactive and isinstance(output, dict): # Modify Update Button update_url = URL(c="default", f="index", args=["subscriptions"], vars={"subscription_id": "[id]"}) S3CRUD.action_buttons(r, update_url=update_url) # Modify Add Button if "form" in output: add_btn = A(T("Create Subscription"), _class="action-btn", _href=URL(c="default", f="index", args=["subscriptions"]) ) output["showadd_btn"] = add_btn return output
def custom_postp(r, output): # Call standard postp if callable(standard_postp): output = standard_postp(r, output) if r.interactive and isinstance(output, dict): # Modify Open Button url = URL(c="default", f="index", args=["subscriptions"], vars={"subscription_id": "[id]"}) if not (has_role("ALERT_EDITOR") or has_role("ALERT_APPROVER")): S3CRUD.action_buttons(r, read_url=url) else: S3CRUD.action_buttons(r, update_url=url) # Modify Add Button if "form" in output: add_btn = A( T("Create Subscription"), _class="action-btn", _href=URL(c="default", f="index", args=["subscriptions"]), ) output["showadd_btn"] = add_btn return output
def custom_postp(r, output): # Call standard postp if callable(standard_postp): output = standard_postp(r, output) if r.interactive and isinstance(output, dict): if r.method == "assign": # No Top Menu current.menu.main = "" # Custom View to waste less space inside popup import os response.view = os.path.join(r.folder, "modules", "templates", "WACOP", "views", "assign.html") else: # Summary or Profile pages # Additional styles s3.external_stylesheets += [ "https://cdn.knightlab.com/libs/timeline3/latest/css/timeline.css", "https://fonts.googleapis.com/css?family=Merriweather:400,700|Source+Sans+Pro:400,700", ] if r.method == "summary": # Open the Custom profile page instead of the normal one from gluon import URL from s3 import S3CRUD custom_url = URL(args=["[id]", "custom"]) S3CRUD.action_buttons(r, read_url=custom_url, update_url=custom_url) # System-wide Alert from templates.WACOP.controllers import custom_WACOP custom = custom_WACOP() output["system_wide"] = custom._system_wide_html() return output
def latest_records(resource, layout, list_id, limit, list_fields, orderby): """ Display a dataList of the latest records for a resource """ #orderby = resource.table[orderby] datalist, numrows = resource.datalist(fields = list_fields, start = None, limit = limit, list_id = list_id, orderby = orderby, layout = layout, ) # NB If this list has a create function then cannot use this approach as # it won't refresh the page after the 1st record is created! if numrows == 0: # Empty table or just no match? table = resource.table #if "deleted" in table: available_records = current.db(table.deleted != True) #else: # available_records = current.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 data = datalist.html() return data
def postp(r, output): if r.record and not r.transformable(): from s3 import S3CRUD, S3XMLContents output = {"item": S3XMLContents(r.record.body).xml()} current.menu.options = None response.view = S3CRUD._view(r, "cms/page.html") if r.record.replies: ckeditor = URL( c="static", f="ckeditor", args="ckeditor.js", ) s3.scripts.append(ckeditor) adapter = URL( c="static", f="ckeditor", args=[ "adapters", "jquery.js", ], ) s3.scripts.append(adapter) # Toolbar options: http://docs.cksource.com/CKEditor_3.x/Developers_Guide/Toolbar js = "".join(('''i18n.reply="''', str(T("Reply")), '''" var img_path=S3.Ap.concat('/static/img/jCollapsible/') var ck_config={toolbar:[['Bold','Italic','-','NumberedList','BulletedList','-','Link','Unlink','-','Smiley','-','Source','Maximize']],toolbarCanCollapse:false,removePlugins:'elementspath'} function comment_reply(id){ $('#cms_comment_post_id__row').hide() $('#cms_comment_post_id__row1').hide() $('#comment-title').html(i18n.reply) $('#cms_comment_body').ckeditorGet().destroy() $('#cms_comment_body').ckeditor(ck_config) $('#comment-form').insertAfter($('#comment-'+id)) $('#cms_comment_parent').val(id) var post_id = $('#comment-'+id).attr('post_id') $('#cms_comment_post_id').val(post_id) }''')) s3.js_global.append(js) 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 __call__(self): T = current.T db = current.db s3db = current.s3db s3 = current.response.s3 session_s3 = current.session.s3 output = {} # Recent Updates etable = s3db.event_event stable = s3db.event_sitrep query = (stable.deleted == False) fields = [ etable.name, stable.id, stable.date, stable.name, stable.summary, ] left = [etable.on(etable.id == stable.event_id)] language = session_s3.language if language != current.deployment_settings.get_L10n_default_language(): ntable = s3db.event_event_name left.append(ntable.on((ntable.event_id == etable.id) & \ (ntable.language == language))) fields.append(ntable.name_l10n) use_local_event_name = True else: use_local_event_name = False sitreps = db(query).select(left=left, limitby=(0, 3), orderby=~stable.date, *fields) len_sitreps = len(sitreps) if len_sitreps == 0: from s3 import S3CRUD recent_updates = DIV(S3CRUD.crud_string("event_sitrep", "msg_list_empty"), _class="empty") else: recent_updates = DIV() rappend = recent_updates.append count = 0 for s in sitreps: count += 1 if use_local_event_name: event_name = s["event_event_name.name_l10n"] or s[ "event_event.name"] else: event_name = s["event_event.name"] if not event_name: event_name = s["event_sitrep.name"] rappend( H3( A( event_name, _href=URL( c="event", f="sitrep", args=[s["event_sitrep.id"]], ), ))) rappend(P(XML(s["event_sitrep.summary"]))) if count != len_sitreps: rappend(HR()) output["recent_updates"] = recent_updates map_btn = A( T("MAP OF CURRENT NEEDS"), #_href = URL(c="default", # f="index", # args="dashboard", # ), _href=URL( c="req", f="need_line", args="map", ), _class="small primary button", ) create_btn = A( T("CREATE A NEED"), _href=URL( c="req", f="need", args="create", ), _class="small primary button", ) output["needs_btn"] = DIV( SPAN(map_btn), SPAN(create_btn), _class="button-group radius", ) output["about_btn"] = A( "%s >" % T("Read More"), _href=URL( c="default", f="about", ), ) # Resources section if current.deployment_settings.has_module("cms"): system_roles = current.auth.get_system_roles() ADMIN = system_roles.ADMIN in session_s3.roles table = s3db.cms_post ltable = s3db.cms_post_module module = "default" resource = "index" query = (ltable.module == module) & \ ((ltable.resource == None) | \ (ltable.resource == resource)) & \ (ltable.post_id == table.id) & \ (table.deleted != True) item = current.db(query).select(table.body, table.id, limitby=(0, 1)).first() if item: if ADMIN: item = DIV( XML(item.body), BR(), A(T("Edit"), _href=URL(c="cms", f="post", args=[item.id, "update"]), _class="action-btn")) else: item = DIV(XML(item.body)) elif ADMIN: if s3.crud.formstyle == "bootstrap": _class = "btn" else: _class = "action-btn" item = A(T("Edit"), _href=URL(c="cms", f="post", args="create", vars={ "module": module, "resource": resource }), _class="%s cms-edit" % _class) else: item = "" else: item = "" output["item"] = item # Inject D3 scripts from s3 import S3Report S3Report.inject_d3() # Inject charts-script appname = current.request.application scripts = s3.scripts if s3.debug: script = "/%s/static/scripts/S3/s3.ui.charts.js" % appname if script not in scripts: scripts.append(script) else: script = "/%s/static/scripts/S3/s3.ui.charts.min.js" % appname if script not in scripts: scripts.append(script) # Instantiate charts scriptopts = { # Standard SHARE theme color set: "colors": [ '#0C9CD0', # blue '#E03158', # red '#FBA629', # amber '#8ABC3F', # green '#AFB8BF', # grey ], } script = '''$('.homepage-chart').uiChart(%s)''' % json.dumps( scriptopts) s3.jquery_ready.append(script) # Add last update time of chart data last_update = HomepageStatistics.last_update() if last_update: output["last_stats_update"] = T("Updated on %(date)s") % { "date": last_update } else: output["last_stats_update"] = None self._view(THEME, "index.html") return output
def s3_rest_controller(prefix=None, resourcename=None, **attr): """ Helper function to apply the S3Resource REST interface Args: prefix: the application prefix resourcename: the resource name (without prefix) attr: additional keyword parameters Any keyword parameters will be copied into the output dict (provided that the output is a dict). If a keyword parameter is callable, then it will be invoked, and its return value will be added to the output dict instead. The callable receives the S3Request as its first and only parameter. CRUD can be configured per table using: s3db.configure(tablename, **attr) *** Redirection: create_next URL to redirect to after a record has been created update_next URL to redirect to after a record has been updated delete_next URL to redirect to after a record has been deleted *** Form configuration: list_fields list of names of fields to include into list views subheadings Sub-headings (see separate documentation) listadd Enable/Disable add-form in list views *** CRUD configuration: editable Allow/Deny record updates in this table deletable Allow/Deny record deletions in this table insertable Allow/Deny record insertions into this table copyable Allow/Deny record copying within this table *** Callbacks: create_onvalidation Function for additional record validation on create create_onaccept Function after successful record insertion update_onvalidation Function for additional record validation on update update_onaccept Function after successful record update onvalidation Fallback for both create_onvalidation and update_onvalidation onaccept Fallback for both create_onaccept and update_onaccept ondelete Function after record deletion """ # Parse the request dynamic = attr.get("dynamic") if dynamic: # Dynamic table controller c = request.controller f = request.function attr = settings.customise_controller("%s_%s" % (c, f), **attr) from s3 import DYNAMIC_PREFIX, s3_get_extension, s3_request r = s3_request( DYNAMIC_PREFIX, dynamic, f="%s/%s" % (f, dynamic), args=request.args[1:], extension=s3_get_extension(request), ) else: # Customise Controller from Template attr = settings.customise_controller( "%s_%s" % ( prefix or request.controller, resourcename or request.function, ), **attr) from s3 import s3_request r = s3_request(prefix, resourcename) # Customize target resource(s) from Template r.customise_resource() # Configure standard method handlers from s3 import S3Compose, S3Filter, S3GroupedItemsReport, S3HierarchyCRUD, \ S3Importer, S3Map, S3Merge, S3MobileCRUD, S3Organizer, \ S3OrgRoleManager, S3Profile, S3Report, S3Summary, \ S3TimePlot, S3XForms, S3Wizard, search_ac from s3db.cms import S3CMS set_handler = r.set_handler set_handler("cms", S3CMS) set_handler("compose", S3Compose) # @ToDo: Make work in Component Tabs: set_handler("copy", lambda r, **attr: \ redirect(URL(args = "create", vars = {"from_record":r.id}, ))) set_handler("deduplicate", S3Merge) set_handler("filter", S3Filter) set_handler("grouped", S3GroupedItemsReport) set_handler("hierarchy", S3HierarchyCRUD) set_handler("import", S3Importer) set_handler("map", S3Map) set_handler("mform", S3MobileCRUD, representation="json") set_handler("organize", S3Organizer) set_handler("profile", S3Profile) set_handler("report", S3Report) # For HTML, JSON set_handler("report", S3Report, transform=True) # For GeoJSON set_handler("search_ac", search_ac) set_handler("summary", S3Summary) set_handler("timeplot", S3TimePlot) set_handler("xform", S3XForms) set_handler("wizard", S3Wizard) method = r.method # Don't load S3PDF unless needed (very slow import with Reportlab) #if method == "import" and r.representation == "pdf": # from s3.s3pdf import S3PDF # set_handler("import", S3PDF(), # http = ("GET", "POST"), # representation = "pdf" # ) # Plugin OrgRoleManager when appropriate S3OrgRoleManager.set_method(r) # List of methods which can have custom action buttons # (defining here allows postp to add a custom method to the list) s3.action_methods = ( "import", "review", "approve", "reject", "deduplicate", "wizard", ) # Execute the request output = r(**attr) if isinstance(output, dict) and \ method in (None, "report", "search", "datatable", "datatable_f", "summary", ): if s3.actions is None: # Add default action buttons prefix, name, table, tablename = r.target() authorised = auth.s3_has_permission("update", tablename) # If a component has components itself, then action buttons # can be forwarded to the native controller by setting native=True if r.component and s3db.has_components(table): native = output.get("native", False) else: native = False # Get table config get_config = s3db.get_config listadd = get_config(tablename, "listadd", True) # Which is the standard open-action? if settings.get_ui_open_read_first(): # Always read, irrespective permissions editable = False else: editable = get_config(tablename, "editable", True) if editable and \ auth.permission.ownership_required("update", table): # User cannot edit all records in the table if settings.get_ui_auto_open_update(): # Decide automatically per-record (implicit method) editable = "auto" else: # Always open read first (explicit read) editable = False deletable = get_config(tablename, "deletable", True) copyable = get_config(tablename, "copyable", False) # URL to open the resource from s3 import S3CRUD open_url = S3CRUD._linkto( r, authorised=authorised, update=editable, native=native, )("[id]") # Add action buttons for Open/Delete/Copy as appropriate s3_action_buttons( r, deletable=deletable, copyable=copyable, editable=editable, read_url=open_url, update_url=open_url # To use modals #update_url = "%s.popup?refresh=list" % open_url ) # Override Add-button, link to native controller and put # the primary key into get_vars for automatic linking if native and not listadd and \ auth.s3_has_permission("create", tablename): label = S3CRUD.crud_string(tablename, "label_create") component = r.resource.components[name] fkey = "%s.%s" % (name, component.fkey) get_vars_copy = get_vars.copy() get_vars_copy.update({fkey: r.record[component.fkey]}) url = URL( prefix, name, args=["create"], vars=get_vars_copy, ) add_btn = A( label, _href=url, _class="action-btn", ) output.update(add_btn=add_btn) elif method not in s3.action_methods: s3.actions = None return output
def __call__(self): T = current.T db = current.db s3db = current.s3db output = {} # Recent Updates etable = s3db.event_event stable = s3db.event_sitrep query = (stable.deleted == False) & \ (stable.event_id == etable.id) fields = [ etable.name, stable.date, stable.summary, ] language = current.session.s3.language if language != current.deployment_settings.get_L10n_default_language(): ntable = s3db.event_event_name left = ntable.on((ntable.event_id == etable.id) & \ (ntable.language == language)) fields.append(ntable.name_l10n) else: left = None sitreps = db(query).select(left=left, limitby=(0, 3), orderby=~stable.date, *fields) len_sitreps = len(sitreps) if len_sitreps == 0: from s3 import S3CRUD recent_updates = DIV(S3CRUD.crud_string("event_sitrep", "msg_list_empty"), _class="empty") else: recent_updates = DIV() rappend = recent_updates.append count = 0 for s in sitreps: count += 1 if left: event_name = s["event_event_name.name_l10n"] or s[ "event_event.name"] else: event_name = s["event_event.name"] rappend(H3(event_name)) rappend(P(s["event_sitrep.summary"])) if count != len_sitreps: rappend(HR()) output["recent_updates"] = recent_updates map_btn = A( T("MAP OF CURRENT NEEDS"), #_href = URL(c="default", # f="index", # args="dashboard", # ), _href=URL( c="req", f="need_line", args="map", ), _class="small primary button", ) create_btn = A( T("CREATE A NEED"), _href=URL( c="req", f="need", args="create", ), _class="small primary button", ) output["needs_btn"] = DIV( SPAN(map_btn), SPAN(create_btn), _class="button-group radius", ) output["about_btn"] = A( "%s >" % T("Read More"), _href=URL( c="default", f="about", ), ) self._view(THEME, "index.html") # Inject D3 scripts from s3 import S3Report S3Report.inject_d3() # Inject charts-script appname = current.request.application s3 = current.response.s3 scripts = s3.scripts if s3.debug: script = "/%s/static/scripts/S3/s3.ui.charts.js" % appname if script not in scripts: scripts.append(script) else: script = "/%s/static/scripts/S3/s3.ui.charts.min.js" % appname if script not in scripts: scripts.append(script) # Instantiate charts scriptopts = { # Standard SHARE theme color set: "colors": [ '#0C9CD0', # blue '#E03158', # red '#FBA629', # amber '#8ABC3F', # green '#AFB8BF', # grey ], } script = '''$('.homepage-chart').uiChart(%s)''' % json.dumps( scriptopts) s3.jquery_ready.append(script) return output
def __call__(self): output = {} T = current.T request = current.request s3 = current.response.s3 # Check logged in and permissions auth = current.auth roles = current.session.s3.roles system_roles = auth.get_system_roles() AUTHENTICATED = system_roles.AUTHENTICATED # Login/Registration forms self_registration = current.deployment_settings.get_security_self_registration() registered = False login_form = None login_div = None register_form = None register_div = None if AUTHENTICATED not in roles: # This user isn't yet logged-in if request.cookies.has_key("registered"): # This browser has logged-in before registered = True if self_registration is True: # Provide a Registration box on front page register_form = auth.register() register_div = DIV(H3(T("Register")), P(XML(T("If you would like to help, then please %(sign_up_now)s") % \ dict(sign_up_now=B(T("sign-up now")))))) if request.env.request_method == "POST": post_script = \ '''$('#register_form').removeClass('hide') $('#login_form').addClass('hide')''' else: post_script = "" register_script = \ '''$('#register-btn').attr('href','#register') $('#login-btn').attr('href','#login') %s $('#register-btn').click(function(){ $('#register_form').removeClass('hide') $('#login_form').addClass('hide') }) $('#login-btn').click(function(){ $('#register_form').addClass('hide') $('#login_form').removeClass('hide') })''' % post_script s3.jquery_ready.append(register_script) # Provide a login box on front page auth.messages.submit_button = T("Login") login_form = auth.login(inline=True) login_div = DIV(H3(T("Login")), P(XML(T("Registered users can %(login)s to access the system") % \ dict(login=B(T("login")))))) output["self_registration"] = self_registration output["registered"] = registered output["login_div"] = login_div output["login_form"] = login_form output["register_div"] = register_div output["register_form"] = register_form # Latest 4 Events and Requests s3db = current.s3db layout = s3db.cms_post_list_layout list_id = "latest_events" limit = 4 list_fields = ["series_id", "location_id", "date", "body", "created_by", "created_by$organisation_id", "document.file", "event_post.event_id", ] resource = s3db.resource("cms_post") resource.add_filter(FS("series_id$name") == "Event") # Only show Future Events resource.add_filter(resource.table.date >= request.now) # Order with next Event first orderby = "date" output["latest_events"] = latest_records(resource, layout, list_id, limit, list_fields, orderby) list_id = "latest_reqs" resource = s3db.resource("req_req") s3db.req_customise_req_fields() list_fields = s3db.get_config("req_req", "list_fields") layout = s3db.req_req_list_layout resource.add_filter(FS("cancel") != True) # Order with most recent Request first orderby = "date desc" output["latest_reqs"] = latest_records(resource, layout, list_id, limit, list_fields, orderby) # Site Activity Log resource = s3db.resource("s3_audit") resource.add_filter(FS("~.method") != "delete") orderby = "s3_audit.timestmp desc" list_fields = ["id", "method", "user_id", "tablename", "record_id", ] #current.deployment_settings.ui.customise_s3_audit() db = current.db 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 auth.s3_logged_in() and auth.user.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"), }, 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 postp(r, output): if r.record: from s3 import S3CRUD response.view = S3CRUD._view(r, "cms/blog.html") return output
def __call__(self): T = current.T db = current.db s3db = current.s3db s3 = current.response.s3 session_s3 = current.session.s3 output = {} # Recent Updates etable = s3db.event_event stable = s3db.event_sitrep query = (stable.deleted == False) fields = [etable.name, stable.id, stable.date, stable.name, stable.summary, ] left = [etable.on(etable.id == stable.event_id)] language = session_s3.language if language != current.deployment_settings.get_L10n_default_language(): ntable = s3db.event_event_name left.append(ntable.on((ntable.event_id == etable.id) & \ (ntable.language == language))) fields.append(ntable.name_l10n) use_local_event_name = True else: use_local_event_name = False sitreps = db(query).select(left = left, limitby = (0, 3), orderby = ~stable.date, *fields ) len_sitreps = len(sitreps) if len_sitreps == 0: from s3 import S3CRUD recent_updates = DIV(S3CRUD.crud_string("event_sitrep", "msg_list_empty"), _class="empty") else: recent_updates = DIV() rappend = recent_updates.append count = 0 for s in sitreps: count += 1 if use_local_event_name: event_name = s["event_event_name.name_l10n"] or s["event_event.name"] else: event_name = s["event_event.name"] if not event_name: event_name = s["event_sitrep.name"] rappend(H3(A(event_name, _href = URL(c = "event", f = "sitrep", args = [s["event_sitrep.id"]], ), ))) rappend(P(XML(s["event_sitrep.summary"]))) if count != len_sitreps: rappend(HR()) output["recent_updates"] = recent_updates map_btn = A(T("MAP OF CURRENT NEEDS"), #_href = URL(c="default", # f="index", # args="dashboard", # ), _href = URL(c="req", f="need_line", args="map", ), _class = "small primary button", ) create_btn = A(T("CREATE A NEED"), _href = URL(c="req", f="need", args="create", ), _class = "small primary button", ) output["needs_btn"] = DIV(SPAN(map_btn), SPAN(create_btn), _class="button-group radius", ) output["about_btn"] = A("%s >" % T("Read More"), _href = URL(c="default", f="about", ), ) # Resources section if current.deployment_settings.has_module("cms"): system_roles = current.auth.get_system_roles() ADMIN = system_roles.ADMIN in session_s3.roles table = s3db.cms_post ltable = s3db.cms_post_module module = "default" resource = "index" query = (ltable.module == module) & \ ((ltable.resource == None) | \ (ltable.resource == resource)) & \ (ltable.post_id == table.id) & \ (table.deleted != True) item = current.db(query).select(table.body, table.id, limitby=(0, 1)).first() if item: if ADMIN: item = DIV(XML(item.body), BR(), A(T("Edit"), _href=URL(c="cms", f="post", args=[item.id, "update"]), _class="action-btn")) else: item = DIV(XML(item.body)) elif ADMIN: if s3.crud.formstyle == "bootstrap": _class = "btn" else: _class = "action-btn" item = A(T("Edit"), _href=URL(c="cms", f="post", args="create", vars={"module": module, "resource": resource }), _class="%s cms-edit" % _class) else: item = "" else: item = "" output["item"] = item # Inject D3 scripts from s3 import S3Report S3Report.inject_d3() # Inject charts-script appname = current.request.application scripts = s3.scripts if s3.debug: script = "/%s/static/scripts/S3/s3.ui.charts.js" % appname if script not in scripts: scripts.append(script) else: script = "/%s/static/scripts/S3/s3.ui.charts.min.js" % appname if script not in scripts: scripts.append(script) # Instantiate charts scriptopts = { # Standard SHARE theme color set: "colors": ['#0C9CD0', # blue '#E03158', # red '#FBA629', # amber '#8ABC3F', # green '#AFB8BF', # grey ], } script = '''$('.homepage-chart').uiChart(%s)''' % json.dumps(scriptopts) s3.jquery_ready.append(script) # Add last update time of chart data last_update = HomepageStatistics.last_update() if last_update: output["last_stats_update"] = T("Updated on %(date)s") % {"date": last_update} else: output["last_stats_update"] = None self._view(THEME, "index.html") return output
def __call__(self): T = current.T db = current.db s3db = current.s3db output = {} # Recent Updates etable = s3db.event_event stable = s3db.event_sitrep query = (stable.deleted == False) fields = [etable.name, stable.date, stable.name, stable.summary, ] left = [etable.on(etable.id == stable.event_id)] language = current.session.s3.language if language != current.deployment_settings.get_L10n_default_language(): ntable = s3db.event_event_name left.append(ntable.on((ntable.event_id == etable.id) & \ (ntable.language == language))) fields.append(ntable.name_l10n) use_local_event_name = True else: use_local_event_name = False sitreps = db(query).select(left = left, limitby = (0, 3), orderby = ~stable.date, *fields ) len_sitreps = len(sitreps) if len_sitreps == 0: from s3 import S3CRUD recent_updates = DIV(S3CRUD.crud_string("event_sitrep", "msg_list_empty"), _class="empty") else: recent_updates = DIV() rappend = recent_updates.append count = 0 for s in sitreps: count += 1 if use_local_event_name: event_name = s["event_event_name.name_l10n"] or s["event_event.name"] else: event_name = s["event_event.name"] if not event_name: event_name = s["event_sitrep.name"] rappend(H3(event_name)) rappend(P(XML(s["event_sitrep.summary"]))) if count != len_sitreps: rappend(HR()) output["recent_updates"] = recent_updates map_btn = A(T("MAP OF CURRENT NEEDS"), #_href = URL(c="default", # f="index", # args="dashboard", # ), _href = URL(c="req", f="need_line", args="map", ), _class = "small primary button", ) create_btn = A(T("CREATE A NEED"), _href = URL(c="req", f="need", args="create", ), _class = "small primary button", ) output["needs_btn"] = DIV(SPAN(map_btn), SPAN(create_btn), _class="button-group radius", ) output["about_btn"] = A("%s >" % T("Read More"), _href = URL(c="default", f="about", ), ) self._view(THEME, "index.html") # Inject D3 scripts from s3 import S3Report S3Report.inject_d3() # Inject charts-script appname = current.request.application s3 = current.response.s3 scripts = s3.scripts if s3.debug: script = "/%s/static/scripts/S3/s3.ui.charts.js" % appname if script not in scripts: scripts.append(script) else: script = "/%s/static/scripts/S3/s3.ui.charts.min.js" % appname if script not in scripts: scripts.append(script) # Instantiate charts scriptopts = { # Standard SHARE theme color set: "colors": ['#0C9CD0', # blue '#E03158', # red '#FBA629', # amber '#8ABC3F', # green '#AFB8BF', # grey ], } script = '''$('.homepage-chart').uiChart(%s)''' % json.dumps(scriptopts) s3.jquery_ready.append(script) # Add last update time of chart data last_update = HomepageStatistics.last_update() if last_update: output["last_stats_update"] = T("Updated on %(date)s") % {"date": last_update} else: output["last_stats_update"] = None return output
def __call__(self): output = {} T = current.T request = current.request s3 = current.response.s3 # Check logged in and permissions auth = current.auth roles = current.session.s3.roles system_roles = auth.get_system_roles() AUTHENTICATED = system_roles.AUTHENTICATED # Login/Registration forms self_registration = current.deployment_settings.get_security_self_registration( ) registered = False login_form = None login_div = None register_form = None register_div = None if AUTHENTICATED not in roles: # This user isn't yet logged-in if request.cookies.has_key("registered"): # This browser has logged-in before registered = True if self_registration is True: # Provide a Registration box on front page register_form = auth.register() register_div = DIV(H3(T("Register")), P(XML(T("If you would like to help, then please %(sign_up_now)s") % \ dict(sign_up_now=B(T("sign-up now")))))) if request.env.request_method == "POST": post_script = \ '''$('#register_form').removeClass('hide') $('#login_form').addClass('hide')''' else: post_script = "" register_script = \ '''$('#register-btn').attr('href','#register') $('#login-btn').attr('href','#login') %s $('#register-btn').click(function(){ $('#register_form').removeClass('hide') $('#login_form').addClass('hide') }) $('#login-btn').click(function(){ $('#register_form').addClass('hide') $('#login_form').removeClass('hide') })''' % post_script s3.jquery_ready.append(register_script) # Provide a login box on front page auth.messages.submit_button = T("Login") login_form = auth.login(inline=True) login_div = DIV(H3(T("Login")), P(XML(T("Registered users can %(login)s to access the system") % \ dict(login=B(T("login")))))) output["self_registration"] = self_registration output["registered"] = registered output["login_div"] = login_div output["login_form"] = login_form output["register_div"] = register_div output["register_form"] = register_form # Latest 4 Events and Requests s3db = current.s3db layout = s3db.cms_post_list_layout list_id = "latest_events" limit = 4 list_fields = [ "series_id", "location_id", "date", "body", "created_by", "created_by$organisation_id", "document.file", "event_post.event_id", ] resource = s3db.resource("cms_post") resource.add_filter(FS("series_id$name") == "Event") # Only show Future Events resource.add_filter(resource.table.date >= request.now) # Order with next Event first orderby = "date" output["latest_events"] = latest_records(resource, layout, list_id, limit, list_fields, orderby) list_id = "latest_reqs" resource = s3db.resource("req_req") s3db.req_customise_req_fields() list_fields = s3db.get_config("req_req", "list_fields") layout = s3db.req_req_list_layout resource.add_filter(FS("cancel") != True) # Order with most recent Request first orderby = "date desc" output["latest_reqs"] = latest_records(resource, layout, list_id, limit, list_fields, orderby) # Site Activity Log resource = s3db.resource("s3_audit") resource.add_filter(FS("~.method") != "delete") orderby = "s3_audit.timestmp desc" list_fields = [ "id", "method", "user_id", "tablename", "record_id", ] #current.deployment_settings.ui.customise_s3_audit() db = current.db 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 auth.s3_logged_in() and auth.user.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"), }, 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 _datatable(output, resource, list_fields, start, limit, orderby, ): tablename = resource.tablename dt, totalrows, ids = resource.datatable(fields=list_fields, start=start, limit=limit, orderby=orderby) displayrows = totalrows if dt.empty: empty_str = S3CRUD.crud_string(tablename, "msg_list_empty") else: empty_str = S3CRUD.crud_string(tablename, "msg_no_match") empty = DIV(empty_str, _class="empty") dtargs = {} # @ToDo: Permissions #messages = current.messages c, f = tablename.split("_", 1) read_url = URL(c=c, f=f, args = "[id].popup") #delete_url = URL(c=c, f=f, # args=["[id]", "delete"]) dtargs["dt_row_actions"] = [{"label": current.messages.READ, "url": read_url, "icon": "fa fa-eye", "_class": "s3_modal", }, # @ToDo: AJAX delete #{"label": messages.DELETE, # "url": delete_url, # "icon": "fa fa-trash", # }, ] dtargs["dt_searching"] = False #dtargs["dt_pagination"] = "false" #dtargs["dt_action_col"] = len(list_fields) #dtargs["dt_ajax_url"] = r.url(vars={"update": tablename}, # representation="aadata") list_id = "custom-list-%s" % tablename datatable = dt.html(totalrows, displayrows, id=list_id, **dtargs) if dt.data: empty.update(_style="display:none") else: datatable.update(_style="display:none") contents = DIV(datatable, empty, _class="dt-contents") # Render the widget output["%s_datatable" % tablename] = DIV(contents, _class="card-holder", )