Пример #1
0
def charactersbyuser(userid, form):
    if userid not in staff.MODS:
        raise WeasylError("Unexpected")

    query = d.execute("""
        SELECT
            ch.charid, pr.username, ch.unixtime,
            ch.char_name, ch.age, ch.gender, ch.height, ch.weight, ch.species,
            ch.content, ch.rating, ch.settings, ch.page_views, pr.config
        FROM character ch
        INNER JOIN profile pr ON ch.userid = pr.userid
        INNER JOIN login ON ch.userid = login.userid
        WHERE login.login_name = '%s'
    """, [d.get_sysname(form.name)])

    return [{
        "contype": 20,
        "userid": userid,
        "charid": item[0],
        "username": item[1],
        "unixtime": item[2],
        "title": item[3],
        "rating": item[10],
        "settings": item[11],
        "sub_media": character.fake_media_items(item[0], userid, d.get_sysname(item[1]), item[11]),
    } for item in query]
Пример #2
0
def charactersbyuser(userid, form):
    if userid not in staff.MODS:
        raise WeasylError("Unexpected")

    query = d.execute("""
        SELECT
            ch.charid, pr.username, ch.unixtime,
            ch.char_name, ch.age, ch.gender, ch.height, ch.weight, ch.species,
            ch.content, ch.rating, ch.settings, ch.page_views, pr.config
        FROM character ch
        INNER JOIN profile pr ON ch.userid = pr.userid
        INNER JOIN login ON ch.userid = login.userid
        WHERE login.login_name = '%s'
    """, [d.get_sysname(form.name)])

    return [{
        "contype": 20,
        "userid": userid,
        "charid": item[0],
        "username": item[1],
        "unixtime": item[2],
        "title": item[3],
        "rating": item[10],
        "settings": item[11],
        "sub_media": character.fake_media_items(item[0], userid, d.get_sysname(item[1]), item[11]),
    } for item in query]
Пример #3
0
def resolve(userid, otherid, othername, myself=True):
    """
    Attempts to determine the userid of a specified user; resolves using otherid,
    othername, and userid (if myself is True), in that order. If no userid can be
    resolved, returns 0 instead.
    """
    result = None

    if otherid:
        result = d.execute("SELECT userid FROM login WHERE userid = %i", [d.get_int(otherid)], ["element"])

        if result:
            return result
    elif othername:
        result = d.execute("SELECT userid FROM login WHERE login_name = '%s'", [d.get_sysname(othername)], ["element"])

        if result:
            return result

        result = d.execute("SELECT userid FROM useralias WHERE alias_name = '%s'", [d.get_sysname(othername)], ["element"])

        if result:
            return result
    elif userid and myself:
        return userid

    return 0
Пример #4
0
    def add_criterion(self, criterion):
        def add_nonempty(s, item):
            if item:
                s.add(item)

        find_modifier = _QUERY_FIND_MODIFIERS.get(criterion)

        if find_modifier:
            self.find = find_modifier
            return

        rating_modifier = _QUERY_RATING_MODIFIERS.get(criterion)

        if rating_modifier:
            self.ratings.add(rating_modifier)
            return

        if criterion.startswith(("user:"******"+user:"******":", 1)[1])
            add_nonempty(self.required_user_includes, user)
        elif criterion.startswith("-user:"******":", 1)[1])
            add_nonempty(self.required_user_excludes, user)
        elif criterion.startswith("+"):
            tag = d.get_search_tag(criterion[1:])
            add_nonempty(self.required_includes, tag)
        elif criterion.startswith("-"):
            tag = d.get_search_tag(criterion[1:])
            add_nonempty(self.required_excludes, tag)
        elif criterion.startswith("|"):
            tag = d.get_search_tag(criterion[1:])
            add_nonempty(self.possible_includes, tag)
        else:
            tag = d.get_search_tag(criterion)
            add_nonempty(self.required_includes, tag)
Пример #5
0
    def add_criterion(self, criterion):
        def add_nonempty(s, item):
            if item:
                s.add(item)

        find_modifier = _QUERY_FIND_MODIFIERS.get(criterion)

        if find_modifier:
            self.find = find_modifier
            return

        rating_modifier = _QUERY_RATING_MODIFIERS.get(criterion)

        if rating_modifier:
            self.ratings.add(rating_modifier)
            return

        if criterion.startswith(("user:"******"+user:"******":", 1)[1])
            add_nonempty(self.required_user_includes, user)
        elif criterion.startswith("-user:"******":", 1)[1])
            add_nonempty(self.required_user_excludes, user)
        elif criterion.startswith("+"):
            tag = d.get_search_tag(criterion[1:])
            add_nonempty(self.required_includes, tag)
        elif criterion.startswith("-"):
            tag = d.get_search_tag(criterion[1:])
            add_nonempty(self.required_excludes, tag)
        elif criterion.startswith("|"):
            tag = d.get_search_tag(criterion[1:])
            add_nonempty(self.possible_includes, tag)
        else:
            tag = d.get_search_tag(criterion)
            add_nonempty(self.required_includes, tag)
Пример #6
0
def resolve(userid, otherid, othername, myself=True):
    """
    Attempts to determine the userid of a specified user; resolves using otherid,
    othername, and userid (if myself is True), in that order. If no userid can be
    resolved, returns 0 instead.
    """
    result = None

    if otherid:
        result = d.execute("SELECT userid FROM login WHERE userid = %i",
                           [d.get_int(otherid)], ["element"])

        if result:
            return result
    elif othername:
        result = d.execute("SELECT userid FROM login WHERE login_name = '%s'",
                           [d.get_sysname(othername)], ["element"])

        if result:
            return result

        result = d.execute(
            "SELECT userid FROM useralias WHERE alias_name = '%s'",
            [d.get_sysname(othername)], ["element"])

        if result:
            return result
    elif userid and myself:
        return userid

    return 0
Пример #7
0
def control_streaming_post_(request):
    form = request.web_input(target="",
                             set_stream="",
                             stream_length="",
                             stream_url="",
                             stream_text="")

    if form.target and request.userid not in staff.MODS:
        raise WeasylError('InsufficientPermissions')

    if form.target:
        target = int(form.target)
    else:
        target = request.userid

    stream_length = define.clamp(define.get_int(form.stream_length), 0, 360)
    p = orm.Profile()
    p.stream_text = form.stream_text
    p.stream_url = define.text_fix_url(form.stream_url.strip())
    set_stream = form.set_stream

    profile.edit_streaming_settings(request.userid,
                                    target,
                                    p,
                                    set_stream=set_stream,
                                    stream_length=stream_length)

    if form.target:
        target_username = define.get_sysname(define.get_display_name(target))
        raise HTTPSeeOther(location="/modcontrol/manageuser?name=" +
                           target_username)
    else:
        raise HTTPSeeOther(location="/control")
Пример #8
0
def frienduser_(request):
    if not define.is_vouched_for(request.userid):
        raise WeasylError("vouchRequired")

    form = request.web_input(userid="")
    otherid = define.get_int(form.userid)

    if request.userid == otherid:
        raise WeasylError('cannotSelfFriend')

    if form.action == "sendfriendrequest":
        if not frienduser.check(request.userid,
                                otherid) and not frienduser.already_pending(
                                    request.userid, otherid):
            frienduser.request(request.userid, otherid)
    elif form.action == "withdrawfriendrequest":
        if frienduser.already_pending(request.userid, otherid):
            frienduser.remove_request(request.userid, otherid)
    elif form.action == "unfriend":
        frienduser.remove(request.userid, otherid)

    if form.feature == "pending":
        raise HTTPSeeOther(location="/manage/friends?feature=pending")
    else:  # typical value will be user
        raise HTTPSeeOther(
            location="/~%s" %
            (define.get_sysname(define.get_display_name(otherid))))
