Esempio n. 1
0
def bulk_edit_rating(userid,
                     new_rating,
                     submissions=(),
                     characters=(),
                     journals=()):
    action_string = 'rerated to ' + ratings.CODE_TO_NAME[new_rating]

    with d.engine.begin() as db:
        affected = collections.defaultdict(list)
        copyable = []

        for (tbl, pk, title_col,
             urlpart), ids in zip(_tables,
                                  [submissions, characters, journals]):
            if not ids:
                continue

            join = (tbl.select().where(tbl.c[pk].in_(ids)).where(
                tbl.c.rating != new_rating).with_for_update().alias('join'))

            results = db.execute(tbl.update().where(
                tbl.c[pk] == join.c[pk]).values(rating=new_rating).returning(
                    tbl.c[pk], tbl.c[title_col], tbl.c.userid, join.c.rating))

            for thingid, title, ownerid, original_rating in results:
                item_format = '- (from %s) %%s' % (original_rating.name, )
                affected[ownerid].append(item_format % text.markdown_link(
                    title, '/%s/%s?anyway=true' % (urlpart, thingid)))
                copyable.append(
                    item_format %
                    text.markdown_link(title, '/%s/%s' % (urlpart, thingid)))

        now = arrow.utcnow()
        values = []
        for target, target_affected in affected.iteritems():
            staff_note = '## The following items were %s:\n\n%s' % (
                action_string, '\n'.join(target_affected))
            values.append({
                'userid': userid,
                'target_user': target,
                'unixtime': now,
                'settings': 's',
                'content': staff_note,
            })
        if values:
            db.execute(d.meta.tables['comments'].insert().values(values))

    return 'Affected items (%s): \n\n%s' % (action_string, '\n'.join(copyable))
Esempio n. 2
0
def edit(userid, journal, friends_only=False):
    if not journal.title:
        raise WeasylError("titleInvalid")
    elif not journal.content:
        raise WeasylError("contentInvalid")
    elif not journal.rating:
        raise WeasylError("ratingInvalid")
    profile.check_user_rating_allowed(userid, journal.rating)

    query = d.execute("SELECT userid, settings FROM journal WHERE journalid = %i", [journal.journalid], options="single")

    if not query or "h" in query[1]:
        raise WeasylError("Unexpected")
    elif userid != query[0] and userid not in staff.MODS:
        raise WeasylError("InsufficientPermissions")

    settings = [query[1].replace("f", "")]
    settings.append("f" if friends_only else "")
    settings = "".join(settings)

    if "f" in settings:
        welcome.journal_remove(journal.journalid)

    d.execute("UPDATE journal SET (title, content, rating, settings) = ('%s', '%s', %i, '%s') WHERE journalid = %i",
              [journal.title, journal.content, journal.rating.code, settings, journal.journalid])

    if userid != query[0]:
        moderation.note_about(
            userid, query[0], 'The following journal was edited:',
            '- ' + text.markdown_link(journal.title, '/journal/%s?anyway=true' % (journal.journalid,)))
Esempio n. 3
0
def bulk_edit_rating(userid, new_rating, submissions=(), characters=(), journals=()):
    action_string = 'rerated to ' + ratings.CODE_TO_NAME[new_rating]

    with d.engine.begin() as db:
        affected = collections.defaultdict(list)
        copyable = []

        for (tbl, pk, title_col, urlpart), ids in zip(_tables, [submissions, characters, journals]):
            if not ids:
                continue

            join = (
                tbl.select()
                .where(tbl.c[pk].in_(ids))
                .where(tbl.c.rating != new_rating)
                .with_for_update()
                .alias('join'))

            results = db.execute(
                tbl.update()
                .where(tbl.c[pk] == join.c[pk])
                .values(rating=new_rating)
                .returning(tbl.c[pk], tbl.c[title_col], tbl.c.userid, join.c.rating))

            for thingid, title, ownerid, original_rating in results:
                item_format = '- (from %s) %%s' % (original_rating.name,)
                affected[ownerid].append(item_format % text.markdown_link(title, '/%s/%s?anyway=true' % (urlpart, thingid)))
                copyable.append(item_format % text.markdown_link(title, '/%s/%s' % (urlpart, thingid)))

        now = arrow.utcnow()
        values = []
        for target, target_affected in affected.iteritems():
            staff_note = '## The following items were %s:\n\n%s' % (action_string, '\n'.join(target_affected))
            values.append({
                'userid': userid,
                'target_user': target,
                'unixtime': now,
                'settings': 's',
                'content': staff_note,
            })
        if values:
            db.execute(d.meta.tables['comments'].insert().values(values))

    return 'Affected items (%s): \n\n%s' % (action_string, '\n'.join(copyable))
