Exemple #1
0
    def custom_prep(r):
        # Call standard prep
        if callable(standard_prep):
            result = standard_prep(r)
            if not result:
                return False

        if r.interactive  or r.representation == "aadata":
            # Configure fields 
            field = r.table.duration
            field.readable = field.writable = True

        if r.interactive:
            from s3.s3filter import S3TextFilter, S3OptionsFilter, S3LocationFilter, S3DateFilter
            filter_widgets = [
                S3TextFilter(["name",
                              "code",
                              "description",
                              "organisation.name",
                              "organisation.acronym",
                              ],
                             label=T("Name"),
                             _class="filter-search",
                             ),
                S3OptionsFilter("status_id",
                                label=T("Status"),
                                represent="%(name)s",
                                cols=3,
                                ),
                S3OptionsFilter("theme_project.theme_id",
                                label=T("Theme"),
                                represent="%(name)s",
                                widget="multiselect",
                                #hidden=True,
                                ),
                S3LocationFilter("location.location_id",
                                 label=T("Location"),
                                 levels=["L1", "L2"],
                                 widget="multiselect",
                                 #hidden=True,
                                 ),
                # @ToDo: Widget to handle Start & End in 1!
                S3DateFilter("start_date",
                             label=T("Start Date"),
                             hide_time=True,
                             #hidden=True,
                             ),
                S3DateFilter("end_date",
                             label=T("End Date"),
                             hide_time=True,
                             #hidden=True,
                             ),
                ]
            current.s3db.configure("project_project",
                                   filter_widgets = filter_widgets,
                                   )
        return True
Exemple #2
0
def _newsfeed():
    """
        Custom Page
        - Filterable DataList of CMS Posts & a DataList of Events
    """

    #if not current.auth.is_logged_in():
    #    current.auth.permission.fail()

    T = current.T
    s3db = current.s3db
    request = current.request
    response = current.response
    s3 = response.s3

    # Ensure that filtered views translate into options which update the Widget
    if "~.series_id$name" in request.get_vars:
        series_name = request.vars["~.series_id$name"]
        table = s3db.cms_series
        series = current.db(table.name == series_name).select(
            table.id, limitby=(0, 1)).first()
        if series:
            series_id = str(series.id)
            request.get_vars.pop("~.series_id$name")
            request.get_vars["~.series_id__belongs"] = series_id

    current.deployment_settings.ui.customize_cms_post()

    list_layout = s3.render_posts

    filter_widgets = [
        S3TextFilter(
            ["body"],
            label="",
            _class="filter-search",
            #_placeholder=T("Search").upper(),
        ),
        S3OptionsFilter(
            "series_id",
            label=T("Filter by Type"),
            represent="%(name)s",
            widget="multiselect",
            hidden=True,
        ),
        S3LocationFilter(
            "location_id",
            label=T("Filter by Location"),
            levels=["L1", "L2", "L3"],
            widget="multiselect",
            hidden=True,
        ),
        S3OptionsFilter(
            "created_by$organisation_id",
            label=T("Filter by Organization"),
            # Can't use this for integers, use field.represent instead
            #represent="%(name)s",
            widget="multiselect",
            hidden=True,
        ),
        S3DateFilter(
            "created_on",
            label=T("Filter by Date"),
            hide_time=True,
            hidden=True,
        ),
    ]

    s3db.configure(
        "cms_post",
        # We use a custom Advanced widget
        filter_advanced=False,
        filter_formstyle=filter_formstyle,
        filter_submit=(T("SEARCH"), "btn btn-primary"),
        filter_widgets=filter_widgets,
        list_layout=list_layout,
        # Create form comes via AJAX in a Modal
        insertable=False,
        notify_fields=[
            (T("Type"), "series_id"),
            (T("Date"), "date"),
            (T("Location"), "location_id"),
            (T("Description"), "body"),
        ],
        notify_template="notify_post",
    )

    s3.dl_pagelength = 6  # 5 forces an AJAX call

    old_args = request.args
    if "datalist_dl_post" in old_args:
        # DataList pagination or Ajax-deletion request
        request.args = ["datalist_f"]
        ajax = "list"
    elif "datalist_dl_filter" in old_args:
        # FilterForm options update request
        request.args = ["filter"]
        ajax = "filter"
    elif "validate.json" in old_args:
        # Inline component validation request
        request.args = []
        ajax = True
    elif current.auth.permission.format == "msg":
        # Subscription lookup request
        request.args = []
        ajax = True
    else:
        # Default
        request.args = ["datalist_f"]
        ajax = None

    def prep(r):
        if ajax == "list":
            r.representation = "dl"
        elif ajax == "filter":
            r.representation = "json"
        return True

    s3.prep = prep

    output = current.rest_controller("cms",
                                     "post",
                                     list_ajaxurl=URL(f="index",
                                                      args="datalist_dl_post"),
                                     filter_ajax_url=URL(
                                         f="index",
                                         args="datalist_dl_filter",
                                         vars={}))

    request.args = old_args

    if ajax == "list":
        # Don't override view if this is an Ajax-deletion request
        if not "delete" in request.get_vars:
            response.view = "plain.html"
    elif not ajax:
        # Set Title & View after REST Controller, in order to override
        output["title"] = T("News Feed")
        view = path.join(request.folder, "private", "templates", THEME,
                         "views", "newsfeed.html")
        try:
            # Pass view as file not str to work in compiled mode
            response.view = open(view, "rb")
        except IOError:
            from gluon.http import HTTP
            raise HTTP(404, "Unable to open Custom View: %s" % view)

        scripts = []
        sappend = scripts.append
        # Style the Search TextFilter widget
        sappend(
            '''$('#post-cms_post_body-text-filter__row').addClass('input-append').append('<span class="add-on"><i class="icon-search"></i></span>')'''
        )
        # Button to toggle Advanced Form
        sappend(
            '''$('#list-filter').append('<a class="accordion-toggle"><i class="icon-reorder"></i> %s</a>')'''
            % T("Advanced Search"))
        # Toggle doesn't work directly when removing 'hide' & requires a 2nd click to open without this
        sappend(
            '''$('.accordion-toggle').click(function(){var a=$('.advanced');if(a.hasClass('hide')){a.removeClass('hide').show()}else{a.toggle()}})'''
        )
        s3.jquery_ready.append('''\n'''.join(scripts))

        # Latest 5 Disasters
        # resource = s3db.resource("event_event")
        # layout = render_events
        # list_id = "event_datalist"
        # limit = 5
        # orderby = "start_date desc"
        # list_fields = ["name",
        # "event_type_id$name",
        # "start_date",
        # "closed",
        # ]
        # output["disasters"] = latest_records(resource, layout, list_id, limit, list_fields, orderby)

    return output
