Beispiel #1
0
def activity(id=0,
             resend=False,
             period='Week',
             format='html',
             source='default'):
    # This will be triggered from runactivity function below which figures out if
    # this needs to be run and on success rolls the run date forward for the next
    # period this just formats the message and formats for sending via email

    db = current.db

    if id > 0:
        rows = db(db.email_runs.id == id).select()
        # if record status not equal to planned then log not sending to console and lets go with
        # only resending by id number
    else:
        rows = db((db.email_runs.runperiod == period)
                  & (db.email_runs.status == 'Planned')).select()

    if rows is None:
        print('No matching parameter record found')
        return 'No matching parameter record found'

    parameters = rows.first()
    params = current.db(current.db.website_parameters.id > 0).select().first()

    if params:
        stripheader = params.website_url[7:]
    else:
        stripheader = 'website_url_not_setup'

    startdate = parameters.datefrom
    enddate = parameters.dateto

    crtquery = (db.question.createdate >= startdate) & (db.question.createdate
                                                        <= enddate)
    resquery = (db.question.resolvedate >=
                startdate) & (db.question.resolvedate <= enddate)
    challquery = (db.question.challengedate >=
                  startdate) & (db.question.challengedate <= enddate)

    orderstr = db.question.createdate
    resolvestr = db.question.resolvedate
    challstr = db.question.challengedate

    allsubmitted = db(crtquery).select(orderby=orderstr)
    resolved = db(resquery).select(orderby=resolvestr)
    challenged = db(challquery).select(orderby=challstr)

    sender = mail.settings.sender
    subject = 'NDS Activity Report'

    # get users for type of run
    if parameters.runperiod == 'Day':
        userquery = (db.auth_user.emaildaily == True)
        periodtext = 'Daily'
    elif parameters.runperiod == 'Week':
        userquery = (db.auth_user.emailweekly == True)
        periodtext = 'Weekly'
    elif parameters.runperiod == 'Month':
        periodtext = 'Monthly'
        userquery = (db.auth_user.emailmonthly == True)
    else:
        return ('Invalid run period parameter - must be Day, Week or Month')

    users = db(userquery).select()
    message = ''
    for user in users:
        to = user.email
        # will change above to create allsubmitteds and then do a filter

        exclude_groups = get_exclude_groups(user.id)
        if exclude_groups:
            submitted = allsubmitted.exclude(
                lambda r: r.answer_group not in exclude_groups)
        else:
            submitted = allsubmitted

        message = '<html><body><h1> ' + periodtext + ' Activity Report</h1>'

        # should be able to make personal as well
        # can do the row exclusions later

        # section below is basically taken from activtiy.i file in the view

        message += "<h1>Items Resolved</h1>"
        if resolved:
            message += """<table style="border: 1px solid DarkGreen;"><thead><tr>
                        <th width="5%">Type</th>
                        <th width="55%">Item Text</th>
                        <th width="15%">Answer</th>
                        <th width="8%"># Agree</th>
                        <th width="8%"># Disagree</th>
                        <th width="9%">Resolved</th>
                    </tr>
                </thead>
                    <tbody>"""
            for row in resolved:
                itemurl = URL('viewquest',
                              'index',
                              args=[row.id],
                              scheme='http',
                              host=stripheader)
                itemtext = truncquest(row.questiontext)
                message += """<tr>
                <th><a href=%s>%s</a></th>
                <td>%s</td>
                <td>%s</td>
                <td>%s</td>
                <td>%s</td>
                <td>%s</td>

                </tr>""" % (itemurl, row.qtype, itemtext, row.correctanstext(),
                            row.othercounts[3], row.othercounts[3],
                            row.resolvedate)
            message += " </tbody></table>"
        else:
            message += "<h3>No items resolved in the period.</h3>"

        message += "<h1>Items Submitted</h1>"
        if submitted:
            message += """<table style="border: 1px solid black;"><thead><tr>
                        <th width="5%">Type</th>
                        <th width="60%">Item Text</th>
                        <th width="13%">Scope</th>
                        <th width="12%">Category</th>
                        <th width="10%">Status</th>
                    </tr>
                </thead>
                    <tbody>"""
            for row in submitted:
                itemurl = URL('viewquest',
                              'index',
                              args=[row.id],
                              scheme='http',
                              host=stripheader)
                itemtext = row.questiontext
                message += """<tr>
                <th><a href=%s>%s</a></th>
                <td>%s</td>
                <td>%s</td>
                <td>%s</td>
                <td>%s</td>
                </tr>""" % (itemurl, row.qtype, itemtext, row.scopetext,
                            row.category, row.status)
            message += " </tbody></table>"
        else:
            message += "<h3>No items submitted in the period.</h3>"

        message += "<h1>Items Challenged</h1>"
        if challenged:
            message += """<table style="border: 1px solid DarkOrange;"><thead><tr>
                        <th width="5%">Level</th>
                        <th width="55%">Question</th>
                        <th width="15%">Answer</th>
                        <th width="8%"># Agree</th>
                        <th width="8%"># Disagree</th>
                        <th width="9%">Challenged</th>
                    </tr>
                </thead>
                    <tbody>"""
            for row in challenged:
                itemurl = URL('viewquest',
                              'index',
                              args=[row.id],
                              scheme='http',
                              host=stripheader)
                itemtext = row.questiontext
                message += """<tr>

                <th><a href=%s>%s</a></th>
                <td>%s</td>
                <td>%s</td>
                <td>%s</td>
                <td>%s</td>
                <td>%s</td>
                </tr>""" % (itemurl, row.qtype, itemtext, row.correctanstext(),
                            row.othercounts[3], row.othercounts[3],
                            row.resolvedate)
            message += " </tbody></table>"
        else:
            message += "<h3>No items challenged in the period.</h3>"

        message += '<p>This report covers the period from %s to %s.</p>' % (
            str(startdate), str(enddate))

        # TODO this should move to module as may be repeated
        params = current.db(
            current.db.website_parameters.id > 0).select().first()
        if params:
            stripheader = params.website_url[7:]
        else:
            stripheader = 'website_url_not_setup'
        if login == 'socialauth':
            controller = 'user'
            itemurl = URL('plugin_social_auth',
                          controller,
                          args=['profile'],
                          scheme='http',
                          host=stripheader)
        else:
            controller = 'user'
            itemurl = URL('default',
                          controller,
                          args=['profile'],
                          scheme='http',
                          host=stripheader)

        footer = '<br><br><p>Login then manage your email preferences at ' + itemurl + '</p>'

        message += footer
        message += '</body></html>'

        if resolved or challenged or submitted:
            send_email(to, mail.settings.sender, subject, message)
        else:
            if debug:
                print(subject, message)
                send_email(to, mail.settings.sender, subject, message)
    print(message)

    return 'run successful'
Beispiel #2
0
def questarch():

    # this came from questload and it may make sense to combine - however fields
    # and strquery would be different lets confirm works this way and then think about it
    # but no point to fields on select for GAE
    # latest thinking is thar request variables would apply if present but otherwise
    # may want to use session variables - but not on home page so maybe have some request args
    # as well - so lets try default to not apply session variables and then qtype for action/issue for now
    # possible session variables are:
    #   session.showcat
    #   session.showscope
    #   session.scope
    #   session.category
    #   session.vwcontinent
    #   session.vwcountry
    #   session.vwsubdivision
    #   session.answer_group
    #   session.sortorder
    # if source is default we don't care about session variables it's a standard view with request vars applied
    # but if other source then we should setup session variables and then apply request vars
    #   session.eventid is not used unless called from eventaddquests and the source will then need to be sent as
    # 'event' to get the button to add and remove from event as appropriate

    source = request.args(0, default='std')
    view = request.args(1, default='Action')

    # sort of got idea of v, q and s to consider for view, strquery and sort order
    # source currently always default for this but will leave as is for now
    scope = request.vars.scope or (source != 'default' and session.scope) or '1 Global'
    category = request.vars.category or (source != 'default' and session.category) or 'Unspecified'
    vwcontinent = request.vars.vwcontinent or (source != 'default' and session.vwcontinent) or 'Unspecified'
    vwcountry = request.vars.vwcountry or (source != 'default' and session.vwcountry) or 'Unspecified'
    vwsubdivision = request.vars.vwsubdivision or (source != 'default' and session.vwsubdivision) or 'Unspecified'
    sortorder = request.vars.sortorder or (source != 'default' and session.sortorder) or 'Unspecified'
    event = request.vars.event or (source != 'default' and session.sortby) or 'Unspecified'
    answer_group = request.vars.answer_group or (source != 'default' and session.answer_group) or 'Unspecified'
    startdate = request.vars.startdate or (source != 'default' and session.startdate) or (
        request.utcnow - timedelta(days=1000))
    enddate = request.vars.enddate or (source != 'default' and session.enddate) or request.utcnow
    context=request.vars.context or 'Unspecified'

    filters = (source != 'default' and session.filters) or []
    # this can be Scope, Category, AnswerGroup and probably Event in due course

    scope_filter = request.vars.scope_filter or 'Scope' in filters
    cat_filter = request.vars.cat_filter or 'Category' in filters
    group_filter = request.vars.group_filter or 'AnswerGroup' in filters
    date_filter = request.vars.datefilter or 'Date' in filters

    selection = (source not in ('default', 'event', 'evtunlink') and session.selection) or ['Question', 'Resolved']

    # selection will currently be displayed separately
    # db.viewscope.selection.requires = IS_IN_SET(['Issue','Question','Action','Proposed','Resolved','Draft'
    # so possibly maybe IP, IR, IM, QP, QR, QM, AP, AR, AM - but this can maybe always be in the URL

    if request.vars.selection == 'QP':
        strquery = (db.eventmap.qtype == 'quest') & (db.eventmap.queststatus == 'In Progress')
    elif request.vars.selection == 'QR':
        strquery = (db.eventmap.qtype == 'quest') & (db.eventmap.queststatus == 'Resolved')
    elif request.vars.selection == 'QD' and auth.user:
        strquery = (db.eventmap.qtype == 'quest') & (db.eventmap.queststatus == 'Draft')\
                   & (db.eventmap.auth_userid == auth.user.id)
    elif request.vars.selection == 'IP':
        strquery = (db.eventmap.qtype == 'issue') & (db.eventmap.queststatus == 'In Progress')
        response.view = 'default/issuearch.load'
    elif request.vars.selection == 'IR':
        strquery = (db.eventmap.qtype == 'issue') & (db.eventmap.queststatus == 'Agreed')
        response.view = 'default/issuearch.load'
    elif request.vars.selection == 'IM':
        strquery = (db.eventmap.qtype == 'issue') & (db.eventmap.queststatus == 'Draft') & (
                    db.eventmap.auth_userid == auth.user_id)
        response.view = 'default/issuearch.load'
    elif request.vars.selection == 'AP':
        strquery = (db.eventmap.qtype == 'action') & (db.eventmap.queststatus == 'In Progress')
        response.view = 'default/actionarch.load'
    elif request.vars.selection == 'AR':
        strquery = (db.eventmap.qtype == 'action') & (db.eventmap.queststatus == 'Agreed')
        response.view = 'default/actionarch.load'
    elif request.vars.selection == 'AM':
        strquery = (db.eventmap.qtype == 'action') & (db.eventmap.queststatus == 'Draft')\
                   & (db.eventmap.auth_userid == auth.user_id)
        response.view = 'default/actionarch.load'
    else:
        strquery = (db.eventmap.qtype == 'quest') & (db.eventmap.queststatus == 'Resolved')

    if date_filter:
        strquery &= (db.eventmap.createdate >= startdate) & (db.eventmap.createdate <= enddate)

    if cat_filter and cat_filter != 'False':
        strquery &= (db.eventmap.category == category)

    if scope_filter is True:
        strquery &= db.eventmap.activescope == scope
        if session.scope == '1 Global':
            strquery &= db.eventmap.activescope == scope
        elif session.scope == '2 Continental':
            strquery = strquery & (db.eventmap.activescope == session.scope) & (
                db.eventmap.continent == vwcontinent)
        elif session.scope == '3 National':
            strquery = strquery & (db.eventmap.activescope == session.scope) & (
                    db.eventmap.country == vwcountry)
        elif session.scope == '4 Local':
            strquery = strquery & (db.eventmap.activescope == session.scope) & (
                    db.eventmap.subdivision == vwsubdivision)

    if group_filter and group_filter != 'False':
        strquery &= db.eventmap.answer_group == answer_group

    strquery &= db.eventmap.eventid == event

    sortby = ~db.eventmap.priority

    if request.vars.page:
        page = int(request.vars.page)
    else:
        page = 0

    if request.vars.items_per_page:
        items_per_page = int(request.vars.items_per_page)
    else:
        items_per_page = 50

    limitby = (page * items_per_page, (page + 1) * items_per_page + 1)
    q = request.vars.selection

    no_page = request.vars.no_page

    # removed caching for now as there are issues
    # quests = db(strquery).select(orderby=[sortby], limitby=limitby, cache=(cache.ram, 1200), cacheable=True)
    quests = db(strquery).select(orderby=[sortby], limitby=limitby)

    # remove excluded groups always
    if session.exclude_groups is None:
        session.exclude_groups = get_exclude_groups(auth.user_id)
    if quests and session.exclue_groups:
        alreadyans = quests.exclude(lambda r: r.answer_group in session.exclude_groups)
    return dict(strquery=strquery, quests=quests, page=page, source=source, items_per_page=items_per_page, q=q,
                view=view, no_page=no_page, event=event)