Esempio n. 4
0
def removethumbnail(userid, submitid):
    sub = Submission.query.get(submitid)
    thumbnail.clear_thumbnail(userid, submitid)
    # Thumbnails may be cached on the front page, so invalidate that cache.
    index.recent_submissions.invalidate()
    index.template_fields.invalidate(userid)
    otherid = sub.owner.userid
    title = sub.title
    note_about(userid, otherid, 'Thumbnail was removed for ' +
               text.markdown_link(title, '/submission/%s?anyway=true' % submitid))
Esempio n. 5
0
def removecoverart(userid, submitid):
    sub = Submission.query.get(submitid)
    if not sub.cover_media:
        raise WeasylError("noCover")
    submission.reupload_cover(userid, submitid, None)
    otherid = sub.owner.userid
    title = sub.title

    note_about(userid, otherid, 'Cover was removed for ' +
               text.markdown_link(title, '/submission/%s?anyway=true' % submitid))
Esempio n. 6
0
def removethumbnail(userid, submitid):
    sub = Submission.query.get(submitid)
    thumbnail.clear_thumbnail(userid, submitid)
    # Thumbnails may be cached on the front page, so invalidate that cache.
    index.recent_submissions.invalidate()
    index.template_fields.invalidate(userid)
    otherid = sub.owner.userid
    title = sub.title
    note_about(userid, otherid, 'Thumbnail was removed for ' +
               text.markdown_link(title, '/submission/%s?anyway=true' % submitid))
Esempio n. 7
0
def removecoverart(userid, submitid):
    sub = Submission.query.get(submitid)
    if not sub.cover_media:
        raise WeasylError("noCover")
    submission.reupload_cover(userid, submitid, None)
    otherid = sub.owner.userid
    title = sub.title

    note_about(userid, otherid, 'Cover was removed for ' +
               text.markdown_link(title, '/submission/%s?anyway=true' % submitid))
Esempio n. 8
0
def edit(userid, character, friends_only):
    query = define.execute(
        "SELECT userid, settings FROM character WHERE charid = %i",
        [character.charid],
        options="single")

    if not query or "h" in query[1]:
        raise WeasylError("Unexpected")
    elif userid != query[0] and userid not in staff.MODS:
        raise WeasylError("InsufficientPermissions")
    elif not character.char_name:
        raise WeasylError("characterNameInvalid")
    elif not character.rating:
        raise WeasylError("Unexpected")
    profile.check_user_rating_allowed(userid, character.rating)

    # Assign settings
    settings = [query[1].replace("f", "")]
    settings.append("f" if friends_only else "")
    settings = "".join(settings)

    if "f" in settings:
        welcome.character_remove(character.charid)

    define.execute(
        """
            UPDATE character
            SET (char_name, age, gender, height, weight, species, content, rating, settings) =
                ('%s', '%s', '%s', '%s', '%s', '%s', '%s', %i, '%s')
            WHERE charid = %i
        """, [
            character.char_name, character.age, character.gender,
            character.height, character.weight, character.species,
            character.content, character.rating.code, settings,
            character.charid
        ])

    if userid != query[0]:
        from weasyl import moderation
        moderation.note_about(
            userid, query[0], 'The following character was edited:',
            '- ' + text.markdown_link(
                character.char_name, '/character/%s?anyway=true' %
                (character.charid, )))
