From 870e18785dec66edc9d6dd8a3fe3f3b4ad86b30a Mon Sep 17 00:00:00 2001 From: Spine Date: Wed, 29 Dec 2021 15:01:05 +0000 Subject: [PATCH] Complete overhaul of the configuration architecture --- .docker/web/entrypoint.sh | 4 +- .docker/web/generate-config.sed | 22 - .docker/web/generate-config.sh | 24 +- .gitignore | 2 +- README.md | 17 +- app/Manager/Donation.php | 2 +- app/Manager/ReportV2Types.php | 2 +- app/Tracker.php | 2 +- app/UserCreator.php | 2 +- classes/config.template.php | 552 ----------------- classes/db_mysql.class.php | 2 +- classes/script_start.php | 10 +- classes/text.class.php | 4 +- docs/01-MysqlRoles.txt | 2 +- docs/INSTALL.txt | 87 +-- docs/crontab | 7 + lib/bootstrap.php | 2 +- lib/config.devel.example.php | 25 + lib/config.php | 996 ++++++++++++++++++++++++++++++ lib/config.production.example.php | 52 ++ lib/stub/memcached.stub | 12 + phinx.php | 2 +- phpstan.neon | 23 +- public/feeds.php | 10 +- public/opensearch.php | 2 +- scripts/getconf | 2 +- scripts/regen-filelists.php | 1 + scripts/upload-wiki.php | 4 - 28 files changed, 1193 insertions(+), 679 deletions(-) delete mode 100644 .docker/web/generate-config.sed delete mode 100644 classes/config.template.php create mode 100644 docs/crontab create mode 100644 lib/config.devel.example.php create mode 100644 lib/config.php create mode 100644 lib/config.production.example.php create mode 100644 lib/stub/memcached.stub diff --git a/.docker/web/entrypoint.sh b/.docker/web/entrypoint.sh index bbf4a9008..bd9fc8cad 100644 --- a/.docker/web/entrypoint.sh +++ b/.docker/web/entrypoint.sh @@ -25,9 +25,7 @@ while ! mysql -h mysql -u "$MYSQL_USER" -p"$MYSQL_PASSWORD" -e "show databases;" fi; done -if [ ! -f /var/www/classes/config.php ]; then - bash /var/www/.docker/web/generate-config.sh -fi +[ -f /var/www/lib/config.override.php ] || bash /var/www/.docker/web/generate-config.sh echo "Run migrations..." if ! FKEY_MY_DATABASE=1 LOCK_MY_DATABASE=1 /var/www/vendor/bin/phinx migrate; then diff --git a/.docker/web/generate-config.sed b/.docker/web/generate-config.sed deleted file mode 100644 index a83f0ca7d..000000000 --- a/.docker/web/generate-config.sed +++ /dev/null @@ -1,22 +0,0 @@ -s/'SITE_NAME', *'/&Gazelle Dev/ -s/'SITE_HOST', *'/&localhost/ - -s|'(SITE_URL)', *'https://'.SITE_HOST|'\1', 'http://'.SITE_HOST.':8080'| - -s|'(SERVER_ROOT(_LIVE)?)', *'/path|'\1', '/var/www| - -s|'ANNOUNCE_HTTP_URL', *'|&http://localhost:34000| -s|'ANNOUNCE_HTTPS_URL', *'|&https://localhost:3400| - -s/('SQLHOST', *')localhost/\1mysql/ -s/('SPHINX(QL)?_HOST', *')(localhost|127\.0\.0\.1)/\1sphinxsearch/ - -s|('host' *=>) *'unix:///var/run/memcached.sock'(, *'port' *=>) *0|\1 'memcached'\2 11211| - -s/('(DEBUG_MODE|DISABLE_IRC)',) *false/\1 true/ - -s|'SOURCE', *'|&DEV| - -s|'TRACKER_SECRET', *'|&00000000000000000000000000000000| -s|'TRACKER_REPORTKEY', *'|&00000000000000000000000000000000| -s/('TRACKER_HOST', *')localhost/\1ocelot/ diff --git a/.docker/web/generate-config.sh b/.docker/web/generate-config.sh index 2a5a16621..1c2146ca8 100755 --- a/.docker/web/generate-config.sh +++ b/.docker/web/generate-config.sh @@ -1,18 +1,14 @@ -#!/usr/bin/env bash +#!/bin/bash -THIS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +set -euo pipefail -TARGET=${THIS_DIR}/../../classes/config.php - -if [ -f ${TARGET} ]; then - exit 0; -fi +LIB_DIR="$(dirname "${BASH_SOURCE[0]}")/../../lib" +SOURCE="${LIB_DIR}/config.devel.example.php" +TARGET="${LIB_DIR}/config.override.php" +[ -f ${TARGET} ] && exit 0 echo "GENERATING GAZELLE CONFIG..." -echo "" -sed -Ef $THIS_DIR/generate-config.sed \ - -e "s/('SQL(LOGIN|_PHINX_USER)', *')/\1${MYSQL_USER}/" \ - -e "s/('SQL(_PHINX_)?PASS', *')/\1${MYSQL_PASSWORD}/" \ - ${THIS_DIR}/../../classes/config.template.php > ${TARGET} - -echo "" +( + perl -ple 's/""/q{"} . qx(head \/dev\/urandom|tr -dc 0-9A-Za-z|head -c 16) . q{"}/e' "${SOURCE}" + date +"define('SITE_LAUNCH_YEAR', %Y);" +) > "${TARGET}" diff --git a/.gitignore b/.gitignore index 5696d833e..b7e611582 100644 --- a/.gitignore +++ b/.gitignore @@ -24,7 +24,7 @@ __MACOSX/ /public/static/font/ /public/static/local/ /vendor -/classes/config.php +/lib/config.override.php /mix-manifest.json /mix.js.map /yarn-error.log diff --git a/README.md b/README.md index 7ea8a3523..542c0fe08 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,11 @@ needs. Gazelle is written in PHP, Twig, JavaScript, and MySQL. * [GCC/G++](http://gcc.gnu.org/) (4.7+ required; 4.8.1+ recommended) * [Boost](http://www.boost.org/) (1.55.0+ required) +## Gazelle/Ocelot Compile-time Dependencies +* [Git](http://git-scm.com/) (required) +* [GCC/G++](http://gcc.gnu.org/) (4.7+ required; 4.8.1+ recommended) +* [Boost](http://www.boost.org/) (1.55.0+ required) + _Note: This list may not be exhaustive._ ## Logchecker @@ -61,7 +66,14 @@ Bullseye. A volume is mounted from the base of the git repository at `/var/www` in the container. Changes to the source code are immediately served without rebuilding or restarting. -## Going further +You can access the site by viewing `http://localhost:8080` + +The first account is 'admin' and has the highest level of access +to the site installation. The second account is 'user' and has +standard user access. The passwords for both accounts are literally +'password' (without the quotes). If you want to change these before +building, edit db/seeds/InitialUserSeeder.php first. + The 'admin' account might not have all the permissions that have been added recently. Navigate to the /tools.php?action=permissions page and tick everything. @@ -72,8 +84,7 @@ The following ports are forwarded: * 3306 -> 36000 (mysql) * 34000 -> 34000 (ocelot) -You can access the site by viewing `http://localhost:8080` - +## Going further You may want to install additional packages: * `apt update` * `apt install less procps vim` diff --git a/app/Manager/Donation.php b/app/Manager/Donation.php index 54b01d172..cf5ef1e88 100644 --- a/app/Manager/Donation.php +++ b/app/Manager/Donation.php @@ -99,7 +99,7 @@ class Donation extends \Gazelle\Base { } // Assign them to the Donor secondary class if it hasn't already been done - $inviteForNewDonor = $xbtAmount > 0 ? DONOR_FIRST_INVITE_COUNT * $this->addDonorStatus($UserID) : 0; + $inviteForNewDonor = $xbtAmount > 0 ? DONOR_INVITES * $this->addDonorStatus($UserID) : 0; // Now that their rank and total rank has been set, we can calculate their special rank and invites $column = []; diff --git a/app/Manager/ReportV2Types.php b/app/Manager/ReportV2Types.php index af2bcd69c..4a3226e05 100644 --- a/app/Manager/ReportV2Types.php +++ b/app/Manager/ReportV2Types.php @@ -3,7 +3,7 @@ * This array is the backbone of the reports system. * Important thing to note about the array: * 1. When coding for a non music site, you need to ensure that the top level of the - * array lines up with the $Categories array in your config.php. + * array lines up with the CATEGORIES array in lib/config.php. * 2. The first sub array contains resolves that are present on every report type * regardless of category. * 3. The only part that shouldn't be self-explanatory is that for the tracks field in diff --git a/app/Tracker.php b/app/Tracker.php index 7b5b0c2a0..2ad06a3c2 100644 --- a/app/Tracker.php +++ b/app/Tracker.php @@ -115,7 +115,7 @@ class Tracker { * @return array with stats in named keys or empty if the request failed */ private function get_stats($Type, $Params = false): array { - if (!TRACKER_REPORTKEY) { + if (DISABLE_TRACKER) { return []; } $Get = TRACKER_REPORTKEY . '/report?'; diff --git a/app/UserCreator.php b/app/UserCreator.php index e8208e343..93b2c0f03 100644 --- a/app/UserCreator.php +++ b/app/UserCreator.php @@ -309,7 +309,7 @@ class UserCreator extends Base { } /** - * Create salted crypt hash for a given string + * Create a password hash of a plaintext password. */ static public function hashPassword(string $plaintext): string { return password_hash(hash('sha256', $plaintext), PASSWORD_DEFAULT); diff --git a/classes/config.template.php b/classes/config.template.php deleted file mode 100644 index 5494cdfe9..000000000 --- a/classes/config.template.php +++ /dev/null @@ -1,552 +0,0 @@ - 'users_mod', - 'uploaded' => 'users_mod', - 'lastseen' => 'users_mod', - 'ratio' => 'users_mod', - 'requiredratio' => 'users_mod', - 'hide_donor_heart' => 'users_mod', - 'bonuspoints' => 'admin_bp_history', - 'torrentcomments' => 'site_moderate_forums', - 'invitedcount' => 'users_view_invites', - 'snatched' => 'users_view_torrents_snatchlist', - 'snatched+' => 'users_view_torrents_snatchlist', - 'leeching' => 'users_view_seedleech', - 'leeching+' => 'users_view_seedleech', - 'seeding' => 'users_view_seedleech', - 'seeding+' => 'users_view_seedleech', - 'uploads' => 'users_view_seedleech', - 'uploads+' => 'users_view_seedleech', -]); - -define('USER_TORRENT_DELETE_MAX', 3); -define('USER_TORRENT_DELETE_HOURS', 24); - -define('DELETE_USER_STATS_DAILY_DAY', 15); // retain how many days worth of hourly granularity -define('DELETE_USER_STATS_MONTHLY_DAY', 120); // retain how many days worth of daily granularity - -define('FEATURE_EMAIL_REENABLE', true); - -// Name of class Class ID (NOT level) -define('USER', 2); -define('MEMBER', 3); -define('POWER', 4); -define('ELITE', 5); -define('TORRENT_MASTER', 7); -define('POWER_TM', 22); -define('ELITE_TM', 23); -define('ULTIMATE_TM', 48); -define('FORUM_MOD', 28); -define('MOD', 11); -define('SYSOP', 15); - -define('DONOR', 20); -define('FLS_TEAM', 23); -define('INTERVIEWER', 30); -define('RECRUITER', 41); -define('VIP', 6); - -// Locked account constant -define('STAFF_LOCKED', 1); -define('STAFF_LEVEL', 820); // least permissions.Level of staff - -// Pagination -define('BOOKMARKS_PER_PAGE', 20); -define('COLLAGES_PER_PAGE', 25); -define('CONTEST_ENTRIES_PER_PAGE', 50); -define('FRIENDS_PER_PAGE', 20); -define('INVITES_PER_PAGE', 50); -define('ITEMS_PER_PAGE', 50); -define('IPS_PER_PAGE', 50); -define('LOG_ENTRIES_PER_PAGE', 50); -define('MESSAGES_PER_PAGE', 25); -define('PEERS_PER_PAGE', 100); -define('POSTS_PER_PAGE', 25); -define('REPORTS_PER_PAGE', '10'); -define('REQUESTS_PER_PAGE', 25); -define('TOPICS_PER_PAGE', 50); -define('TORRENTS_PER_PAGE', 50); -define('TORRENT_COMMENTS_PER_PAGE', 10); -define('USERS_PER_PAGE', 50); -define('WIKI_ARTICLES_PER_PAGE', 25); - -define('AJAX_USERS_PER_PAGE', 30); - -// Cache catalogues -define('THREAD_CATALOGUE', 500); // Limit to THREAD_CATALOGUE posts per cache key. - -// IRC settings -define('DISABLE_IRC', false); -define('IRC_SOCKET_LISTEN_PORT', 51010); -define('IRC_SOCKET_LISTEN_ADDRESS', 'localhost'); -define('BOT_NICK', ''); -define('BOT_SERVER', ''); // IRC server address. Used for onsite chat tool. -define('BOT_PORT', 6667); -define('BOT_CHAN', '#mygazelle'); -define('ADMIN_CHAN', '#admin'); -define('LAB_CHAN', '#lab'); -define('STATUS_CHAN', '#status'); -define('MOD_CHAN', '#staff'); -define('BOT_DISABLED_CHAN', '#disabled'); // Channel to refer disabled users to. -define('BOT_REPORT_CHAN', '#reports'); - -// Push server settings -define('PUSH_SOCKET_LISTEN_ADDRESS', '127.0.0.1'); -define('PUSH_SOCKET_LISTEN_PORT', 6789); - -// Miscellaneous values -define('RANK_ONE_COST', 5); -define('RANK_TWO_COST', 10); -define('RANK_THREE_COST', 15); -define('RANK_FOUR_COST', 20); -define('RANK_FIVE_COST', 30); -define('MAX_RANK', 6); -define('MAX_EXTRA_RANK', 8); -define('DONOR_FORUM_RANK', 6); -define('DONOR_FORUM', null); // donor forum id -define('MAX_SPECIAL_RANK', 3); - -define('BONUS_AWARD_FLAC_PERFECT', 400); -define('BONUS_AWARD_FLAC', 30); -define('BONUS_AWARD_MP3', 30); -define('BONUS_AWARD_OTHER', 10); - -define('BONUS_POOL_TAX_STD', 0.9); -define('BONUS_POOL_TAX_ELITE', 0.8); -define('BONUS_POOL_TAX_TM', 0.7); -define('BONUS_POOL_TAX_STAFF', 0.5); - -define('DEBUG_CONTEST_PAYOUT', true); // set to true to test - -define('INDEX_WIKI_PAGE_ID', 1); -define('RULES_WIKI_PAGE_ID', 127); -define('SOURCE_FLAG_WIKI_PAGE_ID', 113); - -define('TMPDIR', '/tmp'); - -define('FORUM_REVEAL_VOTER', []); - -define('STORAGE_PATH_TORRENT', '/var/lib/gazelle/torrent'); -define('STORAGE_PATH_RIPLOG', '/var/lib/gazelle/riplog'); -define('STORAGE_PATH_RIPLOGHTML', '/var/lib/gazelle/riploghtml'); - -//Useful: http://www.robtex.com/cnet/ -define('ALLOWED_PROXY', [ - //Opera Turbo (may include Opera-owned IP addresses that aren't used for Turbo, but shouldn't run much risk of exploitation) - '64.255.180.*', //Norway - '64.255.164.*', //Norway - '80.239.242.*', //Poland - '80.239.243.*', //Poland - '91.203.96.*', //Norway - '94.246.126.*', //Norway - '94.246.127.*', //Norway - '195.189.142.*', //Norway - '195.189.143.*', //Norway -]); - -define('CATEGORY', ['Music', 'Applications', 'E-Books', 'Audiobooks', 'E-Learning Videos', 'Comedy', 'Comics']); -define('CATEGORY_GROUPED', array_intersect(['Music'], CATEGORY)); -define('CATEGORY_ICON', ['music.png', 'apps.png', 'ebook.png', 'audiobook.png', 'elearning.png', 'comedy.png', 'comics.png']); - -define('FORMAT', [ - 'MP3', - 'FLAC', - 'Ogg Vorbis', - 'AAC', - 'AC3', - 'DTS' -]); -define('ENCODING', [ - 'Lossless', - '24bit Lossless', - 'V0 (VBR)', - 'V1 (VBR)', - 'V2 (VBR)', - '320', - '256', - '192', - '160', - '128', - '96', - '64', - 'APS (VBR)', - 'APX (VBR)', - 'q8.x (VBR)', - 'Other' -]); -define('MEDIA', [ - 'CD', - 'WEB', - 'Vinyl', - 'DVD', - 'BD', - 'Soundboard', - 'SACD', - 'DAT', - 'Cassette', -]); - -define('HOMEPAGE_TAG_IGNORE', [0]); // set to 'test' tag to ignore staff test uploads - -define('ICON_ALL', "\xe2\x9c\x85"); -define('ICON_NONE', "\xf0\x9f\x9a\xab"); -define('ICON_TOGGLE', "\xf0\x9f\x94\x81"); -define('ICON_PADLOCK', "\xF0\x9F\x94\x92"); -define('ICON_STAR', "\xE2\x98\x85"); -define('ICON_BLACK_SQUARE', "\xE2\x96\xA0"); -define('ICON_WHITE_SQUARE', "\xE2\x96\xA1"); - -define('COLLAGE', [ - 0 => 'Personal', - 1 => 'Theme', - 2 => 'Genre Introduction', - 3 => 'Discography', - 4 => 'Label', - 5 => 'Staff picks', - 6 => 'Charts', - 7 => 'Artists', - 8 => 'Awards', - 9 => 'Series', -]); -define('COLLAGE_PERSONAL_ID', 0); -define('COLLAGE_ARTISTS_ID', 7); -define('COLLAGE_SAMPLE_THRESHOLD', 4); -define('PERSONAL_COLLAGE_SAMPLE_THRESHOLD', 4); - -define('ZIP_GROUP', [ - 0 => 'MP3 (VBR) - High Quality', - 1 => 'MP3 (VBR) - Low Quality', - 2 => 'MP3 (CBR)', - 3 => 'FLAC - Lossless', - 4 => 'Others', -]); -define('ZIP_OPTION', [ - '00' => [0, 0, 'V0'], - '01' => [0, 1, 'APX'], - '02' => [0, 2, '256'], - '03' => [0, 3, 'V1'], - '10' => [1, 0, '224'], - '11' => [1, 1, 'V2'], - '12' => [1, 2, 'APS'], - '13' => [1, 3, '192'], - '20' => [2, 0, '320'], - '21' => [2, 1, '256'], - '22' => [2, 2, '224'], - '23' => [2, 3, '192'], - '24' => [2, 4, '160'], - '25' => [2, 5, '128'], - '26' => [2, 6, '96'], - '27' => [2, 7, '64'], - '30' => [3, 0, 'FLAC / 24bit / Vinyl'], - '31' => [3, 1, 'FLAC / 24bit / DVD'], - '32' => [3, 2, 'FLAC / 24bit / SACD'], - '33' => [3, 3, 'FLAC / 24bit / WEB'], - '34' => [3, 4, 'FLAC / Log (100) / Cue'], - '35' => [3, 5, 'FLAC / Log (100)'], - '36' => [3, 6, 'FLAC / Log'], - '37' => [3, 7, 'FLAC / WEB'], - '38' => [3, 8, 'FLAC'], - '40' => [4, 0, 'DTS'], - '42' => [4, 2, 'AAC - 320'], - '43' => [4, 3, 'AAC - 256'], - '44' => [4, 4, 'AAC - q5.5'], - '45' => [4, 5, 'AAC - q5'], - '46' => [4, 6, 'AAC - 192'], -]); - -define('CAPTCHA_FONT', [ - 'ARIBLK.TTF', - 'IMPACT.TTF', - 'TREBUC.TTF', - 'TREBUCBD.TTF', - 'TREBUCBI.TTF', - 'TREBUCIT.TTF', - 'VERDANA.TTF', - 'VERDANAB.TTF', - 'VERDANAI.TTF', - 'VERDANAZ.TTF', -]); -define('CAPTCHA_BG', [ - 'captcha1.png', - 'captcha2.png', - 'captcha3.png', - 'captcha4.png', - 'captcha5.png', - 'captcha6.png', - 'captcha7.png', - 'captcha8.png', - 'captcha9.png', -]); - -// Memcached details -define('MEMCACHE_HOST_LIST', [ - // unix sockets are fast, and other people can't telnet into them - ['host' => 'unix:///var/run/memcached.sock', 'port' => 0, 'buckets' => 1], -]); -define('CACHE_ID', 'ops'); - -// Deny cache access to keys without specified permission -define('CACHE_PERMISSION', [ - 'api_apps' => 'site_debug', - 'catalogue' => 'site_debug' -]); - -define('CACHE_BULK_FLUSH', 500); - -define('CACHE_RESPONSE', [ - 0 => 'success', - 1 => 'failure/delete ok', - 16 => 'not found', -]); - -define('CACHE_DB', [ - 'artist' => ['table' => 'artists_group', 'pk' => 'ArtistID'], - 'collage' => ['table' => 'collages', 'pk' => 'ID'], - 'torrent-group' => ['table' => 'torrents_group', 'pk' => 'ID'], - 'user' => ['table' => 'users_main', 'pk' => 'ID'], -]); - -define('CACHE_NAMESPACE', [ - 'artist' => [ - 'a1' => 'artist_%d', - 'a2' => 'artist_comments_%d', - 'a3' => 'artist_comments_%d_catalogue_0', - 'a4' => 'artist_groups_%d', - 'a5' => 'artists_collages_%d', - 'a6' => 'artists_requests_%d', - 'a7' => 'similar_positions_%d', - ], - 'collage' => [ - 'c1' => 'collage_%d', - 'c2' => 'collage_display_%d', - 'c3' => 'collage_subs_user_%d', - 'c4' => 'collage_subs_user_new_%d', - ], - 'torrent-group' => [ - 'g1' => 'torrents_collages_%d', - 'g2' => 'torrent_collages_personal_%d', - 'g3' => 'torrents_cover_art_%d', - 'g4' => 'torrents_details_%d', - 'g5' => 'torrent_group_%d', - 'g6' => 'torrent_group_light_%d', - 'g7' => 'groups_artists_%d', - 'g8' => 'tg_%d', - 'g9' => 'tlist_%d', - ], - 'user' => [ - 'u1' => 'bookmarks_group_ids_%d', - 'u2' => 'donor_info_%d', - 'u3' => 'inbox_new_%d', - 'u4' => 'u_%d', - 'u6' => 'user_stats_%d', - 'u7' => 'user_statgraphs_%d', - 'u8' => 'user_tokens_%d', - ], -]); - -define('SITE_LAUNCH_YEAR', 2018); - -define('ARTIST_MAIN', 1); -define('ARTIST_GUEST', 2); -define('ARTIST_REMIXER', 3); -define('ARTIST_COMPOSER', 4); -define('ARTIST_CONDUCTOR', 5); -define('ARTIST_DJ', 6); -define('ARTIST_PRODUCER', 7); -define('ARTIST_ARRANGER', 8); -define('ARTIST_TYPE', [ - ARTIST_MAIN => 'Main', - ARTIST_GUEST => 'Guest', - ARTIST_REMIXER => 'Remixer', - ARTIST_COMPOSER => 'Composer', - ARTIST_CONDUCTOR => 'Conductor', - ARTIST_DJ => 'DJ/Compiler', - ARTIST_PRODUCER => 'Producer', - ARTIST_ARRANGER => 'Arranger', -]); - -define('ARTIST_SECTION_ARRANGER', 1020); -define('ARTIST_SECTION_PRODUCER', 1021); -define('ARTIST_SECTION_COMPOSER', 1022); -define('ARTIST_SECTION_REMIXER', 1023); -define('ARTIST_SECTION_GUEST', 1024); - -define('RANDOM_ARTIST_MIN_ENTRIES', 1); -define('RANDOM_COLLAGE_MIN_ENTRIES', 1); -define('RANDOM_TORRENT_MIN_SEEDS', 0); - -define('IP_REGEXP', '/\b(?:\d{1,3}\.){3}\d{1,3}\b/'); -define('URL_REGEXP_STEM', '((?:f|ht)tps?:\/\/)(?:' . str_replace('/', '', IP_REGEXP) . '|[\w-]+(?:\.[\w-]+)+)(?::\d{1,5})?(?:\/\S*)'); -define('URL_REGEXP', '/^' . URL_REGEXP_STEM . '$/i'); -define('CSS_REGEXP', '/^' . URL_REGEXP_STEM . '\.css(?:\?\S*)?$/i'); -define('IMAGE_REGEXP', '/\b(' . URL_REGEXP_STEM . '\.(?:gif|png|webm|jpe?g|tiff?)(\?\S*)?)\b/i'); -define('SITELINK_REGEXP', '(?:' . preg_quote(SITE_URL, '/') . (defined('ALT_SITE_URL') ? '|' . preg_quote(ALT_SITE_URL, '/') : '') . ')'); -define('ARTIST_REGEXP', '/^' . SITELINK_REGEXP . '\/artist\.php\?.*?\bid=(?P\d+)$/'); -define('TGROUP_REGEXP', '/^' . SITELINK_REGEXP . '\/torrents\.php\?.*?\bid=(?P\d+)\b/'); -define('TORRENT_REGEXP', '/^' . SITELINK_REGEXP . '\/torrents\.php\?.*?\btorrentid=(?P\d+)\b/'); -define('EMAIL_REGEXP', '/^[\w-]+(?:\.[\w-]+)*(?:\+[.\w-]+)?@[\w-]+(?:\.[\w-]+)+$/'); -define('USERNAME_REGEXP', '/\b(?:[01]$(*PRUNE)(*FAIL)|(?P[\w.]{1,20}))\b/'); - -define('IMAGE_HOST_BANNED', ['badhost.example.com']); -define('IMAGE_HOST_RECOMMENDED', ['goodhost.example.com']); - -define('DONOR_RANK_PRICE', 10); -define('DONOR_FIRST_INVITE_COUNT', 2); - -define('TAG_OFFICIAL_COLUMNS', 4); - -define('RANKING_WEIGHT', [ - 'uploaded' => [ 8, 'DataUpload'], - 'downloaded' => [20, 'DataDownload'], - 'uploads' => [25, 'Uploads'], - 'requests' => [10, 'RequestsFilled'], - 'posts' => [ 3, 'ForumPosts'], - 'bounty' => [ 4, 'BountySpent'], - 'artists' => [ 1, 'ArtistsAdded'], - 'collage' => [ 5, 'CollageContribution'], - 'votes' => [ 5, 'ReleaseVotes'], - 'bonus' => [ 6, 'BonusPoints'], - 'comment-t' => [18, 'CommentTorrent'], -]); - -define('SHOW_LOGO', true); diff --git a/classes/db_mysql.class.php b/classes/db_mysql.class.php index 5ee0fd91f..35f7743c3 100644 --- a/classes/db_mysql.class.php +++ b/classes/db_mysql.class.php @@ -193,7 +193,7 @@ class DB_MYSQL { public function connect() { if (!$this->LinkID) { - $this->LinkID = mysqli_connect($this->Server, $this->User, $this->Pass, $this->Database, $this->Port, $this->Socket); // defined in config.php + $this->LinkID = mysqli_connect($this->Server, $this->User, $this->Pass, $this->Database, $this->Port, $this->Socket); if (!$this->LinkID) { $this->Errno = mysqli_connect_errno(); $this->Error = mysqli_connect_error(); diff --git a/classes/script_start.php b/classes/script_start.php index 8a09fd58c..462e8ad0d 100644 --- a/classes/script_start.php +++ b/classes/script_start.php @@ -11,15 +11,17 @@ /*------------------------------------------------------*/ /********************************************************/ -require_once(__DIR__ . '/../lib/bootstrap.php'); - -use Gazelle\Util\{Crypto, Irc, Text}; +use Gazelle\Util\Crypto; +use Gazelle\Util\Irc; +use Gazelle\Util\Text; // Deal with dumbasses if (isset($_REQUEST['info_hash']) && isset($_REQUEST['peer_id'])) { die('d14:failure reason40:Invalid .torrent, try downloading again.e'); } +require_once('../lib/bootstrap.php'); + // Get the user's actual IP address if they're proxied. if (!empty($_SERVER['HTTP_X_FORWARDED_FOR']) && proxyCheck($_SERVER['REMOTE_ADDR']) @@ -146,8 +148,6 @@ if (!empty($_SERVER['HTTP_AUTHORIZATION']) && $Document === 'ajax') { } if (!is_null($Viewer)) { - $viewerId = $Viewer->id(); - // Change necessary triggers in external components if ($Viewer->permitted('admin_clear_cache')) { $Cache->enableCacheClear(); diff --git a/classes/text.class.php b/classes/text.class.php index d546bbfb5..71a85520e 100644 --- a/classes/text.class.php +++ b/classes/text.class.php @@ -275,7 +275,7 @@ class Text { return false; } $Host = $URLInfo['host']; - if (empty($URLInfo['port']) && ($Host === SITE_HOST || (defined('ALT_SITE_HOST') && $Host === ALT_SITE_HOST))) { + if (empty($URLInfo['port']) && in_array($Host, [SITE_HOST, ALT_SITE_HOST])) { $URL = ''; if (!empty($URLInfo['path'])) { $URL .= ltrim($URLInfo['path'], '/'); // Things break if the path starts with '//' @@ -298,7 +298,7 @@ class Text { if ( !$info || empty($info['host']) - || ($info['host'] !== SITE_HOST && (!defined('ALT_SITE_HOST') || $info['host'] !== ALT_SITE_HOST)) + || !in_array($info['host'], [SITE_HOST, ALT_SITE_HOST]) ) { return null; } diff --git a/docs/01-MysqlRoles.txt b/docs/01-MysqlRoles.txt index b77666514..5e378f197 100644 --- a/docs/01-MysqlRoles.txt +++ b/docs/01-MysqlRoles.txt @@ -25,7 +25,7 @@ These mysql roles should be configured with different passwords and used in the following places: /etc/sphinxsearch/sphinx.conf - /var/www/gazelle/classes/config.php + /var/www/gazelle/lib/config.override.php /var/www/ocelot/ocelot.conf In practice, the roles will probably have specific IP addresses. localhost diff --git a/docs/INSTALL.txt b/docs/INSTALL.txt index 50c218bc6..7675802ca 100644 --- a/docs/INSTALL.txt +++ b/docs/INSTALL.txt @@ -1,72 +1,79 @@ INSTALLATION NOTES -Note: We make no guarantee of completeness or accuracy of these install notes. The most up-to-date notes on a basic -install setup is found through our docker-compose.yml setup we use for development. Please reference it before asking -questions. +Note: We make no guarantee of completeness or accuracy of these install notes. +The most up-to-date notes on a basic install setup is found through our +docker-compose.yml setup we use for development. Please reference it before +asking questions. -Note: If overwhelmed by the these instructions, we urge you to NOT run a tracker in production. Doing such requires -more additional steps not covered here (setting up proxies, tunneling, LUKS encryption, TCP tuning, etc.) that messing +Note: If overwhelmed by the these instructions, we urge you to NOT run a tracker +in production. Doing such requires more additional steps not covered here +(setting up proxies, tunneling, LUKS encryption, TCP tuning, etc.) that messing up would put the privacy / security of both yourself and your users at risk. -1. Install the PHP and JS dependencies to run / setup the site: +The docker installation does all this for you, but in production you need +to do this by hand. + +1. First, install the PHP and JS dependencies to setup and run the site. composer install yarn install -2. First, you will need to setup the following services: +2. Install and setup the following services: * MySQL * memcached * sphinxsearch Depending on your OS, these may be available in the package manager. You can see -what versions of the above we support by looking at our [docker-compose.yml](../docker-compose.yml) +what versions of the above we support by looking at our docker-compose.yml configuration. -For setting up memcached, we recommend giving it multiple threads and several GB of RAM, for example: +3. For up memcached, we recommend giving it multiple threads and several + gigs of RAM, for example: memcached -d -m 5120 -s /var/run/memcached.sock -a 0777 -t4 -C -u nobody -This will give memcached 4 threads and 5GB of RAM. Tune this accordingly depending on how large your server -is, and traffic you get, but a the more RAM you give memcached, the quicker Gazelle will run as it heavily -relies on caching. +This will give memcached 4 threads and 5GB of RAM. Tune this accordingly +depending on how large your server and how many users you have. Look at +your cache eviction. If you are seeing hundreds of items evicted per second, +you need to scale up drastically. If you are seeing zero evictions, you +have allocated too much RAM and should scale down. Ideally you should only +see expired unfetched activity. -For sphinxsearch, we recommend you use the included sphinx.conf which can be found under .docker/sphinxsearch/sphinx.conf. -You can copy this to /etc/sphinx/sphinx.conf. You need to fill in the details of the SQL server though! +4. Create the required Mysql roles according to 01-MysqlRoles.txt + Use www.random.org to generate passwords. -You might also need to create the /var/lib/sphinx folder. +5. Review lib/config.php. Edit lib/config.override.php as needed. + You should be able to launch boris from the command line. -For documentation, read http://www.sphinxsearch.com/docs/current.html - -After you've installed sphinx, create the indices: - - /usr/bin/indexer -c /etc/sphinx/sphinx.conf --all - -3. Configure config variables. First, you will want to copy over the template file ([classes/config.template.php](../classes/config.template.php)) -to `classes/config.php`, and then go through and configure to your needs. See the comments within that file on what you will need to change. - - -4. After configuring the config.php file in the step above (or minimially the SQL* variables), you can use phinx to setup your DB by running: +6. Run the phinx migrations and seeds to populate the database. vendor/bin/phinx migrate -5. Generate stylesheets and their previews by running the following: +7. Configure Sphinx - we recommend you use the included .docker/sphinxsearch/sphinx.conf + You can copy this to /etc/sphinx/sphinx.conf. You need to fill in the + details of the SQL server from lib/config.override.php and you may need to + create the `/var/lib/sphinx` folder. + + More information is available at: https://sphinxsearch.com/docs/current.html + + Run the indexer to finish the setup: + + /usr/bin/indexer -c /etc/sphinx/sphinx.conf --all + +8. Generate stylesheets and their previews by running the following: yarn build -Note, to generate the previews requires a chrome instance to be installed onto the computer. +Note, generating the previews requires a Chrome instance on the host. -6. Setup your web server. We recommend using nginx (https://www.nginx.com/). A sample configuration for nginx can be found in .docker/web/nginx.conf. +9. Setup your web server. We recommend using nginx (https://www.nginx.com/). + A sample configuration for nginx can be found in .docker/web/nginx.conf. -7. Sign up. The first user is made a SysOp! +10. Set up cron jobs. You need a cron job for the scheduler, a cron job for + the peerupdate (all groups are cached, but the peer counts change often, + so peerupdate is a script to update them), and the two Sphinx indices. -8. Set up cron jobs. You need a cron job for the schedule, a cron job for the peerupdate (all groups are cached, but the peer counts change often, -so peerupdate is a script to update them), and the two Sphinx indices. These are our cron jobs. SCHEDULE_KEY is the same as in classes/config.php: + see docs/crontab -0,15,30,45 * * * * /usr/bin/php /var/www/vhosts/what/schedule.php SCHEDULE_KEY >> /root/schedule.log -10,25,40,55 * * * * /usr/bin/php /var/www/vhosts/what/peerupdate.php SCHEDULE_KEY >> /root/peerupdate.log -* * * * * /usr/bin/indexer -c /etc/sphinx/sphinx.conf --rotate delta requests_delta log_delta >/dev/null -5 0,12 * * * /usr/bin/indexer -c /etc/sphinx/sphinx.conf --rotate --all >>/root/sphinx-indexer.log - -An example cron script can be seen in .docker/web/crontab - -9. Start modifying stuff. Hopefully, everything will have gone smoothly so far and nothing will have exploded (ha ha ha) +11. Start modifying stuff. Hopefully, everything will have gone smoothly so far + and nothing will have exploded (ha ha ha) diff --git a/docs/crontab b/docs/crontab new file mode 100644 index 000000000..1bdd008d1 --- /dev/null +++ b/docs/crontab @@ -0,0 +1,7 @@ +# These are our cron jobs. +# Replace SCHEDULE_KEY with the value referenced in lib/config.php / lib/config.override.php + +0,15,30,45 * * * * /usr/bin/php /var/www/scripts/schedule.php SCHEDULE_KEY >> /root/schedule.log +10,25,40,55 * * * * /usr/bin/php /var/www/scripts/peerupdate.php SCHEDULE_KEY >> /root/peerupdate.log +* * * * * /usr/bin/indexer -c /etc/sphinx/sphinx.conf --rotate delta requests_delta log_delta >/dev/null +5 */2 * * * /usr/bin/indexer -c /etc/sphinx/sphinx.conf --rotate --all >>/root/sphinx-indexer.log diff --git a/lib/bootstrap.php b/lib/bootstrap.php index 0b998fe03..d1543e0de 100644 --- a/lib/bootstrap.php +++ b/lib/bootstrap.php @@ -5,7 +5,7 @@ $now = microtime(true); // To track how long a page takes to create if (!defined('SITE_NAME')) { - require_once(__DIR__ . '/../classes/config.php'); + require_once(__DIR__ . '/config.php'); require_once(__DIR__ . '/../lib/util.php'); require_once(__DIR__ . '/../vendor/autoload.php'); } diff --git a/lib/config.devel.example.php b/lib/config.devel.example.php new file mode 100644 index 000000000..f9933f810 --- /dev/null +++ b/lib/config.devel.example.php @@ -0,0 +1,25 @@ + 'memcached', 'port' => 11211, 'buckets' => 1]]); + +define('ENCKEY', ""); +define('SCHEDULE_KEY', ""); +define('RSS_HASH', ""); + +define('SEEDBOX_SALT', ""); +define('AVATAR_SALT', ""); diff --git a/lib/config.php b/lib/config.php new file mode 100644 index 000000000..98bbabd02 --- /dev/null +++ b/lib/config.php @@ -0,0 +1,996 @@ + 'unix:///var/run/memcached.sock', 'port' => 0, 'buckets' => 1], +]); + +// Memcached prefix (if ever you need to run another namespace in the same +// memcached instance). +defined('CACHE_ID') or define('CACHE_ID', 'ops'); + +// ------------------------------------------------------------------------ +// Email settings + +// The DNS name (MX record) of your email hostname. +defined('MAIL_HOST') or define('MAIL_HOST', 'mail.' . SITE_HOST); + +// Set to true in a development environment. Instead of delivery, messages +// will be written to files in TMPDIR. +defined('DEBUG_EMAIL') or define('DEBUG_EMAIL', false); + +// ------------------------------------------------------------------------ +// IRC settings + +defined('DISABLE_IRC') or define('DISABLE_IRC', false); +defined('IRC_SOCKET_LISTEN_ADDRESS') or define('IRC_SOCKET_LISTEN_ADDRESS', 'localhost'); +defined('IRC_SOCKET_LISTEN_PORT') or define('IRC_SOCKET_LISTEN_PORT', 51010); + +defined('BOT_NICK') or define('BOT_NICK', 'Rippy'); +defined('BOT_SERVER') or define('BOT_SERVER', 'localhost'); +defined('BOT_PORT') or define('BOT_PORT', 7000); +defined('BOT_CHAN') or define('BOT_CHAN', '#mygazelle'); +defined('ADMIN_CHAN') or define('ADMIN_CHAN', '#admin'); +defined('LAB_CHAN') or define('LAB_CHAN', '#lab'); +defined('STATUS_CHAN') or define('STATUS_CHAN', '#status'); +defined('MOD_CHAN') or define('MOD_CHAN', '#staff'); +defined('BOT_DISABLED_CHAN') or define('BOT_DISABLED_CHAN', '#blocked'); +defined('BOT_REPORT_CHAN') or define('BOT_REPORT_CHAN', '#reports'); + +// ------------------------------------------------------------------------ +// Push server settings + +defined('PUSH_SOCKET_LISTEN_ADDRESS') or define('PUSH_SOCKET_LISTEN_ADDRESS', 'localhost'); +defined('PUSH_SOCKET_LISTEN_PORT') or define('PUSH_SOCKET_LISTEN_PORT', 6789); + +// ------------------------------------------------------------------------ +// Site settings + +// Leaving these as is will work, but you will probably want to change them +// either in development or production, or both. Any defines that are likely +// to require a change will be listed in the example override files. +// When in doubt, read the source. + +// Display the site logo on the public pages. +defined('SHOW_LOGO') or define('SHOW_LOGO', true); + +// How many enabled users are allowed? (Set to 0 for unlimited). +defined('USER_LIMIT') or define('USER_LIMIT', 5000); + +// Set to false if you want to display the login form directly. +defined('SHOW_PUBLIC_INDEX') or define('SHOW_PUBLIC_INDEX', true); + +// Can J. Random User create their own account? +defined('OPEN_REGISTRATION') or define('OPEN_REGISTRATION', false); + +// Can inactive users enable themselves automatically? +defined('FEATURE_EMAIL_REENABLE') or define('FEATURE_EMAIL_REENABLE', false); + +// Refuse connections from Tor exit nodes? +defined('BLOCK_TOR') or define('BLOCK_TOR', true); + +// Connect to remote resources with curl via a proxy +defined('HTTP_PROXY') or define('HTTP_PROXY', false); + +// Block Opera Mini proxy? +defined('BLOCK_OPERA_MINI') or define('BLOCK_OPERA_MINI', true); + +// Should PHP errors be shown in the output? +defined('DEBUG_MODE') or define('DEBUG_MODE', false); + +// Can developer+ see PHP warnings in the site footer? +defined('DEBUG_WARNINGS') or define('DEBUG_WARNINGS', true); + +// Do upload notifications need to be traced? (Results written to TMPDIR) +defined('DEBUG_UPLOAD_NOTIFICATION') or define('DEBUG_UPLOAD_NOTIFICATION', false); + +// Do contest payouts need to be tested? +// Results are always written to TMPDIR/payout-contest-.txt +// If true, no PMs sent to users, no db updates performed. +defined('DEBUG_CONTEST_PAYOUT') or define('DEBUG_CONTEST_PAYOUT', false); + +// if null, no attempt will be made to contact the last.fm website. +defined('LASTFM_API_KEY') or define('LASTFM_API_KEY', null); + +// Fake useragent (to override default cURL useragent string). +defined('FAKE_USERAGENT') or define('FAKE_USERAGENT', 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.1 Safari/537.11'); + +// How much upload buffer to members start out with? (3 GiB) +defined('STARTING_UPLOAD') or define('STARTING_UPLOAD', 3 * 1024 * 1024 * 1024); + +// Can freeleech (FL) tokens be stacked? +defined('STACKABLE_FREELEECH_TOKENS') or define('STACKABLE_FREELEECH_TOKENS', true); + +// What size does a token represent? (512 MiB) +defined('BYTES_PER_FREELEECH_TOKEN') or define('BYTES_PER_FREELEECH_TOKEN', 512 * 1024 * 1024); + +// How long does an activated token last before it is purged? +defined('FREELEECH_TOKEN_EXPIRY_DAYS') or define('FREELEECH_TOKEN_EXPIRY_DAYS', 30); + +// How much buffer does a request vote represent? +defined('REQUEST_MIN') or define('REQUEST_MIN', 100 * 1024 * 1024); // 100 MiB + +// How much request buffer is removed as tax? (0 = none, 0.1 = 10%, 0.25 = 25% and so on). +defined('REQUEST_TAX') or define('REQUEST_TAX', 0.0); + +// Retain this many days of hourly snapshots. +defined('DELETE_USER_STATS_DAILY_DAY') or define('DELETE_USER_STATS_DAILY_DAY', 15); + +// Retain this many months of daily snapshots. +defined('DELETE_USER_STATS_MONTHLY_DAY') or define('DELETE_USER_STATS_MONTHLY_DAY', 120); + +// How many invites do new users receive? +defined('STARTING_INVITES') or define('STARTING_INVITES', 0); + +// How many invites does a Donor receive? +defined('DONOR_INVITES') or define('DONOR_INVITES', 2); + +// How much fiat currency is required to acquire a donor point +defined('DONOR_RANK_PRICE') or define('DONOR_RANK_PRICE', 10); + +// Minimum permission.Level allowed to purchase invites. +defined('MIN_INVITE_CLASS') or define('MIN_INVITE_CLASS', 150); + +// Lowest permissions.Level of staff user classes +defined('STAFF_LEVEL') or define('STAFF_LEVEL', 820); + +// Threshold for detecting duplicate IP addresses. +defined('IP_OVERLAPS') or define('IP_OVERLAPS', 5); + +// Maximum length of a pathname in torrent files and zip archives. +defined('MAX_PATH_LEN') or define('MAX_PATH_LEN', 200); + +// How many collages to list on a group page when it appears in many collages. +defined('COLLAGE_SAMPLE_THRESHOLD') or define('COLLAGE_SAMPLE_THRESHOLD', 4); + +// How many personal collages to list on a group page when it appears in many collages. +defined('PERSONAL_COLLAGE_SAMPLE_THRESHOLD') or define('PERSONAL_COLLAGE_SAMPLE_THRESHOLD', 4); + +// Number of groups an artist must have to be selected at random. +defined('RANDOM_ARTIST_MIN_ENTRIES') or define('RANDOM_ARTIST_MIN_ENTRIES', 3); + +// Number of entries a collage must have to be selected at random. +defined('RANDOM_COLLAGE_MIN_ENTRIES') or define('RANDOM_COLLAGE_MIN_ENTRIES', 5); + +// Number of seeds a torrent must have to be selected at random. +defined('RANDOM_TORRENT_MIN_SEEDS') or define('RANDOM_TORRENT_MIN_SEEDS', 3); + +// How many torrents can a user delete before they must take a break? +defined('USER_TORRENT_DELETE_MAX') or define('USER_TORRENT_DELETE_MAX', 3); + +// How long a break must a user take if they delete too many torrents? +defined('USER_TORRENT_DELETE_HOURS') or define('USER_TORRENT_DELETE_HOURS', 24); + +// Which image hosts are acceptable and which aren't? +defined('IMAGE_HOST_BANNED') or define('IMAGE_HOST_BANNED', ['badhost.example.com']); +defined('IMAGE_HOST_RECOMMENDED') or define('IMAGE_HOST_RECOMMENDED', ['goodhost.example.com']); + +// What are the relative weights of user percentiles, in order to calculate +// the overall percentile rank. +defined('RANKING_WEIGHT') or define('RANKING_WEIGHT', [ + 'uploaded' => [ 8, 'DataUpload'], + 'downloaded' => [20, 'DataDownload'], + 'uploads' => [25, 'Uploads'], + 'requests' => [10, 'RequestsFilled'], + 'posts' => [ 3, 'ForumPosts'], + 'bounty' => [ 4, 'BountySpent'], + 'artists' => [ 1, 'ArtistsAdded'], + 'collage' => [ 5, 'CollageContribution'], + 'votes' => [ 5, 'ReleaseVotes'], + 'bonus' => [ 6, 'BonusPoints'], + 'comment-t' => [18, 'CommentTorrent'], +]); + +// Successive login failures generate increasing delays. +defined('LOGIN_ATTEMPT_BACKOFF') or define('LOGIN_ATTEMPT_BACKOFF', [ + 0, + 30, + 90, + 60 * 5, // 5 minutes + 60 * 15, + 3600 * 3, // 3 hours + 3600 * 6, + 86400, + 86400 * 3, + 86400 * 7, +]); + +// Set to TagID of 'test' to ignore uploads tagged with 'test' for the +// recent uploads widget. +defined('HOMEPAGE_TAG_IGNORE') or define('HOMEPAGE_TAG_IGNORE', [0]); + +// ------------------------------------------------------------------------ +// Inactivity reaper settings +// +// There are two types of reaping: uploads that are never announced by +// the initial uploader (never seeded), and uploads that were seeded for +// for a while and since then the size of the swarm has dropped to zero +// (unseeded). To eliminate reaping completely, the corresponding +// scheduled tasks should be disabled. +// It is easier to specify the first and second unseeded notifications +// in terms of the interval remaining until reaping. + +define('MAX_NEVER_SEEDED_PER_RUN', 1000); +define('REMOVE_NEVER_SEEDED_HOUR', 72); +define('NOTIFY_NEVER_SEEDED_INITIAL_HOUR', 8); // 8 hours after upload +define('NOTIFY_NEVER_SEEDED_FINAL_HOUR', REMOVE_NEVER_SEEDED_HOUR - 24); + +define('MAX_UNSEEDED_PER_RUN', 1000); +define('REMOVE_UNSEEDED_HOUR', 24 * 28); // 28 days +define('NOTIFY_UNSEEDED_INITIAL_HOUR', REMOVE_UNSEEDED_HOUR - (24 * 10)); +define('NOTIFY_UNSEEDED_FINAL_HOUR', REMOVE_UNSEEDED_HOUR - (24 * 3)); + +// ------------------------------------------------------------------------ +// Source flag settings + +// Source flag for torrent files. Should be unique across the wider tracker +// space to enable easy cross-seeding. +defined('SOURCE') or define('SOURCE', 'OPS'); + +// Acceptable source flag from a prior site. +defined('GRANDFATHER_SOURCE') or define('GRANDFATHER_SOURCE', ''); + +// Epoch time of cut-off for accepting grandfathered source flags. +defined('GRANDFATHER_OLD_SOURCE') or define('GRANDFATHER_OLD_SOURCE', 0); + +// Epoch time of cut-off for accepting torrents with no source flags (useful if you +// introduce source flags after launch). +defined('GRANDFATHER_NO_SOURCE') or define('GRANDFATHER_NO_SOURCE', 0); + +// ------------------------------------------------------------------------ +// Bonus point settings + +// Points awarded for uploads. +defined('BONUS_AWARD_FLAC_PERFECT') or define('BONUS_AWARD_FLAC_PERFECT', 400); +defined('BONUS_AWARD_FLAC') or define('BONUS_AWARD_FLAC', 30); +defined('BONUS_AWARD_MP3') or define('BONUS_AWARD_MP3', 30); +defined('BONUS_AWARD_OTHER') or define('BONUS_AWARD_OTHER', 10); + +// Tax when donating to bonus pools. +defined('BONUS_POOL_TAX_STD') or define('BONUS_POOL_TAX_STD', 0.9); +defined('BONUS_POOL_TAX_ELITE') or define('BONUS_POOL_TAX_ELITE', 0.8); +defined('BONUS_POOL_TAX_TM') or define('BONUS_POOL_TAX_TM', 0.7); +defined('BONUS_POOL_TAX_STAFF') or define('BONUS_POOL_TAX_STAFF', 0.5); + +// ------------------------------------------------------------------------ +// Pagination + +defined('BOOKMARKS_PER_PAGE') or define('BOOKMARKS_PER_PAGE', 20); +defined('COLLAGES_PER_PAGE') or define('COLLAGES_PER_PAGE', 25); +defined('CONTEST_ENTRIES_PER_PAGE') or define('CONTEST_ENTRIES_PER_PAGE', 50); +defined('FRIENDS_PER_PAGE') or define('FRIENDS_PER_PAGE', 20); +defined('INVITES_PER_PAGE') or define('INVITES_PER_PAGE', 50); +defined('ITEMS_PER_PAGE') or define('ITEMS_PER_PAGE', 50); +defined('IPS_PER_PAGE') or define('IPS_PER_PAGE', 50); +defined('LOG_ENTRIES_PER_PAGE') or define('LOG_ENTRIES_PER_PAGE', 50); +defined('MESSAGES_PER_PAGE') or define('MESSAGES_PER_PAGE', 25); +defined('PEERS_PER_PAGE') or define('PEERS_PER_PAGE', 100); +defined('POSTS_PER_PAGE') or define('POSTS_PER_PAGE', 25); +defined('REPORTS_PER_PAGE') or define('REPORTS_PER_PAGE', 10); +defined('REQUESTS_PER_PAGE') or define('REQUESTS_PER_PAGE', 25); +defined('TOPICS_PER_PAGE') or define('TOPICS_PER_PAGE', 50); +defined('TORRENTS_PER_PAGE') or define('TORRENTS_PER_PAGE', 50); +defined('TORRENT_COMMENTS_PER_PAGE') or define('TORRENT_COMMENTS_PER_PAGE', 10); +defined('USERS_PER_PAGE') or define('USERS_PER_PAGE', 50); +defined('WIKI_ARTICLES_PER_PAGE') or define('WIKI_ARTICLES_PER_PAGE', 25); + +defined('AJAX_USERS_PER_PAGE') or define('AJAX_USERS_PER_PAGE', 30); + +// ------------------------------------------------------------------------ +// User Referral settings + +// Can people from approved trackers create their own account? +defined('OPEN_EXTERNAL_REFERRALS') or define('OPEN_EXTERNAL_REFERRALS', false); + +// Where to forward cURL queries for referrals (URL with trailiing slash). +defined('REFERRAL_BOUNCER') or define('REFERRAL_BOUNCER', ''); + +// Symmetric encryption key for bouncer communication. +defined('REFERRAL_KEY') or define('REFERRAL_KEY', hash('sha512', 'sekret')); + +// Should referrals send invitation emails. +defined('REFERRAL_SEND_EMAIL') or define('REFERRAL_SEND_EMAIL', false); + +// Code names of referral sites (must match the db). +defined('REFERRAL_SITES') or define('REFERRAL_SITES', ['ABC', 'DEF']); + +// ------------------------------------------------------------------------ +// Recovery settings + +// Is recovery open? +defined('RECOVERY') or define('RECOVERY', false); + +// Is buffer from the previous site restituted to recovered users? +defined('RECOVERY_BUFFER') or define('RECOVERY_BUFFER', false); + +// Random salt for generating temporary filenames +defined('RECOVERY_SALT') or define('RECOVERY_SALT', 'thisisfine'); + +// Where are uploads for recovery proof stored? +defined('RECOVERY_PATH') or define('RECOVERY_PATH', ''); + +// Highest torrent id from a previous incarnation +defined('MAX_PREV_TORRENT_ID') or define('MAX_PREV_TORRENT_ID', 0); + +// In which database schema are the users of the previous site stored? +defined('RECOVERY_DB') or define('RECOVERY_DB', ''); + +// Which table stores the old/new user mappings? +defined('RECOVERY_MAPPING_TABLE') or define('RECOVERY_MAPPING_TABLE', 'users_' . RECOVERY_DB . '_mapping'); + +// Which table stores proof about prior IRC users? +defined('RECOVERY_IRC_TABLE') or define('RECOVERY_IRC_TABLE', 'users_' . RECOVERY_DB . '_irc'); + +// Are recovery requests that validate correctly automatically accepted? +defined('RECOVERY_AUTOVALIDATE') or define('RECOVERY_AUTOVALIDATE', true); + +// How many validations are performed per scheduled run? +defined('RECOVERY_AUTOVALIDATE_LIMIT') or define('RECOVERY_AUTOVALIDATE_LIMIT', 20); + +// Which user issues recovery invites? +defined('RECOVERY_ADMIN_ID') or define('RECOVERY_ADMIN_ID', SYSTEM_USER_ID); + +// What name is given to the recovery inviter? +defined('RECOVERY_ADMIN_NAME') or define('RECOVERY_ADMIN_NAME', 'RecoveryBot'); + +// How many pending people can be reassigned buffer in a single run? +defined('RECOVERY_BUFFER_REASSIGN_LIMIT') or define('RECOVERY_BUFFER_REASSIGN_LIMIT', 100); + +// Security check to prevent
stuffing +defined('RECOVERY_PAIR_SALT') or define('RECOVERY_PAIR_SALT', 'thisisfine'); + +// ------------------------------------------------------------------------ +// Permission.ID labels + +// Permission ID of primary class. +defined('USER') or define('USER', 2); +defined('MEMBER') or define('MEMBER', 3); +defined('POWER') or define('POWER', 4); +defined('ELITE') or define('ELITE', 5); +defined('TORRENT_MASTER') or define('TORRENT_MASTER', 7); +defined('POWER_TM') or define('POWER_TM', 22); +defined('ELITE_TM') or define('ELITE_TM', 23); +defined('ULTIMATE_TM') or define('ULTIMATE_TM', 48); +defined('FORUM_MOD') or define('FORUM_MOD', 28); +defined('MOD') or define('MOD', 11); +defined('SYSOP') or define('SYSOP', 15); + +// Permission ID of secondary class. +defined('DONOR') or define('DONOR', 20); +defined('FLS_TEAM') or define('FLS_TEAM', 23); +defined('INTERVIEWER') or define('INTERVIEWER', 30); +defined('RECRUITER') or define('RECRUITER', 41); +defined('VIP') or define('VIP', 6); + +// ------------------------------------------------------------------------ +// Well-known forum settings + +// The secret Donor forum. +defined('DONOR_FORUM') or define('DONOR_FORUM', 70); + +// Where Edit Requests are sent. +defined('EDITING_FORUM_ID') or define('EDITING_FORUM_ID', 34); + +// Staff forum (for polls that display the names of voters). +defined('STAFF_FORUM_ID') or define('STAFF_FORUM_ID', 5); + +// Forums where voter names are revealed. +defined('FORUM_REVEAL_VOTER') or define('FORUM_REVEAL_VOTER', []); + +// Where trashed threads go. +defined('TRASH_FORUM_ID') or define('TRASH_FORUM_ID', 4); + +// The Album of the Month (AotM) forum. +defined('AOTM_FORUM_ID') or define('AOTM_FORUM_ID', 51); + +// The Showcase (Vanity House) forum. +defined('VANITY_HOUSE_FORUM_ID') or define('VANITY_HOUSE_FORUM_ID', 18); + +// The client whitelist suggestion forum. +defined('CLIENT_WHITELIST_FORUM_ID') or define('CLIENT_WHITELIST_FORUM_ID', 680); + +// Number of thread posts per cache key. +defined('THREAD_CATALOGUE') or define('THREAD_CATALOGUE', 500); + +// ------------------------------------------------------------------------ +// Well-known Wiki pages + +// The index page (to prevent it from ever being deleted). +defined('INDEX_WIKI_PAGE_ID') or define('INDEX_WIKI_PAGE_ID', 1); + +// The rules page. +defined('RULES_WIKI_PAGE_ID') or define('RULES_WIKI_PAGE_ID', 127); + +// Information about Source Flags. +defined('SOURCE_FLAG_WIKI_PAGE_ID') or define('SOURCE_FLAG_WIKI_PAGE_ID', 113); + +// ------------------------------------------------------------------------ +// None of the settings below here should need to be changed. They are here +// simply to not have them in the code, either because they are magic +// numbers or they are used in more than place. Any changes here will most +// likely require a corresonding change in the code or stylesheets. +// ------------------------------------------------------------------------ + +// Maximum length of a custom user title. +defined('USER_TITLE_LENGTH') or define('USER_TITLE_LENGTH', 1024); + +// Magic constant of locked accounts. +defined('STAFF_LOCKED') or define('STAFF_LOCKED', 1); + +// Width of avatars (as displayed in forums and profile page). +defined('AVATAR_WIDTH') or define('AVATAR_WIDTH', 150); + +// Width of similar artists map. +defined('SIMILAR_WIDTH') or define('SIMILAR_WIDTH', 720); + +// Height of similar artists map. +defined('SIMILAR_HEIGHT') or define('SIMILAR_HEIGHT', 500); + +// Number of columns in the official tags toolbox +defined('TAG_OFFICIAL_COLUMNS') or define('TAG_OFFICIAL_COLUMNS', 4); + +// ------------------------------------------------------------------------ +// Upload configuration + +// Upload categories. +defined('CATEGORY') or define('CATEGORY', [ + 'Music', + 'Applications', + 'E-Books', + 'Audiobooks', + 'E-Learning Videos', + 'Comedy', + 'Comics' +]); +defined('CATEGORY_GROUPED') or define('CATEGORY_GROUPED', array_intersect(['Music'], CATEGORY)); + +// Icons of upload categories. +defined('CATEGORY_ICON') or define('CATEGORY_ICON', [ + 'music.png', + 'apps.png', + 'ebook.png', + 'audiobook.png', + 'elearning.png', + 'comedy.png', + 'comics.png' +]); + +// Allowed upload formats. +defined('FORMAT') or define('FORMAT', [ + 'MP3', + 'FLAC', + 'Ogg Vorbis', + 'AAC', + 'AC3', + 'DTS' +]); + +// Allowed upload encodings. +defined('ENCODING') or define('ENCODING', [ + 'Lossless', + '24bit Lossless', + 'V0 (VBR)', + 'V1 (VBR)', + 'V2 (VBR)', + '320', + '256', + '192', + '160', + '128', + '96', + '64', + 'APS (VBR)', + 'APX (VBR)', + 'q8.x (VBR)', + 'Other' +]); + +// Allowed upload media. +defined('MEDIA') or define('MEDIA', [ + 'CD', + 'WEB', + 'Vinyl', + 'DVD', + 'BD', + 'Soundboard', + 'SACD', + 'DAT', + 'Cassette', +]); + +// ------------------------------------------------------------------------ +// Paranoia + +// Magic constants for paranoia. +defined('PARANOIA_HIDE') or define('PARANOIA_HIDE', 0); +defined('PARANOIA_ALLOWED') or define('PARANOIA_ALLOWED', 1); +defined('PARANOIA_OVERRIDDEN') or define('PARANOIA_OVERRIDDEN', 2); + +// What permissions allow a viewer to override a user's paranoia? +defined('PARANOIA_OVERRIDE') or define('PARANOIA_OVERRIDE', [ + 'downloaded' => 'users_mod', + 'uploaded' => 'users_mod', + 'lastseen' => 'users_mod', + 'ratio' => 'users_mod', + 'requiredratio' => 'users_mod', + 'hide_donor_heart' => 'users_mod', + 'bonuspoints' => 'admin_bp_history', + 'torrentcomments' => 'site_moderate_forums', + 'invitedcount' => 'users_view_invites', + 'snatched' => 'users_view_torrents_snatchlist', + 'snatched+' => 'users_view_torrents_snatchlist', + 'leeching' => 'users_view_seedleech', + 'leeching+' => 'users_view_seedleech', + 'seeding' => 'users_view_seedleech', + 'seeding+' => 'users_view_seedleech', + 'uploads' => 'users_view_seedleech', + 'uploads+' => 'users_view_seedleech', +]); + +// ------------------------------------------------------------------------ +// Artist configuration + +defined('ARTIST_MAIN') or define('ARTIST_MAIN', 1); +defined('ARTIST_GUEST') or define('ARTIST_GUEST', 2); +defined('ARTIST_REMIXER') or define('ARTIST_REMIXER', 3); +defined('ARTIST_COMPOSER') or define('ARTIST_COMPOSER', 4); +defined('ARTIST_CONDUCTOR') or define('ARTIST_CONDUCTOR', 5); +defined('ARTIST_DJ') or define('ARTIST_DJ', 6); +defined('ARTIST_PRODUCER') or define('ARTIST_PRODUCER', 7); +defined('ARTIST_ARRANGER') or define('ARTIST_ARRANGER', 8); +defined('ARTIST_TYPE') or define('ARTIST_TYPE', [ + ARTIST_MAIN => 'Main', + ARTIST_GUEST => 'Guest', + ARTIST_REMIXER => 'Remixer', + ARTIST_COMPOSER => 'Composer', + ARTIST_CONDUCTOR => 'Conductor', + ARTIST_DJ => 'DJ/Compiler', + ARTIST_PRODUCER => 'Producer', + ARTIST_ARRANGER => 'Arranger', +]); +defined('ARTIST_SECTION_ARRANGER') or define('ARTIST_SECTION_ARRANGER', 1020); +defined('ARTIST_SECTION_PRODUCER') or define('ARTIST_SECTION_PRODUCER', 1021); +defined('ARTIST_SECTION_COMPOSER') or define('ARTIST_SECTION_COMPOSER', 1022); +defined('ARTIST_SECTION_REMIXER') or define('ARTIST_SECTION_REMIXER', 1023); +defined('ARTIST_SECTION_GUEST') or define('ARTIST_SECTION_GUEST', 1024); + +// ------------------------------------------------------------------------ +// Collage configuration + +defined('COLLAGE') or define('COLLAGE', [ + 0 => 'Personal', + 1 => 'Theme', + 2 => 'Genre Introduction', + 3 => 'Discography', + 4 => 'Label', + 5 => 'Staff picks', + 6 => 'Charts', + 7 => 'Artists', + 8 => 'Awards', + 9 => 'Series', +]); +defined('COLLAGE_PERSONAL_ID') or define('COLLAGE_PERSONAL_ID', 0); +defined('COLLAGE_ARTISTS_ID') or define('COLLAGE_ARTISTS_ID', 7); + +// ------------------------------------------------------------------------ +// Donor configuration. Any changes here will need to be reflected in the +// wiki documentation. + +defined('RANK_ONE_COST') or define('RANK_ONE_COST', 5); +defined('RANK_TWO_COST') or define('RANK_TWO_COST', 10); +defined('RANK_THREE_COST') or define('RANK_THREE_COST', 15); +defined('RANK_FOUR_COST') or define('RANK_FOUR_COST', 20); +defined('RANK_FIVE_COST') or define('RANK_FIVE_COST', 30); +defined('MAX_RANK') or define('MAX_RANK', 6); +defined('MAX_EXTRA_RANK') or define('MAX_EXTRA_RANK', 8); +defined('DONOR_FORUM_RANK') or define('DONOR_FORUM_RANK', 6); +defined('MAX_SPECIAL_RANK') or define('MAX_SPECIAL_RANK', 3); + +// ------------------------------------------------------------------------ +// Cache settings + +// Grant cache access to specific keys based on site permission +defined('CACHE_PERMISSION') or define('CACHE_PERMISSION', [ + 'api_apps' => 'site_debug', + 'catalogue' => 'site_debug', +]); + +defined('CACHE_BULK_FLUSH') or define('CACHE_BULK_FLUSH', 500); + +defined('CACHE_RESPONSE') or define('CACHE_RESPONSE', [ + 0 => 'success', + 1 => 'failure/delete ok', + 16 => 'not found', +]); + +defined('CACHE_DB') or define('CACHE_DB', [ + 'artist' => ['table' => 'artists_group', 'pk' => 'ArtistID'], + 'collage' => ['table' => 'collages', 'pk' => 'ID'], + 'torrent' => ['table' => 'torrents', 'pk' => 'ID'], + 'torrent-group' => ['table' => 'torrents_group', 'pk' => 'ID'], + 'user' => ['table' => 'users_main', 'pk' => 'ID'], +]); + +defined('CACHE_NAMESPACE') or define('CACHE_NAMESPACE', [ + 'artist' => [ + 'a1' => 'artist_%d', + 'a2' => 'artist_comments_%d', + 'a3' => 'artist_comments_%d_catalogue_0', + 'a4' => 'artist_groups_%d', + 'a5' => 'artists_collages_%d', + 'a6' => 'artists_requests_%d', + 'a7' => 'similar_positions_%d', + ], + 'collage' => [ + 'c1' => 'collage_%d', + 'c2' => 'collage_display_%d', + 'c3' => 'collage_subs_user_%d', + 'c4' => 'collage_subs_user_new_%d', + ], + 'torrent-group' => [ + 'g1' => 'torrents_collages_%d', + 'g2' => 'torrent_collages_personal_%d', + 'g3' => 'torrents_cover_art_%d', + 'g4' => 'torrents_details_%d', + 'g5' => 'torrent_group_%d', + 'g6' => 'torrent_group_light_%d', + 'g7' => 'groups_artists_%d', + 'g8' => 'tg_%d', + 'g9' => 'tlist_%d', + ], + 'torrent' => [ + 't1' => 't2_%d', + ], + 'user' => [ + 'u1' => 'bookmarks_group_ids_%d', + 'u2' => 'donor_info_%d', + 'u3' => 'inbox_new_%d', + 'u4' => 'u_%d', + 'u5' => 'user_info_%d', + 'u6' => 'user_info_heavy_%d', + 'u7' => 'user_stats_%d', + 'u8' => 'user_statgraphs_%d', + 'u9' => 'user_tokens_%d', + ], +]); + +// ------------------------------------------------------------------------ +// Common regexp patterns + +defined('IP_REGEXP') or define('IP_REGEXP', '/\b(?:\d{1,3}\.){3}\d{1,3}\b/'); +defined('URL_REGEXP_STEM') or define('URL_REGEXP_STEM', '((?:f|ht)tps?:\/\/)(?:' . str_replace('/', '', IP_REGEXP) . '|[\w-]+(?:\.[\w-]+)+)(?::\d{1,5})?(?:\/\S*)'); +defined('URL_REGEXP') or define('URL_REGEXP', '/^' . URL_REGEXP_STEM . '$/i'); +defined('CSS_REGEXP') or define('CSS_REGEXP', '/^' . URL_REGEXP_STEM . '\.css(?:\?\S*)$/i'); +defined('IMAGE_REGEXP') or define('IMAGE_REGEXP', '/\b(' . URL_REGEXP_STEM . '\.(?:gif|png|webm|jpe?g|tiff?)(\?\S*)?)\b/i'); +defined('SITELINK_REGEXP') or define('SITELINK_REGEXP', '(?:' . preg_quote(SITE_URL, '/') . (defined('ALT_SITE_URL') ? '|' . preg_quote(ALT_SITE_URL, '/') : '') . ')'); +defined('ARTIST_REGEXP') or define('ARTIST_REGEXP', '/^' . SITELINK_REGEXP . '\/artist\.php\?.*?\bid=(?P\d+)$/'); +defined('TGROUP_REGEXP') or define('TGROUP_REGEXP', '/^' . SITELINK_REGEXP . '\/torrents\.php\?.*?\bid=(?P\d+)\b/'); +defined('TORRENT_REGEXP') or define('TORRENT_REGEXP', '/^' . SITELINK_REGEXP . '\/torrents\.php\?.*?\btorrentid=(?P\d+)\b/'); +defined('EMAIL_REGEXP') or define('EMAIL_REGEXP', '/^[\w-]+(?:\.[\w-]+)*(?:\+[.\w-]+)?@[\w-]+(?:\.[\w-]+)+$/'); +defined('USERNAME_REGEXP') or define('USERNAME_REGEXP', '/\b(?:[01]$(*PRUNE)(*FAIL)|(?P[\w.]{1,20}))\b/'); + +// ------------------------------------------------------------------------ +// Common icons (emoji) + +defined('ICON_ALL') or define('ICON_ALL', "\xe2\x9c\x85"); +defined('ICON_NONE') or define('ICON_NONE', "\xf0\x9f\x9a\xab"); +defined('ICON_TOGGLE') or define('ICON_TOGGLE', "\xf0\x9f\x94\x81"); +defined('ICON_PADLOCK') or define('ICON_PADLOCK', "\xF0\x9F\x94\x92"); +defined('ICON_STAR') or define('ICON_STAR', "\xE2\x98\x85"); +defined('ICON_BLACK_SQUARE') or define('ICON_BLACK_SQUARE', "\xE2\x96\xA0"); +defined('ICON_WHITE_SQUARE') or define('ICON_WHITE_SQUARE', "\xE2\x96\xA1"); + +// ------------------------------------------------------------------------ +// Collector settings + +defined('ZIP_GROUP') or define('ZIP_GROUP', [ + 0 => 'MP3 (VBR) - High Quality', + 1 => 'MP3 (VBR) - Low Quality', + 2 => 'MP3 (CBR)', + 3 => 'FLAC - Lossless', + 4 => 'Others', +]); +defined('ZIP_OPTION') or define('ZIP_OPTION', [ + '00' => [0, 0, 'V0'], + '01' => [0, 1, 'APX'], + '02' => [0, 2, '256'], + '03' => [0, 3, 'V1'], + '10' => [1, 0, '224'], + '11' => [1, 1, 'V2'], + '12' => [1, 2, 'APS'], + '13' => [1, 3, '192'], + '20' => [2, 0, '320'], + '21' => [2, 1, '256'], + '22' => [2, 2, '224'], + '23' => [2, 3, '192'], + '24' => [2, 4, '160'], + '25' => [2, 5, '128'], + '26' => [2, 6, '96'], + '27' => [2, 7, '64'], + '30' => [3, 0, 'FLAC / 24bit / Vinyl'], + '31' => [3, 1, 'FLAC / 24bit / DVD'], + '32' => [3, 2, 'FLAC / 24bit / SACD'], + '33' => [3, 3, 'FLAC / 24bit / WEB'], + '34' => [3, 4, 'FLAC / Log (100) / Cue'], + '35' => [3, 5, 'FLAC / Log (100)'], + '36' => [3, 6, 'FLAC / Log'], + '37' => [3, 7, 'FLAC / WEB'], + '38' => [3, 8, 'FLAC'], + '40' => [4, 0, 'DTS'], + '42' => [4, 2, 'AAC - 320'], + '43' => [4, 3, 'AAC - 256'], + '44' => [4, 4, 'AAC - q5.5'], + '45' => [4, 5, 'AAC - q5'], + '46' => [4, 6, 'AAC - 192'], +]); + +// ------------------------------------------------------------------------ +// Captcha settings + +defined('CAPTCHA_FONT') or define('CAPTCHA_FONT', [ + 'ARIBLK.TTF', + 'IMPACT.TTF', + 'TREBUC.TTF', + 'TREBUCBD.TTF', + 'TREBUCBI.TTF', + 'TREBUCIT.TTF', + 'VERDANA.TTF', + 'VERDANAB.TTF', + 'VERDANAI.TTF', + 'VERDANAZ.TTF', +]); +defined('CAPTCHA_BG') or define('CAPTCHA_BG', [ + 'captcha1.png', + 'captcha2.png', + 'captcha3.png', + 'captcha4.png', + 'captcha5.png', + 'captcha6.png', + 'captcha7.png', + 'captcha8.png', + 'captcha9.png', +]); + +// ------------------------------------------------------------------------ +// Opera Turbo (may include Opera-owned IP addresses that aren't used for Turbo, but shouldn't run much risk of exploitation) +// Useful: http://www.robtex.com/cnet/ + +defined('ALLOWED_PROXY') or define('ALLOWED_PROXY', [ + '64.255.180.*', //Norway + '64.255.164.*', //Norway + '80.239.242.*', //Poland + '80.239.243.*', //Poland + '91.203.96.*', //Norway + '94.246.126.*', //Norway + '94.246.127.*', //Norway + '195.189.142.*', //Norway + '195.189.143.*', //Norway +]); diff --git a/lib/config.production.example.php b/lib/config.production.example.php new file mode 100644 index 000000000..2aa53da9d --- /dev/null +++ b/lib/config.production.example.php @@ -0,0 +1,52 @@ +UseSSL = (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443); diff --git a/public/opensearch.php b/public/opensearch.php index 42c4334ac..d4a17bf9b 100644 --- a/public/opensearch.php +++ b/public/opensearch.php @@ -2,7 +2,7 @@ header('Content-type: application/opensearchdescription+xml'); -require_once(__DIR__ . '/../lib/bootstrap.php'); +require_once(__DIR__ . '/../lib/config.php'); $Type = in_array(($_GET['type'] ?? ''), ['torrents','artists','requests','forums','users','wiki','log']) ? $_GET['type'] diff --git a/scripts/getconf b/scripts/getconf index 4113a376f..5977fcc65 100755 --- a/scripts/getconf +++ b/scripts/getconf @@ -14,7 +14,7 @@ * try it :) */ -require_once(__DIR__ . '/../classes/config.php'); +require_once(__DIR__ . '/../lib/config.php'); array_shift($argv); $multi = count($argv) > 1; diff --git a/scripts/regen-filelists.php b/scripts/regen-filelists.php index fa522fd24..5bac859a1 100644 --- a/scripts/regen-filelists.php +++ b/scripts/regen-filelists.php @@ -1,6 +1,7 @@ disableLocalCache(); $torMan = new Gazelle\Manager\Torrent; $max = $DB->scalar("SELECT max(ID) FROM torrents"); diff --git a/scripts/upload-wiki.php b/scripts/upload-wiki.php index cf0c4eb76..c1d0371d1 100644 --- a/scripts/upload-wiki.php +++ b/scripts/upload-wiki.php @@ -4,10 +4,6 @@ require_once(__DIR__ . '/../lib/bootstrap.php'); -use Gazelle\Util\Crypto; - -set_include_path(SERVER_ROOT); - $in = fopen($argv[1], 'r'); $row = fgets($in);