Esempio n. 1
0
def finduser(userid, form):
    form.userid = d.get_int(form.userid)
    lo = d.meta.tables['login']
    sh = d.meta.tables['comments']
    q = d.sa.select([
        lo.c.userid,
        lo.c.login_name,
        lo.c.email,
        (d.sa.select([d.sa.func.count()])
         .select_from(sh)
         .where(sh.c.target_user == lo.c.userid)
         .where(sh.c.settings.op('~')('s'))).label('staff_notes'),
    ])

    if form.userid:
        q = q.where(lo.c.userid == form.userid)
    elif form.username:
        q = q.where(lo.c.login_name.op('~')(form.username))
    elif form.email:
        q = q.where(d.sa.or_(
            lo.c.email.op('~')(form.email),
            lo.c.email.op('ilike')('%%%s%%' % form.email),
        ))
    else:
        return []

    q = q.limit(100).order_by(lo.c.login_name.asc())
    db = d.connect()
    return db.execute(q)
Esempio n. 2
0
def is_hidden(submitid):
    db = d.connect()
    su = d.meta.tables['submission']
    q = d.sa.select([su.c.settings.op('~')('h')
                     ]).where(su.c.submitid == submitid)
    results = db.execute(q).fetchall()
    return bool(results and results[0][0])
Esempio n. 3
0
def finduser(userid, form):
    form.userid = d.get_int(form.userid)
    lo = d.meta.tables['login']
    sh = d.meta.tables['comments']
    q = d.sa.select([
        lo.c.userid,
        lo.c.login_name,
        lo.c.email,
        (d.sa.select([
            d.sa.func.count()
        ]).select_from(sh).where(sh.c.target_user == lo.c.userid).where(
            sh.c.settings.op('~')('s'))).label('staff_notes'),
    ])

    if form.userid:
        q = q.where(lo.c.userid == form.userid)
    elif form.username:
        q = q.where(lo.c.login_name.op('~')(form.username))
    elif form.email:
        q = q.where(
            d.sa.or_(
                lo.c.email.op('~')(form.email),
                lo.c.email.op('ilike')('%%%s%%' % form.email),
            ))
    else:
        return []

    q = q.limit(100).order_by(lo.c.login_name.asc())
    db = d.connect()
    return db.execute(q)
Esempio n. 4
0
def check_for_duplicate_media(userid, mediaid):
    db = d.connect()
    q = (db.query(orm.Submission).filter_by(
        userid=userid, is_hidden=False).join(
            orm.SubmissionMediaLink).filter_by(mediaid=mediaid,
                                               link_type='submission'))
    if q.first():
        raise WeasylError('duplicateSubmission')
Esempio n. 5
0
def edit_preferences(userid,
                     timezone=None,
                     preferences=None,
                     jsonb_settings=None):
    """
    Apply changes to stored preferences for a given user.
    :param userid: The userid to apply changes to
    :param timezone: (optional) new Timezone to set for user
    :param preferences: (optional) old-style char preferences, overwrites all previous settings
    :param jsonb_settings: (optional) JSON preferences, overwrites all previous settings
    :return: None
    """
    config = d.get_config(userid)

    tooyoung = False
    if preferences is not None:
        tooyoung |= get_user_age(userid) < preferences.rating.minimum_age
    if jsonb_settings is not None:
        sfwrating = jsonb_settings.max_sfw_rating
        sfwrating = ratings.CODE_MAP.get(sfwrating, ratings.GENERAL)
        tooyoung |= get_user_age(userid) < sfwrating.minimum_age

    if tooyoung:
        raise WeasylError("birthdayInsufficient")
    if timezone is not None and timezone not in pytz.all_timezones:
        raise WeasylError('invalidTimezone')

    db = d.connect()
    updates = {}
    if preferences is not None:
        # update legacy preferences
        # clear out the option codes that are being replaced.
        for i in Config.all_option_codes:
            config = config.replace(i, "")
        config_str = config + preferences.to_code()
        updates['config'] = config_str
        d._get_config.invalidate(userid)
    if jsonb_settings is not None:
        # update jsonb preferences
        updates['jsonb_settings'] = jsonb_settings.get_raw()
        d._get_profile_settings.invalidate(userid)

    d.engine.execute(
        tables.profile.update().where(tables.profile.c.userid == userid),
        updates)

    # update TZ
    if timezone is not None:
        tz = db.query(orm.UserTimezone).get(userid)
        if tz is None:
            tz = orm.UserTimezone(userid=userid)
            db.add(tz)
        tz.timezone = timezone
        db.flush()
        tz.cache()
    else:
        db.flush()
Esempio n. 6
0
def check_for_duplicate_media(userid, mediaid):
    db = d.connect()
    q = (
        db.query(orm.Submission)
        .filter_by(userid=userid, is_hidden=False)
        .join(orm.SubmissionMediaLink)
        .filter_by(mediaid=mediaid, link_type='submission'))
    if q.first():
        raise WeasylError('duplicateSubmission')
Esempio n. 7
0
def edit_preferences(userid, timezone=None,
                     preferences=None, jsonb_settings=None):
    """
    Apply changes to stored preferences for a given user.
    :param userid: The userid to apply changes to
    :param timezone: (optional) new Timezone to set for user
    :param preferences: (optional) old-style char preferences, overwrites all previous settings
    :param jsonb_settings: (optional) JSON preferences, overwrites all previous settings
    :return: None
    """
    config = d.get_config(userid)

    tooyoung = False
    if preferences is not None:
        tooyoung |= get_user_age(userid) < preferences.rating.minimum_age
    if jsonb_settings is not None:
        sfwrating = jsonb_settings.max_sfw_rating
        sfwrating = ratings.CODE_MAP.get(sfwrating, ratings.GENERAL)
        tooyoung |= get_user_age(userid) < sfwrating.minimum_age

    if tooyoung:
        raise WeasylError("birthdayInsufficient")
    if timezone is not None and timezone not in pytz.all_timezones:
        raise WeasylError('invalidTimezone')

    db = d.connect()
    updates = {}
    if preferences is not None:
        # update legacy preferences
        # clear out the option codes that are being replaced.
        for i in Config.all_option_codes:
            config = config.replace(i, "")
        config_str = config + preferences.to_code()
        updates['config'] = config_str
        d._get_config.invalidate(userid)
    if jsonb_settings is not None:
        # update jsonb preferences
        updates['jsonb_settings'] = jsonb_settings.get_raw()
        d._get_profile_settings.invalidate(userid)

    d.engine.execute(
        tables.profile.update().where(tables.profile.c.userid == userid),
        updates
    )

    # update TZ
    if timezone is not None:
        tz = db.query(orm.UserTimezone).get(userid)
        if tz is None:
            tz = orm.UserTimezone(userid=userid)
            db.add(tz)
        tz.timezone = timezone
        db.flush()
        tz.cache()
    else:
        db.flush()
