@@ -3,58 +3,152 @@ defmodule GroupherServer.CMS.Delegate.AbuseReport do
33 CURD and operations for article comments
44 """
55 import Ecto.Query , warn: false
6- # import Helper.Utils, only: [done: 1]
6+ import Helper.Utils , only: [ done: 1 , strip_struct : 1 ]
77
88 import GroupherServer.CMS.Helper.Matcher2
9- # import ShortMaps
9+ import ShortMaps
1010
11- alias Helper . { ORM }
11+ alias Helper.ORM
12+ alias Helper.QueryBuilder
1213 alias GroupherServer . { Accounts , CMS , Repo }
1314
1415 alias Accounts.User
1516 alias CMS . { AbuseReport , Embeds }
1617
17- # alias Accounts.User
18+ alias Ecto.Multi
1819
19- def create_report ( type , content_id , % { reason: reason } , % User { } = user ) do
20+ @ doc """
21+ list paged reports for both comment and article
22+ """
23+ def list_reports ( type , content_id , % { page: page , size: size } = filter ) do
24+ with { :ok , info } <- match ( type ) do
25+ query = from ( r in AbuseReport , where: field ( r , ^ info . foreign_key ) == ^ content_id )
26+
27+ query
28+ |> QueryBuilder . filter_pack ( filter )
29+ |> ORM . paginater ( ~m( page size) a )
30+ |> done ( )
31+ end
32+ end
33+
34+ @ doc """
35+ report article content
36+ """
37+ def report_article ( thread , article_id , reason , attr , % User { } = user ) do
38+ with { :ok , info } <- match ( thread ) ,
39+ { :ok , article } <- ORM . find ( info . model , article_id ) do
40+ Multi . new ( )
41+ |> Multi . run ( :create_abuse_report , fn _ , _ ->
42+ create_report ( thread , article_id , reason , attr , user )
43+ end )
44+ |> Multi . run ( :update_report_flag , fn _ , _ ->
45+ update_report_meta ( info , article , true )
46+ end )
47+ |> Repo . transaction ( )
48+ |> result ( )
49+ end
50+ end
51+
52+ def undo_report_article_comment ( comment_id , % User { } = user ) do
53+ undo_report_article ( :article_comment , comment_id , user )
54+ end
55+
56+ @ doc """
57+ undo report article content
58+ """
59+ def undo_report_article ( thread , article_id , % User { } = user ) do
60+ with { :ok , info } <- match ( thread ) ,
61+ { :ok , article } <- ORM . find ( info . model , article_id ) do
62+ Multi . new ( )
63+ |> Multi . run ( :delete_abuse_report , fn _ , _ ->
64+ delete_report ( thread , article_id , user )
65+ end )
66+ |> Multi . run ( :update_report_flag , fn _ , _ ->
67+ update_report_meta ( info , article , false )
68+ end )
69+ |> Repo . transaction ( )
70+ |> result ( )
71+ end
72+ end
73+
74+ def create_report ( type , content_id , reason , attr , % User { } = user ) do
2075 with { :ok , info } <- match ( type ) ,
2176 { :ok , report } <- not_reported_before ( info , content_id , user ) do
2277 case report do
2378 nil ->
24- updated_report_cases = [
79+ report_cases = [
2580 % {
2681 reason: reason ,
27- additional_reason: "additional_reason" ,
82+ attr: attr ,
2883 user: % { login: user . login , nickname: user . nickname }
2984 }
3085 ]
3186
3287 args =
33- % { report_cases_count: 1 , report_cases: updated_report_cases }
88+ % { report_cases_count: 1 , report_cases: report_cases }
3489 |> Map . put ( info . foreign_key , content_id )
3590
3691 AbuseReport |> ORM . create ( args )
3792
3893 _ ->
39- updated_report_cases =
94+ user = % { login: user . login , nickname: user . nickname }
95+
96+ report_cases =
4097 report . report_cases
4198 |> List . insert_at (
4299 length ( report . report_cases ) ,
43- % Embeds.AbuseReportCase {
44- reason: reason ,
45- additional_reason: "additional_reason" ,
46- user: % { login: user . login , nickname: user . nickname }
47- }
100+ % Embeds.AbuseReportCase { reason: reason , attr: attr , user: user }
48101 )
49102
50103 report
51- |> Ecto.Changeset . change ( % { report_cases_count: length ( updated_report_cases ) } )
52- |> Ecto.Changeset . put_embed ( :report_cases , updated_report_cases )
104+ |> Ecto.Changeset . change ( % { report_cases_count: length ( report_cases ) } )
105+ |> Ecto.Changeset . put_embed ( :report_cases , report_cases )
106+ |> Repo . update ( )
107+ end
108+ end
109+ end
110+
111+ defp delete_report ( thread , content_id , % User { } = user ) do
112+ with { :ok , info } <- match ( thread ) ,
113+ { :error , _ } <- not_reported_before ( info , content_id , user ) ,
114+ { :ok , report } = ORM . find_by ( AbuseReport , Map . put ( % { } , info . foreign_key , content_id ) ) do
115+ case length ( report . report_cases ) do
116+ 1 ->
117+ ORM . delete ( report )
118+
119+ _ ->
120+ report_cases = report . report_cases |> Enum . reject ( & ( & 1 . user . login == user . login ) )
121+
122+ report
123+ |> Ecto.Changeset . change ( % { report_cases_count: length ( report_cases ) } )
124+ |> Ecto.Changeset . put_embed ( :report_cases , report_cases )
53125 |> Repo . update ( )
54126 end
55127 end
56128 end
57129
130+ # update is_reported flag and reported_count in mete for article or comment
131+ defp update_report_meta ( info , content , is_reported ) do
132+ case ORM . find_by ( AbuseReport , Map . put ( % { } , info . foreign_key , content . id ) ) do
133+ { :ok , record } ->
134+ reported_count = record . report_cases |> length
135+ meta = content . meta |> Map . merge ( % { reported_count: reported_count } ) |> strip_struct
136+
137+ content
138+ |> Ecto.Changeset . change ( % { is_reported: is_reported } )
139+ |> Ecto.Changeset . put_embed ( :meta , meta )
140+ |> Repo . update ( )
141+
142+ { :error , _ } ->
143+ meta = content . meta |> Map . merge ( % { reported_count: 0 } ) |> strip_struct
144+
145+ content
146+ |> Ecto.Changeset . change ( % { is_reported: false } )
147+ |> Ecto.Changeset . put_embed ( :meta , meta )
148+ |> Repo . update ( )
149+ end
150+ end
151+
58152 defp not_reported_before ( info , content_id , % User { login: login } ) do
59153 query = from ( r in AbuseReport , where: field ( r , ^ info . foreign_key ) == ^ content_id )
60154
@@ -71,9 +165,13 @@ defmodule GroupherServer.CMS.Delegate.AbuseReport do
71165 |> length
72166 |> Kernel . > ( 0 )
73167
74- if not reported_before ,
75- do: { :ok , report } ,
76- else: { :error , "#{ login } already reported" }
168+ if not reported_before , do: { :ok , report } , else: { :error , "#{ login } already reported" }
77169 end
78170 end
171+
172+ defp result ( { :ok , % { update_report_flag: result } } ) , do: result |> done ( )
173+
174+ defp result ( { :error , _ , result , _steps } ) do
175+ { :error , result }
176+ end
79177end
0 commit comments