Esempio n. 1
0
def manage_thumbnail_get_(request):
    form = request.web_input(submitid="", charid="", auto="")
    submitid = define.get_int(form.submitid)
    charid = define.get_int(form.charid)

    if submitid and request.userid not in staff.ADMINS and request.userid != define.get_ownerid(submitid=submitid):
        return Response(define.errorpage(request.userid, errorcode.permissions))
    elif charid and request.userid not in staff.ADMINS and request.userid != define.get_ownerid(charid=charid):
        return Response(define.errorpage(request.userid, errorcode.permissions))
    elif not submitid and not charid:
        return Response(define.errorpage(request.userid))

    if charid:
        source_path = define.url_make(charid, "char/.thumb", root=True)
        if os.path.exists(source_path):
            source = define.url_make(charid, "char/.thumb")
        else:
            source = define.url_make(charid, "char/cover")
    else:
        try:
            source = thumbnail.thumbnail_source(submitid)['display_url']
        except WeasylError:
            source = None

    return Response(define.webpage(request.userid, "manage/thumbnail.html", [
        # Feature
        "submit" if submitid else "char",
        # Targetid
        define.get_targetid(submitid, charid),
        # Thumbnail
        source,
        # Exists
        bool(source),
    ], options=['imageselect'], title="Select Thumbnail"))
Esempio n. 2
0
    def GET(self):
        form = web.input(submitid="")
        form.submitid = define.get_int(form.submitid)

        if self.user_id != define.get_ownerid(submitid=form.submitid):
            return define.errorpage(self.user_id, errorcode.permission)

        return define.webpage(self.user_id, "submit/reupload_cover.html", [form.submitid])
Esempio n. 3
0
def reupload_cover_get_(request):
    form = request.web_input(submitid="")
    form.submitid = define.get_int(form.submitid)

    if request.userid != define.get_ownerid(submitid=form.submitid):
        raise WeasylError('InsufficientPermissions')

    return Response(define.webpage(request.userid, "submit/reupload_cover.html", [form.submitid], title="Reupload Cover Artwork"))
Esempio n. 4
0
def reupload_cover_get_(request):
    form = request.web_input(submitid="")
    form.submitid = define.get_int(form.submitid)

    if request.userid != define.get_ownerid(submitid=form.submitid):
        return Response(define.errorpage(request.userid, errorcode.permission))

    return Response(define.webpage(request.userid, "submit/reupload_cover.html", [form.submitid]))
Esempio n. 5
0
def reupload_character_post_(request):
    form = request.web_input(targetid="", submitfile="")
    form.targetid = define.get_int(form.targetid)

    if request.userid != define.get_ownerid(charid=form.targetid):
        return Response(define.errorpage(request.userid, errorcode.permission))

    character.reupload(request.userid, form.targetid, form.submitfile)
    raise HTTPSeeOther(location="/character/%i" % (form.targetid,))
Esempio n. 6
0
def reupload_character_post_(request):
    form = request.web_input(targetid="", submitfile="")
    form.targetid = define.get_int(form.targetid)

    if request.userid != define.get_ownerid(charid=form.targetid):
        return Response(define.errorpage(request.userid, errorcode.permission))

    character.reupload(request.userid, form.targetid, form.submitfile)
    raise HTTPSeeOther(location="/character/%i" % (form.targetid, ))
Esempio n. 7
0
    def POST(self):
        form = web.input(targetid="", submitfile="")
        form.targetid = define.get_int(form.targetid)

        if self.user_id != define.get_ownerid(charid=form.targetid):
            return define.errorpage(self.user_id, errorcode.permission)

        character.reupload(self.user_id, form.targetid, form.submitfile)
        raise web.seeother("/character/%i" % (form.targetid,))
Esempio n. 8
0
def reupload_character_post_(request):
    form = request.web_input(targetid="", submitfile="")
    form.targetid = define.get_int(form.targetid)

    if request.userid != define.get_ownerid(charid=form.targetid):
        raise WeasylError('InsufficientPermissions')

    character.reupload(request.userid, form.targetid, form.submitfile)
    raise HTTPSeeOther(location="/character/%i" % (form.targetid, ))
Esempio n. 9
0
    def POST(self):
        form = web.input(targetid="", submitfile="")
        form.targetid = define.get_int(form.targetid)

        if self.user_id != define.get_ownerid(charid=form.targetid):
            return define.errorpage(self.user_id, errorcode.permission)

        character.reupload(self.user_id, form.targetid, form.submitfile)
        raise web.seeother("/character/%i" % (form.targetid, ))
Esempio n. 10
0
    def GET(self):
        form = web.input(submitid="")
        form.submitid = define.get_int(form.submitid)

        if self.user_id != define.get_ownerid(submitid=form.submitid):
            return define.errorpage(self.user_id, errorcode.permission)

        return define.webpage(self.user_id, "submit/reupload_cover.html",
                              [form.submitid])
