diff --git a/config.example.py b/config.example.py index 9054e44..122fb6d 100644 --- a/config.example.py +++ b/config.example.py @@ -1,20 +1,47 @@ import os DEBUG = True + +###################### +## Maintenance mode ## +###################### + # A read-only maintenance mode, in which the database is not modified -MAINTENANCE_MODE = True +MAINTENANCE_MODE = False # A maintenance message (used in layout.html template) MAINTENANCE_MODE_MESSAGE = 'Site is currently in read-only maintenance mode.' # Allow logging in during maintenance (without updating last login date) MAINTENANCE_MODE_LOGINS = True -USE_RECAPTCHA = False -USE_EMAIL_VERIFICATION = False -USE_MYSQL = True +############# +## General ## +############# -# Enable this once stat integration is done +# What the site identifies itself as. This affects templates, not database stuff. +SITE_NAME = 'Nyaa' + +# General prefix for running multiple sites, eg. most database tables are site-prefixed +SITE_FLAVOR = 'nyaa' # 'nyaa' or 'sukebei' +# Full external urls to both sites, used for site-change links +EXTERNAL_URLS = {'fap':'***', 'main':'***'} + +# Secret keys for Flask +CSRF_SESSION_KEY = '***' +SECRET_KEY = '***' + +# Present a recaptcha for anonymous uploaders +USE_RECAPTCHA = False +# Require email validation +USE_EMAIL_VERIFICATION = False +# Use MySQL or Sqlite3 (mostly deprecated) +USE_MYSQL = True +# Show seeds/peers/completions in torrent list/page ENABLE_SHOW_STATS = True +# Recaptcha keys (https://www.google.com/recaptcha) +RECAPTCHA_PUBLIC_KEY = '***' +RECAPTCHA_PRIVATE_KEY = '***' + BASE_DIR = os.path.abspath(os.path.dirname(__file__)) if USE_MYSQL: SQLALCHEMY_DATABASE_URI = ('mysql://test:test123@localhost/nyaav2?charset=utf8mb4') @@ -22,50 +49,54 @@ else: SQLALCHEMY_DATABASE_URI = ( 'sqlite:///' + os.path.join(BASE_DIR, 'test.db') + '?check_same_thread=False') -CSRF_SESSION_KEY = '***' -SECRET_KEY = '***' - -# Prefix for running multiple sites, user table will not be prefixed. -SITE_FLAVOR = 'nyaa' # 'nyaa' or 'sukebei' -EXTERNAL_URLS = {'fap':'***', 'main':'***'} -# for recaptcha and email verification: -# keys for localhost. Change as appropriate when actual domain is registered. -RECAPTCHA_PUBLIC_KEY = '***' -RECAPTCHA_PRIVATE_KEY = '***' +# Email server settings SMTP_SERVER = '***' SMTP_PORT = 587 MAIL_FROM_ADDRESS = '***' SMTP_USERNAME = '***' SMTP_PASSWORD = '***' -# What the site identifies itself as. This affects templates, not database stuff. -SITE_NAME = 'Nyaa' - # The maximum number of files a torrent can contain # until the site says "Too many files to display." MAX_FILES_VIEW = 1000 -# -# Setting to make sure main announce url is present in torrent -# +# Verify uploaded torrents have the given tracker in them? ENFORCE_MAIN_ANNOUNCE_URL = False MAIN_ANNOUNCE_URL = 'http://127.0.0.1:6881/announce' + +# Tracker API integration - don't mind this TRACKER_API_URL = 'http://127.0.0.1:6881/api' TRACKER_API_AUTH = 'topsecret' + +############# +## Account ## +############# + # Torrents uploaded without an account must be at least this big in total (bytes) # Set to 0 to disable MINIMUM_ANONYMOUS_TORRENT_SIZE = 1 * 1024 * 1024 +# Minimum age for an account not to be served a captcha (seconds) +# Relies on USE_RECAPTCHA. Set to 0 to disable. +ACCOUNT_RECAPTCHA_AGE = 7 * 24 * 3600 # A week + +# Backup original .torrent uploads BACKUP_TORRENT_FOLDER = 'torrents' -# -# Search Options -# +############ +## Search ## +############ + +# How many results should a page contain. Applies to RSS as well. RESULTS_PER_PAGE = 75 -# See README.MD on Elasticsearch setup +# Use better searching with ElasticSearch +# See README.MD on setup! USE_ELASTIC_SEARCH = False +# Highlight matches (for debugging) ENABLE_ELASTIC_SEARCH_HIGHLIGHT = False + # Max ES search results, do not set over 10000 ES_MAX_SEARCH_RESULT = 1000 -ES_INDEX_NAME = SITE_FLAVOR # we create indicies named nyaa or sukebei +# ES index name generally (nyaa or sukebei) +ES_INDEX_NAME = SITE_FLAVOR diff --git a/nyaa/forms.py b/nyaa/forms.py index 15d1557..623d68b 100644 --- a/nyaa/forms.py +++ b/nyaa/forms.py @@ -239,6 +239,17 @@ class BanForm(FlaskForm): ]) +def recaptcha_validator_shim(form, field): + ''' Selectively does a recaptcha validation ''' + if app.config['USE_RECAPTCHA']: + # Recaptcha anonymous and new users + if not flask.g.user or flask.g.user.age < app.config['ACCOUNT_RECAPTCHA_AGE']: + return RecaptchaValidator()(form, field) + else: + # Always pass validating the recaptcha field if disabled + return True + + class UploadForm(FlaskForm): torrent_file = FileField('Torrent file', [ FileRequired() @@ -251,17 +262,8 @@ class UploadForm(FlaskForm): '%(max)d at most.') ]) - if config['USE_RECAPTCHA']: - # Captcha only for not logged in users - _recaptcha_validator = RecaptchaValidator() + recaptcha = RecaptchaField(validators=[recaptcha_validator_shim]) - def _validate_recaptcha(form, field): - if not flask.g.user: - return UploadForm._recaptcha_validator(form, field) - - recaptcha = RecaptchaField(validators=[_validate_recaptcha]) - - # category = SelectField('Category') category = DisabledSelectField('Category') def validate_category(form, field): diff --git a/nyaa/models.py b/nyaa/models.py index 020381e..1f1ba10 100644 --- a/nyaa/models.py +++ b/nyaa/models.py @@ -601,6 +601,11 @@ class User(db.Model): def is_banned(self): return self.status == UserStatusType.BANNED + @property + def age(self): + '''Account age in seconds''' + return (datetime.utcnow() - self.created_time).total_seconds() + class AdminLogBase(DeclarativeHelperBase): __tablename_base__ = 'adminlog' diff --git a/nyaa/templates/upload.html b/nyaa/templates/upload.html index 4c7dc05..9632abe 100644 --- a/nyaa/templates/upload.html +++ b/nyaa/templates/upload.html @@ -86,7 +86,7 @@ - {% if config.USE_RECAPTCHA and not g.user %} + {% if config.USE_RECAPTCHA and (not g.user or g.user.age < config['ACCOUNT_RECAPTCHA_AGE']) %}
{% for error in upload_form.recaptcha.errors %}