Esempio n. 8
0
def select_friends(userid,
                   otherid,
                   limit=None,
                   backid=None,
                   nextid=None,
                   choose=False):
    """
    Return accepted friends. If `choose` is an integer, results will be ordered
    randomly.
    """
    fr = d.meta.tables['frienduser']
    pr = d.meta.tables['profile']
    iu = d.meta.tables['ignoreuser']

    friends = d.sa.union(
        (d.sa.select([fr.c.otherid, pr.c.username, pr.c.config]).select_from(
            fr.join(pr, fr.c.otherid == pr.c.userid)).where(
                d.sa.and_(fr.c.userid == otherid,
                          fr.c.settings.op('!~')('p')))),
        (d.sa.select([fr.c.userid, pr.c.username, pr.c.config]).select_from(
            fr.join(pr, fr.c.userid == pr.c.userid)).where(
                d.sa.and_(fr.c.otherid == otherid,
                          fr.c.settings.op('!~')('p')))))
    friends = friends.alias('friends')

    query = d.sa.select(friends.c)

    if userid:
        query = query.where(~friends.c.otherid.in_(
            d.sa.select([iu.c.otherid]).where(iu.c.userid == userid)))
    if backid:
        query = query.where(
            friends.c.username < d.sa.select([pr.c.username]).where(
                pr.c.userid == backid))
    elif nextid:
        query = query.where(
            friends.c.username > d.sa.select([pr.c.username]).where(
                pr.c.userid == nextid))

    if choose:
        query = query.order_by('RANDOM()')
    else:
        query = query.order_by(
            friends.c.username.desc() if backid else friends.c.username.asc())
        query = query.limit(limit)

    db = d.connect()
    query = [{
        "userid": r.otherid,
        "username": r.username,
    } for r in db.execute(query)]

    ret = (d.get_random_set(query, choose)
           if choose else query[::-1] if backid else query)
    media.populate_with_user_media(ret)
    return ret
Esempio n. 9
0
def editprofiletext(userid, otherid, content):
    pr = d.meta.tables['profile']
    db = d.connect()
    condition = pr.c.userid == otherid
    previous_profile = db.scalar(sa.select([pr.c.profile_text]).where(condition))
    db.execute(pr.update().where(condition).values(profile_text=content))
    note_about(
        userid, otherid,
        'Profile text replaced with:',
        '%s\n\n## Profile text was:\n\n%s' % (content, previous_profile))
Esempio n. 10
0
def editprofiletext(userid, otherid, content):
    pr = d.meta.tables['profile']
    db = d.connect()
    condition = pr.c.userid == otherid
    previous_profile = db.scalar(
        sa.select([pr.c.profile_text]).where(condition))
    db.execute(pr.update().where(condition).values(profile_text=content))
    note_about(
        userid, otherid, 'Profile text replaced with:',
        '%s\n\n## Profile text was:\n\n%s' % (content, previous_profile))
Esempio n. 11
0
def editcatchphrase(userid, otherid, content):
    pr = d.meta.tables['profile']
    db = d.connect()
    condition = pr.c.userid == otherid
    previous_catchphrase = db.scalar(
        sa.select([pr.c.catchphrase]).where(condition))
    db.execute(pr.update().where(condition).values(catchphrase=content))
    note_about(
        userid, otherid, 'Catchphrase replaced with:',
        '%s\n\n## Catchphrase was:\n\n%s' % (content, previous_catchphrase))
Esempio n. 12
0
def editcatchphrase(userid, otherid, content):
    pr = d.meta.tables['profile']
    db = d.connect()
    condition = pr.c.userid == otherid
    previous_catchphrase = db.scalar(sa.select([pr.c.catchphrase]).where(condition))
    db.execute(pr.update().where(condition).values(catchphrase=content))
    note_about(
        userid, otherid,
        'Catchphrase replaced with:',
        '%s\n\n## Catchphrase was:\n\n%s' % (content, previous_catchphrase))
Esempio n. 13
0
def note_about(userid, target_user, title, message=None):
    staff_note = '## ' + title
    if message:
        staff_note = '%s\n\n%s' % (staff_note, message)

    db = d.connect()
    db.execute(
        d.meta.tables['comments'].insert()
        .values(
            userid=userid, target_user=target_user, unixtime=arrow.utcnow(),
            settings='s', content=staff_note,
        ))