Esempio n. 11
0
def manage_thumbnail_get_(request):
    form = request.web_input(submitid="", charid="", auto="")
    submitid = define.get_int(form.submitid)
    charid = define.get_int(form.charid)

    if submitid and request.userid not in staff.ADMINS and request.userid != define.get_ownerid(
            submitid=submitid):
        return Response(define.errorpage(request.userid,
                                         errorcode.permissions))
    elif charid and request.userid not in staff.ADMINS and request.userid != define.get_ownerid(
            charid=charid):
        return Response(define.errorpage(request.userid,
                                         errorcode.permissions))
    elif not submitid and not charid:
        return Response(define.errorpage(request.userid))

    if charid:
        source_path = define.url_make(charid, "char/.thumb", root=True)
        if os.path.exists(source_path):
            source = define.url_make(charid, "char/.thumb")
        else:
            source = define.url_make(charid, "char/cover")
    else:
        try:
            source = thumbnail.thumbnail_source(submitid)['display_url']
        except WeasylError:
            source = None

    return Response(
        define.webpage(
            request.userid,
            "manage/thumbnail.html",
            [
                # Feature
                "submit" if submitid else "char",
                # Targetid
                define.get_targetid(submitid, charid),
                # Thumbnail
                source,
                # Exists
                bool(source),
            ],
            options=['imageselect'],
            title="Select Thumbnail"))
Esempio n. 12
0
def manage_thumbnail_post_(request):
    form = request.web_input(submitid="",
                             charid="",
                             x1="",
                             y1="",
                             x2="",
                             y2="",
                             thumbfile="")
    submitid = define.get_int(form.submitid)
    charid = define.get_int(form.charid)

    if submitid and request.userid not in staff.ADMINS and request.userid != define.get_ownerid(
            submitid=submitid):
        return Response(define.errorpage(request.userid))
    if charid and request.userid not in staff.ADMINS and request.userid != define.get_ownerid(
            charid=charid):
        return Response(define.errorpage(request.userid))
    if not submitid and not charid:
        return Response(define.errorpage(request.userid))

    if form.thumbfile:
        thumbnail.upload(request.userid,
                         form.thumbfile,
                         submitid=submitid,
                         charid=charid)
        if submitid:
            raise HTTPSeeOther(location="/manage/thumbnail?submitid=%i" %
                               (submitid, ))
        else:
            raise HTTPSeeOther(location="/manage/thumbnail?charid=%i" %
                               (charid, ))
    else:
        thumbnail.create(request.userid,
                         form.x1,
                         form.y1,
                         form.x2,
                         form.y2,
                         submitid=submitid,
                         charid=charid)
        if submitid:
            raise HTTPSeeOther(location="/submission/%i" % (submitid, ))
        else:
            raise HTTPSeeOther(location="/character/%i" % (charid, ))
Esempio n. 13
0
def reupload_cover_get_(request):
    form = request.web_input(submitid="")
    form.submitid = define.get_int(form.submitid)

    if request.userid != define.get_ownerid(submitid=form.submitid):
        return Response(define.errorpage(request.userid, errorcode.permission))

    return Response(
        define.webpage(request.userid, "submit/reupload_cover.html",
                       [form.submitid]))
Esempio n. 14
0
    def POST(self):
        form = web.input(submitid="",
                         charid="",
                         x1="",
                         y1="",
                         x2="",
                         y2="",
                         thumbfile="")
        submitid = define.get_int(form.submitid)
        charid = define.get_int(form.charid)

        if submitid and self.user_id not in staff.ADMINS and self.user_id != define.get_ownerid(
                submitid=submitid):
            return define.errorpage(self.user_id)
        if charid and self.user_id not in staff.ADMINS and self.user_id != define.get_ownerid(
                charid=charid):
            return define.errorpage(self.user_id)
        if not submitid and not charid:
            return define.errorpage(self.user_id)

        if form.thumbfile:
            thumbnail.upload(self.user_id,
                             form.thumbfile,
                             submitid=submitid,
                             charid=charid)
            if submitid:
                raise web.seeother("/manage/thumbnail?submitid=%i" %
                                   (submitid, ))
            else:
                raise web.seeother("/manage/thumbnail?charid=%i" % (charid, ))
        else:
            thumbnail.create(self.user_id,
                             form.x1,
                             form.y1,
                             form.x2,
                             form.y2,
                             submitid=submitid,
                             charid=charid)
            if submitid:
                raise web.seeother("/submission/%i" % (submitid, ))
            else:
                raise web.seeother("/character/%i" % (charid, ))
Esempio n. 15
0
def reupload_character_get_(request):
    form = request.web_input(charid="")
    form.charid = define.get_int(form.charid)

    if request.userid != define.get_ownerid(charid=form.charid):
        raise WeasylError('InsufficientPermissions')

    return Response(define.webpage(request.userid, "submit/reupload_submission.html", [
        "character",
        # charid
        form.charid,
    ], title="Reupload Character Image"))