Beispiel #3
0
def questload():
    # this came from resolved and thinking is it may replace it in due course but have
    # take then hradio button form out for now at least
    # need to get the event id into the strquery in due course but get it basically working
    # first

    # this came from questload and it may make sense to combine - however fields
    # and strquery would be different lets confirm works this way and then think about it
    # but no point to fields on select for GAE
    # latest thinking is thar request variables would apply if present but otherwise
    # may want to use session variables - but not on home page so maybe have some request args
    # as well - so lets try default to not apply session variables and then qtype for action/issue for now
    # possible session variables are:
    #   session.showcat
    #   session.showscope
    #   session.scope
    #   session.category
    #   session.vwcontinent
    #   session.vwcountry
    #   session.vwsubdivision
    #   session.answer_group
    #   session.sortorder
    #   session.evtid
    # if source is default we don't care about session variables it's a standard view with request vars applied
    # but if other source then we should setup session variables and then apply request vars
    #   session.eventid is not used unless called from eventaddquests and the source will then need to be sent as
    # 'event' to get the button to add and remove from event as appropriate

    source = request.args(0, default='std')
    view = request.args(1, default='Action')

    # sort of got idea of v, q and s to consider for view, strquery and sort order

    scope = request.vars.scope or (source != 'default' and session.scope) or '1 Global'
    category = request.vars.category or (source != 'default' and session.category) or 'Unspecified'
    vwcontinent = request.vars.vwcontinent or (source != 'default' and session.vwcontinent) or 'Unspecified'
    vwcountry = request.vars.vwcountry or (source != 'default' and session.vwcountry) or 'Unspecified'
    vwsubdivision = request.vars.vwsubdivision or (source != 'default' and session.vwsubdivision) or 'Unspecified'
    sortorder = request.vars.sortorder or (source != 'default' and session.sortorder) or 'Unspecified'
    event = request.vars.event or (source != 'default' and session.evtid) or 'Unspecified'
    answer_group = request.vars.answer_group or (source != 'default' and session.answer_group) or 'Unspecified'
    startdate = request.vars.startdate or (source != 'default' and session.startdate) or (
        request.utcnow - timedelta(days=1000))
    enddate = request.vars.enddate or (source != 'default' and session.enddate) or request.utcnow

    filters = (source != 'default' and session.filters) or []
    # this can be Scope, Category, AnswerGroup and probably Event in due course

    scope_filter = request.vars.scope_filter or 'Scope' in filters
    cat_filter = request.vars.cat_filter or 'Category' in filters
    group_filter = request.vars.group_filter or 'AnswerGroup' in filters
    date_filter = request.vars.datefilter or 'Date' in filters
    event_filter = request.vars.event_filter or 'Event' in filters  # so this will now need to be included in some calls

    selection = (source not in ('default', 'event', 'evtunlink') and session.selection) or ['Question', 'Resolved']

    # selection will currently be displayed separately
    # db.viewscope.selection.requires = IS_IN_SET(['Issue','Question','Action','Proposed','Resolved','Draft'
    # so possibly maybe IP, IR, IM, QP, QR, QM, AP, AR, AM - but this can maybe always be in the URL

    if request.vars.selection == 'QP':
        strquery = (db.question.qtype == 'quest') & (db.question.status == 'In Progress')
    elif request.vars.selection == 'QR':
        strquery = (db.question.qtype == 'quest') & (db.question.status == 'Resolved')
    elif request.vars.selection == 'QD' and auth.user:  #  changed to all drafts with event filter
        strquery = (db.question.status == 'Draft') & (db.question.auth_userid == auth.user.id)
    elif request.vars.selection == 'IP':
        strquery = (db.question.qtype == 'issue') & (db.question.status == 'In Progress')
        response.view = 'default/issueload.load'
    elif request.vars.selection == 'IR':
        strquery = (db.question.qtype == 'issue') & (db.question.status == 'Agreed')
        response.view = 'default/issueload.load'
    elif request.vars.selection == 'IM':
        strquery = (db.question.qtype == 'issue') & (db.question.status == 'Draft') & (
                    db.question.auth_userid == auth.user_id)
        response.view = 'default/issueload.load'
    elif request.vars.selection == 'AP':
        strquery = (db.question.qtype == 'action') & (db.question.status == 'In Progress')
        response.view = 'default/actionload.load'
    elif request.vars.selection == 'AR':
        strquery = (db.question.qtype == 'action') & (db.question.status == 'Agreed')
        response.view = 'default/actionload.load'
    elif request.vars.selection == 'PL':
        strquery = (db.question.qtype == 'action') & (db.question.status == 'Agreed')
        response.view = 'default/planload.load'
    elif request.vars.selection == 'AM':
        strquery = (db.question.qtype == 'action') & (db.question.status == 'Draft')\
                   & (db.question.auth_userid == auth.user_id)
        response.view = 'default/actionload.load'
    else:
        strquery = (db.question.qtype == 'quest') & (db.question.status == 'Resolved')

    if date_filter:
        strquery &= (db.question.createdate >= startdate) & (db.question.createdate <= enddate)

    if cat_filter and cat_filter != 'False':
        strquery &= (db.question.category == category)
    
    if request.vars.event or (event_filter and event != 'Unspecified'):
        strquery &= db.question.eventid == event

    if scope_filter is True:
        strquery &= db.question.activescope == scope
        if session.scope == '1 Global':
            strquery &= db.question.activescope == scope
        elif session.scope == '2 Continental':
            strquery = strquery & (db.question.activescope == session.scope) & (
                db.question.continent == vwcontinent)
        elif session.scope == '3 National':
            strquery = strquery & (db.question.activescope == session.scope) & (
                    db.question.country == vwcountry)
        elif session.scope == '4 Local':
            strquery = strquery & (db.question.activescope == session.scope) & (
                    db.question.subdivision == vwsubdivision)

    if group_filter and group_filter != 'False':
        strquery &= db.question.answer_group == answer_group

    if request.vars.sortby == 'ResDate':
        sortorder = '2 Resolved Date'
    elif request.vars.sortby == 'Priority':
        sortorder = '1 Priority'
    elif request.vars.sortby == 'CreateDate':
        sortorder = '3 Submit Date'

    if sortorder == '1 Priority':
        sortby = ~db.question.priority
    elif sortorder == '3 Submit Date':
        sortby = ~db.question.createdate
    else:
        sortby = ~db.question.resolvedate

    if request.vars.page:
        page = int(request.vars.page)
    else:
        page = 0

    if request.vars.items_per_page:
        items_per_page = int(request.vars.items_per_page)
    else:
        items_per_page = 50

    limitby = (page * items_per_page, (page + 1) * items_per_page + 1)
    q = request.vars.selection

    no_page = request.vars.no_page

    # removed caching for now as there are issues
    # quests = db(strquery).select(orderby=[sortby], limitby=limitby, cache=(cache.ram, 1200), cacheable=True)
    quests = db(strquery).select(orderby=[sortby], limitby=limitby)
    
    # remove excluded groups always
    if session.exclude_groups is None:
        session.exclude_groups = get_exclude_groups(auth.user_id)
    if quests and session.exclue_groups:
        alreadyans = quests.exclude(lambda r: r.answer_group in session.exclude_groups)
        
    projxml = "<project>"
    if request.vars.selection == 'PL':
        questlist = [x.id for x in quests]
        dependlist = [[] for x in xrange(len(questlist))]
        intlinks = getlinks(questlist)
        for x in intlinks:
            dependlist[questlist.index(x.targetid)].append(x.sourceid)
    
        if quests:
            for i, row in enumerate(quests):
                z = str(dependlist[i])
                y = max(len(z)-2, 1)
                strdepend = z[1:y]
                projxml += convrow(row, strdepend)  
         
    projxml += '</project>'      
                
    return dict(strquery=strquery, quests=quests, page=page, source=source, items_per_page=items_per_page, q=q,
                view=view, no_page=no_page, event=event, project=projxml)
Beispiel #4
0
def getquesteventsql(eventid, questtype='All', userid=None, excluded_categories=None):
    # so this will be sql based routine to navigate the event questions
    # result should be a list which will start at the top left based on the layout of the items
    # but it should then complete navigation of all links from that question and then restart
    # with next top left and repeat for the entire collection - the navigation needs to be 
    # across the full event but previously answered questions are skipped
    # there is no caring about issues, actions or questions these all flow but excluded questions
    # will break links

    current.session.exclude_groups = get_exclude_groups(userid)
    current.session.permitted_groups = get_groups(userid)
    questrow = 0
    debugsql = True
    debug = True

    orderstr = ''

    if eventid:
        ansquests = current.db((current.db.userquestion.auth_userid == current.session.auth.user) &
                       (current.db.userquestion.status == 'In Progress')).select(current.db.userquestion.questionid)
        if not current.session.answered:
            current.session.answered=[]
        for row in ansquests:
            current.session.answered.append(row.questionid)
            
        query = (current.db.question.eventid == eventid)
        orderstr = current.db.question.xpos

        query &= (current.db.question.answer_group.belongs(current.session.permitted_groups))

        if questtype != 'all':
            query &= (current.db.question.qtype == questtype)
        
        # Not sure whether sorting by x y is better or go the get event route
        quests, questlist=getevent(eventid, 'Open', 'Event')
        not_in_prog = [x.id for x in quests if x.status != 'In Progress']
        #print('nip', not_in_prog)
        
        if questlist:           
            #intlinks = getlinks(questlist)
            intquery = (current.db.questlink.targetid.belongs(questlist)) & (current.db.questlink.status == 'Active') & (
                    current.db.questlink.sourceid.belongs(questlist))
            intlinks = current.db(intquery).select()
            
            links = [x.sourceid for x in intlinks]
            linklist = [(x.sourceid, x.targetid, {'weight': 30}) for x in intlinks]
        
            G = conv_for_iter(questlist, linklist)
        
            sequencelist = list(iter_dfs(G, 0))

            questorderlist=get_trav_list(questlist, sequencelist)

            allquestsordered = questorderlist[1:] # remove event as first element which will be 0

            questwithanswered = [x for x in allquestsordered if x not in not_in_prog]

            if current.session.answered is None:
                current.session.answered = []
                ansquests = current.db((current.db.userquestion.auth_userid == current.session.auth.user) &
                       (current.db.userquestion.status == 'In Progress')).select(current.db.userquestion.questionid)
                for row in ansquests:
                    current.session.answered.append(row.questionid)
        
            questorderlist = [x for x in questwithanswered if x not in current.session.answered]

            if not questorderlist:
                nextquestion = 0
            else:
                nextquestion = questorderlist[0]
                update_session(quests, questtype)
            #for i, row in enumerate(questorderlist):
            #    if i > 0:
            #        current.session[questtype].append(row)
            #    else:
             #       current.session[questtype] = [row]
            if debug:
                print (current.session[questtype])
        else:
            nextquestion = 0
    else:
        nextquestion = 0
    return nextquestion
    
