diff options
Diffstat (limited to 'mediagoblin/moderation/views.py')
-rw-r--r-- | mediagoblin/moderation/views.py | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/mediagoblin/moderation/views.py b/mediagoblin/moderation/views.py new file mode 100644 index 00000000..f4de11ad --- /dev/null +++ b/mediagoblin/moderation/views.py @@ -0,0 +1,219 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + + +from mediagoblin.db.models import (MediaEntry, User,ReportBase, Privilege, + UserBan) +from mediagoblin.decorators import (require_admin_or_moderator_login, + active_user_from_url, user_has_privilege, + allow_reporting) +from mediagoblin.tools.response import render_to_response, redirect +from mediagoblin.moderation import forms as moderation_forms +from mediagoblin.moderation.tools import (take_punitive_actions, \ + take_away_privileges, give_privileges, ban_user, unban_user, \ + parse_report_panel_settings) +from math import ceil + +@require_admin_or_moderator_login +def moderation_media_processing_panel(request): + ''' + Show the global media processing panel for this instance + ''' + processing_entries = MediaEntry.query.filter_by(state = u'processing').\ + order_by(MediaEntry.created.desc()) + + # Get media entries which have failed to process + failed_entries = MediaEntry.query.filter_by(state = u'failed').\ + order_by(MediaEntry.created.desc()) + + processed_entries = MediaEntry.query.filter_by(state = u'processed').\ + order_by(MediaEntry.created.desc()).limit(10) + + # Render to response + return render_to_response( + request, + 'mediagoblin/moderation/media_panel.html', + {'processing_entries': processing_entries, + 'failed_entries': failed_entries, + 'processed_entries': processed_entries}) + +@require_admin_or_moderator_login +def moderation_users_panel(request): + ''' + Show the global panel for monitoring users in this instance + ''' + current_page = 1 + if len(request.args) > 0: + form = moderation_forms.UserPanelSortingForm(request.args) + if form.validate(): + current_page = form.p.data or 1 + + all_user_list = User.query + user_list = all_user_list.order_by( + User.created.desc()).offset( + (current_page-1)*10).limit(10) + last_page = int(ceil(all_user_list.count()/10.)) + + return render_to_response( + request, + 'mediagoblin/moderation/user_panel.html', + {'user_list': user_list, + 'current_page':current_page, + 'last_page':last_page}) + +@require_admin_or_moderator_login +def moderation_users_detail(request): + ''' + Shows details about a particular user. + ''' + user = User.query.filter_by(username=request.matchdict['user']).first() + active_reports = user.reports_filed_on.filter( + ReportBase.resolved==None).limit(5) + closed_reports = user.reports_filed_on.filter( + ReportBase.resolved!=None).all() + privileges = Privilege.query + user_banned = UserBan.query.get(user.id) + ban_form = moderation_forms.BanForm() + + return render_to_response( + request, + 'mediagoblin/moderation/user.html', + {'user':user, + 'privileges': privileges, + 'reports':active_reports, + 'user_banned':user_banned, + 'ban_form':ban_form}) + +@require_admin_or_moderator_login +@allow_reporting +def moderation_reports_panel(request): + ''' + Show the global panel for monitoring reports filed against comments or + media entries for this instance. + ''' + filters = [] + active_settings, closed_settings = {'current_page':1}, {'current_page':1} + + if len(request.args) > 0: + form = moderation_forms.ReportPanelSortingForm(request.args) + if form.validate(): + filters = parse_report_panel_settings(form) + active_settings['current_page'] = form.active_p.data or 1 + closed_settings['current_page'] = form.closed_p.data or 1 + filters = [ + getattr(ReportBase,key)==val + for key,val in filters.viewitems()] + + all_active = ReportBase.query.filter( + ReportBase.resolved==None).filter( + *filters) + all_closed = ReportBase.query.filter( + ReportBase.resolved!=None).filter( + *filters) + + # report_list and closed_report_list are the two lists of up to 10 + # items which are actually passed to the user in this request + report_list = all_active.order_by( + ReportBase.created.desc()).offset( + (active_settings['current_page']-1)*10).limit(10) + closed_report_list = all_closed.order_by( + ReportBase.created.desc()).offset( + (closed_settings['current_page']-1)*10).limit(10) + + active_settings['last_page'] = int(ceil(all_active.count()/10.)) + closed_settings['last_page'] = int(ceil(all_closed.count()/10.)) + # Render to response + return render_to_response( + request, + 'mediagoblin/moderation/report_panel.html', + {'report_list':report_list, + 'closed_report_list':closed_report_list, + 'active_settings':active_settings, + 'closed_settings':closed_settings}) + +@require_admin_or_moderator_login +@allow_reporting +def moderation_reports_detail(request): + """ + This is the page an admin or moderator goes to see the details of a report. + The report can be resolved or unresolved. This is also the page that a mod- + erator would go to to take an action to resolve a report. + """ + form = moderation_forms.ReportResolutionForm(request.form) + report = ReportBase.query.get(request.matchdict['report_id']) + + form.take_away_privileges.choices = [ + (s.privilege_name,s.privilege_name.title()) \ + for s in report.reported_user.all_privileges + ] + + if request.method == "POST" and form.validate() and not ( + not request.user.has_privilege(u'admin') and + report.reported_user.has_privilege(u'admin')): + + user = User.query.get(form.targeted_user.data) + return take_punitive_actions(request, form, report, user) + + + form.targeted_user.data = report.reported_user_id + + return render_to_response( + request, + 'mediagoblin/moderation/report.html', + {'report':report, + 'form':form}) + +@user_has_privilege(u'admin') +@active_user_from_url +def give_or_take_away_privilege(request, url_user): + ''' + A form action to give or take away a particular privilege from a user. + Can only be used by an admin. + ''' + form = moderation_forms.PrivilegeAddRemoveForm(request.form) + if request.method == "POST" and form.validate(): + privilege = Privilege.query.filter( + Privilege.privilege_name==form.privilege_name.data).one() + if not take_away_privileges( + url_user.username, form.privilege_name.data): + + give_privileges(url_user.username, form.privilege_name.data) + url_user.save() + + return redirect( + request, + 'mediagoblin.moderation.users_detail', + user=url_user.username) + +@user_has_privilege(u'admin') +@active_user_from_url +def ban_or_unban(request, url_user): + """ + A page to ban or unban a user. Only can be used by an admin. + """ + form = moderation_forms.BanForm(request.form) + if request.method == "POST" and form.validate(): + already_banned = unban_user(url_user.id) + same_as_requesting_user = (request.user.id == url_user.id) + if not already_banned and not same_as_requesting_user: + user_ban = ban_user(url_user.id, + expiration_date = form.user_banned_until.data, + reason = form.why_user_was_banned.data) + user_ban.save() + return redirect( + request, + 'mediagoblin.moderation.users_detail', + user=url_user.username) |