Esempio n. 16
0
def reupload_submission_get_(request):
    form = request.web_input(submitid="")
    form.submitid = define.get_int(form.submitid)

    if request.userid != define.get_ownerid(submitid=form.submitid):
        return Response(define.errorpage(request.userid, errorcode.permission))

    return Response(define.webpage(request.userid, "submit/reupload_submission.html", [
        "submission",
        # SubmitID
        form.submitid,
    ], title="Reupload Submission"))
Esempio n. 17
0
    def GET(self):
        form = web.input(charid="")
        form.charid = define.get_int(form.charid)

        if self.user_id != define.get_ownerid(charid=form.charid):
            return define.errorpage(self.user_id, errorcode.permission)

        return define.webpage(self.user_id, "submit/reupload_submission.html", [
            "character",
            # charid
            form.charid,
        ])
Esempio n. 18
0
def reupload_submission_get_(request):
    form = request.web_input(submitid="")
    form.submitid = define.get_int(form.submitid)

    if request.userid != define.get_ownerid(submitid=form.submitid):
        raise WeasylError('InsufficientPermissions')

    return Response(define.webpage(request.userid, "submit/reupload_submission.html", [
        "submission",
        # SubmitID
        form.submitid,
    ], title="Reupload Submission"))
Esempio n. 19
0
def reupload_character_get_(request):
    form = request.web_input(charid="")
    form.charid = define.get_int(form.charid)

    if request.userid != define.get_ownerid(charid=form.charid):
        return Response(define.errorpage(request.userid, errorcode.permission))

    return Response(define.webpage(request.userid, "submit/reupload_submission.html", [
        "character",
        # charid
        form.charid,
    ]))
Esempio n. 20
0
def remove(userid, journalid):
    ownerid = d.get_ownerid(journalid=journalid)

    if userid not in staff.MODS and userid != ownerid:
        raise WeasylError("InsufficientPermissions")

    query = d.execute("UPDATE journal SET settings = settings || 'h'"
                      " WHERE journalid = %i AND settings !~ 'h' RETURNING journalid", [journalid])

    if query:
        welcome.journal_remove(journalid)

    return ownerid
Esempio n. 21
0
def remove(userid, journalid):
    ownerid = d.get_ownerid(journalid=journalid)

    if userid not in staff.MODS and userid != ownerid:
        raise WeasylError("InsufficientPermissions")

    query = d.execute("UPDATE journal SET settings = settings || 'h'"
                      " WHERE journalid = %i AND settings !~ 'h' RETURNING journalid", [journalid])

    if query:
        welcome.journal_remove(journalid)

    return ownerid
Esempio n. 22
0
def remove(userid, submitid):
    ownerid = d.get_ownerid(submitid=submitid)

    if userid not in staff.MODS and userid != ownerid:
        raise WeasylError("InsufficientPermissions")

    query = d.execute("UPDATE submission SET settings = settings || 'h'"
                      " WHERE submitid = %i AND settings !~ 'h' RETURNING submitid", [submitid])

    if query:
        welcome.submission_remove(submitid)

    return ownerid
Esempio n. 23
0
def remove(userid, submitid):
    ownerid = d.get_ownerid(submitid=submitid)

    if userid not in staff.MODS and userid != ownerid:
        raise WeasylError("InsufficientPermissions")

    query = d.execute("UPDATE submission SET settings = settings || 'h'"
                      " WHERE submitid = %i AND settings !~ 'h' RETURNING submitid", [submitid])

    if query:
        welcome.submission_remove(submitid)

    return ownerid
Esempio n. 24
0
def remove(userid, charid):
    ownerid = define.get_ownerid(charid=charid)

    if userid not in staff.MODS and userid != ownerid:
        raise WeasylError("InsufficientPermissions")

    query = define.execute("UPDATE character SET settings = settings || 'h'"
                           " WHERE charid = %i AND settings !~ 'h'"
                           " RETURNING charid", [charid])

    if query:
        welcome.character_remove(charid)

    return ownerid
Esempio n. 25
0
def remove(userid, charid):
    ownerid = define.get_ownerid(charid=charid)

    if userid not in staff.MODS and userid != ownerid:
        raise WeasylError("InsufficientPermissions")

    query = define.execute("UPDATE character SET settings = settings || 'h'"
                           " WHERE charid = %i AND settings !~ 'h'"
                           " RETURNING charid", [charid])

    if query:
        welcome.character_remove(charid)

    return ownerid
Esempio n. 26
0
    def POST(self):
        form = web.input(submitid="", charid="", x1="", y1="", x2="", y2="", thumbfile="")
        submitid = define.get_int(form.submitid)
        charid = define.get_int(form.charid)

        if submitid and self.user_id not in staff.ADMINS and self.user_id != define.get_ownerid(submitid=submitid):
            return define.errorpage(self.user_id)
        if charid and self.user_id not in staff.ADMINS and self.user_id != define.get_ownerid(charid=charid):
            return define.errorpage(self.user_id)
        if not submitid and not charid:
            return define.errorpage(self.user_id)

        if form.thumbfile:
            thumbnail.upload(self.user_id, form.thumbfile, submitid=submitid, charid=charid)
            if submitid:
                raise web.seeother("/manage/thumbnail?submitid=%i" % (submitid,))
            else:
                raise web.seeother("/manage/thumbnail?charid=%i" % (charid,))
        else:
            thumbnail.create(self.user_id, form.x1, form.y1, form.x2, form.y2, submitid=submitid, charid=charid)
            if submitid:
                raise web.seeother("/submission/%i" % (submitid,))
            else:
                raise web.seeother("/character/%i" % (charid,))