Beispiel #5
0
def getquestnonsql(questtype='quest', userid=None, excluded_categories=None):
    #This is called on non-sql datastores or if configured as non-sql

    if current.session.answered is None:
        current.session.answered = []
        ansquests = current.db((current.db.userquestion.auth_userid == current.session.auth.user) &
                       (current.db.userquestion.status == 'In Progress')).select(current.db.userquestion.questionid)
        for row in ansquests:
            current.session.answered.append(row.questionid)
    current.session.exclude_groups = get_exclude_groups(userid)
    questrow = 0

    if debug:
        print (current.session.exclude_groups)

    orderstr = ''
    if current.session.auth.user.continent == 'Unspecified':  # ie no geographic restriction
        for i in xrange(0, 3):
            if i == 0:
                query = (current.db.question.question_level == current.session.auth.user.userlevel) & (current.db.question.status == 'In Progress')
                orderstr = ~current.db.question.priority
            elif i == 1:
                if current.auth.user.userlevel >1:
                    query = (current.db.question.question_level < current.session.auth.user.userlevel) & (current.db.question.status == 'In Progress')
                    orderstr = ~current.db.question.question_level | ~current.db.question.priority
            elif i == 2:
                query = (current.db.question.question_level > current.session.auth.user.userlevel) & (current.db.question.status == 'In Progress')
                orderstr = current.db.question.question_level | ~current.db.question.priority
            elif i == 3:
                query = (current.db.question.status == 'In Progress')
                orderstr = ~current.db.question.priority

            if questtype != 'all':
                query &= current.db.question.qtype == questtype

            quests = current.db(query).select(orderby=orderstr)
            questrow = quests.first()

            # exclude previously answered - this approach specifically taken rather than
            # an outer join so it can work on google app engine
            # then filter for unanswered and categories users dont want questions on
            alreadyans = quests.exclude(lambda row: row.id in current.session.answered)
            alreadyans = quests.exclude(lambda row: row.category in excluded_categories)
            alreadyans = quests.exclude(lambda row: row.answer_group in current.session.exclude_groups)

            questrow = quests.first()
            if questrow is not None:
                break
    else:
        # This is separate logic which applies when user has specified a continent - the general
        # thinking is that users cannot opt out of global questions but they may specify a continent
        # and optionally also a country and a subdivision in all cases we will be looking to
        # run 4 queries the global and continental queries will always be the same but
        # the country and subdvision queries are conditional as country and subdivision
        # may be left unspecified in which case users should get all national quests for
        # their continent or all local questions for their country - we will attempt to
        # keep the same logic surrounding levels shorlty

        for i in xrange(0, 3):
            if i == 0:
                query = (current.db.question.question_level == current.session.auth.user.userlevel) & (current.db.question.status == 'In Progress')
            elif i == 1:
                if current.auth.user.userlevel < 2:
                    continue
                else:
                    query = (current.db.question.question_level < current.session.auth.user.userlevel) & (current.db.question.status == 'In Progress')
            elif i == 2:
                query = (current.db.question.question_level > current.session.auth.user.userlevel) & (current.db.question.status == 'In Progress')
            elif i == 3:
                query = (current.db.question.status == 'In Progress')

            if questtype != 'all':
                query &= current.db.question.qtype == questtype
            qcont = query & (current.db.question.continent == current.session.auth.user.continent) & (
                current.db.question.activescope == '2 Continental')
            qglob = query & (current.db.question.activescope == '1 Global')

            if current.session.auth.user.country == 'Unspecified':
                qcount = query & (current.db.question.continent == current.session.auth.user.continent) & (
                    current.db.question.activescope == '3 National')
            else:
                qcount = query & (current.db.question.country == current.session.auth.user.country) & (current.db.question.activescope == '3 National')

            if current.session.auth.user.subdivision == 'Unspecified':
                qlocal = query & (current.db.question.country == current.session.auth.user.country) & (current.db.question.activescope == '4 Local')
            else:
                qlocal = query & (current.db.question.subdivision == current.session.auth.user.subdivision) & (
                    current.db.question.activescope == '4 Local')

            questglob = current.db(qglob).select(current.db.question.id, current.db.question.question_level, current.db.question.priority,
                                         current.db.question.category, current.db.question.answer_group)

            questcont = current.db(qcont).select(current.db.question.id, current.db.question.question_level, current.db.question.priority,
                                         current.db.question.category, current.db.question.answer_group)

            questcount = current.db(qcount).select(current.db.question.id, current.db.question.question_level, current.db.question.priority,
                                           current.db.question.category, current.db.question.answer_group)

            questlocal = current.db(qlocal).select(current.db.question.id, current.db.question.question_level, current.db.question.priority,
                                           current.db.question.category, current.db.question.answer_group)

            quests = (questglob | questcont | questcount | questlocal).sort(lambda r: r.priority, reverse=True)

            if current.session.answered:
                alreadyans = quests.exclude(lambda r: r.id in current.session.answered)
            if current.session.auth.user.exclude_categories:
                alreadyans = quests.exclude(lambda r: r.category in current.session.auth.user.exclude_categories)
            if current.session.exclude_groups:
                alreadyans = quests.exclude(lambda r: r.answer_group in current.session.exclude_groups)
            questrow = quests.first()

            if questrow is not None:
                break

    if questrow is None:
        nextquestion = 0
    else:
        nextquestion = questrow.id
        update_session(quests, questtype)
    #for i, row in enumerate(quests):
    #    if i > 0:
    #        if current.session[questtype]:
    #            current.session[questtype].append(row.id)
    #        else:
    #            current.session[questtype] = [row.id]

    return nextquestion
Beispiel #6
0
def questload():
    # latest thinking is thar request variables would apply if present but otherwise
    # may want to use session variables - but not on home page so maybe have some request args
    # as well - so lets try default to not apply session variables and then qtype for action/issue for now
    # possible session variables are:
    #   session.showcat
    #   session.showscope
    #   session.view_scope
    #   session.category
    #   session.vwcontinent
    #   session.vwcountry
    #   session.vwsubdivision
    #   session.answer_group
    #   session.sortorder
    #   session.evtid
    #   session.projid
    #   session.searchrange
    #   session.coord
    # if source is default we don't care about session variables it's a standard view with request vars applied
    # but if other source then we should setup session variables and then apply request vars
    #   session.eventid is not used unless called from eventaddquests and the source will then need to be sent as
    # 'event' to get the button to add and remove from event as appropriate

    session.forget(response) #no updates to sessions from this load file
    source = request.args(0, default='std')
    view = request.args(1, default='Action')

    # sort of got idea of v, q and s to consider for view, strquery and sort order

    scope = request.vars.scope or (source != 'default' and session.view_scope) or '1 Global'
    category = request.vars.category or (source != 'default' and session.category) or 'Unspecified'
    vwcontinent = request.vars.vwcontinent or (source != 'default' and session.vwcontinent) or 'Unspecified'
    vwcountry = request.vars.vwcountry or (source != 'default' and session.vwcountry) or 'Unspecified'
    vwsubdivision = request.vars.vwsubdivision or (source != 'default' and session.vwsubdivision) or 'Unspecified'
    sortorder = request.vars.sortorder or (source != 'default' and session.sortorder) or 'Unspecified'
    event = request.vars.event or (source != 'default' and session.evtid) or 0
    project = request.vars.project or (source != 'default' and session.projid) or 'Unspecified'

    answer_group = request.vars.answer_group or (source != 'default' and session.answer_group) or 'Unspecified'
    startdate = request.vars.startdate or (source != 'default' and session.startdate) or (
        request.utcnow - timedelta(days=1000))
    enddate = request.vars.enddate or (source != 'default' and session.enddate) or request.utcnow

    filters = (source != 'default' and session.filters) or []
    # this can be Scope, Category, AnswerGroup and probably Event in due course

    scope_filter = request.vars.scope_filter or 'Scope' in filters
    cat_filter = request.vars.cat_filter or 'Category' in filters
    group_filter = request.vars.group_filter or 'AnswerGroup' in filters
    date_filter = request.vars.datefilter or 'Date' in filters
    event_filter = request.vars.event_filter or 'Event' in filters  # so this will now need to be included in some calls
    project_filter = request.vars.project_filter or 'Project' in filters

    selection = (source not in ('default', 'event', 'evtunlink', 'projlink', 'projunlink') and session.selection) or ['Question', 'Resolved']

    # selection will currently be displayed separately
    # db.viewscope.selection.requires = IS_IN_SET(['Issue','Question','Action','Proposed','Resolved','Draft'
    # so possibly maybe IP, IR, IM, QP, QR, QM, AP, AR, AM - but this can maybe always be in the URL

    if request.vars.selection == 'QP':
        strquery = (db.question.qtype == 'quest') & (db.question.status == 'In Progress')
    elif request.vars.selection == 'QR':
        strquery = (db.question.qtype == 'quest') & (db.question.status == 'Resolved')
    elif request.vars.selection == 'QD' and auth.user:  # changed to all drafts with event filter
        strquery = (db.question.status == 'Draft') & (db.question.auth_userid == auth.user.id)
    elif request.vars.selection == 'IP':
        strquery = (db.question.qtype == 'issue') & (db.question.status == 'In Progress')
        response.view = 'default/issueload.load'
    elif request.vars.selection == 'IR':
        strquery = (db.question.qtype == 'issue') & (db.question.status == 'Agreed')
        response.view = 'default/issueload.load'
    elif request.vars.selection == 'IM':
        strquery = (db.question.qtype == 'issue') & (db.question.status == 'Draft') & (
                    db.question.auth_userid == auth.user_id)
        response.view = 'default/issueload.load'
    elif request.vars.selection == 'AP':
        strquery = (db.question.qtype == 'action') & (db.question.status == 'In Progress')
        response.view = 'default/actionload.load'
    elif request.vars.selection == 'AR':
        strquery = (db.question.qtype == 'action') & (db.question.status == 'Agreed')
        response.view = 'default/actionload.load'
        if source == 'default':
            strquery &= db.question.execstatus != 'Completed'
    elif request.vars.selection == 'PL':
        strquery = (db.question.qtype == 'action') & (db.question.status == 'Agreed') & (db.question.execstatus.belongs(session.execstatus))
        response.view = 'default/planload.load'
    elif request.vars.selection == 'AM':
        strquery = (db.question.qtype == 'action') & (db.question.status == 'Draft')\
                   & (db.question.auth_userid == auth.user_id)
        response.view = 'default/actionload.load'
    else:
        strquery = (db.question.qtype == 'quest') & (db.question.status == 'Resolved')

    if date_filter:
        strquery &= (db.question.createdate >= startdate) & (db.question.createdate <= enddate)

    if cat_filter and cat_filter != 'False':
        strquery &= (db.question.category == category)

    if source == 'eventadditems':
        unspeceventid = db(db.evt.evt_name == 'Unspecified').select(db.evt.id).first().id
        strquery &= db.question.eventid == unspeceventid
    elif source == 'projadditems': 
        unspecprojid = db(db.project.proj_name == 'Unspecified').select(db.project.id).first().id
        strquery &= db.question.projid == unspecprojid    
    elif event_filter and event != 0:
        strquery &= db.question.eventid == event
    elif project_filter and project != 'Unspecified':
        strquery &= db.question.projid == project

    if scope_filter is True:
        strquery &= db.question.activescope == scope
        if session.view_scope == '1 Global':
            strquery &= db.question.activescope == scope
        elif session.view_scope == '2 Continental':
            strquery = strquery & (db.question.activescope == session.view_scope) & (
                db.question.continent == vwcontinent)
        elif session.view_scope == '3 National':
            strquery = strquery & (db.question.activescope == session.view_scope) & (
                    db.question.country == vwcountry)
        elif session.view_scope == '4 Provincial':
            strquery = strquery & (db.question.activescope == session.view_scope) & (
                    db.question.subdivision == vwsubdivision)
        elif session.view_scope == '5 Local':
            minlat, minlong, maxlat, maxlong = getbbox(session.coord, session.searchrange)
            strquery = strquery & (db.question.activescope == session.view_scope) & (
                                  (current.db.question.question_lat > minlat) & 
                                  (current.db.question.question_lat < maxlat) &
                                  (current.db.question.question_long > minlong) &
                                  (current.db.question.question_long < maxlong))

    if group_filter and group_filter != 'False':
        strquery &= db.question.answer_group == answer_group

    if request.vars.sortby == 'ResDate':
        sortorder = '2 Resolved Date'
    elif request.vars.sortby == 'Priority':
        sortorder = '1 Priority'
    elif request.vars.sortby == 'CreateDate':
        sortorder = '3 Submit Date'

    if sortorder == '1 Priority':
        sortby = ~db.question.priority
    elif sortorder == '3 Submit Date':
        sortby = ~db.question.createdate
    else:
        sortby = ~db.question.resolvedate

    if request.vars.page:
        page = int(request.vars.page)
    else:
        page = 0

    if request.vars.items_per_page:
        items_per_page = int(request.vars.items_per_page)
    else:
        items_per_page = 50

    limitby = (page * items_per_page, (page + 1) * items_per_page + 1)
    q = request.vars.selection

    no_page = request.vars.no_page

    # removed caching for now as there are issues
    # quests = db(strquery).select(orderby=[sortby], limitby=limitby, cache=(cache.ram, 1200), cacheable=True)
    quests = db(strquery).select(orderby=[sortby], limitby=limitby)

    # remove excluded groups always
    if session.exclude_groups is None:

        session.exclude_groups = get_exclude_groups(auth.user_id)

    if quests:
        if session.exclude_groups is None:
            alreadyans = quests.exclude(lambda r: r.id > 0) # No questions if this is the case
        else:
            alreadyans = quests.exclude(lambda r: r.answer_group in session.exclude_groups)

    if request.vars.selection == 'PL' and quests:    
        projxml = get_gantt_data(quests)
    else:         
        projxml = "<project></project>"

    return dict(strquery=strquery, quests=quests, page=page, source=source, items_per_page=items_per_page, q=q,
                view=view, no_page=no_page, event=event, project=projxml)
