mirror of
https://gitlab.com/SIGBUS/nyaa.git
synced 2024-12-22 15:40:00 +00:00
Implemented report action
Actions: Close report, Hide torrent, Delete torrent
This commit is contained in:
parent
e6083325d6
commit
354736720b
|
@ -282,7 +282,8 @@ class ReportForm(FlaskForm):
|
||||||
reason = TextAreaField('Report reason', [
|
reason = TextAreaField('Report reason', [
|
||||||
Length(min=3, max=255,
|
Length(min=3, max=255,
|
||||||
message='Report reason must be at least %(min)d characters long '
|
message='Report reason must be at least %(min)d characters long '
|
||||||
'and %(max)d at most.')
|
'and %(max)d at most.'),
|
||||||
|
DataRequired('You must provide a valid report reason.')
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ from urllib.parse import unquote as unquote_url
|
||||||
|
|
||||||
if app.config['USE_MYSQL']:
|
if app.config['USE_MYSQL']:
|
||||||
from sqlalchemy.dialects import mysql
|
from sqlalchemy.dialects import mysql
|
||||||
|
|
||||||
BinaryType = mysql.BINARY
|
BinaryType = mysql.BINARY
|
||||||
DescriptionTextType = mysql.TEXT
|
DescriptionTextType = mysql.TEXT
|
||||||
MediumBlobType = mysql.MEDIUMBLOB
|
MediumBlobType = mysql.MEDIUMBLOB
|
||||||
|
@ -27,7 +28,6 @@ else:
|
||||||
COL_UTF8MB4_BIN = None
|
COL_UTF8MB4_BIN = None
|
||||||
COL_ASCII_GENERAL_CI = 'NOCASE'
|
COL_ASCII_GENERAL_CI = 'NOCASE'
|
||||||
|
|
||||||
|
|
||||||
# For property timestamps
|
# For property timestamps
|
||||||
UTC_EPOCH = datetime.utcfromtimestamp(0)
|
UTC_EPOCH = datetime.utcfromtimestamp(0)
|
||||||
|
|
||||||
|
@ -327,6 +327,7 @@ class User(db.Model):
|
||||||
last_login_ip = db.Column(db.Binary(length=16), default=None, nullable=True)
|
last_login_ip = db.Column(db.Binary(length=16), default=None, nullable=True)
|
||||||
|
|
||||||
torrents = db.relationship('Torrent', back_populates='user', lazy="dynamic")
|
torrents = db.relationship('Torrent', back_populates='user', lazy="dynamic")
|
||||||
|
|
||||||
# session = db.relationship('Session', uselist=False, back_populates='user')
|
# session = db.relationship('Session', uselist=False, back_populates='user')
|
||||||
|
|
||||||
def __init__(self, username, email, password):
|
def __init__(self, username, email, password):
|
||||||
|
@ -398,8 +399,8 @@ class Report(db.Model):
|
||||||
reason = db.Column(db.String(length=255), nullable=False)
|
reason = db.Column(db.String(length=255), nullable=False)
|
||||||
status = db.Column(ChoiceType(ReportStatus, impl=db.Integer()), nullable=False)
|
status = db.Column(ChoiceType(ReportStatus, impl=db.Integer()), nullable=False)
|
||||||
|
|
||||||
user = db.relationship('User', uselist=False)
|
user = db.relationship('User', uselist=False, lazy="joined")
|
||||||
torrent = db.relationship('Torrent', uselist=False)
|
torrent = db.relationship('Torrent', uselist=False, lazy="joined")
|
||||||
|
|
||||||
def __init__(self, torrent_id, user_id, reason):
|
def __init__(self, torrent_id, user_id, reason):
|
||||||
self.torrent_id = torrent_id
|
self.torrent_id = torrent_id
|
||||||
|
@ -416,8 +417,16 @@ class Report(db.Model):
|
||||||
return (self.created_time - UTC_EPOCH).total_seconds()
|
return (self.created_time - UTC_EPOCH).total_seconds()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def not_reviewed(cls):
|
def by_id(cls, id):
|
||||||
reports = cls.query.filter_by(status=0).all()
|
return cls.query.get(id)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def not_reviewed(cls, page):
|
||||||
|
reports = cls.query.filter(cls.status == 0)\
|
||||||
|
.join(Torrent, aliased=True).filter(Torrent.flags != 36, Torrent.flags != 2)\
|
||||||
|
.order_by(db.asc(cls.id))\
|
||||||
|
.paginate(page=page, per_page=20)
|
||||||
|
# reports = cls.query.filter_by(status=0).paginate(page=page, per_page=20)
|
||||||
return reports
|
return reports
|
||||||
|
|
||||||
# class Session(db.Model):
|
# class Session(db.Model):
|
||||||
|
|
|
@ -27,7 +27,6 @@ from email.utils import formatdate
|
||||||
|
|
||||||
from flask_paginate import Pagination
|
from flask_paginate import Pagination
|
||||||
|
|
||||||
|
|
||||||
DEBUG_API = False
|
DEBUG_API = False
|
||||||
DEFAULT_MAX_SEARCH_RESULT = 1000
|
DEFAULT_MAX_SEARCH_RESULT = 1000
|
||||||
DEFAULT_PER_PAGE = 75
|
DEFAULT_PER_PAGE = 75
|
||||||
|
@ -582,7 +581,7 @@ def view_torrent(torrent_id):
|
||||||
return flask.render_template('view.html', torrent=torrent,
|
return flask.render_template('view.html', torrent=torrent,
|
||||||
files=files,
|
files=files,
|
||||||
can_edit=can_edit,
|
can_edit=can_edit,
|
||||||
form=report_form)
|
report_form=report_form)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/view/<int:torrent_id>/edit', methods=['GET', 'POST'])
|
@app.route('/view/<int:torrent_id>/edit', methods=['GET', 'POST'])
|
||||||
|
@ -667,34 +666,54 @@ def download_torrent(torrent_id):
|
||||||
|
|
||||||
@app.route('/view/<int:torrent_id>/submit_report', methods=['POST'])
|
@app.route('/view/<int:torrent_id>/submit_report', methods=['POST'])
|
||||||
def submit_report(torrent_id):
|
def submit_report(torrent_id):
|
||||||
|
if not flask.g.user:
|
||||||
|
flask.abort(403)
|
||||||
|
|
||||||
form = forms.ReportForm(flask.request.form)
|
form = forms.ReportForm(flask.request.form)
|
||||||
|
|
||||||
if flask.request.method == 'POST' and form.validate():
|
if flask.request.method == 'POST' and form.validate():
|
||||||
report_reason = (form.reason.data or '').strip()
|
report_reason = form.reason.data
|
||||||
|
current_user_id = flask.g.user.id
|
||||||
|
report = models.Report(
|
||||||
|
torrent_id=torrent_id,
|
||||||
|
user_id=current_user_id,
|
||||||
|
reason=report_reason)
|
||||||
|
|
||||||
if flask.g.user is not None:
|
db.session.add(report)
|
||||||
current_user_id = flask.g.user.id
|
db.session.commit()
|
||||||
report = models.Report(
|
flask.flash('Successfully reported torrent!', 'success')
|
||||||
torrent_id=torrent_id,
|
|
||||||
user_id=current_user_id,
|
|
||||||
reason=report_reason)
|
|
||||||
|
|
||||||
db.session.add(report)
|
|
||||||
db.session.commit()
|
|
||||||
flask.flash('Successfully reported torrent!', 'success')
|
|
||||||
else:
|
|
||||||
flask.abort(403)
|
|
||||||
|
|
||||||
return flask.redirect(flask.url_for('view_torrent', torrent_id=torrent_id))
|
return flask.redirect(flask.url_for('view_torrent', torrent_id=torrent_id))
|
||||||
|
|
||||||
|
|
||||||
@app.route('/reports', methods=['GET'])
|
@app.route('/reports', methods=['GET', 'POST'])
|
||||||
def view_reports():
|
def view_reports():
|
||||||
reports = models.Report.not_reviewed()
|
|
||||||
|
|
||||||
if not flask.g.user or not flask.g.user.is_admin:
|
if not flask.g.user or not flask.g.user.is_admin:
|
||||||
flask.abort(403)
|
flask.abort(403)
|
||||||
|
|
||||||
|
page = flask.request.args.get('p', flask.request.args.get('offset', 1, int), int)
|
||||||
|
reports = models.Report.not_reviewed(page)
|
||||||
|
|
||||||
|
if flask.request.method == 'POST':
|
||||||
|
data = flask.request.form
|
||||||
|
torrent = models.Torrent.by_id(data['torrent'])
|
||||||
|
report = models.Report.by_id(data['report'])
|
||||||
|
if not torrent or not report or report.status != 0:
|
||||||
|
flask.abort(404)
|
||||||
|
else:
|
||||||
|
if data['action'] == 'delete':
|
||||||
|
torrent.deleted = True
|
||||||
|
report.status = 1
|
||||||
|
elif data['action'] == 'hide':
|
||||||
|
torrent.hidden = True
|
||||||
|
report.status = 1
|
||||||
|
else:
|
||||||
|
report.status = 2
|
||||||
|
|
||||||
|
db.session.commit()
|
||||||
|
flask.flash('Closed report #{}'.format(report.id), 'success')
|
||||||
|
return flask.redirect(flask.url_for('view_reports'))
|
||||||
|
|
||||||
return flask.render_template('reports.html',
|
return flask.render_template('reports.html',
|
||||||
reports=reports)
|
reports=reports)
|
||||||
|
|
||||||
|
|
|
@ -2,29 +2,50 @@
|
||||||
{% block title %}Reports :: {{ config.SITE_NAME }}{% endblock %}
|
{% block title %}Reports :: {{ config.SITE_NAME }}{% endblock %}
|
||||||
{% block body %}
|
{% block body %}
|
||||||
{% from "_formhelpers.html" import render_field %}
|
{% from "_formhelpers.html" import render_field %}
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-bordered table-hover table-striped">
|
<table class="table table-bordered table-hover table-striped">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>#</th>
|
<th>#</th>
|
||||||
<th>Reported by:</th>
|
<th>Reported by</th>
|
||||||
<th>Torrent:</th>
|
<th>Torrent</th>
|
||||||
<th>Reason:</th>
|
<th>Reason</th>
|
||||||
<th>Date:</th>
|
<th>Date</th>
|
||||||
<th>Action:</th>
|
<th>Action</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for report in reports %}
|
{% for report in reports.items %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ report.id }}</td>
|
<td>{{ report.id }}</td>
|
||||||
<td><a href="{{ url_for('view_user', user_name=report.user.username) }}">{{ report.user.username }}</a></td>
|
<td>
|
||||||
<td><a href="{{ url_for('view_torrent', torrent_id=report.torrent.id) }}">{{ report.torrent.display_name }}</a></td>
|
<a href="{{ url_for('view_user', user_name=report.user.username) }}">{{ report.user.username }}</a>
|
||||||
<td>{{ report.reason }}</td>
|
</td>
|
||||||
<td>{{ report.created_time }}</td>
|
<td>
|
||||||
</tr>
|
<a href="{{ url_for('view_torrent', torrent_id=report.torrent.id) }}">{{ report.torrent.display_name }}</a>
|
||||||
{% endfor %}
|
</td>
|
||||||
</tbody>
|
<td>{{ report.reason }}</td>
|
||||||
</table>
|
<td>{{ report.created_time }}</td>
|
||||||
</div>
|
<td style="width: 15%">
|
||||||
|
<form method="post">
|
||||||
|
<select name="action" class="pull-left">
|
||||||
|
<option value="close">Close</option>
|
||||||
|
<option value="delete">Delete</option>
|
||||||
|
<option value="hide">Hide</option>
|
||||||
|
</select>
|
||||||
|
<input type="hidden" value="{{ report.torrent.id }}" name="torrent">
|
||||||
|
<input type="hidden" value="{{ report.id }}" name="report">
|
||||||
|
<button type="submit" class="btn btn-primary pull-right">Review</button>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class=pagination>
|
||||||
|
{% from "bootstrap/pagination.html" import render_pagination %}
|
||||||
|
{{ render_pagination(reports) }}
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -2,158 +2,179 @@
|
||||||
{% block title %}{{ torrent.display_name }} :: {{ config.SITE_NAME }}{% endblock %}
|
{% block title %}{{ torrent.display_name }} :: {{ config.SITE_NAME }}{% endblock %}
|
||||||
{% block body %}
|
{% block body %}
|
||||||
{% from "_formhelpers.html" import render_field %}
|
{% from "_formhelpers.html" import render_field %}
|
||||||
<div class="panel panel-{% if torrent.deleted %}deleted{% elif torrent.remake %}danger{% elif torrent.trusted %}success{% else %}default{% endif %}">
|
<div class="panel panel-{% if torrent.deleted %}deleted{% elif torrent.remake %}danger{% elif torrent.trusted %}success{% else %}default{% endif %}">
|
||||||
<div class="panel-heading"{% if torrent.hidden %} style="background-color: darkgray;"{% endif %}>
|
<div class="panel-heading"{% if torrent.hidden %} style="background-color: darkgray;"{% endif %}>
|
||||||
<h3 class="panel-title">
|
<h3 class="panel-title">
|
||||||
{% if can_edit %}
|
{% if can_edit %}
|
||||||
<a href="{{ request.url }}/edit"><i class="fa fa-fw fa-pencil"></i></a>
|
<a href="{{ request.url }}/edit"><i class="fa fa-fw fa-pencil"></i></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{ torrent.display_name }}
|
{{ torrent.display_name }}
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-1">Category:</div>
|
|
||||||
<div class="col-md-5">
|
|
||||||
<a href="{{ url_for("home", c=torrent.main_category.id_as_string) }}">{{ torrent.main_category.name }}</a> - <a href="{{ url_for("home", c=torrent.sub_category.id_as_string) }}">{{ torrent.sub_category.name }}</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-1">Date:</div>
|
|
||||||
<div class="col-md-5" data-timestamp="{{ torrent.created_utc_timestamp|int }}">{{ torrent.created_time.strftime('%Y-%m-%d %H:%M UTC') }}</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-1">Submitter:</div>
|
|
||||||
<div class="col-md-5">{% if not torrent.anonymous and torrent.user %}<a href="{{ url_for('view_user', user_name=torrent.user.username) }}">{{ torrent.user.username }}</a>{% else %}Anonymous{% endif %}</div>
|
|
||||||
|
|
||||||
<div class="col-md-1">Seeders:</div>
|
|
||||||
<div class="col-md-5"><span style="color: green;">{% if config.ENABLE_SHOW_STATS %}{{ torrent.stats.seed_count }}{% else %}Coming soon{% endif %}</span></div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-1">Information:</div>
|
|
||||||
<div class="col-md-5">
|
|
||||||
{% if torrent.information %}
|
|
||||||
{{ torrent.information_as_link | safe }}
|
|
||||||
{% else %}
|
|
||||||
No information.
|
|
||||||
{% endif%}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-1">Leechers:</div>
|
|
||||||
<div class="col-md-5"><span style="color: red;">{% if config.ENABLE_SHOW_STATS %}{{ torrent.stats.leech_count }}{% else %}Coming soon{% endif %}</span></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-1">File size:</div>
|
|
||||||
<div class="col-md-5">{{ torrent.filesize | filesizeformat(True) }}</div>
|
|
||||||
|
|
||||||
<div class="col-md-1">Downloads:</div>
|
|
||||||
<div class="col-md-5">{% if config.ENABLE_SHOW_STATS %}{{ torrent.stats.download_count }}{% else %}Coming soon{% endif %}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="panel-footer">
|
|
||||||
{% if torrent.has_torrent %}<a href="/view/{{ torrent.id }}/torrent"><i class="fa fa-download fa-fw"></i>Download Torrent</a> or {% endif %}<a href="{{ torrent.magnet_uri }}" class="card-footer-item"><i class="fa fa-magnet fa-fw"></i>Magnet</a>
|
|
||||||
<button type="button" class="btn btn-danger pull-right" data-toggle="modal" data-target="#reportModal">Report</button>
|
|
||||||
<div class="clearfix"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-body" id="torrent-description">
|
|
||||||
{% if torrent.description %}
|
|
||||||
{# Escape newlines into html entities because CF strips blank newlines #}
|
|
||||||
{{ torrent.description | escape | replace('\r\n', '\n') | replace('\n', ' '|safe) }}
|
|
||||||
{% else %}
|
|
||||||
#### No description.
|
|
||||||
{% endif%}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% if files and files.__len__() <= config.MAX_FILES_VIEW %}
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading panel-heading-collapse">
|
|
||||||
<h3 class="panel-title">
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<a class="collapsed col-md-12" data-target="#collapseFileList" data-toggle="collapse" style="color:inherit;text-decoration:none;">File list</a>
|
<div class="col-md-1">Category:</div>
|
||||||
|
<div class="col-md-5">
|
||||||
|
<a href="{{ url_for("home", c=torrent.main_category.id_as_string) }}">{{ torrent.main_category.name }}</a>
|
||||||
|
- <a
|
||||||
|
href="{{ url_for("home", c=torrent.sub_category.id_as_string) }}">{{ torrent.sub_category.name }}</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-1">Date:</div>
|
||||||
|
<div class="col-md-5"
|
||||||
|
data-timestamp="{{ torrent.created_utc_timestamp|int }}">{{ torrent.created_time.strftime('%Y-%m-%d %H:%M UTC') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</h3>
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-1">Submitter:</div>
|
||||||
|
<div class="col-md-5">{% if not torrent.anonymous and torrent.user %}
|
||||||
|
<a href="{{ url_for('view_user', user_name=torrent.user.username) }}">{{ torrent.user.username }}</a>{% else %}
|
||||||
|
Anonymous{% endif %}</div>
|
||||||
|
|
||||||
|
<div class="col-md-1">Seeders:</div>
|
||||||
|
<div class="col-md-5"><span style="color: green;">{% if config.ENABLE_SHOW_STATS %}
|
||||||
|
{{ torrent.stats.seed_count }}{% else %}Coming soon{% endif %}</span></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-1">Information:</div>
|
||||||
|
<div class="col-md-5">
|
||||||
|
{% if torrent.information %}
|
||||||
|
{{ torrent.information_as_link | safe }}
|
||||||
|
{% else %}
|
||||||
|
No information.
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-1">Leechers:</div>
|
||||||
|
<div class="col-md-5"><span style="color: red;">{% if config.ENABLE_SHOW_STATS %}
|
||||||
|
{{ torrent.stats.leech_count }}{% else %}Coming soon{% endif %}</span></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-1">File size:</div>
|
||||||
|
<div class="col-md-5">{{ torrent.filesize | filesizeformat(True) }}</div>
|
||||||
|
|
||||||
|
<div class="col-md-1">Downloads:</div>
|
||||||
|
<div class="col-md-5">
|
||||||
|
{% if config.ENABLE_SHOW_STATS %}{{ torrent.stats.download_count }}{% else %}Coming
|
||||||
|
soon{% endif %}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel-footer">
|
||||||
|
{% if torrent.has_torrent %}
|
||||||
|
<a href="/view/{{ torrent.id }}/torrent"><i class="fa fa-download fa-fw"></i>Download Torrent</a>
|
||||||
|
or {% endif %}<a href="{{ torrent.magnet_uri }}" class="card-footer-item"><i
|
||||||
|
class="fa fa-magnet fa-fw"></i>Magnet</a>
|
||||||
|
<button type="button" class="btn btn-danger pull-right" data-toggle="modal" data-target="#reportModal">
|
||||||
|
Report
|
||||||
|
</button>
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel-collapse collapse" id="collapseFileList">
|
<div class="panel panel-default">
|
||||||
<table class="table table-bordered table-hover table-striped">
|
<div class="panel-body" id="torrent-description">
|
||||||
<thead>
|
{% if torrent.description %}
|
||||||
<th style="width:auto;">Path</th>
|
{# Escape newlines into html entities because CF strips blank newlines #}
|
||||||
<th style="width:auto;">Size</th>
|
{{ torrent.description | escape | replace('\r\n', '\n') | replace('\n', ' '|safe) }}
|
||||||
</thead>
|
{% else %}
|
||||||
<tbody>
|
#### No description.
|
||||||
{%- for key, value in files.items() recursive %}
|
{% endif %}
|
||||||
<tr>
|
</div>
|
||||||
{%- if value is iterable %}
|
|
||||||
<td colspan="2" {% if loop.depth0 is greaterthan 0 %}style="padding-left: {{ loop.depth0 * 20 }}px"{% endif %}>
|
|
||||||
<i class="glyphicon glyphicon-folder-open"></i> <b>{{ key }}</b></td>
|
|
||||||
{{ loop(value.items()) }}
|
|
||||||
{%- else %}
|
|
||||||
<td{% if loop.depth0 is greaterthan 0 %} style="padding-left: {{ loop.depth0 * 20 }}px"{% endif %}>
|
|
||||||
<i class="glyphicon glyphicon-file"></i> {{ key }}</td>
|
|
||||||
<td class="col-md-2">{{ value | filesizeformat(True) }}</td>
|
|
||||||
{%- endif %}
|
|
||||||
</tr>
|
|
||||||
{%- endfor %}
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
{% elif files %}
|
{% if files and files.__len__() <= config.MAX_FILES_VIEW %}
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading panel-heading-collapse">
|
<div class="panel-heading panel-heading-collapse">
|
||||||
<h3 class="panel-title">
|
<h3 class="panel-title">
|
||||||
<div class="row"><div class="col-md-12">Too many files to display.</div></div>
|
<div class="row">
|
||||||
</h3>
|
<a class="collapsed col-md-12" data-target="#collapseFileList" data-toggle="collapse"
|
||||||
|
style="color:inherit;text-decoration:none;">File list</a>
|
||||||
|
</div>
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="panel-collapse collapse" id="collapseFileList">
|
||||||
|
<table class="table table-bordered table-hover table-striped">
|
||||||
|
<thead>
|
||||||
|
<th style="width:auto;">Path</th>
|
||||||
|
<th style="width:auto;">Size</th>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{%- for key, value in files.items() recursive %}
|
||||||
|
<tr>
|
||||||
|
{%- if value is iterable %}
|
||||||
|
<td colspan="2"
|
||||||
|
{% if loop.depth0 is greaterthan 0 %}style="padding-left: {{ loop.depth0 * 20 }}px"{% endif %}>
|
||||||
|
<i class="glyphicon glyphicon-folder-open"></i> <b>{{ key }}</b></td>
|
||||||
|
{{ loop(value.items()) }}
|
||||||
|
{%- else %}
|
||||||
|
<td{% if loop.depth0 is greaterthan 0 %}
|
||||||
|
style="padding-left: {{ loop.depth0 * 20 }}px"{% endif %}>
|
||||||
|
<i class="glyphicon glyphicon-file"></i> {{ key }}</td>
|
||||||
|
<td class="col-md-2">{{ value | filesizeformat(True) }}</td>
|
||||||
|
{%- endif %}
|
||||||
|
</tr>
|
||||||
|
{%- endfor %}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% elif files %}
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading panel-heading-collapse">
|
||||||
|
<h3 class="panel-title">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">Too many files to display.</div>
|
||||||
|
</div>
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading panel-heading-collapse">
|
||||||
|
<h3 class="panel-title">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">File list is not available for this torrent.</div>
|
||||||
|
</div>
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div class="modal fade" id="reportModal" tabindex="-1" role="dialog" aria-labelledby="reportModalLabel">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
|
||||||
|
aria-hidden="true">×</span></button>
|
||||||
|
<h4 class="modal-title">Report torrent #{{ torrent.id }}</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form method="POST" action="{{ request.url }}/submit_report">
|
||||||
|
{{ report_form.csrf_token }}
|
||||||
|
{{ render_field(report_form.reason, class_='form-control', maxlength=255) }}
|
||||||
|
<div style="float: right;">
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||||
|
<button type="submit" class="btn btn-danger">Report</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer" style="border-top: none;">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading panel-heading-collapse">
|
|
||||||
<h3 class="panel-title">
|
|
||||||
<div class="row"><div class="col-md-12">File list is not available for this torrent.</div></div>
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div class="modal fade" id="reportModal" tabindex="-1" role="dialog" aria-labelledby="reportModalLabel">
|
<script>
|
||||||
<div class="modal-dialog" role="document">
|
var target = document.getElementById('torrent-description');
|
||||||
<div class="modal-content">
|
var text = target.innerHTML;
|
||||||
<div class="modal-header">
|
var reader = new commonmark.Parser({safe: true});
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
|
var writer = new commonmark.HtmlRenderer({safe: true, softbreak: '<br />'});
|
||||||
aria-hidden="true">×</span></button>
|
var parsed = reader.parse(text.trim());
|
||||||
<h4 class="modal-title">Report torrent #{{ torrent.id }}</h4>
|
target.innerHTML = writer.render(parsed);
|
||||||
</div>
|
</script>
|
||||||
<div class="modal-body">
|
|
||||||
<form method="POST" action="{{ request.url }}/submit_report">
|
|
||||||
{{ form.csrf_token }}
|
|
||||||
{{ render_field(form.reason, class_='form-control', maxlength=255) }}
|
|
||||||
<div style="float: right;">
|
|
||||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
|
||||||
<button type="submit" class="btn btn-danger">Report</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer" style="border-top: none;">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
var target = document.getElementById('torrent-description');
|
|
||||||
var text = target.innerHTML;
|
|
||||||
var reader = new commonmark.Parser({safe: true});
|
|
||||||
var writer = new commonmark.HtmlRenderer({safe: true, softbreak: '<br />'});
|
|
||||||
var parsed = reader.parse(text.trim());
|
|
||||||
target.innerHTML = writer.render(parsed);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
Loading…
Reference in a new issue