Esempio n. 27
0
def manage_thumbnail_post_(request):
    form = request.web_input(submitid="", charid="", x1="", y1="", x2="", y2="", thumbfile="")
    submitid = define.get_int(form.submitid)
    charid = define.get_int(form.charid)

    if submitid and request.userid not in staff.ADMINS and request.userid != define.get_ownerid(submitid=submitid):
        return Response(define.errorpage(request.userid))
    if charid and request.userid not in staff.ADMINS and request.userid != define.get_ownerid(charid=charid):
        return Response(define.errorpage(request.userid))
    if not submitid and not charid:
        return Response(define.errorpage(request.userid))

    if form.thumbfile:
        thumbnail.upload(request.userid, form.thumbfile, submitid=submitid, charid=charid)
        if submitid:
            raise HTTPSeeOther(location="/manage/thumbnail?submitid=%i" % (submitid,))
        else:
            raise HTTPSeeOther(location="/manage/thumbnail?charid=%i" % (charid,))
    else:
        thumbnail.create(request.userid, form.x1, form.y1, form.x2, form.y2, submitid=submitid, charid=charid)
        if submitid:
            raise HTTPSeeOther(location="/submission/%i" % (submitid,))
        else:
            raise HTTPSeeOther(location="/character/%i" % (charid,))
Esempio n. 28
0
    def GET(self):
        form = web.input(charid="")
        form.charid = define.get_int(form.charid)

        if self.user_id != define.get_ownerid(charid=form.charid):
            return define.errorpage(self.user_id, errorcode.permission)

        return define.webpage(
            self.user_id,
            "submit/reupload_submission.html",
            [
                "character",
                # charid
                form.charid,
            ])
Esempio n. 29
0
def reupload_character_get_(request):
    form = request.web_input(charid="")
    form.charid = define.get_int(form.charid)

    if request.userid != define.get_ownerid(charid=form.charid):
        return Response(define.errorpage(request.userid, errorcode.permission))

    return Response(
        define.webpage(
            request.userid,
            "submit/reupload_submission.html",
            [
                "character",
                # charid
                form.charid,
            ]))
Esempio n. 30
0
def collection_request_(request):
    form = request.web_input(submitid="")
    form.submitid = int(form.submitid)
    form.otherid = define.get_ownerid(submitid=form.submitid)

    if not form.otherid:
        raise WeasylError("userRecordMissing")
    if request.userid == form.otherid:
        raise WeasylError("cannotSelfCollect")

    collection.request(request.userid, form.submitid, form.otherid)
    return Response(define.errorpage(
        request.userid,
        "**Success!** Your collection request has been sent. "
        "The submission author may approve or reject this request.",
        [["Go Back", "/submission/%i" % (form.submitid,)], ["Return to the Home Page", "/index"]]))
Esempio n. 31
0
def collection_request_(request):
    form = request.web_input(submitid="")
    form.submitid = int(form.submitid)
    form.otherid = define.get_ownerid(submitid=form.submitid)

    if not form.otherid:
        raise WeasylError("userRecordMissing")
    if request.userid == form.otherid:
        raise WeasylError("cannotSelfCollect")

    collection.request(request.userid, form.submitid, form.otherid)
    return Response(define.errorpage(
        request.userid,
        "**Success!** Your collection request has been sent. "
        "The submission author may approve or reject this request.",
        [["Go Back", "/submission/%i" % (form.submitid,)], ["Return to the Home Page", "/index"]]))
Esempio n. 32
0
def reupload_submission_get_(request):
    form = request.web_input(submitid="")
    form.submitid = define.get_int(form.submitid)

    if request.userid != define.get_ownerid(submitid=form.submitid):
        return Response(define.errorpage(request.userid, errorcode.permission))

    return Response(
        define.webpage(
            request.userid,
            "submit/reupload_submission.html",
            [
                "submission",
                # SubmitID
                form.submitid,
            ],
            title="Reupload Submission"))