Пример #9
0
def submissionsbyuser(userid, form):
    if userid not in staff.MODS:
        raise WeasylError("Unexpected")

    query = d.execute(
        """
        SELECT su.submitid, su.title, su.rating, su.unixtime, su.userid, pr.username, su.settings
        FROM submission su
            INNER JOIN profile pr USING (userid)
        WHERE su.userid = (SELECT userid FROM login WHERE login_name = '%s')
        ORDER BY su.submitid DESC
    """, [d.get_sysname(form.name)])

    ret = [{
        "contype": 10,
        "submitid": i[0],
        "title": i[1],
        "rating": i[2],
        "unixtime": i[3],
        "userid": i[4],
        "username": i[5],
        "settings": i[6],
    } for i in query]
    media.populate_with_submission_media(ret)
    return ret
Пример #10
0
def control_streaming_post_(request):
    form = request.web_input(target="", set_stream="", stream_length="", stream_url="", stream_text="")

    if form.target and request.userid not in staff.MODS:
        return Response(define.errorpage(request.userid, errorcode.permission))

    if form.target:
        target = int(form.target)
    else:
        target = request.userid

    stream_length = define.clamp(define.get_int(form.stream_length), 0, 360)
    p = orm.Profile()
    p.stream_text = form.stream_text
    p.stream_url = define.text_fix_url(form.stream_url.strip())
    set_stream = form.set_stream

    profile.edit_streaming_settings(request.userid, target, p,
                                    set_stream=set_stream,
                                    stream_length=stream_length)

    if form.target:
        target_username = define.get_sysname(define.get_display_name(target))
        raise HTTPSeeOther(location="/modcontrol/manageuser?name=" + target_username)
    else:
        raise HTTPSeeOther(location="/control")
Пример #11
0
def tidy_submission(submission):
    submission['posted_at'] = d.iso8601(submission.pop('unixtime'))
    submission['sub_media'] = api.tidy_all_media(submission['sub_media'])
    if 'user_media' in submission:
        submission['owner_media'] = api.tidy_all_media(
            submission.pop('user_media'))
    submission.pop('userid', None)
    subtype = submission.pop('subtype', None)
    if subtype:
        submission['subtype'] = m.CATEGORY_PARSABLE_MAP[subtype // 1000 * 1000]
    contype = submission.pop('contype', None)
    if contype:
        submission['type'] = m.CONTYPE_PARSABLE_MAP[contype]
    submission['rating'] = ratings.CODE_TO_NAME[submission['rating']]
    submission['owner'] = submission.pop('username')
    submission['owner_login'] = d.get_sysname(submission['owner'])
    submission['media'] = submission.pop('sub_media')
    submitid = 0
    if 'submitid' in submission:
        submitid = submission['submitid']
    if 'charid' in submission:
        submitid = submission['charid']
    if submitid > 0:
        if submission['type'] == "usercollect":
            linktype = "submission"
        else:
            linktype = submission['type']
        submission['link'] = d.absolutify_url(
            "/%s/%d/%s" % (linktype, submitid, slug_for(submission['title'])))
Пример #12
0
Файл: api.py Проект: 0x15/weasyl
def tidy_submission(submission):
    submission['posted_at'] = d.iso8601(submission.pop('unixtime'))
    submission['sub_media'] = api.tidy_all_media(submission['sub_media'])
    if 'user_media' in submission:
        submission['owner_media'] = api.tidy_all_media(submission.pop('user_media'))
    submission.pop('userid', None)
    subtype = submission.pop('subtype', None)
    if subtype:
        submission['subtype'] = m.CATEGORY_PARSABLE_MAP[subtype // 1000 * 1000]
    contype = submission.pop('contype', None)
    if contype:
        submission['type'] = m.CONTYPE_PARSABLE_MAP[contype]
    submission['rating'] = ratings.CODE_TO_NAME[submission['rating']]
    submission['owner'] = submission.pop('username')
    submission['owner_login'] = d.get_sysname(submission['owner'])
    submission['media'] = submission.pop('sub_media')
    submitid = 0
    if 'submitid' in submission:
        submitid = submission['submitid']
    if 'charid' in submission:
        submitid = submission['charid']
    if submitid > 0:
        if submission['type'] == "usercollect":
            linktype = "submission"
        else:
            linktype = submission['type']
        submission['link'] = d.absolutify_url(
            "/%s/%d/%s" % (linktype, submitid, slug_for(submission['title'])))
    return submission
Пример #13
0
def select_view_api(userid, journalid, anyway=False, increment_views=False):
    rating = d.get_rating(userid)

    journal = _select_journal_and_check(
        userid, journalid,
        rating=rating, ignore=anyway, anyway=anyway, increment_views=increment_views)

    return {
        'journalid': journalid,
        'title': journal['title'],
        'owner': journal['username'],
        'owner_login': d.get_sysname(journal['username']),
        'owner_media': api.tidy_all_media(
            media.get_user_media(journal['userid'])),
        'content': text.markdown(journal['content']),
        'tags': searchtag.select(journalid=journalid),
        'link': d.absolutify_url('/journal/%d/%s' % (journalid, text.slug_for(journal['title']))),
        'type': 'journal',
        'rating': ratings.CODE_TO_NAME[journal['rating']],
        'views': journal['page_views'],
        'favorites': favorite.count(journalid, 'journal'),
        'comments': comment.count(journalid, 'journal'),
        'favorited': favorite.check(userid, journalid=journalid),
        'friends_only': 'f' in journal['settings'],
        'posted_at': d.iso8601(journal['unixtime']),
    }
Пример #14
0
def api_user_gallery_(request):
    userid = profile.resolve_by_login(d.get_sysname(request.matchdict['login']))
    if not userid:
        raise WeasylError('userRecordMissing')

    form = request.web_input(since=None, count=0, folderid=0, backid=0, nextid=0)
    since = None
    try:
        if form.since:
            since = d.parse_iso8601(form.since)
        count = int(form.count)
        folderid = int(form.folderid)
        backid = int(form.backid)
        nextid = int(form.nextid)
    except ValueError:
        raise HTTPUnprocessableEntity(json=_ERROR_UNEXPECTED)
    else:
        count = min(count or 100, 100)

    submissions = submission.select_list(
        request.userid, d.get_rating(request.userid), count + 1,
        otherid=userid, folderid=folderid, backid=backid, nextid=nextid)
    backid, nextid = d.paginate(submissions, backid, nextid, count, 'submitid')

    ret = []
    for sub in submissions:
        if since is not None and since >= sub['unixtime']:
            break
        tidy_submission(sub)
        ret.append(sub)

    return {
        'backid': backid, 'nextid': nextid,
        'submissions': ret,
    }
Пример #15
0
def _fake_media_items(i):
    if i.contype == _CONTYPE_CHAR:
        return character.fake_media_items(i.id, i.userid,
                                          d.get_sysname(i.username),
                                          i.settings)
    else:
        return None
Пример #16
0
def vouch_(request):
    if not define.is_vouched_for(request.userid):
        raise WeasylError("vouchRequired")

    targetid = int(request.POST['targetid'])

    updated = define.engine.execute(
        "UPDATE login SET voucher = %(voucher)s WHERE userid = %(target)s AND voucher IS NULL RETURNING email",
        voucher=request.userid,
        target=targetid,
    ).first()

    target_username = define.get_display_name(targetid)

    if updated is not None:
        define._get_all_config.invalidate(targetid)
        emailer.send(updated.email, "Weasyl Account Verified",
                     define.render("email/verified.html", [target_username]))

    if target_username is None:
        assert updated is None
        raise WeasylError("Unexpected")

    raise HTTPSeeOther(location=request.route_path(
        'profile_tilde', name=define.get_sysname(target_username)))
Пример #17
0
def frienduser_(request):
    form = request.web_input(userid="")
    otherid = define.get_int(form.userid)

    if request.userid == otherid:
        return Response(
            define.errorpage(request.userid, "You cannot friend yourself."))

    if form.action == "sendfriendrequest":
        if not frienduser.check(request.userid,
                                otherid) and not frienduser.already_pending(
                                    request.userid, otherid):
            frienduser.request(request.userid, otherid)
    elif form.action == "withdrawfriendrequest":
        if frienduser.already_pending(request.userid, otherid):
            frienduser.remove_request(request.userid, otherid)
    elif form.action == "unfriend":
        frienduser.remove(request.userid, otherid)

    if form.feature == "pending":
        raise HTTPSeeOther(location="/manage/friends?feature=pending")
    else:  # typical value will be user
        raise HTTPSeeOther(
            location="/~%s" %
            (define.get_sysname(define.get_display_name(otherid))))
Пример #18
0
def select_view_api(userid, journalid, anyway=False, increment_views=False):
    rating = d.get_rating(userid)

    journal = _select_journal_and_check(
        userid, journalid,
        rating=rating, ignore=anyway, anyway=anyway, increment_views=increment_views)

    return {
        'journalid': journalid,
        'title': journal['title'],
        'owner': journal['username'],
        'owner_login': d.get_sysname(journal['username']),
        'owner_media': api.tidy_all_media(
            media.get_user_media(journal['userid'])),
        'content': text.markdown(journal['content']),
        'tags': searchtag.select(journalid=journalid),
        'link': d.absolutify_url('/journal/%d/%s' % (journalid, text.slug_for(journal['title']))),
        'type': 'journal',
        'rating': ratings.CODE_TO_NAME[journal['rating']],
        'views': journal['page_views'],
        'favorites': favorite.count(journalid, 'journal'),
        'comments': comment.count(journalid, 'journal'),
        'favorited': favorite.check(userid, journalid=journalid),
        'friends_only': 'f' in journal['settings'],
        'posted_at': d.iso8601(journal['unixtime']),
    }
Пример #19
0
def select_view(userid, charid, rating, ignore=True, anyway=None):
    query = _select_character_and_check(
        userid, charid, rating=rating, ignore=ignore, anyway=anyway == 'anyway')

    login = define.get_sysname(query['username'])

    return {
        'charid': charid,
        'userid': query['userid'],
        'username': query['username'],
        'user_media': media.get_user_media(query['userid']),
        'mine': userid == query['userid'],
        'unixtime': query['unixtime'],
        'title': query['char_name'],
        'age': query['age'],
        'gender': query['gender'],
        'height': query['height'],
        'weight': query['weight'],
        'species': query['species'],
        'content': query['content'],
        'rating': query['rating'],
        'settings': query['settings'],
        'reported': report.check(charid=charid),
        'favorited': favorite.check(userid, charid=charid),
        'page_views': query['page_views'],
        'friends_only': 'f' in query['settings'],
        'hidden_submission': 'h' in query['settings'],
        'fave_count': favorite.count(charid, 'character'),
        'comments': comment.select(userid, charid=charid),
        'sub_media': fake_media_items(
            charid, query['userid'], login, query['settings']),
        'tags': searchtag.select(charid=charid),
    }
Пример #20
0
def select_view(userid, charid, rating, ignore=True, anyway=None):
    query = _select_character_and_check(
        userid, charid, rating=rating, ignore=ignore, anyway=anyway == "true")

    login = define.get_sysname(query['username'])

    return {
        'charid': charid,
        'userid': query['userid'],
        'username': query['username'],
        'user_media': media.get_user_media(query['userid']),
        'mine': userid == query['userid'],
        'unixtime': query['unixtime'],
        'title': query['char_name'],
        'age': query['age'],
        'gender': query['gender'],
        'height': query['height'],
        'weight': query['weight'],
        'species': query['species'],
        'content': query['content'],
        'rating': query['rating'],
        'settings': query['settings'],
        'reported': report.check(charid=charid),
        'favorited': favorite.check(userid, charid=charid),
        'page_views': query['page_views'],
        'friends_only': 'f' in query['settings'],
        'hidden_submission': 'h' in query['settings'],
        'fave_count': favorite.count(charid, 'character'),
        'comments': comment.select(userid, charid=charid),
        'sub_media': fake_media_items(
            charid, query['userid'], login, query['settings']),
        'tags': searchtag.select(charid=charid),
    }
Пример #21
0
def request(form):
    token = security.generate_key(100)
    email = emailer.normalize_address(form.email)
    username = d.get_sysname(form.username)

    # Determine the user associated with `username`; if the user is not found,
    # raise an exception
    user = d.engine.execute(
        "SELECT userid, email FROM login WHERE login_name = %(username)s",
        username=username).first()

    if not user:
        raise WeasylError("loginRecordMissing")

    # Check the user's email address against the provided e-mail address,
    # raising an exception if there is a mismatch
    if email != emailer.normalize_address(user.email):
        raise WeasylError("emailInvalid")

    # Insert a record into the forgotpassword table for the user,
    # or update an existing one
    now = d.get_time()
    address = d.get_address()

    d.engine.execute("""
        INSERT INTO forgotpassword (userid, token, set_time, address)
        VALUES (%(id)s, %(token)s, %(time)s, %(address)s)
        ON CONFLICT (userid) DO UPDATE SET
            token = %(token)s,
            set_time = %(time)s,
            address = %(address)s
    """, id=user.userid, token=token, time=now, address=address)

    # Generate and send an email to the user containing a password reset link
    emailer.append([email], None, "Weasyl Password Recovery", d.render("email/reset_password.html", [token]))
Пример #22
0
def create(form):
    # Normalize form data
    username = d.plaintext(form.username[:_USERNAME])
    sysname = d.get_sysname(username)

    email = emailer.normalize_address(form.email)
    emailcheck = emailer.normalize_address(form.emailcheck)

    password = form.password
    passcheck = form.passcheck

    if form.day and form.month and form.year:
        try:
            birthday = arrow.Arrow(int(form.year), int(form.month), int(form.day))
        except ValueError:
            raise WeasylError("birthdayInvalid")
    else:
        birthday = None

    # Check mismatched form data
    if password != passcheck:
        raise WeasylError("passwordMismatch")
    if email != emailcheck:
        raise WeasylError("emailMismatch")

    # Check invalid form data
    if birthday is None or d.age_in_years(birthday) < 13:
        raise WeasylError("birthdayInvalid")
    if not password_secure(password):
        raise WeasylError("passwordInsecure")
    if not email:
        raise WeasylError("emailInvalid")
    if not sysname or ";" in username:
        raise WeasylError("usernameInvalid")
    if sysname in ["admin", "administrator", "mod", "moderator", "weasyl",
                   "weasyladmin", "weasylmod", "staff", "security"]:
        raise WeasylError("usernameInvalid")
    if email_exists(email):
        raise WeasylError("emailExists")
    if username_exists(sysname):
        raise WeasylError("usernameExists")

    # Create pending account
    token = security.generate_key(40)

    d.engine.execute(d.meta.tables["logincreate"].insert(), {
        "token": token,
        "username": username,
        "login_name": sysname,
        "hashpass": passhash(password),
        "email": email,
        "birthday": birthday,
        "unixtime": arrow.now(),
    })

    # Queue verification email
    emailer.append([email], None, "Weasyl Account Creation", d.render(
        "email/verify_account.html", [token, sysname]))
    d.metric('increment', 'createdusers')
Пример #23
0
def select_list(userid, form):
    # Find the unique violation types and the number of reporters. This will be
    # joined against the Report model to get the violations/reporters for each
    # selected report.
    subq = (
        ReportComment.dbsession.query(
            ReportComment.reportid,
            sa.func.count(),
            sa.type_coerce(
                sa.func.array_agg(ReportComment.violation.distinct()),
                ARRAY(sa.Integer, as_tuple=True)).label('violations'))
        .filter(ReportComment.violation != 0)
        .group_by(ReportComment.reportid)
        .subquery())

    # Find reports, joining against the aforementioned subquery, and eager-load
    # the reports' owners.
    q = (
        Report.dbsession.query(Report, subq)
        .options(joinedload(Report.owner))
        .join(subq, Report.reportid == subq.c.reportid)
        .reset_joinpoint())

    # For each type of report, eagerly load the content reported and the
    # content's owner. Also, keep track of the Login model aliases used for each
    # report type so they can be filtered against later.
    login_aliases = []
    for column_name in _report_types:
        login_alias = aliased(Login)
        login_aliases.append(login_alias)
        q = (
            q
            .outerjoin(getattr(Report, column_name))
            .outerjoin(login_alias)
            .options(contains_eager(column_name + '.owner', alias=login_alias))
            .reset_joinpoint())

    # Filter by report status. form.status can also be 'all', in which case no
    # filter is applied.
    if form.status == 'closed':
        q = q.filter_by(is_closed=True)
    elif form.status == 'open':
        q = q.filter_by(is_closed=False)

    # If filtering by the report's content's owner, iterate over the previously
    # collected Login model aliases to compare against Login.login_name.
    if form.submitter:
        submitter = d.get_sysname(form.submitter)
        q = q.filter(sa.or_(l.login_name == submitter for l in login_aliases))

    # If filtering by violation type, see if the violation is in the array
    # aggregate of unique violations for this report.
    if form.violation and form.violation != '-1':
        q = q.filter(sa.literal(int(form.violation)) == sa.func.any(subq.c.violations))

    q = q.order_by(Report.opened_at.desc())
    return [(report, report_count, map(_convert_violation, violations))
            for report, _, report_count, violations in q.all()]
Пример #24
0
def submissions_(request):
    name = request.matchdict.get('name', request.params.get('name', ''))
    userid = define.get_int(request.params.get('userid'))

    rating = define.get_rating(request.userid)
    otherid = profile.resolve(request.userid, userid, name)
    folderid = define.get_int(request.params.get('folderid')) or None
    backid = request.params.get('backid')
    nextid = request.params.get('nextid')

    if not otherid:
        raise WeasylError("userRecordMissing")
    elif not request.userid and "h" in define.get_config(otherid):
        raise WeasylError('noGuests')

    userprofile = profile.select_profile(otherid, viewer=request.userid)
    has_fullname = userprofile[
        'full_name'] is not None and userprofile['full_name'].strip() != ''
    page_title = u"%s's submissions" % (userprofile['full_name']
                                        if has_fullname else
                                        userprofile['username'], )
    page = define.common_page_start(request.userid, title=page_title)

    url_format = "/submissions/{username}?%s{folderquery}".format(
        username=define.get_sysname(userprofile['username']),
        folderquery="&folderid=%d" % folderid if folderid else "")
    result = pagination.PaginatedResult(submission.select_list,
                                        submission.select_count,
                                        'submitid',
                                        url_format,
                                        request.userid,
                                        rating,
                                        limit=60,
                                        otherid=otherid,
                                        folderid=folderid,
                                        backid=define.get_int(backid),
                                        nextid=define.get_int(nextid),
                                        profile_page_filter=not folderid)

    page.append(
        define.render(
            'user/submissions.html',
            [
                # Profile information
                userprofile,
                # User information
                profile.select_userinfo(otherid, config=userprofile['config']),
                # Relationship
                profile.select_relation(request.userid, otherid),
                # Recent submissions
                result,
                # Folders
                folder.select_list(otherid),
                # Current folder
                folderid,
            ]))

    return Response(define.common_page_end(request.userid, page))
Пример #25
0
def _fake_media_items(i):
    if i.contype == _CONTYPE_CHAR:
        return character.fake_media_items(
            i.id,
            i.userid,
            d.get_sysname(i.username),
            i.settings)
    else:
        return None
Пример #26
0
def submission_(request):
    username = request.matchdict.get('name')
    submitid = request.matchdict.get('submitid')

    form = request.web_input(submitid="", ignore="", anyway="")

    rating = define.get_rating(request.userid)
    submitid = define.get_int(submitid) if submitid else define.get_int(form.submitid)

    extras = {
        "pdf": True,
    }

    if define.user_is_twitterbot():
        extras['twitter_card'] = submission.twitter_card(submitid)

    try:
        item = submission.select_view(
            request.userid, submitid, rating,
            ignore=define.text_bool(form.ignore, True), anyway=form.anyway
        )
    except WeasylError as we:
        we.errorpage_kwargs = extras
        if 'twitter_card' in extras:
            extras['options'] = ['nocache']
        if we.value in ("UserIgnored", "TagBlocked"):
            extras['links'] = [
                ("View Submission", "?ignore=false"),
                ("Return to the Home Page", "/index"),
            ]
        raise

    login = define.get_sysname(item['username'])
    canonical_path = request.route_path('submission_detail_profile', name=login, submitid=submitid, slug=slug_for(item['title']))

    if request.GET.get('anyway'):
        canonical_path += '?anyway=true'

    if login != username:
        raise httpexceptions.HTTPMovedPermanently(location=canonical_path)
    extras["canonical_url"] = canonical_path
    extras["title"] = item["title"]

    page = define.common_page_start(request.userid, **extras)
    page.append(define.render('detail/submission.html', [
        # Myself
        profile.select_myself(request.userid),
        # Submission detail
        item,
        # Subtypes
        macro.MACRO_SUBCAT_LIST,
        # Violations
        [i for i in macro.MACRO_REPORT_VIOLATION if 2000 <= i[0] < 3000],
    ]))

    return Response(define.common_page_end(request.userid, page))
Пример #27
0
 def prepare(info):
     dinfo = dict(info)
     dinfo['localmin'] = convert_currency(info.pricemin, info.pricesettings, currency)
     dinfo['localmax'] = convert_currency(info.pricemax, info.pricesettings, currency)
     if tags:
         terms = ["user:"******"|" + tag for tag in tags]
         dinfo['searchquery'] = "q=" + urllib.quote(u" ".join(terms).encode("utf-8"))
     else:
         dinfo['searchquery'] = ""
     return dinfo
Пример #28
0
    def GET(self, a="", b=None):
        if b is None:
            username, submitid = None, a
        else:
            username, submitid = a, b
        now = time.time()

        form = web.input(submitid="", ignore="", anyway="")

        rating = define.get_rating(self.user_id)
        submitid = define.get_int(submitid) if submitid else define.get_int(form.submitid)

        extras = {
            "pdf": True,
        }

        if define.user_is_twitterbot():
            extras['twitter_card'] = submission.twitter_card(submitid)

        try:
            item = submission.select_view(
                self.user_id, submitid, rating,
                ignore=define.text_bool(form.ignore, True), anyway=form.anyway
            )
        except WeasylError as we:
            we.errorpage_kwargs = extras
            if 'twitter_card' in extras:
                extras['options'] = ['nocache']
            if we.value in ("UserIgnored", "TagBlocked"):
                extras['links'] = [
                    ("View Submission", "?ignore=false"),
                    ("Return to the Home Page", "/index"),
                ]
            raise

        login = define.get_sysname(item['username'])
        if username is not None and login != username:
            raise web.seeother('/~%s/post/%s/%s' % (login, submitid, slug_for(item["title"])))
        extras["canonical_url"] = "/submission/%d/%s" % (submitid, slug_for(item["title"]))
        extras["title"] = item["title"]

        page = define.common_page_start(self.user_id, options=["mediaplayer"], **extras)
        page.append(define.render('detail/submission.html', [
            # Myself
            profile.select_myself(self.user_id),
            # Submission detail
            item,
            # Subtypes
            macro.MACRO_SUBCAT_LIST,
            # Violations
            [i for i in macro.MACRO_REPORT_VIOLATION if 2000 <= i[0] < 3000],
        ]))

        return define.common_page_end(self.user_id, page, now=now)
Пример #29
0
def api_useravatar_(request):
    form = request.web_input(username="")
    userid = profile.resolve_by_login(d.get_sysname(form.username))

    if userid:
        media_items = media.get_user_media(userid)
        return {
            "avatar": d.absolutify_url(media_items['avatar'][0]['display_url']),
        }

    raise WeasylError('userRecordMissing')
Пример #30
0
def ignoreuser_(request):
    form = request.web_input(userid="")
    otherid = define.get_int(form.userid)

    if form.action == "ignore":
        ignoreuser.insert(request.userid, [otherid])
    elif form.action == "unignore":
        ignoreuser.remove(request.userid, [otherid])

    raise HTTPSeeOther(location="/~%s" %
                       (define.get_sysname(define.get_display_name(otherid))))
Пример #31
0
    def POST(self):
        form = web.input(userid="")
        otherid = define.get_int(form.userid)

        if form.action == "ignore":
            if not ignoreuser.check(self.user_id, otherid):
                ignoreuser.insert(self.user_id, otherid)
        elif form.action == "unignore":
            ignoreuser.remove(self.user_id, otherid)

        raise web.seeother("/~%s" % (define.get_sysname(define.get_display_name(otherid))))
Пример #32
0
def ignoreuser_(request):
    form = request.web_input(userid="")
    otherid = define.get_int(form.userid)

    if form.action == "ignore":
        if not ignoreuser.check(request.userid, otherid):
            ignoreuser.insert(request.userid, otherid)
    elif form.action == "unignore":
        ignoreuser.remove(request.userid, otherid)

    raise HTTPSeeOther(location="/~%s" % (define.get_sysname(define.get_display_name(otherid))))
Пример #33
0
def select_char(userid, rating, limit, otherid=None, backid=None, nextid=None, config=None):
    if config is None:
        config = d.get_config(userid)
    query = []
    statement = ["""
        SELECT ch.charid, ch.char_name, ch.rating, fa.unixtime, ch.userid, pr.username, ch.settings
        FROM favorite fa
            INNER JOIN character ch ON fa.targetid = ch.charid
            INNER JOIN profile pr ON ch.userid = pr.userid
        WHERE fa.type = 'f'
            AND ch.settings !~ 'h'
    """]

    if userid:
        # filter own content in SFW mode
        if d.is_sfw_mode():
            statement.append(" AND (ch.rating <= %i)" % (rating,))
        else:
            statement.append(" AND (ch.userid = %i OR ch.rating <= %i)" % (userid, rating))
        statement.append(m.MACRO_FRIENDUSER_CHARACTER % (userid, userid, userid))
        statement.append(m.MACRO_IGNOREUSER % (userid, "ch"))
        statement.append(m.MACRO_BLOCKTAG_CHAR % (userid, userid))
    else:
        statement.append(" AND ch.rating <= %i AND ch.settings !~ 'f'" % (rating,))

    if otherid:
        statement.append(" AND fa.userid = %i" % (otherid,))

    if backid:
        statement.append(" AND fa.unixtime > "
                         "(SELECT unixtime FROM favorite WHERE (userid, targetid, type) = (%i, %i, 'f'))"
                         % (otherid, backid))
    elif nextid:
        statement.append(" AND fa.unixtime < "
                         "(SELECT unixtime FROM favorite WHERE (userid, targetid, type) = (%i, %i, 'f'))"
                         % (otherid, nextid))

    statement.append(" ORDER BY fa.unixtime%s LIMIT %i" % ("" if backid else " DESC", limit))

    from weasyl import character
    query = [{
        "contype": 20,
        "charid": i[0],
        "title": i[1],
        "rating": i[2],
        "unixtime": i[3],
        "userid": i[4],
        "username": i[5],
        "sub_media": character.fake_media_items(i[0], i[4], d.get_sysname(i[5]), i[6]),
    } for i in d.execute("".join(statement))]

    return query[::-1] if backid else query
Пример #34
0
def get_account_verification_token(email=None, username=None):
    email = email and emailer.normalize_address(email)
    username = username and d.get_sysname(username)

    logincreate = d.meta.tables['logincreate']
    statement = select([logincreate.c.token])

    if email:
        statement = statement.where(logincreate.c.email.ilike(email))
    else:
        statement = statement.where(logincreate.c.login_name == username)

    return d.engine.scalar(statement)
Пример #35
0
def get_account_verification_token(email=None, username=None):
    email = email and emailer.normalize_address(email)
    username = username and d.get_sysname(username)

    logincreate = d.meta.tables['logincreate']
    statement = select([logincreate.c.token])

    if email:
        statement = statement.where(logincreate.c.email.ilike(email))
    else:
        statement = statement.where(logincreate.c.login_name == username)

    return d.engine.scalar(statement)
Пример #36
0
def verify(token, ip_address=None):
    lo = d.meta.tables["login"]
    lc = d.meta.tables["logincreate"]
    query = d.engine.execute(lc.select().where(lc.c.token == token)).first()

    # Did the token match a pending login create record?
    if not query:
        raise WeasylError("logincreateRecordMissing")
    elif query.invalid:
        # If the record is explicitly marked as invalid, treat the record as if it doesn't exist.
        raise WeasylError("logincreateRecordMissing")

    db = d.connect()
    with db.begin():
        # Create login record
        userid = db.scalar(
            lo.insert().returning(lo.c.userid), {
                "login_name": d.get_sysname(query.username),
                "last_login": arrow.now(),
                "email": query.email,
                "ip_address_at_signup": ip_address,
            })

        # Create profile records
        db.execute(d.meta.tables["authbcrypt"].insert(), {
            "userid": userid,
            "hashsum": query.hashpass,
        })
        db.execute(
            d.meta.tables["profile"].insert(), {
                "userid": userid,
                "username": query.username,
                "full_name": query.username,
                "unixtime": arrow.now(),
                "config": "kscftj",
            })
        db.execute(d.meta.tables["userinfo"].insert(), {
            "userid": userid,
            "birthday": query.birthday,
        })
        db.execute(d.meta.tables["userstats"].insert(), {
            "userid": userid,
        })
        db.execute(d.meta.tables["welcomecount"].insert(), {
            "userid": userid,
        })

        # Update logincreate records
        db.execute(lc.delete().where(lc.c.token == token))

    d.metric('increment', 'verifiedusers')
Пример #37
0
def followuser_(request):
    form = request.web_input(userid="")
    otherid = define.get_int(form.userid)

    if request.userid == otherid:
        return Response(define.errorpage(request.userid, "You cannot follow yourself."))

    if form.action == "follow":
        if not followuser.check(request.userid, otherid):
            followuser.insert(request.userid, otherid)
    elif form.action == "unfollow":
        followuser.remove(request.userid, otherid)

    raise HTTPSeeOther(location="/~%s" % (define.get_sysname(define.get_display_name(otherid))))
Пример #38
0
 def prepare(info):
     dinfo = dict(info)
     dinfo['localmin'] = convert_currency(info.pricemin, info.pricesettings,
                                          currency)
     dinfo['localmax'] = convert_currency(info.pricemax, info.pricesettings,
                                          currency)
     if tags:
         terms = ["user:"******"|" + tag for tag in tags]
         dinfo['searchquery'] = "q=" + urllib.quote(
             u" ".join(terms).encode("utf-8"))
     else:
         dinfo['searchquery'] = ""
     return dinfo
Пример #39
0
def followuser_(request):
    form = request.web_input(userid="")
    otherid = define.get_int(form.userid)

    if request.userid == otherid:
        raise WeasylError("cannotSelfFollow")

    if form.action == "follow":
        followuser.insert(request.userid, otherid)
    elif form.action == "unfollow":
        followuser.remove(request.userid, otherid)

    raise HTTPSeeOther(location="/~%s" %
                       (define.get_sysname(define.get_display_name(otherid))))
Пример #40
0
def select(**kwargs):
    search = kwargs['search']
    results, next_count, back_count = _find_without_media(**kwargs)

    if search.find == 'submit':
        media.populate_with_submission_media(results)
    elif search.find == 'char':
        for r in results:
            r['sub_media'] = character.fake_media_items(
                r['charid'], r['userid'], d.get_sysname(r['username']), r['settings'])
    elif search.find == 'journal':
        media.populate_with_user_media(results)

    return results, next_count, back_count
Пример #41
0
def journalsbyuser(userid, form):
    if userid not in staff.MODS:
        raise WeasylError("Unexpected")

    results = d.engine.execute("""
        SELECT journalid, title, journal.settings, journal.unixtime, rating,
               profile.username, 30 contype
          FROM journal
               JOIN profile USING (userid)
               JOIN login USING (userid)
         WHERE login_name = %(sysname)s
    """, sysname=d.get_sysname(form.name)).fetchall()

    return map(dict, results)
Пример #42
0
    def POST(self):
        form = web.input(userid="")
        otherid = define.get_int(form.userid)

        if self.user_id == otherid:
            return define.errorpage(self.user_id, "You cannot follow yourself.")

        if form.action == "follow":
            if not followuser.check(self.user_id, otherid):
                followuser.insert(self.user_id, otherid)
        elif form.action == "unfollow":
            followuser.remove(self.user_id, otherid)

        raise web.seeother("/~%s" % (define.get_sysname(define.get_display_name(otherid))))
Пример #43
0
def select(**kwargs):
    search = kwargs['search']
    results, next_count, back_count = _find_without_media(**kwargs)

    if search.find == 'submit':
        media.populate_with_submission_media(results)
    elif search.find == 'char':
        for r in results:
            r['sub_media'] = character.fake_media_items(
                r['charid'], r['userid'], d.get_sysname(r['username']), r['settings'])
    elif search.find == 'journal':
        media.populate_with_user_media(results)

    return results, next_count, back_count
Пример #44
0
def journalsbyuser(userid, form):
    if userid not in staff.MODS:
        raise WeasylError("Unexpected")

    results = d.engine.execute("""
        SELECT journalid, title, journal.settings, journal.unixtime, rating,
               profile.username, 30 contype
          FROM journal
               JOIN profile USING (userid)
               JOIN login USING (userid)
         WHERE login_name = %(sysname)s
    """, sysname=d.get_sysname(form.name)).fetchall()

    return map(dict, results)
Пример #45
0
def verify(token, ip_address=None):
    lo = d.meta.tables["login"]
    lc = d.meta.tables["logincreate"]
    query = d.engine.execute(lc.select().where(lc.c.token == token)).first()

    # Did the token match a pending login create record?
    if not query:
        raise WeasylError("logincreateRecordMissing")
    elif query.invalid:
        # If the record is explicitly marked as invalid, treat the record as if it doesn't exist.
        raise WeasylError("logincreateRecordMissing")

    db = d.connect()
    with db.begin():
        # Create login record
        userid = db.scalar(lo.insert().returning(lo.c.userid), {
            "login_name": d.get_sysname(query.username),
            "last_login": arrow.now(),
            "email": query.email,
            "ip_address_at_signup": ip_address,
        })

        # Create profile records
        db.execute(d.meta.tables["authbcrypt"].insert(), {
            "userid": userid,
            "hashsum": query.hashpass,
        })
        db.execute(d.meta.tables["profile"].insert(), {
            "userid": userid,
            "username": query.username,
            "full_name": query.username,
            "unixtime": arrow.now(),
            "config": "kscftj",
        })
        db.execute(d.meta.tables["userinfo"].insert(), {
            "userid": userid,
            "birthday": query.birthday,
        })
        db.execute(d.meta.tables["userstats"].insert(), {
            "userid": userid,
        })
        db.execute(d.meta.tables["welcomecount"].insert(), {
            "userid": userid,
        })

        # Update logincreate records
        db.execute(lc.delete().where(lc.c.token == token))

    d.metric('increment', 'verifiedusers')
Пример #46
0
def reset(form):
    from weasyl import login

    # Raise an exception if `password` does not enter `passcheck` (indicating
    # that the user mistyped one of the fields) or if `password` does not meet
    # the system's password security requirements
    if form.password != form.passcheck:
        raise WeasylError("passwordMismatch")
    elif not login.password_secure(form.password):
        raise WeasylError("passwordInsecure")

    # Select the user information and record data from the forgotpassword table
    # pertaining to `token`, requiring that the link associated with the record
    # be visited no more than five minutes prior; if the forgotpassword record is
    # not found or does not meet this requirement, raise an exception
    query = d.engine.execute("""
        SELECT lo.userid, lo.login_name, lo.email, fp.link_time, fp.address
        FROM login lo
            INNER JOIN userinfo ui USING (userid)
            INNER JOIN forgotpassword fp USING (userid)
        WHERE fp.token = %(token)s AND fp.link_time > %(cutoff)s
    """,
                             token=form.token,
                             cutoff=d.get_time() - 300).first()

    if not query:
        raise WeasylError("forgotpasswordRecordMissing")

    USERID, USERNAME, EMAIL, LINKTIME, ADDRESS = query

    # Check `username` and `email` against known correct values and raise an
    # exception if there is a mismatch
    if emailer.normalize_address(
            form.email) != emailer.normalize_address(EMAIL):
        raise WeasylError("emailIncorrect")
    elif d.get_sysname(form.username) != USERNAME:
        raise WeasylError("usernameIncorrect")
    elif d.get_address() != ADDRESS:
        raise WeasylError("addressInvalid")

    # Update the authbcrypt table with a new password hash
    d.engine.execute(
        'INSERT INTO authbcrypt (userid, hashsum) VALUES (%(user)s, %(hash)s) '
        'ON CONFLICT (userid) DO UPDATE SET hashsum = %(hash)s',
        user=USERID,
        hash=login.passhash(form.password))

    d.engine.execute("DELETE FROM forgotpassword WHERE token = %(token)s",
                     token=form.token)
Пример #47
0
def followuser_(request):
    form = request.web_input(userid="")
    otherid = define.get_int(form.userid)

    if request.userid == otherid:
        return Response(
            define.errorpage(request.userid, "You cannot follow yourself."))

    if form.action == "follow":
        if not followuser.check(request.userid, otherid):
            followuser.insert(request.userid, otherid)
    elif form.action == "unfollow":
        followuser.remove(request.userid, otherid)

    raise HTTPSeeOther(location="/~%s" %
                       (define.get_sysname(define.get_display_name(otherid))))
Пример #48
0
def reset(form):
    import login

    # Raise an exception if `password` does not enter `passcheck` (indicating
    # that the user mistyped one of the fields) or if `password` does not meet
    # the system's password security requirements
    if form.password != form.passcheck:
        raise WeasylError("passwordMismatch")
    elif not login.password_secure(form.password):
        raise WeasylError("passwordInsecure")

    # Select the user information and record data from the forgotpassword table
    # pertaining to `token`, requiring that the link associated with the record
    # be visited no more than five minutes prior; if the forgotpassword record is
    # not found or does not meet this requirement, raise an exception
    query = d.execute("""
        SELECT lo.userid, lo.login_name, lo.email, fp.link_time, fp.address
        FROM login lo
            INNER JOIN userinfo ui USING (userid)
            INNER JOIN forgotpassword fp USING (userid)
        WHERE fp.token = '%s' AND fp.link_time > %i
    """, [form.token, d.get_time() - 300], options="single")

    if not query:
        raise WeasylError("forgotpasswordRecordMissing")

    USERID, USERNAME, EMAIL, LINKTIME, ADDRESS = query

    # Check `username` and `email` against known correct values and raise an
    # exception if there is a mismatch
    if emailer.normalize_address(form.email) != emailer.normalize_address(EMAIL):
        raise WeasylError("emailIncorrect")
    elif d.get_sysname(form.username) != USERNAME:
        raise WeasylError("usernameIncorrect")
    elif d.get_address() != ADDRESS:
        raise WeasylError("addressInvalid")

    # Update the authbcrypt table with a new password hash
    """ TODO TEMPORARY """
    try:
        d.execute("INSERT INTO authbcrypt VALUES (%i, '')", [USERID])
    except:
        pass

    d.execute("UPDATE authbcrypt SET hashsum = '%s' WHERE userid = %i", [login.passhash(form.password), USERID])

    d.execute("DELETE FROM forgotpassword WHERE token = '%s'", [form.token])
Пример #49
0
def reset(form):
    import login

    # Raise an exception if `password` does not enter `passcheck` (indicating
    # that the user mistyped one of the fields) or if `password` does not meet
    # the system's password security requirements
    if form.password != form.passcheck:
        raise WeasylError("passwordMismatch")
    elif not login.password_secure(form.password):
        raise WeasylError("passwordInsecure")

    # Select the user information and record data from the forgotpassword table
    # pertaining to `token`, requiring that the link associated with the record
    # be visited no more than five minutes prior; if the forgotpassword record is
    # not found or does not meet this requirement, raise an exception
    query = d.execute("""
        SELECT lo.userid, lo.login_name, lo.email, fp.link_time, fp.address
        FROM login lo
            INNER JOIN userinfo ui USING (userid)
            INNER JOIN forgotpassword fp USING (userid)
        WHERE fp.token = '%s' AND fp.link_time > %i
    """, [form.token, d.get_time() - 300], options="single")

    if not query:
        raise WeasylError("forgotpasswordRecordMissing")

    USERID, USERNAME, EMAIL, LINKTIME, ADDRESS = query

    # Check `username` and `email` against known correct values and raise an
    # exception if there is a mismatch
    if emailer.normalize_address(form.email) != emailer.normalize_address(EMAIL):
        raise WeasylError("emailIncorrect")
    elif d.get_sysname(form.username) != USERNAME:
        raise WeasylError("usernameIncorrect")
    elif d.get_address() != ADDRESS:
        raise WeasylError("addressInvalid")

    # Update the authbcrypt table with a new password hash
    """ TODO TEMPORARY """
    try:
        d.execute("INSERT INTO authbcrypt VALUES (%i, '')", [USERID])
    except:
        pass

    d.execute("UPDATE authbcrypt SET hashsum = '%s' WHERE userid = %i", [login.passhash(form.password), USERID])

    d.execute("DELETE FROM forgotpassword WHERE token = '%s'", [form.token])
Пример #50
0
def verify(token):
    lo = d.meta.tables["login"]
    lc = d.meta.tables["logincreate"]
    query = d.engine.execute(lc.select().where(lc.c.token == token)).first()

    if not query:
        raise WeasylError("logincreateRecordMissing")

    db = d.connect()
    with db.begin():
        # Create login record
        userid = db.execute(
            lo.insert().returning(lo.c.userid), {
                "login_name": d.get_sysname(query.username),
                "last_login": arrow.now(),
                "email": query.email,
            }).scalar()

        # Create profile records
        db.execute(d.meta.tables["authbcrypt"].insert(), {
            "userid": userid,
            "hashsum": query.hashpass,
        })
        db.execute(
            d.meta.tables["profile"].insert(), {
                "userid": userid,
                "username": query.username,
                "full_name": query.username,
                "unixtime": arrow.now(),
                "config": "kscftj",
            })
        db.execute(d.meta.tables["userinfo"].insert(), {
            "userid": userid,
            "birthday": query.birthday,
        })
        db.execute(d.meta.tables["userstats"].insert(), {
            "userid": userid,
        })
        db.execute(d.meta.tables["welcomecount"].insert(), {
            "userid": userid,
        })

        # Update logincreate records
        db.execute(lc.delete().where(lc.c.token == token))

    d.metric('increment', 'verifiedusers')
Пример #51
0
def request(form):
    token = security.generate_key(100)
    email = emailer.normalize_address(form.email)
    username = d.get_sysname(form.username)

    # Determine the user associated with `username`; if the user is not found,
    # raise an exception
    user = d.engine.execute(
        "SELECT userid, email FROM login WHERE login_name = %(username)s",
        username=username).first()

    if not user:
        raise WeasylError("loginRecordMissing")

    # Check the user's email address against the provided e-mail address,
    # raising an exception if there is a mismatch
    if email != emailer.normalize_address(user.email):
        raise WeasylError("emailInvalid")

    # Insert a record into the forgotpassword table for the user,
    # or update an existing one
    now = d.get_time()
    address = d.get_address()

    try:
        d.engine.execute(
            "INSERT INTO forgotpassword (userid, token, set_time, address)"
            " VALUES (%(id)s, %(token)s, %(time)s, %(address)s)",
            id=user.userid, token=token, time=now, address=address)
    except IntegrityError:
        # An IntegrityError will probably indicate that a password reset request
        # already exists and that the existing row should be updated. If the update
        # doesn't find anything, though, the original error should be re-raised.
        result = d.engine.execute("""
            UPDATE forgotpassword SET
                token = %(token)s,
                set_time = %(time)s,
                address = %(address)s
            WHERE userid = %(id)s
        """, id=user.userid, token=token, time=now, address=address)

        if result.rowcount != 1:
            raise

    # Generate and send an email to the user containing a password reset link
    emailer.append([email], None, "Weasyl Password Recovery", d.render("email/reset_password.html", [token]))
Пример #52
0
    def GET(self, name=""):
        form = web.input(userid="", name="", backid=None, nextid=None, folderid=None)
        form.name = name if name else form.name
        form.userid = define.get_int(form.userid)

        config = define.get_config(self.user_id)
        rating = define.get_rating(self.user_id)
        otherid = profile.resolve(self.user_id, form.userid, form.name)
        folderid = define.get_int(form.folderid) or None

        if not otherid:
            raise WeasylError("userRecordMissing")
        elif not self.user_id and "h" in define.get_config(otherid):
            return define.errorpage(self.user_id, errorcode.no_guest_access)

        userprofile = profile.select_profile(otherid, images=True, viewer=self.user_id)
        has_fullname = userprofile['full_name'] is not None and userprofile['full_name'].strip() != ''
        page_title = u"%s's submissions" % (userprofile['full_name'] if has_fullname else userprofile['username'],)
        page = define.common_page_start(self.user_id, title=page_title)

        url_format = "/submissions/{username}?%s{folderquery}".format(
                     username=define.get_sysname(userprofile['username']),
                     folderquery="&folderid=%d" % folderid if folderid else "")
        result = pagination.PaginatedResult(
            submission.select_list, submission.select_count, 'submitid', url_format, self.user_id, rating,
            60, otherid=otherid, folderid=folderid, backid=define.get_int(form.backid),
            nextid=define.get_int(form.nextid), config=config, profile_page_filter=not folderid)

        page.append(define.render(template.user_submissions, [
            # Profile information
            userprofile,
            # User information
            profile.select_userinfo(otherid, config=userprofile['config']),
            # Relationship
            profile.select_relation(self.user_id, otherid),
            # Recent submissions
            result,
            # Folders
            folder.select_list(otherid, "sidebar/all"),
            # Current folder
            folderid,
        ]))

        return define.common_page_end(self.user_id, page)
Пример #53
0
def verify(token):
    lo = d.meta.tables["login"]
    lc = d.meta.tables["logincreate"]
    query = d.engine.execute(lc.select().where(lc.c.token == token)).first()

    if not query:
        raise WeasylError("logincreateRecordMissing")

    db = d.connect()
    with db.begin():
        # Create login record
        userid = db.scalar(lo.insert().returning(lo.c.userid), {
            "login_name": d.get_sysname(query.username),
            "last_login": arrow.now(),
            "email": query.email,
        })

        # Create profile records
        db.execute(d.meta.tables["authbcrypt"].insert(), {
            "userid": userid,
            "hashsum": query.hashpass,
        })
        db.execute(d.meta.tables["profile"].insert(), {
            "userid": userid,
            "username": query.username,
            "full_name": query.username,
            "unixtime": arrow.now(),
            "config": "kscftj",
        })
        db.execute(d.meta.tables["userinfo"].insert(), {
            "userid": userid,
            "birthday": query.birthday,
        })
        db.execute(d.meta.tables["userstats"].insert(), {
            "userid": userid,
        })
        db.execute(d.meta.tables["welcomecount"].insert(), {
            "userid": userid,
        })

        # Update logincreate records
        db.execute(lc.delete().where(lc.c.token == token))

    d.metric('increment', 'verifiedusers')
Пример #54
0
    def POST(self):
        form = web.input(userid="")
        otherid = define.get_int(form.userid)

        if self.user_id == otherid:
            return define.errorpage(self.user_id, "You cannot friend yourself.")

        if form.action == "sendfriendrequest":
            if not frienduser.check(self.user_id, otherid) and not frienduser.already_pending(self.user_id, otherid):
                frienduser.request(self.user_id, otherid)
        elif form.action == "withdrawfriendrequest":
            if frienduser.already_pending(self.user_id, otherid):
                frienduser.remove_request(self.user_id, otherid)
        elif form.action == "unfriend":
            frienduser.remove(self.user_id, otherid)

        if form.feature == "pending":
            raise web.seeother("/manage/friends?feature=pending")
        else:  # typical value will be user
            raise web.seeother("/~%s" % (define.get_sysname(define.get_display_name(otherid))))
Пример #55
0
def frienduser_(request):
    form = request.web_input(userid="")
    otherid = define.get_int(form.userid)

    if request.userid == otherid:
        return Response(define.errorpage(request.userid, "You cannot friend yourself."))

    if form.action == "sendfriendrequest":
        if not frienduser.check(request.userid, otherid) and not frienduser.already_pending(request.userid, otherid):
            frienduser.request(request.userid, otherid)
    elif form.action == "withdrawfriendrequest":
        if frienduser.already_pending(request.userid, otherid):
            frienduser.remove_request(request.userid, otherid)
    elif form.action == "unfriend":
        frienduser.remove(request.userid, otherid)

    if form.feature == "pending":
        raise HTTPSeeOther(location="/manage/friends?feature=pending")
    else:  # typical value will be user
        raise HTTPSeeOther(location="/~%s" % (define.get_sysname(define.get_display_name(otherid))))
Пример #56
0
def manageuser(userid, form):
    if userid not in staff.MODS:
        raise WeasylError("Unexpected")

    query = d.execute(
        "SELECT userid, username, config, profile_text, catchphrase FROM profile"
        " WHERE userid = (SELECT userid FROM login WHERE login_name = '%s')",
        [d.get_sysname(form.name)], ["single"])

    if not query:
        raise WeasylError("noUser")

    return {
        "userid": query[0],
        "username": query[1],
        "config": query[2],
        "profile_text": query[3],
        "catchphrase": query[4],
        "user_media": media.get_user_media(query[0]),
        "staff_notes": shout.count(query[0], staffnotes=True),
    }
Пример #57
0
def select_list(userid, rating, limit, otherid=None, backid=None, nextid=None, options=[], config=None):
    statement = ["SELECT ch.charid, ch.char_name, ch.rating, ch.unixtime, ch.userid, pr.username, ch.settings "]
    statement.extend(select_query(userid, rating, otherid, backid, nextid,
                                  options, config))

    statement.append(" ORDER BY ch.charid%s LIMIT %i" % ("" if backid else " DESC", limit))

    query = []
    for i in define.execute("".join(statement)):
        query.append({
            "contype": 20,
            "charid": i[0],
            "title": i[1],
            "rating": i[2],
            "unixtime": i[3],
            "userid": i[4],
            "username": i[5],
            "sub_media": fake_media_items(i[0], i[4], define.get_sysname(i[5]), i[6]),
        })

    return query[::-1] if backid else query