Exemple #3
0
def _updates():
    """
        Custom Page
        - Filterable DataList of CMS Posts & a DataList of Events
    """

    #if not current.auth.is_logged_in():
    #    current.auth.permission.fail()

    T = current.T
    s3db = current.s3db
    request = current.request
    response = current.response
    s3 = response.s3

    current.deployment_settings.ui.customize_cms_post()

    list_layout = s3.render_posts

    filter_widgets = [
        S3TextFilter(
            ["body"],
            label="",
            _class="filter-search",
            #_placeholder=T("Search").upper(),
        ),
        S3OptionsFilter(
            "series_id",
            label=T("Filter by Type"),
            represent="%(name)s",
            widget="multiselect",
            cols=3,
            hidden=True,
        ),
        S3LocationFilter(
            "location_id",
            label=T("Filter by Location"),
            levels=["L1", "L2", "L3"],
            widget="multiselect",
            cols=3,
            hidden=True,
        ),
        S3OptionsFilter(
            "created_by$organisation_id",
            label=T("Filter by Organization"),
            represent="%(name)s",
            widget="multiselect",
            cols=3,
            hidden=True,
        ),
        S3DateFilter(
            "created_on",
            label=T("Filter by Date"),
            hide_time=True,
            hidden=True,
        ),
    ]

    s3db.configure(
        "cms_post",
        # We use a custom Advanced widget
        filter_advanced=False,
        filter_formstyle=filter_formstyle,
        filter_submit=(T("SEARCH"), "btn btn-primary"),
        filter_widgets=filter_widgets,
        list_layout=list_layout,
        # Create form comes via AJAX in a Modal
        insertable=False,
    )

    s3.dl_pagelength = 6  # 5 forces an AJAX call

    if "datalist_dl_post" in request.args:
        # DataList pagination or Ajax-deletion request
        request.args = ["datalist_f"]
        ajax = "list"
    elif "datalist_dl_filter" in request.args:
        # FilterForm options update request
        request.args = ["filter"]
        ajax = "filter"
    elif "validate.json" in request.args:
        ajax = True
    else:
        # Default
        request.args = ["datalist_f"]
        ajax = None

    def prep(r):
        if ajax == "list":
            r.representation = "dl"
        elif ajax == "filter":
            r.representation = "json"
        return True

    s3.prep = prep

    output = current.rest_controller("cms",
                                     "post",
                                     list_ajaxurl=URL(f="index",
                                                      args="datalist_dl_post"),
                                     filter_ajax_url=URL(
                                         f="index",
                                         args="datalist_dl_filter",
                                         vars={}))

    if ajax == "list":
        # Don't override view if this is an Ajax-deletion request
        if not "delete" in request.get_vars:
            response.view = "plain.html"
    elif not ajax:
        # Set Title & View after REST Controller, in order to override
        output["title"] = T("News Feed")
        view = path.join(request.folder, "private", "templates", THEME,
                         "views", "updates.html")
        try:
            # Pass view as file not str to work in compiled mode
            response.view = open(view, "rb")
        except IOError:
            from gluon.http import HTTP
            raise HTTP("404", "Unable to open Custom View: %s" % view)

        scripts = []
        sappend = scripts.append
        # Style the Search TextFilter widget
        sappend(
            '''$('#post-cms_post_body-text-filter__row').addClass('input-append').append('<span class="add-on"><i class="icon-search"></i></span>')'''
        )
        # Button to toggle Advanced Form
        sappend(
            '''$('#list-filter').append('<a class="accordion-toggle"><i class="icon-reorder"></i> %s</a>')'''
            % T("Advanced Search"))
        sappend(
            '''$('.accordion-toggle').click(function(){$('.advanced').toggle()})'''
        )
        s3.jquery_ready.append('''\n'''.join(scripts))

        # Latest 5 Disasters
        resource = s3db.resource("event_event")
        list_fields = [
            "name",
            "event_type_id$name",
            "zero_hour",
            "closed",
        ]
        orderby = resource.get_config("list_orderby",
                                      ~resource.table.created_on)
        datalist, numrows, ids = resource.datalist(fields=list_fields,
                                                   start=None,
                                                   limit=5,
                                                   listid="event_datalist",
                                                   orderby=orderby,
                                                   layout=render_events)
        # Render the list
        data = datalist.html()
        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.insert(1, msg)
        output["disasters"] = data

    return output