Esempio n. 9
0
def edit(userid, journal, friends_only=False):
    if not journal.title:
        raise WeasylError("titleInvalid")
    elif not journal.content:
        raise WeasylError("contentInvalid")
    elif not journal.rating:
        raise WeasylError("ratingInvalid")
    profile.check_user_rating_allowed(userid, journal.rating)

    query = d.engine.execute(
        "SELECT userid, settings FROM journal WHERE journalid = %(id)s",
        id=journal.journalid,
    ).first()

    if not query or "h" in query[1]:
        raise WeasylError("Unexpected")
    elif userid != query[0] and userid not in staff.MODS:
        raise WeasylError("InsufficientPermissions")

    settings = query[1].replace("f", "")

    if friends_only:
        settings += "f"
        welcome.journal_remove(journal.journalid)

    jo = d.meta.tables['journal']
    d.engine.execute(
        jo.update().where(jo.c.journalid == journal.journalid).values({
            'title':
            journal.title,
            'content':
            journal.content,
            'rating':
            journal.rating,
            'settings':
            settings,
        }))

    if userid != query[0]:
        moderation.note_about(
            userid, query[0], 'The following journal was edited:',
            '- ' + text.markdown_link(
                journal.title, '/journal/%s?anyway=true' %
                (journal.journalid, )))
Esempio n. 10
0
def edit(userid, character, friends_only):
    query = define.engine.execute("SELECT userid, settings FROM character WHERE charid = %(id)s",
                                  id=character.charid).first()

    if not query or "h" in query[1]:
        raise WeasylError("Unexpected")
    elif userid != query[0] and userid not in staff.MODS:
        raise WeasylError("InsufficientPermissions")
    elif not character.char_name:
        raise WeasylError("characterNameInvalid")
    elif not character.rating:
        raise WeasylError("Unexpected")
    profile.check_user_rating_allowed(userid, character.rating)

    # Assign settings
    settings = query[1].replace("f", "")

    if friends_only:
        settings += "f"
        welcome.character_remove(character.charid)

    ch = define.meta.tables["character"]
    define.engine.execute(
        ch.update()
        .where(ch.c.charid == character.charid)
        .values({
            'char_name': character.char_name,
            'age': character.age,
            'gender': character.gender,
            'height': character.height,
            'weight': character.weight,
            'species': character.species,
            'content': character.content,
            'rating': character.rating,
            'settings': settings,
        })
    )

    if userid != query[0]:
        from weasyl import moderation
        moderation.note_about(
            userid, query[0], 'The following character was edited:',
            '- ' + text.markdown_link(character.char_name, '/character/%s?anyway=true' % (character.charid,)))
Esempio n. 11
0
def edit(userid, journal, friends_only=False):
    if not journal.title:
        raise WeasylError("titleInvalid")
    elif not journal.content:
        raise WeasylError("contentInvalid")
    elif not journal.rating:
        raise WeasylError("ratingInvalid")
    profile.check_user_rating_allowed(userid, journal.rating)

    query = d.execute(
        "SELECT userid, settings FROM journal WHERE journalid = %i",
        [journal.journalid],
        options="single")

    if not query or "h" in query[1]:
        raise WeasylError("Unexpected")
    elif userid != query[0] and userid not in staff.MODS:
        raise WeasylError("InsufficientPermissions")

    settings = [query[1].replace("f", "")]
    settings.append("f" if friends_only else "")
    settings = "".join(settings)

    if "f" in settings:
        welcome.journal_remove(journal.journalid)

    # TODO(kailys): use ORM
    d.execute(
        "UPDATE journal SET (title, rating, settings) = ('%s', %i, '%s') WHERE journalid = %i",
        [journal.title, journal.rating.code, settings, journal.journalid])

    # Write journal file
    files.write(
        files.make_resource(userid, journal.journalid, "journal/submit"),
        journal.content)

    if userid != query[0]:
        from weasyl import moderation
        moderation.note_about(
            userid, query[0], 'The following journal was edited:',
            '- ' + text.markdown_link(
                journal.title, '/journal/%s?anyway=true' %
                (journal.journalid, )))