Esempio n. 33
0
def associate(userid, tags, submitid=None, charid=None, journalid=None):
    targetid = d.get_targetid(submitid, charid, journalid)

    # Assign table, feature, ownerid
    if submitid:
        table, feature = "searchmapsubmit", "submit"
        ownerid = d.get_ownerid(submitid=targetid)
    elif charid:
        table, feature = "searchmapchar", "char"
        ownerid = d.get_ownerid(charid=targetid)
    else:
        table, feature = "searchmapjournal", "journal"
        ownerid = d.get_ownerid(journalid=targetid)

    # Check permissions and invalid target
    if not ownerid:
        raise WeasylError("TargetRecordMissing")
    elif userid != ownerid and "g" in d.get_config(userid):
        raise WeasylError("InsufficientPermissions")
    elif ignoreuser.check(ownerid, userid):
        raise WeasylError("contentOwnerIgnoredYou")

    # Determine previous tags
    existing = d.engine.execute(
        "SELECT tagid, settings FROM {} WHERE targetid = %(target)s".format(table),
        target=targetid).fetchall()

    # Determine tag titles and tagids
    query = d.engine.execute(
        "SELECT tagid, title FROM searchtag WHERE title = ANY (%(tags)s)",
        tags=list(tags)).fetchall()

    newtags = list(tags - {x.title for x in query})

    if newtags:
        query.extend(
            d.engine.execute(
                "INSERT INTO searchtag (title) SELECT * FROM UNNEST (%(newtags)s) AS title RETURNING tagid, title",
                newtags=newtags
            ).fetchall())

    existing_tagids = {t.tagid for t in existing}
    entered_tagids = {t.tagid for t in query}

    # Assign added and removed
    added = entered_tagids - existing_tagids
    removed = existing_tagids - entered_tagids

    # Check removed artist tags
    if not can_remove_tags(userid, ownerid):
        existing_artist_tags = {t.tagid for t in existing if 'a' in t.settings}
        removed.difference_update(existing_artist_tags)
        entered_tagids.update(existing_artist_tags)

    # Remove tags
    if removed:
        d.engine.execute(
            "DELETE FROM {} WHERE targetid = %(target)s AND tagid = ANY (%(removed)s)".format(table),
            target=targetid, removed=list(removed))

    if added:
        d.execute("INSERT INTO %s VALUES %s" % (table, d.sql_number_series([[i, targetid] for i in added])))

        if userid == ownerid:
            d.execute(
                "UPDATE %s SET settings = settings || 'a' WHERE targetid = %i AND tagid IN %s",
                [table, targetid, d.sql_number_list(list(added))])

    if submitid:
        try:
            d.engine.execute(
                'INSERT INTO submission_tags (submitid, tags) VALUES (%(submission)s, %(tags)s)',
                submission=submitid, tags=list(entered_tagids))
        except PostgresError:
            result = d.engine.execute(
                'UPDATE submission_tags SET tags = %(tags)s WHERE submitid = %(submission)s',
                submission=submitid, tags=list(entered_tagids))

            assert result.rowcount == 1

        db = d.connect()
        db.execute(
            d.meta.tables['tag_updates'].insert()
            .values(submitid=submitid, userid=userid,
                    added=tag_array(added), removed=tag_array(removed)))
        if userid != ownerid:
            welcome.tag_update_insert(ownerid, submitid)

    files.append(
        "%stag.%s.%s.log" % (m.MACRO_SYS_LOG_PATH, feature, d.get_timestamp()),
        "-%sID %i  -T %i  -UID %i  -X %s\n" % (feature[0].upper(), targetid, d.get_time(), userid,
                                               " ".join(tags)))
