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
This commit is contained in:
parent
650a0aa90d
commit
6bba33d7e6
@ -1,115 +0,0 @@
|
||||
# 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 werkzeug.exceptions import Forbidden
|
||||
|
||||
from mediagoblin.db.models import (MediaEntry, User, MediaComment, \
|
||||
CommentReport, ReportBase, Privilege)
|
||||
from mediagoblin.decorators import require_admin_login
|
||||
from mediagoblin.tools.response import render_to_response
|
||||
|
||||
@require_admin_login
|
||||
def admin_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/admin/media_panel.html',
|
||||
{'processing_entries': processing_entries,
|
||||
'failed_entries': failed_entries,
|
||||
'processed_entries': processed_entries})
|
||||
|
||||
@require_admin_login
|
||||
def admin_users_panel(request):
|
||||
'''
|
||||
Show the global panel for monitoring users in this instance
|
||||
'''
|
||||
user_list = User.query
|
||||
|
||||
return render_to_response(
|
||||
request,
|
||||
'mediagoblin/admin/user_panel.html',
|
||||
{'user_list': user_list})
|
||||
|
||||
@require_admin_login
|
||||
def admin_users_detail(request):
|
||||
'''
|
||||
Shows details about a particular user.
|
||||
'''
|
||||
user = User.query.filter_by(username=request.matchdict['user']).first()
|
||||
privileges = Privilege.query
|
||||
active_reports = user.reports_filed_on.filter(
|
||||
ReportBase.resolved==None).limit(5)
|
||||
closed_reports = user.reports_filed_on.filter(
|
||||
ReportBase.resolved!=None).all()
|
||||
|
||||
return render_to_response(
|
||||
request,
|
||||
'mediagoblin/admin/user.html',
|
||||
{'user':user,
|
||||
'privileges':privileges,
|
||||
'reports':active_reports})
|
||||
|
||||
@require_admin_login
|
||||
def admin_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/admin/report_panel.html',
|
||||
{'report_list':report_list,
|
||||
'closed_report_list':closed_report_list})
|
||||
|
||||
@require_admin_login
|
||||
def admin_reports_detail(request):
|
||||
report = ReportBase.query.get(request.matchdict['report_id'])
|
||||
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
|
||||
|
||||
return render_to_response(
|
||||
request,
|
||||
'mediagoblin/admin/report.html',
|
||||
{'report':report,
|
||||
'media_entry':media_entry,
|
||||
'comment':comment})
|
||||
|
||||
|
@ -300,6 +300,7 @@ class ReportBase_v0(declarative_base()):
|
||||
reported_user_id = Column(Integer, ForeignKey(User.id), nullable=False)
|
||||
created = Column(DateTime, nullable=False, default=datetime.datetime.now)
|
||||
resolved = Column(DateTime)
|
||||
result = Column(UnicodeText)
|
||||
discriminator = Column('type', Unicode(50))
|
||||
__mapper_args__ = {'polymorphic_on': discriminator}
|
||||
|
||||
|
@ -239,8 +239,8 @@ class MediaEntry(Base, MediaEntryMixin):
|
||||
This will *not* automatically delete unused collections, which
|
||||
can remain empty...
|
||||
|
||||
:param del_orphan_tags: True/false if we delete unused Tags too
|
||||
:param commit: True/False if this should end the db transaction"""
|
||||
:keyword del_orphan_tags: True/false if we delete unused Tags too
|
||||
:keyword commit: True/False if this should end the db transaction"""
|
||||
# User's CollectionItems are automatically deleted via "cascade".
|
||||
# Comments on this Media are deleted by cascade, hopefully.
|
||||
|
||||
@ -487,6 +487,14 @@ class ProcessingMetaData(Base):
|
||||
|
||||
class ReportBase(Base):
|
||||
"""
|
||||
This is the basic report table which the other reports are based off of.
|
||||
:keyword reporter_id
|
||||
:keyword report_content
|
||||
:keyword reported_user_id
|
||||
:keyword created
|
||||
:keyword resolved
|
||||
:keyword result
|
||||
:keyword discriminator
|
||||
|
||||
"""
|
||||
__tablename__ = 'core__reports'
|
||||
@ -508,6 +516,7 @@ class ReportBase(Base):
|
||||
primaryjoin="User.id==ReportBase.reported_user_id")
|
||||
created = Column(DateTime, nullable=False, default=datetime.datetime.now())
|
||||
resolved = Column(DateTime)
|
||||
result = Column(UnicodeText)
|
||||
discriminator = Column('type', Unicode(50))
|
||||
__mapper_args__ = {'polymorphic_on': discriminator}
|
||||
|
||||
@ -551,13 +560,13 @@ class UserBan(Base):
|
||||
the reason why they are banned and when (if ever) the ban will be
|
||||
lifted
|
||||
|
||||
:param user_id Holds the id of the user this object is
|
||||
:keyword user_id Holds the id of the user this object is
|
||||
attached to. This is a one-to-one
|
||||
relationship.
|
||||
:param expiration_date Holds the date that the ban will be lifted.
|
||||
:keyword expiration_date Holds the date that the ban will be lifted.
|
||||
If this is null, the ban is permanent
|
||||
unless a moderator manually lifts it.
|
||||
:param reason Holds the reason why the user was banned.
|
||||
:keyword reason Holds the reason why the user was banned.
|
||||
"""
|
||||
__tablename__ = 'core__user_bans'
|
||||
|
||||
@ -568,6 +577,17 @@ class UserBan(Base):
|
||||
|
||||
|
||||
class Privilege(Base):
|
||||
"""
|
||||
The Privilege table holds all of the different privileges a user can hold.
|
||||
If a user 'has' a privilege, the User object is in a relationship with the
|
||||
privilege object.
|
||||
|
||||
:keyword privilege_name Holds a unicode object that is the recognizable
|
||||
name of this privilege. This is the column
|
||||
used for identifying whether or not a user
|
||||
has a necessary privilege or not.
|
||||
|
||||
"""
|
||||
__tablename__ = 'core__privileges'
|
||||
|
||||
id = Column(Integer, nullable=False, primary_key=True)
|
||||
@ -578,12 +598,30 @@ class Privilege(Base):
|
||||
secondary="core__privileges_users")
|
||||
|
||||
def __init__(self, privilege_name):
|
||||
'''
|
||||
Currently consructors are required for tables that are initialized thru
|
||||
the FOUNDATIONS system. This is because they need to be able to be con-
|
||||
-structed by a list object holding their arg*s
|
||||
'''
|
||||
self.privilege_name = privilege_name
|
||||
|
||||
def __repr__(self):
|
||||
return "<Privilege %s>" % (self.privilege_name)
|
||||
|
||||
def is_admin_or_moderator(self):
|
||||
'''
|
||||
This method is necessary to check if a user is able to take moderation
|
||||
actions.
|
||||
'''
|
||||
|
||||
return (self.privilege_name==u'admin' or
|
||||
self.privilege_name==u'moderator')
|
||||
|
||||
class PrivilegeUserAssociation(Base):
|
||||
'''
|
||||
This table holds the many-to-many relationship between User and Privilege
|
||||
'''
|
||||
|
||||
__tablename__ = 'core__privileges_users'
|
||||
|
||||
privilege_id = Column(
|
||||
|
@ -21,8 +21,9 @@ from werkzeug.exceptions import Forbidden, NotFound
|
||||
from werkzeug.urls import url_quote
|
||||
|
||||
from mediagoblin import mg_globals as mgg
|
||||
from mediagoblin.db.models import MediaEntry, User, MediaComment, Privilege
|
||||
from mediagoblin.tools.response import redirect, render_404
|
||||
from mediagoblin.db.models import MediaEntry, User, MediaComment, Privilege, \
|
||||
UserBan
|
||||
from mediagoblin.tools.response import redirect, render_404, render_user_banned
|
||||
|
||||
|
||||
def require_active_login(controller):
|
||||
@ -64,6 +65,7 @@ def active_user_from_url(controller):
|
||||
return wrapper
|
||||
|
||||
def user_has_privilege(privilege_name):
|
||||
|
||||
def user_has_privilege_decorator(controller):
|
||||
@wraps(controller)
|
||||
def wrapper(request, *args, **kwargs):
|
||||
@ -71,7 +73,9 @@ def user_has_privilege(privilege_name):
|
||||
privileges_of_user = Privilege.query.filter(
|
||||
Privilege.all_users.any(
|
||||
User.id==user_id))
|
||||
if not privileges_of_user.filter(
|
||||
if UserBan.query.filter(UserBan.user_id==user_id).count():
|
||||
return render_user_banned(request)
|
||||
elif not privileges_of_user.filter(
|
||||
Privilege.privilege_name==privilege_name).count():
|
||||
raise Forbidden()
|
||||
|
||||
@ -271,14 +275,18 @@ def get_workbench(func):
|
||||
|
||||
return new_func
|
||||
|
||||
def require_admin_login(controller):
|
||||
def require_admin_or_moderator_login(controller):
|
||||
"""
|
||||
Require an login from an administrator.
|
||||
Require an login from an administrator or a moderator.
|
||||
"""
|
||||
@wraps(controller)
|
||||
def new_controller_func(request, *args, **kwargs):
|
||||
admin_privilege = Privilege.one({'privilege_name':u'admin'})
|
||||
moderator_privilege = Privilege.one({'privilege_name':u'moderator'})
|
||||
if request.user and \
|
||||
not request.user.is_admin:
|
||||
not admin_privilege in request.user.all_privileges and \
|
||||
not moderator_privilege in request.user.all_privileges:
|
||||
|
||||
raise Forbidden()
|
||||
elif not request.user:
|
||||
next_url = urljoin(
|
||||
@ -293,3 +301,18 @@ def require_admin_login(controller):
|
||||
|
||||
return new_controller_func
|
||||
|
||||
def user_not_banned(controller):
|
||||
"""
|
||||
Requires that the user has not been banned. Otherwise redirects to the page
|
||||
explaining why they have been banned
|
||||
"""
|
||||
@wraps(controller)
|
||||
def wrapper(request, *args, **kwargs):
|
||||
if request.user:
|
||||
user_banned = UserBan.query.get(request.user.id)
|
||||
if user_banned:
|
||||
return render_user_banned(request)
|
||||
return controller(request, *args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
@ -55,6 +55,13 @@ def adduser(args):
|
||||
entry.pw_hash = auth_lib.bcrypt_gen_password_hash(args.password)
|
||||
entry.status = u'active'
|
||||
entry.email_verified = True
|
||||
default_privileges = [
|
||||
db.Privilege.one({'privilege_name':u'commenter'}),
|
||||
db.Privilege.one({'privilege_name':u'uploader'}),
|
||||
db.Privilege.one({'privilege_name':u'reporter'}),
|
||||
db.Privilege.one({'privilege_name':u'active'})
|
||||
]
|
||||
entry.all_privileges = default_privileges
|
||||
entry.save()
|
||||
|
||||
print "User created (and email marked as verified)"
|
||||
|
40
mediagoblin/moderation/forms.py
Normal file
40
mediagoblin/moderation/forms.py
Normal file
@ -0,0 +1,40 @@
|
||||
# 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/>.
|
||||
|
||||
import wtforms
|
||||
from mediagoblin.tools.translate import lazy_pass_to_ugettext as _
|
||||
|
||||
ACTION_CHOICES = [(_(u'takeaway'),_('Take away privilege')),
|
||||
(_(u'userban'),_('Ban the user')),
|
||||
(_(u'closereport'),_('Close the report without taking an action'))]
|
||||
|
||||
class PrivilegeAddRemoveForm(wtforms.Form):
|
||||
giving_privilege = wtforms.HiddenField('',[wtforms.validators.required()])
|
||||
privilege_name = wtforms.HiddenField('',[wtforms.validators.required()])
|
||||
|
||||
class ReportResolutionForm(wtforms.Form):
|
||||
action_to_resolve = wtforms.RadioField(
|
||||
_('What action will you take to resolve this report'),
|
||||
validators=[wtforms.validators.required()],
|
||||
choices=ACTION_CHOICES)
|
||||
targeted_user = wtforms.HiddenField('',
|
||||
validators=[wtforms.validators.required()])
|
||||
user_banned_until = wtforms.DateField(
|
||||
_('User will be banned until:'),
|
||||
format='%Y-%m-%d',
|
||||
validators=[wtforms.validators.optional()])
|
||||
resolution_content = wtforms.TextAreaField()
|
||||
|
35
mediagoblin/moderation/routing.py
Normal file
35
mediagoblin/moderation/routing.py
Normal file
@ -0,0 +1,35 @@
|
||||
# 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/>.
|
||||
|
||||
moderation_routes = [
|
||||
('mediagoblin.moderation.media_panel',
|
||||
'/media/',
|
||||
'mediagoblin.moderation.views:moderation_media_processing_panel'),
|
||||
('mediagoblin.moderation.users',
|
||||
'/users/',
|
||||
'mediagoblin.moderation.views:moderation_users_panel'),
|
||||
('mediagoblin.moderation.reports',
|
||||
'/reports/',
|
||||
'mediagoblin.moderation.views:moderation_reports_panel'),
|
||||
('mediagoblin.moderation.users_detail',
|
||||
'/users/<string:user>/',
|
||||
'mediagoblin.moderation.views:moderation_users_detail'),
|
||||
('mediagoblin.moderation.give_or_take_away_privilege',
|
||||
'/users/<string:user>/privilege/',
|
||||
'mediagoblin.moderation.views:give_or_take_away_privilege'),
|
||||
('mediagoblin.moderation.reports_detail',
|
||||
'/reports/<int:report_id>/',
|
||||
'mediagoblin.moderation.views:moderation_reports_detail')]
|
200
mediagoblin/moderation/views.py
Normal file
200
mediagoblin/moderation/views.py
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
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"<br>%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"<br>%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 + \
|
||||
"<br>"+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"<br>%s banned user %s until %s." % (
|
||||
request.user.username,
|
||||
user.username,
|
||||
form.user_banned_until.data)
|
||||
else:
|
||||
form.resolution_content.data += \
|
||||
u"<br>%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)
|
@ -18,7 +18,7 @@ import logging
|
||||
|
||||
from mediagoblin.tools.routing import add_route, mount, url_map
|
||||
from mediagoblin.tools.pluginapi import PluginManager
|
||||
from mediagoblin.admin.routing import admin_routes
|
||||
from mediagoblin.moderation.routing import moderation_routes
|
||||
from mediagoblin.auth.routing import auth_routes
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@ _log = logging.getLogger(__name__)
|
||||
def get_url_map():
|
||||
add_route('index', '/', 'mediagoblin.views:root_view')
|
||||
mount('/auth', auth_routes)
|
||||
mount('/a', admin_routes)
|
||||
mount('/mod', moderation_routes)
|
||||
|
||||
import mediagoblin.submit.routing
|
||||
import mediagoblin.user_pages.routing
|
||||
|
@ -402,6 +402,8 @@ a.report_authorlink, a.report_whenlink {
|
||||
color: #D486B1;
|
||||
}
|
||||
|
||||
ul#action_to_resolve {list-style:none; margin-left:10px;}
|
||||
|
||||
/* media galleries */
|
||||
|
||||
.media_thumbnail {
|
||||
|
@ -1,3 +1,4 @@
|
||||
{#
|
||||
# GNU MediaGoblin -- federated, autonomous media hosting
|
||||
# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
|
||||
#
|
||||
@ -13,20 +14,15 @@
|
||||
#
|
||||
# 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/>.
|
||||
#}
|
||||
{% extends "mediagoblin/base.html" %}
|
||||
|
||||
admin_routes = [
|
||||
('mediagoblin.admin.media_panel',
|
||||
'/media',
|
||||
'mediagoblin.admin.views:admin_media_processing_panel'),
|
||||
('mediagoblin.admin.users',
|
||||
'/users',
|
||||
'mediagoblin.admin.views:admin_users_panel'),
|
||||
('mediagoblin.admin.reports',
|
||||
'/reports',
|
||||
'mediagoblin.admin.views:admin_reports_panel'),
|
||||
('mediagoblin.admin.users_detail',
|
||||
'/users/<string:user>',
|
||||
'mediagoblin.admin.views:admin_users_detail'),
|
||||
('mediagoblin.admin.reports_detail',
|
||||
'/reports/<int:report_id>',
|
||||
'mediagoblin.admin.views:admin_reports_detail')]
|
||||
{% block title %}You are Banned.{% endblock %}
|
||||
|
||||
{% block mediagoblin_content %}
|
||||
<img class="right_align" src="{{ request.staticdirect('/images/404.png') }}"
|
||||
alt="{% trans %}Image of goblin stressing out{% endtrans %}" />
|
||||
<h1>You have been banned until {{ expiration_date }}</h1>
|
||||
<p>{{ reason|safe }}</p>
|
||||
<div class="clear"></div>
|
||||
{% endblock %}
|
@ -104,9 +104,12 @@
|
||||
{% if request.user.is_admin %}
|
||||
<p>
|
||||
<span class="dropdown_title">Admin powers:</span>
|
||||
<a href="{{ request.urlgen('mediagoblin.admin.media_panel') }}">
|
||||
<a href="{{ request.urlgen('mediagoblin.moderation.media_panel') }}">
|
||||
{%- trans %}Media processing panel{% endtrans -%}
|
||||
</a>
|
||||
<a href="{{ request.urlgen('mediagoblin.moderation.users') }}">
|
||||
{%- trans %}User management panel{% endtrans -%}
|
||||
</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
@ -16,6 +16,7 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#}
|
||||
{%- extends "mediagoblin/base.html" %}
|
||||
{% import "/mediagoblin/utils/wtforms.html" as wtforms_util %}
|
||||
|
||||
{%- block mediagoblin_content %}
|
||||
{% if not report %}
|
||||
@ -29,7 +30,7 @@
|
||||
class="comment_wrapper">
|
||||
<div class="comment_author">
|
||||
<img src="{{ request.staticdirect('/images/icon_comment.png') }}" />
|
||||
<a href="{{ request.urlgen('mediagoblin.admin.users_detail',
|
||||
<a href="{{ request.urlgen('mediagoblin.moderation.users_detail',
|
||||
user=comment.get_author.username) }}"
|
||||
class="comment_authorlink">
|
||||
{{- reported_user.username -}}
|
||||
@ -68,12 +69,12 @@
|
||||
<div class="report_author">
|
||||
<img src="{{ request.staticdirect('/images/icon_clipboard.png') }}"
|
||||
alt="Under a GNU LGPL v.3 or Creative Commons BY-SA 3.0 license. Distributed by the GNOME project http://www.gnome.org" />
|
||||
<a href="{{ request.urlgen('mediagoblin.admin.users_detail',
|
||||
<a href="{{ request.urlgen('mediagoblin.moderation.users_detail',
|
||||
user=report.reporter.username) }}"
|
||||
class="report_authorlink">
|
||||
{{- report.reporter.username -}}
|
||||
</a>
|
||||
<a href="{{ request.urlgen('mediagoblin.admin.reports_detail',
|
||||
<a href="{{ request.urlgen('mediagoblin.moderation.reports_detail',
|
||||
report_id=report.id) }}"
|
||||
class="report_whenlink">
|
||||
<span title='{{- report.created.strftime("%I:%M%p %Y-%m-%d") -}}'>
|
||||
@ -87,5 +88,50 @@
|
||||
{{ report.report_content }}
|
||||
</div>
|
||||
</div>
|
||||
{% if not report.resolved %}
|
||||
<input type=button value=Resolve id=open_resolution_form />
|
||||
<form action="" method="POST" id=resolution_form>
|
||||
{{ wtforms_util.render_divs(form) }}
|
||||
{{ csrf_token }}
|
||||
<input type=submit id="submit_this_report" value="Resolve This Report"/>
|
||||
</form>
|
||||
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('form#resolution_form').hide()
|
||||
$('#user_banned_until').val("YYYY-MM-DD")
|
||||
$('#open_resolution_form').click(function() {
|
||||
$('form#resolution_form').toggle();
|
||||
$('#user_banned_until').hide();
|
||||
$('label[for=user_banned_until]').hide();
|
||||
});
|
||||
$('#action_to_resolve').change(function() {
|
||||
if ($('ul#action_to_resolve li input:checked').val() == "userban") {
|
||||
$('#user_banned_until').show();
|
||||
$('label[for=user_banned_until]').show();
|
||||
} else {
|
||||
$('#user_banned_until').hide();
|
||||
$('label[for=user_banned_until]').hide();
|
||||
}
|
||||
});
|
||||
$("#user_banned_until").focus(function() {
|
||||
$(this).val("");
|
||||
$(this).unbind('focus');
|
||||
});
|
||||
$("#submit_this_report").click(function(){
|
||||
if ($("#user_banned_until").val() == 'YYYY-MM-DD'){
|
||||
$("#user_banned_until").val("");
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% else %}
|
||||
<h2>Status:</h2>
|
||||
RESOLVED on {{ report.resolved.strftime("%I:%M%p %Y-%m-%d") }}
|
||||
{% autoescape False %}
|
||||
<p>{{ report.result }}</p>
|
||||
{% endautoescape %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
@ -29,7 +29,7 @@
|
||||
{% trans %}Here you can look up users in order to take punitive actions on them.{% endtrans %}
|
||||
</p>
|
||||
|
||||
<h2>{% trans %}Reports Filed on Comments{% endtrans %}</h2>
|
||||
<h2>{% trans %}Reports Filed{% endtrans %}</h2>
|
||||
|
||||
{% if report_list.count() %}
|
||||
<table class="admin_panel processing">
|
||||
@ -44,8 +44,10 @@
|
||||
</tr>
|
||||
{% for report in report_list %}
|
||||
<tr>
|
||||
|
||||
<td><a href="{{ request.urlgen('mediagoblin.moderation.reports_detail',
|
||||
report_id=report.id) }}">{{ report.id }}</a></td>
|
||||
{% if report.discriminator == "comment_report" %}
|
||||
<td>{{ report.id }}</td>
|
||||
<td>Comment Report</td>
|
||||
<td>{{ report.comment.get_author.username }}</td>
|
||||
<td>{{ report.created.strftime("%F %R") }}</td>
|
||||
@ -53,7 +55,6 @@
|
||||
<td>{{ report.report_content }}</td>
|
||||
<td><a href="{{ report.comment.get_media_entry.url_for_self(request.urlgen) }}">{{ report.comment.get_media_entry.title }}</a></td>
|
||||
{% elif report.discriminator == "media_report" %}
|
||||
<td>{{ report.id }}</td>
|
||||
<td>Media Report</td>
|
||||
<td>{{ report.media_entry.get_uploader.username }}</td>
|
||||
<td>{{ report.created.strftime("%F %R") }}</td>
|
||||
@ -67,26 +68,36 @@
|
||||
{% else %}
|
||||
<p><em>{% trans %}No open reports found.{% endtrans %}</em></p>
|
||||
{% endif %}
|
||||
<h2>{% trans %}Closed Reports on Comments{% endtrans %}</h2>
|
||||
<h2>{% trans %}Closed Reports{% endtrans %}</h2>
|
||||
{% if closed_report_list.count() %}
|
||||
<table class="media_panel processing">
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Resolved</th>
|
||||
<th>Offender</th>
|
||||
<th>When Reported</th>
|
||||
<th>Action Taken</th>
|
||||
<th>Reported By</th>
|
||||
<th>Reason</th>
|
||||
<th>Comment Posted On</th>
|
||||
<th>Reported Comment or Media Entry</th>
|
||||
</tr>
|
||||
{% for report in closed_report_list %}
|
||||
<tr>
|
||||
<td>{{ report.id }}</td>
|
||||
<td><a href="{{ request.urlgen('mediagoblin.moderation.reports_detail',
|
||||
report_id=report.id) }}">{{ report.id }}</a></td>
|
||||
{% if report.discriminator == "comment_report" %}
|
||||
<td>{{ report.resolved.strftime("%F %R") }}</td>
|
||||
<td>{{ report.comment.get_author.username }}</td>
|
||||
<td>{{ report.created.strftime("%F %R") }}</td>
|
||||
<td>{{ report.reporter.username }}</td>
|
||||
<td>{{ report.report_content }}</td>
|
||||
<td><a href="{{ report.comment.get_media_entry.url_for_self(request.urlgen) }}">{{ report.comment.get_media_entry.title }}</a></td>
|
||||
</tr>
|
||||
{% elif report.discriminator == "media_report" %}
|
||||
<td>{{ report.resolved.strftime("%F %R") }}</td>
|
||||
<td>{{ report.media_entry.get_uploader.username }}</td>
|
||||
<td>{{ report.created.strftime("%F %R") }}</td>
|
||||
<td>{{ report.reporter.username }}</td>
|
||||
<td>{{ report.report_content[0:20] }}...</td>
|
||||
<td><a href="{{ report.media_entry.url_for_self(request.urlgen) }}">{{ report.media_entry.title }}</a></td>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
@ -97,7 +97,7 @@
|
||||
<tr>
|
||||
<td>
|
||||
<img src="{{ request.staticdirect('/images/icon_clipboard.png') }}" />
|
||||
<a href="{{ request.urlgen('mediagoblin.admin.reports_detail',
|
||||
<a href="{{ request.urlgen('mediagoblin.moderation.reports_detail',
|
||||
report_id=report.id) }}">
|
||||
{%- trans %}Report #{% endtrans -%}{{ report.id }}
|
||||
</a>
|
||||
@ -125,11 +125,29 @@
|
||||
<tr>
|
||||
<th>{% trans %}Privilege{% endtrans %}</th>
|
||||
<th>{% trans %}User Has Privilege{% endtrans %}</th>
|
||||
</tr>
|
||||
{% for privilege in privileges %}
|
||||
<tr>
|
||||
<form action="{{ request.urlgen('mediagoblin.moderation.give_or_take_away_privilege',
|
||||
user=user.username) }}"
|
||||
method=post >
|
||||
<td>{{ privilege.privilege_name }}</td>
|
||||
<td>{% if privilege in user.all_privileges %}Yes{% else %}No{% endif %}</td>
|
||||
<td>{% if privilege in user.all_privileges and privilege.id < request.user.get_highest_privilege().id %}<a>{% trans %}Take Away{% endtrans %}</a>{% else %}<a>{% trans %}Give Privilege{% endtrans %}</a>{% endif %}</td>
|
||||
<td>
|
||||
{% if privilege in user.all_privileges %}Yes</td>
|
||||
{% if (not privilege.is_admin_or_moderator() or request.user.is_admin) and not (user.is_admin and not request.user.is_admin) %}
|
||||
<td><input type=submit value="{% trans %}Take Away{% endtrans %}" />
|
||||
<input type=hidden name=giving_privilege />
|
||||
{% endif %}
|
||||
{% else %}No</td>
|
||||
{% if (not privilege.is_admin_or_moderator() or request.user.is_admin) and not (user.is_admin and not request.user.is_admin) %}
|
||||
<td><input type=submit value="{% trans %}Give Privilege{% endtrans %}" >
|
||||
<input type=hidden name=giving_privilege value=True />
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<input type=hidden name=privilege_name value="{{ privilege.privilege_name }}" />
|
||||
</td>
|
||||
{{ csrf_token }}
|
||||
</form>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
@ -42,7 +42,7 @@
|
||||
{% for user in user_list %}
|
||||
<tr>
|
||||
<td>{{ user.id }}</td>
|
||||
<td><a href="{{ request.urlgen('mediagoblin.admin.users_detail',
|
||||
<td><a href="{{ request.urlgen('mediagoblin.moderation.users_detail',
|
||||
user= user.username) }}">{{ user.username }}</a></td>
|
||||
<td>{{ user.created.strftime("%F %R") }}</td>
|
||||
<td>{{ user.posted_comments.count() }}</td>
|
@ -19,6 +19,7 @@ from werkzeug.wrappers import Response as wz_Response
|
||||
from mediagoblin.tools.template import render_template
|
||||
from mediagoblin.tools.translate import (lazy_pass_to_ugettext as _,
|
||||
pass_to_ugettext)
|
||||
from mediagoblin.db.models import UserBan
|
||||
|
||||
class Response(wz_Response):
|
||||
"""Set default response mimetype to HTML, otherwise we get text/plain"""
|
||||
@ -62,6 +63,15 @@ def render_404(request):
|
||||
"you're looking for has been moved or deleted.")
|
||||
return render_error(request, 404, err_msg=err_msg)
|
||||
|
||||
def render_user_banned(request):
|
||||
"""Renders the page which tells a user they have been banned, for how long
|
||||
and the reason why they have been banned"
|
||||
"""
|
||||
user_ban = UserBan.query.get(request.user.id)
|
||||
return render_to_response(request,
|
||||
'mediagoblin/banned.html',
|
||||
{'reason':user_ban.reason,
|
||||
'expiration_date':user_ban.expiration_date})
|
||||
|
||||
def render_http_exception(request, exc, description):
|
||||
"""Return Response() given a werkzeug.HTTPException
|
||||
|
@ -51,11 +51,15 @@ class MediaCollectForm(wtforms.Form):
|
||||
Markdown</a> for formatting."""))
|
||||
|
||||
class CommentReportForm(wtforms.Form):
|
||||
report_reason = wtforms.TextAreaField('Reason for Reporting')
|
||||
report_reason = wtforms.TextAreaField(
|
||||
_('Reason for Reporting'),
|
||||
[wtforms.validators.Required()])
|
||||
comment_id = wtforms.IntegerField()
|
||||
reporter_id = wtforms.IntegerField()
|
||||
|
||||
class MediaReportForm(wtforms.Form):
|
||||
report_reason = wtforms.TextAreaField('Reason for Reporting')
|
||||
report_reason = wtforms.TextAreaField(
|
||||
_('Reason for Reporting'),
|
||||
[wtforms.validators.Required()])
|
||||
media_entry_id = wtforms.IntegerField()
|
||||
reporter_id = wtforms.IntegerField()
|
||||
|
@ -78,7 +78,7 @@ def add_media_to_collection(collection, media, note=None, commit=True):
|
||||
if commit:
|
||||
Session.commit()
|
||||
|
||||
def build_report_form(form_dict):
|
||||
def build_report_table(form_dict):
|
||||
"""
|
||||
This function is used to convert a form dictionary (from a User filing a
|
||||
report) into either a MediaReport or CommentReport object.
|
||||
|
@ -26,14 +26,14 @@ from mediagoblin.tools.response import render_to_response, render_404, \
|
||||
from mediagoblin.tools.translate import pass_to_ugettext as _
|
||||
from mediagoblin.tools.pagination import Pagination
|
||||
from mediagoblin.user_pages import forms as user_forms
|
||||
from mediagoblin.user_pages.lib import (send_comment_email, build_report_form,
|
||||
from mediagoblin.user_pages.lib import (send_comment_email, build_report_table,
|
||||
add_media_to_collection)
|
||||
|
||||
from mediagoblin.decorators import (uses_pagination, get_user_media_entry,
|
||||
get_media_entry_by_id, user_has_privilege,
|
||||
require_active_login, user_may_delete_media, user_may_alter_collection,
|
||||
get_user_collection, get_user_collection_item, active_user_from_url,
|
||||
get_media_comment_by_id)
|
||||
get_media_comment_by_id, user_not_banned)
|
||||
|
||||
from werkzeug.contrib.atom import AtomFeed
|
||||
|
||||
@ -41,7 +41,7 @@ from werkzeug.contrib.atom import AtomFeed
|
||||
_log = logging.getLogger(__name__)
|
||||
_log.setLevel(logging.DEBUG)
|
||||
|
||||
|
||||
@user_not_banned
|
||||
@uses_pagination
|
||||
def user_home(request, page):
|
||||
"""'Homepage' of a User()"""
|
||||
@ -80,7 +80,7 @@ def user_home(request, page):
|
||||
'media_entries': media_entries,
|
||||
'pagination': pagination})
|
||||
|
||||
|
||||
@user_not_banned
|
||||
@active_user_from_url
|
||||
@uses_pagination
|
||||
def user_gallery(request, page, url_user=None):
|
||||
@ -114,7 +114,7 @@ def user_gallery(request, page, url_user=None):
|
||||
|
||||
MEDIA_COMMENTS_PER_PAGE = 50
|
||||
|
||||
|
||||
@user_not_banned
|
||||
@get_user_media_entry
|
||||
@uses_pagination
|
||||
def media_home(request, media, page, **kwargs):
|
||||
@ -190,7 +190,7 @@ def media_post_comment(request, media):
|
||||
|
||||
return redirect_obj(request, media)
|
||||
|
||||
|
||||
@user_not_banned
|
||||
@get_media_entry_by_id
|
||||
@require_active_login
|
||||
def media_collect(request, media):
|
||||
@ -269,6 +269,7 @@ def media_collect(request, media):
|
||||
|
||||
|
||||
#TODO: Why does @user_may_delete_media not implicate @require_active_login?
|
||||
@user_not_banned
|
||||
@get_media_entry_by_id
|
||||
@require_active_login
|
||||
@user_may_delete_media
|
||||
@ -305,7 +306,7 @@ def media_confirm_delete(request, media):
|
||||
{'media': media,
|
||||
'form': form})
|
||||
|
||||
|
||||
@user_not_banned
|
||||
@active_user_from_url
|
||||
@uses_pagination
|
||||
def user_collection(request, page, url_user=None):
|
||||
@ -335,7 +336,7 @@ def user_collection(request, page, url_user=None):
|
||||
'collection_items': collection_items,
|
||||
'pagination': pagination})
|
||||
|
||||
|
||||
@user_not_banned
|
||||
@active_user_from_url
|
||||
def collection_list(request, url_user=None):
|
||||
"""A User-defined Collection"""
|
||||
@ -391,7 +392,7 @@ def collection_item_confirm_remove(request, collection_item):
|
||||
{'collection_item': collection_item,
|
||||
'form': form})
|
||||
|
||||
|
||||
@user_not_banned
|
||||
@get_user_collection
|
||||
@require_active_login
|
||||
@user_may_alter_collection
|
||||
@ -575,7 +576,7 @@ def collection_atom_feed(request):
|
||||
|
||||
return feed.get_response()
|
||||
|
||||
|
||||
@user_not_banned
|
||||
@require_active_login
|
||||
def processing_panel(request):
|
||||
"""
|
||||
@ -625,8 +626,8 @@ def processing_panel(request):
|
||||
@user_has_privilege(u'reporter')
|
||||
def file_a_report(request, media, comment=None):
|
||||
if request.method == "POST":
|
||||
report_form = build_report_form(request.form)
|
||||
report_form.save()
|
||||
report_table = build_report_table(request.form)
|
||||
report_table.save()
|
||||
|
||||
return redirect(
|
||||
request,
|
||||
|
@ -18,10 +18,10 @@ from mediagoblin import mg_globals
|
||||
from mediagoblin.db.models import MediaEntry
|
||||
from mediagoblin.tools.pagination import Pagination
|
||||
from mediagoblin.tools.response import render_to_response
|
||||
from mediagoblin.decorators import uses_pagination
|
||||
|
||||
from mediagoblin.decorators import uses_pagination, user_not_banned
|
||||
|
||||
|
||||
@user_not_banned
|
||||
@uses_pagination
|
||||
def root_view(request, page):
|
||||
cursor = MediaEntry.query.filter_by(state=u'processed').\
|
||||
|
Loading…
x
Reference in New Issue
Block a user