Exemple #4
0
def newsfeed():
    """
        RESTful CRUD controller for display of posts as a filterable dataList
    """

    # Load Model
    table = s3db.cms_post
    title_list = T("Latest Information")

    # Hide Posts linked to Modules & Expired Posts
    FS = s3base.S3FieldSelector
    s3.filter = (FS("post_module.module") == None) & (FS("expired") != True)

    # Ensure that filtered views translate into options which update the Widget
    get_vars = request.get_vars
    if "~.series_id$name" in get_vars:
        series_name = get_vars["~.series_id$name"]
        # Disabled as can change filters dynamically
        # @ToDo: Better Mechanism: Another field in cms_series?
        #if series_name == "Request":
        #    title_list = T("Latest Requests")
        #elif series_name == "Offer":
        #    title_list = T("Latest Offers")
        stable = s3db.cms_series
        series = db(stable.name == series_name).select(stable.id,
                                                       limitby=(0, 1)).first()
        if series:
            series_id = str(series.id)
            get_vars.pop("~.series_id$name")
            get_vars["~.series_id__belongs"] = series_id

    s3.crud_strings["cms_post"].title_list = title_list

    # Which levels of Hierarchy are we using?
    hierarchy = gis.get_location_hierarchy()
    levels = hierarchy.keys()
    if len(settings.get_gis_countries()) == 1:
        levels.remove("L0")

    # @ToDo: deployment_setting
    #org_field = "created_by$organisation_id"
    org_field = "post_organisation.organisation_id"

    # @ToDo: deployment_setting
    #contact_field = "created_by"
    #table.created_by.represent = s3_auth_user_represent_name
    contact_field = "person_id"

    from s3.s3filter import S3TextFilter, S3OptionsFilter, S3LocationFilter, S3DateFilter
    filter_widgets = [
        S3TextFilter(
            ["body"],
            label=T("Search"),
            _class="filter-search",
            #_placeholder=T("Search").upper(),
        ),
        S3LocationFilter(
            "location_id",
            label=T("Filter by Location"),
            levels=levels,
            widget="multiselect",
            hidden=True,
        ),
        S3OptionsFilter(
            org_field,
            label=T("Filter by Organization"),
            # Can't use this for created_by as integer, use field.represent instead
            #represent="%(name)s",
            widget="multiselect",
            hidden=True,
        ),
        S3DateFilter(
            "date",
            label=T("Filter by Date"),
            hide_time=True,
            hidden=True,
        ),
    ]

    if settings.get_cms_show_tags():
        filter_widgets.insert(
            1,
            S3OptionsFilter(
                "tag_post.tag_id",
                label=T("Filter by Tag"),
                represent="%(name)s",
                widget="multiselect",
                hidden=True,
            ))

    if settings.get_cms_bookmarks() and auth.user:
        filter_widgets.insert(
            1,
            S3OptionsFilter(
                "bookmark.user_id",
                label=T("Filter by Bookmark"),
                # Can't just use "" as this is then omitted from rendering
                options={
                    "*": T("All"),
                    auth.user.id: T("My Bookmarks"),
                },
                hidden=True,
                multiple=False,
            ))

    len_series = db(s3db.cms_series.deleted == False).count()
    if len_series > 3:
        # Multiselect widget
        filter_widgets.insert(
            1,
            S3OptionsFilter(
                "series_id",
                label=T("Filter by Type"),
                # We want translations
                #represent="%(name)s",
                widget="multiselect",
                hidden=True,
            ))

    elif len_series > 1:
        # Checkboxes
        filter_widgets.insert(
            1,
            S3OptionsFilter(
                "series_id",
                label=T("Filter by Type"),
                # We want translations
                #represent="%(name)s",
                cols=2,
                hidden=True,
            ))
    else:
        # No Widget
        pass

    s3db.configure(
        "cms_post",
        # We could use a custom Advanced widget
        #filter_advanced = False,
        filter_formstyle=filter_formstyle,
        # No Submit button (done automatically)
        #filter_submit = (T("SEARCH"), "btn btn-primary"),
        filter_widgets=filter_widgets,
        list_layout=s3db.cms_render_posts,
        # Create form comes via AJAX in a Modal
        #insertable = False,
        notify_fields=[
            (T("Type"), "series_id"),
            (T("Date"), "date"),
            (T("Location"), "location_id"),
            (T("Organization"), org_field),
            (T("Contact"), contact_field),
            (T("Description"), "body"),
        ],
        notify_template="notify_post",
    )

    s3.dl_pagelength = 6  # 5 forces an AJAX call

    def prep(r):
        if r.interactive or r.representation == "aadata":
            s3db.cms_customize_post_fields()

        if r.interactive:
            field = table.series_id
            field.label = T("Type")

            if r.method == "read":
                # Restore the label for the Location
                table.location_id.label = T("Location")
            elif r.method == "create":
                pass
                # @ToDo: deployment_setting
                #ADMIN = session.s3.system_roles.ADMIN
                #if (not auth.s3_has_role(ADMIN)):
                #    represent = S3Represent(lookup="cms_series",
                #                            translate=settings.get_L10n_translate_cms_series())
                #    field.requires = IS_ONE_OF(db,
                #                               "cms_series.id",
                #                               represent,
                #                               not_filterby="name",
                #                               not_filter_opts = ["Alert"],
                #                               )

            refresh = get_vars.get("refresh", None)
            if refresh == "datalist":
                # We must be coming from the News Feed page so can change the type on-the-fly
                field.readable = field.writable = True
            #field.requires = field.requires.other
            #field = table.name
            #field.readable = field.writable = False
            #field = table.title
            #field.readable = field.writable = False
            field = table.avatar
            field.default = True
            #field.readable = field.writable = False
            field = table.replies
            field.default = False
            #field.readable = field.writable = False

            field = table.body
            field.label = T("Description")
            # Plain text not Rich
            from s3.s3widgets import s3_comments_widget
            field.widget = s3_comments_widget
            #table.comments.readable = table.comments.writable = False

            #if request.controller == "default":
            #    # Don't override card layout for News Feed/Homepage
            #    return True

            from s3.s3forms import S3SQLCustomForm, S3SQLInlineComponent

            # Filter from a Profile page?
            # If so, then default the fields we know
            location_id = get_vars.get("~.(location)", None)
            if location_id:
                table.location_id.default = location_id
            event_id = get_vars.get("~.(event)", None)
            if event_id:
                crud_form = S3SQLCustomForm(
                    "date",
                    "series_id",
                    "body",
                    "location_id",
                    S3SQLInlineComponent(
                        "document",
                        name="file",
                        label=T("Files"),
                        fields=[
                            "file",
                            #"comments",
                        ],
                    ),
                )

                def create_onaccept(form):
                    table = current.s3db.event_event_post
                    table.insert(event_id=event_id, post_id=form.vars.id)

                s3db.configure(
                    "cms_post",
                    create_onaccept=create_onaccept,
                )
            else:
                crud_form = S3SQLCustomForm(
                    "date",
                    "series_id",
                    "body",
                    "location_id",
                    # @ToDo: deployment_setting for Events
                    #S3SQLInlineComponent(
                    #    "event_post",
                    #    #label = T("Disaster(s)"),
                    #    label = T("Disaster"),
                    #    multiple = False,
                    #    fields = ["event_id"],
                    #    orderby = "event_id$name",
                    #),
                    # @ToDo: deployment_setting
                    S3SQLInlineComponent(
                        "post_organisation",
                        label=T("Organization"),
                        fields=["organisation_id"],
                        # @ToDo: deployment_setting
                        multiple=False,
                    ),
                    # @ToDo: deployment_setting
                    "person_id",
                    S3SQLInlineComponent(
                        "document",
                        name="file",
                        label=T("Files"),
                        fields=[
                            "file",
                            #"comments",
                        ],
                    ),
                )

            # Return to List view after create/update/delete
            # We now do all this in Popups
            #url_next = URL(c="default", f="index", args="newsfeed")

            s3db.configure(
                "cms_post",
                #create_next = url_next,
                #delete_next = url_next,
                #update_next = url_next,
                crud_form=crud_form,
                # Don't include a Create form in 'More' popups
                listadd=False,
                list_layout=s3db.cms_render_posts,
            )

        elif r.representation == "xls":
            table.created_by.represent = s3base.s3_auth_user_represent_name
            #table.created_on.represent = datetime_represent
            utable = auth.settings.table_user
            utable.organisation_id.represent = s3db.org_organisation_represent

            list_fields = [
                (T("Date"), "date"),
                #(T("Disaster"), "event_post.event_id"),
                (T("Type"), "series_id"),
                (T("Details"), "body"),
            ]
            for level in levels:
                list_fields.append(
                    (hierarchy[level], "location_id$%s" % level))
            list_fields = + [
                (T("Contact"), contact_field),
                (T("Organization"), org_field),
            ]
            s3db.configure(
                "cms_post",
                list_fields=list_fields,
            )

        elif r.representation == "plain" and \
             r.method != "search":
            # Map Popups
            table.location_id.represent = s3db.gis_LocationRepresent(sep=" | ")
            table.created_by.represent = s3base.s3_auth_user_represent_name
            # Used by default popups
            series = table.series_id.represent(r.record.series_id)
            s3.crud_strings[
                "cms_post"].title_display = "%(series)s Details" % dict(
                    series=series)
            s3db.configure(
                "cms_post",
                popup_url="",
            )
            table.avatar.readable = False
            table.body.label = ""
            table.expired.readable = False
            table.replies.readable = False
            table.created_by.readable = True
            table.created_by.label = T("Author")
            # Used by cms_post_popup
            #table.created_on.represent = datetime_represent

        elif r.representation == "geojson":
            r.table.age = Field.Lazy(cms_post_age)

        return True

    s3.prep = prep

    def postp(r, output):
        if r.interactive:
            if r.method == "datalist" and r.representation != "dl":
                # Hide side menu
                current.menu.options = None
                response.view = s3base.S3CRUD._view(r, "cms/newsfeed.html")
        return output

    s3.postp = postp

    output = s3_rest_controller(
        "cms",
        "post",
        hide_filter=False,
    )
    return output