Esempio n. 34
0
def associate(userid,
              tags,
              submitid=None,
              charid=None,
              journalid=None,
              preferred_tags_userid=None,
              optout_tags_userid=None):
    """
    Associates searchtags with a content item.

    Parameters:
        userid: The userid of the user associating tags
        tags: A set of tags
        submitid: The ID number of a submission content item to associate
        ``tags`` to. (default: None)
        charid: The ID number of a character content item to associate
        ``tags`` to. (default: None)
        journalid: The ID number of a journal content item to associate
        ``tags`` to. (default: None)
        preferred_tags_userid: The ID number of a user to associate
        ``tags`` to for Preferred tags. (default: None)
        optout_tags_userid: The ID number of a user to associate
        ``tags`` to for Opt-Out tags. (default: None)

    Returns:
        A dict containing two elements. 1) ``add_failure_restricted_tags``, which contains a space separated
        string of tag titles which failed to be added to the content item due to the user or global restricted
        tag lists; and 2) ``remove_failure_owner_set_tags``, which contains a space separated string of tag
        titles which failed to be removed from the content item due to the owner of the aforementioned item
        prohibiting users from removing tags set by the content owner.

        If an element does not have tags, the element is set to None. If neither elements are set,
        the function returns None.
    """
    targetid = d.get_targetid(submitid, charid, journalid)

    # Assign table, feature, ownerid
    if submitid:
        table, feature = "searchmapsubmit", "submit"
        ownerid = d.get_ownerid(submitid=targetid)
    elif charid:
        table, feature = "searchmapchar", "char"
        ownerid = d.get_ownerid(charid=targetid)
    elif journalid:
        table, feature = "searchmapjournal", "journal"
        ownerid = d.get_ownerid(journalid=targetid)
    elif preferred_tags_userid:
        table, feature = "artist_preferred_tags", "user"
        targetid = ownerid = preferred_tags_userid
    elif optout_tags_userid:
        table, feature = "artist_optout_tags", "user"
        targetid = ownerid = optout_tags_userid
    else:
        raise WeasylError("Unexpected")

    # Check permissions and invalid target
    if not ownerid:
        raise WeasylError("TargetRecordMissing")
    elif userid != ownerid and ("g" in d.get_config(userid) or
                                preferred_tags_userid or optout_tags_userid):
        # disallow if user is forbidden from tagging, or trying to set artist tags on someone other than themselves
        raise WeasylError("InsufficientPermissions")
    elif ignoreuser.check(ownerid, userid):
        raise WeasylError("contentOwnerIgnoredYou")

    # Determine previous tagids, titles, and settings
    existing = d.engine.execute(
        "SELECT tagid, title, settings FROM {} INNER JOIN searchtag USING (tagid) WHERE targetid = %(target)s"
        .format(table),
        target=targetid).fetchall()

    # Retrieve tag titles and tagid pairs, for new (if any) and existing tags
    query = add_and_get_searchtags(tags)

    existing_tagids = {t.tagid for t in existing}
    entered_tagids = {t.tagid for t in query}

    # Assign added and removed
    added = entered_tagids - existing_tagids
    removed = existing_tagids - entered_tagids

    # enforce the limit on artist preference tags
    if preferred_tags_userid and (len(added) - len(removed) +
                                  len(existing)) > MAX_PREFERRED_TAGS:
        raise WeasylError("tooManyPreferenceTags")

    # Track which tags fail to be added or removed to later notify the user (Note: These are tagids at this stage)
    add_failure_restricted_tags = None
    remove_failure_owner_set_tags = None

    # If the modifying user is not the owner of the object, and is not staff, check user/global restriction lists
    if userid != ownerid and userid not in staff.MODS:
        user_rtags = set(query_user_restricted_tags(ownerid))
        global_rtags = set(query_global_restricted_tags())
        add_failure_restricted_tags = remove_restricted_tags(
            user_rtags | global_rtags, query)
        added -= add_failure_restricted_tags
        if len(add_failure_restricted_tags) == 0:
            add_failure_restricted_tags = None

    # Check removed artist tags
    if not can_remove_tags(userid, ownerid):
        existing_artist_tags = {t.tagid for t in existing if 'a' in t.settings}
        remove_failure_owner_set_tags = removed & existing_artist_tags
        removed.difference_update(existing_artist_tags)
        entered_tagids.update(existing_artist_tags)
        # Submission items use a different method of tag protection for artist tags; ignore them
        if submitid or len(remove_failure_owner_set_tags) == 0:
            remove_failure_owner_set_tags = None

    # Remove tags
    if removed:
        d.engine.execute(
            "DELETE FROM {} WHERE targetid = %(target)s AND tagid = ANY (%(removed)s)"
            .format(table),
            target=targetid,
            removed=list(removed))

    if added:
        d.engine.execute(
            "INSERT INTO {} SELECT tag, %(target)s FROM UNNEST (%(added)s) AS tag"
            .format(table),
            target=targetid,
            added=list(added))

        # preference/optout tags can only be set by the artist, so this settings column does not apply
        if userid == ownerid and not (preferred_tags_userid
                                      or optout_tags_userid):
            d.engine.execute(
                "UPDATE {} SET settings = settings || 'a' WHERE targetid = %(target)s AND tagid = ANY (%(added)s)"
                .format(table),
                target=targetid,
                added=list(added))

    if submitid:
        d.engine.execute(
            'INSERT INTO submission_tags (submitid, tags) VALUES (%(submission)s, %(tags)s) '
            'ON CONFLICT (submitid) DO UPDATE SET tags = %(tags)s',
            submission=submitid,
            tags=list(entered_tagids))

        db = d.connect()
        db.execute(d.meta.tables['tag_updates'].insert().values(
            submitid=submitid,
            userid=userid,
            added=tag_array(added),
            removed=tag_array(removed)))
        if userid != ownerid:
            welcome.tag_update_insert(ownerid, submitid)

    files.append(
        "%stag.%s.%s.log" % (m.MACRO_SYS_LOG_PATH, feature, d.get_timestamp()),
        "-%sID %i  -T %i  -UID %i  -X %s\n" %
        (feature[0].upper(), targetid, d.get_time(), userid, " ".join(tags)))

    # Return dict with any tag titles as a string that failed to be added or removed
    if add_failure_restricted_tags or remove_failure_owner_set_tags:
        if add_failure_restricted_tags:
            add_failure_restricted_tags = " ".join({
                tag.title
                for tag in query if tag.tagid in add_failure_restricted_tags
            })
        if remove_failure_owner_set_tags:
            remove_failure_owner_set_tags = " ".join({
                tag.title
                for tag in existing
                if tag.tagid in remove_failure_owner_set_tags
            })
        return {
            "add_failure_restricted_tags": add_failure_restricted_tags,
            "remove_failure_owner_set_tags": remove_failure_owner_set_tags
        }
    else:
        return None
