report_content = Column(UnicodeText)
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}
__tablename__ = 'core__reports_on_media'
__mapper_args__ = {'polymorphic_identity': 'media_report'}
- id = Column(
- 'id',
- Integer,
- ForeignKey('core__reports.id'),
- primary_key=True)
+ id = Column('id',Integer, ForeignKey('core__reports.id'), primary_key=True)
media_entry_id = Column(Integer, ForeignKey(MediaEntry.id), nullable=False)
+class ArchivedReport_v0(ReportBase_v0):
+ __tablename__ = 'core__reports_archived'
+ __mapper_args__ = {'polymorphic_identity': 'archived_report'}
+
+ id = Column('id',Integer, ForeignKey('core__reports.id'))
+
+ media_entry_id = Column(Integer, ForeignKey(MediaEntry.id))
+ comment_id = Column(Integer, ForeignKey(MediaComment.id))
+ resolver_id = Column(Integer, ForeignKey(User.id), nullable=False)
+ resolved_time = Column(DateTime)
+ result = Column(UnicodeText)
class UserBan_v0(declarative_base()):
__tablename__ = 'core__user_bans'
ReportBase_v0.__table__.create(db.bind)
CommentReport_v0.__table__.create(db.bind)
MediaReport_v0.__table__.create(db.bind)
+ ArchivedReport_v0.__table__.create(db.bind)
UserBan_v0.__table__.create(db.bind)
Privilege_v0.__table__.create(db.bind)
PrivilegeUserAssociation_v0.__table__.create(db.bind)
cascade="all, delete-orphan"),
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}
+ def is_comment_report(self):
+ return self.discriminator=='comment_report'
+
+ def is_media_entry_report(self):
+ return self.discriminator=='media_report'
+
+ def is_archived_report(self):
+ return self.discriminator=='archived_report'
+
class CommentReport(ReportBase):
"""
media_entry_id = Column(Integer, ForeignKey(MediaEntry.id), nullable=False)
media_entry = relationship(
MediaEntry,
- backref=backref("reports_filed_on",
+ backref=backref("reports_filed_onmod/reports/1/",
lazy="dynamic",
cascade="all, delete-orphan"))
+class ArchivedReport(ReportBase):
+ """
+ A table to keep track of reports that have been resolved
+ """
+ __tablename__ = 'core__reports_archived'
+ __mapper_args__ = {'polymorphic_identity': 'archived_report'}
+ id = Column('id',Integer, ForeignKey('core__reports.id'),
+ primary_key=True)
+
+ media_entry_id = Column(Integer, ForeignKey(MediaEntry.id))
+ media_entry = relationship(
+ MediaEntry,
+ backref=backref("past_reports_filed_on",
+ lazy="dynamic"))
+ comment_id = Column(Integer, ForeignKey(MediaComment.id))
+ comment = relationship(
+ MediaComment, backref=backref("past_reports_filed_on",
+ lazy="dynamic"))
+
+ resolver_id = Column(Integer, ForeignKey(User.id), nullable=False)
+ resolver = relationship(
+ User,
+ backref=backref("reports_resolved_by",
+ lazy="dynamic",
+ cascade="all, delete-orphan"),
+ primaryjoin="User.id==ArchivedReport.resolver_id")
+
+ resolved = Column(DateTime)
+ result = Column(UnicodeText)
+
class UserBan(Base):
"""
Holds the information on a specific user's ban-state. As long as one of
MODELS = [
User, MediaEntry, Tag, MediaTag, MediaComment, Collection, CollectionItem,
MediaFile, FileKeynames, MediaAttachmentFile, ProcessingMetaData, ReportBase,
- CommentReport, MediaReport, UserBan, Privilege, PrivilegeUserAssociation]
+ CommentReport, MediaReport, UserBan, Privilege, PrivilegeUserAssociation,
+ ArchivedReport]
# Foundations are the default rows that are created immediately after the tables are initialized. Each entry to
# this dictionary should be in the format of
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from mediagoblin.db.base import Session
-from mediagoblin.db.models import MediaEntry, Tag, MediaTag, Collection
+from mediagoblin.db.models import (MediaEntry, Tag, MediaTag, Collection, \
+ User, Privilege, FOUNDATIONS)
##########################
does_exist = Session.query(Collection.id).filter(filt).first() is not None
return does_exist
+def user_privileges_to_dictionary(user_id):
+ """
+ This function accepts a users id and returns a dictionary of True or False
+ values for each privilege the user does or does not have. This allows for
+ easier referencing of a user's privileges inside templates.
+ """
+ privilege_dictionary = {}
+ user = User.query.get(user_id)
+ users_privileges = [p_item.privilege_name for p_item in user.all_privileges]
+ for privilege_name in FOUNDATIONS[Privilege]:
+ privilege_name = privilege_name[0]
+ if privilege_name in users_privileges:
+ privilege_dictionary[privilege_name]=True
+ else:
+ privilege_dictionary[privilege_name]=False
+ return privilege_dictionary
if __name__ == '__main__':
from mediagoblin.db.open import setup_connection_and_db_from_config
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'))]
+ACTION_CHOICES = [(_(u'takeaway'),_(u'Take away privilege')),
+ (_(u'userban'),_(u'Ban the user')),
+ (_(u'sendmessage'),(u'Send the user a message')),
+ (_(u'delete'),_(u'Delete the content'))]
+
+class MultiCheckboxField(wtforms.SelectMultipleField):
+ """
+ A multiple-select, except displays a list of checkboxes.
+
+ Iterating the field will produce subfields, allowing custom rendering of
+ the enclosed checkbox fields.
+
+ code from http://wtforms.simplecodes.com/docs/1.0.4/specific_problems.html
+ """
+ widget = wtforms.widgets.ListWidget(prefix_label=False)
+ option_widget = wtforms.widgets.CheckboxInput()
+
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()],
+ action_to_resolve = MultiCheckboxField(
+ _(u'What action will you take to resolve the report?'),
+ validators=[wtforms.validators.optional()],
choices=ACTION_CHOICES)
targeted_user = wtforms.HiddenField('',
validators=[wtforms.validators.required()])
+ take_away_privileges = wtforms.SelectMultipleField(
+ _(u'What privileges will you take away?'),
+ validators=[wtforms.validators.optional()])
user_banned_until = wtforms.DateField(
- _('User will be banned until:'),
+ _(u'User will be banned until:'),
format='%Y-%m-%d',
validators=[wtforms.validators.optional()])
+ why_user_was_banned = wtforms.TextAreaField(
+ validators=[wtforms.validators.optional()])
+ message_to_user = wtforms.TextAreaField(
+ validators=[wtforms.validators.optional()])
resolution_content = wtforms.TextAreaField()
--- /dev/null
+# GNU MediaGoblin -- federated, autonomous media hosting
+# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+from mediagoblin import mg_globals
+from mediagoblin.db.models import User, Privilege, ArchivedReport, UserBan
+from mediagoblin.db.base import Session
+from mediagoblin.tools.mail import send_email
+from mediagoblin.tools.response import redirect
+from datetime import datetime
+from mediagoblin.tools.translate import lazy_pass_to_ugettext as _
+import sys, traceback
+
+def take_punitive_actions(request, form, report, user):
+ message_body =''
+ try:
+
+ # The bulk of this action is running through all of the different
+ # punitive actions that a moderator could take.
+ if u'takeaway' in form.action_to_resolve.data:
+ for privilege_name in form.take_away_privileges.data:
+ privilege = Privilege.one({u'privilege_name':privilege_name})
+ form.resolution_content.data += \
+ u"<br>%s took away %s\'s %s privileges" % (
+ request.user.username,
+ user.username,
+ privilege.privilege_name)
+ user.all_privileges.remove(privilege)
+
+ # If the moderator elects to ban the user, a new instance of user_ban
+ # will be created.
+ if u'userban' in form.action_to_resolve.data:
+ 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.why_user_was_banned.data
+ )
+ Session.add(user_ban)
+
+ if form.user_banned_until.data is not None:
+ 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)
+
+ # If the moderator elects to send a warning message. An email will be
+ # sent to the email address given at sign up
+ if u'sendmessage' in form.action_to_resolve.data:
+ message_body = form.message_to_user.data
+ form.resolution_content.data += \
+ u"<br>%s sent a warning email to the offender." % (
+ request.user.username)
+
+ archive = ArchivedReport(
+ reporter_id=report.reporter_id,
+ report_content=report.report_content,
+ reported_user_id=report.reported_user_id,
+ created=report.created,
+ resolved=datetime.now(),
+ resolver_id=request.user.id
+ )
+
+ if u'delete' in form.action_to_resolve.data and \
+ report.is_comment_report():
+ deleted_comment = report.comment
+ Session.delete(deleted_comment)
+ form.resolution_content.data += \
+ u"<br>%s deleted the comment" % (
+ request.user.username)
+ elif u'delete' in form.action_to_resolve.data and \
+ report.is_media_entry_report():
+ deleted_media = report.media_entry
+ Session.delete(deleted_media)
+ form.resolution_content.data += \
+ u"<br>%s deleted the media entry" % (
+ request.user.username)
+
+ # If the moderator didn't delete the content we then attach the
+ # content to the archived report. We also have to actively delete the
+ # old report, since it won't be deleted by cascading.
+ elif report.is_comment_report():
+ archive.comment_id = report.comment_id
+ Session.delete(report)
+ elif report.is_media_entry_report():
+ archive.media_entry_id = report.media_entry.id
+ Session.delete(report)
+
+
+ archive.result=form.resolution_content.data
+# Session.add(archive)
+ Session.commit()
+ if message_body:
+ send_email(
+ mg_globals.app_config['email_sender_address'],
+ [user.email],
+ _('Warning from')+ '- {moderator} '.format(
+ moderator=request.user.username),
+ message_body)
+
+ return redirect(
+ request,
+ 'mediagoblin.moderation.users_detail',
+ user=user.username)
+ except:
+#TODO make a more effective and specific try except statement. To account for
+# incorrect value addition my moderators
+ print sys.exc_info()[0]
+ print sys.exc_info()[1]
+ traceback.print_tb(sys.exc_info()[2])
+ Session.rollback()
+ return redirect(
+ request,
+ 'mediagoblin.moderation.reports_detail',
+ report_id=report.id)
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
'''
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):
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
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"<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)
+ 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
request,
'mediagoblin/moderation/report.html',
{'report':report,
- 'media_entry':media_entry,
- 'comment':comment,
'form':form})
@require_admin_or_moderator_login
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)
font-weight: bold;
padding-bottom: 4px;
text-align: left;
+ color: #fff;
+}
+
+table td.user_with_privilege {
+ font-weight: bold;
+ color: #86D4B1;
+}
+
+table td.user_without_privilege {
+ font-weight: bold;
+ color: #D486B1;
+}
+
+.return_to_panel {
+ text-align:right;
+ float: right;
+ font-size:1.2em
}
/* Delete panel */
{% if not report %}
Sorry, no such report found.
{% else %}
- <h2> Report #{{ report.id }}</h2>
- {% if comment %}
- Reported comment:
+ <a href="{{ request.urlgen('mediagoblin.moderation.reports') }}"
+ class="return_to_panel button_action"
+ title="Return to Reports Panel">
+ {% trans %}Return to Reports Panel{% endtrans %}</a>
+ <h2>{% trans %}Report{% endtrans %} #{{ report.id }}</h2>
+ {% if report.is_comment_report() or
+ (report.is_archived_report() and report.comment) %}
+
+ {% trans %}Reported comment{% endtrans %}:
+ {% set comment = report.comment %}
{% set reported_user = comment.get_author %}
<div id="comment-{{ comment.id }}"
class="comment_wrapper">
class="comment_authorlink">
{{- reported_user.username -}}
</a>
- <a href="{{ request.urlgen('mediagoblin.user_pages.media_home.view_comment',
+ <a href="{{ request.urlgen(
+ 'mediagoblin.user_pages.media_home.view_comment',
comment=comment.id,
user=comment.get_media_entry.get_uploader.username,
media=comment.get_media_entry.slug_or_id) }}#comment"
{% endautoescape %}
</div>
</div>
- {% elif media_entry %}
+ {% elif report.is_media_entry_report() or
+ (report.is_archived_report() and report.media_entry) %}
+
+ {% set media_entry = report.media_entry %}
<div class="media_thumbnail">
- <a href="request.urlgen('mediagoblin.user_pages.media_home'),
- user=media_entry.get_uploader.username,
- media=media_entry.slug_or_id)"><img src="{{ media_entry.thumb_url}}"/></a>
- <a href="request.urlgen('mediagoblin.user_pages.media_home'),
+ <a href="{{ request.urlgen('mediagoblin.user_pages.media_home',
+ user=media_entry.get_uploader.username,
+ media=media_entry.slug_or_id) }}">
+ <img src="{{ media_entry.thumb_url}}"/></a>
+ <a href="{{ request.urlgen('mediagoblin.user_pages.media_home',
user=media_entry.get_uploader.username,
- media=media_entry.slug_or_id)" class=thumb_entry_title>{{ media_entry.title }}</a>
+ media=media_entry.slug_or_id) }}" class=thumb_entry_title>
+ {{ media_entry.title }}</a>
</div>
<div class=clear></div>
+ <p>❖ Reported media by <a href="">
+ {{ report.reported_user.username }}</a></p>
+ <div class=clear></div>
+ {% else %}
+ <h2>{% trans user_url="request.urlgen(
+ 'mediagoblin.moderation.users_detail',
+ user=report.reporter.username)",
+ user_name=report.reported_user.username %}
+ CONTENT BY
+ <a href="{{ user_url }}">
+ {{ user_name }}</a>
+ HAS BEEN DELETED{% endtrans %}
+ </h2>
{% endif %}
Reason for report:
<div id="report-{{ report.id }}"
class="report_wrapper">
<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" />
+ <img src="{{ request.staticdirect(
+ '/images/icon_clipboard_alert.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.moderation.users_detail',
user=report.reporter.username) }}"
class="report_authorlink">
{{ report.report_content }}
</div>
</div>
- {% if not report.resolved %}
+ {% if not report.is_archived_report() %}
<input type=button value=Resolve id=open_resolution_form />
<form action="" method="POST" id=resolution_form>
{{ wtforms_util.render_divs(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("");
- }
- });
+$(document).ready(function() {
+ hidden_input_names = {
+ 'takeaway':['take_away_privileges'],
+ 'userban':['user_banned_until','why_user_was_banned'],
+ 'sendmessage':['message_to_user']
+}
+
+ $('form#resolution_form').hide()
+ $('#user_banned_until').val("YYYY-MM-DD")
+ $('#open_resolution_form').click(function() {
+ $('form#resolution_form').toggle();
+ $.each(hidden_input_names, function(key, list){
+ $.each(list, function(index, name){
+ $('label[for='+name+']').hide();
+ $('#'+name).hide();
+ });
+ });
+ });
+ $('#action_to_resolve').change(function() {
+ $('ul#action_to_resolve li input:checked').each(function() {
+ $.each(hidden_input_names[$(this).val()], function(index, name){
+ $('label[for='+name+']').show();
+ $('#'+name).show();
+ });
+ });
+ $('ul#action_to_resolve li input:not(:checked)').each(function() {
+ $.each(hidden_input_names[$(this).val()], function(index, name){
+ $('label[for='+name+']').hide();
+ $('#'+name).hide();
+ });
+ });
+/* $.each(hidden_input_names, function(key,name){
+ if ($.inArray(key, $('ul#action_to_resolve li input:checked').val())){
+ $.each(hidden_input_names[key], function(index,name){
+ $('#'+name).show();
+ $('label[for='+name+']').show();
+ });
+ } else {
+ $.each(hidden_input_names[key], function(index,name){
+ $('#'+name).hide();
+ $('label[for='+name+']').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") }}
+ <h2><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" />
+ {% trans %}Status{% endtrans %}:
+ </h2>
+ <b>{% trans %}RESOLVED{% endtrans %}</b>
+ {{ report.resolved.strftime("%I:%M%p %Y-%m-%d") }}
{% autoescape False %}
- <p>{{ report.result }}</p>
+ <p>{{ report.result }}</p>
{% endautoescape %}
{% endif %}
{% endif %}
<h1>{% trans %}Report panel{% endtrans %}</h1>
<p>
- {% trans %}Here you can look up users in order to take punitive actions on them.{% endtrans %}
+ {% trans %}
+ Here you can look up open reports that have been filed by users.
+ {% endtrans %}
</p>
-<h2>{% trans %}Reports Filed{% endtrans %}</h2>
+<h2>{% trans %}Active Reports Filed{% endtrans %}</h2>
{% if report_list.count() %}
<table class="admin_panel processing">
<tr>
- <th>ID</th>
- <th>Report Type</th>
- <th>Offender</th>
- <th>When Reported</th>
- <th>Reported By</th>
- <th>Reason</th>
- <th>Reported Comment or Media Entry</th>
+ <th></th>
+ <th>{% trans %}Offender{% endtrans %}</th>
+ <th>{% trans %}When Reported{% endtrans %}</th>
+ <th>{% trans %}Reported By{% endtrans %}</th>
+ <th>{% trans %}Reason{% endtrans %}</th>
</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>Comment Report</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>
+ <td>
+ <img
+ src="{{ request.staticdirect('/images/icon_clipboard_alert.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.moderation.reports_detail',
+ report_id=report.id) }}">
+ {% trans report_id=report.id %}
+ Comment Report #{{ report_id }}
+ {% endtrans %}
+ </a>
+ </td>
{% elif report.discriminator == "media_report" %}
- <td>Media Report</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>
+ <td>
+ <img
+ src="{{ request.staticdirect('/images/icon_clipboard_alert.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.moderation.reports_detail',
+ report_id=report.id) }}">
+ {% trans report_id=report.id %}
+ Media Report #{{ report_id }}
+ {% endtrans %}
+ </a>
+ </td>
{% endif %}
+ <td>{{ report.reported_user.username }}</td>
+ <td>{{ report.created.strftime("%F %R") }}</td>
+ <td>{{ report.reporter.username }}</td>
+ <td>{{ report.report_content[0:20] }}...</td>
</tr>
{% endfor %}
</table>
{% if closed_report_list.count() %}
<table class="media_panel processing">
<tr>
- <th>ID</th>
- <th>Resolved</th>
- <th>Offender</th>
- <th>Action Taken</th>
- <th>Reported By</th>
- <th>Reason</th>
- <th>Reported Comment or Media Entry</th>
+ <th></th>
+ <th>{% trans %}Resolved{% endtrans %}</th>
+ <th>{% trans %}Offender{% endtrans %}</th>
+ <th>{% trans %}Action Taken{% endtrans %}</th>
+ <th>{% trans %}Reported By{% endtrans %}</th>
+ <th>{% trans %}Reason{% endtrans %}</th>
</tr>
{% for report in closed_report_list %}
- <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>
- {% 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 %}
+ <tr>
+ <td>
+ <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.moderation.reports_detail',
+ report_id=report.id) }}">
+ {% trans report_id=report.id %}
+ Closed Report #{{ report_id }}
+ {% endtrans %}
+ </a>
+ </td>
+ <td>{{ report.resolved.strftime("%F %R") }}</td>
+ <td>{{ report.reported_user.username }}</td>
+ <td>{{ report.created.strftime("%F %R") }}</td>
+ <td>{{ report.reporter.username }}</td>
+ <td>{{ report.report_content }}</td>
+ </tr>
{% endfor %}
</table>
{% else %}
<p>
{% trans -%}
- Someone has registered an account with this username, but it still has to be activated.
+ Someone has registered an account with this username, but it still has
+ to be activated.
{%- endtrans %}
</p>
-
+
<p>
{% trans login_url=request.urlgen('mediagoblin.auth.login') -%}
- If you are that person but you've lost your verification email, you can <a href="{{ login_url }}">log in</a> and resend it.
+ If you are that person but you've lost your verification email, you can
+ <a href="{{ login_url }}">log in</a> and resend it.
{%- endtrans %}
</p>
</div>
{% else %}
<h1>
{%- trans username=user.username %}{{ username }}'s profile{% endtrans -%}
+ {% if user_banned and user_banned.expiration_date %}
+ — BANNED until {{ user_banned.expiration_date }}
+ {% elif user_banned %}
+ — Banned Indefinitely
+ {% endif %}
</h1>
{% if not user.url and not user.bio %}
<a class="right_align">{{ user.username }}'s report history</a>
<span class=clear></span>
<h2>{{ user.username }}'s Privileges</h2>
- <table class="admin_panel">
+ <form action="{{ request.urlgen('mediagoblin.moderation.give_or_take_away_privilege',
+ user=user.username) }}"
+ method=post >
+ <table class="admin_side_panel">
<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</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>
+ {% if privilege in user.all_privileges %}
+ <td class="user_with_privilege">
+ Yes{% else %}
+ <td class="user_without_privilege">
+ No{% endif %}
+ </td>
+ {% if requesting_user_privileges.admin%}
+ <td>{% if privilege in user.all_privileges %}
+ <input type=submit id="{{ privilege.privilege_name }}" class=submit_button value ="-" />{% else %}
+ <input type=submit id="{{ privilege.privilege_name }}" class=submit_button value ="+" />{% endif %}
+ </td>
+ {% endif %}
+
+ </tr>
{% endfor %}
</table>
+ {{ csrf_token }}
+ <input type=hidden name=privilege_name id=hidden_privilege_name />
+ </form>
{% endif %}
+ <script>
+$(document).ready(function(){
+ $('.submit_button').click(function(){
+ $('#hidden_privilege_name').val($(this).attr('id'));
+ });
+});
+ </script>
{% endblock %}
<h1>{% trans %}User panel{% endtrans %}</h1>
<p>
- {% trans %}Here you can look up users in order to take punitive actions on them.{% endtrans %}
+ {% trans %}
+ Here you can look up users in order to take punitive actions on them.
+ {% endtrans %}
</p>
<h2>{% trans %}Active Users{% endtrans %}</h2>
{% for user in user_list %}
<tr>
<td>{{ user.id }}</td>
- <td><a href="{{ request.urlgen('mediagoblin.moderation.users_detail',
- user= user.username) }}">{{ user.username }}</a></td>
+ <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>
</tr>
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
+from mediagoblin.db.models import UserBan, User
+from datetime import datetime
class Response(wz_Response):
"""Set default response mimetype to HTML, otherwise we get text/plain"""
and the reason why they have been banned"
"""
user_ban = UserBan.query.get(request.user.id)
+ if datetime.now()>user_ban.expiration_date:
+ user_ban.delete()
+ redirect(request,
+ 'mediagoblin.index')
return render_to_response(request,
'mediagoblin/banned.html',
{'reason':user_ban.reason,