Exemple #5
0
def newsfeed():
    """
        RESTful CRUD controller for display of posts as a filterable dataList
        (use with /datalist method)
    """

    # Load Model
    table = s3db.cms_post
    stable = db.cms_series

    # Hide Posts linked to Modules and Maps & Expired Posts
    s3.filter = (FS("post_module.module") == None) & \
                (FS("post_layer.layer_id") == None) & \
                (FS("expired") != True)

    title_list = T("Latest Information")

    # Ensure that filtered views translate into options which update the Widget
    if "~.series_id$name" in get_vars:
        series_name = get_vars["~.series_id$name"]
        # Disabled as can change filters dynamically
        # @ToDo: Better Mechanism: Another field in cms_series?
        #if series_name == "Request":
        #    title_list = T("Latest Requests")
        #elif series_name == "Offer":
        #    title_list = T("Latest Offers")
        series = db(stable.name == series_name).select(stable.id,
                                                       cache=s3db.cache,
                                                       limitby=(0, 1)).first()
        if series:
            series_id = str(series.id)
            get_vars.pop("~.series_id$name")
            get_vars["~.series_id__belongs"] = series_id

    s3.crud_strings["cms_post"].title_list = title_list

    contact_field = settings.get_cms_person()
    org_field = settings.get_cms_organisation()
    org_group_field = settings.get_cms_organisation_group()
    show_events = settings.get_cms_show_events()

    hidden = not settings.get_cms_filter_open()

    from s3.s3filter import S3TextFilter, S3OptionsFilter, S3LocationFilter, S3DateFilter
    filter_widgets = [
        S3TextFilter(
            ["body"],
            label=T("Search"),
            _class="filter-search",
            #_placeholder = T("Search").upper(),
        ),
        S3LocationFilter(
            "location_id",
            label=T("Filter by Location"),
            hidden=hidden,
        ),
    ]
    fappend = filter_widgets.append
    finsert = filter_widgets.insert

    if show_events:
        fappend(
            S3OptionsFilter(
                "event_post.event_id",
                label=T("Filter by Disaster"),
                hidden=hidden,
            ))

    if org_field:
        fappend(
            S3OptionsFilter(
                org_field,
                label=T("Filter by Organization"),
                # Can't use this for created_by as integer, use field.represent instead
                #represent = "%(name)s",
                hidden=hidden,
            ))

    if org_group_field:
        group_label = settings.get_org_groups()
        if group_label:
            fappend(
                S3OptionsFilter(
                    org_group_field,
                    label=T("Filter by %(type)s") % dict(type=T(group_label)),
                    # Can't use this for created_by as integer, use field.represent instead
                    #represent = "%(name)s",
                    hidden=hidden,
                ))

    fappend(
        S3DateFilter(
            "date",
            label=T("Filter by Date"),
            hide_time=True,
            hidden=hidden,
        ))

    if settings.get_cms_show_tags():
        finsert(
            1,
            S3OptionsFilter(
                "tag_post.tag_id",
                label=T("Filter by Tag"),
                represent="%(name)s",
                hidden=hidden,
            ))

    if settings.get_cms_bookmarks() and auth.user:
        finsert(
            1,
            S3OptionsFilter(
                "bookmark.user_id",
                label=T("Filter by Bookmark"),
                # Can't just use "" as this is then omitted from rendering
                options={
                    "*": T("All"),
                    auth.user.id: T("My Bookmarks"),
                },
                cols=2,
                multiple=False,
                hidden=hidden,
            ))

    notify_fields = [
        (T("Date"), "date"),
        (T("Location"), "location_id"),
    ]

    len_series = db(stable.deleted == False).count()
    if len_series > 3:
        notify_fields.insert(0, (T("Type"), "series_id"))
        # Multiselect widget
        finsert(
            1,
            S3OptionsFilter(
                "series_id",
                label=T("Filter by Type"),
                # We want translations
                #represent = "%(name)s",
                hidden=hidden,
            ))

    elif len_series > 1:
        notify_fields.insert(0, (T("Type"), "series_id"))
        # Checkboxes
        finsert(
            1,
            S3OptionsFilter(
                "series_id",
                label=T("Filter by Type"),
                # We want translations
                #represent = "%(name)s",
                cols=2,
                hidden=hidden,
            ))
    else:
        # No Widget or notify_field
        pass

    nappend = notify_fields.append
    if org_field:
        nappend((T("Organization"), org_field))
    if org_group_field:
        if isinstance(group_label, bool):
            group_label = T("Organisation Group")
        nappend((T(group_label), org_group_field))
    if contact_field:
        nappend((T("Contact"), contact_field))
    nappend((T("Description"), "body"))

    # @todo: allow configuration (?)
    filter_formstyle = settings.get_ui_formstyle()
    s3db.configure(
        "cms_post",
        # We could use a custom Advanced widget
        #filter_advanced = False,
        filter_formstyle=filter_formstyle,
        # No Submit button (done automatically)
        #filter_submit = (T("SEARCH"), "btn btn-primary"),
        filter_widgets=filter_widgets,
        # Default anyway now:
        #list_layout = s3db.cms_post_list_layout,
        # Create form comes via AJAX in a Modal
        #insertable = False,
        notify_fields=notify_fields,
        notify_template="notify_post",
    )

    s3.dl_pagelength = 6  # 5 forces an AJAX call

    def prep(r):
        if r.interactive or r.representation == "aadata":
            s3db.cms_configure_newsfeed_post_fields()

        if r.interactive:
            if len_series > 1:
                refresh = get_vars.get("refresh", None)
                if refresh == "datalist":
                    # We must be coming from the News Feed page so can change the type on-the-fly
                    field = table.series_id
                    field.label = T("Type")
                    field.readable = field.writable = True
            else:
                field = table.series_id
                row = db(stable.deleted == False).select(stable.id,
                                                         limitby=(0,
                                                                  1)).first()
                try:
                    field.default = row.id
                except:
                    # Prepop not done: expose field to show error
                    field.label = T("Type")
                    field.readable = field.writable = True
                else:
                    field.readable = field.writable = False

            if r.method == "read":
                # Restore the label for the Location
                table.location_id.label = T("Location")
            elif r.method == "create":
                pass
                # @ToDo: deployment_setting
                #if not auth.s3_has_role("ADMIN"):
                #    represent = S3Represent(lookup="cms_series",
                #                            translate=settings.get_L10n_translate_cms_series())
                #    field.requires = IS_ONE_OF(db,
                #                               "cms_series.id",
                #                               represent,
                #                               not_filterby="name",
                #                               not_filter_opts = ("Alert",),
                #                               )

            #field = table.name
            #field.readable = field.writable = False
            #field = table.title
            #field.readable = field.writable = False
            field = table.avatar
            field.default = True
            #field.readable = field.writable = False
            field = table.replies
            field.default = False
            #field.readable = field.writable = False

            field = table.body
            field.label = T("Description")
            # Plain text not Rich
            from s3.s3widgets import s3_comments_widget
            field.widget = s3_comments_widget
            #table.comments.readable = table.comments.writable = False

            #if request.controller == "default":
            #    # Don't override card layout for News Feed/Homepage
            #    return True

            from s3.s3forms import S3SQLCustomForm, S3SQLInlineComponent

            # Filter from a Profile page?
            # If so, then default the fields we know
            location_id = get_vars.get("~.(location)", None)
            if location_id:
                table.location_id.default = location_id
            event_id = get_vars.get("~.(event)", None)
            if event_id:

                def create_onaccept(form):
                    table = current.s3db.event_post
                    table.insert(event_id=event_id, post_id=form.vars.id)

                s3db.configure(
                    "cms_post",
                    create_onaccept=create_onaccept,
                )

            crud_fields = [
                "date",
                "series_id",
            ]
            cappend = crud_fields.append
            if settings.get_cms_show_titles():
                cappend("title")
            crud_fields.extend((
                "body",
                "location_id",
            ))
            if not event_id and show_events:
                cappend(
                    S3SQLInlineComponent(
                        "event_post",
                        # @ToDo: deployment_setting (use same one used to activate?)
                        #label = T("Disaster(s)"),
                        label=T("Disaster"),
                        multiple=False,
                        fields=[("", "event_id")],
                        orderby="event_id$name",
                    ))
            if org_field == "post_organisation.organisation_id":
                cappend(
                    S3SQLInlineComponent(
                        "post_organisation",
                        label=T("Organization"),
                        fields=[("", "organisation_id")],
                        # @ToDo: deployment_setting
                        multiple=False,
                    ))
            if org_group_field == "post_organisation_group.group_id":
                cappend(
                    S3SQLInlineComponent(
                        "post_organisation_group",
                        label=T(group_label),
                        fields=[("", "group_id")],
                        # @ToDo: deployment_setting
                        multiple=False,
                    ))
            if contact_field == "person_id":
                cappend("person_id")

            if settings.get_cms_show_attachments():
                cappend(
                    S3SQLInlineComponent(
                        "document",
                        name="file",
                        label=T("Files"),
                        fields=[
                            ("", "file"),
                            #"comments",
                        ],
                    ))

            if settings.get_cms_show_links():
                cappend(
                    S3SQLInlineComponent(
                        "document",
                        name="url",
                        label=T("Links"),
                        fields=[
                            ("", "url"),
                            #"comments",
                        ],
                    ))
            crud_form = S3SQLCustomForm(*crud_fields)

            # Return to List view after create/update/delete
            # We now do all this in Popups
            #url_next = URL(c="default", f="index", args="newsfeed")

            s3db.configure(
                "cms_post",
                #create_next = url_next,
                #delete_next = url_next,
                #update_next = url_next,
                crud_form=crud_form,
                # Don't include a Create form in 'More' popups
                listadd=False,
            )

        elif r.representation == "xls":
            table.body.represent = None
            table.created_by.represent = s3base.s3_auth_user_represent_name
            #table.created_on.represent = datetime_represent
            utable = auth.settings.table_user
            utable.organisation_id.represent = s3db.org_organisation_represent

            list_fields = [
                (T("Date"), "date"),
                #(T("Disaster"), "event_post.event_id"),
                (T("Type"), "series_id"),
                (T("Details"), "body"),
            ]
            lappend = list_fields.append
            # Which levels of Hierarchy are we using?
            gis = current.gis
            levels = gis.get_relevant_hierarchy_levels()
            hierarchy = gis.get_location_hierarchy()
            for level in levels:
                lappend((hierarchy[level], "location_id$%s" % level))
            if contact_field:
                lappend((T("Contact"), contact_field))
            if org_field:
                lappend((T("Organization"), org_field))
            if org_group_field:
                lappend((T(group_label), org_group_field))
            s3db.configure(
                "cms_post",
                list_fields=list_fields,
            )

        elif r.representation == "plain":
            # Map Popups
            table.location_id.represent = s3db.gis_LocationRepresent(sep=" | ")
            table.created_by.represent = s3base.s3_auth_user_represent_name
            # Used by default popups
            series = table.series_id.represent(r.record.series_id)
            s3.crud_strings[
                "cms_post"].title_display = "%(series)s Details" % dict(
                    series=series)
            s3db.configure(
                "cms_post",
                popup_url="",
            )
            table.avatar.readable = False
            table.body.label = ""
            table.expired.readable = False
            table.replies.readable = False
            table.created_by.readable = True
            table.created_by.label = T("Author")
            # Used by cms_post_popup
            #table.created_on.represent = datetime_represent

        elif r.representation == "geojson":
            r.table.age = Field.Method("age", cms_post_age)

        return True

    s3.prep = prep

    def postp(r, output):
        if r.interactive:
            if r.method == "datalist" and r.representation != "dl":
                # Hide side menu
                current.menu.options = None
                response.view = s3base.S3CRUD._view(r, "cms/newsfeed.html")

        return output

    s3.postp = postp

    output = s3_rest_controller("cms", "post")
    return output