Beispiel #7
0
def getquestsql(questtype='quest', userid=None, excluded_categories=None):

    current.session.exclude_groups = get_exclude_groups(userid)
    current.session.permitted_groups = get_groups(userid)
    questrow = 0
    debugsql = False
    debug = False

    if debug:
        print (current.session.exclude_groups)

    orderstr = ''

    for i in xrange(0, 3):
        if i == 0:
            query = (current.db.question.question_level == current.auth.user.userlevel) & (current.db.question.status == 'In Progress')
            orderstr = ~current.db.question.priority
        elif i == 1 and current.auth.user.userlevel >1:
            query = (current.db.question.question_level < current.auth.user.userlevel) & (current.db.question.status == 'In Progress')
            orderstr = ~current.db.question.question_level | ~current.db.question.priority
        elif i == 2:
            query = (current.db.question.question_level > current.auth.user.userlevel) & (current.db.question.status == 'In Progress')
            orderstr = current.db.question.question_level | ~current.db.question.priority
        elif i == 3:
            query = (current.db.question.status == 'In Progress')
            orderstr = ~current.db.question.priority

        query &= (current.db.userquestion.id == None)

        query &= (current.db.question.answer_group.belongs(current.session.permitted_groups))
        if excluded_categories:
            query &= ~(current.db.question.category.belongs(excluded_categories))

        if questtype != 'all':
            query &= (current.db.question.qtype == questtype)

        if current.auth.user.continent != 'Unspecified':  # some geographic restrictions
            # This is separate logic which applies when user has specified a continent - the general
            # thinking is that users cannot opt out of global questions but they may specify a continent
            # and optionally also a country and a subdivision in all cases we will be looking to
            # run 4 queries the global and continental queries will always be the same but
            # the country and subdvision queries are conditional as country and subdivision
            # may be left unspecified in which case users should get all national quests for
            # their continent or all local questions for their country - we will attempt to

            if current.auth.user.country == 'Unspecified':
                query &=((current.db.question.activescope == '1 Global') |
                        ((current.db.question.continent == current.auth.user.continent) &
                        ((current.db.question.activescope == '2 Continental') |
                         (current.db.question.activescope == '3 National'))))
            else:  # country specified
                if current.auth.user.subdivision == 'Unspecified':
                    query &=((current.db.question.activescope == '1 Global') |
                            ((current.db.question.continent == current.session.auth.user.continent) &
                            ((current.db.question.activescope == '2 Continental'))) |
                            ((current.db.question.country == current.session.auth.user.country) &
                             ((current.db.question.activescope == '4 Local') |
                             (current.db.question.activescope == '3 National'))))
                else:
                    query &=((current.db.question.activescope == '1 Global') |
                            ((current.db.question.continent == current.auth.user.continent) &
                            (current.db.question.activescope == '2 Continental')) |
                            ((current.db.question.country == current.auth.user.country) &
                             (current.db.question.activescope == '3 National')) |
                            ((current.db.question.subdivision == current.auth.user.subdivision) &
                             (current.db.question.activescope == '4 Local')))

        if debugsql:
            print(query)

        limitby = (0, 20)
        quests = current.db(query).select(current.db.question.id, current.db.userquestion.id, current.db.question.category,
                                      left=current.db.userquestion.on((current.db.question.id==current.db.userquestion.questionid) &
                                                              (current.db.userquestion.auth_userid==userid) &
                                                              (current.db.userquestion.status == 'In Progress')), orderby=orderstr,
                                                               limitby=limitby)
        if debugsql:
            print current.db._lastsql

        questrow = quests.first()
        if questrow is not None:
            break

    if questrow is None:
        nextquestion = 0
    else:
        nextquestion = questrow.question.id
        update_session(quests, questtype)
        #for i, row in enumerate(quests):
        #    if i > 0:
        #        if current.session[questtype]:
        #            current.session[questtype].append(row.question.id)
        #        else:
        #            current.session[questtype] = [row.question.id]
    if debug:
        print (current.session[questtype])
    return nextquestion
Beispiel #8
0
def getquesteventsql(eventid,
                     questtype='All',
                     userid=None,
                     excluded_categories=None):
    # so this will be sql based routine to navigate the event questions
    # result should be a list which will start at the top left based on the layout of the items
    # but it should then complete navigation of all links from that question and then restart
    # with next top left and repeat for the entire collection - the navigation needs to be
    # across the full event but previously answered questions are skipped
    # there is no caring about issues, actions or questions these all flow but excluded questions
    # will break links

    current.session.exclude_groups = get_exclude_groups(userid)
    current.session.permitted_groups = get_groups(userid)
    questrow = 0
    debugsql = True
    debug = True

    orderstr = ''

    if eventid:
        ansquests = current.db(
            (current.db.userquestion.auth_userid == current.session.auth.user)
            & (current.db.userquestion.status == 'In Progress')).select(
                current.db.userquestion.questionid)
        if not current.session.answered:
            current.session.answered = []
        for row in ansquests:
            current.session.answered.append(row.questionid)

        query = (current.db.question.eventid == eventid)
        orderstr = current.db.question.xpos

        query &= (current.db.question.answer_group.belongs(
            current.session.permitted_groups))

        if questtype != 'all':
            query &= (current.db.question.qtype == questtype)

        # Not sure whether sorting by x y is better or go the get event route
        quests, questlist = getevent(eventid, 'Open', 'Event')
        not_in_prog = [x.id for x in quests if x.status != 'In Progress']
        #print('nip', not_in_prog)

        if questlist:
            #intlinks = getlinks(questlist)
            intquery = (current.db.questlink.targetid.belongs(questlist)) & (
                current.db.questlink.status == 'Active') & (
                    current.db.questlink.sourceid.belongs(questlist))
            intlinks = current.db(intquery).select()

            links = [x.sourceid for x in intlinks]
            linklist = [(x.sourceid, x.targetid, {
                'weight': 30
            }) for x in intlinks]

            G = conv_for_iter(questlist, linklist)

            sequencelist = list(iter_dfs(G, 0))

            questorderlist = get_trav_list(questlist, sequencelist)

            allquestsordered = questorderlist[
                1:]  # remove event as first element which will be 0

            questwithanswered = [
                x for x in allquestsordered if x not in not_in_prog
            ]

            if current.session.answered is None:
                current.session.answered = []
                ansquests = current.db(
                    (current.db.userquestion.auth_userid ==
                     current.session.auth.user) &
                    (current.db.userquestion.status == 'In Progress')).select(
                        current.db.userquestion.questionid)
                for row in ansquests:
                    current.session.answered.append(row.questionid)

            questorderlist = [
                x for x in questwithanswered
                if x not in current.session.answered
            ]

            if not questorderlist:
                nextquestion = 0
            else:
                nextquestion = questorderlist[0]
                update_session(quests, questtype, 'Event')
            #for i, row in enumerate(questorderlist):
            #    if i > 0:
            #        current.session[questtype].append(row)
            #    else:
            #       current.session[questtype] = [row]
            if debug:
                print(current.session[questtype])
        else:
            nextquestion = 0
    else:
        nextquestion = 0
    return nextquestion
