Commit | Line | Data |
---|---|---|
6bba33d7 | 1 | # GNU MediaGoblin -- federated, autonomous media hosting |
2 | # Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. | |
3 | # | |
4 | # This program is free software: you can redistribute it and/or modify | |
5 | # it under the terms of the GNU Affero General Public License as published by | |
6 | # the Free Software Foundation, either version 3 of the License, or | |
7 | # (at your option) any later version. | |
8 | # | |
9 | # This program is distributed in the hope that it will be useful, | |
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | # GNU Affero General Public License for more details. | |
13 | # | |
14 | # You should have received a copy of the GNU Affero General Public License | |
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
16 | ||
6bba33d7 | 17 | |
64a456a4 | 18 | from mediagoblin.db.models import (MediaEntry, User, Report, Privilege, |
d88fcb03 | 19 | UserBan, LocalUser) |
a523ffce | 20 | from mediagoblin.decorators import (require_admin_or_moderator_login, |
6483b370 | 21 | active_user_from_url, user_has_privilege, |
22 | allow_reporting) | |
6bba33d7 | 23 | from mediagoblin.tools.response import render_to_response, redirect |
24 | from mediagoblin.moderation import forms as moderation_forms | |
dfd66b78 | 25 | from mediagoblin.moderation.tools import (take_punitive_actions, \ |
6acf4ee6 | 26 | take_away_privileges, give_privileges, ban_user, unban_user, \ |
27 | parse_report_panel_settings) | |
dc31cd1b | 28 | from math import ceil |
6bba33d7 | 29 | |
30 | @require_admin_or_moderator_login | |
31 | def moderation_media_processing_panel(request): | |
32 | ''' | |
33 | Show the global media processing panel for this instance | |
34 | ''' | |
35 | processing_entries = MediaEntry.query.filter_by(state = u'processing').\ | |
36 | order_by(MediaEntry.created.desc()) | |
37 | ||
38 | # Get media entries which have failed to process | |
39 | failed_entries = MediaEntry.query.filter_by(state = u'failed').\ | |
40 | order_by(MediaEntry.created.desc()) | |
41 | ||
42 | processed_entries = MediaEntry.query.filter_by(state = u'processed').\ | |
43 | order_by(MediaEntry.created.desc()).limit(10) | |
44 | ||
45 | # Render to response | |
46 | return render_to_response( | |
47 | request, | |
48 | 'mediagoblin/moderation/media_panel.html', | |
49 | {'processing_entries': processing_entries, | |
50 | 'failed_entries': failed_entries, | |
51 | 'processed_entries': processed_entries}) | |
52 | ||
53 | @require_admin_or_moderator_login | |
54 | def moderation_users_panel(request): | |
55 | ''' | |
56 | Show the global panel for monitoring users in this instance | |
57 | ''' | |
6483b370 | 58 | current_page = 1 |
59 | if len(request.args) > 0: | |
60 | form = moderation_forms.UserPanelSortingForm(request.args) | |
61 | if form.validate(): | |
62 | current_page = form.p.data or 1 | |
63 | ||
64 | all_user_list = User.query | |
65 | user_list = all_user_list.order_by( | |
66 | User.created.desc()).offset( | |
67 | (current_page-1)*10).limit(10) | |
68 | last_page = int(ceil(all_user_list.count()/10.)) | |
6bba33d7 | 69 | |
70 | return render_to_response( | |
71 | request, | |
72 | 'mediagoblin/moderation/user_panel.html', | |
6483b370 | 73 | {'user_list': user_list, |
74 | 'current_page':current_page, | |
75 | 'last_page':last_page}) | |
6bba33d7 | 76 | |
77 | @require_admin_or_moderator_login | |
78 | def moderation_users_detail(request): | |
79 | ''' | |
80 | Shows details about a particular user. | |
81 | ''' | |
b4997540 | 82 | user = LocalUser.query.filter( |
d88fcb03 JT |
83 | LocalUser.username==request.matchdict['user'] |
84 | ).first() | |
6bba33d7 | 85 | active_reports = user.reports_filed_on.filter( |
64a456a4 | 86 | Report.resolved==None).limit(5) |
6bba33d7 | 87 | closed_reports = user.reports_filed_on.filter( |
64a456a4 | 88 | Report.resolved!=None).all() |
6bba33d7 | 89 | privileges = Privilege.query |
3aa3871b | 90 | user_banned = UserBan.query.get(user.id) |
1bb367f6 | 91 | ban_form = moderation_forms.BanForm() |
6bba33d7 | 92 | |
93 | return render_to_response( | |
94 | request, | |
95 | 'mediagoblin/moderation/user.html', | |
96 | {'user':user, | |
3aa3871b | 97 | 'privileges': privileges, |
3aa3871b | 98 | 'reports':active_reports, |
1bb367f6 | 99 | 'user_banned':user_banned, |
100 | 'ban_form':ban_form}) | |
6bba33d7 | 101 | |
102 | @require_admin_or_moderator_login | |
6483b370 | 103 | @allow_reporting |
6bba33d7 | 104 | def moderation_reports_panel(request): |
105 | ''' | |
dfd66b78 | 106 | Show the global panel for monitoring reports filed against comments or |
6bba33d7 | 107 | media entries for this instance. |
108 | ''' | |
6acf4ee6 | 109 | filters = [] |
110 | active_settings, closed_settings = {'current_page':1}, {'current_page':1} | |
111 | ||
112 | if len(request.args) > 0: | |
113 | form = moderation_forms.ReportPanelSortingForm(request.args) | |
114 | if form.validate(): | |
115 | filters = parse_report_panel_settings(form) | |
116 | active_settings['current_page'] = form.active_p.data or 1 | |
117 | closed_settings['current_page'] = form.closed_p.data or 1 | |
118 | filters = [ | |
64a456a4 | 119 | getattr(Report,key)==val |
993e0618 | 120 | for key,val in filters.items()] |
dc31cd1b | 121 | |
64a456a4 JT |
122 | all_active = Report.query.filter( |
123 | Report.resolved==None).filter( | |
6acf4ee6 | 124 | *filters) |
64a456a4 JT |
125 | all_closed = Report.query.filter( |
126 | Report.resolved!=None).filter( | |
6acf4ee6 | 127 | *filters) |
128 | ||
129 | # report_list and closed_report_list are the two lists of up to 10 | |
130 | # items which are actually passed to the user in this request | |
dc31cd1b | 131 | report_list = all_active.order_by( |
64a456a4 | 132 | Report.created.desc()).offset( |
6acf4ee6 | 133 | (active_settings['current_page']-1)*10).limit(10) |
dc31cd1b | 134 | closed_report_list = all_closed.order_by( |
64a456a4 | 135 | Report.created.desc()).offset( |
6acf4ee6 | 136 | (closed_settings['current_page']-1)*10).limit(10) |
137 | ||
dc31cd1b | 138 | active_settings['last_page'] = int(ceil(all_active.count()/10.)) |
139 | closed_settings['last_page'] = int(ceil(all_closed.count()/10.)) | |
6bba33d7 | 140 | # Render to response |
141 | return render_to_response( | |
142 | request, | |
143 | 'mediagoblin/moderation/report_panel.html', | |
144 | {'report_list':report_list, | |
dc31cd1b | 145 | 'closed_report_list':closed_report_list, |
146 | 'active_settings':active_settings, | |
147 | 'closed_settings':closed_settings}) | |
6bba33d7 | 148 | |
149 | @require_admin_or_moderator_login | |
6483b370 | 150 | @allow_reporting |
6bba33d7 | 151 | def moderation_reports_detail(request): |
152 | """ | |
153 | This is the page an admin or moderator goes to see the details of a report. | |
154 | The report can be resolved or unresolved. This is also the page that a mod- | |
155 | erator would go to to take an action to resolve a report. | |
156 | """ | |
157 | form = moderation_forms.ReportResolutionForm(request.form) | |
64a456a4 | 158 | report = Report.query.get(request.matchdict['report_id']) |
6bba33d7 | 159 | |
9d6e453f | 160 | form.take_away_privileges.choices = [ |
161 | (s.privilege_name,s.privilege_name.title()) \ | |
dfd66b78 | 162 | for s in report.reported_user.all_privileges |
9d6e453f | 163 | ] |
3aa3871b | 164 | |
8394febb | 165 | if request.method == "POST" and form.validate() and not ( |
166 | not request.user.has_privilege(u'admin') and | |
167 | report.reported_user.has_privilege(u'admin')): | |
168 | ||
6bba33d7 | 169 | user = User.query.get(form.targeted_user.data) |
3aa3871b | 170 | return take_punitive_actions(request, form, report, user) |
6bba33d7 | 171 | |
6bba33d7 | 172 | |
173 | form.targeted_user.data = report.reported_user_id | |
174 | ||
175 | return render_to_response( | |
176 | request, | |
177 | 'mediagoblin/moderation/report.html', | |
178 | {'report':report, | |
6bba33d7 | 179 | 'form':form}) |
180 | ||
dfd66b78 | 181 | @user_has_privilege(u'admin') |
6bba33d7 | 182 | @active_user_from_url |
183 | def give_or_take_away_privilege(request, url_user): | |
184 | ''' | |
8e91df87 | 185 | A form action to give or take away a particular privilege from a user. |
186 | Can only be used by an admin. | |
6bba33d7 | 187 | ''' |
188 | form = moderation_forms.PrivilegeAddRemoveForm(request.form) | |
189 | if request.method == "POST" and form.validate(): | |
9d6e453f | 190 | privilege = Privilege.query.filter( |
191 | Privilege.privilege_name==form.privilege_name.data).one() | |
dfd66b78 | 192 | if not take_away_privileges( |
193 | url_user.username, form.privilege_name.data): | |
194 | ||
195 | give_privileges(url_user.username, form.privilege_name.data) | |
6bba33d7 | 196 | url_user.save() |
dfd66b78 | 197 | |
198 | return redirect( | |
199 | request, | |
200 | 'mediagoblin.moderation.users_detail', | |
201 | user=url_user.username) | |
1bb367f6 | 202 | |
203 | @user_has_privilege(u'admin') | |
204 | @active_user_from_url | |
205 | def ban_or_unban(request, url_user): | |
206 | """ | |
207 | A page to ban or unban a user. Only can be used by an admin. | |
208 | """ | |
209 | form = moderation_forms.BanForm(request.form) | |
1bb367f6 | 210 | if request.method == "POST" and form.validate(): |
211 | already_banned = unban_user(url_user.id) | |
8e91df87 | 212 | same_as_requesting_user = (request.user.id == url_user.id) |
213 | if not already_banned and not same_as_requesting_user: | |
1bb367f6 | 214 | user_ban = ban_user(url_user.id, |
215 | expiration_date = form.user_banned_until.data, | |
216 | reason = form.why_user_was_banned.data) | |
217 | user_ban.save() | |
218 | return redirect( | |
219 | request, | |
220 | 'mediagoblin.moderation.users_detail', | |
221 | user=url_user.username) |