mirror of
				https://github.com/sb745/NyaaV3.git
				synced 2025-11-04 01:45:46 +02:00 
			
		
		
		
	[DB Changes!] Merge branch 'nyaazi-reports' (#146)
Adds reporting functionality. Alembic migration included.
This commit is contained in:
		
						commit
						7b2bfc57ee
					
				
					 14 changed files with 286 additions and 7 deletions
				
			
		
							
								
								
									
										0
									
								
								WSGI.py
									
										
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										0
									
								
								WSGI.py
									
										
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
								
								
									
										0
									
								
								migrations/README
									
										
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										0
									
								
								migrations/README
									
										
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
								
								
									
										0
									
								
								migrations/env.py
									
										
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										0
									
								
								migrations/env.py
									
										
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
								
								
									
										0
									
								
								migrations/script.py.mako
									
										
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										0
									
								
								migrations/script.py.mako
									
										
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
								
								
									
										56
									
								
								migrations/versions/7f064e009cab_add_report_table.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								migrations/versions/7f064e009cab_add_report_table.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,56 @@
 | 
				
			||||||
 | 
					"""Add Report table
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Revision ID: 7f064e009cab
 | 
				
			||||||
 | 
					Revises: 2bceb2cb4d7c
 | 
				
			||||||
 | 
					Create Date: 2017-05-29 16:50:28.720980
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					from alembic import op
 | 
				
			||||||
 | 
					import sqlalchemy as sa
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# revision identifiers, used by Alembic.
 | 
				
			||||||
 | 
					revision = '7f064e009cab'
 | 
				
			||||||
 | 
					down_revision = '2bceb2cb4d7c'
 | 
				
			||||||
 | 
					branch_labels = None
 | 
				
			||||||
 | 
					depends_on = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def upgrade():
 | 
				
			||||||
 | 
					    # ### commands auto generated by Alembic - please adjust! ###
 | 
				
			||||||
 | 
					    op.create_table('nyaa_reports',
 | 
				
			||||||
 | 
					        sa.Column('id', sa.Integer(), nullable=False),
 | 
				
			||||||
 | 
					        sa.Column('created_time', sa.DateTime(), nullable=True),
 | 
				
			||||||
 | 
					        sa.Column('reason', sa.String(length=255), nullable=False),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # sqlalchemy_utils.types.choice.ChoiceType()
 | 
				
			||||||
 | 
					        sa.Column('status', sa.Integer(), nullable=False),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        sa.Column('torrent_id', sa.Integer(), nullable=False),
 | 
				
			||||||
 | 
					        sa.Column('user_id', sa.Integer(), nullable=True),
 | 
				
			||||||
 | 
					        sa.ForeignKeyConstraint(['torrent_id'], ['nyaa_torrents.id'], ondelete='CASCADE'),
 | 
				
			||||||
 | 
					        sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
 | 
				
			||||||
 | 
					        sa.PrimaryKeyConstraint('id')
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    op.create_table('sukebei_reports',
 | 
				
			||||||
 | 
					        sa.Column('id', sa.Integer(), nullable=False),
 | 
				
			||||||
 | 
					        sa.Column('created_time', sa.DateTime(), nullable=True),
 | 
				
			||||||
 | 
					        sa.Column('reason', sa.String(length=255), nullable=False),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # sqlalchemy_utils.types.choice.ChoiceType()
 | 
				
			||||||
 | 
					        sa.Column('status', sa.Integer(), nullable=False),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        sa.Column('torrent_id', sa.Integer(), nullable=False),
 | 
				
			||||||
 | 
					        sa.Column('user_id', sa.Integer(), nullable=True),
 | 
				
			||||||
 | 
					        sa.ForeignKeyConstraint(['torrent_id'], ['sukebei_torrents.id'], ondelete='CASCADE'),
 | 
				
			||||||
 | 
					        sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
 | 
				
			||||||
 | 
					        sa.PrimaryKeyConstraint('id')
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    # ### end Alembic commands ###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def downgrade():
 | 
				
			||||||
 | 
					    # ### commands auto generated by Alembic - please adjust! ###
 | 
				
			||||||
 | 
					    op.drop_table('sukebei_reports')
 | 
				
			||||||
 | 
					    op.drop_table('nyaa_reports')
 | 
				
			||||||
 | 
					    # ### end Alembic commands ###
 | 
				
			||||||
| 
						 | 
					@ -7,7 +7,8 @@ import os
 | 
				
			||||||
import re
 | 
					import re
 | 
				
			||||||
from flask_wtf import FlaskForm
 | 
					from flask_wtf import FlaskForm
 | 
				
			||||||
from flask_wtf.file import FileField, FileRequired
 | 
					from flask_wtf.file import FileField, FileRequired
 | 
				
			||||||
from wtforms import StringField, PasswordField, BooleanField, TextAreaField, SelectField
 | 
					from wtforms import StringField, PasswordField, BooleanField, TextAreaField, SelectField,\
 | 
				
			||||||
 | 
					    HiddenField
 | 
				
			||||||
from wtforms.validators import DataRequired, Optional, Email, Length, EqualTo, ValidationError
 | 
					from wtforms.validators import DataRequired, Optional, Email, Length, EqualTo, ValidationError
 | 
				
			||||||
from wtforms.validators import Regexp
 | 
					from wtforms.validators import Regexp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -295,6 +296,21 @@ class TorrentFileData(object):
 | 
				
			||||||
# https://wiki.theory.org/BitTorrentSpecification#Metainfo_File_Structure
 | 
					# 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.'),
 | 
				
			||||||
 | 
					        DataRequired('You must provide a valid report reason.')
 | 
				
			||||||
 | 
					    ])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ReportActionForm(FlaskForm):
 | 
				
			||||||
 | 
					    action = SelectField(choices=[('close', 'Close'), ('hide', 'Hide'), ('delete', 'Delete')])
 | 
				
			||||||
 | 
					    torrent = HiddenField()
 | 
				
			||||||
 | 
					    report = HiddenField()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _validate_trackers(torrent_dict, tracker_to_check_for=None):
 | 
					def _validate_trackers(torrent_dict, tracker_to_check_for=None):
 | 
				
			||||||
    announce = torrent_dict.get('announce')
 | 
					    announce = torrent_dict.get('announce')
 | 
				
			||||||
    announce_string = _validate_bytes(announce, 'announce', test_decode='utf-8')
 | 
					    announce_string = _validate_bytes(announce, 'announce', test_decode='utf-8')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										70
									
								
								nyaa/models.py
									
										
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										70
									
								
								nyaa/models.py
									
										
									
									
									
										
										
										Executable file → Normal file
									
								
							| 
						 | 
					@ -580,6 +580,65 @@ class User(db.Model):
 | 
				
			||||||
        return self.level >= UserLevelType.TRUSTED
 | 
					        return self.level >= UserLevelType.TRUSTED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ReportStatus(IntEnum):
 | 
				
			||||||
 | 
					    IN_REVIEW = 0
 | 
				
			||||||
 | 
					    VALID = 1
 | 
				
			||||||
 | 
					    INVALID = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ReportBase(DeclarativeHelperBase):
 | 
				
			||||||
 | 
					    __tablename_base__ = 'reports'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    id = db.Column(db.Integer, primary_key=True)
 | 
				
			||||||
 | 
					    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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @declarative.declared_attr
 | 
				
			||||||
 | 
					    def torrent_id(cls):
 | 
				
			||||||
 | 
					        return db.Column(db.Integer, db.ForeignKey(
 | 
				
			||||||
 | 
					            cls._table_prefix('torrents.id'), ondelete='CASCADE'), nullable=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @declarative.declared_attr
 | 
				
			||||||
 | 
					    def user_id(cls):
 | 
				
			||||||
 | 
					        return db.Column(db.Integer, db.ForeignKey('users.id'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @declarative.declared_attr
 | 
				
			||||||
 | 
					    def user(cls):
 | 
				
			||||||
 | 
					        return db.relationship('User', uselist=False, lazy="joined")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @declarative.declared_attr
 | 
				
			||||||
 | 
					    def torrent(cls):
 | 
				
			||||||
 | 
					        return db.relationship(cls._flavor_prefix('Torrent'), uselist=False, lazy="joined")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, torrent_id, user_id, reason):
 | 
				
			||||||
 | 
					        self.torrent_id = torrent_id
 | 
				
			||||||
 | 
					        self.user_id = user_id
 | 
				
			||||||
 | 
					        self.reason = reason
 | 
				
			||||||
 | 
					        self.status = ReportStatus.IN_REVIEW
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __repr__(self):
 | 
				
			||||||
 | 
					        return '<Report %r>' % self.id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def created_utc_timestamp(self):
 | 
				
			||||||
 | 
					        ''' Returns a UTC POSIX timestamp, as seconds '''
 | 
				
			||||||
 | 
					        return (self.created_time - UTC_EPOCH).total_seconds()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def by_id(cls, id):
 | 
				
			||||||
 | 
					        return cls.query.get(id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def not_reviewed(cls, page):
 | 
				
			||||||
 | 
					        reports = cls.query.filter_by(status=0).paginate(page=page, per_page=20)
 | 
				
			||||||
 | 
					        return reports
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def remove_reviewed(cls, id):
 | 
				
			||||||
 | 
					        return cls.query.filter(cls.torrent_id == id, cls.status == 0).delete()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Actually declare our site-specific classes
 | 
					# Actually declare our site-specific classes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Torrent
 | 
					# Torrent
 | 
				
			||||||
| 
						 | 
					@ -672,6 +731,15 @@ class SukebeiComment(CommentBase, db.Model):
 | 
				
			||||||
    __flavor__ = 'Sukebei'
 | 
					    __flavor__ = 'Sukebei'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Report
 | 
				
			||||||
 | 
					class NyaaReport(ReportBase, db.Model):
 | 
				
			||||||
 | 
					    __flavor__ = 'Nyaa'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SukebeiReport(ReportBase, db.Model):
 | 
				
			||||||
 | 
					    __flavor__ = 'Sukebei'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Choose our defaults for models.Torrent etc
 | 
					# Choose our defaults for models.Torrent etc
 | 
				
			||||||
if app.config['SITE_FLAVOR'] == 'nyaa':
 | 
					if app.config['SITE_FLAVOR'] == 'nyaa':
 | 
				
			||||||
    Torrent = NyaaTorrent
 | 
					    Torrent = NyaaTorrent
 | 
				
			||||||
| 
						 | 
					@ -682,6 +750,7 @@ if app.config['SITE_FLAVOR'] == 'nyaa':
 | 
				
			||||||
    MainCategory = NyaaMainCategory
 | 
					    MainCategory = NyaaMainCategory
 | 
				
			||||||
    SubCategory = NyaaSubCategory
 | 
					    SubCategory = NyaaSubCategory
 | 
				
			||||||
    Comment = NyaaComment
 | 
					    Comment = NyaaComment
 | 
				
			||||||
 | 
					    Report = NyaaReport
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    TorrentNameSearch = NyaaTorrentNameSearch
 | 
					    TorrentNameSearch = NyaaTorrentNameSearch
 | 
				
			||||||
elif app.config['SITE_FLAVOR'] == 'sukebei':
 | 
					elif app.config['SITE_FLAVOR'] == 'sukebei':
 | 
				
			||||||
| 
						 | 
					@ -693,5 +762,6 @@ elif app.config['SITE_FLAVOR'] == 'sukebei':
 | 
				
			||||||
    MainCategory = SukebeiMainCategory
 | 
					    MainCategory = SukebeiMainCategory
 | 
				
			||||||
    SubCategory = SukebeiSubCategory
 | 
					    SubCategory = SukebeiSubCategory
 | 
				
			||||||
    Comment = SukebeiComment
 | 
					    Comment = SukebeiComment
 | 
				
			||||||
 | 
					    Report = SukebeiReport
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    TorrentNameSearch = SukebeiTorrentNameSearch
 | 
					    TorrentNameSearch = SukebeiTorrentNameSearch
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,7 +29,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
 | 
				
			||||||
| 
						 | 
					@ -675,11 +674,13 @@ def view_torrent(torrent_id):
 | 
				
			||||||
    if torrent.filelist:
 | 
					    if torrent.filelist:
 | 
				
			||||||
        files = json.loads(torrent.filelist.filelist_blob.decode('utf-8'))
 | 
					        files = json.loads(torrent.filelist.filelist_blob.decode('utf-8'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    report_form = forms.ReportForm()
 | 
				
			||||||
    return flask.render_template('view.html', torrent=torrent,
 | 
					    return flask.render_template('view.html', torrent=torrent,
 | 
				
			||||||
                                 files=files,
 | 
					                                 files=files,
 | 
				
			||||||
                                 comment_form=comment_form,
 | 
					                                 comment_form=comment_form,
 | 
				
			||||||
                                 comments=torrent.comments,
 | 
					                                 comments=torrent.comments,
 | 
				
			||||||
                                 can_edit=can_edit)
 | 
					                                 can_edit=can_edit,
 | 
				
			||||||
 | 
					                                 report_form=report_form)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@app.route('/view/<int:torrent_id>/comment/<int:comment_id>/delete', methods=['POST'])
 | 
					@app.route('/view/<int:torrent_id>/comment/<int:comment_id>/delete', methods=['POST'])
 | 
				
			||||||
| 
						 | 
					@ -798,6 +799,66 @@ def download_torrent(torrent_id):
 | 
				
			||||||
    return resp
 | 
					    return resp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@app.route('/view/<int:torrent_id>/submit_report', methods=['POST'])
 | 
				
			||||||
 | 
					def submit_report(torrent_id):
 | 
				
			||||||
 | 
					    if not flask.g.user:
 | 
				
			||||||
 | 
					        flask.abort(403)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    form = forms.ReportForm(flask.request.form)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if flask.request.method == 'POST' and form.validate():
 | 
				
			||||||
 | 
					        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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        db.session.add(report)
 | 
				
			||||||
 | 
					        db.session.commit()
 | 
				
			||||||
 | 
					        flask.flash('Successfully reported torrent!', 'success')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return flask.redirect(flask.url_for('view_torrent', torrent_id=torrent_id))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@app.route('/reports', methods=['GET', 'POST'])
 | 
				
			||||||
 | 
					def view_reports():
 | 
				
			||||||
 | 
					    if not flask.g.user or not flask.g.user.is_moderator:
 | 
				
			||||||
 | 
					        flask.abort(403)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    page = flask.request.args.get('p', flask.request.args.get('offset', 1, int), int)
 | 
				
			||||||
 | 
					    reports = models.Report.not_reviewed(page)
 | 
				
			||||||
 | 
					    report_action = forms.ReportActionForm(flask.request.form)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if flask.request.method == 'POST' and report_action.validate():
 | 
				
			||||||
 | 
					        action = report_action.action.data
 | 
				
			||||||
 | 
					        torrent_id = report_action.torrent.data
 | 
				
			||||||
 | 
					        report_id = report_action.report.data
 | 
				
			||||||
 | 
					        torrent = models.Torrent.by_id(torrent_id)
 | 
				
			||||||
 | 
					        report = models.Report.by_id(report_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if not torrent or not report or report.status != 0:
 | 
				
			||||||
 | 
					            flask.abort(404)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            if action == 'delete':
 | 
				
			||||||
 | 
					                torrent.deleted = True
 | 
				
			||||||
 | 
					                report.status = 1
 | 
				
			||||||
 | 
					            elif action == 'hide':
 | 
				
			||||||
 | 
					                torrent.hidden = True
 | 
				
			||||||
 | 
					                report.status = 1
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                report.status = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            models.Report.remove_reviewed(torrent_id)
 | 
				
			||||||
 | 
					            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',
 | 
				
			||||||
 | 
					                                 reports=reports,
 | 
				
			||||||
 | 
					                                 report_action=report_action)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _get_cached_torrent_file(torrent):
 | 
					def _get_cached_torrent_file(torrent):
 | 
				
			||||||
    # Note: obviously temporary
 | 
					    # Note: obviously temporary
 | 
				
			||||||
    cached_torrent = os.path.join(app.config['BASE_DIR'],
 | 
					    cached_torrent = os.path.join(app.config['BASE_DIR'],
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										0
									
								
								nyaa/static/css/main.css
									
										
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										0
									
								
								nyaa/static/css/main.css
									
										
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
								
								
									
										0
									
								
								nyaa/templates/edit.html
									
										
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										0
									
								
								nyaa/templates/edit.html
									
										
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
								
								
									
										5
									
								
								nyaa/templates/layout.html
									
										
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										5
									
								
								nyaa/templates/layout.html
									
										
									
									
									
										
										
										Executable file → Normal file
									
								
							| 
						 | 
					@ -88,6 +88,9 @@
 | 
				
			||||||
						{% elif config.SITE_FLAVOR == 'sukebei' %}
 | 
											{% elif config.SITE_FLAVOR == 'sukebei' %}
 | 
				
			||||||
						<li><a href="https://nyaa.si/">Fun</a></li>
 | 
											<li><a href="https://nyaa.si/">Fun</a></li>
 | 
				
			||||||
						{% endif %}
 | 
											{% endif %}
 | 
				
			||||||
 | 
											{% if g.user.is_moderator %}
 | 
				
			||||||
 | 
												<li><a href="{{ url_for('view_reports') }}">Reports</a> </li>
 | 
				
			||||||
 | 
											{% endif %}
 | 
				
			||||||
					</ul>
 | 
										</ul>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					<ul class="nav navbar-nav navbar-right">
 | 
										<ul class="nav navbar-nav navbar-right">
 | 
				
			||||||
| 
						 | 
					@ -304,5 +307,3 @@
 | 
				
			||||||
		</footer>
 | 
							</footer>
 | 
				
			||||||
	</body>
 | 
						</body>
 | 
				
			||||||
</html>
 | 
					</html>
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										48
									
								
								nyaa/templates/reports.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								nyaa/templates/reports.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,48 @@
 | 
				
			||||||
 | 
					{% extends "layout.html" %}
 | 
				
			||||||
 | 
					{% block title %}Reports :: {{ config.SITE_NAME }}{% endblock %}
 | 
				
			||||||
 | 
					{% block body %}
 | 
				
			||||||
 | 
					{% from "_formhelpers.html" import render_field %}
 | 
				
			||||||
 | 
						<div class="table-responsive">
 | 
				
			||||||
 | 
							<table class="table table-bordered table-hover table-striped">
 | 
				
			||||||
 | 
								<thead>
 | 
				
			||||||
 | 
								<tr>
 | 
				
			||||||
 | 
									<th>#</th>
 | 
				
			||||||
 | 
									<th>Reported by</th>
 | 
				
			||||||
 | 
									<th>Torrent</th>
 | 
				
			||||||
 | 
									<th>Reason</th>
 | 
				
			||||||
 | 
									<th>Date</th>
 | 
				
			||||||
 | 
									<th>Action</th>
 | 
				
			||||||
 | 
								</tr>
 | 
				
			||||||
 | 
								</thead>
 | 
				
			||||||
 | 
								<tbody>
 | 
				
			||||||
 | 
								{% for report in reports.items %}
 | 
				
			||||||
 | 
								<tr>
 | 
				
			||||||
 | 
									<td>{{ report.id }}</td>
 | 
				
			||||||
 | 
									<td>
 | 
				
			||||||
 | 
										<a href="{{ url_for('view_user', user_name=report.user.username) }}">{{ report.user.username }}</a>
 | 
				
			||||||
 | 
									</td>
 | 
				
			||||||
 | 
									<td>
 | 
				
			||||||
 | 
										<a href="{{ url_for('view_torrent', torrent_id=report.torrent.id) }}">{{ report.torrent.display_name }}</a>
 | 
				
			||||||
 | 
									</td>
 | 
				
			||||||
 | 
									<td>{{ report.reason }}</td>
 | 
				
			||||||
 | 
									<td>{{ report.created_time }}</td>
 | 
				
			||||||
 | 
									<td style="width: 15%">
 | 
				
			||||||
 | 
										<form method="post">
 | 
				
			||||||
 | 
											{{ report_action.csrf_token }}
 | 
				
			||||||
 | 
											{{ report_action.action }}
 | 
				
			||||||
 | 
											{{ report_action.torrent(value=report.torrent.id) }}
 | 
				
			||||||
 | 
											{{ report_action.report(value=report.id) }}
 | 
				
			||||||
 | 
											<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 %}
 | 
				
			||||||
							
								
								
									
										0
									
								
								nyaa/templates/upload.html
									
										
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										0
									
								
								nyaa/templates/upload.html
									
										
									
									
									
										
										
										Executable file → Normal file
									
								
							| 
						 | 
					@ -71,8 +71,12 @@
 | 
				
			||||||
			<div class="col-md-5"><kbd>{{ torrent.info_hash_as_hex }}</kbd></div>
 | 
								<div class="col-md-5"><kbd>{{ torrent.info_hash_as_hex }}</kbd></div>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
	<div class="panel-footer">
 | 
					
 | 
				
			||||||
 | 
						<div class="panel-footer clearfix">
 | 
				
			||||||
		{% if torrent.has_torrent %}<a href="{{ url_for('download_torrent', torrent_id=torrent.id )}}"><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>
 | 
							{% if torrent.has_torrent %}<a href="{{ url_for('download_torrent', torrent_id=torrent.id )}}"><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>
 | 
						</div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -180,6 +184,29 @@
 | 
				
			||||||
	{% endif %}
 | 
						{% endif %}
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						<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>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
	var target = document.getElementById('torrent-description');
 | 
						var target = document.getElementById('torrent-description');
 | 
				
			||||||
	var text = target.innerHTML;
 | 
						var text = target.innerHTML;
 | 
				
			||||||
| 
						 | 
					@ -189,4 +216,4 @@
 | 
				
			||||||
	target.innerHTML = writer.render(parsed);
 | 
						target.innerHTML = writer.render(parsed);
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% endblock %}
 | 
					{% endblock %}
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue