예제 #1
0
def contact_admin():
    """ Contact Admin - This can allow anonymous users to post spam,
    so for them, I'll add some "poor man's captcha" """
    view_info = {}
    view_info['errors'] = []
    captcha = stackhelper.gen_pwd()
    view_info['anon_captcha'] = captcha
    view_info['anon_captcha_base64'] = base64.standard_b64encode(captcha)
    req = request.vars
    if req.form_submitted:
        if req.send_b:
            if req.subject and req.message:
                if auth_user.is_auth() or\
                (not auth_user.is_auth() and\
                 base64.standard_b64encode(req.captcha_response) == req.c):
                    db.admin_messages.insert(
                        auth_user_id=auth_user.get_user_id(),
                        subject=parse_content(req.subject),
                        message=parse_content(req.message),
                        creation_date=request.now,
                        read_flag=False)
                    redirect(URL(r=request, c='default', f='index'))
                else:
                    view_info['errors'].append(
                        'Invalid humanity challenge response, please try '
                        'again')
                    return dict(request=request, view_info=view_info)
            else:
                view_info['errors'].append(
                    'Both Subject and Message are required fields')
                return dict(request=request, view_info=view_info)
        else:
            redirect(URL(r=request, c='default', f='index'))
    else:
        return dict(request=request, view_info=view_info)
예제 #2
0
def contact_admin():
    """ Contact Admin - This can allow anonymous users to post spam,
    so for them, I'll add some "poor man's captcha" """
    view_info = {}
    view_info['errors'] = []
    captcha = stackhelper.gen_pwd()
    view_info['anon_captcha'] = captcha
    view_info['anon_captcha_base64'] = base64.standard_b64encode(captcha)
    req = request.vars
    if req.form_submitted:
        if req.send_b:
            if req.subject and req.message:
                if auth_user.is_auth() or\
                (not auth_user.is_auth() and\
                 base64.standard_b64encode(req.captcha_response) == req.c):
                    db.admin_messages.insert(
                        auth_user_id=auth_user.get_user_id(),
                        subject=parse_content(req.subject),
                        message=parse_content(req.message),
                        creation_date=request.now,
                        read_flag=False)
                    redirect(URL(r=request, c='default', f='index'))
                else:
                    view_info['errors'].append(
                        'Invalid humanity challenge response, please try '
                        'again')
                    return dict(request=request, view_info=view_info)
            else:
                view_info['errors'].append(
                    'Both Subject and Message are required fields')
                return dict(request=request, view_info=view_info)
        else:
            redirect(URL(r=request, c='default', f='index'))
    else:
        return dict(request=request, view_info=view_info)
예제 #3
0
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)
예제 #4
0
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)
예제 #5
0
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'))
예제 #6
0
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)
예제 #7
0
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'))
예제 #8
0
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)