Exemple #6
0
def homepage():
    """
        Custom Homepage
        - DataList of CMS Posts
    """

    if not current.auth.is_logged_in():
        return login()

    T = current.T
    s3db = current.s3db
    request = current.request
    response = current.response
    s3 = response.s3

    current.deployment_settings.ui.customize_cms_post()

    list_layout = render_homepage_posts

    filter_widgets = [
        S3TextFilter(["body"],
                     label="",
                     _class="filter-search",
                     _placeholder=T("Search").upper()),
        S3OptionsFilter("series_id",
                        label=T("Filter by Type"),
                        represent="%(name)s",
                        cols=3),
        S3OptionsFilter("location_id",
                        label=T("Filter by Location"),
                        represent="%(name)s",
                        widget="multiselect",
                        cols=3),
        S3OptionsFilter("created_by$organisation_id",
                        label=T("Filter by Organization"),
                        represent="%(name)s",
                        widget="multiselect",
                        cols=3),
        S3DateFilter("created_on", label=T("Filter by Date")),
    ]

    s3db.configure(
        "cms_post",
        filter_formstyle=filter_formstyle,
        filter_submit=(T("Filter Results"), "btn btn-primary"),
        filter_widgets=filter_widgets,
        list_layout=list_layout,
    )

    s3.dl_pagelength = 6  # 5 forces an AJAX call

    if "datalist_dl_post" in request.args:
        ajax = True
    else:
        ajax = False

    def prep(r):
        if ajax:
            r.representation = "dl"
        return True

    s3.prep = prep

    request.args = ["datalist"]
    output = current.rest_controller("cms",
                                     "post",
                                     list_ajaxurl=URL(f="index",
                                                      args="datalist_dl_post"))

    if ajax:
        response.view = "plain.html"
    else:
        form = output["form"]
        # Remove duplicate Submit button
        form[0][-1] = ""
        if form.errors:
            s3.jquery_ready.append('''$("#myModal").modal("show")''')
        # Set Title & View after REST Controller, in order to override
        output[
            "title"] = response.title = current.deployment_settings.get_system_name(
            )
        view = path.join(request.folder, "private", "templates", "CSN",
                         "views", "index.html")
        try:
            # Pass view as file not str to work in compiled mode
            response.view = open(view, "rb")
        except IOError:
            from gluon.http import HTTP
            raise HTTP(404, "Unable to open Custom View: %s" % view)

        # Latest 5 Disasters
        resource = s3db.resource("event_event")
        list_fields = [
            "name",
            "zero_hour",
            "closed",
        ]
        orderby = resource.get_config("list_orderby",
                                      ~resource.table.created_on)
        datalist, numrows, ids = resource.datalist(
            fields=list_fields,
            start=None,
            limit=5,
            list_id="event_datalist",
            orderby=orderby,
            layout=render_homepage_events)
        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
            dl = datalist.html()
            data = dl

        output["disasters"] = data

    return output