Beispiel #9
0
def getquestnonsql(questtype='quest', userid=None, excluded_categories=None):
    # This is called on non-sql datastores or if configured as non-sql -
    # it is left for reference but not being maintained at present

    if current.session.answered is None:
        current.session.answered = []
        ansquests = current.db(
            (current.db.userquestion.auth_userid == current.session.auth.user)
            & (current.db.userquestion.status == 'In Progress')).select(
                current.db.userquestion.questionid)
        for row in ansquests:
            current.session.answered.append(row.questionid)
    current.session.exclude_groups = get_exclude_groups(userid)
    questrow = 0

    if debug:
        print(current.session.exclude_groups)

    orderstr = ''
    if current.session.auth.user.continent == 'Unspecified':  # ie no geographic restriction
        for i in range(0, 3):
            if i == 0:
                query = (current.db.question.question_level
                         == current.session.auth.user.userlevel) & (
                             current.db.question.status == 'In Progress')
                orderstr = ~current.db.question.priority
            elif i == 1:
                if current.auth.user.userlevel > 1:
                    query = (current.db.question.question_level <
                             current.session.auth.user.userlevel) & (
                                 current.db.question.status == 'In Progress')
                    orderstr = ~current.db.question.question_level | ~current.db.question.priority
            elif i == 2:
                query = (current.db.question.question_level >
                         current.session.auth.user.userlevel) & (
                             current.db.question.status == 'In Progress')
                orderstr = current.db.question.question_level | ~current.db.question.priority
            elif i == 3:
                query = (current.db.question.status == 'In Progress')
                orderstr = ~current.db.question.priority

            if questtype != 'all':
                query &= current.db.question.qtype == questtype

            quests = current.db(query).select(orderby=orderstr)
            questrow = quests.first()

            # exclude previously answered - this approach specifically taken rather than
            # an outer join so it can work on google app engine
            # then filter for unanswered and categories users dont want questions on
            alreadyans = quests.exclude(
                lambda row: row.id in current.session.answered)
            alreadyans = quests.exclude(
                lambda row: row.category in excluded_categories)
            alreadyans = quests.exclude(
                lambda row: row.answer_group in current.session.exclude_groups)

            questrow = quests.first()
            if questrow is not None:
                break
    else:
        # This is separate logic which applies when user has specified a continent - the general
        # thinking is that users cannot opt out of global questions but they may specify a continent
        # and optionally also a country and a subdivision in all cases we will be looking to
        # run 4 queries the global and continental queries will always be the same but
        # the country and subdvision queries are conditional as country and subdivision
        # may be left unspecified in which case users should get all national quests for
        # their continent or all local questions for their country - we will attempt to
        # keep the same logic surrounding levels shorlty

        for i in range(0, 3):
            if i == 0:
                query = (current.db.question.question_level
                         == current.session.auth.user.userlevel) & (
                             current.db.question.status == 'In Progress')
            elif i == 1:
                if current.auth.user.userlevel < 2:
                    continue
                else:
                    query = (current.db.question.question_level <
                             current.session.auth.user.userlevel) & (
                                 current.db.question.status == 'In Progress')
            elif i == 2:
                query = (current.db.question.question_level >
                         current.session.auth.user.userlevel) & (
                             current.db.question.status == 'In Progress')
            elif i == 3:
                query = (current.db.question.status == 'In Progress')

            if questtype != 'all':
                query &= current.db.question.qtype == questtype
            qcont = query & (current.db.question.continent
                             == current.session.auth.user.continent) & (
                                 current.db.question.activescope
                                 == '2 Continental')
            qglob = query & (current.db.question.activescope == '1 Global')

            if current.session.auth.user.country == 'Unspecified':
                qcount = query & (current.db.question.continent
                                  == current.session.auth.user.continent) & (
                                      current.db.question.activescope
                                      == '3 National')
            else:
                qcount = query & (current.db.question.country
                                  == current.session.auth.user.country) & (
                                      current.db.question.activescope
                                      == '3 National')

            if current.session.auth.user.subdivision == 'Unspecified':
                qlocal = query & (current.db.question.country
                                  == current.session.auth.user.country) & (
                                      current.db.question.activescope
                                      == '4 Provincial')
            else:
                qlocal = query & (current.db.question.subdivision
                                  == current.session.auth.user.subdivision) & (
                                      current.db.question.activescope
                                      == '4 Provincial')

            questglob = current.db(qglob).select(
                current.db.question.id, current.db.question.question_level,
                current.db.question.priority, current.db.question.category,
                current.db.question.answer_group)

            questcont = current.db(qcont).select(
                current.db.question.id, current.db.question.question_level,
                current.db.question.priority, current.db.question.category,
                current.db.question.answer_group)

            questcount = current.db(qcount).select(
                current.db.question.id, current.db.question.question_level,
                current.db.question.priority, current.db.question.category,
                current.db.question.answer_group)

            questlocal = current.db(qlocal).select(
                current.db.question.id, current.db.question.question_level,
                current.db.question.priority, current.db.question.category,
                current.db.question.answer_group)

            quests = (questglob | questcont | questcount | questlocal).sort(
                lambda r: r.priority, reverse=True)

            if current.session.answered:
                alreadyans = quests.exclude(
                    lambda r: r.id in current.session.answered)
            if current.session.auth.user.exclude_categories:
                alreadyans = quests.exclude(
                    lambda r: r.category in current.session.auth.user.
                    exclude_categories)
            if current.session.exclude_groups:
                alreadyans = quests.exclude(
                    lambda r: r.answer_group in current.session.exclude_groups)
            questrow = quests.first()

            if questrow is not None:
                break

    if questrow is None:
        nextquestion = 0
    else:
        nextquestion = questrow.id
        update_session(quests, questtype)
    return nextquestion
Beispiel #10
0
def answer_question():
    """
    This allows the user to answer the question or pass and the result is 
    handled by the score question function.  This can really now be called
    from any event and it is an exposed url - so now need to check if not 
    resolved or already answered and if so we will not accept another answer
    """

    questid = request.args(0, cast=int, default=0)
    questtype = request.args(1, default='quest') # This will be All if on an event flow and this will flow to viewquest
    # This will display the question submitted to it by get_question

    form2 = SQLFORM(db.userquestion, showid=False, fields=['answer', 'reject', 'urgency', 'importance', 'answerreason',
                                                           'changecat', 'category', 'changescope',
                                                           'activescope', 'continent', 'country', 'subdivision'],
                    submit_button='Answer', col3={'answer': 'Enter 0 to Pass',
                                                  'reject': 'Select if invalid or off subject '},
                    hidden=dict(uq_level='level'), formstyle='table3cols')

    # bootstrap3_inline
    # quest = db(db.question.id == questid).select(cache=(cache.ram, 600), cacheable=True).first().as_dict()
    # this now caused userquestion to be set to wrong level so caching removed for now
    quest = db(db.question.id == questid).select().first().as_dict()

    if session.exclude_groups is None:
        session.exclude_groups = get_exclude_groups(auth.user_id)

    if quest['answer_group'] in session.exclude_groups:
        redirect(URL('viewquest', 'notshowing', args=[questid, questtype]))

    if quest['status'] != 'In Progress':
        redirect(URL('viewquest', 'index', args=[questid, questtype]))
    else:
        uq = db((db.userquestion.questionid == questid) &
                (db.userquestion.status == 'In Progress') &
                (db.userquestion.auth_userid == auth.user_id)).select(db.userquestion.id).first()
        if uq:  # User has already answered item so not allowed to answer again
            redirect(URL('viewquest', 'index', args=[questid, questtype]))

    form2.vars.activescope = quest['activescope']
    form2.vars.continent = quest['continent']
    form2.vars.country = quest['country']
    form2.vars.subdivision = quest['subdivision']
    form2.vars.category = quest['category']

    if form2.validate():
        form2.vars.auth_userid = auth.user.id
        form2.vars.questionid = questid
        form2.vars.uq_level = quest['question_level']
        form2.vars.status = 'In Progress'
        # default to urgency 10 for testing so questions that are answered continue to get answered
        if auth.user.first_name[:4] == 'Test':
            form2.vars.urgency = 10
            form2.vars.importance = 10

        form2.vars.id = db.userquestion.insert(**dict(form2.vars))
        response.flash = 'form accepted'
        # redirect(URL('update_question', args=form2.vars.id))
        status = score_question(questid, form2.vars.id)
        if status == 'Resolved':
            scheduler.queue_task('send_email_resolved', pvars=dict(questid=questid), period=600)
        redirect(URL('viewquest', 'index', args=[questid, questtype]))
    elif form2.errors:
        response.flash = 'form has errors'

    form2.vars.continet = quest['continent']
    form2.vars.country = quest['country']
    form2.vars.subdivision = quest['subdivision']
    form2.vars.category = quest['category']

    return dict(form2=form2, quest=quest)
Beispiel #11
0
def eventreviewload():
    # this started from questload - but will be changed for eventreview as more specified -
    # lets just go with request.vars.selection and not much else for now - but not sure if actually
    # want to do it this way as may be hard to do pdfs - SO THIS REMAINS UNFINISHED FOR NOW
    # selection will currently be displayed separately
    eventid = request.args(0)
    eventrow = db(db.evt.id == eventid).select(cache=(cache.ram, 1200), cacheable=True).first()

    if request.vars.selection == 'QP':
        strquery = (db.eventmap.qtype == 'quest') & (db.eventmap.queststatus == 'In Progress')
    elif request.vars.selection == 'QR':
        strquery = (db.eventmap.qtype == 'quest') & (db.eventmap.queststatus == 'Resolved')
    elif request.vars.selection == 'IP':
        strquery = (db.eventmap.qtype == 'issue') & (db.eventmap.queststatus == 'In Progress')
        response.view = 'event/eventissueload.load'
    elif request.vars.selection == 'IR':
        strquery = (db.eventmap.qtype == 'issue') & (db.eventmap.queststatus == 'In Progress')
        response.view = 'event/eventissueload.load'
    elif request.vars.selection == 'AP':
        strquery = (db.eventmap.qtype == 'action') & (db.eventmap.queststatus == 'In Progress')
        response.view = 'default/eventissueload.load'
    elif request.vars.selection == 'AR':
        strquery = (db.eventmap.qtype == 'action') & (db.eventmap.queststatus == 'Agreed')
        response.view = 'event/eventissueload.load'
    elif request.vars.selection == 'AD':
        strquery = (db.eventmap.qtype == 'action') & (db.eventmap.queststatus == 'Disagreed')
        response.view = 'event/eventissueload.load'
    else:
        strquery = (db.eventmap.qtype == 'quest') & (db.eventmap.queststatus == 'Resolved')

    strquery &= (db.eventmap.eventid == eventid)

    sortorder = '1 Priority'
    if request.vars.sortby == 'ResDate':
        sortorder = '2 Resolved Date'
    elif request.vars.sortby == 'Priority':
        sortorder = '1 Priority'
    elif request.vars.sortby == 'CreateDate':
        sortorder = '3 Submit Date'

    if sortorder == '1 Priority':
        sortby = ~db.question.priority
    elif sortorder == '3 Submit Date':
        sortby = ~db.question.createdate
    else:
        sortby = ~db.question.resolvedate

    if request.vars.page:
        page = int(request.vars.page)
    else:
        page = 0

    if request.vars.items_per_page:
        items_per_page = int(request.vars.items_per_page)
    else:
        items_per_page = 3

    limitby = (page * items_per_page, (page + 1) * items_per_page + 1)
    q = request.vars.selection

    no_page = request.vars.no_page

    quests = db(strquery).select(orderby=[sortby], limitby=limitby)

    # remove excluded groups always - this probably neees to stay which would mean questgroup
    # is required in the event archive (makes sense)
    if session.exclude_groups is None:
        session.exclude_groups = get_exclude_groups(auth.user_id)
    if quests and session.exclue_groups:
        alreadyans = quests.exclude(lambda r: r.answer_group in session.exclude_groups)

    source = 'Eventreview'
    view = 'std'
    return dict(eventrow=eventrow, quests=quests, page=page, source=source, items_per_page=items_per_page, q=q,
                view=view, no_page=no_page)