Esempio n. 12
0
def edit(userid, character, friends_only):
    query = define.execute("SELECT userid, settings FROM character WHERE charid = %i",
                           [character.charid], options="single")

    if not query or "h" in query[1]:
        raise WeasylError("Unexpected")
    elif userid != query[0] and userid not in staff.MODS:
        raise WeasylError("InsufficientPermissions")
    elif not character.char_name:
        raise WeasylError("characterNameInvalid")
    elif not character.rating:
        raise WeasylError("Unexpected")
    profile.check_user_rating_allowed(userid, character.rating)

    # Assign settings
    settings = [query[1].replace("f", "")]
    settings.append("f" if friends_only else "")
    settings = "".join(settings)

    if "f" in settings:
        welcome.character_remove(character.charid)

    define.execute(
        """
            UPDATE character
            SET (char_name, age, gender, height, weight, species, content, rating, settings) =
                ('%s', '%s', '%s', '%s', '%s', '%s', '%s', %i, '%s')
            WHERE charid = %i
        """,
        [character.char_name, character.age, character.gender, character.height, character.weight, character.species,
         character.content, character.rating.code, settings, character.charid])

    if userid != query[0]:
        from weasyl import moderation
        moderation.note_about(
            userid, query[0], 'The following character was edited:',
            '- ' + text.markdown_link(character.char_name, '/character/%s?anyway=true' % (character.charid,)))
Esempio n. 13
0
def edit(userid,
         submission,
         embedlink=None,
         friends_only=False,
         critique=False):
    query = d.execute(
        "SELECT userid, subtype, settings FROM submission WHERE submitid = %i",
        [submission.submitid], ["single"])

    if not query or "h" in query[2]:
        raise WeasylError("Unexpected")
    elif "a" in query[2] and userid not in staff.MODS:
        raise WeasylError("AdminLocked")
    elif userid != query[0] and userid not in staff.MODS:
        raise WeasylError("InsufficientPermissions")
    elif not submission.title:
        raise WeasylError("titleInvalid")
    elif not submission.rating:
        raise WeasylError("Unexpected")
    elif not folder.check(query[0], submission.folderid):
        raise WeasylError("Unexpected")
    elif submission.subtype / 1000 != query[1] / 1000:
        raise WeasylError("Unexpected")
    elif 'v' in query[2] and not embed.check_valid(embedlink):
        raise WeasylError("embedlinkInvalid")
    elif 'D' in query[2]:
        check_google_doc_embed_data(embedlink)
    profile.check_user_rating_allowed(userid, submission.rating)

    # Assign settings
    settings = [query[2].replace("f", "").replace("q", "")]
    settings.append("f" if friends_only else "")
    settings.append("q" if critique else "")
    settings = "".join(settings)

    if "v" in settings:
        submission.content = "%s\n%s" % (embedlink, submission.content)

    if "f" in settings:
        welcome.submission_became_friends_only(submission.submitid, userid)

    # TODO(kailys): maintain ORM object
    db = d.connect()
    su = d.meta.tables['submission']
    q = (su.update().values(
        folderid=submission.folderid,
        title=submission.title,
        content=submission.content,
        subtype=submission.subtype,
        rating=submission.rating,
        settings=settings,
    ).where(su.c.submitid == submission.submitid))
    db.execute(q)

    if 'D' in settings:
        db = d.connect()
        gde = d.meta.tables['google_doc_embeds']
        q = (gde.update().values(embed_url=embedlink).where(
            gde.c.submitid == submission.submitid))
        db.execute(q)

    if userid != query[0]:
        from weasyl import moderation
        moderation.note_about(
            userid, query[0], 'The following submission was edited:',
            '- ' + text.markdown_link(
                submission.title, '/submission/%s?anyway=true' %
                (submission.submitid, )))