Exemple #7
0
def _newsfeed():
    """
        Custom Page
        - Filterable DataList of CMS Posts & a DataList of Events
    """

    #if not current.auth.is_logged_in():
    #    current.auth.permission.fail()

    T = current.T
    s3db = current.s3db
    request = current.request
    response = current.response
    s3 = response.s3

    # Ensure that filtered views translate into options which update the Widget
    get_vars = request.get_vars
    if "~.series_id$name" in get_vars:
        series_name = get_vars["~.series_id$name"]
        table = s3db.cms_series
        series = current.db(table.name == series_name).select(
            table.id, limitby=(0, 1)).first()
        if series:
            series_id = str(series.id)
            get_vars.pop("~.series_id$name")
            get_vars["~.series_id__belongs"] = series_id

    current.deployment_settings.ui.customize_cms_post()

    list_layout = s3.render_posts

    filter_widgets = [
        S3TextFilter(
            ["body"],
            label="",
            _class="filter-search",
            #_placeholder=T("Search").upper(),
        ),
        S3OptionsFilter(
            "series_id",
            label=T("Filter by Type"),
            represent="%(name)s",
            widget="multiselect",
            hidden=True,
        ),
        S3LocationFilter(
            "location_id",
            label=T("Filter by Location"),
            levels=["L1", "L2", "L3"],
            widget="multiselect",
            hidden=True,
        ),
        S3OptionsFilter(
            "created_by$organisation_id",
            label=T("Filter by Organization"),
            # Can't use this for integers, use field.represent instead
            #represent="%(name)s",
            widget="multiselect",
            hidden=True,
        ),
        S3DateFilter(
            "created_on",
            label=T("Filter by Date"),
            hide_time=True,
            hidden=True,
        ),
    ]

    s3db.configure(
        "cms_post",
        # We use a custom Advanced widget
        filter_advanced=False,
        filter_formstyle=filter_formstyle,
        filter_submit=(T("SEARCH"), "btn btn-primary"),
        filter_widgets=filter_widgets,
        list_layout=list_layout,
        # Create form comes via AJAX in a Modal
        insertable=False,
        notify_fields=[
            (T("Type"), "series_id"),
            (T("Date"), "date"),
            (T("Location"), "location_id"),
            (T("Description"), "body"),
        ],
        notify_template="notify_post",
    )

    s3.dl_pagelength = 6  # 5 forces an AJAX call

    old_args = request.args
    if "datalist_dl_post" in old_args:
        # DataList pagination or Ajax-deletion request
        request.args = ["datalist_f"]
        ajax = "list"
    elif "datalist_dl_filter" in old_args:
        # FilterForm options update request
        request.args = ["filter"]
        ajax = "filter"
    elif "validate.json" in old_args:
        # Inline component validation request
        request.args = []
        ajax = True
    elif current.auth.permission.format == "msg":
        # Subscription lookup request
        request.args = []
        ajax = True
    else:
        # Default
        request.args = ["datalist_f"]
        ajax = None

    def prep(r):
        if ajax == "list":
            r.representation = "dl"
        elif ajax == "filter":
            r.representation = "json"
        return True

    s3.prep = prep

    output = current.rest_controller(
        "cms",
        "post",
        list_ajaxurl=URL(f="index", args="datalist_dl_post"),
        filter_ajax_url=URL(f="index", args="datalist_dl_filter", vars={}),
    )

    request.args = old_args

    if ajax == "list":
        # Don't override view if this is an Ajax-deletion request
        if not "delete" in request.get_vars:
            response.view = "plain.html"
    elif not ajax:
        # Set Title & View after REST Controller, in order to override
        output["title"] = T("News Feed")
        view = path.join(request.folder, "private", "templates", THEME,
                         "views", "newsfeed.html")
        try:
            # Pass view as file not str to work in compiled mode
            response.view = open(view, "rb")
        except IOError:
            from gluon.http import HTTP
            raise HTTP(404, "Unable to open Custom View: %s" % view)

        s3.js_global.append('''i18n.adv_search="%s"''' % T("Advanced Search"))
        s3.scripts.append("/%s/static/themes/%s/js/newsfeed.js" %
                          (request.application, THEME))

        # Latest 5 Disasters
        resource = s3db.resource("event_event")
        layout = render_events
        list_id = "event_datalist"
        limit = 5
        orderby = "zero_hour desc"
        list_fields = [
            "name",
            "event_type_id$name",
            "zero_hour",
            "closed",
        ]
        output["disasters"] = latest_records(resource, layout, list_id, limit,
                                             list_fields, orderby)

    return output