Esempio n. 35
0
def associate(userid, tags, submitid=None, charid=None, journalid=None, preferred_tags_userid=None, optout_tags_userid=None):
    """
    Associates searchtags with a content item.

    Parameters:
        userid: The userid of the user associating tags
        tags: A set of tags
        submitid: The ID number of a submission content item to associate
        ``tags`` to. (default: None)
        charid: The ID number of a character content item to associate
        ``tags`` to. (default: None)
        journalid: The ID number of a journal content item to associate
        ``tags`` to. (default: None)
        preferred_tags_userid: The ID number of a user to associate
        ``tags`` to for Preferred tags. (default: None)
        optout_tags_userid: The ID number of a user to associate
        ``tags`` to for Opt-Out tags. (default: None)

    Returns:
        A dict containing two elements. 1) ``add_failure_restricted_tags``, which contains a space separated
        string of tag titles which failed to be added to the content item due to the user or global restricted
        tag lists; and 2) ``remove_failure_owner_set_tags``, which contains a space separated string of tag
        titles which failed to be removed from the content item due to the owner of the aforementioned item
        prohibiting users from removing tags set by the content owner.

        If an element does not have tags, the element is set to None. If neither elements are set,
        the function returns None.
    """
    targetid = d.get_targetid(submitid, charid, journalid)

    # Assign table, feature, ownerid
    if submitid:
        table, feature = "searchmapsubmit", "submit"
        ownerid = d.get_ownerid(submitid=targetid)
    elif charid:
        table, feature = "searchmapchar", "char"
        ownerid = d.get_ownerid(charid=targetid)
    elif journalid:
        table, feature = "searchmapjournal", "journal"
        ownerid = d.get_ownerid(journalid=targetid)
    elif preferred_tags_userid:
        table, feature = "artist_preferred_tags", "user"
        targetid = ownerid = preferred_tags_userid
    elif optout_tags_userid:
        table, feature = "artist_optout_tags", "user"
        targetid = ownerid = optout_tags_userid
    else:
        raise WeasylError("Unexpected")

    # Check permissions and invalid target
    if not ownerid:
        raise WeasylError("TargetRecordMissing")
    elif userid != ownerid and ("g" in d.get_config(userid) or preferred_tags_userid or optout_tags_userid):
        # disallow if user is forbidden from tagging, or trying to set artist tags on someone other than themselves
        raise WeasylError("InsufficientPermissions")
    elif ignoreuser.check(ownerid, userid):
        raise WeasylError("contentOwnerIgnoredYou")

    # Determine previous tagids, titles, and settings
    existing = d.engine.execute(
        "SELECT tagid, title, settings FROM {} INNER JOIN searchtag USING (tagid) WHERE targetid = %(target)s".format(table),
        target=targetid).fetchall()

    # Retrieve tag titles and tagid pairs, for new (if any) and existing tags
    query = add_and_get_searchtags(tags)

    existing_tagids = {t.tagid for t in existing}
    entered_tagids = {t.tagid for t in query}

    # Assign added and removed
    added = entered_tagids - existing_tagids
    removed = existing_tagids - entered_tagids

    # enforce the limit on artist preference tags
    if preferred_tags_userid and (len(added) - len(removed) + len(existing)) > MAX_PREFERRED_TAGS:
        raise WeasylError("tooManyPreferenceTags")

    # Track which tags fail to be added or removed to later notify the user (Note: These are tagids at this stage)
    add_failure_restricted_tags = None
    remove_failure_owner_set_tags = None

    # If the modifying user is not the owner of the object, and is not staff, check user/global restriction lists
    if userid != ownerid and userid not in staff.MODS:
        user_rtags = set(query_user_restricted_tags(ownerid))
        global_rtags = set(query_global_restricted_tags())
        add_failure_restricted_tags = remove_restricted_tags(user_rtags | global_rtags, query)
        added -= add_failure_restricted_tags
        if len(add_failure_restricted_tags) == 0:
            add_failure_restricted_tags = None

    # Check removed artist tags
    if not can_remove_tags(userid, ownerid):
        existing_artist_tags = {t.tagid for t in existing if 'a' in t.settings}
        remove_failure_owner_set_tags = removed & existing_artist_tags
        removed.difference_update(existing_artist_tags)
        entered_tagids.update(existing_artist_tags)
        # Submission items use a different method of tag protection for artist tags; ignore them
        if submitid or len(remove_failure_owner_set_tags) == 0:
            remove_failure_owner_set_tags = None

    # Remove tags
    if removed:
        d.engine.execute(
            "DELETE FROM {} WHERE targetid = %(target)s AND tagid = ANY (%(removed)s)".format(table),
            target=targetid, removed=list(removed))

    if added:
        d.engine.execute(
            "INSERT INTO {} SELECT tag, %(target)s FROM UNNEST (%(added)s) AS tag".format(table),
            target=targetid, added=list(added))

        # preference/optout tags can only be set by the artist, so this settings column does not apply
        if userid == ownerid and not (preferred_tags_userid or optout_tags_userid):
            d.execute(
                "UPDATE %s SET settings = settings || 'a' WHERE targetid = %i AND tagid IN %s",
                [table, targetid, d.sql_number_list(list(added))])

    if submitid:
        d.engine.execute(
            'INSERT INTO submission_tags (submitid, tags) VALUES (%(submission)s, %(tags)s) '
            'ON CONFLICT (submitid) DO UPDATE SET tags = %(tags)s',
            submission=submitid, tags=list(entered_tagids))

        db = d.connect()
        db.execute(
            d.meta.tables['tag_updates'].insert()
            .values(submitid=submitid, userid=userid,
                    added=tag_array(added), removed=tag_array(removed)))
        if userid != ownerid:
            welcome.tag_update_insert(ownerid, submitid)

    files.append(
        "%stag.%s.%s.log" % (m.MACRO_SYS_LOG_PATH, feature, d.get_timestamp()),
        "-%sID %i  -T %i  -UID %i  -X %s\n" % (feature[0].upper(), targetid, d.get_time(), userid,
                                               " ".join(tags)))

    # Return dict with any tag titles as a string that failed to be added or removed
    if add_failure_restricted_tags or remove_failure_owner_set_tags:
        if add_failure_restricted_tags:
            add_failure_restricted_tags = " ".join({tag.title for tag in query if tag.tagid in add_failure_restricted_tags})
        if remove_failure_owner_set_tags:
            remove_failure_owner_set_tags = " ".join({tag.title for tag in existing if tag.tagid in remove_failure_owner_set_tags})
        return {"add_failure_restricted_tags": add_failure_restricted_tags,
                "remove_failure_owner_set_tags": remove_failure_owner_set_tags}
    else:
        return None