Esempio n. 14
0
def bulk_edit(userid, action, submissions=(), characters=(), journals=()):
    if not submissions and not characters and not journals or action == 'null':
        return 'Nothing to do.'

    if action == 'show':
        # Unhide (show/make visible) a submission
        def action(tbl):
            return (
                tbl.update()
                .values(settings=sa.func.replace(tbl.c.settings, 'h', ''))
                .where(tbl.c.settings.op('~')('h')))
        action_string = 'unhidden'
        provide_link = True

    elif action == 'hide':
        # Hide a submission from public view
        def action(tbl):
            return (
                tbl.update()
                .values(settings=tbl.c.settings.op('||')('h'))
                .where(tbl.c.settings.op('!~')('h')))
        action_string = 'hidden'
        # There's no value in giving the user a link to the submission as they
        # won't be able to see it.
        provide_link = False

    elif action.startswith('rate-'):
        # Re-rate a submission
        _, _, rating = action.partition('-')
        rating = int(rating)

        def action(tbl):
            return (
                tbl.update()
                .values(rating=rating)
                .where(tbl.c.rating != rating))

        action_string = 'rerated ' + ratings.CODE_TO_NAME[rating]
        provide_link = True

    elif action == 'clearcritique':
        # Clear the "critique requested" flag
        def action(tbl):
            return (
                tbl.update()
                .values(settings=sa.func.replace(tbl.c.settings, 'q', ''))
                .where(tbl.c.settings.op('~')('q')))
        action_string = 'unmarked as "critique requested"'
        provide_link = True

    elif action == 'setcritique':
        # Set the "critique requested" flag
        def action(tbl):
            return (
                tbl.update()
                .values(settings=tbl.c.settings.op('||')('q'))
                .where(tbl.c.settings.op('!~')('q')))
        action_string = 'marked as "critique requested"'
        provide_link = True

    else:
        raise WeasylError('Unexpected')

    db = d.connect()
    affected = collections.defaultdict(list)
    copyable = []
    for (tbl, col, title_col, urlpart), values in zip(_tables, [submissions, characters, journals]):
        if values:
            results = db.execute(
                action(tbl)
                .where(tbl.c[col].in_(values))
                .returning(tbl.c[col], tbl.c[title_col], tbl.c.userid))
            for thingid, title, ownerid in results:
                affected[ownerid].append('- ' + text.markdown_link(title, '/%s/%s?anyway=true' % (urlpart, thingid)))
                if provide_link:
                    copyable.append('- ' + text.markdown_link(title, '/%s/%s' % (urlpart, thingid)))
                else:
                    copyable.append('- %s' % (title,))

    now = arrow.utcnow()
    values = []
    for target, target_affected in affected.iteritems():
        staff_note = '## The following items were %s:\n\n%s' % (action_string, '\n'.join(target_affected))
        values.append({
            'userid': userid,
            'target_user': target,
            'unixtime': now,
            'settings': 's',
            'content': staff_note,
        })
    if values:
        db.execute(d.meta.tables['comments'].insert().values(values))

    return 'Affected items (%s): \n\n%s' % (action_string, '\n'.join(copyable))