Exemple #8
0
    def custom_prep(r):
        # Call standard prep
        if callable(standard_prep):
            result = standard_prep(r)
            if not result:
                return False

        if r.interactive:
            messages = current.messages
            from s3.s3filter import S3TextFilter, S3OptionsFilter, S3LocationFilter, S3DateFilter
            filter_widgets = [
                S3TextFilter(["project_id$name",
                              "project_id$code",
                              "project_id$description",
                              "location_id$name",
                              "project_id$organisation.name",
                              "project_id$organisation.acronym",
                              ],
                             label=T("Name"),
                             _class="filter-search",
                             ),
                S3OptionsFilter("project_id$status_id",
                                label=T("Status"),
                                represent="%(name)s",
                                #widget="multiselect",
                                cols=3,
                                #hidden=True,
                                ),
                S3OptionsFilter("project_id$theme_project.theme_id",
                                label=T("Theme"),
                                represent="%(name)s",
                                widget="multiselect",
                                cols=3,
                                #hidden=True,
                                ),
                S3LocationFilter("location_id",
                                 label=T("Location"),
                                 levels=["L1", "L2"],
                                 widget="multiselect",
                                 cols=3,
                                 #hidden=True,
                                 ),
                # @ToDo: Widget to handle Start & End in 1!
                S3DateFilter("start_date",
                             label=T("Start Date"),
                             hide_time=True,
                             #hidden=True,
                             ),
                S3DateFilter("end_date",
                             label=T("End Date"),
                             hide_time=True,
                             #hidden=True,
                             ),
                ]
            report_fields = [
                #(messages.COUNTRY, "location_id$L0"),
                "location_id$L1",
                "location_id$L2",
                #"location_id$L3",
                #"location_id$L4",
                (messages.ORGANISATION, "project_id$organisation_id"),
                (T("Project"), "project_id"),
                #(T("Activity Types"), "activity_type.activity_type_id"),
                (T("Themes"), "project_id$theme.name"),
                ]
            report_options = Storage(
                rows=report_fields,
                cols=report_fields,
                fact=report_fields,
                defaults=Storage(rows="location_id$L2",
                                 #cols=(T("Themes"), "project_id$theme.name"),
                                 cols="project_id$theme.name",
                                 # T("Projects")
                                 fact="count(project_id$name)",
                                 totals=True
                                 )
                )
            current.s3db.configure("project_location",
                                   filter_widgets = filter_widgets,
                                   report_options = report_options,
                                   )
        return True