Esempio n. 36
0
def associate(userid, tags, submitid=None, charid=None, journalid=None):
    targetid = d.get_targetid(submitid, charid, journalid)

    # Assign table, feature, ownerid
    if submitid:
        table, feature = "searchmapsubmit", "submit"
        ownerid = d.get_ownerid(submitid=targetid)
    elif charid:
        table, feature = "searchmapchar", "char"
        ownerid = d.get_ownerid(charid=targetid)
    else:
        table, feature = "searchmapjournal", "journal"
        ownerid = d.get_ownerid(journalid=targetid)

    # Check permissions and invalid target
    if not ownerid:
        raise WeasylError("TargetRecordMissing")
    elif userid != ownerid and "g" in d.get_config(userid):
        raise WeasylError("InsufficientPermissions")
    elif ignoreuser.check(ownerid, userid):
        raise WeasylError("contentOwnerIgnoredYou")

    # Determine previous tags
    existing = d.engine.execute(
        "SELECT tagid, settings FROM {} WHERE targetid = %(target)s".format(table),
        target=targetid).fetchall()

    # Determine tag titles and tagids
    query = d.engine.execute(
        "SELECT tagid, title FROM searchtag WHERE title = ANY (%(tags)s)",
        tags=list(tags)).fetchall()

    newtags = list(tags - {x.title for x in query})

    if newtags:
        query.extend(
            d.engine.execute(
                "INSERT INTO searchtag (title) SELECT * FROM UNNEST (%(newtags)s) AS title RETURNING tagid, title",
                newtags=newtags
            ).fetchall())

    existing_tagids = {t.tagid for t in existing}
    entered_tagids = {t.tagid for t in query}

    # Assign added and removed
    added = entered_tagids - existing_tagids
    removed = existing_tagids - entered_tagids

    # Check removed artist tags
    if not can_remove_tags(userid, ownerid):
        existing_artist_tags = {t.tagid for t in existing if 'a' in t.settings}
        removed.difference_update(existing_artist_tags)
        entered_tagids.update(existing_artist_tags)

    # Remove tags
    if removed:
        d.engine.execute(
            "DELETE FROM {} WHERE targetid = %(target)s AND tagid = ANY (%(removed)s)".format(table),
            target=targetid, removed=list(removed))

    if added:
        d.engine.execute(
            "INSERT INTO {} SELECT tag, %(target)s FROM UNNEST (%(added)s) AS tag".format(table),
            target=targetid, added=list(added))

        if userid == ownerid:
            d.execute(
                "UPDATE %s SET settings = settings || 'a' WHERE targetid = %i AND tagid IN %s",
                [table, targetid, d.sql_number_list(list(added))])

    if submitid:
        d.engine.execute(
            'INSERT INTO submission_tags (submitid, tags) VALUES (%(submission)s, %(tags)s) '
            'ON CONFLICT (submitid) DO UPDATE SET tags = %(tags)s',
            submission=submitid, tags=list(entered_tagids))

        db = d.connect()
        db.execute(
            d.meta.tables['tag_updates'].insert()
            .values(submitid=submitid, userid=userid,
                    added=tag_array(added), removed=tag_array(removed)))
        if userid != ownerid:
            welcome.tag_update_insert(ownerid, submitid)

    files.append(
        "%stag.%s.%s.log" % (m.MACRO_SYS_LOG_PATH, feature, d.get_timestamp()),
        "-%sID %i  -T %i  -UID %i  -X %s\n" % (feature[0].upper(), targetid, d.get_time(), userid,
                                               " ".join(tags)))