Esempio n. 15
0
def bulk_edit(userid, action, submissions=(), characters=(), journals=()):
    if not submissions and not characters and not journals or action == 'null':
        return 'Nothing to do.'

    if action == 'show':
        # Unhide (show/make visible) a submission
        def action(tbl):
            return (
                tbl.update()
                .values(settings=sa.func.replace(tbl.c.settings, 'h', ''))
                .where(tbl.c.settings.op('~')('h')))
        action_string = 'unhidden'
        provide_link = True

    elif action == 'hide':
        # Hide a submission from public view
        def action(tbl):
            return (
                tbl.update()
                .values(settings=tbl.c.settings.op('||')('h'))
                .where(tbl.c.settings.op('!~')('h')))
        action_string = 'hidden'
        # There's no value in giving the user a link to the submission as they
        # won't be able to see it.
        provide_link = False

    elif action.startswith('rate-'):
        # Re-rate a submission
        _, _, rating = action.partition('-')
        rating = int(rating)

        return bulk_edit_rating(userid, rating, submissions, characters, journals)

    elif action == 'clearcritique':
        # Clear the "critique requested" flag
        def action(tbl):
            return (
                tbl.update()
                .values(settings=sa.func.replace(tbl.c.settings, 'q', ''))
                .where(tbl.c.settings.op('~')('q')))
        action_string = 'unmarked as "critique requested"'
        provide_link = True

    elif action == 'setcritique':
        # Set the "critique requested" flag
        def action(tbl):
            return (
                tbl.update()
                .values(settings=tbl.c.settings.op('||')('q'))
                .where(tbl.c.settings.op('!~')('q')))
        action_string = 'marked as "critique requested"'
        provide_link = True

    else:
        raise WeasylError('Unexpected')

    db = d.connect()
    affected = collections.defaultdict(list)
    copyable = []
    for (tbl, col, title_col, urlpart), values in zip(_tables, [submissions, characters, journals]):
        if values:
            results = db.execute(
                action(tbl)
                .where(tbl.c[col].in_(values))
                .returning(tbl.c[col], tbl.c[title_col], tbl.c.userid))
            for thingid, title, ownerid in results:
                affected[ownerid].append('- ' + text.markdown_link(title, '/%s/%s?anyway=true' % (urlpart, thingid)))
                if provide_link:
                    copyable.append('- ' + text.markdown_link(title, '/%s/%s' % (urlpart, thingid)))
                else:
                    copyable.append('- %s' % (title,))

    now = arrow.utcnow()
    values = []
    for target, target_affected in affected.items():
        staff_note = '## The following items were %s:\n\n%s' % (action_string, '\n'.join(target_affected))
        values.append({
            'userid': userid,
            'target_user': target,
            'unixtime': now,
            'settings': 's',
            'content': staff_note,
        })
    if values:
        db.execute(d.meta.tables['comments'].insert().values(values))

    return 'Affected items (%s): \n\n%s' % (action_string, '\n'.join(copyable))
Esempio n. 16
0
def edit(userid, submission, embedlink=None, friends_only=False, critique=False):
    query = d.execute(
        "SELECT userid, subtype, settings FROM submission WHERE submitid = %i",
        [submission.submitid], ["single"])

    if not query or "h" in query[2]:
        raise WeasylError("Unexpected")
    elif "a" in query[2] and userid not in staff.MODS:
        raise WeasylError("AdminLocked")
    elif userid != query[0] and userid not in staff.MODS:
        raise WeasylError("InsufficientPermissions")
    elif not submission.title:
        raise WeasylError("titleInvalid")
    elif not submission.rating:
        raise WeasylError("Unexpected")
    elif not folder.check(query[0], submission.folderid):
        raise WeasylError("Unexpected")
    elif submission.subtype / 1000 != query[1] / 1000:
        raise WeasylError("Unexpected")
    elif 'v' in query[2] and not embed.check_valid(embedlink):
        raise WeasylError("embedlinkInvalid")
    elif 'D' in query[2]:
        check_google_doc_embed_data(embedlink)
    profile.check_user_rating_allowed(userid, submission.rating)

    # Assign settings
    settings = [query[2].replace("f", "").replace("q", "")]
    settings.append("f" if friends_only else "")
    settings.append("q" if critique else "")
    settings = "".join(settings)

    if "v" in settings:
        submission.content = "%s\n%s" % (embedlink, submission.content)

    if "f" in settings:
        welcome.submission_became_friends_only(submission.submitid, userid)

    # TODO(kailys): maintain ORM object
    db = d.connect()
    su = d.meta.tables['submission']
    q = (
        su.update()
        .values(
            folderid=submission.folderid,
            title=submission.title,
            content=submission.content,
            subtype=submission.subtype,
            rating=submission.rating,
            settings=settings,
        )
        .where(su.c.submitid == submission.submitid))
    db.execute(q)

    if 'D' in settings:
        db = d.connect()
        gde = d.meta.tables['google_doc_embeds']
        q = (gde.update()
             .values(embed_url=embedlink)
             .where(gde.c.submitid == submission.submitid))
        db.execute(q)

    if userid != query[0]:
        from weasyl import moderation
        moderation.note_about(
            userid, query[0], 'The following submission was edited:',
            '- ' + text.markdown_link(submission.title, '/submission/%s?anyway=true' % (submission.submitid,)))
Esempio n. 17
0
def test_markdown_link(target, expected):
    assert markdown_link(*target) == expected
Esempio n. 18
0
def test_markdown_link(target, expected):
    assert markdown_link(*target) == expected