Exemple #9
0
    def custom_prep(r):
        # Call standard prep
        if callable(standard_prep):
            result = standard_prep(r)
        else:
            result = True

        if r.interactive or r.representation == "aadata":
            from s3.s3forms import S3SQLCustomForm, S3SQLInlineComponent, S3SQLInlineComponentCheckbox
            s3db = current.s3db

            table = r.table
            tablename = "project_project"
            table.code.label = T("Project blurb (max. 100 characters)")
            table.code.max_length = 100 
            table.comments.label = T("How people can help")

            script = '''$('#project_project_code').attr('maxlength','100')'''
            s3.jquery_ready.append(script)

            crud_form = S3SQLCustomForm(
                "organisation_id",
                "name",
                "code",        
                "description",
                "status_id",
                "start_date",
                "end_date",
                "calendar",
                #"drr.hfa",
                #"objectives",
                "human_resource_id",
                # Activities
                S3SQLInlineComponent(
                    "location",
                    label = T("Location"),
                    fields = ["location_id"],
                ),
                # Partner Orgs
                S3SQLInlineComponent(
                    "organisation",
                    name = "partner",
                    label = T("Partner Organizations"),
                    fields = ["organisation_id",
                              "comments", # NB This is labelled 'Role' in DRRPP
                              ],
                    filterby = dict(field = "role",
                    options = "2"
                    )
                ),
                S3SQLInlineComponent(
                    "document",
                    name = "media",
                    label = T("URLs (media, fundraising, website, social media, etc."),
                    fields = ["document_id",
                              "name",
                              "url",
                              "comments",
                              ],
                    filterby = dict(field = "name")
                ),                                                                
                S3SQLInlineComponentCheckbox(
                    "activity_type",
                    label = T("Categories"),
                    field = "activity_type_id",
                    cols = 3,
                    # Filter Activity Type by Project
                    filter = {"linktable": "project_activity_type_project",
                              "lkey": "project_id",
                              "rkey": "activity_type_id",
                              },
                ),
                #"budget",
                #"currency",
                "comments",
            )
            
            from s3.s3filter import S3TextFilter, S3OptionsFilter, S3LocationFilter, S3DateFilter
            filter_widgets = [
                S3TextFilter(["name",
                              "code",
                              "description",
                              "organisation.name",
                              "organisation.acronym",
                              ],
                             label=T("Name"),
                             _class="filter-search",
                             ),
                S3OptionsFilter("status_id",
                                label=T("Status"),
                                represent="%(name)s",
                                cols=3,
                                ),
                #S3OptionsFilter("theme_project.theme_id",
                #                label=T("Theme"),
                #                represent="%(name)s",
                #                widget="multiselect",
                #                #hidden=True,
                #                ),
                S3LocationFilter("location.location_id",
                                 label=T("Location"),
                                 levels=["L1", "L2", "L3", "L4"],
                                 widget="multiselect",
                                 #hidden=True,
                                 ),
                # @ToDo: Widget to handle Start & End in 1!
                S3DateFilter("start_date",
                             label=T("Start Date"),
                             hide_time=True,
                             #hidden=True,
                             ),
                S3DateFilter("end_date",
                             label=T("End Date"),
                             hide_time=True,
                             #hidden=True,
                             ),
                ]

            list_fields = ["id",
                           "name",
                           "code",
                           "organisation_id",
                           "start_date",
                           "end_date",
                           (T("Locations"), "location.location_id"),
                           ]

            s3db.configure(tablename,
                           crud_form = crud_form,
                           filter_widgets = filter_widgets,
                           list_fields = list_fields,
                           )

        return result