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'
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)
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)
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
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
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)
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
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
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
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)
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)
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)
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'
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)
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)
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
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)
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)