diff --git a/nyaa/forms.py b/nyaa/forms.py index 09bef8d..8e83fd8 100644 --- a/nyaa/forms.py +++ b/nyaa/forms.py @@ -278,6 +278,14 @@ class TorrentFileData(object): # https://wiki.theory.org/BitTorrentSpecification#Metainfo_File_Structure +class ReportForm(FlaskForm): + reason = TextAreaField('Report reason', [ + Length(min=3, max=255, + message='Report reason must be at least %(min)d characters long ' + 'and %(max)d at most.') + ]) + + def _validate_trackers(torrent_dict, tracker_to_check_for=None): announce = torrent_dict.get('announce') announce_string = _validate_bytes(announce, 'announce', 'utf-8') diff --git a/nyaa/models.py b/nyaa/models.py index 189c635..239da4a 100644 --- a/nyaa/models.py +++ b/nyaa/models.py @@ -380,6 +380,39 @@ class User(db.Model): return self.level is UserLevelType.TRUSTED +class ReportStatus(IntEnum): + IN_REVIEW = 0 + VALID = 1 + INVALID = 2 + + +class Report(db.Model): + __tablename__ = DB_TABLE_PREFIX + 'reports' + + id = db.Column(db.Integer, primary_key=True) + torrent = db.Column(db.Integer, db.ForeignKey( + DB_TABLE_PREFIX + 'torrents.id')) + user_id = db.Column(db.Integer, db.ForeignKey( + 'users.id')) + created_time = db.Column(db.DateTime(timezone=False), default=datetime.utcnow) + reason = db.Column(db.String(length=255), nullable=False) + status = db.Column(ChoiceType(ReportStatus, impl=db.Integer()), nullable=False) + + def __init__(self, torrent, user_id, reason): + self.torrent = torrent + self.user_id = user_id + self.reason = reason + self.status = ReportStatus.IN_REVIEW + + def __repr__(self): + return '' % self.id + + @property + def created_utc_timestamp(self): + ''' Returns a UTC POSIX timestamp, as seconds ''' + return (self.created_time - UTC_EPOCH).total_seconds() + + # class Session(db.Model): # __tablename__ = 'sessions' # diff --git a/nyaa/routes.py b/nyaa/routes.py index fe4ccff..e1a2c14 100644 --- a/nyaa/routes.py +++ b/nyaa/routes.py @@ -578,9 +578,11 @@ def view_torrent(torrent_id): if torrent.filelist: files = json.loads(torrent.filelist.filelist_blob.decode('utf-8')) + report_form = forms.ReportForm() return flask.render_template('view.html', torrent=torrent, files=files, - can_edit=can_edit) + can_edit=can_edit, + form=report_form) @app.route('/view//edit', methods=['GET', 'POST']) @@ -663,6 +665,29 @@ def download_torrent(torrent_id): return resp +@app.route('/view//submit_report', methods=['POST']) +def submit_report(torrent_id): + form = forms.ReportForm(flask.request.form) + + if flask.request.method == 'POST' and form.validate(): + report_reason = (form.reason.data or '').strip() + + if flask.g.user is not None: + current_user_id = flask.g.user.id + report = models.Report( + torrent=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)) + + def _get_cached_torrent_file(torrent): # Note: obviously temporary cached_torrent = os.path.join(app.config['BASE_DIR'], diff --git a/nyaa/templates/view.html b/nyaa/templates/view.html index 6c835b8..cf4b93a 100644 --- a/nyaa/templates/view.html +++ b/nyaa/templates/view.html @@ -1,6 +1,7 @@ {% extends "layout.html" %} {% block title %}{{ torrent.display_name }} :: {{ config.SITE_NAME }}{% endblock %} {% block body %} +{% from "_formhelpers.html" import render_field %}

@@ -54,6 +55,8 @@

@@ -119,6 +122,31 @@ {% endif %} + +