Esempio n. 14
0
def select_view_api(userid, submitid, anyway=False, increment_views=False):
    rating = d.get_rating(userid)
    db = d.connect()
    sub = db.query(orm.Submission).get(submitid)
    if sub is None or 'hidden' in sub.settings:
        raise WeasylError("submissionRecordMissing")
    sub_rating = sub.rating.code
    if 'friends-only' in sub.settings and not frienduser.check(userid, sub.userid):
        raise WeasylError("submissionRecordMissing")
    elif sub_rating > rating and userid != sub.userid:
        raise WeasylError("RatingExceeded")
    elif not anyway and ignoreuser.check(userid, sub.userid):
        raise WeasylError("UserIgnored")
    elif not anyway and blocktag.check(userid, submitid=submitid):
        raise WeasylError("TagBlocked")

    description = sub.content
    embedlink = None
    if 'embedded-content' in sub.settings:
        embedlink, _, description = description.partition('\n')
    elif 'gdocs-embed' in sub.settings:
        embedlink = sub.google_doc_embed.embed_url

    views = sub.page_views
    if increment_views and d.common_view_content(userid, submitid, 'submit'):
        views += 1

    return {
        'submitid': submitid,
        'title': sub.title,
        'owner': sub.owner.profile.username,
        'owner_login': sub.owner.login_name,
        'owner_media': api.tidy_all_media(media.get_user_media(sub.userid)),
        'media': api.tidy_all_media(media.get_submission_media(submitid)),
        'description': text.markdown(description),
        'embedlink': embedlink,
        'folderid': sub.folderid,
        'folder_name': sub.folder.title if sub.folderid else None,
        'posted_at': d.iso8601(sub.unixtime),
        'tags': searchtag.select(submitid=submitid),
        'link': d.absolutify_url("/submission/%d/%s" % (submitid, text.slug_for(sub.title))),

        'type': 'submission',
        'subtype': m.CATEGORY_PARSABLE_MAP[sub.subtype // 1000 * 1000],
        'rating': sub.rating.name,

        'views': views,
        'favorites': favorite.count(submitid),
        'comments': comment.count(submitid),
        'favorited': favorite.check(userid, submitid=submitid),
        'friends_only': 'friends-only' in sub.settings,
    }
Esempio n. 15
0
def note_about(userid, target_user, title, message=None):
    staff_note = '## ' + title
    if message:
        staff_note = '%s\n\n%s' % (staff_note, message)

    db = d.connect()
    db.execute(d.meta.tables['comments'].insert().values(
        userid=userid,
        target_user=target_user,
        unixtime=arrow.utcnow(),
        settings='s',
        content=staff_note,
    ))
Esempio n. 16
0
def select_friends(userid, otherid, limit=None, backid=None, nextid=None, choose=False):
    """
    Return accepted friends. If `choose` is an integer, results will be ordered
    randomly.
    """
    fr = d.meta.tables['frienduser']
    pr = d.meta.tables['profile']
    iu = d.meta.tables['ignoreuser']

    friends = d.sa.union(
        (d.sa
         .select([fr.c.otherid, pr.c.username, pr.c.config])
         .select_from(fr.join(pr, fr.c.otherid == pr.c.userid))
         .where(d.sa.and_(fr.c.userid == otherid, fr.c.settings.op('!~')('p')))),
        (d.sa
         .select([fr.c.userid, pr.c.username, pr.c.config])
         .select_from(fr.join(pr, fr.c.userid == pr.c.userid))
         .where(d.sa.and_(fr.c.otherid == otherid, fr.c.settings.op('!~')('p')))))
    friends = friends.alias('friends')

    query = d.sa.select(friends.c)

    if userid:
        query = query.where(
            ~friends.c.otherid.in_(d.sa.select([iu.c.otherid]).where(iu.c.userid == userid)))
    if backid:
        query = query.where(
            friends.c.username < d.sa.select([pr.c.username]).where(pr.c.userid == backid))
    elif nextid:
        query = query.where(
            friends.c.username > d.sa.select([pr.c.username]).where(pr.c.userid == nextid))

    if choose:
        query = query.order_by('RANDOM()')
    else:
        query = query.order_by(
            friends.c.username.desc() if backid else friends.c.username.asc())
        query = query.limit(limit)

    db = d.connect()
    query = [{
        "userid": r.otherid,
        "username": r.username,
    } for r in db.execute(query)]

    ret = (d.get_random_set(query, choose) if choose else query[::-1] if backid else query)
    media.populate_with_user_media(ret)
    return ret
Esempio n. 17
0
def _post_to_twitter_about(submitid, title, rating, tags):
    url = d.absolutify_url('/submission/%s/%s' % (submitid, text.slug_for(title)))

    st = d.meta.tables['searchtag']
    sms = d.meta.tables['searchmapsubmit']
    q = (sa.select([st.c.title])
         .select_from(st.join(sms, st.c.tagid == sms.c.tagid))
         .where(st.c.title.in_(t.lower() for t in tags))
         .group_by(st.c.title)
         .order_by(sa.func.count().desc()))

    account = 'WeasylCritique'
    if rating in (ratings.MATURE.code, ratings.EXPLICIT.code):
        account = 'WZLCritiqueNSFW'
    length = 26
    selected_tags = []
    db = d.connect()
    for tag, in db.execute(q):
        if len(tag) + 2 + length > 140:
            break
        selected_tags.append('#' + tag)
        length += len(tag) + 2

    twits.post(account, u'%s %s' % (url, ' '.join(selected_tags)))
Esempio n. 18
0
def _post_to_twitter_about(submitid, title, rating, tags):
    url = d.absolutify_url('/submission/%s/%s' %
                           (submitid, text.slug_for(title)))

    st = d.meta.tables['searchtag']
    sms = d.meta.tables['searchmapsubmit']
    q = (sa.select([st.c.title]).select_from(
        st.join(sms, st.c.tagid == sms.c.tagid)).where(
            st.c.title.in_(t.lower() for t in tags)).group_by(
                st.c.title).order_by(sa.func.count().desc()))

    account = 'WeasylCritique'
    if rating in (ratings.MATURE.code, ratings.EXPLICIT.code):
        account = 'WZLCritiqueNSFW'
    length = 26
    selected_tags = []
    db = d.connect()
    for tag, in db.execute(q):
        if len(tag) + 2 + length > 140:
            break
        selected_tags.append('#' + tag)
        length += len(tag) + 2

    twits.post(account, u'%s %s' % (url, ' '.join(selected_tags)))
Esempio n. 19
0
def select_view(userid, submitid, rating, ignore=True, anyway=None):
    query = d.execute("""
        SELECT
            su.userid, pr.username, su.folderid, su.unixtime, su.title, su.content, su.subtype, su.rating, su.settings,
            su.page_views, su.sorttime, pr.config, fd.title
        FROM submission su
            INNER JOIN profile pr USING (userid)
            LEFT JOIN folder fd USING (folderid)
        WHERE su.submitid = %i
    """, [submitid],
                      options=["single", "list"])

    # Sanity check
    if query and userid in staff.MODS and anyway == "true":
        pass
    elif not query or "h" in query[8]:
        raise WeasylError("submissionRecordMissing")
    elif query[7] > rating and (
        (userid != query[0] and userid not in staff.MODS) or d.is_sfw_mode()):
        raise WeasylError("RatingExceeded")
    elif "f" in query[8] and not frienduser.check(userid, query[0]):
        raise WeasylError("FriendsOnly")
    elif ignore and ignoreuser.check(userid, query[0]):
        raise WeasylError("UserIgnored")
    elif ignore and blocktag.check(userid, submitid=submitid):
        raise WeasylError("TagBlocked")

    # Get submission filename
    submitfile = media.get_submission_media(submitid).get(
        'submission', [None])[0]

    # Get submission text
    if submitfile and submitfile['file_type'] in ['txt', 'htm']:
        submittext = files.read(submitfile['full_file_path'])
    else:
        submittext = None

    embedlink = d.text_first_line(query[5]) if "v" in query[8] else None

    google_doc_embed = None
    if 'D' in query[8]:
        db = d.connect()
        gde = d.meta.tables['google_doc_embeds']
        q = (sa.select([gde.c.embed_url]).where(gde.c.submitid == submitid))
        results = db.execute(q).fetchall()
        if not results:
            raise WeasylError("can't find embed information")
        google_doc_embed = results[0]

    tags, artist_tags = searchtag.select_with_artist_tags(submitid)
    settings = d.get_profile_settings(query[0])

    return {
        "submitid":
        submitid,
        "userid":
        query[0],
        "username":
        query[1],
        "folderid":
        query[2],
        "unixtime":
        query[3],
        "title":
        query[4],
        "content": (d.text_first_line(query[5], strip=True)
                    if "v" in query[8] else query[5]),
        "subtype":
        query[6],
        "rating":
        query[7],
        "settings":
        query[8],
        "page_views": (query[9] + 1 if d.common_view_content(
            userid, 0 if anyway == "true" else submitid, "submit") else
                       query[9]),
        "fave_count":
        d.execute(
            "SELECT COUNT(*) FROM favorite WHERE (targetid, type) = (%i, 's')",
            [submitid], ["element"]),
        "mine":
        userid == query[0],
        "reported":
        report.check(submitid=submitid),
        "favorited":
        favorite.check(userid, submitid=submitid),
        "friends_only":
        "f" in query[8],
        "hidden_submission":
        "h" in query[8],
        "collectors":
        collection.find_owners(submitid),
        "no_request":
        not settings.allow_collection_requests,
        "text":
        submittext,
        "sub_media":
        media.get_submission_media(submitid),
        "user_media":
        media.get_user_media(query[0]),
        "submit":
        submitfile,
        "embedlink":
        embedlink,
        "embed":
        embed.html(embedlink) if embedlink is not None else None,
        "google_doc_embed":
        google_doc_embed,
        "tags":
        tags,
        "artist_tags":
        artist_tags,
        "removable_tags":
        searchtag.removable_tags(userid, query[0], tags, artist_tags),
        "can_remove_tags":
        searchtag.can_remove_tags(userid, query[0]),
        "folder_more":
        select_near(userid, rating, 1, query[0], query[2], submitid),
        "folder_title":
        query[12] if query[12] else "Root",
        "comments":
        comment.select(userid, submitid=submitid),
    }
Esempio n. 20
0
def create_literary(userid, submission, embedlink=None, friends_only=False, tags=None,
                    coverfile=None, thumbfile=None, submitfile=None, critique=False,
                    create_notifications=True):
    premium = d.get_premium(userid)

    if embedlink:
        check_google_doc_embed_data(embedlink)

    # Determine filesizes
    coversize = len(coverfile)
    thumbsize = len(thumbfile)
    submitsize = len(submitfile)

    if not submitsize and not embedlink:
        raise WeasylError("submitSizeZero")
    elif coversize > 10 * _MEGABYTE:
        raise WeasylError("coverSizeExceedsLimit")
    elif thumbsize > 10 * _MEGABYTE:
        raise WeasylError("thumbSizeExceedsLimit")

    if submitsize:
        submitextension = files.get_extension_for_category(submitfile, m.TEXT_SUBMISSION_CATEGORY)
        if submitextension is None:
            raise WeasylError("submitType")
        if _limit(submitsize, submitextension, premium):
            raise WeasylError("submitSizeExceedsLimit")
        submit_media_item = orm.fetch_or_create_media_item(
            submitfile, file_type=submitextension.lstrip('.'))
        check_for_duplicate_media(userid, submit_media_item.mediaid)
    else:
        submit_media_item = None

    thumb_media_item = media.make_cover_media_item(thumbfile)
    cover_media_item = media.make_cover_media_item(coverfile)
    if cover_media_item and not thumb_media_item:
        thumb_media_item = cover_media_item

    # Assign settings
    settings = []
    settings.append("f" if friends_only else "")
    settings.append("q" if critique else "")
    if embedlink:
        settings.append('D')
    settings = "".join(settings)

    # Create submission
    # TODO(kailys): use ORM object
    db = d.connect()
    now = arrow.get()
    try:
        q = (
            d.meta.tables['submission'].insert().values([{
                "folderid": submission.folderid,
                "userid": userid,
                "unixtime": now,
                "title": submission.title,
                "content": submission.content,
                "subtype": submission.subtype,
                "rating": submission.rating.code,
                "settings": settings,
                "sorttime": now,
            }])
            .returning(d.meta.tables['submission'].c.submitid))
        submitid = db.scalar(q)
        if embedlink:
            q = (d.meta.tables['google_doc_embeds'].insert()
                 .values(submitid=submitid, embed_url=embedlink))
            db.execute(q)
    except:
        files.clear_temporary(userid)
        raise

    # Assign search tags
    searchtag.associate(userid, tags, submitid=submitid)

    if submit_media_item:
        orm.SubmissionMediaLink.make_or_replace_link(
            submitid, 'submission', submit_media_item, rating=submission.rating.code)
    if cover_media_item:
        orm.SubmissionMediaLink.make_or_replace_link(
            submitid, 'cover', cover_media_item, rating=submission.rating.code)
    if thumb_media_item:
        orm.SubmissionMediaLink.make_or_replace_link(submitid, 'thumbnail-source', thumb_media_item)

    # Create notifications
    if create_notifications:
        _create_notifications(userid, submitid, submission.rating, settings,
                              submission.title, tags)

    # Clear temporary files
    files.clear_temporary(userid)

    d.metric('increment', 'submissions')
    d.metric('increment', 'literarysubmissions')

    return submitid, bool(thumb_media_item)
Esempio n. 21
0
def create_multimedia(userid,
                      submission,
                      embedlink=None,
                      friends_only=None,
                      tags=None,
                      coverfile=None,
                      thumbfile=None,
                      submitfile=None,
                      critique=False,
                      create_notifications=True,
                      auto_thumb=False):
    premium = d.get_premium(userid)
    embedlink = embedlink.strip()

    # Determine filesizes
    coversize = len(coverfile)
    thumbsize = len(thumbfile)
    submitsize = len(submitfile)

    if not submitsize and not embedlink:
        raise WeasylError("submitSizeZero")
    elif embedlink and not embed.check_valid(embedlink):
        raise WeasylError("embedlinkInvalid")
    elif coversize > 10 * _MEGABYTE:
        raise WeasylError("coverSizeExceedsLimit")
    elif thumbsize > 10 * _MEGABYTE:
        raise WeasylError("thumbSizeExceedsLimit")

    if submitsize:
        submitextension = files.get_extension_for_category(
            submitfile, m.MULTIMEDIA_SUBMISSION_CATEGORY)
        if submitextension is None:
            raise WeasylError("submitType")
        elif submitextension not in [".mp3", ".swf"] and not embedlink:
            raise WeasylError("submitType")
        elif _limit(submitsize, submitextension, premium):
            raise WeasylError("submitSizeExceedsLimit")
        submit_media_item = orm.fetch_or_create_media_item(
            submitfile, file_type=submitextension.lstrip('.'))
        check_for_duplicate_media(userid, submit_media_item.mediaid)
    else:
        submit_media_item = None

    thumb_media_item = media.make_cover_media_item(thumbfile)
    cover_media_item = media.make_cover_media_item(coverfile)
    if cover_media_item and not thumb_media_item:
        thumb_media_item = cover_media_item

    tempthumb_media_item = None
    im = None
    if auto_thumb:
        if thumbsize == 0 and coversize == 0:
            # Fetch default thumbnail from source if available
            thumb_url = embed.thumbnail(embedlink)
            if thumb_url:
                resp = d.http_get(thumb_url, timeout=5)
                im = image.from_string(resp.content)
    if not im and (thumbsize or coversize):
        im = image.from_string(thumbfile or coverfile)
    if im:
        tempthumb = images.make_thumbnail(im)
        tempthumb_type = images.image_file_type(tempthumb)
        tempthumb_media_item = orm.fetch_or_create_media_item(
            tempthumb.to_buffer(format=tempthumb_type),
            file_type=tempthumb_type,
            im=tempthumb)

    # Assign settings
    settings = []
    settings.append("f" if friends_only else "")
    settings.append("q" if critique else "")
    settings.append("v" if embedlink else "")
    settings = "".join(settings)

    # Inject embedlink
    if embedlink:
        submission.content = "".join([embedlink, "\n", submission.content])

    # Create submission
    db = d.connect()
    now = arrow.get()
    try:
        q = (d.meta.tables['submission'].insert().values([{
            "folderid":
            submission.folderid,
            "userid":
            userid,
            "unixtime":
            now,
            "title":
            submission.title,
            "content":
            submission.content,
            "subtype":
            submission.subtype,
            "rating":
            submission.rating,
            "settings":
            settings,
            "sorttime":
            now,
        }]).returning(d.meta.tables['submission'].c.submitid))
        submitid = db.scalar(q)
    except PostgresError:
        files.clear_temporary(userid)
        raise

    # Assign search tags
    searchtag.associate(userid, tags, submitid=submitid)

    if submit_media_item:
        orm.SubmissionMediaLink.make_or_replace_link(
            submitid,
            'submission',
            submit_media_item,
            rating=submission.rating.code)
    if cover_media_item:
        orm.SubmissionMediaLink.make_or_replace_link(
            submitid, 'cover', cover_media_item, rating=submission.rating.code)
    if thumb_media_item:
        orm.SubmissionMediaLink.make_or_replace_link(submitid,
                                                     'thumbnail-source',
                                                     thumb_media_item)
    if tempthumb_media_item:
        orm.SubmissionMediaLink.make_or_replace_link(submitid,
                                                     'thumbnail-custom',
                                                     tempthumb_media_item)

    # Create notifications
    if create_notifications:
        _create_notifications(userid, submitid, submission.rating, settings,
                              submission.title, tags)

    # Clear temporary files
    files.clear_temporary(userid)

    d.metric('increment', 'submissions')
    d.metric('increment', 'multimediasubmissions')

    return submitid, bool(thumb_media_item)
Esempio n. 22
0
def create_literary(userid,
                    submission,
                    embedlink=None,
                    friends_only=False,
                    tags=None,
                    coverfile=None,
                    thumbfile=None,
                    submitfile=None,
                    critique=False,
                    create_notifications=True):
    premium = d.get_premium(userid)

    if embedlink:
        check_google_doc_embed_data(embedlink)

    # Determine filesizes
    coversize = len(coverfile)
    thumbsize = len(thumbfile)
    submitsize = len(submitfile)

    if not submitsize and not embedlink:
        raise WeasylError("submitSizeZero")
    elif coversize > 10 * _MEGABYTE:
        raise WeasylError("coverSizeExceedsLimit")
    elif thumbsize > 10 * _MEGABYTE:
        raise WeasylError("thumbSizeExceedsLimit")

    if submitsize:
        submitextension = files.get_extension_for_category(
            submitfile, m.TEXT_SUBMISSION_CATEGORY)
        if submitextension is None:
            raise WeasylError("submitType")
        if _limit(submitsize, submitextension, premium):
            raise WeasylError("submitSizeExceedsLimit")
        submit_media_item = orm.fetch_or_create_media_item(
            submitfile, file_type=submitextension.lstrip('.'))
        check_for_duplicate_media(userid, submit_media_item.mediaid)
    else:
        submit_media_item = None

    thumb_media_item = media.make_cover_media_item(thumbfile)
    cover_media_item = media.make_cover_media_item(coverfile)
    if cover_media_item and not thumb_media_item:
        thumb_media_item = cover_media_item

    # Assign settings
    settings = []
    settings.append("f" if friends_only else "")
    settings.append("q" if critique else "")
    if embedlink:
        settings.append('D')
    settings = "".join(settings)

    # Create submission
    # TODO(kailys): use ORM object
    db = d.connect()
    now = arrow.get()
    try:
        q = (d.meta.tables['submission'].insert().values([{
            "folderid":
            submission.folderid,
            "userid":
            userid,
            "unixtime":
            now,
            "title":
            submission.title,
            "content":
            submission.content,
            "subtype":
            submission.subtype,
            "rating":
            submission.rating.code,
            "settings":
            settings,
            "sorttime":
            now,
        }]).returning(d.meta.tables['submission'].c.submitid))
        submitid = db.scalar(q)
        if embedlink:
            q = (d.meta.tables['google_doc_embeds'].insert().values(
                submitid=submitid, embed_url=embedlink))
            db.execute(q)
    except:
        files.clear_temporary(userid)
        raise

    # Assign search tags
    searchtag.associate(userid, tags, submitid=submitid)

    if submit_media_item:
        orm.SubmissionMediaLink.make_or_replace_link(
            submitid,
            'submission',
            submit_media_item,
            rating=submission.rating.code)
    if cover_media_item:
        orm.SubmissionMediaLink.make_or_replace_link(
            submitid, 'cover', cover_media_item, rating=submission.rating.code)
    if thumb_media_item:
        orm.SubmissionMediaLink.make_or_replace_link(submitid,
                                                     'thumbnail-source',
                                                     thumb_media_item)

    # Create notifications
    if create_notifications:
        _create_notifications(userid, submitid, submission.rating, settings,
                              submission.title, tags)

    # Clear temporary files
    files.clear_temporary(userid)

    d.metric('increment', 'submissions')
    d.metric('increment', 'literarysubmissions')

    return submitid, bool(thumb_media_item)
Esempio n. 23
0
def create_visual(userid, submission, friends_only, tags, imageURL, thumbfile,
                  submitfile, critique, create_notifications):
    premium = d.get_premium(userid)

    if imageURL:
        resp = d.http_get(imageURL, timeout=5)
        submitfile = resp.content

    # Determine filesizes
    thumbsize = len(thumbfile)
    submitsize = len(submitfile)

    if not submitsize:
        files.clear_temporary(userid)
        raise WeasylError("submitSizeZero")
    elif thumbsize > 10 * _MEGABYTE:
        files.clear_temporary(userid)
        raise WeasylError("thumbSizeExceedsLimit")

    im = image.from_string(submitfile)
    submitextension = image.image_extension(im)
    if _limit(submitsize, submitextension, premium):
        raise WeasylError("submitSizeExceedsLimit")
    elif submitextension not in [".jpg", ".png", ".gif"]:
        raise WeasylError("submitType")
    submit_file_type = submitextension.lstrip('.')
    submit_media_item = orm.fetch_or_create_media_item(
        submitfile, file_type=submit_file_type, im=im)
    check_for_duplicate_media(userid, submit_media_item.mediaid)
    cover_media_item = submit_media_item.ensure_cover_image(im)

    # Thumbnail stuff.
    # Always create a 'generated' thumbnail from the source image.
    thumb_generated = images.make_thumbnail(im)
    if thumb_generated is im:
        thumb_generated_media_item = submit_media_item
    else:
        thumb_generated_media_item = orm.fetch_or_create_media_item(
            thumb_generated.to_buffer(format=submit_file_type),
            file_type=submit_file_type,
            im=thumb_generated)
    # If requested, also create a 'custom' thumbnail.
    thumb_media_item = media.make_cover_media_item(thumbfile)
    if thumb_media_item:
        thumb_custom = images.make_thumbnail(image.from_string(thumbfile))
        thumb_custom_media_item = orm.fetch_or_create_media_item(
            thumb_custom.to_buffer(format=submit_file_type),
            file_type=submit_file_type,
            im=thumb_custom)

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

    # TODO(kailys): maintain ORM object
    db = d.connect()
    now = arrow.get()
    q = (d.meta.tables['submission'].insert().values([{
        "folderid":
        submission.folderid,
        "userid":
        userid,
        "unixtime":
        now,
        "title":
        submission.title,
        "content":
        submission.content,
        "subtype":
        submission.subtype,
        "rating":
        submission.rating.code,
        "settings":
        settings,
        "sorttime":
        now,
    }]).returning(d.meta.tables['submission'].c.submitid))
    submitid = db.scalar(q)

    orm.SubmissionMediaLink.make_or_replace_link(submitid, 'submission',
                                                 submit_media_item)
    orm.SubmissionMediaLink.make_or_replace_link(submitid, 'cover',
                                                 cover_media_item)
    orm.SubmissionMediaLink.make_or_replace_link(submitid,
                                                 'thumbnail-generated',
                                                 thumb_generated_media_item)
    if thumb_media_item:
        orm.SubmissionMediaLink.make_or_replace_link(submitid,
                                                     'thumbnail-source',
                                                     thumb_media_item)
        orm.SubmissionMediaLink.make_or_replace_link(submitid,
                                                     'thumbnail-custom',
                                                     thumb_custom_media_item)

    # Assign search tags
    searchtag.associate(userid, tags, submitid=submitid)

    # Create notifications
    if create_notifications:
        _create_notifications(userid, submitid, submission.rating, settings,
                              submission.title, tags)

    d.metric('increment', 'submissions')
    d.metric('increment', 'visualsubmissions')

    return submitid
Esempio n. 24
0
def is_hidden(submitid):
    db = d.connect()
    su = d.meta.tables['submission']
    q = d.sa.select([su.c.settings.op('~')('h')]).where(su.c.submitid == submitid)
    results = db.execute(q).fetchall()
    return bool(results and results[0][0])
Esempio n. 25
0
def create_visual(userid, submission,
                  friends_only, tags, imageURL, thumbfile,
                  submitfile, critique, create_notifications):
    premium = d.get_premium(userid)

    if imageURL:
        resp = d.http_get(imageURL, timeout=5)
        submitfile = resp.content

    # Determine filesizes
    thumbsize = len(thumbfile)
    submitsize = len(submitfile)

    if not submitsize:
        files.clear_temporary(userid)
        raise WeasylError("submitSizeZero")
    elif thumbsize > 10 * _MEGABYTE:
        files.clear_temporary(userid)
        raise WeasylError("thumbSizeExceedsLimit")

    im = image.from_string(submitfile)
    submitextension = image.image_extension(im)
    if _limit(submitsize, submitextension, premium):
        raise WeasylError("submitSizeExceedsLimit")
    elif submitextension not in [".jpg", ".png", ".gif"]:
        raise WeasylError("submitType")
    submit_file_type = submitextension.lstrip('.')
    submit_media_item = orm.fetch_or_create_media_item(
        submitfile, file_type=submit_file_type, im=im)
    check_for_duplicate_media(userid, submit_media_item.mediaid)
    cover_media_item = submit_media_item.ensure_cover_image(im)

    # Thumbnail stuff.
    # Always create a 'generated' thumbnail from the source image.
    thumb_generated = images.make_thumbnail(im)
    if thumb_generated is im:
        thumb_generated_media_item = submit_media_item
    else:
        thumb_generated_media_item = orm.fetch_or_create_media_item(
            thumb_generated.to_buffer(format=submit_file_type), file_type=submit_file_type,
            im=thumb_generated)
    # If requested, also create a 'custom' thumbnail.
    thumb_media_item = media.make_cover_media_item(thumbfile)
    if thumb_media_item:
        thumb_custom = images.make_thumbnail(image.from_string(thumbfile))
        thumb_custom_media_item = orm.fetch_or_create_media_item(
            thumb_custom.to_buffer(format=submit_file_type), file_type=submit_file_type,
            im=thumb_custom)

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

    # TODO(kailys): maintain ORM object
    db = d.connect()
    now = arrow.get()
    q = (
        d.meta.tables['submission'].insert().values([{
            "folderid": submission.folderid,
            "userid": userid,
            "unixtime": now,
            "title": submission.title,
            "content": submission.content,
            "subtype": submission.subtype,
            "rating": submission.rating.code,
            "settings": settings,
            "sorttime": now,
        }]).returning(d.meta.tables['submission'].c.submitid))
    submitid = db.scalar(q)

    orm.SubmissionMediaLink.make_or_replace_link(
        submitid, 'submission', submit_media_item)
    orm.SubmissionMediaLink.make_or_replace_link(
        submitid, 'cover', cover_media_item)
    orm.SubmissionMediaLink.make_or_replace_link(
        submitid, 'thumbnail-generated', thumb_generated_media_item)
    if thumb_media_item:
        orm.SubmissionMediaLink.make_or_replace_link(submitid, 'thumbnail-source', thumb_media_item)
        orm.SubmissionMediaLink.make_or_replace_link(
            submitid, 'thumbnail-custom', thumb_custom_media_item)

    # Assign search tags
    searchtag.associate(userid, tags, submitid=submitid)

    # Create notifications
    if create_notifications:
        _create_notifications(userid, submitid, submission.rating, settings,
                              submission.title, tags)

    d.metric('increment', 'submissions')
    d.metric('increment', 'visualsubmissions')

    return submitid
Esempio n. 26
0
def is_hidden(charid):
    db = define.connect()
    ch = define.meta.tables['character']
    q = define.sa.select([ch.c.settings.op('~')('h')]).where(ch.c.charid == charid)
    results = db.execute(q).fetchall()
    return bool(results and results[0][0])
Esempio n. 27
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. 28
0
def select_view(userid, submitid, rating, ignore=True, anyway=None):
    query = d.execute("""
        SELECT
            su.userid, pr.username, su.folderid, su.unixtime, su.title, su.content, su.subtype, su.rating, su.settings,
            su.page_views, su.sorttime, pr.config, fd.title
        FROM submission su
            INNER JOIN profile pr USING (userid)
            LEFT JOIN folder fd USING (folderid)
        WHERE su.submitid = %i
    """, [submitid], options=["single", "list"])

    # Sanity check
    if query and userid in staff.MODS and anyway == "true":
        pass
    elif not query or "h" in query[8]:
        raise WeasylError("submissionRecordMissing")
    elif query[7] > rating and ((userid != query[0] and userid not in staff.MODS) or d.is_sfw_mode()):
        raise WeasylError("RatingExceeded")
    elif "f" in query[8] and not frienduser.check(userid, query[0]):
        raise WeasylError("FriendsOnly")
    elif ignore and ignoreuser.check(userid, query[0]):
        raise WeasylError("UserIgnored")
    elif ignore and blocktag.check(userid, submitid=submitid):
        raise WeasylError("TagBlocked")

    # Get submission filename
    submitfile = media.get_submission_media(submitid).get('submission', [None])[0]

    # Get submission text
    if submitfile and submitfile['file_type'] in ['txt', 'htm']:
        submittext = files.read(submitfile['full_file_path'])
    else:
        submittext = None

    embedlink = d.text_first_line(query[5]) if "v" in query[8] else None

    google_doc_embed = None
    if 'D' in query[8]:
        db = d.connect()
        gde = d.meta.tables['google_doc_embeds']
        q = (sa.select([gde.c.embed_url])
             .where(gde.c.submitid == submitid))
        results = db.execute(q).fetchall()
        if not results:
            raise WeasylError("can't find embed information")
        google_doc_embed = results[0]

    tags, artist_tags = searchtag.select_with_artist_tags(submitid)
    settings = d.get_profile_settings(query[0])

    return {
        "submitid": submitid,
        "userid": query[0],
        "username": query[1],
        "folderid": query[2],
        "unixtime": query[3],
        "title": query[4],
        "content": (d.text_first_line(query[5], strip=True) if "v" in query[8] else query[5]),
        "subtype": query[6],
        "rating": query[7],
        "settings": query[8],
        "page_views": (
            query[9] + 1 if d.common_view_content(userid, 0 if anyway == "true" else submitid, "submit") else query[9]),
        "fave_count": d.execute(
            "SELECT COUNT(*) FROM favorite WHERE (targetid, type) = (%i, 's')",
            [submitid], ["element"]),


        "mine": userid == query[0],
        "reported": report.check(submitid=submitid),
        "favorited": favorite.check(userid, submitid=submitid),
        "friends_only": "f" in query[8],
        "hidden_submission": "h" in query[8],
        "collectors": collection.find_owners(submitid),
        "no_request": not settings.allow_collection_requests,

        "text": submittext,
        "sub_media": media.get_submission_media(submitid),
        "user_media": media.get_user_media(query[0]),
        "submit": submitfile,
        "embedlink": embedlink,
        "embed": embed.html(embedlink) if embedlink is not None else None,
        "google_doc_embed": google_doc_embed,


        "tags": tags,
        "artist_tags": artist_tags,
        "removable_tags": searchtag.removable_tags(userid, query[0], tags, artist_tags),
        "can_remove_tags": searchtag.can_remove_tags(userid, query[0]),
        "folder_more": select_near(userid, rating, 1, query[0], query[2], submitid),
        "folder_title": query[12] if query[12] else "Root",


        "comments": comment.select(userid, submitid=submitid),
    }
Esempio n. 29
0
def is_hidden(charid):
    db = define.connect()
    ch = define.meta.tables['character']
    q = define.sa.select([ch.c.settings.op('~')('h')]).where(ch.c.charid == charid)
    results = db.execute(q).fetchall()
    return bool(results and results[0][0])
Esempio n. 30
0
def select_view_api(userid, submitid, anyway=False, increment_views=False):
    rating = d.get_rating(userid)
    db = d.connect()
    sub = db.query(orm.Submission).get(submitid)
    if sub is None or 'hidden' in sub.settings:
        raise WeasylError("submissionRecordMissing")
    sub_rating = sub.rating.code
    if 'friends-only' in sub.settings and not frienduser.check(
            userid, sub.userid):
        raise WeasylError("submissionRecordMissing")
    elif sub_rating > rating and userid != sub.userid:
        raise WeasylError("RatingExceeded")
    elif not anyway and ignoreuser.check(userid, sub.userid):
        raise WeasylError("UserIgnored")
    elif not anyway and blocktag.check(userid, submitid=submitid):
        raise WeasylError("TagBlocked")

    description = sub.content
    embedlink = None
    if 'embedded-content' in sub.settings:
        embedlink, _, description = description.partition('\n')
    elif 'gdocs-embed' in sub.settings:
        embedlink = sub.google_doc_embed.embed_url

    views = sub.page_views
    if increment_views and d.common_view_content(userid, submitid, 'submit'):
        views += 1

    return {
        'submitid':
        submitid,
        'title':
        sub.title,
        'owner':
        sub.owner.profile.username,
        'owner_login':
        sub.owner.login_name,
        'owner_media':
        api.tidy_all_media(media.get_user_media(sub.userid)),
        'media':
        api.tidy_all_media(media.get_submission_media(submitid)),
        'description':
        text.markdown(description),
        'embedlink':
        embedlink,
        'folderid':
        sub.folderid,
        'folder_name':
        sub.folder.title if sub.folderid else None,
        'posted_at':
        d.iso8601(sub.unixtime),
        'tags':
        searchtag.select(submitid=submitid),
        'link':
        d.absolutify_url("/submission/%d/%s" %
                         (submitid, text.slug_for(sub.title))),
        'type':
        'submission',
        'subtype':
        m.CATEGORY_PARSABLE_MAP[sub.subtype // 1000 * 1000],
        'rating':
        sub.rating.name,
        'views':
        views,
        'favorites':
        favorite.count(submitid),
        'comments':
        comment.count(submitid),
        'favorited':
        favorite.check(userid, submitid=submitid),
        'friends_only':
        'friends-only' in sub.settings,
    }
Esempio n. 31
0
def create_multimedia(userid, submission, embedlink=None, friends_only=None,
                      tags=None, coverfile=None, thumbfile=None, submitfile=None,
                      critique=False, create_notifications=True, auto_thumb=False):
    premium = d.get_premium(userid)
    embedlink = embedlink.strip()

    # Determine filesizes
    coversize = len(coverfile)
    thumbsize = len(thumbfile)
    submitsize = len(submitfile)

    if not submitsize and not embedlink:
        raise WeasylError("submitSizeZero")
    elif embedlink and not embed.check_valid(embedlink):
        raise WeasylError("embedlinkInvalid")
    elif coversize > 10 * _MEGABYTE:
        raise WeasylError("coverSizeExceedsLimit")
    elif thumbsize > 10 * _MEGABYTE:
        raise WeasylError("thumbSizeExceedsLimit")

    if submitsize:
        submitextension = files.get_extension_for_category(submitfile, m.MULTIMEDIA_SUBMISSION_CATEGORY)
        if submitextension is None:
            raise WeasylError("submitType")
        elif submitextension not in [".mp3", ".swf"] and not embedlink:
            raise WeasylError("submitType")
        elif _limit(submitsize, submitextension, premium):
            raise WeasylError("submitSizeExceedsLimit")
        submit_media_item = orm.fetch_or_create_media_item(
            submitfile, file_type=submitextension.lstrip('.'))
        check_for_duplicate_media(userid, submit_media_item.mediaid)
    else:
        submit_media_item = None

    thumb_media_item = media.make_cover_media_item(thumbfile)
    cover_media_item = media.make_cover_media_item(coverfile)
    if cover_media_item and not thumb_media_item:
        thumb_media_item = cover_media_item

    tempthumb_media_item = None
    im = None
    if auto_thumb:
        if thumbsize == 0 and coversize == 0:
            # Fetch default thumbnail from source if available
            thumb_url = embed.thumbnail(embedlink)
            if thumb_url:
                resp = d.http_get(thumb_url, timeout=5)
                im = image.from_string(resp.content)
    if not im and (thumbsize or coversize):
        im = image.from_string(thumbfile or coverfile)
    if im:
        tempthumb = images.make_thumbnail(im)
        tempthumb_type = images.image_file_type(tempthumb)
        tempthumb_media_item = orm.fetch_or_create_media_item(
            tempthumb.to_buffer(format=tempthumb_type),
            file_type=tempthumb_type,
            im=tempthumb)

    # Assign settings
    settings = []
    settings.append("f" if friends_only else "")
    settings.append("q" if critique else "")
    settings.append("v" if embedlink else "")
    settings = "".join(settings)

    # Inject embedlink
    if embedlink:
        submission.content = "".join([embedlink, "\n", submission.content])

    # Create submission
    db = d.connect()
    now = arrow.get()
    try:
        q = (
            d.meta.tables['submission'].insert().values([{
                "folderid": submission.folderid,
                "userid": userid,
                "unixtime": now,
                "title": submission.title,
                "content": submission.content,
                "subtype": submission.subtype,
                "rating": submission.rating,
                "settings": settings,
                "sorttime": now,
            }])
            .returning(d.meta.tables['submission'].c.submitid))
        submitid = db.scalar(q)
    except PostgresError:
        files.clear_temporary(userid)
        raise

    # Assign search tags
    searchtag.associate(userid, tags, submitid=submitid)

    if submit_media_item:
        orm.SubmissionMediaLink.make_or_replace_link(
            submitid, 'submission', submit_media_item, rating=submission.rating.code)
    if cover_media_item:
        orm.SubmissionMediaLink.make_or_replace_link(
            submitid, 'cover', cover_media_item, rating=submission.rating.code)
    if thumb_media_item:
        orm.SubmissionMediaLink.make_or_replace_link(submitid, 'thumbnail-source', thumb_media_item)
    if tempthumb_media_item:
        orm.SubmissionMediaLink.make_or_replace_link(submitid, 'thumbnail-custom',
                                                     tempthumb_media_item)

    # Create notifications
    if create_notifications:
        _create_notifications(userid, submitid, submission.rating, settings,
                              submission.title, tags)

    # Clear temporary files
    files.clear_temporary(userid)

    d.metric('increment', 'submissions')
    d.metric('increment', 'multimediasubmissions')

    return submitid, bool(thumb_media_item)
Esempio n. 32
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. 33
0
def bulk_edit(userid, action, submissions=(), characters=(), journals=()):
    web.header('Content-Type', 'text/plain')

    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. 34
0
def bulk_edit(userid, action, submissions=(), characters=(), journals=()):
    web.header('Content-Type', 'text/plain')

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