def delete_comment(torrent_id, comment_id): if not flask.g.user: flask.abort(403) torrent = models.Torrent.by_id(torrent_id) if not torrent: flask.abort(404) comment = models.Comment.query.filter_by(id=comment_id).first() if not comment: flask.abort(404) if not (comment.user.id == flask.g.user.id or flask.g.user.is_superadmin): flask.abort(403) if torrent_id != comment.torrent_id: flask.abort(400) if torrent.comment_locked and not flask.g.user.is_moderator: flask.abort(403) db.session.delete(comment) db.session.flush() torrent.update_comment_count() url = flask.url_for('torrents.view', torrent_id=torrent.id) if flask.g.user.is_moderator: log = "Comment deleted on torrent [#{}]({})".format(torrent.id, url) adminlog = models.AdminLog(log=log, admin_id=flask.g.user.id) db.session.add(adminlog) db.session.commit() flask.flash('Comment successfully deleted.', 'success') return flask.redirect(url)
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) report_user = models.User.by_id(report.user_id) if not torrent or not report or report.status != 0: flask.abort(404) else: log = "Report #{}: {} [#{}]({}), reported by [{}]({})" if action == 'delete': torrent.deleted = True report.status = 1 log = log.format( report_id, 'Deleted', torrent_id, flask.url_for('torrents.view', torrent_id=torrent_id), report_user.username, flask.url_for('users.view_user', user_name=report_user.username)) elif action == 'hide': log = log.format( report_id, 'Hid', torrent_id, flask.url_for('torrents.view', torrent_id=torrent_id), report_user.username, flask.url_for('users.view_user', user_name=report_user.username)) torrent.hidden = True report.status = 1 else: log = log.format( report_id, 'Closed', torrent_id, flask.url_for('torrents.view', torrent_id=torrent_id), report_user.username, flask.url_for('users.view_user', user_name=report_user.username)) report.status = 2 adminlog = models.AdminLog(log=log, admin_id=flask.g.user.id) db.session.add(adminlog) models.Report.remove_reviewed(torrent_id) db.session.commit() flask.flash('Closed report #{}'.format(report.id), 'success') return flask.redirect(flask.url_for('admin.reports')) return flask.render_template('reports.html', reports=reports, report_action=report_action)
def view_adminbans(): if not flask.g.user or not flask.g.user.is_moderator: flask.abort(403) form = forms.StringSubmitForm() if flask.request.method == 'POST' and form.validate(): ban = models.Ban.by_id(form.submit.data) if not ban: flask.abort(404) log = 'Unbanned ban #{0}'.format(ban.id) if ban.user: log += ' ' + ban.user.username ban.user.status = models.UserStatusType.ACTIVE db.session.add(ban.user) if ban.user_ip: log += ' IP({0})'.format(ip_address(ban.user_ip)) adminlog = models.AdminLog(log=log, admin_id=flask.g.user.id) db.session.add(adminlog) db.session.delete(ban) db.session.commit() flask.flash('Unbanned ban #{0}'.format(ban.id), 'success') page = flask.request.args.get('p', flask.request.args.get('offset', 1, int), int) bans = models.Ban.all_bans() \ .order_by(models.Ban.created_time.desc()) \ .paginate(page=page, per_page=20) return flask.render_template('admin_bans.html', bans=bans, form=form)
def edit_torrent(torrent_id): torrent = models.Torrent.by_id(torrent_id) form = forms.EditForm(flask.request.form) form.category.choices = _create_upload_category_choices() delete_form = forms.DeleteForm() ban_form = None editor = flask.g.user if not torrent: flask.abort(404) # Only allow admins edit deleted torrents if torrent.deleted and not (editor and editor.is_moderator): flask.abort(404) # Only allow torrent owners or admins edit torrents if not editor or not (editor is torrent.user or editor.is_moderator): flask.abort(403) torrent_user_level = torrent.user and torrent.user.level if editor and editor.is_moderator and \ (torrent_user_level is None or editor.level > torrent_user_level): ban_form = forms.BanForm() if flask.request.method == 'POST' and form.submit.data and form.validate(): # Form has been sent, edit torrent with data. torrent.main_category_id, torrent.sub_category_id = \ form.category.parsed_data.get_category_ids() torrent.display_name = (form.display_name.data or '').strip() torrent.information = (form.information.data or '').strip() torrent.description = (form.description.data or '').strip() torrent.hidden = form.is_hidden.data torrent.remake = form.is_remake.data torrent.complete = form.is_complete.data torrent.anonymous = form.is_anonymous.data if editor.is_trusted: torrent.trusted = form.is_trusted.data if editor.is_moderator: locked_changed = torrent.comment_locked != form.is_comment_locked.data torrent.comment_locked = form.is_comment_locked.data url = flask.url_for('torrents.view', torrent_id=torrent.id) if editor.is_moderator and locked_changed: log = "Torrent [#{0}]({1}) marked as {2}".format( torrent.id, url, "comments locked" if torrent.comment_locked else "comments unlocked") adminlog = models.AdminLog(log=log, admin_id=editor.id) db.session.add(adminlog) db.session.commit() flask.flash( flask.Markup( 'Torrent has been successfully edited! Changes might take a few minutes to show up.' ), 'success') url = flask.url_for('torrents.view', torrent_id=torrent.id) return flask.redirect(url) elif flask.request.method == 'POST' and delete_form.validate() and \ (not ban_form or ban_form.validate()): return _delete_torrent(torrent, delete_form, ban_form) else: if flask.request.method != 'POST': # Fill form data only if the POST didn't fail form.category.data = torrent.sub_category.id_as_string form.display_name.data = torrent.display_name form.information.data = torrent.information form.description.data = torrent.description form.is_hidden.data = torrent.hidden form.is_remake.data = torrent.remake form.is_complete.data = torrent.complete form.is_anonymous.data = torrent.anonymous form.is_trusted.data = torrent.trusted form.is_comment_locked.data = torrent.comment_locked ipbanned = None if editor.is_moderator: torrent_ip_banned = True user_ip_banned = True # Archived torrents do not have a null uploader_ip if torrent.uploader_ip: torrent_ip_banned = models.Ban.banned( None, torrent.uploader_ip).first() if torrent.user: user_ip_banned = models.Ban.banned( None, torrent.user.last_login_ip).first() ipbanned = (torrent_ip_banned and user_ip_banned) return flask.render_template('edit.html', form=form, delete_form=delete_form, ban_form=ban_form, torrent=torrent, ipbanned=ipbanned)
def _delete_torrent(torrent, form, banform): editor = flask.g.user uploader = torrent.user # Only allow admins edit deleted torrents if torrent.deleted and not (editor and editor.is_moderator): flask.abort(404) action = None url = flask.url_for('main.home') ban_torrent = form.ban.data if banform: ban_torrent = ban_torrent or banform.ban_user.data or banform.ban_userip.data if form.delete.data and not torrent.deleted: action = 'deleted' torrent.deleted = True db.session.add(torrent) elif ban_torrent and not torrent.banned and editor.is_moderator: action = 'banned' torrent.banned = True if not torrent.deleted: torrent.deleted = True action = 'deleted and banned' db.session.add(models.TrackerApi(torrent.info_hash, 'remove')) torrent.stats.seed_count = 0 torrent.stats.leech_count = 0 db.session.add(torrent) elif form.undelete.data and torrent.deleted: action = 'undeleted' torrent.deleted = False if torrent.banned: action = 'undeleted and unbanned' torrent.banned = False db.session.add(models.TrackerApi(torrent.info_hash, 'insert')) db.session.add(torrent) elif form.unban.data and torrent.banned: action = 'unbanned' torrent.banned = False db.session.add(models.TrackerApi(torrent.info_hash, 'insert')) db.session.add(torrent) if not action and not ban_torrent: flask.flash(flask.Markup('What the f**k are you doing?'), 'danger') return flask.redirect( flask.url_for('torrents.edit', torrent_id=torrent.id)) if action and editor.is_moderator: url = flask.url_for('torrents.view', torrent_id=torrent.id) if editor is not uploader: log = "Torrent [#{0}]({1}) has been {2}".format( torrent.id, url, action) adminlog = models.AdminLog(log=log, admin_id=editor.id) db.session.add(adminlog) if action: db.session.commit() flask.flash( flask.Markup('Torrent has been successfully {0}.'.format(action)), 'success') if not banform or not (banform.ban_user.data or banform.ban_userip.data): return flask.redirect(url) if banform.ban_userip.data: tbanned = models.Ban.banned(None, torrent.uploader_ip).first() ubanned = True if uploader: ubanned = models.Ban.banned(None, uploader.last_login_ip).first() ipbanned = (tbanned and ubanned) if (banform.ban_user.data and (not uploader or uploader.is_banned)) or \ (banform.ban_userip.data and ipbanned): flask.flash(flask.Markup('What the f**k are you doing?'), 'danger') return flask.redirect( flask.url_for('torrents.edit', torrent_id=torrent.id)) flavor = "Nyaa" if app.config['SITE_FLAVOR'] == 'nyaa' else "Sukebei" eurl = flask.url_for('torrents.view', torrent_id=torrent.id, _external=True) reason = "[{0}#{1}]({2}) {3}".format(flavor, torrent.id, eurl, banform.reason.data) ban1 = models.Ban(admin_id=editor.id, reason=reason) ban2 = models.Ban(admin_id=editor.id, reason=reason) db.session.add(ban1) if uploader: uploader.status = models.UserStatusType.BANNED db.session.add(uploader) ban1.user_id = uploader.id ban2.user_id = uploader.id if banform.ban_userip.data: if not ubanned: ban1.user_ip = ip_address(uploader.last_login_ip) if not tbanned: uploader_ip = ip_address(torrent.uploader_ip) if ban1.user_ip != uploader_ip: ban2.user_ip = uploader_ip db.session.add(ban2) else: ban1.user_ip = ip_address(torrent.uploader_ip) uploader_str = "Anonymous" if uploader: uploader_url = flask.url_for('users.view_user', user_name=uploader.username) uploader_str = "[{0}]({1})".format(uploader.username, uploader_url) if ban1.user_ip: uploader_str += " IP({0})".format(ban1.user_ip) ban1.user_ip = ban1.user_ip.packed if ban2.user_ip: uploader_str += " IP({0})".format(ban2.user_ip) ban2.user_ip = ban2.user_ip.packed log = "Uploader {0} of torrent [#{1}]({2}) has been banned.".format( uploader_str, torrent.id, flask.url_for('torrents.view', torrent_id=torrent.id), action) adminlog = models.AdminLog(log=log, admin_id=editor.id) db.session.add(adminlog) db.session.commit() flask.flash(flask.Markup('Uploader has been successfully banned.'), 'success') return flask.redirect(url)
def view_user(user_name): user = models.User.by_username(user_name) if not user: flask.abort(404) admin_form = None ban_form = None bans = None ipbanned = None if flask.g.user and flask.g.user.is_moderator and flask.g.user.level > user.level: admin_form = forms.UserForm() default, admin_form.user_class.choices = _create_user_class_choices( user) if flask.request.method == 'GET': admin_form.user_class.data = default ban_form = forms.BanForm() if flask.request.method == 'POST': doban = (ban_form.ban_user.data or ban_form.unban.data or ban_form.ban_userip.data) bans = models.Ban.banned(user.id, user.last_login_ip).all() ipbanned = list(filter(lambda b: b.user_ip == user.last_login_ip, bans)) url = flask.url_for('users.view_user', user_name=user.username) if flask.request.method == 'POST' and admin_form and not doban and admin_form.validate( ): selection = admin_form.user_class.data log = None if selection == 'regular': user.level = models.UserLevelType.REGULAR log = "[{}]({}) changed to regular user".format(user_name, url) elif selection == 'trusted': user.level = models.UserLevelType.TRUSTED log = "[{}]({}) changed to trusted user".format(user_name, url) elif selection == 'moderator': user.level = models.UserLevelType.MODERATOR log = "[{}]({}) changed to moderator user".format(user_name, url) adminlog = models.AdminLog(log=log, admin_id=flask.g.user.id) db.session.add(user) db.session.add(adminlog) db.session.commit() return flask.redirect(url) if flask.request.method == 'POST' and ban_form and doban and ban_form.validate( ): if (ban_form.ban_user.data and user.is_banned) or \ (ban_form.ban_userip.data and ipbanned) or \ (ban_form.unban.data and not user.is_banned and not bans): flask.flash(flask.Markup('What the f**k are you doing?'), 'danger') return flask.redirect(url) user_str = "[{0}]({1})".format(user.username, url) if ban_form.unban.data: action = "unbanned" user.status = models.UserStatusType.ACTIVE db.session.add(user) for ban in bans: if ban.user_ip: user_str += " IP({0})".format(ip_address(ban.user_ip)) db.session.delete(ban) else: action = "banned" user.status = models.UserStatusType.BANNED db.session.add(user) ban = models.Ban(admin_id=flask.g.user.id, user_id=user.id, reason=ban_form.reason.data) db.session.add(ban) if ban_form.ban_userip.data: ban.user_ip = ip_address(user.last_login_ip) user_str += " IP({0})".format(ban.user_ip) ban.user_ip = ban.user_ip.packed log = "User {0} has been {1}.".format(user_str, action) adminlog = models.AdminLog(log=log, admin_id=flask.g.user.id) db.session.add(adminlog) db.session.commit() flask.flash( flask.Markup('User has been successfully {0}.'.format(action)), 'success') return flask.redirect(url) if flask.request.method == 'POST' and ban_form and ban_form.nuke.data: if flask.g.user.is_superadmin: nyaa_banned = 0 sukebei_banned = 0 info_hashes = [] for t in chain(user.nyaa_torrents, user.sukebei_torrents): t.deleted = True t.banned = True info_hashes.append([t.info_hash]) db.session.add(t) if isinstance(t, models.NyaaTorrent): nyaa_banned += 1 else: sukebei_banned += 1 if info_hashes: backend.tracker_api(info_hashes, 'ban') for log_flavour, num in ((models.NyaaAdminLog, nyaa_banned), (models.SukebeiAdminLog, sukebei_banned)): if num > 0: log = "Nuked {0} torrents of [{1}]({2})".format( num, user.username, url) adminlog = log_flavour(log=log, admin_id=flask.g.user.id) db.session.add(adminlog) db.session.commit() flask.flash( 'Torrents of {0} have been nuked.'.format(user.username), 'success') return flask.redirect(url) else: flask.flash('Insufficient permissions to nuke.', 'danger') return flask.redirect(url) req_args = flask.request.args search_term = chain_get(req_args, 'q', 'term') sort_key = req_args.get('s') sort_order = req_args.get('o') category = chain_get(req_args, 'c', 'cats') quality_filter = chain_get(req_args, 'f', 'filter') page_number = chain_get(req_args, 'p', 'page', 'offset') try: page_number = max(1, int(page_number)) except (ValueError, TypeError): page_number = 1 results_per_page = app.config.get('RESULTS_PER_PAGE', DEFAULT_PER_PAGE) query_args = { 'term': search_term or '', 'user': user.id, 'sort': sort_key or 'id', 'order': sort_order or 'desc', 'category': category or '0_0', 'quality_filter': quality_filter or '0', 'page': page_number, 'rss': False, 'per_page': results_per_page } if flask.g.user: query_args['logged_in_user'] = flask.g.user if flask.g.user.is_moderator: # God mode query_args['admin'] = True # Use elastic search for term searching rss_query_string = _generate_query_string(search_term, category, quality_filter, user_name) use_elastic = app.config.get('USE_ELASTIC_SEARCH') if use_elastic and search_term: query_args['term'] = search_term max_search_results = app.config.get('ES_MAX_SEARCH_RESULT', DEFAULT_MAX_SEARCH_RESULT) # Only allow up to (max_search_results / page) pages max_page = min(query_args['page'], int(math.ceil(max_search_results / results_per_page))) query_args['page'] = max_page query_args['max_search_results'] = max_search_results query_results = search_elastic(**query_args) max_results = min(max_search_results, query_results['hits']['total']) # change p= argument to whatever you change page_parameter to or pagination breaks pagination = Pagination(p=query_args['page'], per_page=results_per_page, total=max_results, bs_version=3, page_parameter='p', display_msg=SERACH_PAGINATE_DISPLAY_MSG) return flask.render_template('user.html', use_elastic=True, pagination=pagination, torrent_query=query_results, search=query_args, user=user, user_page=True, rss_filter=rss_query_string, admin_form=admin_form, ban_form=ban_form, bans=bans, ipbanned=ipbanned) # Similar logic as home page else: if use_elastic: query_args['term'] = '' else: query_args['term'] = search_term or '' query = search_db(**query_args) return flask.render_template('user.html', use_elastic=False, torrent_query=query, search=query_args, user=user, user_page=True, rss_filter=rss_query_string, admin_form=admin_form, ban_form=ban_form, bans=bans, ipbanned=ipbanned)
def edit_torrent(torrent_id): torrent = models.Torrent.by_id(torrent_id) form = forms.EditForm(flask.request.form) form.category.choices = _create_upload_category_choices() editor = flask.g.user if not torrent: flask.abort(404) # Only allow admins edit deleted torrents if torrent.deleted and not (editor and editor.is_moderator): flask.abort(404) # Only allow torrent owners or admins edit torrents if not editor or not (editor is torrent.user or editor.is_moderator): flask.abort(403) if flask.request.method == 'POST' and form.validate(): # Form has been sent, edit torrent with data. torrent.main_category_id, torrent.sub_category_id = \ form.category.parsed_data.get_category_ids() torrent.display_name = (form.display_name.data or '').strip() torrent.information = (form.information.data or '').strip() torrent.description = (form.description.data or '').strip() torrent.hidden = form.is_hidden.data torrent.remake = form.is_remake.data torrent.complete = form.is_complete.data torrent.anonymous = form.is_anonymous.data if editor.is_trusted: torrent.trusted = form.is_trusted.data deleted_changed = torrent.deleted != form.is_deleted.data if editor.is_moderator: torrent.deleted = form.is_deleted.data url = flask.url_for('view_torrent', torrent_id=torrent.id) if deleted_changed and editor.is_moderator: log = "Torrent [#{0}]({1}) marked as {2}".format( torrent.id, url, "deleted" if torrent.deleted else "undeleted") adminlog = models.AdminLog(log=log, admin_id=editor.id) db.session.add(adminlog) db.session.commit() flask.flash( flask.Markup( 'Torrent has been successfully edited! Changes might take a few minutes to show up.' ), 'info') return flask.redirect(url) else: if flask.request.method != 'POST': # Fill form data only if the POST didn't fail form.category.data = torrent.sub_category.id_as_string form.display_name.data = torrent.display_name form.information.data = torrent.information form.description.data = torrent.description form.is_hidden.data = torrent.hidden form.is_remake.data = torrent.remake form.is_complete.data = torrent.complete form.is_anonymous.data = torrent.anonymous form.is_trusted.data = torrent.trusted form.is_deleted.data = torrent.deleted return flask.render_template('edit.html', form=form, torrent=torrent)
def view_user(user_name): user = models.User.by_username(user_name) if not user: flask.abort(404) admin_form = None if flask.g.user and flask.g.user.is_moderator and flask.g.user.level > user.level: admin_form = forms.UserForm() default, admin_form.user_class.choices = _create_user_class_choices( user) if flask.request.method == 'GET': admin_form.user_class.data = default url = flask.url_for('view_user', user_name=user.username) if flask.request.method == 'POST' and admin_form and admin_form.validate(): selection = admin_form.user_class.data log = None if selection == 'regular': user.level = models.UserLevelType.REGULAR log = "[{}]({}) changed to regular user".format(user_name, url) elif selection == 'trusted': user.level = models.UserLevelType.TRUSTED log = "[{}]({}) changed to trusted user".format(user_name, url) elif selection == 'moderator': user.level = models.UserLevelType.MODERATOR log = "[{}]({}) changed to moderator user".format(user_name, url) adminlog = models.AdminLog(log=log, admin_id=flask.g.user.id) db.session.add(user) db.session.add(adminlog) db.session.commit() return flask.redirect(url) user_level = ['Regular', 'Trusted', 'Moderator', 'Administrator'][user.level] req_args = flask.request.args search_term = chain_get(req_args, 'q', 'term') sort_key = req_args.get('s') sort_order = req_args.get('o') category = chain_get(req_args, 'c', 'cats') quality_filter = chain_get(req_args, 'f', 'filter') page_number = chain_get(req_args, 'p', 'page', 'offset') try: page_number = max(1, int(page_number)) except (ValueError, TypeError): page_number = 1 results_per_page = app.config.get('RESULTS_PER_PAGE', DEFAULT_PER_PAGE) query_args = { 'term': search_term or '', 'user': user.id, 'sort': sort_key or 'id', 'order': sort_order or 'desc', 'category': category or '0_0', 'quality_filter': quality_filter or '0', 'page': page_number, 'rss': False, 'per_page': results_per_page } if flask.g.user: query_args['logged_in_user'] = flask.g.user if flask.g.user.is_moderator: # God mode query_args['admin'] = True # Use elastic search for term searching rss_query_string = _generate_query_string(search_term, category, quality_filter, user_name) use_elastic = app.config.get('USE_ELASTIC_SEARCH') if use_elastic and search_term: query_args['term'] = search_term max_search_results = app.config.get('ES_MAX_SEARCH_RESULT', DEFAULT_MAX_SEARCH_RESULT) # Only allow up to (max_search_results / page) pages max_page = min(query_args['page'], int(math.ceil(max_search_results / results_per_page))) query_args['page'] = max_page query_args['max_search_results'] = max_search_results query_results = search_elastic(**query_args) max_results = min(max_search_results, query_results['hits']['total']) # change p= argument to whatever you change page_parameter to or pagination breaks pagination = Pagination(p=query_args['page'], per_page=results_per_page, total=max_results, bs_version=3, page_parameter='p', display_msg=SERACH_PAGINATE_DISPLAY_MSG) return flask.render_template('user.html', use_elastic=True, pagination=pagination, torrent_query=query_results, search=query_args, user=user, user_page=True, rss_filter=rss_query_string, level=user_level, admin_form=admin_form) # Similar logic as home page else: if use_elastic: query_args['term'] = '' else: query_args['term'] = search_term or '' query = search_db(**query_args) return flask.render_template('user.html', use_elastic=False, torrent_query=query, search=query_args, user=user, user_page=True, rss_filter=rss_query_string, level=user_level, admin_form=admin_form)
def delete_torrent(torrent_id): torrent = models.Torrent.by_id(torrent_id) form = forms.DeleteForm(flask.request.form) editor = flask.g.user if not torrent: flask.abort(404) # Only allow admins edit deleted torrents if torrent.deleted and not (editor and editor.is_moderator): flask.abort(404) # Only allow torrent owners or admins edit torrents if not editor or not (editor is torrent.user or editor.is_moderator): flask.abort(403) action = None url = flask.url_for('main.home') if form.delete.data and not torrent.deleted: action = 'deleted' torrent.deleted = True db.session.add(torrent) elif form.ban.data and not torrent.banned and editor.is_moderator: action = 'banned' torrent.banned = True if not torrent.deleted: torrent.deleted = True action = 'deleted and banned' backend.tracker_api([torrent.info_hash], 'ban') db.session.add(torrent) elif form.undelete.data and torrent.deleted: action = 'undeleted' torrent.deleted = False if torrent.banned: action = 'undeleted and unbanned' torrent.banned = False backend.tracker_api([torrent.info_hash], 'unban') db.session.add(torrent) elif form.unban.data and torrent.banned: action = 'unbanned' torrent.banned = False backend.tracker_api([torrent.info_hash], 'unban') db.session.add(torrent) if not action: flask.flash(flask.Markup('What the f**k are you doing?'), 'danger') return flask.redirect(flask.url_for('torrents.edit', torrent_id=torrent.id)) if editor.is_moderator: url = flask.url_for('torrents.view', torrent_id=torrent.id) if editor is not torrent.user: log = "Torrent [#{0}]({1}) has been {2}".format(torrent.id, url, action) adminlog = models.AdminLog(log=log, admin_id=editor.id) db.session.add(adminlog) db.session.commit() flask.flash(flask.Markup('Torrent has been successfully {0}.'.format(action)), 'info') return flask.redirect(url)