Beispiel #12
0
def eventreviewload():
    # this started from questload - but will be changed for eventreview as more specified -
    # lets just go with request.vars.selection and not much else for now - but not sure if actually
    # want to do it this way as may be hard to do pdfs - SO THIS REMAINS UNFINISHED FOR NOW
    # selection will currently be displayed separately
    eventid = request.args(0)
    eventrow = db(db.evt.id == eventid).select(cache=(cache.ram, 1200), cacheable=True).first()

    if request.vars.selection == 'QP':
        strquery = (db.eventmap.qtype == 'quest') & (db.eventmap.queststatus == 'In Progress')
    elif request.vars.selection == 'QR':
        strquery = (db.eventmap.qtype == 'quest') & (db.eventmap.queststatus == 'Resolved')
    elif request.vars.selection == 'IP':
        strquery = (db.eventmap.qtype == 'issue') & (db.eventmap.queststatus == 'In Progress')
        response.view = 'event/eventissueload.load'
    elif request.vars.selection == 'IR':
        strquery = (db.eventmap.qtype == 'issue') & (db.eventmap.queststatus == 'In Progress')
        response.view = 'event/eventissueload.load'
    elif request.vars.selection == 'AP':
        strquery = (db.eventmap.qtype == 'action') & (db.eventmap.queststatus == 'In Progress')
        response.view = 'default/eventissueload.load'
    elif request.vars.selection == 'AR':
        strquery = (db.eventmap.qtype == 'action') & (db.eventmap.queststatus == 'Agreed')
        response.view = 'event/eventissueload.load'
    elif request.vars.selection == 'AD':
        strquery = (db.eventmap.qtype == 'action') & (db.eventmap.queststatus == 'Disagreed')
        response.view = 'event/eventissueload.load'
    else:
        strquery = (db.eventmap.qtype == 'quest') & (db.eventmap.queststatus == 'Resolved')

    strquery &= (db.eventmap.eventid == eventid)

    sortorder = '1 Priority'
    if request.vars.sortby == 'ResDate':
        sortorder = '2 Resolved Date'
    elif request.vars.sortby == 'Priority':
        sortorder = '1 Priority'
    elif request.vars.sortby == 'CreateDate':
        sortorder = '3 Submit Date'

    if sortorder == '1 Priority':
        sortby = ~db.question.priority
    elif sortorder == '3 Submit Date':
        sortby = ~db.question.createdate
    else:
        sortby = ~db.question.resolvedate

    if request.vars.page:
        page = int(request.vars.page)
    else:
        page = 0

    if request.vars.items_per_page:
        items_per_page = int(request.vars.items_per_page)
    else:
        items_per_page = 3

    limitby = (page * items_per_page, (page + 1) * items_per_page + 1)
    q = request.vars.selection

    no_page = request.vars.no_page

    # removed caching for now as there are issues
    # quests = db(strquery).select(orderby=[sortby], limitby=limitby, cache=(cache.ram, 1200), cacheable=True)
    quests = db(strquery).select(orderby=[sortby], limitby=limitby)

    # remove excluded groups always - this probably neees to stay which would mean questgroup
    # is required in the event archive (makes sense)
    if session.exclude_groups is None:
        session.exclude_groups = get_exclude_groups(auth.user_id)
    if quests and session.exclue_groups:
        alreadyans = quests.exclude(lambda r: r.answer_group in session.exclude_groups)

    source = 'Eventreview'
    view = 'std'
    return dict(eventrow=eventrow, quests=quests, page=page, source=source, items_per_page=items_per_page, q=q,
                view=view, no_page=no_page)
Beispiel #13
0
def activity(id=0, resend=False, period='Week', format='html', source='default'):
    # This will be triggered from runactivity function below which figures out if 
    # this needs to be run and on success rolls the run date forward for the next
    # period this just formats the message and formats for sending via email

    db = current.db

    if id > 0:
        rows = db(db.email_runs.id == id).select()
        # if record status not equal to planned then log not sending to console and lets go with
        # only resending by id number
    else:
        rows = db((db.email_runs.runperiod == period) & (db.email_runs.status == 'Planned')).select()

    if rows is None:
        print 'No matching parameter record found'
        return 'No matching parameter record found'

    parameters = rows.first()
    params = current.db(current.db.website_parameters.id > 0).select().first()
    
    if params:
        stripheader = params.website_url[7:]
    else:
        stripheader = 'website_url_not_setup'

    startdate = parameters.datefrom
    enddate = parameters.dateto

    crtquery = (db.question.createdate >= startdate) & (db.question.createdate <= enddate)
    resquery = (db.question.resolvedate >= startdate) & (db.question.resolvedate <= enddate)
    challquery = (db.question.challengedate >= startdate) & (db.question.challengedate <= enddate)

    orderstr = db.question.createdate
    resolvestr = db.question.resolvedate
    challstr = db.question.challengedate

    allsubmitted = db(crtquery).select(orderby=orderstr)
    resolved = db(resquery).select(orderby=resolvestr)
    challenged = db(challquery).select(orderby=challstr)

    sender = mail.settings.sender
    subject = 'NDS Activity Report'
    
    # get users for type of run
    if parameters.runperiod == 'Day':
        userquery = (db.auth_user.emaildaily == True)
        periodtext = 'Daily'
    elif parameters.runperiod == 'Week':
        userquery = (db.auth_user.emailweekly == True)
        periodtext = 'Weekly'
    elif parameters.runperiod == 'Month':
        periodtext = 'Monthly'
        userquery = (db.auth_user.emailmonthly == True)
    else:
        return('Invalid run period parameter - must be Day, Week or Month')

    users = db(userquery).select()
    message = ''
    for user in users:
        # print user.email
        to = user.email
        # will change above to create allsubmitteds and then do a filter

        exclude_groups = get_exclude_groups(user.id)
        if exclude_groups:
            submitted = allsubmitted.exclude(lambda r: r.answer_group not in exclude_groups)
        else:
            submitted = allsubmitted
    
        message = '<html><body><h1> ' + periodtext + ' Activity Report</h1>'

        # should be able to make personal as well
        # can do the row exclusions later

        # section below is basically taken from activtiy.i file in the view

        message += "<h1>Items Resolved</h1>"
        if resolved:
            message += """<table><thead><tr>
                        <th width="5%">Type</th>
                        <th width="55%">Item Text</th>
                        <th width="15%">Answer</th>
                        <th width="8%"># Agree</th>
                        <th width="8%"># Disagree</th>
                        <th width="9%">Resolved</th>
                    </tr>
                </thead>
                    <tbody>"""
            for row in resolved:
                itemurl = URL('viewquest', 'index', args=[row.id], scheme='http', host=stripheader)
                itemtext = truncquest(row.questiontext)
                message += """<tr>
                <th><a href=%s>%s</a></th>
                <td>%s</td>
                <td>%s</td>
                <td>%s</td>
                <td>%s</td>
                <td>%s</td>

                </tr>""" % (itemurl, row.qtype, itemtext, row.correctanstext(), row.othercounts[3],
                            row.othercounts[3], row.resolvedate)
            message += " </tbody></table>"
        else:
            message += "<h3>No items resolved in the period.</h3>"

        message += "<h1>Items Submitted</h1>"
        if submitted:
            message += """<table><thead><tr>
                        <th width="5%">Type</th>
                        <th width="60%">Item Text</th>
                        <th width="13%">Scope</th>
                        <th width="12%">Category</th>
                        <th width="10%">Status</th>
                    </tr>
                </thead>
                    <tbody>"""
            for row in submitted:
                itemurl = URL('viewquest', 'index', args=[row.id], scheme='http', host=stripheader)
                itemtext = row.questiontext
                message += """<tr>
                <th><a href=%s>%s</a></th>
                <td>%s</td>
                <td>%s</td>
                <td>%s</td>
                <td>%s</td>
                </tr>""" % (itemurl, row.qtype, itemtext, row.scopetext, row.category, row.status)
            message += " </tbody></table>"
        else:
            message += "<h3>No items submitted in the period.</h3>"

        message += "<h1>Items Challenged</h1>"
        if challenged:
            message += """<table><thead><tr>
                        <th width="5%">Level</th>
                        <th width="55%">Question</th>
                        <th width="15%">Answer</th>
                        <th width="8%"># Agree</th>
                        <th width="8%"># Disagree</th>
                        <th width="9%">Challenged</th>
                    </tr>
                </thead>
                    <tbody>"""
            for row in challenged:
                itemurl = URL('viewquest', 'index', args=[row.id], scheme='http', host=stripheader)
                itemtext = row.questiontext
                message += """<tr>

                <th><a href=%s>%s</a></th>
                <td>%s</td>
                <td>%s</td>
                <td>%s</td>
                <td>%s</td>
                <td>%s</td>
                </tr>""" % (itemurl, row.qtype, itemtext, row.correctanstext(), row.othercounts[3],
                            row.othercounts[3], row.resolvedate)
            message += " </tbody></table>"
        else:
            message += "<h3>No items challenged in the period.</h3>"
            
        message += '<p>This report covers the period from %s to %s.</p>' % (str(startdate), str(enddate))
        message += '</body></html>'

        if resolved or challenged or submitted:
            send_email(to, mail.settings.sender, subject, message)
        else:
            if debug:
                print subject, message
                send_email(to, mail.settings.sender, subject, message)
    print message

    return 'run successful'
Beispiel #14
0
def activity():
    # This should support a report of activity in terms of both items submitted and actions resolved
    # thinking at present is not to use load and to not show too many details - perhaps
    # just the type and the question on submissions and the agreed answers and so on for quests
    # idea is that queries will be global and cacheable but will probably have to call a different
    # way eventually for email - it will also be callable via newindex and loaded in that case but will
    # NOT use session parameters instead these will be request vars to the extent supported

    period = request.args(0, default='weekly')
    format = request.args(1, default='html')
    source = request.args(2, default='default')
    view = request.args(3, default='All')  # will not use session variables as standard here so get everything#

    if view == 'resolved':
        response.view = 'review/resolved.load'
    elif view == 'submitted':
        response.view = 'review/submitted.load'
    # if run weekly or daily then lets run up to end of previous day - but final reports will
    # be dates

    if period == 'weekly':
        numdays = 7
    else:
        numdays = 1

    scope = request.vars.scope or (source != 'default' and session.scope) or '1 Global'
    category = request.vars.category or (source != 'default' and session.category) or 'Unspecified'
    vwcontinent = request.vars.vwcontinent or (source != 'default' and session.vwcontinent) or 'Unspecified'
    vwcountry = request.vars.vwcountry or (source != 'default' and session.vwcountry) or 'Unspecified'
    vwsubdivision = request.vars.vwsubdivision or (source != 'default' and session.vwsubdivision) or 'Unspecified'
    sortorder = request.vars.sortorder or (source != 'default' and session.sortorder) or 'Unspecified'
    event = request.vars.event or (source != 'default' and session.sortby) or 'Unspecified'
    answer_group = request.vars.answer_group or (source != 'default' and session.answer_group) or 'Unspecified'
    startdate = request.vars.startdate or (source != 'default' and session.startdate) or (request.utcnow - timedelta(days=numdays))
    enddate = request.vars.enddate or (source != 'default' and session.enddate) or request.utcnow.date()    
    context = request.vars.context or 'Unspecified'
    enddate += timedelta(days=1) #  because reporting on a datetime field from date and defaults to 00:00:00

    filters = (source != 'default' and session.filters) or []
    # this can be Scope, Category, AnswerGroup and probably Event in due course

    scope_filter = request.vars.scope_filter or 'Scope' in filters
    cat_filter = request.vars.cat_filter or 'Category' in filters
    group_filter = request.vars.group_filter or 'AnswerGroup' in filters

    crtquery = (db.question.createdate >= startdate) & (db.question.createdate <= enddate)
    resquery = (db.question.resolvedate >= startdate) & (db.question.resolvedate <= enddate)
    challquery = (db.question.challengedate >= startdate) & (db.question.challengedate <= enddate)

    if cat_filter and cat_filter != 'False':
        crtquery &= (db.question.category == category)

    if scope_filter is True:
        crtquery &= db.question.activescope == scope
        if session.scope == '1 Global':
            crtquery &= db.question.activescope == scope
        elif session.scope == '2 Continental':
            crtquery &= (db.question.activescope == session.scope) & (db.question.continent == vwcontinent)
        elif session.scope == '3 National':
            crtquery &= (db.question.activescope == session.scope) & (db.question.country == vwcountry)
        elif session.scope == '4 Local':
            crtquery &= (db.question.activescope == session.scope) & (db.question.subdivision == vwsubdivision)

    if group_filter and group_filter != 'False':
        crtquery &= db.question.answer_group == answer_group

    if event != 'Unspecified':
        crtquery &= db.question.eventid == event

    orderstr = db.question.createdate
    resolvestr = db.question.resolvedate
    challstr = db.question.challengedate
    if debug:
        print(crtquery)
        print(resquery)

    submitted = db(crtquery).select(orderby=orderstr)
    resolved = db(resquery).select(orderby=resolvestr)
    challenged = db(challquery).select(orderby=challstr)

    # remove excluded groups always
    if session.exclude_groups is None:
        session.exclude_groups = get_exclude_groups(auth.user_id)
    if debug:
        print(session.exclude_groups)
    if session.exclue_groups:
        alreadyans = resolved.exclude(lambda r: r.answer_group in session.exclude_groups)
        alreadyans = submitted.exclude(lambda r: r.answer_group in session.exclude_groups)
        alreadyans = challenged.exclude(lambda r: r.answer_group in session.exclude_groups)

    return dict(submitted=submitted, resolved=resolved, challenged=challenged)
Beispiel #15
0
def answer_question():
    """
    This allows the user to answer the question or pass and the result is 
    handled by the score question function.  This can really now be called
    from any event and it is an exposed url - so now need to check if not 
    resolved or already answered and if so we will not accept another answer
    """

    questid = request.args(0, cast=int, default=0)
    questtype = request.args(1, default='quest')  # This will be All if on an event flow and this will flow to viewquest
    # This will display the question submitted to it by get_question

    form2 = SQLFORM(db.userquestion, showid=False, fields=['answer', 'reject', 'urgency', 'importance', 'answerreason',
                                                           'changecat', 'category', 'changescope',
                                                           'activescope', 'continent', 'country', 'subdivision'],
                    submit_button='Answer', col3={'answer': 'Enter 0 to Pass',
                                                  'reject': 'Select if invalid or off subject '},
                    hidden=dict(uq_level='level'), formstyle='table3cols')

    #quest = db(db.question.id == questid).select().first().as_dict()

    form2.element(_type='submit')['_class'] = "btn btn-success"

    quest = db(db.question.id == questid).select().first()
    if session.exclude_groups is None:
        session.exclude_groups = get_exclude_groups(auth.user_id)

    if quest['answer_group'] in session.exclude_groups:
        redirect(URL('viewquest', 'notshowing', args=[questid, questtype]))

    if quest['status'] != 'In Progress':
        redirect(URL('viewquest', 'index', args=[questid, questtype]))
    else:
        uq = db((db.userquestion.questionid == questid) &
                (db.userquestion.status == 'In Progress') &
                (db.userquestion.auth_userid == auth.user_id)).select(db.userquestion.id).first()
        if uq:  # User has already answered item so not allowed to answer again
            redirect(URL('viewquest', 'index', args=[questid, questtype]))

    form2.vars.activescope = quest['activescope']
    form2.vars.continent = quest['continent']
    form2.vars.country = quest['country']
    form2.vars.subdivision = quest['subdivision']
    form2.vars.category = quest['category']

    if form2.validate():
        form2.vars.auth_userid = auth.user.id
        form2.vars.questionid = questid
        form2.vars.uq_level = quest['question_level']
        form2.vars.status = 'In Progress'
        # default to urgency 10 for testing so questions that are answered continue to get answered
        if auth.user.first_name[:4] == 'Test':
            form2.vars.urgency = 10
            form2.vars.importance = 10

        form2.vars.id = db.userquestion.insert(**dict(form2.vars))
        response.flash = 'form accepted'
        status = score_question(questid, form2.vars.id,False, anon_resolve=PARAMS.anon_resolve)
        if status == 'Resolved':
            scheduler.queue_task('send_email_resolved', pvars=dict(questid=questid), period=600)
        redirect(URL('viewquest', 'index', args=[questid, questtype]))
    elif form2.errors:
        response.flash = 'form has errors'

    form2.vars.continet = quest['continent']
    form2.vars.country = quest['country']
    form2.vars.subdivision = quest['subdivision']
    form2.vars.category = quest['category']

    return dict(form2=form2, quest=quest)
Beispiel #16
0
def getquestsql(questtype='quest',
                userid=None,
                excluded_categories=None,
                use_address=False):
    # This returns the next question for the user and builds a list of questions
    # to answer - extending support for local questions currently in progress and
    # thinking is it should work like this
    # There is no obligation on users to provide there location or specify location restrictions
    # and if they don't then the existing process worked.  If they do then we will prioritise
    # local questions based on their location

    current.session.exclude_groups = get_exclude_groups(userid)
    current.session.permitted_groups = get_groups(userid)
    questrow = 0
    debugsql = False
    debug = False

    if debug:
        print(current.session.exclude_groups)

    orderstr = ''

    if use_address and current.auth.user.continent != 'Unspecified':
        minlat, minlong, maxlat, maxlong = getbbox(
            current.auth.user.coord, current.auth.user.localrange)

        for i in range(0, 3):
            if i == 0:
                query = (current.db.question.question_level
                         == current.auth.user.userlevel) & (
                             current.db.question.status == 'In Progress')
                orderstr = ~current.db.question.priority
            elif i == 1 and current.auth.user.userlevel > 1:
                query = (current.db.question.question_level <
                         current.auth.user.userlevel) & (
                             current.db.question.status == 'In Progress')
                orderstr = ~current.db.question.question_level | ~current.db.question.priority
            elif i == 2:
                query = (current.db.question.question_level >
                         current.auth.user.userlevel) & (
                             current.db.question.status == 'In Progress')
                orderstr = current.db.question.question_level | ~current.db.question.priority
            elif i == 3:
                query = (current.db.question.status == 'In Progress')
                orderstr = ~current.db.question.priority

            query &= (current.db.userquestion.id == None)

            query &= (current.db.question.answer_group.belongs(
                current.session.permitted_groups))
            if excluded_categories:
                query &= ~(
                    current.db.question.category.belongs(excluded_categories))

            if questtype != 'all':
                query &= (current.db.question.qtype == questtype)

            query &= (current.db.question.activescope == '5 Local')

            query &= ((current.db.question.question_lat > minlat) &
                      (current.db.question.question_lat < maxlat) &
                      (current.db.question.question_long > minlong) &
                      (current.db.question.question_long < maxlong))

            # if debugsql:
            #    print(query)

            limitby = (0, 20)
            localquests = current.db(query).select(
                current.db.question.id,
                current.db.userquestion.id,
                current.db.question.category,
                current.db.question.answer_group,
                left=current.db.userquestion.on(
                    (current.db.question.id ==
                     current.db.userquestion.questionid)
                    & (current.db.userquestion.auth_userid == userid)
                    & (current.db.userquestion.status == 'In Progress')),
                orderby=orderstr,
                limitby=limitby)

            # TO DO might exclude  items based on radius here
            if localquests and current.session.exclude_groups:
                alreadyans = localquests.exclude(
                    lambda r: r.question.answer_group in current.session.
                    exclude_groups)

            questrow = localquests.first()
            if questrow is not None:
                break
            #else:
            #    print 'no quest', i
            #    if debugsql:
            #        print(query)

        if questrow is not None:
            nextquestion = questrow.question.id
            update_session(localquests, questtype)
            return nextquestion  # onlly local questions as these are being prioritised

    #This works for all questions with a scope that is not local or for users that don't have question set
    for i in range(0, 3):
        if i == 0:
            query = (current.db.question.question_level
                     == current.auth.user.userlevel) & (
                         current.db.question.status == 'In Progress')
            orderstr = ~current.db.question.priority
        elif i == 1 and current.auth.user.userlevel > 1:
            query = (current.db.question.question_level <
                     current.auth.user.userlevel) & (current.db.question.status
                                                     == 'In Progress')
            orderstr = ~current.db.question.question_level | ~current.db.question.priority
        elif i == 2:
            query = (current.db.question.question_level >
                     current.auth.user.userlevel) & (current.db.question.status
                                                     == 'In Progress')
            orderstr = current.db.question.question_level | ~current.db.question.priority
        elif i == 3:
            query = (current.db.question.status == 'In Progress')
            orderstr = ~current.db.question.priority

        query &= (current.db.userquestion.id == None)
        query &= (current.db.question.answer_group.belongs(
            current.session.permitted_groups))

        if excluded_categories:
            query &= ~(
                current.db.question.category.belongs(excluded_categories))

        if questtype != 'all':
            query &= (current.db.question.qtype == questtype)

        if current.auth.user.continent != 'Unspecified':  # some geographic restrictions
            # This is separate logic which applies when user has specified a continent - the general
            # thinking is that users cannot opt out of global questions but they may specify a continent
            # and optionally also a country and a subdivision in all cases we will be looking to
            # run 4 queries the global and continental queries will always be the same but
            # the country and subdvision queries are conditional as country and subdivision
            # may be left unspecified in which case users should get all national quests for
            # their continent or all local questions for their country - we will attempt to

            if current.auth.user.country == 'Unspecified':
                query &= ((current.db.question.activescope == '1 Global') | (
                    (current.db.question.continent
                     == current.auth.user.continent) &
                    ((current.db.question.activescope == '2 Continental') |
                     (current.db.question.activescope == '3 National') |
                     (current.db.question.activescope == '4 Provincial'))))
            else:  # country specified
                if current.auth.user.subdivision == 'Unspecified':
                    query &= (
                        (current.db.question.activescope == '1 Global') |
                        ((current.db.question.continent
                          == current.session.auth.user.continent) &
                         ((current.db.question.activescope
                           == '2 Continental'))) |
                        ((current.db.question.country
                          == current.session.auth.user.country) &
                         ((current.db.question.activescope == '4 Provincial') |
                          (current.db.question.activescope == '3 National'))))
                else:
                    query &= (
                        (current.db.question.activescope == '1 Global') |
                        ((current.db.question.continent
                          == current.auth.user.continent) &
                         (current.db.question.activescope == '2 Continental'))
                        | ((current.db.question.country
                            == current.auth.user.country) &
                           (current.db.question.activescope == '3 National')) |
                        ((current.db.question.subdivision
                          == current.auth.user.subdivision) &
                         (current.db.question.activescope == '4 Provincial')))

        if debugsql:
            print(query)

        limitby = (0, 20)
        quests = current.db(query).select(
            current.db.question.id,
            current.db.userquestion.id,
            current.db.question.category,
            current.db.question.answer_group,
            left=current.db.userquestion.on(
                (current.db.question.id == current.db.userquestion.questionid)
                & (current.db.userquestion.auth_userid == userid)
                & (current.db.userquestion.status == 'In Progress')),
            orderby=orderstr,
            limitby=limitby)

        if quests and current.session.exclude_groups:
            alreadyans = quests.exclude(lambda r: r.question.answer_group in
                                        current.session.exclude_groups)

        # Think we add local questions in here but maybe reasonable to allow prioritisation of local issues
        # and put at the top of the function with the global stuff being optional - no point getting if
        # too many local

        if debugsql:
            print(current.db._lastsql)

        questrow = quests.first()
        if questrow is not None:
            break

    # TO DO
    # could now merge quests and localquests but mandating local first for now if users specify location
    # so not doing this now

    if questrow is None:
        nextquestion = 0
    else:
        nextquestion = questrow.question.id
        update_session(quests, questtype)
    if debug:
        print(current.session[questtype])
    return nextquestion
Beispiel #17
0
def activity():
    # This should support a report of activity in terms of both items submitted and actions resolved
    # thinking at present is not to use load and to not show too many details - perhaps
    # just the type and the question on submissions and the agreed answers and so on for quests
    # idea is that queries will be global and cacheable but will probably have to call a different
    # way eventually for email - it will also be callable via newindex and loaded in that case but will
    # NOT use session parameters instead these will be request vars to the extent supported

    period = request.args(0, default='weekly')
    format = request.args(1, default='html')
    source = request.args(2, default='default')
    view = request.args(
        3, default='All'
    )  # will not use session variables as standard here so get everything#

    if view == 'resolved':
        response.view = 'review/resolved.load'
    elif view == 'submitted':
        response.view = 'review/submitted.load'
    # if run weekly or daily then lets run up to end of previous day - but final reports will
    # be dates

    if period == 'weekly':
        numdays = 7
    else:
        numdays = 1

    scope = request.vars.scope or (source != 'default'
                                   and session.view_scope) or '1 Global'
    category = request.vars.category or (source != 'default'
                                         and session.category) or 'Unspecified'
    vwcontinent = request.vars.vwcontinent or (
        source != 'default' and session.vwcontinent) or 'Unspecified'
    vwcountry = request.vars.vwcountry or (source != 'default' and
                                           session.vwcountry) or 'Unspecified'
    vwsubdivision = request.vars.vwsubdivision or (
        source != 'default' and session.vwsubdivision) or 'Unspecified'
    sortorder = request.vars.sortorder or (source != 'default' and
                                           session.sortorder) or 'Unspecified'
    event = request.vars.event or (source != 'default'
                                   and session.evtid) or 'Unspecified'
    project = request.vars.project or 'Unspecified'
    answer_group = request.vars.answer_group or (
        source != 'default' and session.answer_group) or 'Unspecified'
    startdate = request.vars.startdate or (
        source != 'default'
        and session.startdate) or (request.utcnow - timedelta(days=numdays))
    enddate = request.vars.enddate or (
        source != 'default' and session.enddate) or request.utcnow.date()
    context = request.vars.context or 'Unspecified'
    enddate += timedelta(
        days=1
    )  # because reporting on a datetime field from date and defaults to 00:00:00

    filters = (source != 'default' and session.filters) or []
    # this can be Scope, Category, AnswerGroup and probably Event in due course

    scope_filter = request.vars.scope_filter or 'Scope' in filters
    cat_filter = request.vars.cat_filter or 'Category' in filters
    group_filter = request.vars.group_filter or 'AnswerGroup' in filters
    date_filter = request.vars.datefilter or 'Date' in filters
    event_filter = request.vars.event_filter or 'Event' in filters  # so this will now need to be included in some calls
    project_filter = request.vars.project_filter or 'Project' in filters

    if date_filter:
        crtquery = (db.question.createdate >=
                    startdate) & (db.question.createdate <= enddate)
        resquery = (db.question.resolvedate >=
                    startdate) & (db.question.resolvedate <= enddate)
        challquery = (db.question.challengedate >=
                      startdate) & (db.question.challengedate <= enddate)
    else:
        crtquery = (db.question.id > 0)
        resquery = (db.question.id > 0)
        challquery = (db.question.id > 0)

    if cat_filter and cat_filter != 'False':
        crtquery &= (db.question.category == category)

    if scope_filter is True:
        crtquery &= db.question.activescope == scope
        if session.view_scope == '1 Global':
            crtquery &= db.question.activescope == scope
        elif session.view_scope == '2 Continental':
            crtquery &= (db.question.activescope == session.view_scope) & (
                db.question.continent == vwcontinent)
        elif session.view_scope == '3 National':
            crtquery &= (db.question.activescope == session.view_scope) & (
                db.question.country == vwcountry)
        elif session.view_scope == '4 Local':
            crtquery &= (db.question.activescope == session.view_scope) & (
                db.question.subdivision == vwsubdivision)

    if group_filter and group_filter != 'False':
        crtquery &= db.question.answer_group == answer_group

    if event_filter and event != 'Unspecified':
        crtquery &= db.question.eventid == event
        resquery &= db.question.eventid == event

    if project_filter and project != 'Unspecified':
        crtquery &= db.question.projid == project
        resquery &= db.question.projid == project

    orderstr = db.question.createdate
    resolvestr = db.question.resolvedate
    challstr = db.question.challengedate

    submitted = db(crtquery).select(orderby=orderstr)
    resolved = db(resquery).select(orderby=resolvestr)
    challenged = db(challquery).select(orderby=challstr)

    # remove excluded groups always
    if session.exclude_groups is None:
        session.exclude_groups = get_exclude_groups(auth.user_id)

    if session.exclue_groups:
        alreadyans = resolved.exclude(
            lambda r: r.answer_group in session.exclude_groups)
        alreadyans = submitted.exclude(
            lambda r: r.answer_group in session.exclude_groups)
        alreadyans = challenged.exclude(
            lambda r: r.answer_group in session.exclude_groups)

    return dict(submitted=submitted, resolved=resolved, challenged=challenged)
Beispiel #18
0
def questarch():

    # this came from questload and it may make sense to combine - however fields
    # and strquery would be different lets confirm works this way and then think about it
    # but no point to fields on select for GAE
    # latest thinking is thar request variables would apply if present but otherwise
    # may want to use session variables - but not on home page so maybe have some request args
    # as well - so lets try default to not apply session variables and then qtype for action/issue for now
    # possible session variables are:
    #   session.showcat
    #   session.showscope
    #   session.view_scope
    #   session.category
    #   session.vwcontinent
    #   session.vwcountry
    #   session.vwsubdivision
    #   session.answer_group
    #   session.sortorder
    # if source is default we don't care about session variables it's a standard view with request vars applied
    # but if other source then we should setup session variables and then apply request vars

    source = request.args(0, default='std')
    view = request.args(1, default='Action')

    # sort of got idea of v, q and s to consider for view, strquery and sort order
    # source currently always default for this but will leave as is for now
    scope = request.vars.scope or (source != 'default' and session.view_scope) or '1 Global'
    category = request.vars.category or (source != 'default' and session.category) or 'Unspecified'
    vwcontinent = request.vars.vwcontinent or (source != 'default' and session.vwcontinent) or 'Unspecified'
    vwcountry = request.vars.vwcountry or (source != 'default' and session.vwcountry) or 'Unspecified'
    vwsubdivision = request.vars.vwsubdivision or (source != 'default' and session.vwsubdivision) or 'Unspecified'
    sortorder = request.vars.sortorder or (source != 'default' and session.sortorder) or 'Unspecified'
    event = request.vars.event or (source != 'default' and session.sortby) or 'Unspecified'
    project = request.vars.project or (
              source != 'default' and session.projid) or 'Unspecified'
    answer_group = request.vars.answer_group or (source != 'default' and session.answer_group) or 'Unspecified'
    startdate = request.vars.startdate or (source != 'default' and session.startdate) or (
        request.utcnow - timedelta(days=1000))
    enddate = request.vars.enddate or (source != 'default' and session.enddate) or request.utcnow
    context = request.vars.context or 'Unspecified'

    filters = (source != 'default' and session.filters) or []
    # this can be Scope, Category, AnswerGroup and probably Event in due course

    scope_filter = request.vars.scope_filter or 'Scope' in filters
    cat_filter = request.vars.cat_filter or 'Category' in filters
    group_filter = request.vars.group_filter or 'AnswerGroup' in filters
    date_filter = request.vars.datefilter or 'Date' in filters
    project_filter = request.vars.project_filter or 'Project' in filters
    event_filter = request.vars.event_filter or 'Event' in filters

    selection = (source not in ('default', 'event', 'evtunlink') and session.selection) or ['Question', 'Resolved']

    # selection will currently be displayed separately
    # db.viewscope.selection.requires = IS_IN_SET(['Issue','Question','Action','Proposed','Resolved','Draft'
    # so possibly maybe IP, IR, IM, QP, QR, QM, AP, AR, AM - but this can maybe always be in the URL

    if request.vars.selection == 'QP':
        strquery = (db.eventmap.qtype == 'quest') & (db.eventmap.queststatus == 'In Progress')
    elif request.vars.selection == 'QR':
        strquery = (db.eventmap.qtype == 'quest') & (db.eventmap.queststatus == 'Resolved')
    elif request.vars.selection == 'QD' and auth.user:
        strquery = (db.eventmap.qtype == 'quest') & (db.eventmap.queststatus == 'Draft')\
                   & (db.eventmap.auth_userid == auth.user.id)
    elif request.vars.selection == 'IP':
        strquery = (db.eventmap.qtype == 'issue') & (db.eventmap.queststatus == 'In Progress')
        response.view = 'default/issuearch.load'
    elif request.vars.selection == 'IR':
        strquery = (db.eventmap.qtype == 'issue') & (db.eventmap.queststatus == 'Agreed')
        response.view = 'default/issuearch.load'
    elif request.vars.selection == 'IM':
        strquery = (db.eventmap.qtype == 'issue') & (db.eventmap.queststatus == 'Draft') & (
                    db.eventmap.auth_userid == auth.user_id)
        response.view = 'default/issuearch.load'
    elif request.vars.selection == 'AP':
        strquery = (db.eventmap.qtype == 'action') & (db.eventmap.queststatus == 'In Progress')
        response.view = 'default/actionarch.load'
    elif request.vars.selection == 'AR':
        strquery = (db.eventmap.qtype == 'action') & (db.eventmap.queststatus == 'Agreed')
        response.view = 'default/actionarch.load'
    elif request.vars.selection == 'AM':
        strquery = (db.eventmap.qtype == 'action') & (db.eventmap.queststatus == 'Draft')\
                   & (db.eventmap.auth_userid == auth.user_id)
        response.view = 'default/actionarch.load'
    else:
        strquery = (db.eventmap.qtype == 'quest') & (db.eventmap.queststatus == 'Resolved')

    if date_filter:
        strquery &= (db.eventmap.createdate >= startdate) & (db.eventmap.createdate <= enddate)

    if cat_filter and cat_filter != 'False':
        strquery &= (db.eventmap.category == category)

    if scope_filter is True:
        strquery &= db.eventmap.activescope == scope
        if session.view_scope == '1 Global':
            strquery &= db.eventmap.activescope == scope
        elif session.view_scope == '2 Continental':
            strquery = strquery & (db.eventmap.activescope == session.view_scope) & (
                db.eventmap.continent == vwcontinent)
        elif session.view_scope == '3 National':
            strquery = strquery & (db.eventmap.activescope == session.view_scope) & (
                    db.eventmap.country == vwcountry)
        elif session.view_scope == '4 Provincial':
            strquery = strquery & (db.eventmap.activescope == session.view_scope) & (
                    db.eventmap.subdivision == vwsubdivision)

    if group_filter and group_filter != 'False':
        strquery &= db.eventmap.answer_group == answer_group

    strquery &= db.eventmap.eventid == event

    sortby = ~db.eventmap.priority

    if request.vars.page:
        page = int(request.vars.page)
    else:
        page = 0

    if request.vars.items_per_page:
        items_per_page = int(request.vars.items_per_page)
    else:
        items_per_page = 50

    limitby = (page * items_per_page, (page + 1) * items_per_page + 1)
    q = request.vars.selection

    no_page = request.vars.no_page

    # removed caching for now as there are issues
    # quests = db(strquery).select(orderby=[sortby], limitby=limitby, cache=(cache.ram, 1200), cacheable=True)
    quests = db(strquery).select(orderby=[sortby], limitby=limitby)

    # remove excluded groups always
    if session.exclude_groups is None:
        session.exclude_groups = get_exclude_groups(auth.user_id)
    if quests and session.exclue_groups:
        alreadyans = quests.exclude(lambda r: r.answer_group in session.exclude_groups)
    #for row in quests:
    #    print 'row', row
    return dict(strquery=strquery, quests=quests, page=page, source=source, items_per_page=items_per_page, q=q,
                view=view, no_page=no_page, event=event)