From 6bba33d7e6fbb0cedc39f9a11f816fe5bd372ae7 Mon Sep 17 00:00:00 2001 From: tilly-Q Date: Wed, 17 Jul 2013 16:16:07 -0400 Subject: Whew. This is a big update. I did some significant keeping work. I moved all of the folders and enpoints labeled 'admin' to the more accurate term of 'moderat- ion.' I also created the ability for admins and moderators to add or remove pr- ivileges or to ban a user in response to a report. This also meant implementing the UserBan class in various places. I also had to add a column called result to the ReportBase table. This allows the moderator/admin to leave comments when they respond to a report, allowing for archiving of what responses they do/n't take. --\ mediagoblin/db/migrations.py --| Added result column to ReportBase --\ mediagoblin/db/models.py --| Added result column to ReportBase --| Added documentation to tables I had made previously --\ mediagoblin/decorators.py --| Editted the user_has_privilege decorator to check whether a user has been | banned or not --| Created a seperate user_not_banned decorator to prevent banned users from | accessing any pages --| Changed require_admin_login into require_admin_or_moderator login --\ mediagoblin/gmg_commands/users.py --| Made the gmg command `adduser` create a user w/ the appropriate privileges --\ mediagoblin/moderation/routing.py << formerly mediagoblin/admin/routing.py --| Renamed all of the routes from admin -> moderation --\ mediagoblin/routing.py --| Renamed all of the routes from admin -> moderation --\ mediagoblin/moderation/views.py << formerly mediagoblin/admin/views.py --| Renamed all of the routes & functions from admin -> moderation --| Expanded greatly on the moderation_reports_detail view and functionality --| Added in the give_or_take_away_privilege form, however this might be a use- | -less function which I could remove (because privilege changes should happe- | n in response to a report so they can be archived and visible) --\ mediagoblin/static/css/base.css --| Added in a style for the reports_detail page --\ mediagoblin/templates/mediagoblin/base.html --| Renamed all of the routes from admin -> moderation --\ mediagoblin/templates/mediagoblin/moderation/report.html --| Added form to allow moderators and admins to respond to reports. --\ mediagoblin/templates/mediagoblin/moderation/reports_panel.html --| Fixed the table for closed reports --\ mediagoblin/templates/mediagoblin/moderation/user.html --| Added in a table w/ all of the user's privileges and the option to add or | remove them. Again, this is probably vestigial --| Renamed all of the routes from admin -> moderation --\ mediagoblin/templates/mediagoblin/moderation/user_panel.html --| Renamed all of the routes from admin -> moderation --\ mediagoblin/tools/response.py --| Added function render_user_banned, this is the view function for the redir- | -ect that happens when a user tries to access the site whilst banned --\ mediagoblin/user_pages/forms.py --| Added important translate function where I had text --\ mediagoblin/user_pages/lib.py --| Renamed functiion for clarity --\ mediagoblin/user_pages/views.py --| Added the user_not_banned decorator to every view --\ mediagoblin/views.py --| Added the user_not_banned decorator --\ mediagoblin/moderation/forms.py --| Created this new file --\ mediagoblin/templates/mediagoblin/banned.html --| Created this new file --| This is the page which people are redirected to when they access the site | while banned --- mediagoblin/moderation/views.py | 200 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 mediagoblin/moderation/views.py (limited to 'mediagoblin/moderation/views.py') diff --git a/mediagoblin/moderation/views.py b/mediagoblin/moderation/views.py new file mode 100644 index 00000000..6f6318bc --- /dev/null +++ b/mediagoblin/moderation/views.py @@ -0,0 +1,200 @@ +# 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 . + +from werkzeug.exceptions import Forbidden + +from mediagoblin.db.models import (MediaEntry, User, MediaComment, \ + CommentReport, ReportBase, Privilege, \ + UserBan) +from mediagoblin.decorators import (require_admin_or_moderator_login, \ + active_user_from_url) +from mediagoblin.tools.response import render_to_response, redirect +from mediagoblin.moderation import forms as moderation_forms +from datetime import datetime + +@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 + ''' + user_list = User.query + + return render_to_response( + request, + 'mediagoblin/moderation/user_panel.html', + {'user_list': user_list}) + +@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 + + return render_to_response( + request, + 'mediagoblin/moderation/user.html', + {'user':user, + 'privileges':privileges, + 'reports':active_reports}) + +@require_admin_or_moderator_login +def moderation_reports_panel(request): + ''' + Show the global panel for monitoring reports filed against comments or + media entries for this instance. + ''' + report_list = ReportBase.query.filter( + ReportBase.resolved==None).order_by( + ReportBase.created.desc()).limit(10) + closed_report_list = ReportBase.query.filter( + ReportBase.resolved!=None).order_by( + ReportBase.created.desc()).limit(10) + + # Render to response + return render_to_response( + request, + 'mediagoblin/moderation/report_panel.html', + {'report_list':report_list, + 'closed_report_list':closed_report_list}) + +@require_admin_or_moderator_login +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']) + + if request.method == "POST" and form.validate(): + user = User.query.get(form.targeted_user.data) + if form.action_to_resolve.data == u'takeaway': + if report.discriminator == u'comment_report': + privilege = Privilege.one({'privilege_name':u'commenter'}) + form.resolution_content.data += \ + u"
%s took away %s\'s commenting privileges" % ( + request.user.username, + user.username) + else: + privilege = Privilege.one({'privilege_name':u'uploader'}) + form.resolution_content.data += \ + u"
%s took away %s\'s media uploading privileges" % ( + request.user.username, + user.username) + user.all_privileges.remove(privilege) + user.save() + report.result = form.resolution_content.data + report.resolved = datetime.now() + report.save() + + elif form.action_to_resolve.data == u'userban': + reason = form.resolution_content.data + \ + "
"+request.user.username + user_ban = UserBan( + user_id=form.targeted_user.data, + expiration_date=form.user_banned_until.data, + reason= form.resolution_content.data) + user_ban.save() + if not form.user_banned_until == "": + form.resolution_content.data += \ + u"
%s banned user %s until %s." % ( + request.user.username, + user.username, + form.user_banned_until.data) + else: + form.resolution_content.data += \ + u"
%s banned user %s indefinitely." % ( + request.user.username, + user.username, + form.user_banned_until.data) + + report.result = form.resolution_content.data + report.resolved = datetime.now() + report.save() + + else: + pass + + return redirect( + request, + 'mediagoblin.moderation.users_detail', + user=user.username) + + if report.discriminator == 'comment_report': + comment = MediaComment.query.get(report.comment_id) + media_entry = None + elif report.discriminator == 'media_report': + media_entry = MediaEntry.query.get(report.media_entry_id) + comment = None + + form.targeted_user.data = report.reported_user_id + + return render_to_response( + request, + 'mediagoblin/moderation/report.html', + {'report':report, + 'media_entry':media_entry, + 'comment':comment, + 'form':form}) + +@require_admin_or_moderator_login +@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 + ''' + form = moderation_forms.PrivilegeAddRemoveForm(request.form) + if request.method == "POST" and form.validate(): + privilege = Privilege.one({'privilege_name':form.privilege_name.data}) + if privilege in url_user.all_privileges is True: + url_user.all_privileges.remove(privilege) + else: + url_user.all_privileges.append(privilege) + url_user.save() + return redirect( + request, + 'mediagoblin.moderation.users_detail', + user=url_user.username) -- cgit v1.2.3 From 3aa3871b909500ae9198d63814dd79fd28921f93 Mon Sep 17 00:00:00 2001 From: tilly-Q Date: Sat, 27 Jul 2013 16:44:40 -0400 Subject: This commit had some important milestones in it. The major update is that now I have mostly completed the moderator punishment and resolution of reports. Along with this, I have also added one last table to the database: one that holds ar- -chived (or resolved) reports. This is some of the primary functionality of my whole update, so this is a big step! The other changes I made this update are primarily organizational. I refactored some of my code into functions and I cl- eaned up many of my templates. --\ mediagoblin/db/models.py --| Created the new ArchivedReport table --| Removed columns from BaseReport table that are only necessary for Archived | reports --\ mediagoblin/db/migrations.py --| Created the new ArchivedReport table --| Removed columns from BaseReport table that are only necessary for Archived | reports --\ mediagoblin/db/util.py --| Created the user_privileges_to_dictionary function. This is useful for | accessing a user's permissions from within a template. --\ mediagoblin/moderation/forms.py --| Expanded the disciplinary actions a moderator can take --| Allowed the moderator to choose more than one disciplinary action at a time | (It's now managed with a list of checkboxes rather than radio buttons) ----| Pulled a MultiCheckBox class from a wtforms tutorial --| Added various other form inputs for details of the moderator's disciplinary | actions --| Tried to ensure that every string is unicode and translated --\ mediagoblin/moderation/tools.py --| Created this file for holding useful moderation tools --| Moved the penalizing code from views to the function take_punitive_actions --| Added many more types of punitive actions --| Added the archiving of old reports --\ mediagoblin/moderation/views.py --| Used the privileges_to_dictionary function for the Users Detail view to | allow for different actions available to a moderator and an admin. --| Added in functionality for ArchivedReports to the reports_detail and | reports_panel views --| Moved the punishments of repots_detail to tools.py (as mentioned above) --\ mediagoblin/static/css/base.css --| Added new styling for the User Detail page --\ mediagoblin/static/images/icon_clipboard_alert.png --| Added this image to represent unresolved reports --\ mediagoblin/templates/mediagoblin/moderation/report.html --| Added 'Return to Reports Panel' button --| Fixed the spacing to be less that 80 columns wide --| Added in display for Archived Reports --\ mediagoblin/templates/mediagoblin/moderation/reports_panel.html --| Changed the placement and columns of the tables --| Fixed the spacing to be less that 80 columns wide --| Added in display for Archived Reports --\ mediagoblin/templates/mediagoblin/moderation/user.html --| Fixed the spacing to be less that 80 columns wide --| Took away the moderator's ability to add and remove privileges at will. | Only the admin has this power now. --\ mediagoblin/templates/mediagoblin/moderation/users_panel.html --| Fixed the spacing to be less that 80 columns wide --\ mediagoblin/tools/response.py --| Added in code to remove a UserBan from a User if that user logs in after | the expiration date --- mediagoblin/moderation/views.py | 85 +++++++++-------------------------------- 1 file changed, 18 insertions(+), 67 deletions(-) (limited to 'mediagoblin/moderation/views.py') diff --git a/mediagoblin/moderation/views.py b/mediagoblin/moderation/views.py index 6f6318bc..67928927 100644 --- a/mediagoblin/moderation/views.py +++ b/mediagoblin/moderation/views.py @@ -18,11 +18,13 @@ from werkzeug.exceptions import Forbidden from mediagoblin.db.models import (MediaEntry, User, MediaComment, \ CommentReport, ReportBase, Privilege, \ - UserBan) + UserBan, ArchivedReport) +from mediagoblin.db.util import user_privileges_to_dictionary from mediagoblin.decorators import (require_admin_or_moderator_login, \ active_user_from_url) 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 from datetime import datetime @require_admin_or_moderator_login @@ -67,17 +69,22 @@ def moderation_users_detail(request): ''' user = User.query.filter_by(username=request.matchdict['user']).first() active_reports = user.reports_filed_on.filter( - ReportBase.resolved==None).limit(5) + ReportBase.discriminator!='archived_report').limit(5) closed_reports = user.reports_filed_on.filter( - ReportBase.resolved!=None).all() + ReportBase.discriminator=='archived_report').all() privileges = Privilege.query + user_banned = UserBan.query.get(user.id) + user_privileges = user_privileges_to_dictionary(user.id) + requesting_user_privileges = user_privileges_to_dictionary(request.user.id) return render_to_response( request, 'mediagoblin/moderation/user.html', {'user':user, - 'privileges':privileges, - 'reports':active_reports}) + 'privileges': privileges, + 'requesting_user_privileges':requesting_user_privileges, + 'reports':active_reports, + 'user_banned':user_banned}) @require_admin_or_moderator_login def moderation_reports_panel(request): @@ -86,10 +93,10 @@ def moderation_reports_panel(request): media entries for this instance. ''' report_list = ReportBase.query.filter( - ReportBase.resolved==None).order_by( + ReportBase.discriminator!="archived_report").order_by( ReportBase.created.desc()).limit(10) closed_report_list = ReportBase.query.filter( - ReportBase.resolved!=None).order_by( + ReportBase.discriminator=="archived_report").order_by( ReportBase.created.desc()).limit(10) # Render to response @@ -109,66 +116,12 @@ def moderation_reports_detail(request): 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(): user = User.query.get(form.targeted_user.data) - if form.action_to_resolve.data == u'takeaway': - if report.discriminator == u'comment_report': - privilege = Privilege.one({'privilege_name':u'commenter'}) - form.resolution_content.data += \ - u"
%s took away %s\'s commenting privileges" % ( - request.user.username, - user.username) - else: - privilege = Privilege.one({'privilege_name':u'uploader'}) - form.resolution_content.data += \ - u"
%s took away %s\'s media uploading privileges" % ( - request.user.username, - user.username) - user.all_privileges.remove(privilege) - user.save() - report.result = form.resolution_content.data - report.resolved = datetime.now() - report.save() - - elif form.action_to_resolve.data == u'userban': - reason = form.resolution_content.data + \ - "
"+request.user.username - user_ban = UserBan( - user_id=form.targeted_user.data, - expiration_date=form.user_banned_until.data, - reason= form.resolution_content.data) - user_ban.save() - if not form.user_banned_until == "": - form.resolution_content.data += \ - u"
%s banned user %s until %s." % ( - request.user.username, - user.username, - form.user_banned_until.data) - else: - form.resolution_content.data += \ - u"
%s banned user %s indefinitely." % ( - request.user.username, - user.username, - form.user_banned_until.data) - - report.result = form.resolution_content.data - report.resolved = datetime.now() - report.save() - - else: - pass - - return redirect( - request, - 'mediagoblin.moderation.users_detail', - user=user.username) + return take_punitive_actions(request, form, report, user) - if report.discriminator == 'comment_report': - comment = MediaComment.query.get(report.comment_id) - media_entry = None - elif report.discriminator == 'media_report': - media_entry = MediaEntry.query.get(report.media_entry_id) - comment = None form.targeted_user.data = report.reported_user_id @@ -176,8 +129,6 @@ def moderation_reports_detail(request): request, 'mediagoblin/moderation/report.html', {'report':report, - 'media_entry':media_entry, - 'comment':comment, 'form':form}) @require_admin_or_moderator_login @@ -189,7 +140,7 @@ def give_or_take_away_privilege(request, url_user): form = moderation_forms.PrivilegeAddRemoveForm(request.form) if request.method == "POST" and form.validate(): privilege = Privilege.one({'privilege_name':form.privilege_name.data}) - if privilege in url_user.all_privileges is True: + if privilege in url_user.all_privileges: url_user.all_privileges.remove(privilege) else: url_user.all_privileges.append(privilege) -- cgit v1.2.3 From 9d6e453f8fd337813c2933835aedff2949193fbe Mon Sep 17 00:00:00 2001 From: tilly-Q Date: Tue, 30 Jul 2013 17:09:01 -0400 Subject: This commit was the work I did fixing errors that cropped up from the merge. There were a few errors because of the switch from sqlalchemy 0.7 to 0.8 but I cleared them up. --- mediagoblin/moderation/views.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'mediagoblin/moderation/views.py') diff --git a/mediagoblin/moderation/views.py b/mediagoblin/moderation/views.py index 67928927..041cf5b3 100644 --- a/mediagoblin/moderation/views.py +++ b/mediagoblin/moderation/views.py @@ -116,7 +116,10 @@ def moderation_reports_detail(request): 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] + 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(): user = User.query.get(form.targeted_user.data) @@ -139,7 +142,8 @@ def give_or_take_away_privilege(request, url_user): ''' form = moderation_forms.PrivilegeAddRemoveForm(request.form) if request.method == "POST" and form.validate(): - privilege = Privilege.one({'privilege_name':form.privilege_name.data}) + privilege = Privilege.query.filter( + Privilege.privilege_name==form.privilege_name.data).one() if privilege in url_user.all_privileges: url_user.all_privileges.remove(privilege) else: -- cgit v1.2.3 From 8394febbe1408030d1afa8f3961d92341eefa474 Mon Sep 17 00:00:00 2001 From: tilly-Q Date: Tue, 13 Aug 2013 18:38:00 -0400 Subject: This has been an update to clean out the code a little bit. The primary change I made was I added the method has_privilege (which takes a variable amount of unicode privilege names as an argument) to the User model. This method allowed for much cleaner checks as to whether or not a user has a privilege. Other- wise, I also made it impossible for moderators to punish admins. I created a new url path and three new pages for Users to look at filed reports and the code of conduct for the mg instance. === Made reports on admins not resolvable by moderators: --\ mediagoblin/moderation/views.py --\ mediagoblin/templates/mediagoblin/moderation/report.html === Created new files for the new pages: --\ mediagoblin/meta/__init__.py --\ mediagoblin/meta/routing.py --\ mediagoblin/meta/views.py --\ mediagoblin/templates/mediagoblin/meta/code_of_conduct.html --\ mediagoblin/templates/mediagoblin/meta/reports_details.html --\ mediagoblin/templates/mediagoblin/meta/reports_panel.html --\ mediagoblin/routing.py --\ mediagoblin/static/css/base.css === Replaced vestigial methods of checking a user's privilege with the more ====== effective method has_privilege(u'privilege_name'): --\ mediagoblin/db/models.py --| Added in the has_privilege method to the User class --\ mediagoblin/db/migrations.py --\ mediagoblin/db/models.py --\ mediagoblin/decorators.py --\ mediagoblin/edit/lib.py --\ mediagoblin/edit/views.py --\ mediagoblin/gmg_commands/users.py --\ mediagoblin/moderation/views.py --\ mediagoblin/templates/mediagoblin/base.html --\ mediagoblin/templates/mediagoblin/user_pages/collection.html --\ mediagoblin/templates/mediagoblin/user_pages/media.html --\ mediagoblin/templates/mediagoblin/user_pages/user.html --\ mediagoblin/templates/mediagoblin/utils/collection_gallery.html --\ mediagoblin/user_pages/views.py === Minor UI changes --\ mediagoblin/templates/mediagoblin/moderation/report_panel.html --\ mediagoblin/templates/mediagoblin/moderation/user.html === Other Bugs: --\ mediagoblin/tools/response.py --\ mediagoblin/db/migrations.py --- mediagoblin/moderation/views.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'mediagoblin/moderation/views.py') diff --git a/mediagoblin/moderation/views.py b/mediagoblin/moderation/views.py index 041cf5b3..d82eca7d 100644 --- a/mediagoblin/moderation/views.py +++ b/mediagoblin/moderation/views.py @@ -74,15 +74,12 @@ def moderation_users_detail(request): ReportBase.discriminator=='archived_report').all() privileges = Privilege.query user_banned = UserBan.query.get(user.id) - user_privileges = user_privileges_to_dictionary(user.id) - requesting_user_privileges = user_privileges_to_dictionary(request.user.id) return render_to_response( request, 'mediagoblin/moderation/user.html', {'user':user, 'privileges': privileges, - 'requesting_user_privileges':requesting_user_privileges, 'reports':active_reports, 'user_banned':user_banned}) @@ -121,7 +118,10 @@ def moderation_reports_detail(request): for s in report.reported_user.all_privileges ] - if request.method == "POST" and form.validate(): + 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) -- cgit v1.2.3 From dfd66b789cd6cc9470c2a98bcbda9ee5e0f3ad0f Mon Sep 17 00:00:00 2001 From: tilly-Q Date: Thu, 29 Aug 2013 13:47:50 -0400 Subject: This was a big commit! I included lots of documentation below, but generally I did a few things. I wrote many many many new tests, either in old test files or in the three new test files I made. I also did some code-keeping work, deleting trailing whitespace and deleting vestigial code. Lastly, I fixed the parts of the code which I realized were broken thru the process of running tests. =============================================================================== Deleted trailing whitespace: =============================================================================== --\ mediagoblin/decorators.py --\ mediagoblin/auth/tools.py --\ mediagoblin/db/migrations.py --\ mediagoblin/db/models.py --\ mediagoblin/gmg_commands/users.py --\ mediagoblin/moderation/forms.py --\ mediagoblin/moderation/tools.py --\ mediagoblin/moderation/views.py --\ mediagoblin/templates/mediagoblin/moderation/media_panel.html --\ mediagoblin/templates/mediagoblin/moderation/report.html --\ mediagoblin/templates/mediagoblin/moderation/report_panel.html --\ mediagoblin/templates/mediagoblin/moderation/user.html --\ mediagoblin/templates/mediagoblin/moderation/user_panel.html --\ mediagoblin/templates/mediagoblin/user_pages/report.html --\ mediagoblin/templates/mediagoblin/utils/report.html --\ mediagoblin/user_pages/lib.py --\ mediagoblin/user_pages/views.py =============================================================================== Deleted Vestigial Code =============================================================================== --\ mediagoblin/db/util.py --\ mediagoblin/tests/test_notifications.py =============================================================================== Modified the Code: =============================================================================== --\ mediagoblin/moderation/tools.py --| Encapsulated the code around giving/taking away privileges into two | funtions. --\ mediagoblin/moderation/views.py --| Imported and used the give/take away privilege functions --| Replaced 'require_admin_or_moderator_login' with |'user_has_privilege(u"admin")' for adding/taking away privileges, only | admins are allowed to do this. --\ mediagoblin/templates/mediagoblin/banned.html --| Added relevant translation tags --| Added ability to display indefinite banning --\ mediagoblin/templates/mediagoblin/user_pages/media.html --| Made sure the add comments button was only visible for users with the | `commenter` privilege --\ mediagoblin/tests/test_submission.py --| Paroneayea fixed a DetachedInstanceError I was having with the our_user | function --\ mediagoblin/tests/tools.py --| Added a fixture_add_comment_report function for testing. --\ mediagoblin/tools/response.py --| Fixed a minor error where a necessary return statement was missing --| Fit the code within 80 columns --\ mediagoblin/user_pages/views.py --| Added a necessary decorator to ensure that only users with the 'commenter' | privilege can post comments =============================================================================== Wrote new tests for an old test file: =============================================================================== --\ mediagoblin/tests/test_auth.py --| Added a new test to make sure privilege granting on registration happens | correctly --\ mediagoblin/tests/test_modelmethods.py* --| Added a test to ensure the User method has_privilege works properly =============================================================================== Wrote entirely new files full of tests: =============================================================================== --\ mediagoblin/tests/test_moderation.py --\ mediagoblin/tests/test_privileges.py --\ mediagoblin/tests/test_reporting.py =============================================================================== =============================================================================== NOTE: Any files I've marked with a * in this commit report, were actually subm- itted in my last commit. I made that committ to fix an error I was having, so they weren't properly documented in that report. =============================================================================== =============================================================================== --- mediagoblin/moderation/views.py | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'mediagoblin/moderation/views.py') diff --git a/mediagoblin/moderation/views.py b/mediagoblin/moderation/views.py index d82eca7d..b2223744 100644 --- a/mediagoblin/moderation/views.py +++ b/mediagoblin/moderation/views.py @@ -19,12 +19,12 @@ from werkzeug.exceptions import Forbidden from mediagoblin.db.models import (MediaEntry, User, MediaComment, \ CommentReport, ReportBase, Privilege, \ UserBan, ArchivedReport) -from mediagoblin.db.util import user_privileges_to_dictionary from mediagoblin.decorators import (require_admin_or_moderator_login, \ - active_user_from_url) + active_user_from_url, user_has_privilege) 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 +from mediagoblin.moderation.tools import (take_punitive_actions, \ + take_away_privileges, give_privileges) from datetime import datetime @require_admin_or_moderator_login @@ -86,7 +86,7 @@ def moderation_users_detail(request): @require_admin_or_moderator_login def moderation_reports_panel(request): ''' - Show the global panel for monitoring reports filed against comments or + Show the global panel for monitoring reports filed against comments or media entries for this instance. ''' report_list = ReportBase.query.filter( @@ -115,7 +115,7 @@ def moderation_reports_detail(request): form.take_away_privileges.choices = [ (s.privilege_name,s.privilege_name.title()) \ - for s in report.reported_user.all_privileges + for s in report.reported_user.all_privileges ] if request.method == "POST" and form.validate() and not ( @@ -134,7 +134,7 @@ def moderation_reports_detail(request): {'report':report, 'form':form}) -@require_admin_or_moderator_login +@user_has_privilege(u'admin') @active_user_from_url def give_or_take_away_privilege(request, url_user): ''' @@ -144,12 +144,13 @@ def give_or_take_away_privilege(request, url_user): if request.method == "POST" and form.validate(): privilege = Privilege.query.filter( Privilege.privilege_name==form.privilege_name.data).one() - if privilege in url_user.all_privileges: - url_user.all_privileges.remove(privilege) - else: - url_user.all_privileges.append(privilege) + 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) + + return redirect( + request, + 'mediagoblin.moderation.users_detail', + user=url_user.username) -- cgit v1.2.3 From 1bb367f6136ae4cbcdf6dd86af65eb613913dbd8 Mon Sep 17 00:00:00 2001 From: tilly-Q Date: Thu, 29 Aug 2013 17:31:19 -0400 Subject: This is a quick commit. I gave admins the ability to ban or unban users straight from the moderation.users_detail page. I also changed the UserBan.expiration_date type from DateTime into Date. I also began work on the Terms of Service, pulled from another website (which will be cited clearly before I'm done). I added new tests as well for the ban/unbanning. Lastly, I added a few `user_not_banned` decorators to relevant views, so banned users cannot access any pages. --- mediagoblin/moderation/views.py | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'mediagoblin/moderation/views.py') diff --git a/mediagoblin/moderation/views.py b/mediagoblin/moderation/views.py index b2223744..869b7b8a 100644 --- a/mediagoblin/moderation/views.py +++ b/mediagoblin/moderation/views.py @@ -24,7 +24,7 @@ from mediagoblin.decorators import (require_admin_or_moderator_login, \ 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) + take_away_privileges, give_privileges, ban_user, unban_user) from datetime import datetime @require_admin_or_moderator_login @@ -74,6 +74,7 @@ def moderation_users_detail(request): ReportBase.discriminator=='archived_report').all() privileges = Privilege.query user_banned = UserBan.query.get(user.id) + ban_form = moderation_forms.BanForm() return render_to_response( request, @@ -81,7 +82,8 @@ def moderation_users_detail(request): {'user':user, 'privileges': privileges, 'reports':active_reports, - 'user_banned':user_banned}) + 'user_banned':user_banned, + 'ban_form':ban_form}) @require_admin_or_moderator_login def moderation_reports_panel(request): @@ -154,3 +156,23 @@ def give_or_take_away_privilege(request, url_user): 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) + print "accessed page" + if request.method == "POST" and form.validate(): + already_banned = unban_user(url_user.id) + if not already_banned: + 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) -- cgit v1.2.3 From dc31cd1b658067d25cda470795020d3c377feae0 Mon Sep 17 00:00:00 2001 From: tilly-Q Date: Tue, 3 Sep 2013 11:57:10 -0400 Subject: I've moved on to one of the last phases of my work! Now I'm just checking off items from my last to-do list. The biggest change in this commit is that I made the moderation reports panel sortable via get request. I also added in page nu- mbers so that more than 10 reports can be viewed. I'm hoping to go from here to make a search page. Aside from that, there were only a few other changes I made this time. I fixed two bugs in my code. I copy-ed and pasted function mediagoblin.user_pages.views:media_preview_comment which I must've deleted ear- -lier in a merge. And I moved some of the javascript I was using in the modera- -tion templates into it's own seperate .js file. =============================================================================== Made the moderation reports panel view sortable =============================================================================== --\ mediagoblin/moderation/forms.py --\ mediagoblin/moderation/views.py --\ mediagoblin/templates/mediagoblin/moderation/report_panel.html --\ mediagoblin/templates/mediagoblin/moderation/user.html --| Made ` report history` into a link that automatically shows all open | and closed reports on . =============================================================================== Grabbed some code from master that I accidentally deleted in a merge =============================================================================== --\ mediagoblin/user_pages/views.py =============================================================================== Moved javascript away from templates into its own file =============================================================================== --\ mediagoblin/static/js/setup_report_forms.js --\ mediagoblin/templates/mediagoblin/moderation/report.html --\ mediagoblin/templates/mediagoblin/moderation/user.html =============================================================================== Cleared trailing white space =============================================================================== --\ mediagoblin/templates/mediagoblin/moderation/media_panel.html --\ mediagoblin/moderation/tools.py --\ mediagoblin/templates/mediagoblin/meta/terms_of_service.html --\ mediagoblin/templates/mediagoblin/moderation/report_panel.html --\ mediagoblin/templates/mediagoblin/user_pages/media.html --\ mediagoblin/tests/test_modelmethods.py =============================================================================== Small fixes =============================================================================== --\ mediagoblin/templates/mediagoblin/moderation/report.html --| Fixed a link so that it points to the correct user page --\ mediagoblin/templates/mediagoblin/user_pages/media.html --| Fixed a bug that crashed this page when a guest visitted it (because | request.user is None) --- mediagoblin/moderation/views.py | 43 ++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) (limited to 'mediagoblin/moderation/views.py') diff --git a/mediagoblin/moderation/views.py b/mediagoblin/moderation/views.py index 869b7b8a..35c586ea 100644 --- a/mediagoblin/moderation/views.py +++ b/mediagoblin/moderation/views.py @@ -26,6 +26,7 @@ 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) from datetime import datetime +from math import ceil @require_admin_or_moderator_login def moderation_media_processing_panel(request): @@ -91,19 +92,47 @@ def moderation_reports_panel(request): Show the global panel for monitoring reports filed against comments or media entries for this instance. ''' - report_list = ReportBase.query.filter( - ReportBase.discriminator!="archived_report").order_by( - ReportBase.created.desc()).limit(10) - closed_report_list = ReportBase.query.filter( - ReportBase.discriminator=="archived_report").order_by( - ReportBase.created.desc()).limit(10) + form = moderation_forms.ReportPanelSortingForm(request.args) + active_settings = {'start_page':1, 'filters':{}} + closed_settings = {'start_page':1, 'filters':{}} + if form.validate(): + active_settings['start_page'] = form.active_p.data or 1 + active_settings['filters']['reported_user_id'] = form.active_reported_user.data + active_settings['filters']['reporter_id'] = form.active_reporter.data + closed_settings['start_page'] = form.closed_p.data or 1 + closed_settings['filters']['reported_user_id'] = form.closed_reported_user.data + closed_settings['filters']['reporter_id'] = form.closed_reporter.data + + active_settings['filters']=dict((k, v) for k, v in active_settings['filters'].iteritems() if v) + closed_settings['filters']=dict((k, v) for k, v in closed_settings['filters'].iteritems() if v) + active_filter = [ + getattr(ReportBase,key)==val \ +for key,val in active_settings['filters'].viewitems()] + closed_filter = [ + getattr(ReportBase,key)==val \ +for key,val in active_settings['filters'].viewitems()] + + all_active = ReportBase.query.filter( + ReportBase.discriminator!="archived_report").filter( + *active_filter) + all_closed = ReportBase.query.filter( + ReportBase.discriminator=="archived_report").filter( + *closed_filter) + report_list = all_active.order_by( + ReportBase.created.desc()).offset((active_settings['start_page']-1)*10).limit(10) + closed_report_list = all_closed.order_by( + ReportBase.created.desc()).offset((closed_settings['start_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}) + 'closed_report_list':closed_report_list, + 'active_settings':active_settings, + 'closed_settings':closed_settings}) @require_admin_or_moderator_login def moderation_reports_detail(request): -- cgit v1.2.3 From 8e91df87349b91611a4dfcf3f2640cb540307144 Mon Sep 17 00:00:00 2001 From: tilly-Q Date: Tue, 3 Sep 2013 16:19:07 -0400 Subject: I did some more code-keeping in this commit. I added a lot of documentation, so that most of my functions do indeed have effective docstrings. I also changed the decorators so that they imply eachother in a logical way. I also modified the one decorator get_media_comment_by_id to be more usable with the variable urls of mediagoblin.user_pages.views:file_a_report. I also noticed a few tests had broken, so I went through them and fixed them up, finding that mostly there were problems in my actual writing of the tests. I also did a few other small tasks such as creating a new User method to check whether or not a User is ban- -ned. =============================================================================== Added in documentation =============================================================================== --\ mediagoblin/db/models.py --\ mediagoblin/decorators.py --\ mediagoblin/moderation/forms.py --\ mediagoblin/moderation/tools.py --\ mediagoblin/moderation/views.py --\ mediagoblin/user_pages/lib.py =============================================================================== Rearranged decorators to be more efficient =============================================================================== --\ mediagoblin/decorators.py --| Made it so that user_not_banned is encapsulated in require_active_login --| Made it so that require_active_login is encapsulated in user_has_privilege --| Changed get_media_comment_by_id into get_optional_media_comment_by_id. It | now returns valid code if the MediaComment id is absent. This makes it pos- | -sible to use this decorator for the function: | mediagoblin.user_pages.views:file_a_report --\ mediagoblin/user_pages/views.py --| Replaced the mediagoblin.user_pages.views:file_a_comment_report with the | decorator mentioned above --\ mediagoblin/user_pages/routing.py ----------------------------------------------------------- | took out unnecessary @user_not_banned decorators | ----------------------------------------------------------- --\ mediagoblin/submit/views.py --\ mediagoblin/user_pages/views.py =============================================================================== Fixed broken tests =============================================================================== --\ mediagoblin/tests/test_auth.py --\ mediagoblin/tests/test_privileges.py --\ mediagoblin/tests/test_submission.py =============================================================================== Fixed broken code =============================================================================== --\ mediagoblin/tools/response.py =============================================================================== Other Tasks =============================================================================== --\ mediagoblin/db/models.py --| Added in User.is_banned() method --\ mediagoblin/decorators.py --| Utitilized User.is_banned() method in the user_not_banned decorator --\ mediagoblin/moderation/views.py --| Made it impossible for an admin to ban themself. --| Got rid of a vestigial print statement --\ mediagoblin/templates/mediagoblin/base.html --| Made it so the top panel does not show up for users that are banned. --\ mediagoblin/templates/mediagoblin/moderation/user.html --| Rearranged the javascript slightly =============================================================================== --- mediagoblin/moderation/views.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'mediagoblin/moderation/views.py') diff --git a/mediagoblin/moderation/views.py b/mediagoblin/moderation/views.py index 35c586ea..f09f4c99 100644 --- a/mediagoblin/moderation/views.py +++ b/mediagoblin/moderation/views.py @@ -169,7 +169,8 @@ def moderation_reports_detail(request): @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 + 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(): @@ -193,10 +194,10 @@ 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) - print "accessed page" if request.method == "POST" and form.validate(): already_banned = unban_user(url_user.id) - if not already_banned: + 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) -- cgit v1.2.3 From 6acf4ee60e3c07aea5bbd9e613335f0de1240d73 Mon Sep 17 00:00:00 2001 From: tilly-Q Date: Tue, 10 Sep 2013 13:16:22 -0400 Subject: This should be my final code update before I am ready for review! Basically, in this update I finished the search/sort function on the Reports Panel. I also finished the Terms of Service and made the decision to remove the meta portion of the site I had planned to create. I decided that the features involved were just unnecessary at this point. I also dropped the User status column and added a migration to establish default privileges (and create the privilege foundat- -ions. I fixed a few small errors that were left over as well, in the implemen- tation and in the tests. Next, I just need to await code review and work on the documentation for these new features. I also need to supervise a new merge to master. =============================================================================== Dropped the vestigial 'status' column =============================================================================== --\ mediagoblin/db/migrations.py --\ mediagoblin/db/models.py --| Also added in comments describing the current situation with the `is_admin` | and `email_verified` columns, where they are 100% vestigial but cannot be | dropped. =============================================================================== Wrote necessary migrations to set up Privilege foundations and give users the necessary privileges on an older implementation of mediagoblin that is migrating into this update =============================================================================== --\ mediagoblin/db/migrations.py =============================================================================== Deleted the meta pages =============================================================================== --\ Deleted mediagoblin/meta/__init__.py --\ Deleted mediagoblin/meta/routing.py --\ Deleted mediagoblin/meta/views.py --\ Deleted mediagoblin/templates/mediagoblin/meta/code_of_conduct.html --\ Deleted mediagoblin/templates/mediagoblin/meta/reports_details.html --\ Deleted mediagoblin/templates/mediagoblin/meta/reports_panel.html ---------------------------------------------------------------- Moved the terms of service to /terms_of_service ---------------------------------------------------------------- --\ Moved mediagoblin/templates/mediagoblin/meta/terms_of_service.html -> mediagoblin/templates/mediagoblin/terms_of_service.html --| I decided that terms of service were really the only necessary part of my | planned "meta" pages, so I moved it instead to its own singular page --\ mediagoblin/routing.py --\ mediagoblin/static/css/base.css --\ mediagoblin/templates/mediagoblin/base.html --\ mediagoblin/views.py =============================================================================== Simplified & Finished the Reports Panel Searching =============================================================================== --\ mediagoblin/moderation/forms.py --\ mediagoblin/moderation/tools.py --\ mediagoblin/moderation/views.py --\ mediagoblin/templates/mediagoblin/moderation/report_panel.html --\ mediagoblin/templates/mediagoblin/moderation/user.html =============================================================================== Fixed Small Errors =============================================================================== --\ mediagoblin/templates/mediagoblin/user_pages/user.html --\ mediagoblin/tests/test_moderation.py --\ mediagoblin/tests/tools.py =============================================================================== --- mediagoblin/moderation/views.py | 50 ++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'mediagoblin/moderation/views.py') diff --git a/mediagoblin/moderation/views.py b/mediagoblin/moderation/views.py index f09f4c99..6a23ddd6 100644 --- a/mediagoblin/moderation/views.py +++ b/mediagoblin/moderation/views.py @@ -24,7 +24,9 @@ from mediagoblin.decorators import (require_admin_or_moderator_login, \ 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) + take_away_privileges, give_privileges, ban_user, unban_user, \ + parse_report_panel_settings) +from werkzeug.datastructures import ImmutableMultiDict from datetime import datetime from math import ceil @@ -92,37 +94,35 @@ def moderation_reports_panel(request): Show the global panel for monitoring reports filed against comments or media entries for this instance. ''' - - form = moderation_forms.ReportPanelSortingForm(request.args) - active_settings = {'start_page':1, 'filters':{}} - closed_settings = {'start_page':1, 'filters':{}} - if form.validate(): - active_settings['start_page'] = form.active_p.data or 1 - active_settings['filters']['reported_user_id'] = form.active_reported_user.data - active_settings['filters']['reporter_id'] = form.active_reporter.data - closed_settings['start_page'] = form.closed_p.data or 1 - closed_settings['filters']['reported_user_id'] = form.closed_reported_user.data - closed_settings['filters']['reporter_id'] = form.closed_reporter.data - - active_settings['filters']=dict((k, v) for k, v in active_settings['filters'].iteritems() if v) - closed_settings['filters']=dict((k, v) for k, v in closed_settings['filters'].iteritems() if v) - active_filter = [ - getattr(ReportBase,key)==val \ -for key,val in active_settings['filters'].viewitems()] - closed_filter = [ - getattr(ReportBase,key)==val \ -for key,val in active_settings['filters'].viewitems()] + 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.discriminator!="archived_report").filter( - *active_filter) + *filters) all_closed = ReportBase.query.filter( ReportBase.discriminator=="archived_report").filter( - *closed_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['start_page']-1)*10).limit(10) + 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['start_page']-1)*10).limit(10) + 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 -- cgit v1.2.3 From c906887025098746ba851f0977a20c7f5f1366ee Mon Sep 17 00:00:00 2001 From: tilly-Q Date: Wed, 11 Sep 2013 17:09:21 -0400 Subject: In this commit, I'm deleting the ArchivedReports object, at paroneyea's recom- -mendation. Instead, all of its functionality will be in the ReportBase object. --- mediagoblin/moderation/views.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'mediagoblin/moderation/views.py') diff --git a/mediagoblin/moderation/views.py b/mediagoblin/moderation/views.py index 6a23ddd6..45edff1d 100644 --- a/mediagoblin/moderation/views.py +++ b/mediagoblin/moderation/views.py @@ -18,7 +18,7 @@ from werkzeug.exceptions import Forbidden from mediagoblin.db.models import (MediaEntry, User, MediaComment, \ CommentReport, ReportBase, Privilege, \ - UserBan, ArchivedReport) + UserBan) from mediagoblin.decorators import (require_admin_or_moderator_login, \ active_user_from_url, user_has_privilege) from mediagoblin.tools.response import render_to_response, redirect @@ -72,9 +72,9 @@ def moderation_users_detail(request): ''' user = User.query.filter_by(username=request.matchdict['user']).first() active_reports = user.reports_filed_on.filter( - ReportBase.discriminator!='archived_report').limit(5) + ReportBase.resolved==None).limit(5) closed_reports = user.reports_filed_on.filter( - ReportBase.discriminator=='archived_report').all() + ReportBase.resolved!=None).all() privileges = Privilege.query user_banned = UserBan.query.get(user.id) ban_form = moderation_forms.BanForm() @@ -108,10 +108,10 @@ def moderation_reports_panel(request): for key,val in filters.viewitems()] all_active = ReportBase.query.filter( - ReportBase.discriminator!="archived_report").filter( + ReportBase.resolved==None).filter( *filters) all_closed = ReportBase.query.filter( - ReportBase.discriminator=="archived_report").filter( + ReportBase.resolved!=None).filter( *filters) # report_list and closed_report_list are the two lists of up to 10 -- cgit v1.2.3 From 6483b37060062ef7c7d40d9ae712c99a7e73775a Mon Sep 17 00:00:00 2001 From: tilly-Q Date: Mon, 23 Sep 2013 13:20:18 -0400 Subject: At this point, I am very close to done with this code! I made one big change at paroneayea's request, which was to make to possible to turn off user's ability to file reports through a mediagoblin.ini setting. Aside from this, I had to make it possible for the Moderation User Panel to display more than 10 users. And aside from that, I just had to fix some errors which cropped up with my most recent additions. I also fixed some tests that were broken because I had changed the checks for whether or not a user is active. Nearing the end! =============================================================================== Made it possible to turn off reports through a mediagoblin.ini setting =============================================================================== --\ mediagoblin.ini --\ mediagoblin/config_spec.ini --\ mediagoblin/decorators.py --\ mediagoblin/moderation/views.py --\ mediagoblin/templates/mediagoblin/user_pages/media.html --\ mediagoblin/user_pages/views.py =============================================================================== Made User Panel capable of showing more than 1 page of users =============================================================================== --\ mediagoblin/moderation/forms.py --\ mediagoblin/moderation/views.py --\ mediagoblin/templates/mediagoblin/moderation/user_panel.html =============================================================================== Fixed Broken Tests =============================================================================== --\ mediagoblin/tests/test_notifications.py --\ mediagoblin/tests/test_openid.py --\ mediagoblin/tests/test_persona.py --\ mediagoblin/tests/test_reporting.py =============================================================================== Fixed errors in code =============================================================================== --\ mediagoblin/db/migrations.py --| Set nullable to True for MediaReports' and CommentReports' content foreign |keys --\ mediagoblin/db/models.py --| Got rid of cascading rules for MediaReports' and CommentReports' content |foreign keys. This makes it possible for the Reports to continue to exist |after the content is deleted. --\ mediagoblin/moderation/tools.py --| Fixed formatting of Report Resolution Methods --| Took out pieces of code used in debugging --\ mediagoblin/templates/mediagoblin/base.html --\ mediagoblin/templates/mediagoblin/moderation/report.html --| Made reports details page able to tell what is a deleted archived report. --\ mediagoblin/templates/mediagoblin/moderation/report_panel.html --\ mediagoblin/templates/mediagoblin/utils/report.html --- mediagoblin/moderation/views.py | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'mediagoblin/moderation/views.py') diff --git a/mediagoblin/moderation/views.py b/mediagoblin/moderation/views.py index 45edff1d..4721834a 100644 --- a/mediagoblin/moderation/views.py +++ b/mediagoblin/moderation/views.py @@ -19,8 +19,9 @@ from werkzeug.exceptions import Forbidden from mediagoblin.db.models import (MediaEntry, User, MediaComment, \ CommentReport, ReportBase, Privilege, \ UserBan) -from mediagoblin.decorators import (require_admin_or_moderator_login, \ - active_user_from_url, user_has_privilege) +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, \ @@ -58,12 +59,24 @@ def moderation_users_panel(request): ''' Show the global panel for monitoring users in this instance ''' - user_list = User.query + 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}) + {'user_list': user_list, + 'current_page':current_page, + 'last_page':last_page}) @require_admin_or_moderator_login def moderation_users_detail(request): @@ -89,6 +102,7 @@ def moderation_users_detail(request): '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 @@ -135,6 +149,7 @@ def moderation_reports_panel(request): '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. -- cgit v1.2.3 From a523ffce3c84832f95b1376c5a3719fc9ba8cb77 Mon Sep 17 00:00:00 2001 From: tilly-Q Date: Mon, 23 Sep 2013 14:10:11 -0400 Subject: This commit was solely to remove unused imports in the code that I have written --- mediagoblin/moderation/views.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'mediagoblin/moderation/views.py') diff --git a/mediagoblin/moderation/views.py b/mediagoblin/moderation/views.py index 4721834a..f4de11ad 100644 --- a/mediagoblin/moderation/views.py +++ b/mediagoblin/moderation/views.py @@ -14,12 +14,10 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from werkzeug.exceptions import Forbidden -from mediagoblin.db.models import (MediaEntry, User, MediaComment, \ - CommentReport, ReportBase, Privilege, \ +from mediagoblin.db.models import (MediaEntry, User,ReportBase, Privilege, UserBan) -from mediagoblin.decorators import (require_admin_or_moderator_login, +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 @@ -27,8 +25,6 @@ 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 werkzeug.datastructures import ImmutableMultiDict -from datetime import datetime from math import ceil @require_admin_or_moderator_login -- cgit v1.2.3