diff options
-rw-r--r-- | elm/Report.elm | 42 | ||||
-rw-r--r-- | lib/VNWeb/Discussions/Thread.pm | 2 | ||||
-rw-r--r-- | lib/VNWeb/HTML.pm | 2 | ||||
-rw-r--r-- | lib/VNWeb/Misc/Reports.pm | 45 | ||||
-rw-r--r-- | lib/VNWeb/Reviews/Page.pm | 2 | ||||
-rw-r--r-- | lib/VNWeb/Reviews/VNTab.pm | 2 | ||||
-rw-r--r-- | sql/schema.sql | 7 | ||||
-rw-r--r-- | util/updates/wip-reviews.sql | 7 |
8 files changed, 70 insertions, 39 deletions
diff --git a/elm/Report.elm b/elm/Report.elm index c3254397..f63a9411 100644 --- a/elm/Report.elm +++ b/elm/Report.elm @@ -31,14 +31,16 @@ type Msg type alias ReasonLabel = { label : String - , vis : String -> String -> Bool -- Given an rtype & objectid, returns whether it should be listed + , vis : String -> Bool -- Given an objectid, returns whether it should be listed , submit : Bool -- Whether it allows submission of the form - , msg : String -> String -> List (Html Msg) -- Message to display + , msg : String -> List (Html Msg) -- Message to display } -vis _ _ = True -nomsg _ _ = [] +vis _ = True +nomsg _ = [] +objtype s o = String.any (\c -> String.startsWith (String.fromChar c) o) s +editable = objtype "vrpcs" initial = { label = "-- Select --" , vis = vis, submit = False , msg = nomsg } reasons : List ReasonLabel @@ -55,19 +57,19 @@ reasons = , msg = nomsg } , { label = "Off-topic / wrong board" - , vis = \t _ -> t == "t" + , vis = objtype "tw" , submit = True , msg = nomsg } , { label = "Unwelcome behavior" - , vis = \t _ -> t == "t" + , vis = objtype "tw" , submit = True , msg = nomsg } , { label = "Unmarked spoilers" , vis = vis , submit = True - , msg = \t o -> if not (t == "db" && not (String.startsWith "d" o)) then [] else + , msg = \o -> if editable o then [] else [ text "VNDB is an open wiki, it is often easier if you removed the spoilers yourself by " , a [ href ("/" ++ o ++ "/edit") ] [ text " editing the entry" ] , text ". You likely know more about this entry than our moderators, after all. " @@ -78,9 +80,9 @@ reasons = ] } , { label = "Incorrect information" - , vis = \t o -> t == "db" && not (String.startsWith "d" o) + , vis = editable , submit = False - , msg = \_ o -> + , msg = \o -> [ text "VNDB is an open wiki, you can correct the information in this database yourself by " , a [ href ("/" ++ o ++ "/edit") ] [ text " editing the entry" ] , text ". You likely know more about this entry than our moderators, after all. " @@ -91,9 +93,9 @@ reasons = ] } , { label = "Missing information" - , vis = \t o -> t == "db" && not (String.startsWith "d" o) + , vis = editable , submit = False - , msg = \_ o -> + , msg = \o -> [ text "VNDB is an open wiki, you can add any missing information to this database yourself. " , text "You likely know more about this entry than our moderators, after all. " , br [] [] @@ -103,9 +105,9 @@ reasons = ] } , { label = "Not a visual novel" - , vis = \t o -> t == "db" && String.startsWith "v" o + , vis = objtype "v" , submit = False - , msg = \_ _ -> + , msg = \_ -> [ text "If you suspect that this entry does not adhere to our " , a [ href "/d2#1" ] [ text "inclusion criteria" ] , text ", please report it in " @@ -114,20 +116,20 @@ reasons = ] } , { label = "Does not belong here" - , vis = \t o -> t == "db" && not (String.startsWith "v" o || String.startsWith "d" o) + , vis = \o -> editable o && not (objtype "v" o) , submit = True , msg = nomsg } , { label = "Duplicate entry" - , vis = \t o -> t == "db" && not (String.startsWith "d" o) + , vis = editable , submit = True - , msg = \_ _ -> [ text "Please include a link to the entry that this is a duplicate of." ] + , msg = \_ -> [ text "Please include a link to the entry that this is a duplicate of." ] } , { label = "Other" , vis = vis , submit = True - , msg = \t o -> - if t == "db" && not (String.startsWith "d" o) + , msg = \o -> + if editable o then [ text "Keep in mind that VNDB is an open wiki, you can edit most of the information in this database." , br [] [] , text "Reports for issues that do not require a moderator to get involved will most likely be ignored." @@ -153,7 +155,7 @@ update msg (state,model) = view : Model -> Html Msg view (state,model) = let - lst = List.filter (\l -> l.vis model.rtype model.object) reasons + lst = List.filter (\l -> l.vis model.object) reasons cur = List.filter (\l -> l.label == model.reason) lst |> List.head |> Maybe.withDefault initial in form_ Submit (state == Api.Loading) @@ -173,7 +175,7 @@ view (state,model) = else text "We generally do not provide feedback on reports, but you may leave your email address in the message if you wish to be available for clarification." ] , formField "reason::Reason" [ inputSelect "reason" model.reason Reason [style "width" "300px"] <| List.map (\l->(l.label,l.label)) lst ] - , formField "" (cur.msg model.rtype model.object) + , formField "" (cur.msg model.object) ] ++ if not cur.submit then [] else [ formField "message::Message" [ inputTextArea "message" model.message Message [] ] , formField "" [ submitButton "Submit" state True ] diff --git a/lib/VNWeb/Discussions/Thread.pm b/lib/VNWeb/Discussions/Thread.pm index 0949309d..3712826d 100644 --- a/lib/VNWeb/Discussions/Thread.pm +++ b/lib/VNWeb/Discussions/Thread.pm @@ -119,7 +119,7 @@ sub posts_ { a_ href => "/$t->{id}.$_->{num}/edit", 'edit'; txt_ ' - '; } - a_ href => "/report/t/$t->{id}.$_->{num}", 'report'; + a_ href => "/report/$t->{id}.$_->{num}", 'report'; txt_ ' >'; }; if($_->{hidden}) { diff --git a/lib/VNWeb/HTML.pm b/lib/VNWeb/HTML.pm index 159b1d4b..28cfa66a 100644 --- a/lib/VNWeb/HTML.pm +++ b/lib/VNWeb/HTML.pm @@ -771,7 +771,7 @@ sub itemmsg_ { txt_ 'You can not edit this page. '; } } - a_ href => "/report/db/$type$obj->{id}", 'Report an issue on this page.'; + a_ href => "/report/$type$obj->{id}", 'Report an issue on this page.'; }; } diff --git a/lib/VNWeb/Misc/Reports.pm b/lib/VNWeb/Misc/Reports.pm index 1d610076..309650f5 100644 --- a/lib/VNWeb/Misc/Reports.pm +++ b/lib/VNWeb/Misc/Reports.pm @@ -6,26 +6,49 @@ my $reportsperday = 5; my @STATUS = qw/new busy done dismissed/; -# Requires objects with {rtype,object} fields, adds a HTML-formatted 'title' field, which formats and links to the entry. +# Requires objects with {object,objectnum} fields, adds a HTML-formatted 'title' field, which formats and links to the entry. sub enrich_object { for my $o (@_) { delete $o->{title}; - if($o->{rtype} eq 't' && $o->{object} =~ /^$RE{postid}$/) { + if($o->{object} =~ /^$RE{wid}$/ && $o->{objectnum}) { + my $w = tuwf->dbRowi( + 'SELECT rp.id, rp.num, ', sql_user(), ' + FROM reviews_posts rp LEFT JOIN users u ON u.id = rp.uid + WHERE NOT rp.hidden AND rp.id =', \$o->{object}, 'AND rp.num =', \$o->{objectnum} + ); + $o->{title} = xml_string sub { + txt_ 'Comment '; + a_ href => "/$o->{object}.$o->{objectnum}", "#$o->{objectnum}"; + txt_ ' on review '; + a_ href => "/$o->{object}.$o->{objectnum}", $o->{object}; + txt_ ' by '; + user_ $w; + } if $w->{id}; + + } elsif($o->{object} =~ /^$RE{wid}$/) { + my $w = tuwf->dbRowi('SELECT r.id, v.title,', sql_user(), 'FROM reviews r JOIN vn v ON v.id = r.vid LEFT JOIN users u ON u.id = r.uid WHERE r.id =', \$o->{object}); + $o->{title} = xml_string sub { + a_ href => "/$o->{object}", "Review of $w->{title}"; + txt_ ' by '; + user_ $w; + } if $w->{id}; + + } elsif($o->{object} =~ /^$RE{tid}$/ && $o->{objectnum}) { my $post = tuwf->dbRowi( 'SELECT tp.num, t.title, ', sql_user(), ' FROM threads t JOIN threads_posts tp ON tp.tid = t.id LEFT JOIN users u ON u.id = tp.uid - WHERE NOT t.hidden AND NOT t.private AND t.id =', \"$+{id}", 'AND tp.num =', \"$+{num}" + WHERE NOT t.hidden AND NOT t.private AND t.id =', \$o->{object}, 'AND tp.num =', \$o->{objectnum} ); $o->{title} = xml_string sub { txt_ 'Post '; - a_ href => "/$o->{object}", "#$post->{num}"; + a_ href => "/$o->{object}.$o->{objectnum}", "#$post->{num}"; txt_ ' on '; - a_ href => "/$o->{object}", $post->{title}; + a_ href => "/$o->{object}.$o->{objectnum}", $post->{title}; txt_ ' by '; user_ $post; } if $post->{num}; - } elsif($o->{rtype} eq 'db' && $o->{object} =~ /^([vrpcsd])$RE{num}$/) { + } elsif($o->{object} =~ /^([vrpcsd])$RE{num}$/ && !defined $o->{objectnum}) { my($t,$id) = ($1, $+{num}); my $obj = dbobj $t, $id; $o->{title} = xml_string sub { @@ -44,8 +67,8 @@ sub is_throttled { my $FORM = form_compile any => { - rtype => {}, object => {}, + objectnum=> { required => 0, uint => 1 }, title => {}, reason => { maxlength => 50 }, message => { required => 0, default => '', maxlength => 50000 }, @@ -61,8 +84,8 @@ elm_api Report => undef, $FORM, sub { tuwf->dbExeci('INSERT INTO reports', { uid => auth->uid, ip => auth ? undef : tuwf->reqIP, - rtype => $data->{rtype}, object => $data->{object}, + objectnum=> $data->{objectnum}, reason => $data->{reason}, message => $data->{message}, }); @@ -70,8 +93,8 @@ elm_api Report => undef, $FORM, sub { }; -TUWF::get qr{/report/(?<rtype>t|db)/(?<object>.+)}, sub { - my $obj = { rtype => tuwf->capture('rtype'), object => tuwf->capture('object') }; +TUWF::get qr{/report/(?<object>[vrpcsdtw]$RE{num})(?:\.(?<subid>$RE{num}))?}, sub { + my $obj = { object => tuwf->capture('object'), objectnum => tuwf->capture('subid') }; enrich_object $obj; return tuwf->resNotFound if !$obj->{title}; @@ -143,7 +166,7 @@ TUWF::get qr{/report/list}, sub { my $cnt = tuwf->dbVali('SELECT count(*) FROM reports r WHERE', $where); my $lst = tuwf->dbPagei({results => 25, page => $opt->{p}}, - 'SELECT r.id,', sql_totime('r.date'), 'as date, r.uid, u.username, r.ip, r.reason, r.rtype, r.object, r.status, r.message, r.log + 'SELECT r.id,', sql_totime('r.date'), 'as date, r.uid, u.username, r.ip, r.reason, r.object, r.objectnum, r.status, r.message, r.log FROM reports r LEFT JOIN users u ON u.id = r.uid WHERE', $where, ' diff --git a/lib/VNWeb/Reviews/Page.pm b/lib/VNWeb/Reviews/Page.pm index 190e317a..d235373e 100644 --- a/lib/VNWeb/Reviews/Page.pm +++ b/lib/VNWeb/Reviews/Page.pm @@ -124,7 +124,7 @@ TUWF::get qr{/$RE{wid}(?:(?<sep>[\./])$RE{num})?}, sub { a_ href => "/$w->{id}/edit", 'Edit'; b_ class => 'grayedout', ' | '; } - a_ href => "/report/w/$w->{id}", 'Report'; # TODO + a_ href => "/report/$w->{id}", 'Report'; }; h1_ 'Review'; review_ $w; diff --git a/lib/VNWeb/Reviews/VNTab.pm b/lib/VNWeb/Reviews/VNTab.pm index c39ef098..d9f276a1 100644 --- a/lib/VNWeb/Reviews/VNTab.pm +++ b/lib/VNWeb/Reviews/VNTab.pm @@ -40,7 +40,7 @@ sub reviews_ { a_ href => "/$r->{id}/edit", 'edit'; txt_ ' - '; } - a_ href => "/report/w/$r->{id}", 'report'; # TODO + a_ href => "/report/$r->{id}", 'report'; txt_ '>'; }; if($r->{spoiler}) { diff --git a/sql/schema.sql b/sql/schema.sql index bcf1bfc2..88ceb384 100644 --- a/sql/schema.sql +++ b/sql/schema.sql @@ -64,7 +64,6 @@ CREATE TYPE producer_type AS ENUM ('co', 'in', 'ng'); CREATE TYPE producer_relation AS ENUM ('old', 'new', 'sub', 'par', 'imp', 'ipa', 'spa', 'ori'); CREATE TYPE release_type AS ENUM ('complete', 'partial', 'trial'); CREATE TYPE report_status AS ENUM ('new', 'busy', 'done', 'dismissed'); -CREATE TYPE report_type AS ENUM ('t', 'db'); CREATE TYPE tag_category AS ENUM('cont', 'ero', 'tech'); CREATE TYPE vn_relation AS ENUM ('seq', 'preq', 'set', 'alt', 'char', 'side', 'par', 'ser', 'fan', 'orig'); CREATE TYPE session_type AS ENUM ('web', 'pass', 'mail'); @@ -491,11 +490,11 @@ CREATE TABLE reports ( uid integer, -- user who created the report, if logged in ip inet, -- IP address of the visitor, if not logged in reason text NOT NULL, - rtype report_type NOT NULL, status report_status NOT NULL DEFAULT 'new', - object text NOT NULL, -- The id of the thing being reported + object vndbid NOT NULL, -- The id of the thing being reported message text NOT NULL, - log text NOT NULL DEFAULT '' + log text NOT NULL DEFAULT '', + objectnum integer -- The sub-id of the thing to be reported ); -- rlists diff --git a/util/updates/wip-reviews.sql b/util/updates/wip-reviews.sql index 6ce5182d..677eb7b6 100644 --- a/util/updates/wip-reviews.sql +++ b/util/updates/wip-reviews.sql @@ -1,3 +1,10 @@ +ALTER TABLE reports ADD COLUMN objectnum integer; +UPDATE reports SET objectnum = regexp_replace(object, '^.+\.([0-9]+)$', '\1')::integer WHERE object LIKE '%.%'; +ALTER TABLE reports ALTER COLUMN object TYPE vndbid USING regexp_replace(object, '\.[0-9]+$','')::vndbid; +ALTER TABLE reports DROP COLUMN rtype; +DROP TYPE report_type; + + -- WIP: The modifications in this file are not final and haven't been integrated in sql/ yet. CREATE SEQUENCE reviews_seq; |