def index(): req = request.vars # /admin/function?tag=value # view_type possible values = (nothing) --> default to "unread" # "read" and "all" # read_modifier is a variable that controls the "read" or "unread" state # of the data to be pulled from the "admin_messages" table read_modifier = None view_type = req.get('view_type', 'unread') if view_type == 'unread': read_modifier = False elif view_type == 'read': read_modifier = True # Nasty-truncate for preview purposes msgs = db.admin_messages.message[:40] # Here, if deletion of messages was requested, carry out the request... form_submitted = req.form_submitted msg_ids = req.msg_ids if msg_ids is not None: if not type(msg_ids) is list: msg_ids = [msg_ids] db(db.admin_messages.id.belongs(msg_ids)).delete() # First condition triggers if the admin user does pick a "modifier" # meaning that he elected, "show me the read" or "show me the unread" msgs if read_modifier is not None: # I will need an inner join on a left join, please read # http://groups.google.com/group/web2py/browse_thread/thread/ # d7f5e5820176813/d418ba81180fe40a?lnk=gst&q=multiple+left+ # joins#d418ba81180fe40a # For more info on why I wil need to make a second pass on the # generated resultset, not a biggie, a bit annoying though. messages = db(db.admin_messages.read_flag==read_modifier).select( db.admin_messages.id, db.admin_messages.auth_user_id, db.admin_messages.subject, msgs, db.admin_messages.creation_date, db.admin_messages.read_flag, orderby=~db.admin_messages.creation_date ) else: # Second condition is if the admin user wants to see both read and # unread admin messages... messages = db().select( db.admin_messages.id, db.admin_messages.auth_user_id, db.admin_messages.subject, msgs, db.admin_messages.creation_date, db.admin_messages.read_flag, orderby=~db.admin_messages.creation_date ) return dict(messages=messages)
def qa_mgmt(): """ Main page to control question/answer/comment management, usually to manage any of those that have been flagged for deletion. """ q_cnt = db(db.questions.is_visible==False).count() qc_cnt = db((db.comments.c_type=='Q') & ( db.comments.is_visible==False)).count() a_cnt = db(db.answers.is_visible==False).count() ac_cnt = db((db.comments.c_type=='A') & ( db.comments.is_visible==False)).count() return dict(q_cnt=q_cnt, qc_cnt=qc_cnt, a_cnt=a_cnt, ac_cnt=ac_cnt)
def system(): req = request.vars if req.form_submitted: #raise ValueError(req.property_names) # Save Changes Requested for p_name in req.property_names: db(db.system_properties.property_name==p_name).update( property_value=req.get(p_name, '')) redirect(URL(r=request, c='admin', f='system', vars=dict(saved=1))) else: sys_properties = db().select(db.system_properties.ALL) return dict(sys_properties=sys_properties)
def qa_mgmt(): """ Main page to control question/answer/comment management, usually to manage any of those that have been flagged for deletion. """ q_cnt = db(db.questions.is_visible == False).count() qc_cnt = db((db.comments.c_type == 'Q') & (db.comments.is_visible == False)).count() a_cnt = db(db.answers.is_visible == False).count() ac_cnt = db((db.comments.c_type == 'A') & (db.comments.is_visible == False)).count() return dict(q_cnt=q_cnt, qc_cnt=qc_cnt, a_cnt=a_cnt, ac_cnt=ac_cnt)
def system(): req = request.vars if req.form_submitted: #raise ValueError(req.property_names) # Save Changes Requested for p_name in req.property_names: db(db.system_properties.property_name == p_name).update( property_value=req.get(p_name, '')) redirect(URL(r=request, c='admin', f='system', vars=dict(saved=1))) else: sys_properties = db().select(db.system_properties.ALL) return dict(sys_properties=sys_properties)
def qa_mgmt_hq(): """ Management of questions that have been marked for possible deletion by a sysadmin. """ questions = db(db.questions.is_visible == False).select( db.questions.ALL, orderby=~db.questions.modified_on) return dict(questions=questions)
def qa_mgmt_hq(): """ Management of questions that have been marked for possible deletion by a sysadmin. """ questions = db(db.questions.is_visible==False).select( db.questions.ALL, orderby=~db.questions.modified_on) return dict(questions=questions)
def qa_mgmt_ha(): """ Management of answers that have been marked for possible deletion by a sysadmin. """ answers = db((db.questions.id==db.answers.question_id) & ( db.answers.is_visible==False)).select( db.questions.id, db.questions.title, db.answers.description, db.answers.id, db.answers.modified_on) return dict(answers=answers)
def tags(): """ Returns a simple list of all the most popular tags """ view_info = {} view_info.update(dict(errors=[])) tag_cnt = db.question_tags.id.count() tags = db(db.tags.id == db.question_tags.tag_id).select(db.tags.tagname, tag_cnt, groupby=db.tags.id, orderby=~tag_cnt, limitby=(0, 30)) return dict(tags=tags, view_info=view_info)
def qa_mgmt_hqc(): """ Management of commments for a question that have been marked for possible deletion by a sysadmin. """ questions = db( (db.questions.id==db.comments.qa_id) & (db.comments.c_type=='Q') & ( db.comments.is_visible==False)).select( db.comments.qa_id, db.comments.description, db.comments.id, db.questions.id, db.questions.title, db.comments.modified_on, orderby=~db.comments.modified_on) return dict(questions=questions)
def tags(): """ Returns a simple list of all the most popular tags """ view_info = {} view_info.update(dict(errors=[])) tag_cnt = db.question_tags.id.count() tags = db(db.tags.id==db.question_tags.tag_id).select( db.tags.tagname, tag_cnt, groupby=db.tags.id, orderby=~tag_cnt, limitby=(0, 30)) return dict(tags=tags, view_info=view_info)
def users(): view_options = None users = db(db.auth_users.auth_role_id == db.auth_roles.id).select( db.auth_users.ALL, db.auth_roles.role_name, orderby=~db.auth_roles.role_min_score) user_dict = {} for user in users: user_dict.update({ user.auth_users.id: { 'user_real_name': stackhelper.get_member_property('m_display_name', user.auth_users.id, '') } }) return dict(view_options=view_options, users=users, user_dict=user_dict)
def users(): view_options = None users = db(db.auth_users.auth_role_id==db.auth_roles.id).select( db.auth_users.ALL, db.auth_roles.role_name, orderby=~db.auth_roles.role_min_score) user_dict = {} for user in users: user_dict.update({user.auth_users.id: {'user_real_name': stackhelper.get_member_property( 'm_display_name', user.auth_users.id, '')}}) return dict(view_options=view_options, users=users, user_dict=user_dict)
def view(): """ The default page when viewing a question """ # We need to pull here several important things: Questions, comments for # questions, answers, comments for answers.. view_info = {'errors': []} req = request.vars qid = req.qid if req.qid is not None else request.args[0] # Question ID # Read the question here to see if the user is allowed to access it question = db(db.questions.id==qid).select(db.questions.ALL) user_id = auth_user.get_user_id() if not question or ( not question[0].is_visible and not auth_user.is_admin()): # Only admins may see hidden questions.. redirect(URL(r=request, c='default', f='unauthorized')) featured_votes = db( (db.score_log.l_type=='Q') & (db.score_log.subtype=='featuredrequest') & (db.score_log.qac_id==qid)).count() view_info.update(dict(featured_votes=featured_votes)) offensive_votes = db( (db.score_log.l_type=='Q') & (db.score_log.subtype=='offensiverequest') & (db.score_log.qac_id==qid)).count() view_info.update(dict(offensive_votes=offensive_votes)) # This controls if the user is subscribed or not to this question view_info['is_subscribed'] = False if auth_user.is_auth(): if stackhelper.user_is_subscribed(qid, user_id): view_info['is_subscribed'] = True # Only the following roles can add comments can_comment = auth_user.has_role('Reviewer,TeamLead,Manager,SysAdmin') view_info['can_comment'] = can_comment if req.form_submitted: view_info['form_submitted'] = True preview_answer = req.preview_answer post_answer = req.post_answer answer = req.get('answer', '').strip() view_info['answer'] = answer if preview_answer is not None: view_info['preview_answer'] = preview_answer else: # Posting an answer to this question here if answer: modified_by = user_id db.answers.insert(question_id=qid, description=answer, created_by=modified_by, created_on=request.now, modified_by=modified_by, is_outstanding=False, votes_up=0, votes_dn=0, is_visible=True, is_answer=False, modified_on=request.now) # Update the original question's last update date/user db(db.questions.id==qid).update(modified_by=modified_by, modified_on=request.now) # Also, increment the number of answers this user has posted stackhelper.increment_member_property('m_answers', modified_by, 1) else: view_info['errors'].append( 'Please add a valid answer to continue') else: # Update the page views for this question, only # if the page is viewed via GET view_rec = db(db.questions.id==qid).select(db.questions.views)[0] db(db.questions.id==qid).update(views=view_rec.views+1) question = db( (db.questions.id==qid) & (db.questions.created_by==db.member_properties.auth_user) & (db.member_properties.property_id==db.member_properties_skel.id) & (db.member_properties_skel.property_name=='m_display_name')).select( db.questions.ALL, db.member_properties.property_value)[0] tags = db( (db.questions.id==db.question_tags.question_id) &\ (db.question_tags.tag_id==db.tags.id) &\ (db.questions.id==question.questions.id)).select( db.tags.tagname) q_comments = db( (db.comments.c_type=='Q') & (db.comments.qa_id==qid) & (db.comments.is_visible==True) & (db.comments.created_by==db.member_properties.auth_user) & (db.member_properties.property_id==db.member_properties_skel.id) & (db.member_properties_skel.property_name==\ 'm_display_name')).select(db.comments.ALL, db.member_properties.property_value, orderby=db.comments.modified_on) answers = db( (db.answers.question_id==qid) & (db.answers.is_visible==True) & (db.answers.created_by==db.member_properties.auth_user) & (db.member_properties.property_id==db.member_properties_skel.id) & (db.member_properties_skel.property_name=='m_display_name')).select( db.answers.ALL, db.member_properties.property_value, orderby=~db.answers.is_answer|~db.answers.modified_on) # Now every different proposed answer can have comments, # so I need the comments for each answer if applicable) comments_a = {} for answer in answers: comments = db( (db.comments.c_type=='A') & (db.comments.qa_id==answer.answers.id) & (db.comments.is_visible==True) & (db.comments.created_by==db.member_properties.auth_user) & (db.member_properties.property_id==db.member_properties_skel.id) & (db.member_properties_skel.property_name==\ 'm_display_name')).select( db.comments.ALL, db.member_properties.property_value, orderby=db.comments.modified_on) if comments: comments_a.update({answer.answers.id: comments}) return dict( question=question, tags=tags, q_comments=q_comments, answers=answers, comments_a=comments_a, can_comment=can_comment, view_info=view_info)
def index(): """ Main application index (entry point) page """ if session.RUN_ONCE is None: view_info = {} view_info.update({'errors': []}) req = request.vars args = request.args nav_css = 'aquestions' # Some needed system information (think about caching this and # update every 4 hours or so..) num_recs = int( stackhelper.get_system_property('s_questions_per_page', 30)) mode = '' try: offset = int(req.start) except: offset = 0 try: mode = args[0] nav_css = 'a%s' % (mode) except: pass sort_css = 's_dates' if req.sort is None else req.sort # Constraints: # Sort (qsort): # Latest == order by questions.modified_on DESC # Most Voted = order by questions.votes_up DESC # Featured = where questions.is_featured == 'T' # # Type (qtype) # Questions = (no constraints) # Unanswered = where questions.is_answered == 'F' qsort = req.sort # Latest, Most Voted (Sub Tabs) # qtype = req.qtype - Questions, Unanswered (Main Tabs) sql_order = 'questions.modified_on DESC' if qsort == 's_votes': # "most voted" sql_order = 'questions.votes_up DESC' qtype = '' if len(args) > 0: qtype_arg = args[0] if qtype_arg == 'unanswered': qtype = 'u' elif qtype_arg == 'featured': qtype = 'f' elif qtype_arg == 'subscribed': qtype = 's' sql_where = [] extra_tables = [''] # <-- Important if qtype == 'u': # Unanswered sql_where.append("questions.is_answered = 'F'") elif qtype == 'f': # Featured sql_where.append("questions.is_featured = 'T'") elif qtype == 's': # Subscribed sql_where.append("questions.id = " "question_subscriptions.question_id") sql_where.append("question_subscriptions.is_active = 'T'") sql_where.append("question_subscriptions.auth_user_id = " "%s" % (auth_user.get_user_id() or 0)) extra_tables.append('question_subscriptions') # Tag Handling srch_tag = '' tag_table = '' if mode == 'tags': srch_tag = req.get('tag', 'qa-stack') # /default/index/tags?tag=meh # get the "id" of this tag.. sql_tags = db( db.tags.tagname.like('%s%%' % (srch_tag))).select(db.tags.id) tags = ','.join([str(tag.id) for tag in sql_tags]) # '1,5,7,9,etc' sql_where.append('question_tags.question_id = questions.id') sql_where.append('question_tags.tag_id in (%s)' % (tags if tags else 0)) extra_tables.append('question_tags') sql_where_str = '' if sql_where: sql_where_str = "\nand %s" % (' and '.join(sql_where)) # Grab questions sql_cnt = """ select count(questions.id) from questions %s where questions.is_visible='T' %s """ % (','.join(extra_tables), sql_where_str) question_cnt = db.executesql(sql_cnt)[0][0] view_info['question_cnt'] = question_cnt sql = """ select questions.title, questions.created_on, questions.modified_on, questions.views, questions.votes_up, questions.votes_dn, questions.is_answered, questions.is_featured, member_properties.property_value, COUNT(answers.id), auth_roles.role_name, questions.is_closed, questions.id, auth_users.auth_alias, auth_users.id from questions LEFT JOIN answers ON answers.question_id=questions.id, auth_users, member_properties, member_properties_skel, auth_roles %s where questions.is_visible='T' AND member_properties.auth_user=questions.created_by AND member_properties.property_id=member_properties_skel.id AND member_properties_skel.property_name='m_display_name' AND auth_roles.id=auth_users.auth_role_id AND auth_users.id=questions.created_by %s group by questions.id order by %s limit %s offset %s """ % (','.join(extra_tables), sql_where_str, sql_order, num_recs, offset) questions = [] all_questions = db.executesql(sql) if all_questions: for q in all_questions: questions.append({ 'questions.title': q[0], 'questions.created_on': q[1], 'questions.modified_on': q[2], 'questions.views': q[3], 'questions.votes_up': q[4], 'questions.votes_dn': q[5], 'questions.is_answered': (True if q[6] == 'T' else False), 'questions.is_featured': (True if q[7] == 'T' else False), 'member_properties.property_value': q[8], 'answers_id_count': q[9], 'auth_roles.role_name': q[10], 'questions.is_closed': (True if q[11] == 'T' else False), 'questions.id': q[12], 'tags': None, 'auth_users.auth_alias': q[13], 'auth_users.id': q[14]}) # Get tags for questions for q in questions: tags = db( (db.questions.id==db.question_tags.question_id) & (db.question_tags.tag_id==db.tags.id) & (db.questions.id==q['questions.id'])).select( db.tags.tagname) #raise ValueError, tags if tags: q['tags'] = tags return dict(view_info=view_info, questions=questions, nav_css=nav_css, sort_css=sort_css) else: # So apparently we have a new system install, redirect to the # appropriate page: redirect(URL(r=request, c='default', f='runonce'))
def qa_mgmt_actions(): """ This really should be a "helper" method for a module instead of a controller method, ask Massimo what would be the _preferred_ way of doing things here, since this only executes "stuff" and redirects back to the calling page. """ # "action", "action_type" and "question" are always provided as "vars" req = request.vars action = req.action action_type = req.action_type question = req.question # Request restore of a hidden question: if action == 'release' and action_type == 'question': # Here basically change the flag of the question, all of the # other question's siblings (comments, answers, and answers # to comments should become visible as well db(db.questions.id == question).update(is_visible=True) redirect(URL(r=request, c='admin', f='qa_mgmt_hq')) elif action == 'remove' and action_type == 'question': # This is a little bit more "complex" so to speak, the following # rules will apply: # Question is deleted. # Comments on the actual question, as well as answers and comments # on these answers are also removed. # Points awarded, etc remain. # 1. Remove all comments for this question db((db.comments.c_type == 'Q') & (db.comments.qa_id == question)).delete() # 2. Get all the possible answers for this question answers = db(db.answers.question_id == question).select(db.answers.id) # 3. for each answer, remove all its comments and the answer itself if answers: # Store all of our answer_ids a_ids = [answer.id for answer in answers] # Remove any comments for any of the answer ids stored above db((db.comments.c_type == 'A') & (db.comments.qa_id.belongs(tuple(a_ids)))).delete() # Remove all the answers for this question db(db.answers.question_id == question).delete() # 4. Remove the actual question. db(db.questions.id == question).delete() # 5. Clean up stub tables: # Remove the references of this question from the subscriptions # table in case some members have this question marked db(db.question_subscriptions.question_id == question).delete() # Remove the tags associated with this question db(db.question_tags.question_id == question).delete() redirect(URL(r=request, c='admin', f='qa_mgmt_hq')) elif action == 'release' and action_type == 'answer': # Another easy one, just change the flag of the answer's answer = req.answer db(db.answers.id == answer).update(is_visible=True) redirect(URL(r=request, c='admin', f='qa_mgmt_ha')) elif action == 'remove' and action_type == 'answer': # In this case, I need to remove this answer's comments and the # answer itself answer = req.answer db((db.comments.c_type == 'A') % (db.comments.qa_id == answer)).delete() db(db.answers.id == answer).delete() redirect(URL(r=request, c='admin', f='qa_mgmt_ha')) elif action == 'release' and action_type == 'comment': # In this case we just need to make this comment visible, since we # have the comment.id it should be pretty straightforward db(db.comments.id == req.comment).update(is_visible=True) redirect(URL(r=request, c='admin', f='qa_mgmt')) elif action == 'remove' and action_type == 'comment': # Also easy, remove the comment db(db.comments.id == req.comment).delete() redirect(URL(r=request, c='admin', f='qa_mgmt')) else: redirect( URL(r=request, c='admin', f='qa_mgmt', vars=dict(invalid_selection=True)))
def view(): """ The default page when viewing a question """ # We need to pull here several important things: Questions, comments for # questions, answers, comments for answers.. view_info = {'errors': []} req = request.vars qid = req.qid if req.qid is not None else request.args[0] # Question ID # Read the question here to see if the user is allowed to access it question = db(db.questions.id == qid).select(db.questions.ALL) user_id = auth_user.get_user_id() if not question or (not question[0].is_visible and not auth_user.is_admin()): # Only admins may see hidden questions.. redirect(URL(r=request, c='default', f='unauthorized')) featured_votes = db((db.score_log.l_type == 'Q') & (db.score_log.subtype == 'featuredrequest') & (db.score_log.qac_id == qid)).count() view_info.update(dict(featured_votes=featured_votes)) offensive_votes = db((db.score_log.l_type == 'Q') & (db.score_log.subtype == 'offensiverequest') & (db.score_log.qac_id == qid)).count() view_info.update(dict(offensive_votes=offensive_votes)) # This controls if the user is subscribed or not to this question view_info['is_subscribed'] = False if auth_user.is_auth(): if stackhelper.user_is_subscribed(qid, user_id): view_info['is_subscribed'] = True # Only the following roles can add comments can_comment = auth_user.has_role('Reviewer,TeamLead,Manager,SysAdmin') view_info['can_comment'] = can_comment if req.form_submitted: view_info['form_submitted'] = True preview_answer = req.preview_answer post_answer = req.post_answer answer = req.get('answer', '').strip() view_info['answer'] = answer if preview_answer is not None: view_info['preview_answer'] = preview_answer else: # Posting an answer to this question here if answer: modified_by = user_id db.answers.insert(question_id=qid, description=answer, created_by=modified_by, created_on=request.now, modified_by=modified_by, is_outstanding=False, votes_up=0, votes_dn=0, is_visible=True, is_answer=False, modified_on=request.now) # Update the original question's last update date/user db(db.questions.id == qid).update(modified_by=modified_by, modified_on=request.now) # Also, increment the number of answers this user has posted stackhelper.increment_member_property('m_answers', modified_by, 1) else: view_info['errors'].append( 'Please add a valid answer to continue') else: # Update the page views for this question, only # if the page is viewed via GET view_rec = db(db.questions.id == qid).select(db.questions.views)[0] db(db.questions.id == qid).update(views=view_rec.views + 1) question = db( (db.questions.id == qid) & (db.questions.created_by == db.member_properties.auth_user) & (db.member_properties.property_id == db.member_properties_skel.id) & (db.member_properties_skel.property_name == 'm_display_name')).select( db.questions.ALL, db.member_properties.property_value)[0] tags = db( (db.questions.id==db.question_tags.question_id) &\ (db.question_tags.tag_id==db.tags.id) &\ (db.questions.id==question.questions.id)).select( db.tags.tagname) q_comments = db( (db.comments.c_type=='Q') & (db.comments.qa_id==qid) & (db.comments.is_visible==True) & (db.comments.created_by==db.member_properties.auth_user) & (db.member_properties.property_id==db.member_properties_skel.id) & (db.member_properties_skel.property_name==\ 'm_display_name')).select(db.comments.ALL, db.member_properties.property_value, orderby=db.comments.modified_on) answers = db( (db.answers.question_id == qid) & (db.answers.is_visible == True) & (db.answers.created_by == db.member_properties.auth_user) & (db.member_properties.property_id == db.member_properties_skel.id) & (db.member_properties_skel.property_name == 'm_display_name')).select( db.answers.ALL, db.member_properties.property_value, orderby=~db.answers.is_answer | ~db.answers.modified_on) # Now every different proposed answer can have comments, # so I need the comments for each answer if applicable) comments_a = {} for answer in answers: comments = db( (db.comments.c_type=='A') & (db.comments.qa_id==answer.answers.id) & (db.comments.is_visible==True) & (db.comments.created_by==db.member_properties.auth_user) & (db.member_properties.property_id==db.member_properties_skel.id) & (db.member_properties_skel.property_name==\ 'm_display_name')).select( db.comments.ALL, db.member_properties.property_value, orderby=db.comments.modified_on) if comments: comments_a.update({answer.answers.id: comments}) return dict(question=question, tags=tags, q_comments=q_comments, answers=answers, comments_a=comments_a, can_comment=can_comment, view_info=view_info)
def index(): """ Main application index (entry point) page """ if session.RUN_ONCE is None: view_info = {} view_info.update({'errors': []}) req = request.vars args = request.args nav_css = 'aquestions' # Some needed system information (think about caching this and # update every 4 hours or so..) num_recs = int( stackhelper.get_system_property('s_questions_per_page', 30)) mode = '' try: offset = int(req.start) except: offset = 0 try: mode = args[0] nav_css = 'a%s' % (mode) except: pass sort_css = 's_dates' if req.sort is None else req.sort # Constraints: # Sort (qsort): # Latest == order by questions.modified_on DESC # Most Voted = order by questions.votes_up DESC # Featured = where questions.is_featured == 'T' # # Type (qtype) # Questions = (no constraints) # Unanswered = where questions.is_answered == 'F' qsort = req.sort # Latest, Most Voted (Sub Tabs) # qtype = req.qtype - Questions, Unanswered (Main Tabs) sql_order = 'questions.modified_on DESC' if qsort == 's_votes': # "most voted" sql_order = 'questions.votes_up DESC' qtype = '' if len(args) > 0: qtype_arg = args[0] if qtype_arg == 'unanswered': qtype = 'u' elif qtype_arg == 'featured': qtype = 'f' elif qtype_arg == 'subscribed': qtype = 's' sql_where = [] extra_tables = [''] # <-- Important if qtype == 'u': # Unanswered sql_where.append("questions.is_answered = 'F'") elif qtype == 'f': # Featured sql_where.append("questions.is_featured = 'T'") elif qtype == 's': # Subscribed sql_where.append("questions.id = " "question_subscriptions.question_id") sql_where.append("question_subscriptions.is_active = 'T'") sql_where.append("question_subscriptions.auth_user_id = " "%s" % (auth_user.get_user_id() or 0)) extra_tables.append('question_subscriptions') # Tag Handling srch_tag = '' tag_table = '' if mode == 'tags': srch_tag = req.get('tag', 'qa-stack') # /default/index/tags?tag=meh # get the "id" of this tag.. sql_tags = db(db.tags.tagname.like('%s%%' % (srch_tag))).select( db.tags.id) tags = ','.join([str(tag.id) for tag in sql_tags]) # '1,5,7,9,etc' sql_where.append('question_tags.question_id = questions.id') sql_where.append('question_tags.tag_id in (%s)' % (tags if tags else 0)) extra_tables.append('question_tags') sql_where_str = '' if sql_where: sql_where_str = "\nand %s" % (' and '.join(sql_where)) # Grab questions sql_cnt = """ select count(questions.id) from questions %s where questions.is_visible='T' %s """ % (','.join(extra_tables), sql_where_str) question_cnt = db.executesql(sql_cnt)[0][0] view_info['question_cnt'] = question_cnt sql = """ select questions.title, questions.created_on, questions.modified_on, questions.views, questions.votes_up, questions.votes_dn, questions.is_answered, questions.is_featured, member_properties.property_value, COUNT(answers.id), auth_roles.role_name, questions.is_closed, questions.id, auth_users.auth_alias, auth_users.id from questions LEFT JOIN answers ON answers.question_id=questions.id, auth_users, member_properties, member_properties_skel, auth_roles %s where questions.is_visible='T' AND member_properties.auth_user=questions.created_by AND member_properties.property_id=member_properties_skel.id AND member_properties_skel.property_name='m_display_name' AND auth_roles.id=auth_users.auth_role_id AND auth_users.id=questions.created_by %s group by questions.id order by %s limit %s offset %s """ % (','.join(extra_tables), sql_where_str, sql_order, num_recs, offset) questions = [] all_questions = db.executesql(sql) if all_questions: for q in all_questions: questions.append({ 'questions.title': q[0], 'questions.created_on': q[1], 'questions.modified_on': q[2], 'questions.views': q[3], 'questions.votes_up': q[4], 'questions.votes_dn': q[5], 'questions.is_answered': (True if q[6] == 'T' else False), 'questions.is_featured': (True if q[7] == 'T' else False), 'member_properties.property_value': q[8], 'answers_id_count': q[9], 'auth_roles.role_name': q[10], 'questions.is_closed': (True if q[11] == 'T' else False), 'questions.id': q[12], 'tags': None, 'auth_users.auth_alias': q[13], 'auth_users.id': q[14] }) # Get tags for questions for q in questions: tags = db((db.questions.id == db.question_tags.question_id) & (db.question_tags.tag_id == db.tags.id) & (db.questions.id == q['questions.id'])).select( db.tags.tagname) #raise ValueError, tags if tags: q['tags'] = tags return dict(view_info=view_info, questions=questions, nav_css=nav_css, sort_css=sort_css) else: # So apparently we have a new system install, redirect to the # appropriate page: redirect(URL(r=request, c='default', f='runonce'))
def view_admin_message(): message = db(db.admin_messages.id == request.args[0]).select( db.admin_messages.ALL)[0] # In addition, update this message's status to "read" db(db.admin_messages.id == request.args[0]).update(read_flag=True) return dict(message=message)
def edit_user(): view_info = {} view_info['errors'] = [] view_info['props'] = {} req = request.vars user_id = request.args[0] # /admin/edit_user/1000 admin_username = auth_user.get_user_name() admin_user_id = auth_user.get_user_id() # roles will be used in the page roles = db().select(db.auth_roles.ALL, orderby=db.auth_roles.role_min_score) # To get the selected user username (located in member_properties) # I will query the table directly username = db(db.auth_users.id == user_id).select( db.auth_users.auth_alias)[0].auth_alias #username = db( # (db.member_properties_skel.property_name=='m_display_name') & # (db.member_properties_skel.id==db.member_properties.property_id) & # (db.member_properties.auth_user==user_id)).select( # db.member_properties.property_value)[0].property_value user_role_info = db((db.auth_users.auth_role_id == db.auth_roles.id) & (db.auth_users.id == user_id)).select( db.auth_roles.role_name, db.auth_roles.id, db.auth_roles.color_designation)[0] view_info['props'].update({ 'user_role_name': user_role_info.role_name, 'user_role_color': user_role_info.color_designation }) user_email = username # Avatar Restrictions (px) - Maybe we need to make these dynamic?? AVATAR_MAX_HEIGHT = 120 AVATAR_MAX_WIDTH = 100 AVATAR_MAX_SIZE = 111213 # Bytes view_info['props'].update({ 'questions': stackhelper.get_member_property('m_questions', user_id, '0') }) view_info['props'].update({ 'real_name': stackhelper.get_member_property('m_real_name', user_id, '') }) view_info['props'].update({ 'web_page': stackhelper.get_member_property('m_web_page', user_id, '') }) view_info['props'].update( {'country': stackhelper.get_member_property('m_country', user_id, '')}) view_info['props'].update( {'locale': stackhelper.get_member_property('m_locale', user_id, '')}) view_info['props'].update({ 'display_name': stackhelper.get_member_property('m_display_name', user_id, '') }) view_info['props'].update({ 'answers': stackhelper.get_member_property('m_answers', user_id, '0') }) view_info['props'].update({ 'comments': stackhelper.get_member_property('m_comments', user_id, '0') }) view_info['props'].update({ 'second_email': stackhelper.get_member_property('m_email', user_id, '') }) view_info['props'].update({ 'points_up': stackhelper.get_member_property('m_points_up', user_id, '0') }) view_info['props'].update({ 'points_dn': stackhelper.get_member_property('m_points_dn', user_id, '0') }) question_subscriptions = db( (db.question_subscriptions.auth_user_id == user_id) & (db.question_subscriptions.is_active == True) & (db.questions.id == db.question_subscriptions.question_id)).select( db.questions.id, db.questions.title) if req.form_submitted: if req.update_b: # Was a change in roles requested? if int(req.new_role) != user_role_info.id: # Yes, then change it db(db.auth_users.id == user_id).update( auth_role_id=req.new_role) # Standard Properties stackhelper.put_member_property('m_real_name', user_id, req.real_name) stackhelper.put_member_property('m_web_page', user_id, req.web_page) stackhelper.put_member_property('m_country', user_id, req.country) stackhelper.put_member_property('m_display_name', user_id, req.display_name) stackhelper.put_member_property('m_email', user_id, req.second_email) # Question Subscriptions remove_questions_subscription = req.remove_questions_subscription if remove_questions_subscription: #raise ValueError, remove_question_subscriptions stackhelper.del_question_subscription( remove_questions_subscription, user_id) # Password Changes if req.new_passwd or req.new_passwd_confirm: if req.new_passwd == req.new_passwd_confirm: # Probably need to offset this to its own security class, # So far there are several (few however) places where I # perform security updates. hash_passwd = hashlib.sha1( '%s%s' % (user_email, req.new_passwd)).hexdigest() db(db.auth_users.auth_alias == user_email).update( auth_passwd=hash_passwd) else: view_info['errors'].append('Password and confirmation do ' 'not match, please try again') # Avatars if req.remove_avatar: db(db.member_avatars.auth_user_id == user_id).update( avatar_active=False) # Crude verification of a FileUpload object set try: filename = req.avatar_data.filename except AttributeError: filename = None if filename: # Resource: # http://epydoc.sourceforge.net/stdlib/ [cont'd next line] # cgi.FieldStorage-class.html image_data = req.avatar_data.file.read() content_type = req.avatar_data.type # "image/png" doc_type, ext = content_type.split('/') if doc_type == 'image': c_type, width, height = \ stackhelper.get_image_info(image_data) update_avatar = True if height > AVATAR_MAX_HEIGHT or width > AVATAR_MAX_WIDTH: view_info['errors'].append( 'Image dimensions exceed the ' 'limits set by the ' 'administrator: ' '(W:%spx, H:%spx)' % (width, height)) view_info['errors'].append( 'Limits are ' '(W:%dpx, H:%dpx)' % (AVATAR_MAX_WIDTH, AVATAR_MAX_HEIGHT)) update_avatar = False if len(image_data) > AVATAR_MAX_SIZE: view_info['errors'].append( 'Avatar exceeds the maximum image size set by the ' 'administrator: %s bytes' % (len(image_data))) view_info['errors'].append('Limit is: (%d bytes)' % (AVATAR_MAX_SIZE)) update_avatar = False if update_avatar: if stackhelper.has_member_avatar(user_id, bypass=False): # Update: db(db.member_avatars.auth_user_id == user_id).update(content_type=content_type, avatar_image=image_data, avatar_active=True) else: # Add: db.member_avatars.insert(content_type=content_type, auth_user_id=user_id, avatar_image=image_data, avatar_active=True) if view_info['errors']: return dict(request=request, view_info=view_info, username=username, user_email=user_email, user_id=user_id, roles=roles, question_subscriptions=question_subscriptions) else: # Save was successful redirect( URL(r=request, c='admin', f='edit_user', args=[user_id], vars=dict(saved=1))) else: # Cancel Requested - back to admin "main" screen redirect(URL(r=request, c='admin', f='users')) else: return dict(request=request, view_info=view_info, username=username, user_email=user_email, user_id=user_id, roles=roles, question_subscriptions=question_subscriptions)
def edit_user(): view_info = {} view_info['errors'] = [] view_info['props'] = {} req = request.vars user_id = request.args[0] # /admin/edit_user/1000 admin_username = auth_user.get_user_name() admin_user_id = auth_user.get_user_id() # roles will be used in the page roles = db().select( db.auth_roles.ALL, orderby=db.auth_roles.role_min_score) # To get the selected user username (located in member_properties) # I will query the table directly username = db( db.auth_users.id==user_id).select( db.auth_users.auth_alias)[0].auth_alias #username = db( # (db.member_properties_skel.property_name=='m_display_name') & # (db.member_properties_skel.id==db.member_properties.property_id) & # (db.member_properties.auth_user==user_id)).select( # db.member_properties.property_value)[0].property_value user_role_info = db( (db.auth_users.auth_role_id==db.auth_roles.id) & (db.auth_users.id==user_id)).select( db.auth_roles.role_name, db.auth_roles.id, db.auth_roles.color_designation)[0] view_info['props'].update({'user_role_name': user_role_info.role_name, 'user_role_color': user_role_info.color_designation}) user_email = username # Avatar Restrictions (px) - Maybe we need to make these dynamic?? AVATAR_MAX_HEIGHT = 120 AVATAR_MAX_WIDTH = 100 AVATAR_MAX_SIZE = 111213 # Bytes view_info['props'].update( {'questions': stackhelper.get_member_property('m_questions', user_id, '0')}) view_info['props'].update( {'real_name': stackhelper.get_member_property('m_real_name', user_id, '')}) view_info['props'].update( {'web_page': stackhelper.get_member_property('m_web_page', user_id, '')}) view_info['props'].update( {'country': stackhelper.get_member_property('m_country', user_id, '')}) view_info['props'].update( {'locale': stackhelper.get_member_property('m_locale', user_id, '')}) view_info['props'].update( {'display_name': stackhelper.get_member_property('m_display_name', user_id, '')}) view_info['props'].update( {'answers': stackhelper.get_member_property('m_answers', user_id, '0')}) view_info['props'].update( {'comments': stackhelper.get_member_property('m_comments', user_id, '0')}) view_info['props'].update( {'second_email': stackhelper.get_member_property('m_email', user_id, '')}) view_info['props'].update( {'points_up': stackhelper.get_member_property('m_points_up', user_id, '0')}) view_info['props'].update( {'points_dn': stackhelper.get_member_property('m_points_dn', user_id, '0')}) question_subscriptions = db( (db.question_subscriptions.auth_user_id==user_id) & (db.question_subscriptions.is_active==True) & (db.questions.id==db.question_subscriptions.question_id)).select( db.questions.id, db.questions.title) if req.form_submitted: if req.update_b: # Was a change in roles requested? if int(req.new_role) != user_role_info.id: # Yes, then change it db(db.auth_users.id==user_id).update( auth_role_id=req.new_role) # Standard Properties stackhelper.put_member_property('m_real_name', user_id, req.real_name) stackhelper.put_member_property('m_web_page', user_id, req.web_page) stackhelper.put_member_property('m_country', user_id, req.country) stackhelper.put_member_property('m_display_name', user_id, req.display_name) stackhelper.put_member_property('m_email', user_id, req.second_email) # Question Subscriptions remove_questions_subscription = req.remove_questions_subscription if remove_questions_subscription: #raise ValueError, remove_question_subscriptions stackhelper.del_question_subscription( remove_questions_subscription, user_id) # Password Changes if req.new_passwd or req.new_passwd_confirm: if req.new_passwd == req.new_passwd_confirm: # Probably need to offset this to its own security class, # So far there are several (few however) places where I # perform security updates. hash_passwd = hashlib.sha1( '%s%s' % (user_email, req.new_passwd)).hexdigest() db(db.auth_users.auth_alias==user_email).update( auth_passwd=hash_passwd) else: view_info['errors'].append('Password and confirmation do ' 'not match, please try again') # Avatars if req.remove_avatar: db(db.member_avatars.auth_user_id==user_id).update( avatar_active=False) # Crude verification of a FileUpload object set try: filename = req.avatar_data.filename except AttributeError: filename = None if filename: # Resource: # http://epydoc.sourceforge.net/stdlib/ [cont'd next line] # cgi.FieldStorage-class.html image_data = req.avatar_data.file.read() content_type = req.avatar_data.type # "image/png" doc_type, ext = content_type.split('/') if doc_type == 'image': c_type, width, height = \ stackhelper.get_image_info(image_data) update_avatar = True if height > AVATAR_MAX_HEIGHT or width > AVATAR_MAX_WIDTH: view_info['errors'].append( 'Image dimensions exceed the ' 'limits set by the ' 'administrator: ' '(W:%spx, H:%spx)' % (width, height)) view_info['errors'].append( 'Limits are ' '(W:%dpx, H:%dpx)' % (AVATAR_MAX_WIDTH, AVATAR_MAX_HEIGHT)) update_avatar = False if len(image_data) > AVATAR_MAX_SIZE: view_info['errors'].append( 'Avatar exceeds the maximum image size set by the ' 'administrator: %s bytes' % (len(image_data))) view_info['errors'].append( 'Limit is: (%d bytes)' % (AVATAR_MAX_SIZE)) update_avatar = False if update_avatar: if stackhelper.has_member_avatar( user_id, bypass=False): # Update: db(db.member_avatars.auth_user_id==user_id).update( content_type=content_type, avatar_image=image_data, avatar_active=True) else: # Add: db.member_avatars.insert(content_type=content_type, auth_user_id=user_id, avatar_image=image_data, avatar_active=True) if view_info['errors']: return dict(request=request, view_info=view_info, username=username, user_email=user_email, user_id=user_id, roles=roles, question_subscriptions=question_subscriptions) else: # Save was successful redirect(URL(r=request, c='admin', f='edit_user', args=[user_id], vars=dict(saved=1))) else: # Cancel Requested - back to admin "main" screen redirect(URL(r=request, c='admin', f='users')) else: return dict(request=request, view_info=view_info, username=username, user_email=user_email, user_id=user_id, roles=roles, question_subscriptions=question_subscriptions)
def qa_mgmt_actions(): """ This really should be a "helper" method for a module instead of a controller method, ask Massimo what would be the _preferred_ way of doing things here, since this only executes "stuff" and redirects back to the calling page. """ # "action", "action_type" and "question" are always provided as "vars" req = request.vars action = req.action action_type = req.action_type question = req.question # Request restore of a hidden question: if action == 'release' and action_type == 'question': # Here basically change the flag of the question, all of the # other question's siblings (comments, answers, and answers # to comments should become visible as well db(db.questions.id==question).update(is_visible=True) redirect(URL(r=request, c='admin', f='qa_mgmt_hq')) elif action == 'remove' and action_type == 'question': # This is a little bit more "complex" so to speak, the following # rules will apply: # Question is deleted. # Comments on the actual question, as well as answers and comments # on these answers are also removed. # Points awarded, etc remain. # 1. Remove all comments for this question db((db.comments.c_type=='Q') & (db.comments.qa_id==question)).delete() # 2. Get all the possible answers for this question answers = db(db.answers.question_id==question).select(db.answers.id) # 3. for each answer, remove all its comments and the answer itself if answers: # Store all of our answer_ids a_ids = [answer.id for answer in answers] # Remove any comments for any of the answer ids stored above db((db.comments.c_type=='A') & ( db.comments.qa_id.belongs(tuple(a_ids)))).delete() # Remove all the answers for this question db(db.answers.question_id==question).delete() # 4. Remove the actual question. db(db.questions.id==question).delete() # 5. Clean up stub tables: # Remove the references of this question from the subscriptions # table in case some members have this question marked db(db.question_subscriptions.question_id==question).delete() # Remove the tags associated with this question db(db.question_tags.question_id==question).delete() redirect(URL(r=request, c='admin', f='qa_mgmt_hq')) elif action == 'release' and action_type == 'answer': # Another easy one, just change the flag of the answer's answer = req.answer db(db.answers.id==answer).update(is_visible=True) redirect(URL(r=request, c='admin', f='qa_mgmt_ha')) elif action == 'remove' and action_type == 'answer': # In this case, I need to remove this answer's comments and the # answer itself answer = req.answer db((db.comments.c_type=='A') % (db.comments.qa_id==answer)).delete() db(db.answers.id==answer).delete() redirect(URL(r=request, c='admin', f='qa_mgmt_ha')) elif action == 'release' and action_type == 'comment': # In this case we just need to make this comment visible, since we # have the comment.id it should be pretty straightforward db(db.comments.id==req.comment).update(is_visible=True) redirect(URL(r=request, c='admin', f='qa_mgmt')) elif action == 'remove' and action_type == 'comment': # Also easy, remove the comment db(db.comments.id==req.comment).delete() redirect(URL(r=request, c='admin', f='qa_mgmt')) else: redirect(URL(r=request, c='admin', f='qa_mgmt', vars=dict(invalid_selection=True)))
def view_admin_message(): message = db(db.admin_messages.id==request.args[0]).select( db.admin_messages.ALL)[0] # In addition, update this message's status to "read" db(db.admin_messages.id==request.args[0]).update(read_flag=True) return dict(message=message)