def _manage_subscriptions(self, resources, filters, recipient_filters, group_filters):

        from gluon.http import redirect
        from gluon.validators import IS_IN_SET
        from s3.s3widgets import S3GroupedOptionsWidget, S3MultiSelectWidget
        from s3layouts import S3PopupLink
        # Uses Default Eden formstyle
        from s3theme import formstyle_foundation as formstyle

        # L10n
        T = current.T
        db = current.db
        s3db = current.s3db
        auth = current.auth
        auth_user = auth.user
        gtable = db.auth_group
        has_role = auth.s3_has_role
        request = current.request
        response = current.response
        stable = s3db.pr_subscription
        ftable = s3db.pr_filter
        group_table = s3db.pr_group

        labels = Storage(
            #RESOURCES = T("Subscribe To"),
            #NOTIFY_ON = T("Notify On"),
            #FREQUENCY = T("Frequency"),
            NOTIFY_BY = T("Notify By"),
            #MORE = T("More Options"),
            #LESS = T("Less Options"),
        )
        messages = Storage(
            ERROR = T("Error: could not update notification settings"),
            SUCCESS = T("Notification settings updated"),
        )
        # Initialize form
        form = FORM(_id="subscription-form",
                    hidden={"subscription-filters": ""})

        row = db(gtable.role == "Alert Editor").select(gtable.id,
                                                       limitby=(0, 1)).first()

        ae_id = row.id # Alert Editor role as the owned_by_group to distinguish Admin-controlled subscriptions
        if recipient_filters is not None:
            subscription_id = request.get_vars.get("subscription_id")
            if subscription_id:
                # Update form from pr_subscription
                pr_row = db(stable.id == subscription_id).select(stable.pe_id,
                                                        limitby=(0, 1)).first()
                pe_id = pr_row.pe_id
                subscription = self._get_admin_subscription(\
                                                subscription_id=subscription_id,
                                                pe_id=pe_id,
                                                )
                recipient_subscription = self._get_recipients_and_groups(\
                                                subscription_id=subscription_id,
                                                pe_id=pe_id,
                                                caller="recipients",
                                                )
                group_subscription = self._get_recipients_and_groups(\
                                                subscription_id=subscription_id,
                                                pe_id=pe_id,
                                                caller="groups",
                                                )
            else:
                # Create form
                subscription = self._get_admin_subscription()
                recipient_subscription = self._get_recipients_and_groups()
                group_subscription = self._get_recipients_and_groups()
            filter_form = S3FilterForm(filters, clear=False)
            fieldset = FIELDSET(filter_form.fields(None,
                                                   subscription["get_vars"]),
                                _id="subscription-filter-form")
            recipient_filter_form = S3FilterForm(recipient_filters, clear=False)
            recipient_fieldset = FIELDSET(recipient_filter_form.fields(None,
                                            recipient_subscription["get_vars"]),
                                          _id="recipient-filter-form")
            group_filter_form = S3FilterForm(group_filters, clear=False)
            group_fieldset = FIELDSET(group_filter_form.fields(None,
                                                group_subscription["get_vars"]),
                                      _id="group-filter-form")
            form.append(recipient_fieldset)
            form.append(group_fieldset)
            form.append(fieldset)
        else:
            subscription_id = request.get_vars.get("subscription_id")
            if subscription_id:
                # Get current subscription settings resp. form defaults
                # Normal User
                subscription = self._get_subscription(subscription_id=subscription_id)
            else:
                # Create Form
                subscription = self._get_subscription()

            # Filters
            filter_form = S3FilterForm(filters, clear=False)
            fieldset = FIELDSET(filter_form.fields(None,
                                                   subscription["get_vars"]),
                                _id="subscription-filter-form")
            form.append(fieldset)

        # Notification options
        rows = []

        selector = S3GroupedOptionsWidget(cols=1)
        # Deactivated trigger selector
        #rows.append(("trigger_selector__row",
        #             "%s:" % labels.NOTIFY_ON,
        #             selector(stable.notify_on,
        #                      subscription["notify_on"],
        #                      _id="trigger_selector"),
        #             ""))

        #switch = S3GroupedOptionsWidget(cols=1, multiple=False, sort=False)
        # Deactivated: frequency selector
        #rows.append(("frequency_selector__row",
        #             "%s:" % labels.FREQUENCY,
        #             switch(stable.frequency,
        #                    subscription["frequency"],
        #                    _id="frequency_selector"),
        #             ""))

        methods = [("EMAIL", T("Email")),
                   ("SMS", T("SMS")),
                   ("FTP", T("FTP")),
                   ]

        method_options = Storage(name = "method", requires = IS_IN_SET(methods))

        rows.append(("method_selector__row",
                     "%s:" % labels.NOTIFY_BY,
                     selector(method_options,
                              subscription["method"],
                              _id="method_selector"),
                     ""))

        if not (request.get_vars["option"] == "manage_recipient" and \
           (has_role("ALERT_EDITOR") or has_role("ALERT_APPROVER"))):
            # managing own subscriptions
            properties = subscription["comments"]
            if properties:
                properties = json.loads(properties)

            synctable = s3db.sync_repository
            query = (synctable.apitype == "ftp") & \
                    (synctable.deleted != True) & \
                    (synctable.owned_by_user == auth_user.id)

            ftp_rows = db(query).select(synctable.id,
                                        synctable.name,
                                        orderby = synctable.id)

            multiselect = S3MultiSelectWidget(header = False,
                                              multiple = False,
                                              create = {"c": "sync",
                                                        "f": "repository",
                                                        "label": "Create Repository",
                                                        },
                                              )
            if ftp_rows:
                if properties:
                    user_repository_id = properties["repository_id"]
                else:
                    user_repository_id = ftp_rows.first().id

                if auth.s3_has_permission("update", "sync_repository",
                                          record_id = user_repository_id):
                    repository_comment = S3PopupLink(c = "sync",
                                                     f = "repository",
                                                     m = "update",
                                                     args = [user_repository_id],
                                                     title = T("Update Repository"),
                                                     tooltip = T("You can edit your FTP repository here"),
                                                     )
                field = s3db.sync_task.repository_id
                ftp_ids = [(r.id, s3_str(T(r.name))) for r in ftp_rows]
                field.requires = IS_IN_SET(ftp_ids)

                rows.append(("sync_task_repository_id__row",
                             "",
                             multiselect(field,
                                         user_repository_id,
                                         _id="sync_task_repository_id"),
                             repository_comment))
            else:
                if auth.s3_has_permission("create", "sync_repository"):
                    repository_comment = S3PopupLink(c = "sync",
                                                     f = "repository",
                                                     title = T("Add FTP Directory and Authentication Details"),
                                                     tooltip = T("Click on the link to begin creating your FTP repository and setting authentication details"),
                                                     )
                rows.append(("sync_task_repository_id__row",
                             "",
                             "",
                             repository_comment))

        parent = FIELDSET()

        for row in rows:
            parent.append(formstyle(form, [row]))

        # Deactivated Toggle
        #parent.insert(0,
        #              DIV(SPAN([I(_class="icon-reorder"), labels.MORE],
        #                       _class="toggle-text",
        #                       _style="display:none"),
        #                  SPAN([I(_class="icon-reorder"), labels.LESS],
        #                       _class="toggle-text"),
        #                  _id="notification-options",
        #                  _class="control-group"))
        form.append(parent)

        # Submit button
        submit_fieldset = FIELDSET(DIV("",
                                       INPUT(_type="submit",
                                             _value="Update Settings",
                                             _class="button small"),
                                       _id = "submit__row"))

        form.append(submit_fieldset)

        # Script (to extract filters on submit and toggle options visibility)
        script = URL(c="static", f="scripts", args=["S3", "s3.subscriptions.js"])
        response.s3.scripts.append(script)

        # Script to show/hide the ftp repo row for FTP checkbox on/off
        repository_script = '''
if($('#method_selector option[value=FTP]').is(':selected')){
    $('#sync_task_repository_id__row').show();
} else {
    $('#sync_task_repository_id__row').hide();
}

$('#method_selector').change(function(){
    if($(this).val().indexOf('FTP') != -1){
        $('#sync_task_repository_id__row').show();
    } else {
        $('#sync_task_repository_id__row').hide();
    }
})
'''
        response.s3.jquery_ready.append(repository_script)

        # Accept form
        if form.accepts(request.post_vars,
                        current.session,
                        formname="subscription",
                        keepvalues=True):

            formvars = form.vars

            #listify = lambda x: None if not x else x if type(x) is list else [x]

            # Fixed resource selection:
            subscription["subscribe"] = [resources[0]]
            # Alternatively, with resource selector:
            #subscribe = listify(formvars.resources)
            #if subscribe:
                #subscription["subscribe"] = \
                        #[r for idx, r in enumerate(resources)
                           #if str(idx) in subscribe]

            subscription["filters"] = form.request_vars \
                                      .get("subscription-filters", None)
            # Fixed method
            subscription["method"] = formvars.method
            # Fixed Notify On and Frequency
            subscription["notify_on"] = ["new"]
            subscription["frequency"] = "immediately"
            # Alternatively, with notify and frequency selector
            #subscription["notify_on"] = listify(formvars.notify_on)
            #subscription["frequency"] = formvars.frequency
            # Group IDs
            group_ids = formvars["group-filter"]
            # Recipient IDs
            user_ids = formvars["person-filter"]

            from collections import Counter

            get_event_type_priorities = self._get_event_type_priorities
            bulk_user_pe_id = auth.s3_bulk_user_pe_id
            get_group_pe_id = self._get_group_pe_id
            pr_group_table = s3db.pr_group
            define_resource = s3db.resource
            base_query = (stable.deleted != True)
            if user_ids is not None:
                # Admin Subscriptions
                # @ToDo: check super-set and/or sub-set for priorities and locations
                # of same event_type
                update_admin_subscription = self._update_admin_subscription
                if group_ids is None:
                    group_ids = []
                if group_ids or user_ids:
                    user_pe_ids = None
                    group_pe_ids = None
                    if user_ids:
                        user_pe_ids = bulk_user_pe_id(user_ids) # Current Selection
                    if group_ids:
                        group_pe_ids = get_group_pe_id(group_ids)
                    event_type_id, priorities = \
                        get_event_type_priorities(subscription["filters"]) # Current filters
                    subscription_id = request.get_vars.get("subscription_id")
                    if subscription_id:
                        query = base_query & \
                                (stable.id == subscription_id) & \
                                (stable.filter_id == ftable.id)
                        row = db(query).select(stable.pe_id,
                                               stable.filter_id,
                                               stable.comments,
                                               ftable.query,
                                               limitby=(0, 1)).first()
                        pr_subscription = row.pr_subscription
                        pe_id = row.pr_subscription.pe_id
                        if group_pe_ids and (pe_id in group_pe_ids.keys()):
                                event_type_id_s, priorities_s = \
                                    get_event_type_priorities(row.pr_filter.query)
                                if event_type_id_s == event_type_id and \
                                   Counter(priorities_s) == Counter(priorities):
                                    # Update
                                    comments = json.loads(pr_subscription.comments)
                                    success_subscription = update_admin_subscription(\
                                            subscription,
                                            pe_id,
                                            ae_id,
                                            group_id=comments["pr_group.id"],
                                            filter_id=pr_subscription.filter_id,
                                            subscription_id=subscription_id,
                                            )
                        elif user_pe_ids and (pe_id in user_pe_ids.values()):
                                event_type_id_s, priorities_s = \
                                    get_event_type_priorities(row.pr_filter.query)
                                if event_type_id_s == event_type_id and \
                                   Counter(priorities_s) == Counter(priorities):
                                    # Update
                                    user_id = [key for key, value in user_pe_ids.items()
                                               if value == pe_id][0]
                                    success_subscription = update_admin_subscription(\
                                            subscription,
                                            pe_id,
                                            ae_id,
                                            user_id=int(user_id),
                                            filter_id=pr_subscription.filter_id,
                                            subscription_id=subscription_id,
                                            )
                        else:
                            # Removed from subscriptions
                            define_resource("pr_subscription",
                                            id=subscription_id).delete()
                            define_resource("pr_filter",
                                            id=row.pr_subscription.filter_id).delete()
                    base_query = base_query & \
                                 (stable.owned_by_group != None) & \
                                 (stable.filter_id == ftable.id)
                    # Groups
                    if group_pe_ids:
                        for pe_id in group_pe_ids:
                            group_id = group_pe_ids[pe_id]
                            query = base_query & \
                                    (stable.pe_id == pe_id)
                            rows = db(query).select(stable.id,
                                                    stable.filter_id,
                                                    ftable.query)
                            if not rows:
                                # Create
                                success_subscription = update_admin_subscription(\
                                                            subscription,
                                                            pe_id,
                                                            ae_id,
                                                            group_id=int(group_id),
                                                            )
                            else:
                                for row in rows:
                                    event_type_id_s, priorities_s = \
                                        get_event_type_priorities(row.pr_filter.query)
                                    if event_type_id_s == event_type_id and \
                                       Counter(priorities_s) == Counter(priorities):
                                        # Update
                                        success_subscription = update_admin_subscription(\
                                            subscription,
                                            pe_id,
                                            ae_id,
                                            group_id=int(group_id),
                                            filter_id=row.pr_subscription.filter_id,
                                            subscription_id=row.pr_subscription.id,
                                            )
                                        break
                                else:
                                    # Create
                                    success_subscription = update_admin_subscription(\
                                                            subscription,
                                                            pe_id,
                                                            ae_id,
                                                            group_id=int(group_id),
                                                            )
                    # People
                    if user_pe_ids:
                        for user_id in user_pe_ids:
                            pe_id = int(user_pe_ids[user_id])
                            query = base_query & \
                                    (stable.pe_id == pe_id)
                            rows = db(query).select(stable.id,
                                                    stable.filter_id,
                                                    ftable.query)
                            if not rows:
                                # Create
                                success_subscription = update_admin_subscription(\
                                                                subscription,
                                                                pe_id,
                                                                ae_id,
                                                                user_id=int(user_id),
                                                                )
                            else:
                                for row in rows:
                                    event_type_id_s, priorities_s = \
                                        get_event_type_priorities(row.pr_filter.query)
                                    if event_type_id_s == event_type_id and \
                                       Counter(priorities_s) == Counter(priorities):
                                        # Update
                                        success_subscription = update_admin_subscription(\
                                                subscription,
                                                pe_id,
                                                ae_id,
                                                user_id=int(user_id),
                                                filter_id=row.pr_subscription.filter_id,
                                                subscription_id=row.pr_subscription.id,
                                                )
                                        break
                                else:
                                    # Create
                                    success_subscription = update_admin_subscription(\
                                                            subscription,
                                                            pe_id,
                                                            ae_id,
                                                            user_id=int(user_id),
                                                            )
                else:
                    # Removed from subscription
                    subscription_id = request.get_vars.get("subscription_id")
                    if subscription_id:
                        row = db(stable.id == subscription_id).select(\
                                                        stable.filter_id,
                                                        limitby=(0, 1)).first()
                        define_resource("pr_subscription",
                                        id=subscription_id).delete()
                        define_resource("pr_filter",
                                        id=row.filter_id).delete()
                redirect(URL(c="pr", f="subscription",
                             vars={"option": "manage_recipient"})
                         )
            else:
                # managing own subscription
                # @ToDo: check super-set and/or sub-set for priorities and locations
                # of same event_type
                update_subscription = self._update_subscription
                pe_id = auth_user.pe_id
                user_id = auth_user.id
                event_type_id, priorities = \
                    get_event_type_priorities(subscription["filters"]) # Current filters
                subscription_id = request.get_vars.get("subscription_id")
                if subscription_id:
                    query = base_query & \
                            (stable.id == subscription_id) & \
                            (stable.filter_id == ftable.id)
                    row = db(query).select(stable.filter_id,
                                           ftable.query,
                                           limitby=(0, 1)).first()
                    if row.pr_filter.query == subscription["filters"]:
                        # Update
                        success_subscription = update_subscription(\
                                        subscription,
                                        pe_id,
                                        filter_id=row.pr_subscription.filter_id,
                                        subscription_id=subscription_id,
                                        )
                    else:
                        # Remove
                        define_resource("pr_subscription",
                                        id=subscription_id).delete()
                        define_resource("pr_filter",
                                        id=row.pr_subscription.filter_id).delete()

                query = base_query & \
                        (stable.owned_by_group == None) & \
                        (stable.owned_by_user == user_id) & \
                        (stable.pe_id == pe_id) & \
                        (stable.filter_id == ftable.id)
                rows = db(query).select(stable.id,
                                        stable.filter_id,
                                        ftable.query)
                if rows:
                    for row in rows:
                        event_type_id_s, priorities_s = \
                            get_event_type_priorities(row.pr_filter.query)
                        if event_type_id_s == event_type_id and \
                           Counter(priorities_s) == Counter(priorities):
                            # Update
                            success_subscription = update_subscription(\
                                        subscription,
                                        pe_id,
                                        filter_id=row.pr_subscription.filter_id,
                                        subscription_id=row.pr_subscription.id,
                                        )
                            break
                    else:
                        # Create
                        success_subscription = update_subscription(subscription,
                                                                   pe_id)
                else:
                    # Create
                    success_subscription = update_subscription(subscription, pe_id)

                # Process Sync FTP Subscription
                if "FTP" in subscription["method"] and formvars.repository_id:
                    properties = self._update_sync(subscription["subscribe"][0]['resource'],
                                                   subscription.get("filters"),
                                                   int(formvars.repository_id),
                                                   properties)
                    properties = json.dumps(properties)
                    query = base_query & \
                            (stable.pe_id == pe_id) & \
                            (stable.owned_by_group == None) & \
                            (stable.owned_by_user == user_id)
                    db(query).update(comments=properties)
                else:
                    self._remove_sync(properties)
                    query = base_query & \
                            (stable.pe_id == pe_id) & \
                            (stable.owned_by_group == None) & \
                            (stable.owned_by_user == user_id)
                    db(query).update(comments=None)
                
                redirect(URL(c="pr", f="subscription"))

            if success_subscription:
                response.confirmation = messages.SUCCESS
            else:
                response.error = messages.ERROR

        return form

    # -------------------------------------------------------------------------
Custom form to manage subscriptions
dataset/ETHPy150Open sahana/eden/modules/templates/SAMBRO/controllers.py/subscriptions._manage_subscriptions