4 Commits

Author SHA1 Message Date
  biotorrents 72cb2e0792 Add OPS's prepared_query() SQL method 4 years ago
  biotorrents 63fe3124b5 Further integrate Skeleton and fix a large swath of minor bugs 4 years ago
  biotorrents 1530171f7b Add Skeleton CSS support, mostly 4 years ago
  biotorrents f397d945f4 Add $ENV->convert, update readme and config template, add more Twig templates, etc. 4 years ago
84 changed files with 1825 additions and 3003 deletions
  1. 1
    0
      .gitignore
  2. 5
    16
      classes/autoload.php
  3. 0
    63
      classes/charts.class.php
  4. 32
    24
      classes/config.template.php
  5. 46
    39
      classes/env.class.php
  6. 0
    44
      classes/input.class.php
  7. 34
    8
      classes/mysql.class.php
  8. 26
    6
      classes/security.class.php
  9. 0
    360
      classes/seqhash.class.php
  10. 67
    63
      classes/torrent_form.class.php
  11. 6
    3
      classes/twig.class.php
  12. 11
    3
      classes/util.php
  13. 17
    15
      composer.json
  14. 178
    38
      composer.lock
  15. 1
    1
      design/privatefooter.php
  16. 1
    0
      design/privateheader.php
  17. 1
    0
      design/publicfooter.php
  18. 4
    1
      design/publicheader.php
  19. 1
    1
      design/views/generic/reply/quickreply.php
  20. 1
    1
      design/views/generic/reply/staffpm.php
  21. 39
    20
      readme.md
  22. 22
    4
      sections/api/autofill/doi.php
  23. 1
    0
      sections/api/index.php
  24. 4
    4
      sections/better/better.php
  25. 3
    3
      sections/better/index.php
  26. 24
    25
      sections/better/literature.php
  27. 9
    9
      sections/better/single.php
  28. 15
    13
      sections/bookmarks/torrents.php
  29. 2
    2
      sections/collages/browse.php
  30. 2
    2
      sections/collages/edit.php
  31. 1
    1
      sections/collages/new.php
  32. 6
    11
      sections/collages/torrent_collage.php
  33. 113
    64
      sections/comments/comments.php
  34. 11
    2
      sections/comments/index.php
  35. 15
    1
      sections/donate/donate.php
  36. 2
    2
      sections/forums/newthread.php
  37. 47
    36
      sections/friends/friends.php
  38. 7
    2
      sections/inbox/inbox.php
  39. 25
    7
      sections/login/login.php
  40. 14
    11
      sections/login/recover_step2.php
  41. 2
    1
      sections/register/step1.php
  42. 12
    11
      sections/reportsv2/report.php
  43. 3
    4
      sections/reportsv2/takereport.php
  44. 2
    2
      sections/requests/new_edit.php
  45. 7
    7
      sections/requests/request.php
  46. 19
    19
      sections/requests/requests.php
  47. 1
    1
      sections/rules/clients.php
  48. 9
    9
      sections/tools/tools.php
  49. 1
    1
      sections/top10/donors.php
  50. 1
    1
      sections/top10/tags.php
  51. 1
    1
      sections/top10/torrents.php
  52. 1
    1
      sections/top10/users.php
  53. 13
    5
      sections/torrents/browse.php
  54. 10
    10
      sections/torrents/details.php
  55. 78
    78
      sections/torrents/user.php
  56. 2
    2
      sections/upload/index.php
  57. 21
    17
      sections/user/notify_edit.php
  58. 2
    2
      sections/user/user.php
  59. 59
    55
      sections/userhistory/subscriptions.php
  60. 1
    1
      sections/wiki/article.php
  61. 1
    1
      sections/wiki/wiki_browse.php
  62. BIN
      static/common/logos/torrents.bio.png
  63. 254
    217
      static/functions/upload.js
  64. 0
    23
      static/functions/vendor/biojs/cytoscape.js
  65. 0
    1335
      static/functions/vendor/biojs/ntseq.js
  66. 30
    72
      static/styles/bookish/scss/colors.scss
  67. 11
    2
      static/styles/bookish/scss/fonts.scss
  68. 20
    72
      static/styles/bookish/scss/layout.scss
  69. 11
    10
      static/styles/bookish/scss/menus.scss
  70. 65
    76
      static/styles/bookish/scss/tables.scss
  71. 1
    0
      static/styles/global/global.scss
  72. 1
    1
      static/styles/global/scss/debug.scss
  73. 0
    1
      static/styles/global/scss/fonts.scss
  74. 28
    0
      static/styles/global/scss/layout.scss
  75. 20
    0
      static/styles/global/scss/legacy.scss
  76. 162
    0
      static/styles/global/scss/skeleton-fixes.scss
  77. 19
    9
      static/styles/public/scss/public.scss
  78. 24
    0
      templates/input/passphrase.html
  79. 14
    0
      templates/torrent_form/mirrors.html
  80. 16
    0
      templates/torrent_form/picture.html
  81. 54
    0
      templates/torrent_form/seqhash.html
  82. 2
    2
      templates/torrent_form/version.html
  83. 53
    0
      templates/wiki/browse.html
  84. 0
    49
      templates/wiki/browse.twig

+ 1
- 0
.gitignore View File

33
 /static/common/badges/**
33
 /static/common/badges/**
34
 /static/styles/**/*.css
34
 /static/styles/**/*.css
35
 /static/styles/assets/fonts/**
35
 /static/styles/assets/fonts/**
36
+fonts.tgz

+ 5
- 16
classes/autoload.php View File

11
  * @see https://www.php.net/manual/en/language.oop5.autoload.php
11
  * @see https://www.php.net/manual/en/language.oop5.autoload.php
12
  */
12
  */
13
 spl_autoload_register(function ($ClassName) {
13
 spl_autoload_register(function ($ClassName) {
14
-    $FilePath = SERVER_ROOT . '/classes/' . strtolower($ClassName) . '.class.php';
15
-    #$FilePath = $_SERVER['DOCUMENT_ROOT'] . '/classes/' . strtolower($ClassName) . '.class.php';
14
+  $ENV = ENV::go();
15
+
16
+  $classname = strtolower($ClassName);
17
+    $FilePath = "$ENV->SERVER_ROOT/classes/$classname.class.php";
16
 
18
 
17
     if (!file_exists($FilePath)) {
19
     if (!file_exists($FilePath)) {
18
         // todo: Rename the following classes to conform with the code guidelines
20
         // todo: Rename the following classes to conform with the code guidelines
43
           $FileName = 'env.class';
45
           $FileName = 'env.class';
44
           break;
46
           break;
45
 
47
 
46
-        case 'Parsedown':
47
-          $FileName = 'vendor/Parsedown';
48
-          break;
49
-
50
-        case 'ParsedownExtra':
51
-          $FileName = 'vendor/ParsedownExtra';
52
-          break;
53
-
54
-        case 'TwitterAPIExchange':
55
-          $FileName = 'vendor/TwitterAPIExchange';
56
-          break;
57
-
58
         default:
48
         default:
59
           error("Couldn't import class $ClassName");
49
           error("Couldn't import class $ClassName");
60
     }
50
     }
61
 
51
 
62
-        $FilePath = SERVER_ROOT . "/classes/$FileName.php";
63
-        #$FilePath = $_SERVER['DOCUMENT_ROOT'] . "/classes/$FileName.php";
52
+        $FilePath = "$ENV->SERVER_ROOT/classes/$FileName.php";
64
     }
53
     }
65
 
54
 
66
     require_once $FilePath;
55
     require_once $FilePath;

+ 0
- 63
classes/charts.class.php View File

168
         $this->URL .= "&chl=".implode('|', $Labels).'&chd=e:'.implode('', $Data);
168
         $this->URL .= "&chl=".implode('|', $Labels).'&chd=e:'.implode('', $Data);
169
     }
169
     }
170
 }
170
 }
171
-
172
-/*
173
-class LOG_BAR_GRAPH extends GOOGLE_CHARTS
174
-{
175
-    // todo: Finish
176
-    public function __construct($Base, $Width, $Height, $Options = [])
177
-    {
178
-        parent::__construct('lc', $Width, $Height, $Options);
179
-    }
180
-
181
-    public function color($Color)
182
-    {
183
-        $this->URL .= '&chco='.$Color.'&chm=B,'.$Color.'50,0,0,0';
184
-    }
185
-
186
-    public function generate()
187
-    {
188
-        $Max = max($this->Data);
189
-        $Min = ((isset($this->Options['Break'])) ? $Min = min($this->Data) : 0);
190
-        $Data = [];
191
-
192
-        foreach ($this->Data as $Value) {
193
-            $Data[] = $this->encode((($Value - $Min) / ($Max - $Min)) * 4095);
194
-        }
195
-        $this->URL .= "&chxt=y,x&chxs=0,h&chxl=1:|".implode('|', $this->Labels).'&chxr=0,'.$Min.','.($Max-$Min).'&chd=e:'.implode('', $Data);
196
-    }
197
-}
198
-*/
199
-
200
-/*
201
-class POLL_GRAPH extends GOOGLE_CHARTS
202
-{
203
-    public function __construct()
204
-    {
205
-        $this->URL .= '?cht=bhg';
206
-    }
207
-
208
-    public function add($Label, $Data)
209
-    {
210
-        if ($Label !== false) {
211
-            $this->Labels[] = Format::cut_string($Label, 35);
212
-        }
213
-        $this->Data[] = $Data;
214
-    }
215
-
216
-    public function generate()
217
-    {
218
-        $Count = count($this->Data);
219
-        $Height = (30 * $Count) + 20;
220
-        $Max = max($this->Data);
221
-        $Sum = array_sum($this->Data);
222
-        $Increment = ($Max / $Sum) * 25; // * 100% / 4divisions
223
-        $Data = [];
224
-        $Labels = [];
225
-
226
-        foreach ($this->Data as $Key => $Value) {
227
-            $Data[] = $this->encode(($Value / $Max) * 4095);
228
-            $Labels[] = '@t'.str_replace(array(' ', ','), array('+', '\,'), $this->Labels[$Key]).',000000,1,'.round((($Key + 1) / $Count) - (12 / $Height), 2).':0,12';
229
-        }
230
-        $this->URL .= "&chbh=25,0,5&chs=214x$Height&chl=0%|".round($Increment, 1)."%|".round($Increment * 2, 1)."%|".round($Increment * 3, 1)."%|".round($Increment * 4, 1)."%&chm=".implode('|', $Labels).'&chd=e:'.implode('', $Data);
231
-    }
232
-}
233
-*/

+ 32
- 24
classes/config.template.php View File

1
+
1
 <?php
2
 <?php
2
 declare(strict_types=1);
3
 declare(strict_types=1);
3
 
4
 
19
  *   $LongArray = [];
20
  *   $LongArray = [];
20
  *   ENV::setPub(
21
  *   ENV::setPub(
21
  *     'CONFIG',
22
  *     'CONFIG',
22
- *     new RecursiveArrayObject($LongArray)
23
+ *     $ENV->convert($LongArray)
23
  *   );
24
  *   );
24
  *
25
  *
25
  *   $ENV = ENV::go();
26
  *   $ENV = ENV::go();
32
  *
33
  *
33
  *   var_dump(
34
  *   var_dump(
34
  *     $ENV->dedupe(
35
  *     $ENV->dedupe(
35
- *       $ENV->CATS->SEQ->Platforms,
36
- *       $ENV->CATS->IMG->Platforms->toArray(),
37
- *       [$MapVectorFormats, $MapRasterFormats, $PlainFormats]
36
+ *       $ENV->META->Formats->Sequences,
37
+ *       $ENV->META->Formats->Proteins->toArray()
38
  *     )
38
  *     )
39
  *   );
39
  *   );
40
  */
40
  */
42
 # Initialize
42
 # Initialize
43
 require_once 'env.class.php';
43
 require_once 'env.class.php';
44
 $ENV = ENV::go();
44
 $ENV = ENV::go();
45
+
46
+# Basic info
45
 ENV::setPub('PHP_MIN', '7.4.0');
47
 ENV::setPub('PHP_MIN', '7.4.0');
46
 ENV::setPub('DEV', true);
48
 ENV::setPub('DEV', true);
47
 
49
 
132
 ];
134
 ];
133
 ENV::setPub(
135
 ENV::setPub(
134
     'HELP',
136
     'HELP',
135
-    new RecursiveArrayObject($TechSupport)
137
+    $ENV->convert($TechSupport)
136
 );
138
 );
137
 
139
 
138
 
140
 
180
 #ENV::setPriv('SQLSOCK', '/var/run/mysqld/mysqld.sock');
182
 #ENV::setPriv('SQLSOCK', '/var/run/mysqld/mysqld.sock');
181
 
183
 
182
 # TLS client certs
184
 # TLS client certs
183
-ENV::setPriv('SQL_CERT', "/var/www/sql-keys/client-cert.pem");
184
-ENV::setPriv('SQL_KEY', "/var/www/sql-keys/client-key.pem");
185
-ENV::setPriv('SQL_CA', "/var/www/sql-keys/ca.pem");
185
+ENV::setPriv('SQL_CERT', "$ENV->WEB_ROOT/sql-keys/client-cert.pem");
186
+ENV::setPriv('SQL_KEY', "$ENV->WEB_ROOT/sql-keys/client-key.pem");
187
+ENV::setPriv('SQL_CA', "$ENV->WEB_ROOT/sql-keys/ca.pem");
186
 
188
 
187
  # Production
189
  # Production
188
  if (!$ENV->DEV) {
190
  if (!$ENV->DEV) {
251
     ];
253
     ];
252
     ENV::setPub(
254
     ENV::setPub(
253
         'ANNOUNCE_URLS',
255
         'ANNOUNCE_URLS',
254
-        new RecursiveArrayObject($AnnounceURLs)
256
+        $ENV->convert($AnnounceURLs)
255
     );
257
     );
256
 }
258
 }
257
 
259
 
270
     ];
272
     ];
271
     ENV::setPub(
273
     ENV::setPub(
272
         'ANNOUNCE_URLS',
274
         'ANNOUNCE_URLS',
273
-        new RecursiveArrayObject($AnnounceURLs)
275
+        $ENV->convert($AnnounceURLs)
274
     );
276
     );
275
 }
277
 }
276
 
278
 
378
 # (should only be used for initial setup)
380
 # (should only be used for initial setup)
379
 ENV::setPub('FEATURE_SET_ENC_KEY_PUBLIC', false);
381
 ENV::setPub('FEATURE_SET_ENC_KEY_PUBLIC', false);
380
 
382
 
383
+# Attempt to support the Seqhash algorithm
384
+# https://blog.libredna.org/post/seqhash/
385
+ENV::setPub('FEATURE_BIOPHP', true);
386
+
381
 
387
 
382
 /**
388
 /**
383
  * Settings
389
  * Settings
592
 ];
598
 ];
593
 ENV::setPub(
599
 ENV::setPub(
594
     'AUTOMATED_BADGE_IDS',
600
     'AUTOMATED_BADGE_IDS',
595
-    new RecursiveArrayObject($AutomatedBadgeIDs)
601
+    $ENV->convert($AutomatedBadgeIDs)
596
 );
602
 );
597
 
603
 
598
 
604
 
822
     'picture' => ['name' => 'Picture', 'desc' => 'A meaningful picture, e.g., the specimen or a thumbnail'],
828
     'picture' => ['name' => 'Picture', 'desc' => 'A meaningful picture, e.g., the specimen or a thumbnail'],
823
 
829
 
824
     # From the non-renamed `torrents` table
830
     # From the non-renamed `torrents` table
825
-    'version' => ['name' => 'Version', 'desc' => 'Start with 0.1.0', 'note' => 'Please see <a href="https://semver.org target=" _blank">Semantic Versioning</a>'],
831
+    'version' => ['name' => 'Version', 'desc' => 'Start with 0.1.0', 'note' => 'Please see <a href="https://semver.org" target="_blank">Semantic Versioning</a>'],
832
+    'license' => ['name' => 'License', 'desc' => '', 'note' => 'Please see <a href="http://www.dcc.ac.uk/resources/how-guides/license-research-data" target="_blank">How to License Research Data</a>'],
833
+    'mirrors' => ['name' => 'Mirrors', 'desc' => 'Up to two FTP/HTTP addresses that either point directly to a file, or for multi-file torrents, to the enclosing folder'],
826
 ];
834
 ];
827
 ENV::setPub(
835
 ENV::setPub(
828
     'DB',
836
     'DB',
829
-    new RecursiveArrayObject($DB)
837
+    $ENV->convert($DB)
830
 );
838
 );
831
 
839
 
832
 
840
 
947
             'Binary',
955
             'Binary',
948
             'Text',
956
             'Text',
949
         ],
957
         ],
950
-    ], # End $this->META->Platforms
958
+    ], # End $ENV->META->Platforms
951
 
959
 
952
     /**
960
     /**
953
      * 1.
961
      * 1.
1172
             'Jupyter'      => ['ipynb'],
1180
             'Jupyter'      => ['ipynb'],
1173
             'Ontology'     => ['cgif', 'cl', 'clif', 'csv', 'htm', 'html', 'kif', 'obo', 'owl', 'rdf', 'rdfa', 'rdfs', 'rif', 'tsv', 'xcl', 'xht', 'xhtml', 'xml'],
1181
             'Ontology'     => ['cgif', 'cl', 'clif', 'csv', 'htm', 'html', 'kif', 'obo', 'owl', 'rdf', 'rdfa', 'rdfs', 'rif', 'tsv', 'xcl', 'xht', 'xhtml', 'xml'],
1174
         ],
1182
         ],
1175
-    ], # End $this->META->Formats
1183
+    ], # End $ENV->META->Formats
1176
 
1184
 
1177
 
1185
 
1178
     /**
1186
     /**
1268
             'Velocity',
1276
             'Velocity',
1269
             'Weight',
1277
             'Weight',
1270
         ],
1278
         ],
1271
-    ], # End $this->META->Scopes
1279
+    ], # End $ENV->META->Scopes
1272
 
1280
 
1273
     /**
1281
     /**
1274
      * 1.
1282
      * 1.
1294
         'OpenMTA',
1302
         'OpenMTA',
1295
         'Public Domain',
1303
         'Public Domain',
1296
         'Unspecified',
1304
         'Unspecified',
1297
-    ], # End $this->META->Licenses
1305
+    ], # End $ENV->META->Licenses
1298
 ];
1306
 ];
1299
 ENV::setPub(
1307
 ENV::setPub(
1300
     'META',
1308
     'META',
1301
-    new RecursiveArrayObject($META)
1309
+    $ENV->convert($META)
1302
 );
1310
 );
1303
 
1311
 
1304
 
1312
 
1322
         'Icon' => "$CatIcons/sequences.png",
1330
         'Icon' => "$CatIcons/sequences.png",
1323
         'Description' => "For data that's ACGT, ACGU, amino acid letters on disk.",
1331
         'Description' => "For data that's ACGT, ACGU, amino acid letters on disk.",
1324
         'Platforms' => $ENV->META->Platforms->Sequences,
1332
         'Platforms' => $ENV->META->Platforms->Sequences,
1325
-        'Formats' => [
1326
-            $ENV->META->Formats->Sequences,
1327
-            $ENV->META->Formats->Proteins,
1328
-            $ENV->META->Formats->Plain,
1333
+        'Formats' => array_merge([
1329
             /*
1334
             /*
1330
             'Sequences' => $ENV->META->Formats->Sequences,
1335
             'Sequences' => $ENV->META->Formats->Sequences,
1331
             'Proteins' => $ENV->META->Formats->Proteins,
1336
             'Proteins' => $ENV->META->Formats->Proteins,
1332
             'Plain' => $ENV->META->Formats->Plain,
1337
             'Plain' => $ENV->META->Formats->Plain,
1333
             */
1338
             */
1334
-        ],
1339
+            $ENV->META->Formats->Sequences,
1340
+            $ENV->META->Formats->Proteins,
1341
+            $ENV->META->Formats->Plain,
1342
+        ]),
1335
     ],
1343
     ],
1336
 
1344
 
1337
     2 => [
1345
     2 => [
1481
 ];
1489
 ];
1482
 ENV::setPub(
1490
 ENV::setPub(
1483
     'CATS',
1491
     'CATS',
1484
-    new RecursiveArrayObject($CATS)
1492
+    $ENV->convert($CATS)
1485
 );
1493
 );
1486
 
1494
 
1487
 
1495
 

+ 46
- 39
classes/env.class.php View File

43
     # Prevents multiple instances
43
     # Prevents multiple instances
44
     public function __clone()
44
     public function __clone()
45
     {
45
     {
46
-        return trigger_error(
47
-            'clone() not allowed',
48
-            E_USER_ERROR
49
-        );
46
+        return error('clone() not allowed.');
50
     }
47
     }
51
 
48
 
52
     # Prevents unserializing
49
     # Prevents unserializing
53
     public function __wakeup()
50
     public function __wakeup()
54
     {
51
     {
55
-        return trigger_error(
56
-            'wakeup() not allowed',
57
-            E_USER_ERROR
58
-        );
52
+        return error('wakeup() not allowed.');
59
     }
53
     }
60
 
54
 
61
     # $this->key returns public->key
55
     # $this->key returns public->key
112
     }
106
     }
113
 
107
 
114
 
108
 
109
+    /**
110
+     * convert
111
+     *
112
+     * Take a mixed input and returns a RecursiveArrayObject.
113
+     * This function is the sausage grinder, so to speak.
114
+     */
115
+    public function convert($obj)
116
+    {
117
+        switch (gettype($obj)) {
118
+            case 'string':
119
+                $out = json_decode($obj, true);
120
+                return (json_last_error() === JSON_ERROR_NONE)
121
+                    ? new RecursiveArrayObject($out)
122
+                    : error('json_last_error_msg(): ' . json_last_error_msg());
123
+                break;
124
+            
125
+            case 'array':
126
+            case 'object':
127
+                return new RecursiveArrayObject($obj);
128
+            
129
+            default:
130
+                return error('$ENV->convert() expects a JSON string, array, or object.');
131
+                break;
132
+        }
133
+    }
134
+
135
+
115
     /**
136
     /**
116
      * toArray
137
      * toArray
138
+     *
139
+     * Takes an object and returns an array.
140
+     * @param object|string $obj Thing to turn into an array
141
+     * @return $new New recursive array with $obj contents
117
      * @see https://ben.lobaugh.net/blog/567/php-recursively-convert-an-object-to-an-array
142
      * @see https://ben.lobaugh.net/blog/567/php-recursively-convert-an-object-to-an-array
118
      */
143
      */
119
     public function toArray($obj)
144
     public function toArray($obj)
135
     }
160
     }
136
 
161
 
137
 
162
 
138
-    /**
139
-     * fromJson
140
-     *
141
-     * @param string $JSON Valid JavaScript object string
142
-     * @return RecursiveArrayObject Not stdClass as in json_decode()
143
-     */
144
-
145
-    public function fromJson($str)
146
-    {
147
-        if (!is_string($str) || is_empty($str)) {
148
-            error('$ENV->fromJson() expects a string.');
149
-        }
150
-
151
-        $json = json_decode($str, true);
152
-        
153
-        if (json_last_error() === JSON_ERROR_NONE) {
154
-            # Decode to array and construct RAO
155
-            return new RecursiveArrayObject($json);
156
-        } else {
157
-            error('Unable to parse JSON in $ENV->fromJson().');
158
-        }
159
-    }
160
-
161
-
162
     /**
163
     /**
163
      * dedupe
164
      * dedupe
164
      *
165
      *
181
     /**
182
     /**
182
      * flatten
183
      * flatten
183
      *
184
      *
184
-     * Takes an $ENV node (Recursive ArrayObject)
185
+     * Takes an $ENV node or array of them
185
      * and flattens out the multi-dimensionality.
186
      * and flattens out the multi-dimensionality.
186
-     * Returns a single, non-deduplicated array.
187
+     * It returns a flat array with keys intact.
187
      */
188
      */
188
-    public function flatten($arr)
189
+    public function flatten($arr, int $lvl = null)
189
     {
190
     {
191
+        if (!is_array($arr) && !is_object($arr)) {
192
+            return error('$ENV->flatten() expects an array or object, got ' . gettype($arr));
193
+        }
194
+
190
         $new = array();
195
         $new = array();
191
 
196
 
192
         foreach ($arr as $k => $v) {
197
         foreach ($arr as $k => $v) {
193
-            if (is_object($v)) {
198
+            /*
199
+             if (is_object($v)) {
194
                 $v = $this->toArray($v);
200
                 $v = $this->toArray($v);
195
             }
201
             }
202
+            */
196
     
203
     
197
             if (is_array($v)) {
204
             if (is_array($v)) {
198
                 $new = array_merge($new, $this->flatten($v));
205
                 $new = array_merge($new, $this->flatten($v));
212
      * Maps a callback (or default) to an object.
219
      * Maps a callback (or default) to an object.
213
      *
220
      *
214
      * Example output:
221
      * Example output:
215
-     * $Hashes = $ENV->map('md5', $ENV->CATS->SEQ);
222
+     * $Hashes = $ENV->map('md5', $ENV->CATS->{6});
216
      *
223
      *
217
      * var_dump($Hashes);
224
      * var_dump($Hashes);
218
      * object(RecursiveArrayObject)#324 (1) {
225
      * object(RecursiveArrayObject)#324 (1) {
237
      * string(32) "52963afccc006d2bce3c890ad9e8f73a"
244
      * string(32) "52963afccc006d2bce3c890ad9e8f73a"
238
      *
245
      *
239
      * @param string $fn Callback function
246
      * @param string $fn Callback function
240
-     * @param object $obj Object to operate on
247
+     * @param object|string $obj Object or property to operate on
241
      * @return object $RAO Mapped RecursiveArrayObject
248
      * @return object $RAO Mapped RecursiveArrayObject
242
      */
249
      */
243
-    public function map($fn = '', $obj = null)
250
+    public function map(string $fn = '', $obj = null)
244
     {
251
     {
245
         # Set a default function if desired
252
         # Set a default function if desired
246
         if (empty($fn) && !is_object($fn)) {
253
         if (empty($fn) && !is_object($fn)) {

+ 0
- 44
classes/input.class.php View File

1
-<?php
2
-declare(strict_types=1);
3
-
4
-/**
5
- * Input class
6
- * 
7
- * An attempt to normalize and secure form inputs.
8
- */
9
-
10
-class Input {
11
-
12
-    /**
13
-     * passphrase
14
-     */
15
-    function passphrase(
16
-        string $Name = 'password',
17
-        string $ID = 'password',
18
-        string $Placeholder = 'Passphrase',
19
-        bool $Advice = false) {
20
-        $ENV = ENV::go();
21
-
22
-        # Input validation
23
-        if (!is_string($Name) || empty($Name)) {
24
-            error("Expected non-empty string, got \$Name = $Name in Input::passphrase.");
25
-        }
26
-
27
-        if (!empty($Advice) && $Advice !== true || $Advice !== false) {
28
-            error("Expected true|false, got \$Advice = $Advice in Input::passphrase.");
29
-        }
30
-
31
-        $Field = <<<HTML
32
-        <input type="password" name="$Name" id="$ID" placeholder="$Placeholder"
33
-          minlength="$ENV->PW_MIN" maxlength="$ENV->PW_MAX"
34
-          class="inputtext" autocomplete="off" required="required" />
35
-HTML;
36
-
37
-if ($Advice) {
38
-    return $Field . $ENV->PW_ADVICE;
39
-} else {
40
-    return $Field;
41
-}
42
-
43
-    }
44
-}

+ 34
- 8
classes/mysql.class.php View File

111
 -------------------------------------------------------------------------------------
111
 -------------------------------------------------------------------------------------
112
 *///---------------------------------------------------------------------------------
112
 *///---------------------------------------------------------------------------------
113
 
113
 
114
-if (!extension_loaded('mysqli')) {
115
-    error('Mysqli Extension not loaded.');
116
-}
117
-
118
 
114
 
119
 /**
115
 /**
120
  * db_string
116
  * db_string
285
 
281
 
286
 
282
 
287
     /**
283
     /**
288
-     * prepare_query
284
+     * Prepare and execute a prepared query returning the result set.
285
+     *
286
+     * Utility function that wraps DB_MYSQL::prepare and DB_MYSQL::execute
287
+     * as most times, the query is going to be one-off and this will save
288
+     * on keystrokes. If you do plan to be executing a prepared query
289
+     * multiple times with different bound parameters, you'll want to call
290
+     * the two functions separately instead of this function.
291
+     *
292
+     * @param $Query
293
+     * @param mixed ...$Parameters
294
+     * @return bool|mysqli_result
295
+     */
296
+    public function prepared_query($Query, ...$Parameters) {
297
+        $this->prepare($Query);
298
+        return $this->execute(...$Parameters);
299
+    }
300
+
301
+    /**
302
+     * prepare
289
      */
303
      */
290
-    public function prepare_query($Query, &...$BindVars)
304
+    public function prepare($Query, &...$BindVars)
291
     {
305
     {
292
         $this->connect();
306
         $this->connect();
293
         $this->StatementID = mysqli_prepare($this->LinkID, $Query);
307
         $this->StatementID = mysqli_prepare($this->LinkID, $Query);
306
         return $this->StatementID;
320
         return $this->StatementID;
307
     }
321
     }
308
 
322
 
323
+    # Compatibility function for the old name
324
+    public function prepare_query($Query, &...$BindVars)
325
+    {
326
+        return $this->prepare($Query, $BindVars);
327
+    }
328
+
309
 
329
 
310
     /**
330
     /**
311
-     * exec_prepared_query
331
+     * execute
312
      */
332
      */
313
-    public function exec_prepared_query()
333
+    public function execute()
314
     {
334
     {
315
         $QueryStartTime = microtime(true);
335
         $QueryStartTime = microtime(true);
316
         mysqli_stmt_execute($this->StatementID);
336
         mysqli_stmt_execute($this->StatementID);
320
         $this->Time += $QueryRunTime;
340
         $this->Time += $QueryRunTime;
321
     }
341
     }
322
 
342
 
343
+    # Compatibility function for the old name
344
+    public function exec_prepared_query()
345
+    {
346
+        return $this->execute();
347
+    }
348
+
323
 
349
 
324
     /**
350
     /**
325
      * Runs a raw query assuming pre-sanitized input. However, attempting to self sanitize (such
351
      * Runs a raw query assuming pre-sanitized input. However, attempting to self sanitize (such

+ 26
- 6
classes/security.class.php View File

39
     {
39
     {
40
         $ENV = ENV::go();
40
         $ENV = ENV::go();
41
 
41
 
42
+        # Bad PHP version
43
+        if (version_compare(PHP_VERSION, $ENV->PHP_MIN, '<')) {
44
+            error("Gazelle requires PHP > $ENV->PHP_MIN.");
45
+        }
46
+
42
         # short_open_tag
47
         # short_open_tag
43
         if (!ini_get('short_open_tag')) {
48
         if (!ini_get('short_open_tag')) {
44
-            error('short_open_tag != On in php.ini');
49
+            error('short_open_tag != On in php.ini.');
45
         }
50
         }
46
 
51
 
47
         # apcu
52
         # apcu
48
         if (!extension_loaded('apcu')) {
53
         if (!extension_loaded('apcu')) {
49
-            error('APCu extension not loaded');
54
+            error('APCu extension php-apcu not loaded.');
50
         }
55
         }
51
 
56
 
52
-        # Bad PHP version
53
-        if (version_compare($ENV->PHP_MIN, '7.4.0', '<')) {
54
-            error("Gazelle requires PHP > $ENV->PHP_MIN.");
57
+        # mbstring
58
+        if (!extension_loaded('mbstring')) {
59
+            error('Multibyte string extension php-mbstring not loaded.');
60
+        }
61
+
62
+        # memcache
63
+        if (!extension_loaded('memcache')) {
64
+            error('memcached extension php-memcache not loaded.');
65
+        }
66
+
67
+        # mysqli
68
+        if (!extension_loaded('mysqli')) {
69
+            error('mysqli extension php-mysql not loaded.');
70
+        }
71
+        
72
+        # blake3
73
+        if ($ENV->FEATURE_BIOPHP && !extension_loaded('blake3')) {
74
+            error('Please install and enable the php-blake3 extension.');
55
         }
75
         }
56
 
76
 
57
         # Deal with dumbasses
77
         # Deal with dumbasses
58
-        if (isset($_REQUEST['info_hash']) && isset($_REQUEST['peer_id'])) {
78
+        if (isset($_REQUEST['info_hash']) || isset($_REQUEST['peer_id'])) {
59
             error(
79
             error(
60
                 'd14:failure reason40:Invalid .torrent, try downloading again.e',
80
                 'd14:failure reason40:Invalid .torrent, try downloading again.e',
61
                 $NoHTML = true,
81
                 $NoHTML = true,

+ 0
- 360
classes/seqhash.class.php View File

1
-<?php
2
-#declare(strict_types = 1);
3
-# PHP Notice:  Trying to access array offset on value of type bool in /var/www/html/dev.biotorrents.de/classes/seqhash.class.php on line 233
4
-
5
-/**
6
- * Seqhash
7
- *
8
- * Implements Keoni's Seqhash algorithm for DNA/RNA/protein sequences,
9
- * e.g., v1_DCD_4b0616d1b3fc632e42d78521deb38b44fba95cca9fde159e01cd567fa996ceb9
10
- *
11
- * > The first element is the version tag (v1 for version 1).
12
- * > If there is ever a Seqhash version 2, this tag will differentiate seqhashes.
13
- *
14
- * > The second element is the metadata tag, which has 3 letters.
15
- * > The first letter codes for the sequenceType (D for DNA, R for RNA, and P for Protein).
16
- * > The second letter codes for whether or not the sequence is circular (C for Circular, L for Linear).
17
- * > The final letter codes for whether or not the sequence is double stranded (D for Double stranded, S for Single stranded).
18
- *
19
- * > The final element is the blake3 hash of the sequence (once rotated and complemented).
20
- *
21
- * Requires the php-blake3 extension from:
22
- * https://github.com/cypherbits/php-blake3
23
- *
24
- * @see https://blog.libredna.org/post/seqhash/
25
- * @see https://github.com/TimothyStiles/poly/blob/prime/hash.go
26
- * @see https://github.com/TimothyStiles/poly/blob/prime/hash_test.go
27
- */
28
-
29
-class Seqhash
30
-{
31
-    /**
32
-     * boothLeastRotation
33
-     *
34
-     * Gets the least rotation of a circular string.
35
-     * @see https://en.wikipedia.org/wiki/Lexicographically_minimal_string_rotation
36
-     */
37
-    public function boothLeastRotation(string $Sequence)
38
-    {
39
-        # First concatenate the sequence to itself to avoid modular arithmatic
40
-        # todo: Use buffers just for speed? May get annoying with larger sequences
41
-        $Sequence = $Sequence . $Sequence;
42
-        $LeastRotationIndex = 0;
43
-
44
-        # Initializing failure slice
45
-        $FailureSlice = array_fill(0, strlen($Sequence), -1);
46
-
47
-        /*
48
-        for ($i = 0; $i <= strlen($Sequence); $i++) {
49
-            $FailureSlice[$i] = -1;
50
-        }
51
-        */
52
-
53
-        # Iterate through each character in the doubled-over sequence
54
-        for ($CharacterIndex = 1; $CharacterIndex < strlen($Sequence); $CharacterIndex++) {
55
-
56
-            # Get character
57
-            $Character = $Sequence[$CharacterIndex];
58
-
59
-            # Get failure
60
-            $Failure = $FailureSlice[$CharacterIndex - $LeastRotationIndex - 1];
61
-
62
-            # While failure !== -1 and character !== the character found at the least rotation + failure + 1
63
-            while ($Failure !== -1 && $Character !== $Sequence[$LeastRotationIndex + $Failure + 1]) {
64
-
65
-                # If character is lexically less than whatever is at $LeastRotationIndex, update $LeastRotationIndex
66
-                if ($Character < $Sequence[$LeastRotationIndex + $Failure + 1]) {
67
-                    $LeastRotationIndex = $CharacterIndex - $Failure - 1;
68
-                }
69
-
70
-                # Update failure using previous failure as index?
71
-                $Failure = $FailureSlice[$Failure];
72
-            } # while
73
-
74
-            # If character does not equal whatever character is at leastRotationIndex plus failure
75
-            if ($Character !== $Sequence[$LeastRotationIndex + $Failure + 1]) {
76
-
77
-                # If character is lexically less then what is rotated, $LeastRotatationIndex gets value of $CharacterIndex
78
-                if ($Character < $Sequence[$LeastRotationIndex]) {
79
-                    $LeastRotationIndex = $CharacterIndex;
80
-                }
81
-
82
-                # Assign -1 to whatever is at the index of difference between character and rotation indices
83
-                $FailureSlice[$CharacterIndex - $LeastRotationIndex] = -1;
84
-    
85
-            # If character does equal whatever character is at $LeastRotationIndex + $Failure
86
-            } else {
87
-                # Assign $Failure + 1 at the index of difference between character and rotation indices
88
-                $FailureSlice[$CharacterIndex - $LeastRotationIndex] = $Failure + 1;
89
-            }
90
-        } # for
91
-
92
-        return $LeastRotationIndex;
93
-    }
94
-
95
-
96
-    /**
97
-     * rotateSequence
98
-     *
99
-     * Rotates circular sequences to a deterministic point.
100
-     */
101
-    public function rotateSequence(string $Sequence)
102
-    {
103
-        $RotationIndex = $this->boothLeastRotation($Sequence);
104
-
105
-        # Writing the same sequence twice
106
-        # PHP has no strings.Builder.WriteString
107
-        $ConcatenatedSequence = $Sequence . $Sequence;
108
-
109
-        # https://stackoverflow.com/a/2423867
110
-        $Length = $RotationIndex % strlen($Sequence);
111
-        return substr($Sequence, $Length) . substr($Sequence, 0, $Length);
112
-    }
113
-
114
-
115
-    /**
116
-     * reverseComplement
117
-     *
118
-     * Takes the reverse complement of a sequence.
119
-     * Doesn't validate the sequence alphabet first.
120
-     */
121
-    public function reverseComplement(string $Sequence)
122
-    {
123
-        # Normalize the sequence
124
-        $Sequence = strtoupper($Sequence);
125
-
126
-        /**
127
-         * Provides 1:1 mapping between bases and their complements.
128
-         * Kind of ghetto, but lowercase replaces help stop extra flips.
129
-         * @see https://github.com/TimothyStiles/poly/blob/prime/sequence.go
130
-         */
131
-        $RuneMap = [
132
-            'A' => 't',
133
-            'B' => 'v',
134
-            'C' => 'g',
135
-            'D' => 'h',
136
-            'G' => 'c',
137
-            'H' => 'd',
138
-            'K' => 'm',
139
-            'M' => 'k',
140
-            'N' => 'n',
141
-            'R' => 'y',
142
-            'S' => 's',
143
-            'T' => 'a',
144
-            'U' => 'a',
145
-            'V' => 'b',
146
-            'W' => 'w',
147
-            'Y' => 'r',
148
-        ];
149
-
150
-        return $ComplementString = strtoupper(
151
-            str_replace(
152
-                array_keys($RuneMap),
153
-                array_values($RuneMap),
154
-                $Sequence
155
-            )
156
-        );
157
-    }
158
-
159
-
160
-    /**
161
-     * hash
162
-     *
163
-     * Create a Seqhash from a string.
164
-     */
165
-    public function hash(
166
-        string $Sequence,
167
-        string $SequenceType,
168
-        bool   $Circular = false,
169
-        bool   $DoubleStranded = true
170
-    ) {
171
-        # Check for Blake3 support
172
-        if (!extension_loaded('blake3')) {
173
-            throw new Exception('Please install and enable the php-blake3 extension.');
174
-        }
175
-
176
-        # By definition, Seqhashes are of uppercase sequences
177
-        $Sequence = strtoupper($Sequence);
178
-
179
-        # If RNA, convert to a DNA sequence
180
-        # The hash itself between a DNA and RNA sequence will not be different,
181
-        # but their Seqhash will have a different metadata string (R vs. D)
182
-        if ($SequenceType === 'RNA') {
183
-            $Sequence = str_replace('T', 'U', $Sequence);
184
-        }
185
-
186
-        # Run checks on the input
187
-        if (!in_array($SequenceType, ['DNA', 'RNA', 'PROTEIN'])) {
188
-            throw new Exception("SequenceType must be one of [DNA, RNA, PROTEIN]. Got $SequenceType.");
189
-        }
190
-
191
-        # Check the alphabet used
192
-        $SequenceRegex = '/[ATUGCYRSWKMBDHVNZ]/';
193
-        $ProteinRegex = '/[ACDEFGHIKLMNPQRSTVWYUO*BXZ]/';
194
-
195
-        # todo: Refactor this to detect $SequenceType from alphabet
196
-        if ($SequenceType === 'DNA' || $SequenceType === 'RNA') {
197
-            foreach (str_split($Sequence) as $Letter) {
198
-                if (!preg_match($SequenceRegex, $Letter)) {
199
-                    throw new Exception("Only letters ATUGCYRSWKMBDHVNZ are allowed for DNA/RNA. Got $Letter.");
200
-                }
201
-            }
202
-        }
203
-
204
-        /**
205
-         * Selenocysteine (Sec; U) and pyrrolysine (Pyl; O) are added
206
-         * in accordance with https://www.uniprot.org/help/sequences
207
-         *
208
-         * The release notes https://web.expasy.org/docs/relnotes/relstat.html
209
-         * also state there are Asx (B), Glx (Z), and Xaa (X) amino acids,
210
-         * so these are added in as well.
211
-         */
212
-        else {
213
-            foreach (str_split($Sequence) as $Letter) {
214
-                if (!preg_match($ProteinRegex, $Letter)) {
215
-                    throw new Exception("Only letters ACDEFGHIKLMNPQRSTVWYUO*BXZ are allowed for proteins. Got $Letter.");
216
-                }
217
-            }
218
-        }
219
-    
220
-        # There is no check for circular proteins since proteins can be circular
221
-        if ($SequenceType === 'PROTEIN' && $DoubleStranded) {
222
-            throw new Exception("Proteins can't be double stranded.");
223
-        }
224
-
225
-        # Gets deterministic sequence based off of metadata + sequence
226
-        #switch ($Circular && $DoubleStranded) {
227
-        switch ([$Circular, $DoubleStranded]) {
228
-            #case (true && true):
229
-            case [true, true]:
230
-                $PotentialSequences = [
231
-                    $this->rotateSequence($Sequence),
232
-                    $this->rotateSequence($this->reverseComplement($Sequence)),
233
-                ];
234
-                $DeterministicSequence = sort($PotentialSequences)[0];
235
-                break;
236
-
237
-            #case (true && false):
238
-            case [true, false]:
239
-                $DeterministicSequence = $this->rotateSequence($Sequence);
240
-                break;
241
-
242
-            #case (false && true):
243
-            case [false, true]:
244
-                $PotentialSequences = [
245
-                    $Sequence,
246
-                    $this->reverseComplement($Sequence),
247
-                ];
248
-                $DeterministicSequence = sort($PotentialSequences)[0];
249
-                break;
250
-
251
-            #case (false && false):
252
-            case [false, false]:
253
-                $DeterministicSequence = $Sequence;
254
-                break;
255
-
256
-            default:
257
-                break;
258
-        }
259
-
260
-        /**
261
-         * Build 3 letter metadata
262
-         */
263
-
264
-        # Get first letter: D for DNA, R for RNA, and P for Protein
265
-        switch ($SequenceType) {
266
-            case 'DNA':
267
-                $SequenceTypeLetter = 'D';
268
-                break;
269
-            
270
-            case 'RNA':
271
-                $SequenceTypeLetter = 'R';
272
-                break;
273
-            
274
-            case 'PROTEIN':
275
-                $SequenceTypeLetter = 'P';
276
-                break;
277
-                
278
-            default:
279
-                break;
280
-            }
281
-
282
-        # Get 2nd letter: C for circular, L for Linear
283
-        if ($Circular) {
284
-            $CircularLetter = 'C';
285
-        } else {
286
-            $CircularLetter = 'L';
287
-        }
288
-
289
-        # Get 3rd letter: D for Double stranded, S for Single stranded
290
-        if ($DoubleStranded) {
291
-            $DoubleStrandedLetter = 'D';
292
-        } else {
293
-            $DoubleStrandedLetter = 'S';
294
-        }
295
-
296
-        # php-blake3 returns hex by default,
297
-        # binary if $rawOutput = true
298
-        return
299
-            'v1'
300
-          . '_'
301
-          . $SequenceTypeLetter
302
-          . $CircularLetter
303
-          . $DoubleStrandedLetter
304
-          . '_'
305
-          . blake3($DeterministicSequence);
306
-    }
307
-
308
-
309
-    /**
310
-     * validate
311
-     *
312
-     * Validates a Seqhash's metadata.
313
-     * Doesn't check the Blake3 hash itself,
314
-     * because php-blake3 has no such feature.
315
-     */
316
-    public function validate(string $Seqhash)
317
-    {
318
-        $Parts = explode('_', $Seqhash);
319
-
320
-        # Check version info
321
-        if ($Parts[0] !== 'v1') {
322
-            throw new Exception("Invalid version info. Got $Parts[0].");
323
-        }
324
-
325
-        # Check 3 letter metadata
326
-        $Meta = str_split($Parts[1]);
327
-        if (!in_array($Meta[0], ['D', 'R', 'P'])
328
-         || !in_array($Meta[1], ['C', 'L'])
329
-         || !in_array($Meta[2], ['D', 'S'])) {
330
-            throw new Exception("Invalid metadata. Got $Parts[1].");
331
-        }
332
-
333
-        # Check Blake3 hex and hash length
334
-        if (!ctype_xdigit($Parts[2]) || strlen($Parts[2] !== 64)) {
335
-            throw new Exception("Invalid Blake3 hash. Expected a 64-character hex string.");
336
-        }
337
-
338
-        return true;
339
-    }
340
-
341
-
342
-    /**
343
-     * gcContent
344
-     *
345
-     * Bonus feature!
346
-     * Calculate GC content of a DNA sequence.
347
-     * Shamelessly ripped from kennypavan/BioPHP.
348
-     *
349
-     * @see https://github.com/kennypavan/BioPHP/blob/master/BioPHP.php
350
-     */
351
-    public function gcContent(string $Sequence, int $Precision = 2)
352
-    {
353
-        $Sequence = strtoupper($Sequence);
354
-        
355
-        $G = substr_count($Sequence, 'G');
356
-        $C = substr_count($Sequence, 'C');
357
-
358
-        return number_format((($G + $C) / strlen($Sequence)) * 100, $Precision);
359
-    }
360
-}

+ 67
- 63
classes/torrent_form.class.php View File

76
 
76
 
77
     /**
77
     /**
78
      * ====================
78
      * ====================
79
-     * = Twig based class =
79
+     * = Twig-based class =
80
      * ====================
80
      * ====================
81
     */
81
     */
82
 
82
 
388
 
388
 
389
         echo <<<HTML
389
         echo <<<HTML
390
               <tr>
390
               <tr>
391
-                <td>
392
-                  <input id="post" type="submit" value="$Value" />
391
+                <td class="center">
392
+                  <input id="post" type="submit" value="$Value" class="button-primary" />
393
                 </td>
393
                 </td>
394
               </tr>
394
               </tr>
395
             </table> <!-- torrent_form -->
395
             </table> <!-- torrent_form -->
403
      * upload_form
403
      * upload_form
404
      *
404
      *
405
      * Finally the "real" upload form.
405
      * Finally the "real" upload form.
406
-     * Contains all the field you'd expect.
406
+     * Contains all the fields you'd expect.
407
      *
407
      *
408
      * This is currently one enormous function.
408
      * This is currently one enormous function.
409
      * It has sub-functions, variables, and everything.
409
      * It has sub-functions, variables, and everything.
438
 
438
 
439
 
439
 
440
         /**
440
         /**
441
-         * Semantic Version
441
+         * Version
442
          */
442
          */
443
         
443
         
444
         $Version = display_str($Torrent['Version']);
444
         $Version = display_str($Torrent['Version']);
445
 
445
 
446
         echo $Twig->render(
446
         echo $Twig->render(
447
-            'torrent_form/identifier.html',
447
+            'torrent_form/version.html',
448
             [
448
             [
449
               'db' => $ENV->DB->version,
449
               'db' => $ENV->DB->version,
450
               'version' => $Version,
450
               'version' => $Version,
583
             'torrent_form/year.html',
583
             'torrent_form/year.html',
584
             [
584
             [
585
             'db' => $ENV->DB->year,
585
             'db' => $ENV->DB->year,
586
-            'location' => $TorrentYear,
586
+            'year' => $TorrentYear,
587
           ]
587
           ]
588
         );
588
         );
589
 
589
 
699
                 $trID = 'media_tr',
699
                 $trID = 'media_tr',
700
                 $Label = 'Platform',
700
                 $Label = 'Platform',
701
                 $Torrent = $Torrent,
701
                 $Torrent = $Torrent,
702
-                $Media = $ENV->META->Platforms->Sequences
702
+                $Media = $ENV->CATS->{1}->Platforms
703
             );
703
             );
704
             
704
             
705
 
705
 
710
                 $trID = 'media_graphs_tr',
710
                 $trID = 'media_graphs_tr',
711
                 $Label = 'Platform',
711
                 $Label = 'Platform',
712
                 $Torrent = $Torrent,
712
                 $Torrent = $Torrent,
713
-                $Media = $ENV->flatten([
714
-                    $ENV->META->Platforms->Graphs,
715
-                    $ENV->META->Platforms->Sequences
716
-                ])
713
+                $Media = $ENV->CATS->{2}->Platforms
717
             );
714
             );
718
             
715
             
719
 
716
 
724
                 $trID = 'media_scalars_vectors_tr',
721
                 $trID = 'media_scalars_vectors_tr',
725
                 $Label = 'Platform',
722
                 $Label = 'Platform',
726
                 $Torrent = $Torrent,
723
                 $Torrent = $Torrent,
727
-                $Media = $ENV->flatten([
728
-                    $ENV->META->Platforms->Graphs,
729
-                    $ENV->META->Platforms->Images
730
-                ])
724
+                $Media = $ENV->CATS->{5}->Platforms
731
             );
725
             );
732
 
726
 
733
 
727
 
738
                 $trID = 'media_images_tr',
732
                 $trID = 'media_images_tr',
739
                 $Label = 'Platform',
733
                 $Label = 'Platform',
740
                 $Torrent = $Torrent,
734
                 $Torrent = $Torrent,
741
-                $Media = $ENV->META->Platforms->Images
735
+                $Media = $ENV->CATS->{8}->Platforms
742
             );
736
             );
743
 
737
 
744
 
738
 
749
                 $trID = 'media_documents_tr',
743
                 $trID = 'media_documents_tr',
750
                 $Label = 'Platform',
744
                 $Label = 'Platform',
751
                 $Torrent = $Torrent,
745
                 $Torrent = $Torrent,
752
-                $Media = $ENV->META->Platforms->Documents
746
+                $Media = $ENV->CATS->{11}->Platforms
753
             );
747
             );
754
 
748
 
755
 
749
 
760
                 $trID = 'media_machine_data_tr',
754
                 $trID = 'media_machine_data_tr',
761
                 $Label = 'Platform',
755
                 $Label = 'Platform',
762
                 $Torrent = $Torrent,
756
                 $Torrent = $Torrent,
763
-                $Media = $ENV->META->Platforms->Raw
757
+                $Media = $ENV->CATS->{12}->Platforms
764
             );
758
             );
765
         } # fi NewTorrent
759
         } # fi NewTorrent
766
         else {
760
         else {
780
          */
774
          */
781
         function formatSelect($trID = '', $Label = '', $Torrent = [], $FileTypes = [])
775
         function formatSelect($trID = '', $Label = '', $Torrent = [], $FileTypes = [])
782
         {
776
         {
777
+            #var_dump($FileTypes);
783
             echo <<<HTML
778
             echo <<<HTML
784
             <tr id="$trID">
779
             <tr id="$trID">
785
               <td>
780
               <td>
787
                   $Label
782
                   $Label
788
                 <label>
783
                 <label>
789
               </td>
784
               </td>
790
-              
785
+
791
               <td>
786
               <td>
792
                 <select id="container" name="container">
787
                 <select id="container" name="container">
793
                   <option value="Autofill">Autofill</option>
788
                   <option value="Autofill">Autofill</option>
794
 HTML;
789
 HTML;
795
 
790
 
796
-            foreach ($FileTypes as $Type => $Extensions) {
797
-                echo "<option value='$Type'";
791
+            foreach ($FileTypes as $FileType) {
792
+                foreach ($FileType as $Type => $Extensions) {
793
+                    echo "<option value='$Type'";
798
 
794
 
799
-                if ($Type === ($Torrent['Container'] ?? false)) {
800
-                    echo ' selected';
801
-                }
795
+                    if ($Type === ($Torrent['Container'] ?? false)) {
796
+                        echo ' selected';
797
+                    }
802
 
798
 
803
-                echo ">$Type</option>\n";
799
+                    echo ">$Type</option>\n";
800
+                }
804
             }
801
             }
802
+        
805
 
803
 
806
             echo <<<HTML
804
             echo <<<HTML
807
                 </select>
805
                 </select>
826
             $trID = 'container_tr',
824
             $trID = 'container_tr',
827
             $Label = 'Format',
825
             $Label = 'Format',
828
             $Torrent = $Torrent,
826
             $Torrent = $Torrent,
829
-            $FileTypes = array_merge(($ENV->CATS->{1}->Formats))
827
+            $FileTypes = $ENV->CATS->{1}->Formats
830
         );
828
         );
831
         
829
         
832
 
830
 
837
             $trID = 'container_graphs_tr',
835
             $trID = 'container_graphs_tr',
838
             $Label = 'Format',
836
             $Label = 'Format',
839
             $Torrent = $Torrent,
837
             $Torrent = $Torrent,
840
-            $FileTypes = array_merge($this->GraphXmlFormats, $this->GraphTxtFormats, $this->SeqFormats, $this->ProtFormats, $this->PlainFormats)
838
+            #$FileTypes = array_column($ENV->META, $Formats)
839
+            $FileTypes = $ENV->CATS->{2}->Formats
841
         );
840
         );
842
 
841
 
843
 
842
 
848
             $trID = 'container_scalars_vectors_tr',
847
             $trID = 'container_scalars_vectors_tr',
849
             $Label = 'Format',
848
             $Label = 'Format',
850
             $Torrent = $Torrent,
849
             $Torrent = $Torrent,
851
-            $FileTypes = $ENV->flatten($ENV->CATS->{5}->Formats)
850
+            #$FileTypes = $ENV->flatten($ENV->CATS->{5}->Formats)
851
+            $FileTypes = $ENV->CATS->{5}->Formats
852
         );
852
         );
853
 
853
 
854
 
854
 
859
             $trID = 'container_images_tr',
859
             $trID = 'container_images_tr',
860
             $Label = 'Format',
860
             $Label = 'Format',
861
             $Torrent = $Torrent,
861
             $Torrent = $Torrent,
862
-            $FileTypes = array_merge($this->ImgFormats, $this->PlainFormats)
862
+            #$FileTypes = array_merge($this->ImgFormats)
863
+            $FileTypes = $ENV->CATS->{8}->Formats
863
         );
864
         );
864
 
865
 
865
 
866
 
870
             $trID = 'container_spatial_tr',
871
             $trID = 'container_spatial_tr',
871
             $Label = 'Format',
872
             $Label = 'Format',
872
             $Torrent = $Torrent,
873
             $Torrent = $Torrent,
873
-            $FileTypes = array_merge($this->MapVectorFormats, $this->MapRasterFormats, $this->ImgFormats, $this->PlainFormats)
874
+            #$FileTypes = array_merge($this->MapVectorFormats, $this->MapRasterFormats, $this->ImgFormats, $this->PlainFormats)
875
+            $FileTypes = $ENV->CATS->{9}->Formats
874
         );
876
         );
875
 
877
 
876
 
878
 
881
             $trID = 'container_documents_tr',
883
             $trID = 'container_documents_tr',
882
             $Label = 'Format',
884
             $Label = 'Format',
883
             $Torrent = $Torrent,
885
             $Torrent = $Torrent,
884
-            $FileTypes = array_merge($this->BinDocFormats, $this->CpuGenFormats, $this->PlainFormats)
886
+            #$FileTypes = array_merge($this->BinDocFormats, $this->CpuGenFormats, $this->PlainFormats)
887
+            $FileTypes = $ENV->CATS->{11}->Formats
885
         );
888
         );
886
 
889
 
887
 
890
 
892
             $trID = 'archive_tr',
895
             $trID = 'archive_tr',
893
             $Label = 'Archive',
896
             $Label = 'Archive',
894
             $Torrent = $Torrent,
897
             $Torrent = $Torrent,
895
-            $FileTypes = $this->Archives
898
+            # $ENV->Archives nests -1 deep
899
+            $FileTypes = [$ENV->META->Formats->Archives]
896
         );
900
         );
897
 
901
 
898
 
902
 
1030
             $TorrentImage = display_str($Torrent['Image']);
1034
             $TorrentImage = display_str($Torrent['Image']);
1031
             $Disabled = $this->Disabled;
1035
             $Disabled = $this->Disabled;
1032
 
1036
 
1033
-            echo <<<HTML
1034
-            <tr id="cover_tr">
1035
-            <td>
1036
-              <label for="image">
1037
-                Picture
1038
-              </label>
1039
-            </td>
1040
-            
1041
-            <td>
1042
-              <input type="text" id="image" name="image" size="60"
1043
-                placeholder="A meaningful picture, e.g., the specimen or a thumbnail"
1044
-                value="$TorrentImage" $Disabled? />
1045
-            </td>
1046
-          </tr>
1047
-HTML;
1037
+            echo $Twig->render(
1038
+                'torrent_form/picture.html',
1039
+                [
1040
+                    'db' => $ENV->DB->picture,
1041
+                    'picture' => $TorrentImage,
1042
+                ]
1043
+            );
1048
         }
1044
         }
1049
 
1045
 
1050
 
1046
 
1056
          */
1052
          */
1057
         if (!$this->DisabledFlag && $this->NewTorrent) {
1053
         if (!$this->DisabledFlag && $this->NewTorrent) {
1058
             $TorrentMirrors = display_str($Torrent['Mirrors']);
1054
             $TorrentMirrors = display_str($Torrent['Mirrors']);
1059
-            echo <<<HTML
1060
-            <tr id="mirrors_tr">
1061
-              <td>
1062
-                <label for="mirrors">
1063
-                  Mirrors
1064
-                </label>
1065
-              </td>
1066
-              
1067
-              <td>
1068
-                <!-- Needs to be all on one line -->
1069
-                <textarea rows="2" name="mirrors" id="mirrors"
1070
-                  placeholder="Up to two FTP/HTTP addresses that either point directly to a file, or for multi-file torrents, to the enclosing folder">$TorrentMirrors</textarea>
1071
-              </td>
1072
-            </tr>
1073
-HTML;
1055
+            echo $Twig->render(
1056
+                'torrent_form/mirrors.html',
1057
+                [
1058
+                  'db' => $ENV->DB->mirrors,
1059
+                  'mirrors' => $TorrentMirrors,
1060
+              ]
1061
+            );
1074
         }
1062
         }
1075
 
1063
 
1076
 
1064
 
1103
         }
1091
         }
1104
 
1092
 
1105
 
1093
 
1094
+        /**
1095
+         * Seqhash
1096
+         */
1097
+
1098
+        if ($ENV->FEATURE_BIOPHP && !$this->DisabledFlag && $this->NewTorrent) {
1099
+            $TorrentSeqhash = display_str($Torrent['Seqhash']);
1100
+            echo $Twig->render(
1101
+                'torrent_form/seqhash.html',
1102
+                [
1103
+                    'db' => $ENV->DB->seqhash,
1104
+                    'seqhash' => $TorrentSeqhash,
1105
+                ]
1106
+            );
1107
+        }
1108
+
1109
+
1106
         /**
1110
         /**
1107
          * Torrent group description
1111
          * Torrent group description
1108
          *
1112
          *

+ 6
- 3
classes/twig.class.php View File

60
     private static function factory(): \Twig\Environment
60
     private static function factory(): \Twig\Environment
61
     {
61
     {
62
         $ENV = ENV::go();
62
         $ENV = ENV::go();
63
+
64
+        # https://twig.symfony.com/doc/3.x/api.html
63
         $Twig = new \Twig\Environment(
65
         $Twig = new \Twig\Environment(
64
             new \Twig\Loader\FilesystemLoader("$ENV->SERVER_ROOT/templates"),
66
             new \Twig\Loader\FilesystemLoader("$ENV->SERVER_ROOT/templates"),
65
             [
67
             [
66
                 'auto_reload' => true,
68
                 'auto_reload' => true,
67
-                'autoescape' => 'html',
68
-                'cache' => "$ENV->WEB_ROOT/cache/twig"
69
-                #'debug' => DEBUG_MODE,
69
+                'autoescape' => 'name',
70
+                'cache' => "$ENV->WEB_ROOT/cache/twig",
71
+                'debug' => $ENV->DEV,
72
+                'strict_variables' => true,
70
         ]
73
         ]
71
         );
74
         );
72
 
75
 

+ 11
- 3
classes/util.php View File

383
      * Append $Log
383
      * Append $Log
384
      * Formerly in sections/error/index.php
384
      * Formerly in sections/error/index.php
385
      */
385
      */
386
-    if ($Log ?? false) {
386
+    if ($Log) {
387
         $Message .= " <a href='log.php?search=$Title'>Search Log</a>";
387
         $Message .= " <a href='log.php?search=$Title'>Search Log</a>";
388
     }
388
     }
389
 
389
 
390
     /**
390
     /**
391
      * Append $Debug
391
      * Append $Debug
392
      */
392
      */
393
-    if ($Debug ?? false) {
393
+    if ($Debug) {
394
         $DateTime = strftime('%c', $_SERVER['REQUEST_TIME']);
394
         $DateTime = strftime('%c', $_SERVER['REQUEST_TIME']);
395
         $BackTrace = debug_string_backtrace();
395
         $BackTrace = debug_string_backtrace();
396
 
396
 
516
  */
516
  */
517
 function json_error($Code)
517
 function json_error($Code)
518
 {
518
 {
519
-    echo json_encode(add_json_info(['status' => 'failure', 'error' => $Code, 'response' => []]));
519
+    echo json_encode(
520
+        add_json_info(
521
+            [
522
+                'status' => 'failure',
523
+                'error' => $Code,
524
+                'response' => []
525
+            ]
526
+        )
527
+    );
520
     die();
528
     die();
521
 }
529
 }
522
 
530
 

+ 17
- 15
composer.json View File

1
 {
1
 {
2
   "name": "biotorrents/gazelle",
2
   "name": "biotorrents/gazelle",
3
   "description": "Web framework for private BitTorrent trackers using Ocelot",
3
   "description": "Web framework for private BitTorrent trackers using Ocelot",
4
-
5
   "type": "project",
4
   "type": "project",
6
   "license": "Unlicense",
5
   "license": "Unlicense",
7
-
8
   "authors": [
6
   "authors": [
9
-    { "name": "What.cd" },
10
-    { "name": "Oppaitime" },
11
-    { "name": "BioTorrents.de" }
7
+    {
8
+      "name": "What.cd"
9
+    },
10
+    {
11
+      "name": "Oppaitime"
12
+    },
13
+    {
14
+      "name": "BioTorrents.de"
15
+    }
12
   ],
16
   ],
13
-
14
   "autoload": {
17
   "autoload": {
15
-    "classmap": ["classes/"],
16
-    "files": ["classes/autoload.php"]
18
+    "classmap": [
19
+      "classes/"
20
+    ],
21
+    "files": [
22
+      "classes/autoload.php"
23
+    ]
17
   },
24
   },
18
-
19
   "config": {
25
   "config": {
20
     "sort-packages": true
26
     "sort-packages": true
21
   },
27
   },
22
-
23
   "require": {
28
   "require": {
24
     "php": ">=7.4",
29
     "php": ">=7.4",
25
-
26
     "ext-apcu": "*",
30
     "ext-apcu": "*",
27
-    "ext-blake3": "*",
28
     "ext-curl": "*",
31
     "ext-curl": "*",
29
     "ext-json": "*",
32
     "ext-json": "*",
30
     "ext-mbstring": "*",
33
     "ext-mbstring": "*",
31
     "ext-memcache": "*",
34
     "ext-memcache": "*",
32
     "ext-mysqli": "*",
35
     "ext-mysqli": "*",
33
-
36
+    "biotorrents/biophp": "dev-master",
34
     "erusev/parsedown": "^1.8.0-beta-7",
37
     "erusev/parsedown": "^1.8.0-beta-7",
35
     "erusev/parsedown-extra": "^0.8.1",
38
     "erusev/parsedown-extra": "^0.8.1",
36
     "j7mbo/twitter-api-php": "^1.0.6",
39
     "j7mbo/twitter-api-php": "^1.0.6",
38
     "robmorgan/phinx": "^0.12.7",
41
     "robmorgan/phinx": "^0.12.7",
39
     "twig/twig": "^3.3.2"
42
     "twig/twig": "^3.3.2"
40
   },
43
   },
41
-
42
   "require-dev": {
44
   "require-dev": {
45
+    "d11wtq/boris": "^1.0.10",
43
     "phpstan/phpstan": "^0.12.92",
46
     "phpstan/phpstan": "^0.12.92",
44
     "phpunit/phpunit": "^9.5.6",
47
     "phpunit/phpunit": "^9.5.6",
45
     "squizlabs/php_codesniffer": "^3.6.0"
48
     "squizlabs/php_codesniffer": "^3.6.0"
46
   },
49
   },
47
-
48
   "scripts": {
50
   "scripts": {
49
     "phpstan": "phpstan analyse",
51
     "phpstan": "phpstan analyse",
50
     "test": "phpunit"
52
     "test": "phpunit"

+ 178
- 38
composer.lock View File

4
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
4
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5
         "This file is @generated automatically"
5
         "This file is @generated automatically"
6
     ],
6
     ],
7
-    "content-hash": "b306af0027bec610a1abaf7776f3253c",
7
+    "content-hash": "344f2e6f0358a24896af389a4bca5a1a",
8
     "packages": [
8
     "packages": [
9
+        {
10
+            "name": "biotorrents/biophp",
11
+            "version": "dev-master",
12
+            "source": {
13
+                "type": "git",
14
+                "url": "https://github.com/biotorrents/biophp.git",
15
+                "reference": "8b099fb0c78ec2a5dcab16c351e5d369853109ee"
16
+            },
17
+            "dist": {
18
+                "type": "zip",
19
+                "url": "https://api.github.com/repos/biotorrents/biophp/zipball/8b099fb0c78ec2a5dcab16c351e5d369853109ee",
20
+                "reference": "8b099fb0c78ec2a5dcab16c351e5d369853109ee",
21
+                "shasum": ""
22
+            },
23
+            "require": {
24
+                "ext-blake3": "*",
25
+                "ext-curl": "*",
26
+                "pear/math_biginteger": "^1.0.3",
27
+                "php": ">=7.4"
28
+            },
29
+            "require-dev": {
30
+                "d11wtq/boris": "^1.0.10"
31
+            },
32
+            "default-branch": true,
33
+            "type": "library",
34
+            "autoload": {
35
+                "psr-4": {
36
+                    "BioPHP\\": "src/"
37
+                }
38
+            },
39
+            "notification-url": "https://packagist.org/downloads/",
40
+            "license": [
41
+                "MIT"
42
+            ],
43
+            "authors": [
44
+                {
45
+                    "name": "ohm",
46
+                    "email": "help@biotorrents.de"
47
+                }
48
+            ],
49
+            "description": "BioPHP implements some light tools for manipulating genomic data",
50
+            "support": {
51
+                "source": "https://github.com/biotorrents/biophp/tree/master"
52
+            },
53
+            "time": "2021-07-23T19:02:18+00:00"
54
+        },
9
         {
55
         {
10
             "name": "cakephp/core",
56
             "name": "cakephp/core",
11
-            "version": "4.2.7",
57
+            "version": "4.2.8",
12
             "source": {
58
             "source": {
13
                 "type": "git",
59
                 "type": "git",
14
                 "url": "https://github.com/cakephp/core.git",
60
                 "url": "https://github.com/cakephp/core.git",
15
-                "reference": "aa8b40e2adcfbe52c71ec273866628ffc6d87838"
61
+                "reference": "bed4b6f09550909beea5440627d5a6ff85fb1934"
16
             },
62
             },
17
             "dist": {
63
             "dist": {
18
                 "type": "zip",
64
                 "type": "zip",
19
-                "url": "https://api.github.com/repos/cakephp/core/zipball/aa8b40e2adcfbe52c71ec273866628ffc6d87838",
20
-                "reference": "aa8b40e2adcfbe52c71ec273866628ffc6d87838",
65
+                "url": "https://api.github.com/repos/cakephp/core/zipball/bed4b6f09550909beea5440627d5a6ff85fb1934",
66
+                "reference": "bed4b6f09550909beea5440627d5a6ff85fb1934",
21
                 "shasum": ""
67
                 "shasum": ""
22
             },
68
             },
23
             "require": {
69
             "require": {
61
                 "issues": "https://github.com/cakephp/cakephp/issues",
107
                 "issues": "https://github.com/cakephp/cakephp/issues",
62
                 "source": "https://github.com/cakephp/core"
108
                 "source": "https://github.com/cakephp/core"
63
             },
109
             },
64
-            "time": "2021-05-24T17:26:44+00:00"
110
+            "time": "2021-06-26T14:06:56+00:00"
65
         },
111
         },
66
         {
112
         {
67
             "name": "cakephp/database",
113
             "name": "cakephp/database",
68
-            "version": "4.2.7",
114
+            "version": "4.2.8",
69
             "source": {
115
             "source": {
70
                 "type": "git",
116
                 "type": "git",
71
                 "url": "https://github.com/cakephp/database.git",
117
                 "url": "https://github.com/cakephp/database.git",
120
         },
166
         },
121
         {
167
         {
122
             "name": "cakephp/datasource",
168
             "name": "cakephp/datasource",
123
-            "version": "4.2.7",
169
+            "version": "4.2.8",
124
             "source": {
170
             "source": {
125
                 "type": "git",
171
                 "type": "git",
126
                 "url": "https://github.com/cakephp/datasource.git",
172
                 "url": "https://github.com/cakephp/datasource.git",
127
-                "reference": "cfc914efc099d48300c1a99316fc8d0d55babc67"
173
+                "reference": "cc101051e8d601cf6c2895d635ccefecca97ff4e"
128
             },
174
             },
129
             "dist": {
175
             "dist": {
130
                 "type": "zip",
176
                 "type": "zip",
131
-                "url": "https://api.github.com/repos/cakephp/datasource/zipball/cfc914efc099d48300c1a99316fc8d0d55babc67",
132
-                "reference": "cfc914efc099d48300c1a99316fc8d0d55babc67",
177
+                "url": "https://api.github.com/repos/cakephp/datasource/zipball/cc101051e8d601cf6c2895d635ccefecca97ff4e",
178
+                "reference": "cc101051e8d601cf6c2895d635ccefecca97ff4e",
133
                 "shasum": ""
179
                 "shasum": ""
134
             },
180
             },
135
             "require": {
181
             "require": {
174
                 "issues": "https://github.com/cakephp/cakephp/issues",
220
                 "issues": "https://github.com/cakephp/cakephp/issues",
175
                 "source": "https://github.com/cakephp/datasource"
221
                 "source": "https://github.com/cakephp/datasource"
176
             },
222
             },
177
-            "time": "2021-05-24T17:26:44+00:00"
223
+            "time": "2021-07-03T10:28:16+00:00"
178
         },
224
         },
179
         {
225
         {
180
             "name": "cakephp/utility",
226
             "name": "cakephp/utility",
181
-            "version": "4.2.7",
227
+            "version": "4.2.8",
182
             "source": {
228
             "source": {
183
                 "type": "git",
229
                 "type": "git",
184
                 "url": "https://github.com/cakephp/utility.git",
230
                 "url": "https://github.com/cakephp/utility.git",
435
             },
481
             },
436
             "time": "2020-10-12T00:27:44+00:00"
482
             "time": "2020-10-12T00:27:44+00:00"
437
         },
483
         },
484
+        {
485
+            "name": "pear/math_biginteger",
486
+            "version": "v1.0.3",
487
+            "source": {
488
+                "type": "git",
489
+                "url": "https://github.com/pear/Math_BigInteger.git",
490
+                "reference": "33d4357543037a458fad3e8c837a01b93104e592"
491
+            },
492
+            "dist": {
493
+                "type": "zip",
494
+                "url": "https://api.github.com/repos/pear/Math_BigInteger/zipball/33d4357543037a458fad3e8c837a01b93104e592",
495
+                "reference": "33d4357543037a458fad3e8c837a01b93104e592",
496
+                "shasum": ""
497
+            },
498
+            "require": {
499
+                "ext-pcre": "*",
500
+                "php": ">=4.2.0"
501
+            },
502
+            "suggest": {
503
+                "ext-bcmath": "Allows using the BCMath extension internally for computation. Faster than native implementation.",
504
+                "ext-gmp": "Allows using the GNU Multiple Precision extension internally for computation. If you are doing a lot of computation this is the recommended extension."
505
+            },
506
+            "type": "library",
507
+            "autoload": {
508
+                "psr-0": {
509
+                    "Math_": "./"
510
+                }
511
+            },
512
+            "notification-url": "https://packagist.org/downloads/",
513
+            "license": [
514
+                "MIT"
515
+            ],
516
+            "authors": [
517
+                {
518
+                    "name": "Jim Wigginton",
519
+                    "email": "terrafrost@php.net"
520
+                }
521
+            ],
522
+            "description": "Pure-PHP arbitrary precission integer arithmetic library. If GMP or BCMath are available they are used.",
523
+            "homepage": "https://github.com/pear/Math_BigInteger",
524
+            "keywords": [
525
+                "arbitrary",
526
+                "bcmath",
527
+                "gmp",
528
+                "integer",
529
+                "precision"
530
+            ],
531
+            "support": {
532
+                "issues": "http://pear.php.net/bugs/search.php?cmd=display&package_name[]=Math_BigInteger",
533
+                "source": "https://github.com/pear/Math_BigInteger"
534
+            },
535
+            "time": "2016-04-12T05:46:52+00:00"
536
+        },
438
         {
537
         {
439
             "name": "psr/container",
538
             "name": "psr/container",
440
             "version": "2.0.1",
539
             "version": "2.0.1",
1768
         }
1867
         }
1769
     ],
1868
     ],
1770
     "packages-dev": [
1869
     "packages-dev": [
1870
+        {
1871
+            "name": "d11wtq/boris",
1872
+            "version": "v1.0.10",
1873
+            "source": {
1874
+                "type": "git",
1875
+                "url": "https://github.com/borisrepl/boris.git",
1876
+                "reference": "31055b15e2d3fe47f31f6aa8e277f8f3fc7eb483"
1877
+            },
1878
+            "dist": {
1879
+                "type": "zip",
1880
+                "url": "https://api.github.com/repos/borisrepl/boris/zipball/31055b15e2d3fe47f31f6aa8e277f8f3fc7eb483",
1881
+                "reference": "31055b15e2d3fe47f31f6aa8e277f8f3fc7eb483",
1882
+                "shasum": ""
1883
+            },
1884
+            "require": {
1885
+                "ext-pcntl": "*",
1886
+                "ext-posix": "*",
1887
+                "ext-readline": "*",
1888
+                "php": ">=5.3.0"
1889
+            },
1890
+            "bin": [
1891
+                "bin/boris"
1892
+            ],
1893
+            "type": "library",
1894
+            "autoload": {
1895
+                "psr-0": {
1896
+                    "Boris": "lib"
1897
+                }
1898
+            },
1899
+            "notification-url": "https://packagist.org/downloads/",
1900
+            "license": [
1901
+                "MIT"
1902
+            ],
1903
+            "description": "A tiny, but robust REPL (Read-Evaluate-Print-Loop) for PHP.",
1904
+            "support": {
1905
+                "issues": "https://github.com/borisrepl/boris/issues",
1906
+                "source": "https://github.com/borisrepl/boris/tree/v1.0.10"
1907
+            },
1908
+            "time": "2015-03-01T08:05:19+00:00"
1909
+        },
1771
         {
1910
         {
1772
             "name": "doctrine/instantiator",
1911
             "name": "doctrine/instantiator",
1773
             "version": "1.4.0",
1912
             "version": "1.4.0",
1897
         },
2036
         },
1898
         {
2037
         {
1899
             "name": "nikic/php-parser",
2038
             "name": "nikic/php-parser",
1900
-            "version": "v4.11.0",
2039
+            "version": "v4.12.0",
1901
             "source": {
2040
             "source": {
1902
                 "type": "git",
2041
                 "type": "git",
1903
                 "url": "https://github.com/nikic/PHP-Parser.git",
2042
                 "url": "https://github.com/nikic/PHP-Parser.git",
1904
-                "reference": "fe14cf3672a149364fb66dfe11bf6549af899f94"
2043
+                "reference": "6608f01670c3cc5079e18c1dab1104e002579143"
1905
             },
2044
             },
1906
             "dist": {
2045
             "dist": {
1907
                 "type": "zip",
2046
                 "type": "zip",
1908
-                "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/fe14cf3672a149364fb66dfe11bf6549af899f94",
1909
-                "reference": "fe14cf3672a149364fb66dfe11bf6549af899f94",
2047
+                "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/6608f01670c3cc5079e18c1dab1104e002579143",
2048
+                "reference": "6608f01670c3cc5079e18c1dab1104e002579143",
1910
                 "shasum": ""
2049
                 "shasum": ""
1911
             },
2050
             },
1912
             "require": {
2051
             "require": {
1947
             ],
2086
             ],
1948
             "support": {
2087
             "support": {
1949
                 "issues": "https://github.com/nikic/PHP-Parser/issues",
2088
                 "issues": "https://github.com/nikic/PHP-Parser/issues",
1950
-                "source": "https://github.com/nikic/PHP-Parser/tree/v4.11.0"
2089
+                "source": "https://github.com/nikic/PHP-Parser/tree/v4.12.0"
1951
             },
2090
             },
1952
-            "time": "2021-07-03T13:36:55+00:00"
2091
+            "time": "2021-07-21T10:44:31+00:00"
1953
         },
2092
         },
1954
         {
2093
         {
1955
             "name": "phar-io/manifest",
2094
             "name": "phar-io/manifest",
1956
-            "version": "2.0.1",
2095
+            "version": "2.0.3",
1957
             "source": {
2096
             "source": {
1958
                 "type": "git",
2097
                 "type": "git",
1959
                 "url": "https://github.com/phar-io/manifest.git",
2098
                 "url": "https://github.com/phar-io/manifest.git",
1960
-                "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133"
2099
+                "reference": "97803eca37d319dfa7826cc2437fc020857acb53"
1961
             },
2100
             },
1962
             "dist": {
2101
             "dist": {
1963
                 "type": "zip",
2102
                 "type": "zip",
1964
-                "url": "https://api.github.com/repos/phar-io/manifest/zipball/85265efd3af7ba3ca4b2a2c34dbfc5788dd29133",
1965
-                "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133",
2103
+                "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53",
2104
+                "reference": "97803eca37d319dfa7826cc2437fc020857acb53",
1966
                 "shasum": ""
2105
                 "shasum": ""
1967
             },
2106
             },
1968
             "require": {
2107
             "require": {
2007
             "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
2146
             "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
2008
             "support": {
2147
             "support": {
2009
                 "issues": "https://github.com/phar-io/manifest/issues",
2148
                 "issues": "https://github.com/phar-io/manifest/issues",
2010
-                "source": "https://github.com/phar-io/manifest/tree/master"
2149
+                "source": "https://github.com/phar-io/manifest/tree/2.0.3"
2011
             },
2150
             },
2012
-            "time": "2020-06-27T14:33:11+00:00"
2151
+            "time": "2021-07-20T11:28:43+00:00"
2013
         },
2152
         },
2014
         {
2153
         {
2015
             "name": "phar-io/version",
2154
             "name": "phar-io/version",
2289
         },
2428
         },
2290
         {
2429
         {
2291
             "name": "phpstan/phpstan",
2430
             "name": "phpstan/phpstan",
2292
-            "version": "0.12.92",
2431
+            "version": "0.12.93",
2293
             "source": {
2432
             "source": {
2294
                 "type": "git",
2433
                 "type": "git",
2295
                 "url": "https://github.com/phpstan/phpstan.git",
2434
                 "url": "https://github.com/phpstan/phpstan.git",
2296
-                "reference": "64d4c5dc8ea96972bc18432d137a330239a5d2b2"
2435
+                "reference": "7b7602f05d340ffa418c59299f8c053ac6c3e7ea"
2297
             },
2436
             },
2298
             "dist": {
2437
             "dist": {
2299
                 "type": "zip",
2438
                 "type": "zip",
2300
-                "url": "https://api.github.com/repos/phpstan/phpstan/zipball/64d4c5dc8ea96972bc18432d137a330239a5d2b2",
2301
-                "reference": "64d4c5dc8ea96972bc18432d137a330239a5d2b2",
2439
+                "url": "https://api.github.com/repos/phpstan/phpstan/zipball/7b7602f05d340ffa418c59299f8c053ac6c3e7ea",
2440
+                "reference": "7b7602f05d340ffa418c59299f8c053ac6c3e7ea",
2302
                 "shasum": ""
2441
                 "shasum": ""
2303
             },
2442
             },
2304
             "require": {
2443
             "require": {
2329
             "description": "PHPStan - PHP Static Analysis Tool",
2468
             "description": "PHPStan - PHP Static Analysis Tool",
2330
             "support": {
2469
             "support": {
2331
                 "issues": "https://github.com/phpstan/phpstan/issues",
2470
                 "issues": "https://github.com/phpstan/phpstan/issues",
2332
-                "source": "https://github.com/phpstan/phpstan/tree/0.12.92"
2471
+                "source": "https://github.com/phpstan/phpstan/tree/0.12.93"
2333
             },
2472
             },
2334
             "funding": [
2473
             "funding": [
2335
                 {
2474
                 {
2349
                     "type": "tidelift"
2488
                     "type": "tidelift"
2350
                 }
2489
                 }
2351
             ],
2490
             ],
2352
-            "time": "2021-07-10T13:53:49+00:00"
2491
+            "time": "2021-07-20T10:49:53+00:00"
2353
         },
2492
         },
2354
         {
2493
         {
2355
             "name": "phpunit/php-code-coverage",
2494
             "name": "phpunit/php-code-coverage",
2671
         },
2810
         },
2672
         {
2811
         {
2673
             "name": "phpunit/phpunit",
2812
             "name": "phpunit/phpunit",
2674
-            "version": "9.5.6",
2813
+            "version": "9.5.7",
2675
             "source": {
2814
             "source": {
2676
                 "type": "git",
2815
                 "type": "git",
2677
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
2816
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
2678
-                "reference": "fb9b8333f14e3dce976a60ef6a7e05c7c7ed8bfb"
2817
+                "reference": "d0dc8b6999c937616df4fb046792004b33fd31c5"
2679
             },
2818
             },
2680
             "dist": {
2819
             "dist": {
2681
                 "type": "zip",
2820
                 "type": "zip",
2682
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fb9b8333f14e3dce976a60ef6a7e05c7c7ed8bfb",
2683
-                "reference": "fb9b8333f14e3dce976a60ef6a7e05c7c7ed8bfb",
2821
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d0dc8b6999c937616df4fb046792004b33fd31c5",
2822
+                "reference": "d0dc8b6999c937616df4fb046792004b33fd31c5",
2684
                 "shasum": ""
2823
                 "shasum": ""
2685
             },
2824
             },
2686
             "require": {
2825
             "require": {
2758
             ],
2897
             ],
2759
             "support": {
2898
             "support": {
2760
                 "issues": "https://github.com/sebastianbergmann/phpunit/issues",
2899
                 "issues": "https://github.com/sebastianbergmann/phpunit/issues",
2761
-                "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.6"
2900
+                "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.7"
2762
             },
2901
             },
2763
             "funding": [
2902
             "funding": [
2764
                 {
2903
                 {
2770
                     "type": "github"
2909
                     "type": "github"
2771
                 }
2910
                 }
2772
             ],
2911
             ],
2773
-            "time": "2021-06-23T05:14:38+00:00"
2912
+            "time": "2021-07-19T06:14:47+00:00"
2774
         },
2913
         },
2775
         {
2914
         {
2776
             "name": "sebastian/cli-parser",
2915
             "name": "sebastian/cli-parser",
3625
                     "type": "github"
3764
                     "type": "github"
3626
                 }
3765
                 }
3627
             ],
3766
             ],
3767
+            "abandoned": true,
3628
             "time": "2020-09-28T06:45:17+00:00"
3768
             "time": "2020-09-28T06:45:17+00:00"
3629
         },
3769
         },
3630
         {
3770
         {
3904
     "aliases": [],
4044
     "aliases": [],
3905
     "minimum-stability": "stable",
4045
     "minimum-stability": "stable",
3906
     "stability-flags": {
4046
     "stability-flags": {
4047
+        "biotorrents/biophp": 20,
3907
         "erusev/parsedown": 10
4048
         "erusev/parsedown": 10
3908
     },
4049
     },
3909
     "prefer-stable": false,
4050
     "prefer-stable": false,
3911
     "platform": {
4052
     "platform": {
3912
         "php": ">=7.4",
4053
         "php": ">=7.4",
3913
         "ext-apcu": "*",
4054
         "ext-apcu": "*",
3914
-        "ext-blake3": "*",
3915
         "ext-curl": "*",
4055
         "ext-curl": "*",
3916
         "ext-json": "*",
4056
         "ext-json": "*",
3917
         "ext-mbstring": "*",
4057
         "ext-mbstring": "*",

+ 1
- 1
design/privatefooter.php View File

6
 
6
 
7
 # End <div#content>, begin <footer>
7
 # End <div#content>, begin <footer>
8
 # This needs to be <main>, in each page
8
 # This needs to be <main>, in each page
9
-echo $HTML = '</div></main><footer class="halfwide">';
9
+echo $HTML = '</div></main><footer>';
10
 
10
 
11
 # Disclaimer
11
 # Disclaimer
12
 #if (!empty($Options['disclaimer'])) {
12
 #if (!empty($Options['disclaimer'])) {

+ 1
- 0
design/privateheader.php View File

50
         [
50
         [
51
           'vendor/jquery-ui.min',
51
           'vendor/jquery-ui.min',
52
           'vendor/normalize',
52
           'vendor/normalize',
53
+          'vendor/skeleton',
53
           #'assets/fonts/fa/css/all.min',
54
           #'assets/fonts/fa/css/all.min',
54
           'global'
55
           'global'
55
         ],
56
         ],

+ 1
- 0
design/publicfooter.php View File

8
 
8
 
9
 <footer>
9
 <footer>
10
   <a href="https://github.com/biotorrents/gazelle" target="_blank">GitHub</a>
10
   <a href="https://github.com/biotorrents/gazelle" target="_blank">GitHub</a>
11
+  <a href="https://docs.biotorrents.de" target="_blank">API</a>
11
   <a href="/legal.php?p=privacy">Privacy</a>
12
   <a href="/legal.php?p=privacy">Privacy</a>
12
   <a href="/legal.php?p=dmca">DMCA</a>
13
   <a href="/legal.php?p=dmca">DMCA</a>
13
 </footer>
14
 </footer>

+ 4
- 1
design/publicheader.php View File

41
 }
41
 }
42
 
42
 
43
 # Load CSS
43
 # Load CSS
44
-$Styles = ['vendor/normalize', 'global', 'public'];
44
+$Styles = ['vendor/normalize', 'vendor/skeleton', 'global', 'public'];
45
 foreach ($Styles as $Style) {
45
 foreach ($Styles as $Style) {
46
     echo View::pushAsset(
46
     echo View::pushAsset(
47
         "$ENV->STATIC_SERVER/styles/$Style.css",
47
         "$ENV->STATIC_SERVER/styles/$Style.css",
68
     echo '<a href="register.php">Register</a>';
68
     echo '<a href="register.php">Register</a>';
69
 }
69
 }
70
 
70
 
71
+/*
71
 $Email = $ENV->HELP->Email;
72
 $Email = $ENV->HELP->Email;
72
 $Subject = $ENV->HELP->Subject;
73
 $Subject = $ENV->HELP->Subject;
73
 $Body = $ENV->HELP->Body;
74
 $Body = $ENV->HELP->Body;
74
 echo "<a href='mailto:$Email?subject=$Subject&body=$Body'>Support</a>";
75
 echo "<a href='mailto:$Email?subject=$Subject&body=$Body'>Support</a>";
76
+*/
75
 
77
 
76
 echo <<<HTML
78
 echo <<<HTML
79
+    <a href="https://github.com/biotorrents/gazelle/issues" target="_blank">Support</a>
77
   </header>
80
   </header>
78
 
81
 
79
 <main>
82
 <main>

+ 1
- 1
design/views/generic/reply/quickreply.php View File

200
           class="hidden button_preview_<?=$ReplyText->getID()?>"
200
           class="hidden button_preview_<?=$ReplyText->getID()?>"
201
           tabindex="1" />
201
           tabindex="1" />
202
 
202
 
203
-        <input type="submit" value="Post" id="submit_button" tabindex="1" />
203
+        <input type="submit" class="button-primary" value="Post" id="submit_button" tabindex="1" />
204
       </div>
204
       </div>
205
     </form>
205
     </form>
206
   </div>
206
   </div>

+ 1
- 1
design/views/generic/reply/staffpm.php View File

32
 
32
 
33
     <input type="button" value="Preview"
33
     <input type="button" value="Preview"
34
       class="hidden button_preview_<?=$TextPrev->getID()?>" />
34
       class="hidden button_preview_<?=$TextPrev->getID()?>" />
35
-    <input type="submit" value="Send message" />
35
+    <input type="submit" class="button-primary" value="Send message" />
36
     <input type="button" value="Hide" data-toggle-target="#compose" />
36
     <input type="button" value="Hide" data-toggle-target="#compose" />
37
   </form>
37
   </form>
38
 </div>
38
 </div>

+ 39
- 20
readme.md View File

1
 # BioTorrents.de Gazelle
1
 # BioTorrents.de Gazelle
2
 
2
 
3
 This software is twice removed from the original
3
 This software is twice removed from the original
4
-[What.cd Gazelle](https://github.com/WhatCD/Gazelle):
5
-it's based on the security hardened PHP7 fork
4
+[What.cd Gazelle](https://github.com/WhatCD/Gazelle).
5
+It's based on the security hardened PHP7 fork
6
 [Oppaitime Gazelle](https://git.oppaiti.me/Oppaitime/Gazelle).
6
 [Oppaitime Gazelle](https://git.oppaiti.me/Oppaitime/Gazelle).
7
+It shares several features with
8
+[Orpheus Gazelle](https://github.com/OPSnet/Gazelle).
7
 The goal is to organize a functional database with pleasant interfaces,
9
 The goal is to organize a functional database with pleasant interfaces,
8
 and render insightful views using data from robust external sources.
10
 and render insightful views using data from robust external sources.
9
 
11
 
23
 with the appropriate bold/italic glyphs and monospace.
25
 with the appropriate bold/italic glyphs and monospace.
24
 These options are available to every theme.
26
 These options are available to every theme.
25
 Font Awesome 5 is also universally available.
27
 Font Awesome 5 is also universally available.
28
+[Download the fonts](https://docs.biotorrents.de/dl/fonts.tgz).
26
 
29
 
27
 ## Markdown support
30
 ## Markdown support
28
 
31
 
36
 ## $ENV recursive singleton
39
 ## $ENV recursive singleton
37
 
40
 
38
 [The site configuration](classes/config.template.php)
41
 [The site configuration](classes/config.template.php)
39
-is being migrated to a format govered by
40
-[the ENV special class](classes/env.class.php)
41
-for modified ArrayObjects.
42
-This is useful for several reasons:
43
-
44
-- prevents multiple configs loaded in memory;
45
-- ensures the config's immutability;
46
-- doesn't pollute the constants table;
47
-- allows public (echoed) and private (accessed) values;
48
-- supports large, nested static metadata structures;
49
-- able to scope access to the function level;
50
-- easy to extend ENV with new class methods;
51
-- good interoperability potential with JSON; and
52
-- native PHP ArrayObject support with Array compatibility.
42
+is being migrated to a format govered by the
43
+[ENV special class](classes/env.class.php)
44
+for modified recursive ArrayObjects.
53
 
45
 
54
 ## Twig template system
46
 ## Twig template system
55
 
47
 
56
-Similar to ENV,
57
-[the Twig interface](classes/twig.class.php)
48
+Similar to ENV, the
49
+[Twig interface](classes/twig.class.php)
58
 operates as a singleton because it's an external module with its own cache.
50
 operates as a singleton because it's an external module with its own cache.
59
 Twig provides a security benefit by escaping rendered output,
51
 Twig provides a security benefit by escaping rendered output,
60
 and a secondary benefit of clarifying the PHP running the site sections.
52
 and a secondary benefit of clarifying the PHP running the site sections.
61
-Several custom filters are available from
62
-[Orpheus Gazelle](https://github.com/OPSnet/Gazelle).
53
+Several custom filters are available from OPS.
54
+
55
+## Active data minimization
56
+
57
+BioTorrents.de has
58
+[real lawyer-vetted policies](templates/legal).
59
+In the process of matching the tech to the legal word,
60
+we dropped support for a number of compromising features:
61
+
62
+- Bitcoin, PayPal, and currency exchange API and system calls;
63
+- Bitcoin addresses, user donation history, and similar metadata; and
64
+- IP address and geolocation, email address, passphrase, and passkey history.
65
+
66
+Besides that, BioTorrents has several passive developments in progress:
67
+
68
+- prepare all queries with parameterized statements;
69
+- declare strict mode at the top of every PHP and JS file;
70
+- check strict equality and strong typing, including function arguments;
71
+- run all files through generic formatters such as PHP-CS-Fixer; and
72
+- move all external libraries to uncomplicated package management.
73
+
74
+## Minor changes
75
+
76
+- Database crypto bumped up to AES-256
77
+- Good subresource integrity support
78
+- Configurable HTTP status code errors
79
+- Integrated diceware passphrase generator
80
+- TLS database connections
81
+- Semantic HTML5 themes (WIP)
63
 
82
 
64
 # Changelog: WCD → OT
83
 # Changelog: WCD → OT
65
 
84
 

+ 22
- 4
sections/api/autofill/doi.php View File

1
 <?php
1
 <?php
2
-#declare(strict_types=1);
2
+declare(strict_types=1);
3
+
4
+$ENV = ENV::go();
3
 
5
 
4
 if (!$_GET['doi']) {
6
 if (!$_GET['doi']) {
5
-    json_die();
7
+    json_error('expected doi param');
8
+} elseif (!preg_match("/$ENV->DOI_REGEX/", strtoupper($_GET['doi']))) {
9
+    json_error('expected valid doi');
10
+} else {
11
+    $DOI = $_GET['doi'];
6
 }
12
 }
7
 
13
 
14
+# https://weichie.com/blog/curl-api-calls-with-php/
15
+$curl = curl_init();
16
+curl_setopt($curl, CURLOPT_URL, "$ENV->SS/$DOI");
17
+curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
18
+curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
19
+$output = curl_exec($curl);
20
+curl_close($curl);
21
+
22
+# I don't like this nested json_*code() business
23
+# It's slow and unnecesary since SS already outputs JSON
24
+# todo: At least cache the response, then refactor
8
 print
25
 print
9
     json_encode(
26
     json_encode(
10
         [
27
         [
11
             'status' => 'success',
28
             'status' => 'success',
12
-            'response' => ['loadAverage' => sys_getloadavg()]
13
-        ]
29
+            'response' => json_decode($output, true),
30
+        ],
31
+        JSON_UNESCAPED_SLASHES
14
     );
32
     );

+ 1
- 0
sections/api/index.php View File

266
   */
266
   */
267
 
267
 
268
   case 'autofill':
268
   case 'autofill':
269
+    require_once "$ENV->SERVER_ROOT/sections/api/autofill/doi.php";
269
     /*
270
     /*
270
     if ($_GET['cat'] === 'anime') {
271
     if ($_GET['cat'] === 'anime') {
271
         require_once "$ENV->SERVER_ROOT/sections/api/autofill/anime.php";
272
         require_once "$ENV->SERVER_ROOT/sections/api/autofill/anime.php";

+ 4
- 4
sections/better/better.php View File

24
 </h3>
24
 </h3>
25
 
25
 
26
 <div class="box pad">
26
 <div class="box pad">
27
-  <table>
27
+  <table class="better_list">
28
     <tr class="colhead">
28
     <tr class="colhead">
29
       <td style="width: 150px;">Method</td>
29
       <td style="width: 150px;">Method</td>
30
       <td style="width: 400px;">Additional Information</td>
30
       <td style="width: 400px;">Additional Information</td>
42
 
42
 
43
     <tr class="row">
43
     <tr class="row">
44
       <td class="nobr">
44
       <td class="nobr">
45
-        <a href="better.php?method=screenshots&filter=all">Publications</a>
45
+        <a href="better.php?method=literature&filter=all">DOI numbers</a>
46
       </td>
46
       </td>
47
 
47
 
48
       <td class="nobr">
48
       <td class="nobr">
49
-        When a torrent group doesn't have a publication
49
+        Torrent groups without citations, for enhanced metadata support
50
       </td>
50
       </td>
51
     </tr>
51
     </tr>
52
 
52
 
55
         <a href="better.php?method=covers&filter=all">Pictures</a>
55
         <a href="better.php?method=covers&filter=all">Pictures</a>
56
       </td>
56
       </td>
57
       <td class="nobr">
57
       <td class="nobr">
58
-        When a torrent group doesn't have a picture
58
+        Torrent groups without pictures, for at-a-glance context
59
       </td>
59
       </td>
60
     </tr>
60
     </tr>
61
 
61
 

+ 3
- 3
sections/better/index.php View File

1
 <?php
1
 <?php
2
 declare(strict_types=1);
2
 declare(strict_types=1);
3
 
3
 
4
-enforce_login();
4
+#enforce_login();
5
 
5
 
6
 if (isset($_GET['method'])) {
6
 if (isset($_GET['method'])) {
7
     switch ($_GET['method']) {
7
     switch ($_GET['method']) {
9
       require_once SERVER_ROOT.'/sections/better/single.php';
9
       require_once SERVER_ROOT.'/sections/better/single.php';
10
       break;
10
       break;
11
   
11
   
12
-    case 'screenshots':
13
-      require_once SERVER_ROOT.'/sections/better/screenshots.php';
12
+    case 'literature':
13
+      require_once SERVER_ROOT.'/sections/better/literature.php';
14
       break;
14
       break;
15
 
15
 
16
     case 'covers':
16
     case 'covers':

sections/better/screenshots.php → sections/better/literature.php View File

3
 
3
 
4
 $All = (!empty($_GET['filter']) && $_GET['filter'] === 'all');
4
 $All = (!empty($_GET['filter']) && $_GET['filter'] === 'all');
5
 $Join = $All
5
 $Join = $All
6
-? ''
7
-: (
8
-    'JOIN torrents AS t ON t.GroupID=tg.ID
9
-    JOIN xbt_snatched AS x ON x.fid = t.ID AND x.uid = '
10
-    . $LoggedUser['ID']
11
-);
6
+    ? ''
7
+    : ("
8
+        JOIN `torrents` AS t ON t.`GroupID` = tg.`id`
9
+        JOIN `xbt_snatched` AS x ON x.`fid` = t.`ID`
10
+        AND x.`uid` = '$LoggedUser[ID]'
11
+    ");
12
 
12
 
13
 View::show_header('Torrent groups with no publications');
13
 View::show_header('Torrent groups with no publications');
14
 
14
 
15
-$DB->query("
15
+$DB->prepared_query("
16
 SELECT SQL_CALC_FOUND_ROWS
16
 SELECT SQL_CALC_FOUND_ROWS
17
-  tg.`ID`
17
+  tg.`id`
18
 FROM
18
 FROM
19
   `torrents_group` AS tg
19
   `torrents_group` AS tg
20
 $Join
20
 $Join
21
 WHERE
21
 WHERE
22
-  tg.`ID` NOT IN(
22
+  tg.`id` NOT IN(
23
   SELECT DISTINCT
23
   SELECT DISTINCT
24
-    `TorrentID`
24
+    `group_id`
25
   FROM
25
   FROM
26
-    `torrents_doi`
26
+    `literature`
27
   )
27
   )
28
 ORDER BY
28
 ORDER BY
29
   RAND()
29
   RAND()
30
 LIMIT 20
30
 LIMIT 20
31
 ");
31
 ");
32
 
32
 
33
-$Groups = $DB->to_array('ID', MYSQLI_ASSOC);
33
+$Groups = $DB->to_array('id', MYSQLI_ASSOC);
34
 $DB->query('SELECT FOUND_ROWS()');
34
 $DB->query('SELECT FOUND_ROWS()');
35
 list($NumResults) = $DB->next_record();
35
 list($NumResults) = $DB->next_record();
36
-$Results = Torrents::get_groups(array_keys($Groups));
37
-?>
36
+$Results = Torrents::get_groups(array_keys($Groups)); ?>
38
 
37
 
39
 <div class="header">
38
 <div class="header">
40
   <?php if ($All) { ?>
39
   <?php if ($All) { ?>
41
   <h2>
40
   <h2>
42
-    All groups with no publications
41
+    All groups with no DOI numbers
43
   </h2>
42
   </h2>
44
 
43
 
45
   <?php } else { ?>
44
   <?php } else { ?>
46
   <h2>
45
   <h2>
47
-    Torrent groups with no publications that you have snatched
46
+    Torrent groups with no DOI numbers that you have snatched
48
   </h2>
47
   </h2>
49
   <?php } ?>
48
   <?php } ?>
50
 
49
 
51
   <div class="linkbox">
50
   <div class="linkbox">
52
     <a href="better.php" class="brackets">Back to better.php list</a>
51
     <a href="better.php" class="brackets">Back to better.php list</a>
53
     <?php if ($All) { ?>
52
     <?php if ($All) { ?>
54
-    <a href="better.php?method=screenshots" class="brackets">Show only those you have snatched</a>
53
+    <a href="better.php?method=literature" class="brackets">Show only those you have snatched</a>
55
     <?php } else { ?>
54
     <?php } else { ?>
56
-    <a href="better.php?method=screenshots&amp;filter=all" class="brackets">Show all</a>
55
+    <a href="better.php?method=literature&amp;filter=all" class="brackets">Show all</a>
57
     <?php } ?>
56
     <?php } ?>
58
   </div>
57
   </div>
59
 </div>
58
 </div>
67
     <?php
66
     <?php
68
 foreach ($Results as $Result) {
67
 foreach ($Results as $Result) {
69
     extract($Result);
68
     extract($Result);
70
-    $LangName = $Name ? $Name : ($Title2 ? $Title2 : $NameJP);
71
-    $TorrentTags = new Tags($TagList);
69
+    $LangName = $title ? $title : ($subject ? $subject : $object);
70
+    $TorrentTags = new Tags($tag_list);
72
 
71
 
73
-    $DisplayName = "<a href='torrents.php?id=$ID' ";
72
+    $DisplayName = "<a href='torrents.php?id=$id' ";
74
     if (!isset($LoggedUser['CoverArt']) || $LoggedUser['CoverArt']) {
73
     if (!isset($LoggedUser['CoverArt']) || $LoggedUser['CoverArt']) {
75
-        $DisplayName .= 'data-cover="'.ImageTools::process($WikiImage, 'thumb').'" ';
74
+        $DisplayName .= 'data-cover="'.ImageTools::process($picture, 'thumb').'" ';
76
     }
75
     }
77
     $DisplayName .= ">$LangName</a>";
76
     $DisplayName .= ">$LangName</a>";
78
 
77
 
79
-    if ($Year > 0) {
80
-        $DisplayName .= " [$Year]";
78
+    if ($year > 0) {
79
+        $DisplayName .= " [$year]";
81
     } ?>
80
     } ?>
82
 
81
 
83
     <tr class="torrent">
82
     <tr class="torrent">
84
       <td>
83
       <td>
85
-        <div class="<?=Format::css_category($CategoryID)?>"></div>
84
+        <div class="<?=Format::css_category($category_id)?>"></div>
86
       </td>
85
       </td>
87
 
86
 
88
       <td>
87
       <td>

+ 9
- 9
sections/better/single.php View File

1
 <?php
1
 <?php
2
+declare(strict_types = 1);
3
+
2
 if (($Results = $Cache->get_value('better_single_groupids')) === false) {
4
 if (($Results = $Cache->get_value('better_single_groupids')) === false) {
3
     $DB->query("
5
     $DB->query("
4
     SELECT
6
     SELECT
5
-      t.ID AS TorrentID,
6
-      t.GroupID AS GroupID
7
-    FROM xbt_files_users AS x
8
-      JOIN torrents AS t ON t.ID=x.fid
9
-    GROUP BY x.fid
10
-    HAVING COUNT(x.uid) = 1
7
+      t.`ID` AS `TorrentID`,
8
+      t.`GroupID` AS `GroupID`
9
+    FROM `xbt_files_users` AS x
10
+      JOIN `torrents` AS t ON t.`ID`=x.`fid`
11
+    GROUP BY x.`fid`
12
+    HAVING COUNT(x.`uid`) = 1
11
     LIMIT 30");
13
     LIMIT 30");
12
 
14
 
13
     $Results = $DB->to_pair('GroupID', 'TorrentID', false);
15
     $Results = $DB->to_pair('GroupID', 'TorrentID', false);
15
 }
17
 }
16
 
18
 
17
 $Groups = Torrents::get_groups(array_keys($Results));
19
 $Groups = Torrents::get_groups(array_keys($Results));
18
-
19
-View::show_header('Single seeder torrents');
20
-?>
20
+View::show_header('Single seeder torrents'); ?>
21
 
21
 
22
 <div class="header">
22
 <div class="header">
23
   <h2>
23
   <h2>

+ 15
- 13
sections/bookmarks/torrents.php View File

66
         }
66
         }
67
     }
67
     }
68
 
68
 
69
-    $TorrentTags = new Tags($TagList);
70
-    $DisplayName = Artists::display_artists($Artists);
71
-    $GroupName = empty($GroupName) ? (empty($GroupTitle2) ? $GroupNameJP : $GroupTitle2) : $GroupName;
69
+    $TorrentTags = new Tags($tag_list);
70
+    $DisplayName = '';
71
+    #$DisplayName = Artists::display_artists($Artists);
72
+    $GroupName = empty($title) ? (empty($subject) ? $object : $subject) : $title;
72
     
73
     
73
     $DisplayName .= '<a href="torrents.php?id='.$GroupID.'" ';
74
     $DisplayName .= '<a href="torrents.php?id='.$GroupID.'" ';
74
     if (!isset($LoggedUser['CoverArt']) || $LoggedUser['CoverArt']) {
75
     if (!isset($LoggedUser['CoverArt']) || $LoggedUser['CoverArt']) {
75
-        $DisplayName .= 'data-cover="'.ImageTools::process($WikiImage, 'thumb').'" ';
76
+        $DisplayName .= 'data-cover="'.ImageTools::process($picture, 'thumb').'" ';
76
     }
77
     }
77
 
78
 
78
     $DisplayName .= ' class="tooltip" title="View torrent group" dir="ltr">'.$GroupName.'</a>';
79
     $DisplayName .= ' class="tooltip" title="View torrent group" dir="ltr">'.$GroupName.'</a>';
79
-    if ($GroupYear > 0) {
80
-        $DisplayName = "$DisplayName [$GroupYear]";
80
+    if ($year > 0) {
81
+        $DisplayName = "$DisplayName [$year]";
81
     }
82
     }
82
     $SnatchedGroupClass = $GroupFlags['IsSnatched'] ? ' snatched_group' : '';
83
     $SnatchedGroupClass = $GroupFlags['IsSnatched'] ? ' snatched_group' : '';
83
 
84
 
159
         $TorrentID = key($Torrents);
160
         $TorrentID = key($Torrents);
160
         $Torrent = current($Torrents);
161
         $Torrent = current($Torrents);
161
 
162
 
162
-        $DisplayName = Artists::display_artists(Artists::get_artist($GroupID));
163
+        $DisplayName = '';
164
+        #$DisplayName = Artists::display_artists(Artists::get_artist($GroupID));
163
         $DisplayName .= '<a href="torrents.php?id='.$GroupID.'" ';
165
         $DisplayName .= '<a href="torrents.php?id='.$GroupID.'" ';
164
 
166
 
165
         if (!isset($LoggedUser['CoverArt']) || $LoggedUser['CoverArt']) {
167
         if (!isset($LoggedUser['CoverArt']) || $LoggedUser['CoverArt']) {
166
-            $DisplayName .= 'data-cover="'.ImageTools::process($WikiImage, 'thumb').'" ';
168
+            $DisplayName .= 'data-cover="'.ImageTools::process($picture, 'thumb').'" ';
167
         }
169
         }
168
 
170
 
169
         $DisplayName .=' class="tooltip" title="View torrent group" dir="ltr">'.$GroupName.'</a>';
171
         $DisplayName .=' class="tooltip" title="View torrent group" dir="ltr">'.$GroupName.'</a>';
241
     #$DisplayName .= Artists::display_artists($Artists, false);
243
     #$DisplayName .= Artists::display_artists($Artists, false);
242
     $DisplayName .= $GroupName;
244
     $DisplayName .= $GroupName;
243
 
245
 
244
-    if ($GroupYear > 0) {
245
-        $DisplayName = "$DisplayName [$GroupYear]";
246
+    if ($year > 0) {
247
+        $DisplayName = "$DisplayName [$year]";
246
     }
248
     }
247
 
249
 
248
     $Tags = display_str($TorrentTags->format());
250
     $Tags = display_str($TorrentTags->format());
252
   <a href="torrents.php?id=<?=$GroupID?>"
254
   <a href="torrents.php?id=<?=$GroupID?>"
253
     class="bookmark_<?=$GroupID?>">
255
     class="bookmark_<?=$GroupID?>">
254
 
256
 
255
-    <?php if (!$WikiImage) {
256
-        $WikiImage = STATIC_SERVER.'common/noartwork/music.png';
257
+    <?php if (!$picture) {
258
+        $picture = STATIC_SERVER.'common/noartwork/music.png';
257
     } ?>
259
     } ?>
258
 
260
 
259
     <img class="tooltip"
261
     <img class="tooltip"
260
-      src="<?=ImageTools::process($WikiImage, 'thumb')?>"
262
+      src="<?=ImageTools::process($picture, 'thumb')?>"
261
       alt="<?=$DisplayName?>"
263
       alt="<?=$DisplayName?>"
262
       title="<?=$DisplayName?>"
264
       title="<?=$DisplayName?>"
263
       data-title-plain="<?=$DisplayName?>" width="100%" />
265
       data-title-plain="<?=$DisplayName?>" width="100%" />

+ 2
- 2
sections/collages/browse.php View File

180
         <input type="hidden" name="action" value="search" />
180
         <input type="hidden" name="action" value="search" />
181
       </div>
181
       </div>
182
 
182
 
183
-      <table cellpadding="6" cellspacing="1" border="0" class="layout" width="100%">
183
+      <table cellpadding="6" cellspacing="1" border="0" class="layout torrent_search" width="100%">
184
         <tr id="search_terms">
184
         <tr id="search_terms">
185
           <td class="label"></td>
185
           <td class="label"></td>
186
           <td>
186
           <td>
262
         </tr>
262
         </tr>
263
         <tr>
263
         <tr>
264
           <td colspan="2" class="center">
264
           <td colspan="2" class="center">
265
-            <input type="submit" value="Search" />
265
+            <input type="submit" class="button-primary" value="Search" />
266
           </td>
266
           </td>
267
         </tr>
267
         </tr>
268
       </table>
268
       </table>

+ 2
- 2
sections/collages/edit.php View File

44
         value="<?=$LoggedUser['AuthKey']?>" />
44
         value="<?=$LoggedUser['AuthKey']?>" />
45
       <input type="hidden" name="collageid"
45
       <input type="hidden" name="collageid"
46
         value="<?=$CollageID?>" />
46
         value="<?=$CollageID?>" />
47
-      <table id="edit_collage" class="layout">
47
+      <table id="edit_collage" class="layout collage_edit">
48
         <?php if (check_perms('site_collages_delete') || ($CategoryID == 0 && $UserID == $LoggedUser['ID'] && check_perms('site_collages_renamepersonal'))) { ?>
48
         <?php if (check_perms('site_collages_delete') || ($CategoryID == 0 && $UserID == $LoggedUser['ID'] && check_perms('site_collages_renamepersonal'))) { ?>
49
         <tr>
49
         <tr>
50
           <td class="label">Name</td>
50
           <td class="label">Name</td>
117
 
117
 
118
         <?php } ?>
118
         <?php } ?>
119
         <tr>
119
         <tr>
120
-          <td colspan="2" class="center"><input type="submit" value="Edit" /></td>
120
+          <td colspan="2" class="center"><input type="submit" class="button-primary" value="Edit" /></td>
121
         </tr>
121
         </tr>
122
       </table>
122
       </table>
123
     </form>
123
     </form>

+ 1
- 1
sections/collages/new.php View File

136
 
136
 
137
         <tr>
137
         <tr>
138
           <td colspan="2" class="center">
138
           <td colspan="2" class="center">
139
-            <input type="submit" value="Create" />
139
+            <input type="submit" class="button-primary" value="Create" />
140
           </td>
140
           </td>
141
         </tr>
141
         </tr>
142
       </table>
142
       </table>

+ 6
- 11
sections/collages/torrent_collage.php View File

231
   id="group_<?=$GroupID?>">
231
   id="group_<?=$GroupID?>">
232
   <td></td>
232
   <td></td>
233
 
233
 
234
-  <td class="center">
235
-    <div title="<?=$TorrentTags->title()?>"
236
-      class="tooltip <?=Format::css_category($GroupCategoryID)?> <?=$TorrentTags->css_name()?>">
237
-    </div>
238
-  </td>
234
+  <td></td>
239
 
235
 
240
   <td>
236
   <td>
241
     <span class="brackets">
237
     <span class="brackets">
584
             value="<?=$LoggedUser['AuthKey']?>" />
580
             value="<?=$LoggedUser['AuthKey']?>" />
585
           <input type="hidden" name="collageid"
581
           <input type="hidden" name="collageid"
586
             value="<?=$CollageID?>" />
582
             value="<?=$CollageID?>" />
587
-          <div>
588
-            <input type="text" size="20" name="url" />
589
-          </div>
583
+
590
           <div class="submit_div">
584
           <div class="submit_div">
591
-            <input type="submit" value="Add" />
585
+            <input type="text" size="20" name="url" />
586
+            <input type="submit" class="button-primary" value="Add" />
592
           </div>
587
           </div>
593
-          <span style="font-style: italic;">Enter the URL of a torrent group on the site.</span>
588
+          <p>Enter the URL of a torrent group on the site.</p>
594
         </form>
589
         </form>
595
       </div>
590
       </div>
596
 
591
 
672
             <textarea name="body" cols="24" rows="5"></textarea>
667
             <textarea name="body" cols="24" rows="5"></textarea>
673
           </div>
668
           </div>
674
           <div class="submit_div">
669
           <div class="submit_div">
675
-            <input type="submit" id="submit_button" value="Post" />
670
+            <input type="submit" id="submit_button" class="button-primary" value="Post" />
676
           </div>
671
           </div>
677
         </div>
672
         </div>
678
       </form>
673
       </form>

+ 113
- 64
sections/comments/comments.php View File

1
 <?
1
 <?
2
-/*
2
+declare(strict_types=1);
3
+
4
+/**
3
  * $_REQUEST['action'] is artist, collages, requests or torrents (default torrents)
5
  * $_REQUEST['action'] is artist, collages, requests or torrents (default torrents)
4
  * $_REQUEST['type'] depends on the page:
6
  * $_REQUEST['type'] depends on the page:
5
  *     collages:
7
  *     collages:
16
 // User ID
18
 // User ID
17
 if (isset($_GET['id']) && is_number($_GET['id'])) {
19
 if (isset($_GET['id']) && is_number($_GET['id'])) {
18
   $UserID = (int)$_GET['id'];
20
   $UserID = (int)$_GET['id'];
19
-
20
   $UserInfo = Users::user_info($UserID);
21
   $UserInfo = Users::user_info($UserID);
21
-
22
   $Username = $UserInfo['Username'];
22
   $Username = $UserInfo['Username'];
23
-  if ($LoggedUser['ID'] == $UserID) {
23
+
24
+  if ($LoggedUser['ID'] === $UserID) {
24
     $Self = true;
25
     $Self = true;
25
   } else {
26
   } else {
26
     $Self = false;
27
     $Self = false;
27
   }
28
   }
29
+
28
   $Perms = Permissions::get_permissions($UserInfo['PermissionID']);
30
   $Perms = Permissions::get_permissions($UserInfo['PermissionID']);
29
   $UserClass = $Perms['Class'];
31
   $UserClass = $Perms['Class'];
32
+
30
   if (!check_paranoia('torrentcomments', $UserInfo['Paranoia'], $UserClass, $UserID)) {
33
   if (!check_paranoia('torrentcomments', $UserInfo['Paranoia'], $UserClass, $UserID)) {
31
     error(403);
34
     error(403);
32
   }
35
   }
49
 } else {
52
 } else {
50
   $Action = $_REQUEST['action'];
53
   $Action = $_REQUEST['action'];
51
 }
54
 }
55
+
52
 if (!isset($_REQUEST['type'])) {
56
 if (!isset($_REQUEST['type'])) {
53
   $Type = 'default';
57
   $Type = 'default';
54
 } else {
58
 } else {
55
   $Type = $_REQUEST['type'];
59
   $Type = $_REQUEST['type'];
56
 }
60
 }
57
 
61
 
62
+
58
 // Construct the SQL query
63
 // Construct the SQL query
64
+
59
 $Conditions = $Join = [];
65
 $Conditions = $Join = [];
60
 switch ($Action) {
66
 switch ($Action) {
67
+  # artist comments
61
   case 'artist':
68
   case 'artist':
62
-    $Field1 = 'artists_group.ArtistID';
63
-    $Field2 = 'artists_group.Name';
64
-    $Table = 'artists_group';
69
+    $Field1 = '`artists_group`.`ArtistID`';
70
+    $Field2 = '`artists_group`.`Name`';
71
+    $Table = '`artists_group`';
65
     $Title = 'Artist comments left by ' . ($Self ? 'you' : $Username);
72
     $Title = 'Artist comments left by ' . ($Self ? 'you' : $Username);
66
     $Header = 'Artist comments left by ' . ($Self ? 'you' : Users::format_username($UserID, false, false, false));
73
     $Header = 'Artist comments left by ' . ($Self ? 'you' : Users::format_username($UserID, false, false, false));
67
-    $Conditions[] = "comments.AuthorID = $UserID";
74
+    $Conditions[] = "`comments`.`AuthorID` = $UserID";
68
     break;
75
     break;
76
+
77
+  
78
+  # collage comments
69
   case 'collages':
79
   case 'collages':
70
-    $Field1 = 'collages.ID';
71
-    $Field2 = 'collages.Name';
72
-    $Table = 'collages';
73
-    $Conditions[] = "collages.Deleted = '0'";
80
+    $Field1 = '`collages`.`ID`';
81
+    $Field2 = '`collages`.`Name`';
82
+    $Table = '`collages`';
83
+    $Conditions[] = "`collages`.`Deleted` = '0'";
84
+
74
     if ($Type == 'created') {
85
     if ($Type == 'created') {
75
-      $Conditions[] = "collages.UserID = $UserID";
76
-      $Conditions[] = "comments.AuthorID != $UserID";
86
+      $Conditions[] = "`collages`.`UserID` = $UserID";
87
+      $Conditions[] = "`comments`.`AuthorID` != $UserID";
77
       $Title = 'Comments left on collages ' . ($Self ? 'you' : $Username) . ' created';
88
       $Title = 'Comments left on collages ' . ($Self ? 'you' : $Username) . ' created';
78
       $Header = 'Comments left on collages ' . ($Self ? 'you' : Users::format_username($UserID, false, false, false)) . ' created';
89
       $Header = 'Comments left on collages ' . ($Self ? 'you' : Users::format_username($UserID, false, false, false)) . ' created';
79
     } elseif ($Type == 'contributed') {
90
     } elseif ($Type == 'contributed') {
80
-      $Conditions[] = 'IF(collages.CategoryID = ' . array_search('Artists', $CollageCats) . ', collages_artists.ArtistID, collages_torrents.GroupID) IS NOT NULL';
81
-      $Conditions[] = "comments.AuthorID != $UserID";
82
-      $Join[] = "LEFT JOIN collages_torrents ON collages_torrents.CollageID = collages.ID AND collages_torrents.UserID = $UserID";
83
-      $Join[] = "LEFT JOIN collages_artists ON collages_artists.CollageID = collages.ID AND collages_artists.UserID = $UserID";
91
+      $Conditions[] = 'IF(`collages`.`CategoryID` = ' . array_search('Artists', $CollageCats) . ', `collages_artists`.`ArtistID`, `collages_torrents`.`GroupID`) IS NOT NULL';
92
+      $Conditions[] = "`comments`.`AuthorID` != $UserID";
93
+      $Join[] = "LEFT JOIN `collages_torrents` ON `collages_torrents`.`CollageID` = `collages`.`ID` AND `collages_torrents`.`UserID` = $UserID";
94
+      $Join[] = "LEFT JOIN `collages_artists` ON `collages_artists`.`CollageID` = `collages`.`ID` AND `collages_artists`.`UserID` = $UserID";
84
       $Title = 'Comments left on collages ' . ($Self ? 'you\'ve' : $Username . ' has') . ' contributed to';
95
       $Title = 'Comments left on collages ' . ($Self ? 'you\'ve' : $Username . ' has') . ' contributed to';
85
       $Header = 'Comments left on collages ' . ($Self ? 'you\'ve' : Users::format_username($UserID, false, false, false).' has') . ' contributed to';
96
       $Header = 'Comments left on collages ' . ($Self ? 'you\'ve' : Users::format_username($UserID, false, false, false).' has') . ' contributed to';
86
     } else {
97
     } else {
87
       $Type = 'default';
98
       $Type = 'default';
88
-      $Conditions[] = "comments.AuthorID = $UserID";
99
+      $Conditions[] = "`comments`.`AuthorID` = $UserID";
89
       $Title = 'Collage comments left by ' . ($Self ? 'you' : $Username);
100
       $Title = 'Collage comments left by ' . ($Self ? 'you' : $Username);
90
       $Header = 'Collage comments left by ' . ($Self ? 'you' : Users::format_username($UserID, false, false, false));
101
       $Header = 'Collage comments left by ' . ($Self ? 'you' : Users::format_username($UserID, false, false, false));
91
     }
102
     }
92
     break;
103
     break;
104
+
105
+
106
+  # request comments
93
   case 'requests':
107
   case 'requests':
94
-    $Field1 = 'requests.ID';
95
-    $Field2 = 'requests.Title';
108
+    $Field1 = '`requests`.`ID`';
109
+    $Field2 = '`requests`.`Title`';
96
     $Table = 'requests';
110
     $Table = 'requests';
111
+
97
     if ($Type == 'created') {
112
     if ($Type == 'created') {
98
-      $Conditions[] = "requests.UserID = $UserID";
99
-      $Conditions[] = "comments.AuthorID != $UserID";
113
+      $Conditions[] = "`requests`.`UserID` = $UserID";
114
+      $Conditions[] = "`comments`.`AuthorID` != $UserID";
100
       $Title = 'Comments left on requests ' . ($Self ? 'you' : $Username) . ' created';
115
       $Title = 'Comments left on requests ' . ($Self ? 'you' : $Username) . ' created';
101
       $Header = 'Comments left on requests ' . ($Self ? 'you' : Users::format_username($UserID, false, false, false)) . ' created';
116
       $Header = 'Comments left on requests ' . ($Self ? 'you' : Users::format_username($UserID, false, false, false)) . ' created';
102
     } elseif ($Type == 'voted') {
117
     } elseif ($Type == 'voted') {
103
-      $Conditions[] = "requests_votes.UserID = $UserID";
104
-      $Conditions[] = "comments.AuthorID != $UserID";
105
-      $Join[] = 'JOIN requests_votes ON requests_votes.RequestID = requests.ID';
118
+      $Conditions[] = "`requests_votes`.`UserID` = $UserID";
119
+      $Conditions[] = "`comments`.`AuthorID` != $UserID";
120
+      $Join[] = 'JOIN `requests_votes` ON `requests_votes`.`RequestID` = `requests`.`ID`';
106
       $Title = 'Comments left on requests ' . ($Self ? 'you\'ve' : $Username . ' has') . ' voted on';
121
       $Title = 'Comments left on requests ' . ($Self ? 'you\'ve' : $Username . ' has') . ' voted on';
107
       $Header = 'Comments left on requests ' . ($Self ? 'you\'ve' : Users::format_username($UserID, false, false, false) . ' has') . ' voted on';
122
       $Header = 'Comments left on requests ' . ($Self ? 'you\'ve' : Users::format_username($UserID, false, false, false) . ' has') . ' voted on';
108
     } else {
123
     } else {
109
       $Type = 'default';
124
       $Type = 'default';
110
-      $Conditions[] = "comments.AuthorID = $UserID";
125
+      $Conditions[] = "`comments`.`AuthorID` = $UserID";
111
       $Title = 'Request comments left by ' . ($Self ? 'you' : $Username);
126
       $Title = 'Request comments left by ' . ($Self ? 'you' : $Username);
112
       $Header = 'Request comments left by ' . ($Self ? 'you' : Users::format_username($UserID, false, false, false));
127
       $Header = 'Request comments left by ' . ($Self ? 'you' : Users::format_username($UserID, false, false, false));
113
     }
128
     }
114
     break;
129
     break;
130
+
131
+
132
+  # torrent comments
115
   case 'torrents':
133
   case 'torrents':
116
   default:
134
   default:
117
     $Action = 'torrents';
135
     $Action = 'torrents';
118
-    $Field1 = 'torrents.GroupID';
119
-    $Field2 = "COALESCE(NULLIF(tg.Name,''),NULLIF(tg.Title2,''),tg.NameJP) AS Name";
120
-    $Table = 'torrents';
121
-    $Join[] = 'JOIN torrents_group AS tg ON torrents.GroupID = tg.ID';
136
+    $Field1 = '`torrents`.`GroupID`';
137
+    $Field2 = "COALESCE(NULLIF(tg.`title`,''),NULLIF(tg.`subject`,''),tg.`object`) AS Name";
138
+    $Table = '`torrents`';
139
+    $Join[] = 'JOIN `torrents_group` AS tg ON `torrents`.`GroupID` = tg.`id`';
140
+
122
     if ($Type == 'uploaded') {
141
     if ($Type == 'uploaded') {
123
-      $Conditions[] = "torrents.UserID = $UserID";
124
-      $Conditions[] = 'comments.AddedTime > torrents.Time';
125
-      $Conditions[] = "comments.AuthorID != $UserID";
142
+      $Conditions[] = "`torrents`.`UserID` = $UserID";
143
+      $Conditions[] = '`comments`.`AddedTime` > `torrents`.`Time`';
144
+      $Conditions[] = "`comments`.`AuthorID` != $UserID";
126
       $Title = 'Comments left on torrents ' . ($Self ? 'you\'ve' : $Username . ' has') . ' uploaded';
145
       $Title = 'Comments left on torrents ' . ($Self ? 'you\'ve' : $Username . ' has') . ' uploaded';
127
       $Header = 'Comments left on torrents ' . ($Self ? 'you\'ve' : Users::format_username($UserID, false, false, false) . ' has') . ' uploaded';
146
       $Header = 'Comments left on torrents ' . ($Self ? 'you\'ve' : Users::format_username($UserID, false, false, false) . ' has') . ' uploaded';
128
     } else {
147
     } else {
129
       $Type = 'default';
148
       $Type = 'default';
130
-      $Conditions[] = "comments.AuthorID = $UserID";
149
+      $Conditions[] = "`comments`.`AuthorID` = $UserID";
131
       $Title = 'Torrent comments left by ' . ($Self ? 'you' : $Username);
150
       $Title = 'Torrent comments left by ' . ($Self ? 'you' : $Username);
132
       $Header = 'Torrent comments left by ' . ($Self ? 'you' : Users::format_username($UserID, false, false, false));
151
       $Header = 'Torrent comments left by ' . ($Self ? 'you' : Users::format_username($UserID, false, false, false));
133
     }
152
     }
134
     break;
153
     break;
135
 }
154
 }
136
-$Join[] = "JOIN comments ON comments.Page = '$Action' AND comments.PageID = $Field1";
155
+
156
+# end SQL query constructor
157
+
158
+
159
+$Join[] = "JOIN `comments` ON `comments`.`Page` = '$Action' AND `comments`.`PageID` = $Field1";
137
 $Join = implode("\n\t\t", $Join);
160
 $Join = implode("\n\t\t", $Join);
138
 $Conditions = implode(" AND ", $Conditions);
161
 $Conditions = implode(" AND ", $Conditions);
139
 $Conditions = ($Conditions ? 'WHERE ' . $Conditions : '');
162
 $Conditions = ($Conditions ? 'WHERE ' . $Conditions : '');
141
 $SQL = "
164
 $SQL = "
142
   SELECT
165
   SELECT
143
     SQL_CALC_FOUND_ROWS
166
     SQL_CALC_FOUND_ROWS
144
-    comments.AuthorID,
145
-    comments.Page,
146
-    comments.PageID,
167
+    `comments`.`AuthorID`,
168
+    `comments`.`Page`,
169
+    `comments`.`PageID`,
147
     $Field2,
170
     $Field2,
148
-    comments.ID,
149
-    comments.Body,
150
-    comments.AddedTime,
151
-    comments.EditedTime,
152
-    comments.EditedUserID
171
+    `comments`.`ID`,
172
+    `comments`.`Body`,
173
+    `comments`.`AddedTime`,
174
+    `comments`.`EditedTime`,
175
+    `comments`.`EditedUserID`
153
   FROM $Table
176
   FROM $Table
154
     $Join
177
     $Join
155
   $Conditions
178
   $Conditions
156
-  GROUP BY comments.ID
157
-  ORDER BY comments.ID DESC
179
+  GROUP BY `comments`.`ID`
180
+  ORDER BY `comments`.`ID` DESC
158
   LIMIT $Limit";
181
   LIMIT $Limit";
159
 
182
 
160
 $Comments = $DB->query($SQL);
183
 $Comments = $DB->query($SQL);
163
 $DB->query("SELECT FOUND_ROWS()");
186
 $DB->query("SELECT FOUND_ROWS()");
164
 list($Results) = $DB->next_record();
187
 list($Results) = $DB->next_record();
165
 $Pages = Format::get_pages($Page, $Results, $PerPage, 11);
188
 $Pages = Format::get_pages($Page, $Results, $PerPage, 11);
166
-
167
 $DB->set_query_id($Comments);
189
 $DB->set_query_id($Comments);
168
-if ($Action == 'requests') {
190
+
191
+# Remove the weird comment headings on torrent and request comments
192
+/*
193
+if ($Action === 'requests') {
169
   $RequestIDs = array_flip(array_flip($DB->collect('PageID')));
194
   $RequestIDs = array_flip(array_flip($DB->collect('PageID')));
170
   $Artists = [];
195
   $Artists = [];
196
+
171
   foreach ($RequestIDs as $RequestID) {
197
   foreach ($RequestIDs as $RequestID) {
172
     $Artists[$RequestID] = Requests::get_artists($RequestID);
198
     $Artists[$RequestID] = Requests::get_artists($RequestID);
173
   }
199
   }
174
   $DB->set_query_id($Comments);
200
   $DB->set_query_id($Comments);
175
-} elseif ($Action == 'torrents') {
201
+} elseif ($Action === 'torrents') {
176
   $GroupIDs = array_flip(array_flip($DB->collect('PageID')));
202
   $GroupIDs = array_flip(array_flip($DB->collect('PageID')));
177
   $Artists = Artists::get_artists($GroupIDs);
203
   $Artists = Artists::get_artists($GroupIDs);
178
   $DB->set_query_id($Comments);
204
   $DB->set_query_id($Comments);
179
 }
205
 }
206
+*/
207
+
208
+# Replace the "shifting" main links with regular static ones
209
+# There are already shifting supplemental links for each type
210
+$ActionLinks[] = '<a href="comments.php?action=torrents' . $LinkID . '" class="brackets">Torrent comments</a>';
211
+$ActionLinks[] = '<a href="comments.php?action=collages' . $LinkID . '" class="brackets">Collections comments</a>';
212
+$ActionLinks[] = '<a href="comments.php?action=requests' . $LinkID . '" class="brackets">Request comments</a>';
213
+$ActionLinks[] = '<a href="comments.php?action=artist' . $LinkID . '" class="brackets">Artist comments</a>';
180
 
214
 
215
+/*
181
 $LinkID = (!$Self ? '&amp;id=' . $UserID : '');
216
 $LinkID = (!$Self ? '&amp;id=' . $UserID : '');
182
 $ActionLinks = $TypeLinks = [];
217
 $ActionLinks = $TypeLinks = [];
183
-if ($Action != 'artist') {
218
+if ($Action !== 'artist') {
184
   $ActionLinks[] = '<a href="comments.php?action=artist' . $LinkID . '" class="brackets">Artist comments</a>';
219
   $ActionLinks[] = '<a href="comments.php?action=artist' . $LinkID . '" class="brackets">Artist comments</a>';
185
 }
220
 }
186
-if ($Action != 'collages') {
221
+
222
+if ($Action !== 'collages') {
187
   $ActionLinks[] = '<a href="comments.php?action=collages' . $LinkID . '" class="brackets">Collections comments</a>';
223
   $ActionLinks[] = '<a href="comments.php?action=collages' . $LinkID . '" class="brackets">Collections comments</a>';
188
 }
224
 }
189
-if ($Action != 'requests') {
225
+
226
+if ($Action !== 'requests') {
190
   $ActionLinks[] = '<a href="comments.php?action=requests' . $LinkID . '" class="brackets">Request comments</a>';
227
   $ActionLinks[] = '<a href="comments.php?action=requests' . $LinkID . '" class="brackets">Request comments</a>';
191
 }
228
 }
192
-if ($Action != 'torrents') {
229
+
230
+if ($Action !== 'torrents') {
193
   $ActionLinks[] = '<a href="comments.php?action=torrents' . $LinkID . '" class="brackets">Torrent comments</a>';
231
   $ActionLinks[] = '<a href="comments.php?action=torrents' . $LinkID . '" class="brackets">Torrent comments</a>';
194
 }
232
 }
233
+*/
234
+
195
 switch ($Action) {
235
 switch ($Action) {
196
   case 'collages':
236
   case 'collages':
197
     $BaseLink = 'comments.php?action=collages' . $LinkID;
237
     $BaseLink = 'comments.php?action=collages' . $LinkID;
198
-    if ($Type != 'default') {
238
+    if ($Type !== 'default') {
199
       $TypeLinks[] = '<a href="' . $BaseLink . '" class="brackets">Display collage comments ' . ($Self ? 'you\'ve' : $Username . ' has') . ' made</a>';
239
       $TypeLinks[] = '<a href="' . $BaseLink . '" class="brackets">Display collage comments ' . ($Self ? 'you\'ve' : $Username . ' has') . ' made</a>';
200
     }
240
     }
201
-    if ($Type != 'created') {
241
+
242
+    if ($Type !== 'created') {
202
       $TypeLinks[] = '<a href="' . $BaseLink . '&amp;type=created" class="brackets">Display comments left on ' . ($Self ? 'your collections' : 'collections created by ' .$Username) . '</a>';
243
       $TypeLinks[] = '<a href="' . $BaseLink . '&amp;type=created" class="brackets">Display comments left on ' . ($Self ? 'your collections' : 'collections created by ' .$Username) . '</a>';
203
     }
244
     }
204
-    if ($Type != 'contributed') {
245
+
246
+    if ($Type !== 'contributed') {
205
       $TypeLinks[] = '<a href="' . $BaseLink . '&amp;type=contributed" class="brackets">Display comments left on collections ' . ($Self ? 'you\'ve' : $Username . ' has') . ' contributed to</a>';
247
       $TypeLinks[] = '<a href="' . $BaseLink . '&amp;type=contributed" class="brackets">Display comments left on collections ' . ($Self ? 'you\'ve' : $Username . ' has') . ' contributed to</a>';
206
     }
248
     }
207
     break;
249
     break;
250
+
208
   case 'requests':
251
   case 'requests':
209
     $BaseLink = 'comments.php?action=requests' . $LinkID;
252
     $BaseLink = 'comments.php?action=requests' . $LinkID;
210
-    if ($Type != 'default') {
253
+    if ($Type !== 'default') {
211
       $TypeLinks[] = '<a href="' . $BaseLink . '" class="brackets">Display request comments you\'ve made</a>';
254
       $TypeLinks[] = '<a href="' . $BaseLink . '" class="brackets">Display request comments you\'ve made</a>';
212
     }
255
     }
213
-    if ($Type != 'created') {
256
+
257
+    if ($Type !== 'created') {
214
       $TypeLinks[] = '<a href="' . $BaseLink . '&amp;type=created" class="brackets">Display comments left on your requests</a>';
258
       $TypeLinks[] = '<a href="' . $BaseLink . '&amp;type=created" class="brackets">Display comments left on your requests</a>';
215
     }
259
     }
216
-    if ($Type != 'voted') {
260
+
261
+    if ($Type !== 'voted') {
217
       $TypeLinks[] = '<a href="' . $BaseLink . '&amp;type=voted" class="brackets">Display comments left on requests you\'ve voted on</a>';
262
       $TypeLinks[] = '<a href="' . $BaseLink . '&amp;type=voted" class="brackets">Display comments left on requests you\'ve voted on</a>';
218
     }
263
     }
219
     break;
264
     break;
265
+
220
   case 'torrents':
266
   case 'torrents':
221
-    if ($Type != 'default') {
267
+    if ($Type !== 'default') {
222
       $TypeLinks[] = '<a href="comments.php?action=torrents' . $LinkID . '" class="brackets">Display comments you have made</a>';
268
       $TypeLinks[] = '<a href="comments.php?action=torrents' . $LinkID . '" class="brackets">Display comments you have made</a>';
223
     }
269
     }
224
-    if ($Type != 'uploaded') {
270
+
271
+    if ($Type !== 'uploaded') {
225
       $TypeLinks[] = '<a href="comments.php?action=torrents' . $LinkID . '&amp;type=uploaded" class="brackets">Display comments left on your uploads</a>';
272
       $TypeLinks[] = '<a href="comments.php?action=torrents' . $LinkID . '&amp;type=uploaded" class="brackets">Display comments left on your uploads</a>';
226
     }
273
     }
227
     break;
274
     break;
250
       case 'artist':
297
       case 'artist':
251
         $Header = " on <a href=\"artist.php?id=$PageID\">$Name</a>";
298
         $Header = " on <a href=\"artist.php?id=$PageID\">$Name</a>";
252
         break;
299
         break;
300
+
253
       case 'collages':
301
       case 'collages':
254
         $Header = " on <a href=\"collages.php?id=$PageID\">$Name</a>";
302
         $Header = " on <a href=\"collages.php?id=$PageID\">$Name</a>";
255
         break;
303
         break;
304
+
256
       case 'requests':
305
       case 'requests':
257
         $Header = ' on ' . Artists::display_artists($Artists[$PageID]) . " <a href=\"requests.php?action=view&id=$PageID\">$Name</a>";
306
         $Header = ' on ' . Artists::display_artists($Artists[$PageID]) . " <a href=\"requests.php?action=view&id=$PageID\">$Name</a>";
258
         break;
307
         break;
308
+
259
       case 'torrents':
309
       case 'torrents':
260
         $Header = ' on ' . Artists::display_artists($Artists[$PageID]) . " <a href=\"torrents.php?id=$PageID\">$Name</a>";
310
         $Header = ' on ' . Artists::display_artists($Artists[$PageID]) . " <a href=\"torrents.php?id=$PageID\">$Name</a>";
261
         break;
311
         break;
263
     CommentsView::render_comment($AuthorID, $PostID, $Body, $AddedTime, $EditedUserID, $EditedTime, $Link, false, $Header, false);
313
     CommentsView::render_comment($AuthorID, $PostID, $Body, $AddedTime, $EditedUserID, $EditedTime, $Link, false, $Header, false);
264
   }
314
   }
265
 } else { ?>
315
 } else { ?>
266
-  <div class="center">No results.</div>
316
+  <h2 class="center">No results.</h2>
267
 <? } ?>
317
 <? } ?>
268
   <div class="linkbox">
318
   <div class="linkbox">
269
     <?=$Pages?>
319
     <?=$Pages?>
270
   </div>
320
   </div>
271
 </div>
321
 </div>
272
-<?
273
-View::show_footer();
322
+<? View::show_footer();

+ 11
- 2
sections/comments/index.php View File

1
 <?
1
 <?
2
+declare(strict_types=1);
3
+
2
 enforce_login();
4
 enforce_login();
3
 
5
 
4
 // fix old links
6
 // fix old links
5
-if ($_REQUEST['action'] == 'artists') {
7
+if ($_REQUEST['action'] === 'artists') {
6
   $_REQUEST['action'] = 'artist';
8
   $_REQUEST['action'] = 'artist';
7
-} elseif ($_REQUEST['action'] == 'my_torrents') {
9
+} elseif ($_REQUEST['action'] === 'my_torrents') {
8
   $_REQUEST['action'] = 'torrents';
10
   $_REQUEST['action'] = 'torrents';
9
   $_REQUEST['type'] = 'uploaded';
11
   $_REQUEST['type'] = 'uploaded';
10
 }
12
 }
18
   case 'take_post':
20
   case 'take_post':
19
     require SERVER_ROOT . '/sections/comments/take_post.php';
21
     require SERVER_ROOT . '/sections/comments/take_post.php';
20
     break;
22
     break;
23
+
21
   case 'take_edit':
24
   case 'take_edit':
22
     require SERVER_ROOT . '/sections/comments/take_edit.php';
25
     require SERVER_ROOT . '/sections/comments/take_edit.php';
23
     break;
26
     break;
27
+
24
   case 'take_delete':
28
   case 'take_delete':
25
     require SERVER_ROOT . '/sections/comments/take_delete.php';
29
     require SERVER_ROOT . '/sections/comments/take_delete.php';
26
     break;
30
     break;
31
+
27
   case 'warn':
32
   case 'warn':
28
     require SERVER_ROOT . '/sections/comments/warn.php';
33
     require SERVER_ROOT . '/sections/comments/warn.php';
29
     break;
34
     break;
35
+
30
   case 'take_warn':
36
   case 'take_warn':
31
     require SERVER_ROOT . '/sections/comments/take_warn.php';
37
     require SERVER_ROOT . '/sections/comments/take_warn.php';
32
     break;
38
     break;
39
+
33
   case 'get':
40
   case 'get':
34
     require SERVER_ROOT . '/sections/comments/get.php';
41
     require SERVER_ROOT . '/sections/comments/get.php';
35
     break;
42
     break;
43
+
36
   case 'jump':
44
   case 'jump':
37
     require SERVER_ROOT . '/sections/comments/jump.php';
45
     require SERVER_ROOT . '/sections/comments/jump.php';
38
     break;
46
     break;
47
+    
39
   case 'artist':
48
   case 'artist':
40
   case 'collages':
49
   case 'collages':
41
   case 'requests':
50
   case 'requests':

+ 15
- 1
sections/donate/donate.php View File

55
 
55
 
56
       <li>
56
       <li>
57
         <strong>Domain.</strong>
57
         <strong>Domain.</strong>
58
-        The domain name is $15 per year.
58
+        The primary domain name (biotorrents.de) is $15 per year.
59
+        The secondary one (torrents.bio) is $80 per year.
59
         The TLS certificates are gratis.
60
         The TLS certificates are gratis.
60
       </li>
61
       </li>
61
 
62
 
64
         Omics Tools LLC is <?= $ENV->SITE_NAME ?>'s parent company.
65
         Omics Tools LLC is <?= $ENV->SITE_NAME ?>'s parent company.
65
         It's $50 per year for annual reports and $125 for resident agent services.
66
         It's $50 per year for annual reports and $125 for resident agent services.
66
       </li>
67
       </li>
68
+
69
+      <li>
70
+        <strong>Legal.</strong>
71
+        Registering a U.S. copyright agent is $6 per year.
72
+        The legal counsel is gratis.
73
+      </li>
74
+
75
+
76
+      <li>
77
+        <strong>Total.</strong>
78
+        Depending on the exchange rate, it costs about $350 per year to run <?= $ENV->SITE_NAME ?>.
79
+      </li>
80
+
67
     </ul>
81
     </ul>
68
   </div>
82
   </div>
69
 
83
 

+ 2
- 2
sections/forums/newthread.php View File

103
       <input type="hidden" name="auth"
103
       <input type="hidden" name="auth"
104
         value="<?=$LoggedUser['AuthKey']?>" />
104
         value="<?=$LoggedUser['AuthKey']?>" />
105
       <input type="hidden" name="forum" value="<?=$ForumID?>" />
105
       <input type="hidden" name="forum" value="<?=$ForumID?>" />
106
-      <table id="newthreadtext" class="layout">
106
+      <table id="newthreadtext" class="layout new_thread">
107
         <tr>
107
         <tr>
108
           <td class="label">Title</td>
108
           <td class="label">Title</td>
109
           <td><input id="title" class="required" type="text" name="title" style="width: 98%;" /></td>
109
           <td><input id="title" class="required" type="text" name="title" style="width: 98%;" /></td>
196
       <div id="buttons" class="center">
196
       <div id="buttons" class="center">
197
         <input type="button" value="Preview" onclick="Newthread_Preview(1);" id="newthreadpreviewbutton" />
197
         <input type="button" value="Preview" onclick="Newthread_Preview(1);" id="newthreadpreviewbutton" />
198
         <input type="button" value="Editor" onclick="Newthread_Preview(0);" id="newthreadeditbutton" class="hidden" />
198
         <input type="button" value="Editor" onclick="Newthread_Preview(0);" id="newthreadeditbutton" class="hidden" />
199
-        <input type="submit" class="submit" id="submit_button" value="Create" />
199
+        <input type="submit" class="submit button-primary" id="submit_button" value="Create" />
200
       </div>
200
       </div>
201
     </form>
201
     </form>
202
   </div>
202
   </div>

+ 47
- 36
sections/friends/friends.php View File

1
 <?php
1
 <?php
2
 #declare(strict_types=1);
2
 #declare(strict_types=1);
3
 
3
 
4
-/************************************************************************
5
-//------------// Main friends page //----------------------------------//
6
-This page lists a user's friends.
4
+/**
5
+ * Main friends page
6
+ * 
7
+ * This page lists a user's friends.
8
+ * There's no real point in caching this page.
9
+ * I doubt users load it that much.
10
+ */
7
 
11
 
8
-There's no real point in caching this page. I doubt users load it that
9
-much.
10
-************************************************************************/
12
+$ENV = ENV::go();
11
 
13
 
12
 // Number of users per page
14
 // Number of users per page
13
 define('FRIENDS_PER_PAGE', '20');
15
 define('FRIENDS_PER_PAGE', '20');
14
-include_once(SERVER_ROOT.'/classes/paranoia.class.php');
15
-
16
-
16
+include_once "$ENV->SERVER_ROOT/classes/paranoia.class.php";
17
 
17
 
18
 View::show_header('Friends');
18
 View::show_header('Friends');
19
 
19
 
20
-
21
 $UserID = $LoggedUser['ID'];
20
 $UserID = $LoggedUser['ID'];
22
-
23
-
24
 list($Page, $Limit) = Format::page_limit(FRIENDS_PER_PAGE);
21
 list($Page, $Limit) = Format::page_limit(FRIENDS_PER_PAGE);
25
 
22
 
26
 // Main query
23
 // Main query
27
 $DB->query("
24
 $DB->query("
28
   SELECT
25
   SELECT
29
     SQL_CALC_FOUND_ROWS
26
     SQL_CALC_FOUND_ROWS
30
-    f.FriendID,
31
-    f.Comment,
32
-    m.Username,
33
-    m.Uploaded,
34
-    m.Downloaded,
35
-    m.PermissionID,
36
-    m.Paranoia,
37
-    m.LastAccess,
38
-    i.Avatar
39
-  FROM friends AS f
40
-    JOIN users_main AS m ON f.FriendID = m.ID
41
-    JOIN users_info AS i ON f.FriendID = i.UserID
42
-  WHERE f.UserID = '$UserID'
43
-  ORDER BY Username
27
+    f.`FriendID`,
28
+    f.`Comment`,
29
+    m.`Username`,
30
+    m.`Uploaded`,
31
+    m.`Downloaded`,
32
+    m.`PermissionID`,
33
+    m.`Paranoia`,
34
+    m.`LastAccess`,
35
+    i.`Avatar`
36
+  FROM `friends` AS f
37
+    JOIN `users_main` AS m ON f.`FriendID` = m.`ID`
38
+    JOIN `users_info` AS i ON f.`FriendID` = i.`UserID`
39
+  WHERE f.`UserID` = '$UserID'
40
+  ORDER BY `Username`
44
   LIMIT $Limit");
41
   LIMIT $Limit");
45
 $Friends = $DB->to_array(false, MYSQLI_BOTH, array(6, 'Paranoia'));
42
 $Friends = $DB->to_array(false, MYSQLI_BOTH, array(6, 'Paranoia'));
46
 
43
 
48
 $DB->query('SELECT FOUND_ROWS()');
45
 $DB->query('SELECT FOUND_ROWS()');
49
 list($Results) = $DB->next_record();
46
 list($Results) = $DB->next_record();
50
 
47
 
51
-// Start printing stuff
52
-?>
48
+// Start printing stuff ?>
49
+
53
 <div>
50
 <div>
54
   <div class="header">
51
   <div class="header">
55
     <h2>Friends List</h2>
52
     <h2>Friends List</h2>
56
   </div>
53
   </div>
54
+
57
   <div class="linkbox">
55
   <div class="linkbox">
58
     <?php
56
     <?php
59
 // Pagination
57
 // Pagination
60
 $Pages = Format::get_pages($Page, $Results, FRIENDS_PER_PAGE, 9);
58
 $Pages = Format::get_pages($Page, $Results, FRIENDS_PER_PAGE, 9);
61
-echo $Pages;
62
-?>
59
+echo $Pages; ?>
63
   </div>
60
   </div>
61
+
64
   <div class="box pad">
62
   <div class="box pad">
65
     <?php
63
     <?php
66
-if ($Results == 0) {
64
+if ($Results === 0) {
67
     echo '<p>You have no friends! :(</p>';
65
     echo '<p>You have no friends! :(</p>';
68
 }
66
 }
67
+
69
 // Start printing out friends
68
 // Start printing out friends
70
 foreach ($Friends as $Friend) {
69
 foreach ($Friends as $Friend) {
71
     list($FriendID, $Comment, $Username, $Uploaded, $Downloaded, $Class, $Paranoia, $LastAccess, $Avatar) = $Friend; ?>
70
     list($FriendID, $Comment, $Username, $Uploaded, $Downloaded, $Class, $Paranoia, $LastAccess, $Avatar) = $Friend; ?>
80
               &nbsp;Ratio: <strong><?=Format::get_ratio_html($Uploaded, $Downloaded)?></strong>
79
               &nbsp;Ratio: <strong><?=Format::get_ratio_html($Uploaded, $Downloaded)?></strong>
81
               <?php
80
               <?php
82
   }
81
   }
82
+
83
     if (check_paranoia('uploaded', $Paranoia, $Class, $FriendID)) {
83
     if (check_paranoia('uploaded', $Paranoia, $Class, $FriendID)) {
84
         ?>
84
         ?>
85
               &nbsp;Up: <strong><?=Format::get_size($Uploaded)?></strong>
85
               &nbsp;Up: <strong><?=Format::get_size($Uploaded)?></strong>
86
               <?php
86
               <?php
87
     }
87
     }
88
+
88
     if (check_paranoia('downloaded', $Paranoia, $Class, $FriendID)) {
89
     if (check_paranoia('downloaded', $Paranoia, $Class, $FriendID)) {
89
         ?>
90
         ?>
90
               &nbsp;Down: <strong><?=Format::get_size($Downloaded)?></strong>
91
               &nbsp;Down: <strong><?=Format::get_size($Downloaded)?></strong>
106
             <input type="hidden" name="friendid"
107
             <input type="hidden" name="friendid"
107
               value="<?=$FriendID?>" />
108
               value="<?=$FriendID?>" />
108
 
109
 
109
-            <textarea name="comment" rows="4"
110
-              cols="65"><?=$Comment?></textarea>
110
+            <textarea
111
+              name = "comment"
112
+              rows = "5"
113
+              cols = "50"
114
+              placeholder ="Your saved notes about this friend"
115
+              ><?=$Comment?></textarea>
111
           </td>
116
           </td>
112
           <td class="left" valign="top">
117
           <td class="left" valign="top">
113
-            <input type="submit" name="action" value="Update" /><br />
114
-            <input type="submit" name="action" value="Remove friend" /><br />
115
-            <input type="submit" name="action" value="Contact" /><br />
118
+          <p>
119
+            <input type="submit" name="action" value="Update" />
120
+            <input type="submit" name="action" value="Remove friend" />
121
+          </p>
122
+
123
+          <p>
124
+            <input type="submit" name="action" class="button-primary" value="Contact" />
125
+          </p>
126
+
116
           </td>
127
           </td>
117
         </tr>
128
         </tr>
118
       </table>
129
       </table>

+ 7
- 2
sections/inbox/inbox.php View File

122
     <input type="hidden" name="action" value="masschange" />
122
     <input type="hidden" name="action" value="masschange" />
123
     <input type="hidden" name="auth"
123
     <input type="hidden" name="auth"
124
       value="<?=$LoggedUser['AuthKey']?>" />
124
       value="<?=$LoggedUser['AuthKey']?>" />
125
-    <input type="submit" name="read" value="Mark as read" />
125
+    <input type="submit" name="read" class="button-primary" value="Mark as read" />
126
     <input type="submit" name="unread" value="Mark as unread" />
126
     <input type="submit" name="unread" value="Mark as unread" />
127
     <input type="submit" name="delete" value="Delete message(s)" />
127
     <input type="submit" name="delete" value="Delete message(s)" />
128
 
128
 
181
       }
181
       }
182
   } ?>
182
   } ?>
183
     </table>
183
     </table>
184
-    <input type="submit" name="read" value="Mark as read" />
184
+    <?php
185
+    $MsgLimit = ($LoggedUser['PostsPerPage']) ? $LoggedUser['PostsPerPage'] : MESSAGES_PER_PAGE;
186
+    if ($Count > $MsgLimit) { ?>
187
+    <input type="submit" name="read" class="button-primary" value="Mark as read" />
185
     <input type="submit" name="unread" value="Mark as unread" />
188
     <input type="submit" name="unread" value="Mark as unread" />
186
     <input type="submit" name="delete" value="Delete message(s)" />
189
     <input type="submit" name="delete" value="Delete message(s)" />
190
+    <?php } ?>
187
   </form>
191
   </form>
188
   <?php } ?>
192
   <?php } ?>
189
 </div>
193
 </div>
194
+
190
 <div class="linkbox">
195
 <div class="linkbox">
191
   <?= $Pages ?>
196
   <?= $Pages ?>
192
 </div>
197
 </div>

+ 25
- 7
sections/login/login.php View File

1
 <?php
1
 <?php
2
 declare(strict_types=1);
2
 declare(strict_types=1);
3
 
3
 
4
+$ENV = ENV::go();
5
+$Twig = Twig::go();
6
+
4
 View::show_header('Login'); ?>
7
 View::show_header('Login'); ?>
5
 
8
 
6
 <p class="center mouseless">
9
 <p class="center mouseless">
36
   </aside>
39
   </aside>
37
   <?php } ?>
40
   <?php } ?>
38
 
41
 
39
-  <table>
42
+  <br />
43
+  <table class="login_form">
40
     <tr>
44
     <tr>
41
       <td colspan="2">
45
       <td colspan="2">
42
         <input type="text" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" name="username"
46
         <input type="text" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" name="username"
43
           id="username" class="inputtext" required="required" maxlength="20" pattern="[A-Za-z0-9_?]{1,20}"
47
           id="username" class="inputtext" required="required" maxlength="20" pattern="[A-Za-z0-9_?]{1,20}"
44
-          autofocus="autofocus" placeholder="Username" size="40" autocomplete="username" />
48
+          autofocus="autofocus" placeholder="Username" size="35" autocomplete="username" />
45
       </td>
49
       </td>
46
     </tr>
50
     </tr>
47
 
51
 
48
     <tr>
52
     <tr>
49
       <td>
53
       <td>
50
-        <?= Input::passphrase() ?>
54
+        <?=
55
+        $Twig->render('input/passphrase.html', [
56
+          'name' => 'password',
57
+          'id' => 'password',
58
+          'placeholder' => 'Passphrase',
59
+          'pw_min' => $ENV->PW_MIN,
60
+          'pw_max' => $ENV->PW_MAX,
61
+          'advice' => false,
62
+        ]) ?>
51
       </td>
63
       </td>
52
 
64
 
53
       <td>
65
       <td>
58
     </tr>
70
     </tr>
59
 
71
 
60
     <tr>
72
     <tr>
61
-      <td colspan="2">
62
-        <input type="submit" name="login" value="Log In" class="submit" />
73
+      <td colspan="4">
74
+        <input type="submit" name="login" value="Log In" class="submit button-primary" />
75
+
76
+        <?php if ($ENV->OPEN_REGISTRATION) { ?>
77
+          &ensp;
78
+          <a href="/register.php" class="button">Register</a>
79
+          <?php } ?>
63
       </td>
80
       </td>
81
+
64
     </tr>
82
     </tr>
65
   </table>
83
   </table>
66
 </form>
84
 </form>
76
 
94
 
77
 if ($Attempts > 0) { ?>
95
 if ($Attempts > 0) { ?>
78
 <p class="center">
96
 <p class="center">
79
-  Forgot your password?
80
-  <a href="login.php?act=recover" class="tooltip" title="Recover your password">Reset it here!</a>
97
+  Forgot your passphrase?
98
+  <a href="login.php?act=recover" class="tooltip" title="Recover your passphrase">Reset it here!</a>
81
 </p>
99
 </p>
82
 
100
 
83
 <?php
101
 <?php

+ 14
- 11
sections/login/recover_step2.php View File

2
 declare(strict_types=1);
2
 declare(strict_types=1);
3
 
3
 
4
 $ENV = ENV::go();
4
 $ENV = ENV::go();
5
-View::show_header('Recover Password', 'validate,password_validate');
5
+$Twig = Twig::go();
6
 
6
 
7
+View::show_header('Recover Password', 'validate,password_validate');
7
 echo '<h2>Reset your password</h2>';
8
 echo '<h2>Reset your password</h2>';
8
 
9
 
9
 if (empty($PassWasReset)) {
10
 if (empty($PassWasReset)) {
22
       </td>
23
       </td>
23
 
24
 
24
       <td>
25
       <td>
25
-        <?= Input::passphrase($Name = 'password', $ID='new_pass_1', $Placeholder = 'New passphrase') ?>
26
-        <!--
27
-        <input type="password" minlength="15" name="password" id="new_pass_1" class="inputtext" size="40"
28
-          placeholder="New Password" pattern=".{15,307200}" required style="width: 250px !important;">
29
-        -->
26
+        <?=
27
+        $Twig->render('input/passphrase.html', [
28
+          'name' => 'password',
29
+          'id' => 'new_pass_1',
30
+          'placeholder' => 'New passphrase'
31
+        ]) ?>
30
       </td>
32
       </td>
31
     </tr>
33
     </tr>
32
 
34
 
35
         <strong id="pass_match"></strong>
37
         <strong id="pass_match"></strong>
36
       </td>
38
       </td>
37
       <td>
39
       <td>
38
-        <?= Input::passphrase($Name = 'verifypassword', $ID='new_pass_2', $Placeholder = 'Confirm passphrase') ?>
39
-        <!--
40
-        <input type="password" minlength="15" name="verifypassword" id="new_pass_2" class="inputtext" size="40"
41
-          placeholder="Confirm Password" pattern=".{15,307200}" required style="width: 250px !important;">
42
-        -->
40
+      <?=
41
+        $Twig->render('input/passphrase.html', [
42
+          'name' => 'verifypassword',
43
+          'id' => 'new_pass_2',
44
+          'placeholder' => 'Confirm passphrase'
45
+        ]) ?>
43
       </td>
46
       </td>
44
     </tr>
47
     </tr>
45
 
48
 

+ 2
- 1
sections/register/step1.php View File

39
           <strong>Don't choose one associated with your real name.</strong>
39
           <strong>Don't choose one associated with your real name.</strong>
40
           If you do, we won't be changing it for you.
40
           If you do, we won't be changing it for you.
41
         </p>
41
         </p>
42
+        <br />
42
 
43
 
43
         <input type="text" name="username" id="username" class="inputtext" placeholder="Username"
44
         <input type="text" name="username" id="username" class="inputtext" placeholder="Username"
44
           value="<?=(!empty($_REQUEST['username']) ? display_str($_REQUEST['username']) : '')?>" />
45
           value="<?=(!empty($_REQUEST['username']) ? display_str($_REQUEST['username']) : '')?>" />
96
     </tr>
97
     </tr>
97
 
98
 
98
     <tr>
99
     <tr>
99
-      <td colspan="2" align="right"><input type="submit" name="submit" value="Submit" class="submit" /></td>
100
+      <td colspan="2" align="right"><input type="submit" name="submit" value="Submit" class="submit button-primary" /></td>
100
     </tr>
101
     </tr>
101
   </table>
102
   </table>
102
 </form>
103
 </form>

+ 12
- 11
sections/reportsv2/report.php View File

1
 <?php
1
 <?php
2
 #declare(strict_types=1);
2
 #declare(strict_types=1);
3
 
3
 
4
-/*
4
+/**
5
  * This is the frontend of reporting a torrent, it's what users see when
5
  * This is the frontend of reporting a torrent, it's what users see when
6
  * they visit reportsv2.php?id=xxx
6
  * they visit reportsv2.php?id=xxx
7
  */
7
  */
8
 
8
 
9
-include(SERVER_ROOT.'/sections/torrents/functions.php');
9
+$ENV = ENV::go();
10
+
11
+require_once "$ENV->SERVER_ROOT/sections/torrents/functions.php";
10
 
12
 
11
 // If we're not coming from torrents.php, check we're being returned because of an error.
13
 // If we're not coming from torrents.php, check we're being returned because of an error.
12
 if (!isset($_GET['id']) || !is_number($_GET['id'])) {
14
 if (!isset($_GET['id']) || !is_number($_GET['id'])) {
16
 } else {
18
 } else {
17
     $TorrentID = $_GET['id'];
19
     $TorrentID = $_GET['id'];
18
     $DB->query("
20
     $DB->query("
19
-    SELECT tg.CategoryID, t.GroupID, u.Username
20
-    FROM torrents_group AS tg
21
-      LEFT JOIN torrents AS t ON t.GroupID = tg.ID
22
-      LEFT JOIN users_main AS u ON t.UserID = u.ID
23
-    WHERE t.ID = " . $_GET['id']);
21
+    SELECT tg.`category_id`, t.`GroupID`, u.`Username`
22
+    FROM `torrents_group` AS tg
23
+      LEFT JOIN `torrents` AS t ON t.`GroupID` = tg.`id`
24
+      LEFT JOIN `users_main` AS u ON t.`UserID` = u.`ID`
25
+    WHERE t.`ID` = " . $_GET['id']);
24
     list($CategoryID, $GroupID, $Username) = $DB->next_record();
26
     list($CategoryID, $GroupID, $Username) = $DB->next_record();
25
     $Artists = Artists::get_artist($GroupID);
27
     $Artists = Artists::get_artist($GroupID);
26
     $TorrentCache = get_group_info($GroupID, true);
28
     $TorrentCache = get_group_info($GroupID, true);
137
 
139
 
138
       <div id="dynamic_form">
140
       <div id="dynamic_form">
139
 <?php
141
 <?php
140
-        /*
142
+        /**
141
          * THIS IS WHERE SEXY AJAX COMES IN
143
          * THIS IS WHERE SEXY AJAX COMES IN
142
          * The following malarky is needed so that if you get sent back here, the fields are filled in.
144
          * The following malarky is needed so that if you get sent back here, the fields are filled in.
143
          */
145
          */
149
         <input id="extra" type="hidden" name="extra" value="<?=(!empty($_POST['extra']) ? display_str($_POST['extra']) : '')?>" />
151
         <input id="extra" type="hidden" name="extra" value="<?=(!empty($_POST['extra']) ? display_str($_POST['extra']) : '')?>" />
150
       </div>
152
       </div>
151
     </div>
153
     </div>
152
-  <input type="submit" value="Report" />
154
+  <input type="submit" class="button-primary" value="Report" />
153
   </form>
155
   </form>
154
 </div>
156
 </div>
155
-<?php
156
-View::show_footer();
157
+<?php View::show_footer();

+ 3
- 4
sections/reportsv2/takereport.php View File

1
 <?
1
 <?
2
-/*
2
+
3
+/**
3
  * This page handles the backend from when a user submits a report.
4
  * This page handles the backend from when a user submits a report.
4
  * It checks for (in order):
5
  * It checks for (in order):
5
  * 1. The usual POST injections, then checks that things.
6
  * 1. The usual POST injections, then checks that things.
56
   } else {
57
   } else {
57
     $Err = 'The permalink was incorrect. It should look like '.site_url().'torrents.php?torrentid=12345';
58
     $Err = 'The permalink was incorrect. It should look like '.site_url().'torrents.php?torrentid=12345';
58
   }
59
   }
59
-} else {
60
-  $ExtraIDs = '';
61
 }
60
 }
62
 
61
 
63
 if (!empty($_POST['link'])) {
62
 if (!empty($_POST['link'])) {
108
 list($GroupID) = $DB->next_record();
107
 list($GroupID) = $DB->next_record();
109
 
108
 
110
 if (!empty($Err)) {
109
 if (!empty($Err)) {
111
-  error($Err);
110
+  error($Error = $Err, $Debug = false);
112
   include(SERVER_ROOT.'/sections/reportsv2/report.php');
111
   include(SERVER_ROOT.'/sections/reportsv2/report.php');
113
   error();
112
   error();
114
 }
113
 }

+ 2
- 2
sections/requests/new_edit.php View File

444
         <!-- Submit -->
444
         <!-- Submit -->
445
         <tr>
445
         <tr>
446
           <td colspan="2" class="center">
446
           <td colspan="2" class="center">
447
-            <input type="submit" id="button" value="Create" disabled="disabled" />
447
+            <input type="submit" id="button" class="button-primary" value="Create" disabled="disabled" />
448
           </td>
448
           </td>
449
         </tr>
449
         </tr>
450
         <?php } else { ?>
450
         <?php } else { ?>
451
         <tr>
451
         <tr>
452
           <td colspan="2" class="center">
452
           <td colspan="2" class="center">
453
-            <input type="submit" id="button" value="Edit" />
453
+            <input type="submit" id="button" class="button-primary" value="Edit" />
454
           </td>
454
           </td>
455
         </tr>
455
         </tr>
456
         <?php } ?>
456
         <?php } ?>

+ 7
- 7
sections/requests/request.php View File

244
     <div class="box">
244
     <div class="box">
245
       <div class="head"><strong>Info</strong></div>
245
       <div class="head"><strong>Info</strong></div>
246
       <div class="pad">
246
       <div class="pad">
247
-        <table class="layout">
247
+        <table class="layout request_form">
248
           <tr>
248
           <tr>
249
             <td class="label">Created</td>
249
             <td class="label">Created</td>
250
             <td>
250
             <td>
318
           <tr id="voting">
318
           <tr id="voting">
319
             <td class="label">Custom Vote</td>
319
             <td class="label">Custom Vote</td>
320
             <td>
320
             <td>
321
-              These units are in base 2, not base 10, e.g., there are 1,024 MiB in 1 GiB
321
+              These units are in base 2, not base 10, e.g., there are 1,024 MiB in 1 GiB.
322
+              <strong>The system deducts <?= ($RequestTax * 100) ?>% as tax.</strong>
323
+              <br />
324
+
322
               <input type="text" id="amount_box" size="8" onchange="Calculate();" />
325
               <input type="text" id="amount_box" size="8" onchange="Calculate();" />
323
               <select id="unit" name="unit" onchange="Calculate();">
326
               <select id="unit" name="unit" onchange="Calculate();">
324
                 <option value="mb">MiB</option>
327
                 <option value="mb">MiB</option>
325
                 <option value="gb">GiB</option>
328
                 <option value="gb">GiB</option>
326
               </select>
329
               </select>
327
               <input type="button" value="Preview" onclick="Calculate();" />
330
               <input type="button" value="Preview" onclick="Calculate();" />
328
-              <strong>The system deducts <?= ($RequestTax * 100) ?>%
329
-                as tax</strong>
330
-
331
             </td>
331
             </td>
332
           </tr>
332
           </tr>
333
           <tr>
333
           <tr>
361
                   <li><strong>Ratio:</strong> <span id="new_ratio"><?= Format::get_ratio_html($LoggedUser['BytesUploaded'], $LoggedUser['BytesDownloaded']) ?></span>
361
                   <li><strong>Ratio:</strong> <span id="new_ratio"><?= Format::get_ratio_html($LoggedUser['BytesUploaded'], $LoggedUser['BytesDownloaded']) ?></span>
362
                   </li>
362
                   </li>
363
                 </ul>
363
                 </ul>
364
-                <input type="button" id="button" value="Vote!" disabled="disabled" onclick="Vote();" />
364
+                <input type="button" id="button" value="Vote!" class="button-primary" disabled="disabled" onclick="Vote();" />
365
               </form>
365
               </form>
366
             </td>
366
             </td>
367
           </tr>
367
           </tr>
413
                 </div>
413
                 </div>
414
                 <?php } ?>
414
                 <?php } ?>
415
                 <div class="submit_div">
415
                 <div class="submit_div">
416
-                  <input type="submit" value="Fill" />
416
+                  <input type="submit" class="button-primary" value="Fill" />
417
                 </div>
417
                 </div>
418
               </form>
418
               </form>
419
             </td>
419
             </td>

+ 19
- 19
sections/requests/requests.php View File

359
             value="<?=$_GET['userid']?>" />
359
             value="<?=$_GET['userid']?>" />
360
         <?php } ?>
360
         <?php } ?>
361
         <div class="box pad">
361
         <div class="box pad">
362
-            <table cellpadding="6" cellspacing="1" border="0" class="layout" width="100%">
362
+            <table cellpadding="6" cellspacing="1" border="0" class="layout torrent_requests" width="100%">
363
 
363
 
364
                 <tr id="search_terms">
364
                 <tr id="search_terms">
365
                     <td class="label">
365
                     <td class="label">
443
             <table class="layout">
443
             <table class="layout">
444
                 <tr>
444
                 <tr>
445
                     <td colspan="2" class="center">
445
                     <td colspan="2" class="center">
446
-                        <input type="submit" value="Search" />
446
+                        <input type="submit" class="button-primary" value="Search" />
447
                     </td>
447
                     </td>
448
                 </tr>
448
                 </tr>
449
             </table>
449
             </table>
456
     <?php } ?>
456
     <?php } ?>
457
     <table id="request_table" class="request_table border" cellpadding="6" cellspacing="1" border="0" width="100%">
457
     <table id="request_table" class="request_table border" cellpadding="6" cellspacing="1" border="0" width="100%">
458
         <tr class="colhead_dark">
458
         <tr class="colhead_dark">
459
-            <td class="small cats_col"></td>
460
-            <td style="width: 38%;" class="nobr">
459
+            <th class="small cats_col"></th>
460
+            <th style="width: 38%;" class="nobr">
461
                 <strong>Request Name</strong>
461
                 <strong>Request Name</strong>
462
-            </td>
463
-            <td class="nobr">
462
+            </th>
463
+            <th class="nobr">
464
                 <a
464
                 <a
465
                     href="?order=votes&amp;sort=<?=($OrderBy === 'votes' ? $NewSort : 'desc')?>&amp;<?=$CurrentURL?>"><strong>Votes</strong></a>
465
                     href="?order=votes&amp;sort=<?=($OrderBy === 'votes' ? $NewSort : 'desc')?>&amp;<?=$CurrentURL?>"><strong>Votes</strong></a>
466
-            </td>
467
-            <td class="nobr">
466
+            </th>
467
+            <th class="nobr">
468
                 <a
468
                 <a
469
                     href="?order=bounty&amp;sort=<?=($OrderBy === 'bounty' ? $NewSort : 'desc')?>&amp;<?=$CurrentURL?>"><strong>Bounty</strong></a>
469
                     href="?order=bounty&amp;sort=<?=($OrderBy === 'bounty' ? $NewSort : 'desc')?>&amp;<?=$CurrentURL?>"><strong>Bounty</strong></a>
470
-            </td>
471
-            <td class="nobr">
470
+            </th>
471
+            <th class="nobr">
472
                 <a
472
                 <a
473
                     href="?order=filled&amp;sort=<?=($OrderBy === 'filled' ? $NewSort : 'desc')?>&amp;<?=$CurrentURL?>"><strong>Filled</strong></a>
473
                     href="?order=filled&amp;sort=<?=($OrderBy === 'filled' ? $NewSort : 'desc')?>&amp;<?=$CurrentURL?>"><strong>Filled</strong></a>
474
-            </td>
475
-            <td class="nobr">
474
+            </th>
475
+            <th class="nobr">
476
                 <strong>Filled by</strong>
476
                 <strong>Filled by</strong>
477
-            </td>
478
-            <td class="nobr">
477
+            </th>
478
+            <th class="nobr">
479
                 <strong>Requested by</strong>
479
                 <strong>Requested by</strong>
480
-            </td>
481
-            <td class="nobr">
480
+            </th>
481
+            <th class="nobr">
482
                 <a
482
                 <a
483
                     href="?order=created&amp;sort=<?=($OrderBy === 'created' ? $NewSort : 'desc')?>&amp;<?=$CurrentURL?>"><strong>Created</strong></a>
483
                     href="?order=created&amp;sort=<?=($OrderBy === 'created' ? $NewSort : 'desc')?>&amp;<?=$CurrentURL?>"><strong>Created</strong></a>
484
-            </td>
485
-            <td class="nobr">
484
+            </th>
485
+            <th class="nobr">
486
                 <a
486
                 <a
487
                     href="?order=lastvote&amp;sort=<?=($OrderBy === 'lastvote' ? $NewSort : 'desc')?>&amp;<?=$CurrentURL?>"><strong>Last
487
                     href="?order=lastvote&amp;sort=<?=($OrderBy === 'lastvote' ? $NewSort : 'desc')?>&amp;<?=$CurrentURL?>"><strong>Last
488
                         vote</strong></a>
488
                         vote</strong></a>
489
-            </td>
489
+            </th>
490
         </tr>
490
         </tr>
491
         <?php
491
         <?php
492
     if ($NumResults === 0) {
492
     if ($NumResults === 0) {

+ 1
- 1
sections/rules/clients.php View File

34
   </p>
34
   </p>
35
   <br />
35
   <br />
36
 
36
 
37
-  <table>
37
+  <table class="clients_table">
38
     <tr class="colhead">
38
     <tr class="colhead">
39
       <td>
39
       <td>
40
         <strong>Allowed Clients</strong>
40
         <strong>Allowed Clients</strong>

+ 9
- 9
sections/tools/tools.php View File

53
   if ($ToolsHTML) {
53
   if ($ToolsHTML) {
54
       ?>
54
       ?>
55
     <div class="permission_subcontainer">
55
     <div class="permission_subcontainer">
56
-      <table class="layout">
56
+      <table class="layout admin_tools">
57
         <tr class="colhead">
57
         <tr class="colhead">
58
           <td>Administration</td>
58
           <td>Administration</td>
59
         </tr>
59
         </tr>
72
   if ($ToolsHTML) {
72
   if ($ToolsHTML) {
73
       ?>
73
       ?>
74
     <div class="permission_subcontainer">
74
     <div class="permission_subcontainer">
75
-      <table class="layout">
75
+      <table class="layout admin_tools">
76
         <tr class="colhead">
76
         <tr class="colhead">
77
           <td>Announcements</td>
77
           <td>Announcements</td>
78
         </tr>
78
         </tr>
89
   if ($ToolsHTML) {
89
   if ($ToolsHTML) {
90
       ?>
90
       ?>
91
     <div class="permission_subcontainer">
91
     <div class="permission_subcontainer">
92
-      <table class="layout">
92
+      <table class="layout admin_tools">
93
         <tr class="colhead">
93
         <tr class="colhead">
94
           <td>Community</td>
94
           <td>Community</td>
95
         </tr>
95
         </tr>
107
   if ($ToolsHTML) {
107
   if ($ToolsHTML) {
108
       ?>
108
       ?>
109
     <div class="permission_subcontainer">
109
     <div class="permission_subcontainer">
110
-      <table class="layout">
110
+      <table class="layout admin_tools">
111
         <tr class="colhead">
111
         <tr class="colhead">
112
           <td>Finances</td>
112
           <td>Finances</td>
113
         </tr>
113
         </tr>
130
   if ($ToolsHTML) {
130
   if ($ToolsHTML) {
131
       ?>
131
       ?>
132
     <div class="permission_subcontainer">
132
     <div class="permission_subcontainer">
133
-      <table class="layout">
133
+      <table class="layout admin_tools">
134
         <tr class="colhead">
134
         <tr class="colhead">
135
           <td>Queue</td>
135
           <td>Queue</td>
136
         </tr>
136
         </tr>
149
   if ($ToolsHTML) {
149
   if ($ToolsHTML) {
150
       ?>
150
       ?>
151
     <div class="permission_subcontainer">
151
     <div class="permission_subcontainer">
152
-      <table class="layout">
152
+      <table class="layout admin_tools">
153
         <tr class="colhead">
153
         <tr class="colhead">
154
           <td>Managers</td>
154
           <td>Managers</td>
155
         </tr>
155
         </tr>
171
   if ($ToolsHTML) {
171
   if ($ToolsHTML) {
172
       ?>
172
       ?>
173
     <div class="permission_subcontainer">
173
     <div class="permission_subcontainer">
174
-      <table class="layout">
174
+      <table class="layout admin_tools">
175
         <tr class="colhead">
175
         <tr class="colhead">
176
           <td>Development</td>
176
           <td>Development</td>
177
         </tr>
177
         </tr>
200
   if ($ToolsHTML) {
200
   if ($ToolsHTML) {
201
       ?>
201
       ?>
202
     <div class="permission_subcontainer">
202
     <div class="permission_subcontainer">
203
-      <table class="layout">
203
+      <table class="layout admin_tools">
204
         <tr class="colhead">
204
         <tr class="colhead">
205
           <td>Site Information</td>
205
           <td>Site Information</td>
206
         </tr>
206
         </tr>
224
   if ($ToolsHTML) {
224
   if ($ToolsHTML) {
225
       ?>
225
       ?>
226
     <div class="permission_subcontainer">
226
     <div class="permission_subcontainer">
227
-      <table class="layout">
227
+      <table class="layout admin_tools">
228
         <tr class="colhead">
228
         <tr class="colhead">
229
           <td>Torrents</td>
229
           <td>Torrents</td>
230
         </tr>
230
         </tr>

+ 1
- 1
sections/top10/donors.php View File

65
     </small>
65
     </small>
66
   </h3>
66
   </h3>
67
 
67
 
68
-  <table class="border">
68
+  <table class="border top10_table">
69
     <tr class="colhead">
69
     <tr class="colhead">
70
       <td class="center">Position</td>
70
       <td class="center">Position</td>
71
       <td>User</td>
71
       <td>User</td>

+ 1
- 1
sections/top10/tags.php View File

108
     </small>
108
     </small>
109
   </h3>
109
   </h3>
110
 
110
 
111
-  <table class="border">
111
+  <table class="border top10_table">
112
     <tr class="colhead">
112
     <tr class="colhead">
113
       <td class="center">Rank</td>
113
       <td class="center">Rank</td>
114
       <td>Tag</td>
114
       <td>Tag</td>

+ 1
- 1
sections/top10/torrents.php View File

92
                 </tr>
92
                 </tr>
93
                 <tr>
93
                 <tr>
94
                     <td colspan="2" class="center">
94
                     <td colspan="2" class="center">
95
-                        <input type="submit" value="Search" />
95
+                        <input type="submit" class="button-primary" value="Search" />
96
                     </td>
96
                     </td>
97
                 </tr>
97
                 </tr>
98
             </table>
98
             </table>

+ 1
- 1
sections/top10/users.php View File

130
       <?php } ?>
130
       <?php } ?>
131
     </small>
131
     </small>
132
   </h3>
132
   </h3>
133
-  <table class="border">
133
+  <table class="border top10_table">
134
     <tr class="colhead">
134
     <tr class="colhead">
135
       <td class="center">Rank</td>
135
       <td class="center">Rank</td>
136
       <td>User</td>
136
       <td>User</td>

+ 13
- 5
sections/torrents/browse.php View File

195
         <?php
195
         <?php
196
         } ?>
196
         } ?>
197
 
197
 
198
-        <table class="layout">
198
+        <table class="layout torrent_search">
199
           <tr id="numbers" class="ftr_advanced<?=$HideAdvanced?>">
199
           <tr id="numbers" class="ftr_advanced<?=$HideAdvanced?>">
200
             <td class="label">
200
             <td class="label">
201
               <!--
201
               <!--
607
           </tr>
607
           </tr>
608
         </table>
608
         </table>
609
 
609
 
610
-        <!-- Result count and submit button -->
610
+        <!-- Result count, submit, and reset -->
611
         <div class="submit ft_submit">
611
         <div class="submit ft_submit">
612
-          <span class="float_left"><?=number_format($NumResults)?>
613
-            Results</span>
614
-          <input type="submit" value="Search" />
612
+          <span class="float_left">
613
+            <?=number_format($NumResults)?>
614
+            Results
615
+          </span>
616
+
617
+          <input type="submit" value="Search" class="button-primary"/>
618
+
615
           <input type="hidden" name="action" id="ft_type"
619
           <input type="hidden" name="action" id="ft_type"
616
             value="<?=($AdvancedSearch ? 'advanced' : 'basic')?>" />
620
             value="<?=($AdvancedSearch ? 'advanced' : 'basic')?>" />
621
+
617
           <input type="hidden" name="searchsubmit" value="1" />
622
           <input type="hidden" name="searchsubmit" value="1" />
623
+
618
           <input type="button" value="Reset" <input type="button" value="Reset"
624
           <input type="button" value="Reset" <input type="button" value="Reset"
619
             onclick="window.location.href = 'torrents.php<?php if (isset($_GET['action']) && $_GET['action'] === 'advanced') { ?>?action=advanced<?php } ?>'" />
625
             onclick="window.location.href = 'torrents.php<?php if (isset($_GET['action']) && $_GET['action'] === 'advanced') { ?>?action=advanced<?php } ?>'" />
626
+
620
           &emsp;
627
           &emsp;
628
+
621
           <?php if ($Search->has_filters()) { ?>
629
           <?php if ($Search->has_filters()) { ?>
622
           <input type="submit" name="setdefault" value="Make Default" />
630
           <input type="submit" name="setdefault" value="Make Default" />
623
           <?php }
631
           <?php }

+ 10
- 10
sections/torrents/details.php View File

322
             value="<?=$GroupID?>" />
322
             value="<?=$GroupID?>" />
323
           <input type="text" id="artist" name="artistname[]" <?php Users::has_autocomplete_enabled('other'); ?>
323
           <input type="text" id="artist" name="artistname[]" <?php Users::has_autocomplete_enabled('other'); ?>
324
           />
324
           />
325
-          <input type="submit" value="Add" />
325
+          <input type="submit" class="button-primary" value="Add" />
326
         </form>
326
         </form>
327
       </div>
327
       </div>
328
     </div>
328
     </div>
396
             value="<?=$GroupID?>" />
396
             value="<?=$GroupID?>" />
397
           <input type="text" name="tagname" id="tagname" <?php Users::has_autocomplete_enabled('other'); ?>
397
           <input type="text" name="tagname" id="tagname" <?php Users::has_autocomplete_enabled('other'); ?>
398
           />
398
           />
399
-          <input type="submit" value="Add" />
399
+          <input type="submit" class="button-primary" value="Add" />
400
         </form>
400
         </form>
401
         <br />
401
         <br />
402
         <strong><a href="rules.php?p=tag" class="brackets">View tagging rules</a></strong>
402
         <strong><a href="rules.php?p=tag" class="brackets">View tagging rules</a></strong>
413
         class="torrent_table details<?=$GroupFlags['IsSnatched'] ? ' snatched' : ''?>"
413
         class="torrent_table details<?=$GroupFlags['IsSnatched'] ? ' snatched' : ''?>"
414
         id="torrent_details">
414
         id="torrent_details">
415
         <tr class="colhead_dark">
415
         <tr class="colhead_dark">
416
-          <td width="80%"><strong>Torrents</strong></td>
417
-          <td><strong>Size</strong></td>
418
-          <td class="sign snatches">
416
+          <th width="80%"><strong>Torrents</strong></th>
417
+          <th><strong>Size</strong></th>
418
+          <th class="sign snatches">
419
419
420
-          <td class="sign seeders">
420
+          <th class="sign seeders">
421
             &uarr;
421
             &uarr;
422
-          </td>
423
-          <td class="sign leechers">
422
+          </th>
423
+          <th class="sign leechers">
424
             &darr;
424
             &darr;
425
-          </td>
425
+          </th>
426
         </tr>
426
         </tr>
427
         <?php
427
         <?php
428
 function filelist($Str)
428
 function filelist($Str)
851
     <div class="box">
851
     <div class="box">
852
       <table class="collage_table" id="collages">
852
       <table class="collage_table" id="collages">
853
         <tr class="colhead">
853
         <tr class="colhead">
854
-          <td width="75%"><a href="#">&uarr;</a>&nbsp;This content is in <?=number_format(count($Collages))?> collection<?=((count($Collages) > 1) ? 's' : '')?><?=$SeeAll?>
854
+          <td width="85%"><a href="#">&uarr;</a>&nbsp;This content is in <?=number_format(count($Collages))?> collection<?=((count($Collages) > 1) ? 's' : '')?><?=$SeeAll?>
855
           </td>
855
           </td>
856
           <td># torrents</td>
856
           <td># torrents</td>
857
         </tr>
857
         </tr>

+ 78
- 78
sections/torrents/user.php View File

50
 $SearchWhere = [];
50
 $SearchWhere = [];
51
 if (!empty($_GET['format'])) {
51
 if (!empty($_GET['format'])) {
52
     if (in_array($_GET['format'], $Formats)) {
52
     if (in_array($_GET['format'], $Formats)) {
53
-        $SearchWhere[] = "t.Format = '".db_string($_GET['format'])."'";
53
+        $SearchWhere[] = "t.`Format` = '".db_string($_GET['format'])."'";
54
     }
54
     }
55
 }
55
 }
56
 
56
 
57
 # Get release specifics
57
 # Get release specifics
58
 if (isset($_GET['container'])
58
 if (isset($_GET['container'])
59
  && in_array($_GET['container'], $ENV-flatten($ENV->META->Formats))) {
59
  && in_array($_GET['container'], $ENV-flatten($ENV->META->Formats))) {
60
-    $SearchWhere[] = "t.Container = '".db_string($_GET['container'])."'";
60
+    $SearchWhere[] = "t.`Container` = '".db_string($_GET['container'])."'";
61
 }
61
 }
62
 
62
 
63
 if (isset($_GET['bitrate'])
63
 if (isset($_GET['bitrate'])
64
  && in_array($_GET['bitrate'], $Bitrates)) {
64
  && in_array($_GET['bitrate'], $Bitrates)) {
65
-    $SearchWhere[] = "t.Encoding = '".db_string($_GET['bitrate'])."'";
65
+    $SearchWhere[] = "t.`Encoding` = '".db_string($_GET['bitrate'])."'";
66
 }
66
 }
67
 
67
 
68
 if (isset($_GET['media'])
68
 if (isset($_GET['media'])
69
  && in_array($_GET['media'], $ENV-flatten($ENV->META->Platforms))) {
69
  && in_array($_GET['media'], $ENV-flatten($ENV->META->Platforms))) {
70
-    $SearchWhere[] = "t.Media = '".db_string($_GET['media'])."'";
70
+    $SearchWhere[] = "t.`Media` = '".db_string($_GET['media'])."'";
71
 }
71
 }
72
 
72
 
73
 if (isset($_GET['codec'])
73
 if (isset($_GET['codec'])
74
  && in_array($_GET['codec'], $ENV->META->Licenses)) {
74
  && in_array($_GET['codec'], $ENV->META->Licenses)) {
75
-    $SearchWhere[] = "t.Codec = '".db_string($_GET['codec'])."'";
75
+    $SearchWhere[] = "t.`Codec` = '".db_string($_GET['codec'])."'";
76
 }
76
 }
77
 
77
 
78
 if (isset($_GET['version'])) {
78
 if (isset($_GET['version'])) {
79
-    $SearchWhere[] = "t.Version = '".db_string($_GET['version'])."'";
79
+    $SearchWhere[] = "t.`Version` = '".db_string($_GET['version'])."'";
80
 }
80
 }
81
 
81
 
82
 if (isset($_GET['resolution'])
82
 if (isset($_GET['resolution'])
83
  && in_array($_GET['resolution'], $ENV->flatten($ENV->META->Scopes))) {
83
  && in_array($_GET['resolution'], $ENV->flatten($ENV->META->Scopes))) {
84
-    $SearchWhere[] = "t.Resolution = '".db_string($_GET['resolution'])."'";
84
+    $SearchWhere[] = "t.`Resolution` = '".db_string($_GET['resolution'])."'";
85
 }
85
 }
86
 
86
 
87
 if (isset($_GET['censored'])
87
 if (isset($_GET['censored'])
88
  && in_array($_GET['censored'], array(1, 0))) {
88
  && in_array($_GET['censored'], array(1, 0))) {
89
-    $SearchWhere[] = "t.Censored = '".db_string($_GET['censored'])."'";
89
+    $SearchWhere[] = "t.`Censored` = '".db_string($_GET['censored'])."'";
90
 }
90
 }
91
 
91
 
92
 if (!empty($_GET['categories'])) {
92
 if (!empty($_GET['categories'])) {
95
         if (!is_number($Cat)) {
95
         if (!is_number($Cat)) {
96
             error(0);
96
             error(0);
97
         }
97
         }
98
-        $Cats[] = "tg.CategoryID = '".db_string($Cat)."'";
98
+        $Cats[] = "tg.`category_id` = '".db_string($Cat)."'";
99
     }
99
     }
100
     $SearchWhere[] = '('.implode(' OR ', $Cats).')';
100
     $SearchWhere[] = '('.implode(' OR ', $Cats).')';
101
 }
101
 }
120
             if (empty($Tag)) {
120
             if (empty($Tag)) {
121
                 continue;
121
                 continue;
122
             }
122
             }
123
-            $TagList[] = "tg.TagList NOT RLIKE '[[:<:]]".db_string($Tag)."(:[^ ]+)?[[:>:]]'";
123
+            $TagList[] = "tg.`tag_list` NOT RLIKE '[[:<:]]".db_string($Tag)."(:[^ ]+)?[[:>:]]'";
124
         } else {
124
         } else {
125
-            $TagList[] = "tg.TagList RLIKE '[[:<:]]".db_string($Tag)."(:[^ ]+)?[[:>:]]'";
125
+            $TagList[] = "tg.`tag_list` RLIKE '[[:<:]]".db_string($Tag)."(:[^ ]+)?[[:>:]]'";
126
         }
126
         }
127
     }
127
     }
128
 
128
 
151
     if (!check_paranoia('snatched', $User['Paranoia'], $UserClass, $UserID)) {
151
     if (!check_paranoia('snatched', $User['Paranoia'], $UserClass, $UserID)) {
152
         error(403);
152
         error(403);
153
     }
153
     }
154
-    $Time = 'xs.tstamp';
155
-    $UserField = 'xs.uid';
154
+    $Time = 'xs.`tstamp`';
155
+    $UserField = 'xs.`uid`';
156
     $ExtraWhere = '';
156
     $ExtraWhere = '';
157
     $From = "
157
     $From = "
158
-      xbt_snatched AS xs
159
-        JOIN torrents AS t ON t.ID = xs.fid";
158
+      `xbt_snatched` AS xs
159
+        JOIN `torrents` AS t ON t.`ID` = xs.`fid`";
160
     break;
160
     break;
161
 
161
 
162
   case 'seeding':
162
   case 'seeding':
163
     if (!check_paranoia('seeding', $User['Paranoia'], $UserClass, $UserID)) {
163
     if (!check_paranoia('seeding', $User['Paranoia'], $UserClass, $UserID)) {
164
         error(403);
164
         error(403);
165
     }
165
     }
166
-    $Time = '(xfu.mtime - xfu.timespent)';
167
-    $UserField = 'xfu.uid';
166
+    $Time = '(xfu.`mtime` - xfu.`timespent`)';
167
+    $UserField = 'xfu.`uid`';
168
     $ExtraWhere = '
168
     $ExtraWhere = '
169
-      AND xfu.active = 1
170
-      AND xfu.Remaining = 0';
169
+      AND xfu.`active` = 1
170
+      AND xfu.`Remaining` = 0';
171
     $From = "
171
     $From = "
172
-      xbt_files_users AS xfu
173
-        JOIN torrents AS t ON t.ID = xfu.fid";
172
+      `xbt_files_users` AS xfu
173
+        JOIN `torrents` AS t ON t.`ID` = xfu.`fid`";
174
     break;
174
     break;
175
 
175
 
176
   case 'contest':
176
   case 'contest':
177
-    $Time = 'unix_timestamp(t.Time)';
178
-    $UserField = 't.UserID';
177
+    $Time = 'unix_timestamp(t.`Time`)';
178
+    $UserField = 't.`UserID`';
179
     $ExtraWhere = "
179
     $ExtraWhere = "
180
-      AND t.ID IN (
181
-        SELECT TorrentID
182
-        FROM library_contest
183
-        WHERE UserID = $UserID
180
+      AND t.`ID` IN (
181
+        SELECT `TorrentID`
182
+        FROM `library_contest`
183
+        WHERE `UserID` = $UserID
184
       )";
184
       )";
185
-    $From = 'torrents AS t';
185
+    $From = '`torrents` AS t';
186
     break;
186
     break;
187
 
187
 
188
   case 'leeching':
188
   case 'leeching':
189
     if (!check_paranoia('leeching', $User['Paranoia'], $UserClass, $UserID)) {
189
     if (!check_paranoia('leeching', $User['Paranoia'], $UserClass, $UserID)) {
190
         error(403);
190
         error(403);
191
     }
191
     }
192
-    $Time = '(xfu.mtime - xfu.timespent)';
193
-    $UserField = 'xfu.uid';
192
+    $Time = '(xfu.`mtime` - xfu.`timespent`)';
193
+    $UserField = 'xfu.`uid`';
194
     $ExtraWhere = '
194
     $ExtraWhere = '
195
-      AND xfu.active = 1
196
-      AND xfu.Remaining > 0';
195
+      AND xfu.`active` = 1
196
+      AND xfu.`Remaining` > 0';
197
     $From = "
197
     $From = "
198
-      xbt_files_users AS xfu
199
-        JOIN torrents AS t ON t.ID = xfu.fid";
198
+      `xbt_files_users` AS xfu
199
+        JOIN `torrents` AS t ON t.`ID` = xfu.`fid`";
200
     break;
200
     break;
201
 
201
 
202
   case 'uploaded':
202
   case 'uploaded':
203
     if ((empty($_GET['filter']) || $_GET['filter'] !== 'perfectflac') && !check_paranoia('uploads', $User['Paranoia'], $UserClass, $UserID)) {
203
     if ((empty($_GET['filter']) || $_GET['filter'] !== 'perfectflac') && !check_paranoia('uploads', $User['Paranoia'], $UserClass, $UserID)) {
204
         error(403);
204
         error(403);
205
     }
205
     }
206
-    $Time = 'unix_timestamp(t.Time)';
207
-    $UserField = 't.UserID';
206
+    $Time = 'unix_timestamp(t.`Time`)';
207
+    $UserField = 't.`UserID`';
208
     $ExtraWhere = '';
208
     $ExtraWhere = '';
209
-    $From = "torrents AS t";
209
+    $From = "`torrents` AS t";
210
     break;
210
     break;
211
 
211
 
212
   case 'downloaded':
212
   case 'downloaded':
213
     if (!check_perms('site_view_torrent_snatchlist')) {
213
     if (!check_perms('site_view_torrent_snatchlist')) {
214
         error(403);
214
         error(403);
215
     }
215
     }
216
-    $Time = 'unix_timestamp(ud.Time)';
217
-    $UserField = 'ud.UserID';
216
+    $Time = 'unix_timestamp(ud.`Time`)';
217
+    $UserField = 'ud.`UserID`';
218
     $ExtraWhere = '';
218
     $ExtraWhere = '';
219
     $From = "
219
     $From = "
220
-      users_downloads AS ud
221
-        JOIN torrents AS t ON t.ID = ud.TorrentID";
220
+      `users_downloads` AS ud
221
+        JOIN `torrents` AS t ON t.`ID` = ud.`TorrentID`";
222
     break;
222
     break;
223
     
223
     
224
   default:
224
   default:
226
 }
226
 }
227
 
227
 
228
 if (empty($GroupBy)) {
228
 if (empty($GroupBy)) {
229
-    $GroupBy = 't.ID';
229
+    $GroupBy = 't.`ID`';
230
 }
230
 }
231
 
231
 
232
 if ((empty($_GET['search'])
232
 if ((empty($_GET['search'])
234
     $SQL = "
234
     $SQL = "
235
       SELECT
235
       SELECT
236
         SQL_CALC_FOUND_ROWS
236
         SQL_CALC_FOUND_ROWS
237
-        t.GroupID,
238
-        t.ID AS TorrentID,
237
+        t.`GroupID`,
238
+        t.`ID` AS TorrentID,
239
         $Time AS Time,
239
         $Time AS Time,
240
-        COALESCE(NULLIF(tg.Name, ''), NULLIF(tg.Title2, ''), tg.NameJP) AS Name,
241
-        tg.CategoryID
240
+        COALESCE(NULLIF(tg.`title`, ''), NULLIF(tg. subject, ''), tg.`object`) AS Name,
241
+        tg.`category_id`
242
       FROM $From
242
       FROM $From
243
-        JOIN torrents_group AS tg ON tg.ID = t.GroupID
243
+        JOIN `torrents_group` AS tg ON tg.`id` = t.`GroupID`
244
       WHERE $UserField = '$UserID'
244
       WHERE $UserField = '$UserID'
245
         $ExtraWhere
245
         $ExtraWhere
246
         $SearchWhere
246
         $SearchWhere
249
       LIMIT $Limit";
249
       LIMIT $Limit";
250
 } else {
250
 } else {
251
     $DB->query("
251
     $DB->query("
252
-      CREATE TEMPORARY TABLE temp_sections_torrents_user (
253
-        GroupID int(10) unsigned not null,
254
-        TorrentID int(10) unsigned not null,
255
-        Time int(12) unsigned not null,
256
-        CategoryID int(3) unsigned,
257
-        Seeders int(6) unsigned,
258
-        Leechers int(6) unsigned,
259
-        Snatched int(10) unsigned,
260
-        Name mediumtext,
261
-        Size bigint(12) unsigned,
262
-      PRIMARY KEY (TorrentID)) CHARSET=utf8");
252
+      CREATE TEMPORARY TABLE `temp_sections_torrents_user` (
253
+        `GroupID` int(10) unsigned not null,
254
+        `TorrentID` int(10) unsigned not null,
255
+        `Time` int(12) unsigned not null,
256
+        `CategoryID` int(3) unsigned,
257
+        `Seeders` int(6) unsigned,
258
+        `Leechers` int(6) unsigned,
259
+        `Snatched` int(10) unsigned,
260
+        `Name` mediumtext,
261
+        `Size` bigint(12) unsigned,
262
+      PRIMARY KEY (`TorrentID`)) CHARSET=utf8");
263
 
263
 
264
     $DB->query("
264
     $DB->query("
265
-      INSERT IGNORE INTO temp_sections_torrents_user
265
+      INSERT IGNORE INTO `temp_sections_torrents_user`
266
       SELECT
266
       SELECT
267
-        t.GroupID,
268
-        t.ID AS TorrentID,
267
+        t.`GroupID`,
268
+        t.`ID` AS TorrentID,
269
         $Time AS Time,
269
         $Time AS Time,
270
-        tg.CategoryID,
271
-        t.Seeders,
272
-        t.Leechers,
273
-        t.Snatched,
274
-        CONCAT_WS(' ', GROUP_CONCAT(ag.Name SEPARATOR ' '), ' ', COALESCE(NULLIF(tg.Name,''), NULLIF(tg.Title2,''), tg.NameJP), ' ', tg.Year, ' ') AS Name,
275
-        t.Size
270
+        tg.`category_id`,
271
+        t.`Seeders`,
272
+        t.`Leechers`,
273
+        t.`Snatched`,
274
+        CONCAT_WS(' ', GROUP_CONCAT(ag.`Name` SEPARATOR ' '), ' ', COALESCE(NULLIF(tg.`title`,''), NULLIF(tg.`subject`,''), tg.`object`), ' ', tg.`year`, ' ') AS Name,
275
+        t.`Size`
276
       FROM $From
276
       FROM $From
277
-        JOIN torrents_group AS tg ON tg.ID = t.GroupID
278
-        LEFT JOIN torrents_artists AS ta ON ta.GroupID = tg.ID
279
-        LEFT JOIN artists_group AS ag ON ag.ArtistID = ta.ArtistID
277
+        JOIN `torrents_group` AS tg ON tg.`id` = t.`GroupID`
278
+        LEFT JOIN `torrents_artists` AS ta ON ta.`GroupID` = tg.`id`
279
+        LEFT JOIN `artists_group` AS ag ON ag.`ArtistID` = ta.`ArtistID`
280
       WHERE $UserField = '$UserID'
280
       WHERE $UserField = '$UserID'
281
         $ExtraWhere
281
         $ExtraWhere
282
         $SearchWhere
282
         $SearchWhere
283
-      GROUP BY TorrentID, Time");
283
+      GROUP BY `TorrentID`, `Time`");
284
 
284
 
285
     if (!empty($_GET['search']) && trim($_GET['search']) !== '') {
285
     if (!empty($_GET['search']) && trim($_GET['search']) !== '') {
286
         $Words = array_unique(explode(' ', db_string($_GET['search'])));
286
         $Words = array_unique(explode(' ', db_string($_GET['search'])));
289
     $SQL = "
289
     $SQL = "
290
       SELECT
290
       SELECT
291
         SQL_CALC_FOUND_ROWS
291
         SQL_CALC_FOUND_ROWS
292
-        GroupID,
293
-        TorrentID,
294
-        Time,
295
-        CategoryID
296
-      FROM temp_sections_torrents_user";
292
+        `GroupID`,
293
+        `TorrentID`,
294
+        `Time`,
295
+        `CategoryID`
296
+      FROM `temp_sections_torrents_user`";
297
 
297
 
298
     if (!empty($Words)) {
298
     if (!empty($Words)) {
299
         $SQL .= "
299
         $SQL .= "
300
-          WHERE Name LIKE '%".implode("%' AND Name LIKE '%", $Words)."%'";
300
+          WHERE `Name` LIKE '%".implode("%' AND `Name` LIKE '%", $Words)."%'";
301
     }
301
     }
302
 
302
 
303
     $SQL .= "
303
     $SQL .= "
470
           <?= number_format($TorrentCount) ?>
470
           <?= number_format($TorrentCount) ?>
471
           Results
471
           Results
472
         </span>
472
         </span>
473
-        <input type="submit" value="Search" />
473
+        <input type="submit" class="button-primary" value="Search" />
474
       </div>
474
       </div>
475
     </form>
475
     </form>
476
   </div>
476
   </div>

+ 2
- 2
sections/upload/index.php View File

3
 
3
 
4
 enforce_login();
4
 enforce_login();
5
 if (!check_perms('site_upload')) {
5
 if (!check_perms('site_upload')) {
6
-    error(403);
6
+    error('Please read the site wiki for information on how to become a Member and gain upload privileges.', $Debug = false);
7
 }
7
 }
8
 
8
 
9
 if ($LoggedUser['DisableUpload']) {
9
 if ($LoggedUser['DisableUpload']) {
10
-    error('Your upload privileges have been revoked.');
10
+    error('Your upload privileges have been revoked.', $Debug = false);
11
 }
11
 }
12
 
12
 
13
 // Build the page
13
 // Build the page

+ 21
- 17
sections/user/notify_edit.php View File

4
 if (!check_perms('site_torrents_notify')) {
4
 if (!check_perms('site_torrents_notify')) {
5
     error(403);
5
     error(403);
6
 }
6
 }
7
+
7
 View::show_header(
8
 View::show_header(
8
     'Manage notifications',
9
     'Manage notifications',
9
     'vendor/jquery.validate.min,form_validate'
10
     'vendor/jquery.validate.min,form_validate'
21
   <?php
22
   <?php
22
 $DB->query("
23
 $DB->query("
23
   SELECT
24
   SELECT
24
-    ID,
25
-    Label,
26
-    Artists,
27
-    NewGroupsOnly,
28
-    Tags,
29
-    NotTags,
30
-    ReleaseTypes,
31
-    Categories,
32
-    Formats,
33
-    Encodings,
34
-    Media,
35
-    FromYear,
36
-    ToYear,
37
-    Users
38
-  FROM users_notify_filters
39
-  WHERE UserID=$LoggedUser[ID]");
25
+    `ID`,
26
+    `Label`,
27
+    `Artists`,
28
+    `NewGroupsOnly`,
29
+    `Tags`,
30
+    `NotTags`,
31
+    `ReleaseTypes`,
32
+    `Categories`,
33
+    `Formats`,
34
+    `Encodings`,
35
+    `Media`,
36
+    `FromYear`,
37
+    `ToYear`,
38
+    `Users`
39
+  FROM `users_notify_filters`
40
+  WHERE `UserID` = $LoggedUser[ID]
41
+");
40
 
42
 
41
 $NumFilters = $DB->record_count();
43
 $NumFilters = $DB->record_count();
42
 
44
 
82
     if ($N['FromYear'] === 0) {
84
     if ($N['FromYear'] === 0) {
83
         $N['FromYear'] = '';
85
         $N['FromYear'] = '';
84
     }
86
     }
87
+
85
     if ($N['ToYear'] === 0) {
88
     if ($N['ToYear'] === 0) {
86
         $N['ToYear'] = '';
89
         $N['ToYear'] = '';
87
     }
90
     }
91
+
88
     if ($NewFilter && $NumFilters > 0) {
92
     if ($NewFilter && $NumFilters > 0) {
89
         ?>
93
         ?>
90
   <br><br>
94
   <br><br>
207
 
211
 
208
       <tr>
212
       <tr>
209
         <td colspan="2" class="center">
213
         <td colspan="2" class="center">
210
-          <input type="submit"
214
+          <input type="submit" class="button-primary"
211
             value="<?=($NewFilter ? 'Create' : 'Update')?>">
215
             value="<?=($NewFilter ? 'Create' : 'Update')?>">
212
         </td>
216
         </td>
213
       </tr>
217
       </tr>

+ 2
- 2
sections/user/user.php View File

1514
       <?php } ?>
1514
       <?php } ?>
1515
     </table>
1515
     </table>
1516
     <?php if (check_perms('users_disable_any')) { ?>
1516
     <?php if (check_perms('users_disable_any')) { ?>
1517
-    <table class="layout box">
1517
+    <table class="layout box" id="user_lock_account">
1518
       <tr class="colhead">
1518
       <tr class="colhead">
1519
         <td colspan="2">
1519
         <td colspan="2">
1520
           Lock Account
1520
           Lock Account
1703
 
1703
 
1704
       <tr>
1704
       <tr>
1705
         <td align="right" colspan="2">
1705
         <td align="right" colspan="2">
1706
-          <input type="submit" value="Save changes" />
1706
+          <input type="submit" class="button-primary" value="Save changes" />
1707
         </td>
1707
         </td>
1708
       </tr>
1708
       </tr>
1709
     </table>
1709
     </table>

+ 59
- 55
sections/userhistory/subscriptions.php View File

1
 <?php
1
 <?php
2
 #declare(strict_types=1);
2
 #declare(strict_types=1);
3
 
3
 
4
-/*
4
+/**
5
  * User subscription page
5
  * User subscription page
6
  */
6
  */
7
 
7
 
38
 $DB->query("
38
 $DB->query("
39
   (SELECT
39
   (SELECT
40
     SQL_CALC_FOUND_ROWS
40
     SQL_CALC_FOUND_ROWS
41
-    s.Page,
42
-    s.PageID,
43
-    lr.PostID,
41
+    s.`Page`,
42
+    s.`PageID`,
43
+    lr.`PostID`,
44
     null AS ForumID,
44
     null AS ForumID,
45
     null AS ForumName,
45
     null AS ForumName,
46
-    IF(s.Page = 'artist', a.Name, co.Name) AS Name,
47
-    c.ID AS LastPost,
48
-    c.AddedTime AS LastPostTime,
49
-    c_lr.Body AS LastReadBody,
50
-    c_lr.EditedTime AS LastReadEditedTime,
51
-    um.ID AS LastReadUserID,
52
-    um.Username AS LastReadUsername,
53
-    ui.Avatar AS LastReadAvatar,
54
-    c_lr.EditedUserID AS LastReadEditedUserID
55
-  FROM users_subscriptions_comments AS s
56
-    LEFT JOIN users_comments_last_read AS lr ON lr.UserID = $LoggedUser[ID] AND lr.Page = s.Page AND lr.PageID = s.PageID
57
-    LEFT JOIN artists_group AS a ON s.Page = 'artist' AND a.ArtistID = s.PageID
58
-    LEFT JOIN collages AS co ON s.Page = 'collages' AND co.ID = s.PageID
59
-    LEFT JOIN comments AS c ON c.ID = (
60
-          SELECT MAX(ID)
61
-          FROM comments
62
-          WHERE Page = s.Page
63
-            AND PageID = s.PageID
46
+    IF(s.`Page` = 'artist', a.`Name`, co.`Name`) AS Name,
47
+    c.`ID` AS LastPost,
48
+    c.`AddedTime` AS LastPostTime,
49
+    c_lr.`Body` AS LastReadBody,
50
+    c_lr.`EditedTime` AS LastReadEditedTime,
51
+    um.`ID` AS LastReadUserID,
52
+    um.`Username` AS LastReadUsername,
53
+    ui.`Avatar` AS LastReadAvatar,
54
+    c_lr.`EditedUserID` AS LastReadEditedUserID
55
+  FROM `users_subscriptions_comments` AS s
56
+    LEFT JOIN `users_comments_last_read` AS lr ON lr.`UserID` = $LoggedUser[ID] AND lr.`Page` = s.`Page` AND lr.`PageID` = s.`PageID`
57
+    LEFT JOIN `artists_group` AS a ON s.`Page` = 'artist' AND a.`ArtistID` = s.`PageID`
58
+    LEFT JOIN `collages` AS co ON s.`Page` = 'collages' AND co.`ID` = s.`PageID`
59
+    LEFT JOIN `comments` AS c ON c.`ID` = (
60
+          SELECT MAX(`ID`)
61
+          FROM `comments`
62
+          WHERE `Page` = s.`Page`
63
+            AND `PageID` = s.`PageID`
64
         )
64
         )
65
-    LEFT JOIN comments AS c_lr ON c_lr.ID = lr.PostID
66
-    LEFT JOIN users_main AS um ON um.ID = c_lr.AuthorID
67
-    LEFT JOIN users_info AS ui ON ui.UserID = um.ID
68
-  WHERE s.UserID = $LoggedUser[ID] AND s.Page IN ('artist', 'collages', 'requests', 'torrents') AND (s.Page != 'collages' OR co.Deleted = '0')" . ($ShowUnread ? ' AND c.ID > IF(lr.PostID IS NULL, 0, lr.PostID)' : '') . "
69
-  GROUP BY s.PageID)
65
+    LEFT JOIN `comments` AS c_lr ON c_lr.`ID` = lr.`PostID`
66
+    LEFT JOIN `users_main` AS um ON um.`ID` = c_lr.`AuthorID`
67
+    LEFT JOIN `users_info` AS ui ON ui.`UserID` = um.`ID`
68
+  WHERE s.`UserID` = $LoggedUser[ID] AND s.`Page` IN ('artist', 'collages', 'requests', 'torrents') AND (s.`Page` != 'collages' OR co.`Deleted` = '0')" . ($ShowUnread ? ' AND c.`ID` > IF(lr.`PostID` IS NULL, 0, lr.`PostID`)' : '') . "
69
+  GROUP BY s.`PageID`)
70
   UNION ALL
70
   UNION ALL
71
-  (SELECT 'forums', s.TopicID, lr.PostID, f.ID, f.Name, t.Title, p.ID, p.AddedTime, p_lr.Body, p_lr.EditedTime, um.ID, um.Username, ui.Avatar, p_lr.EditedUserID
72
-  FROM users_subscriptions AS s
73
-    LEFT JOIN forums_last_read_topics AS lr ON lr.UserID = $LoggedUser[ID] AND s.TopicID = lr.TopicID
74
-    LEFT JOIN forums_topics AS t ON t.ID = s.TopicID
75
-    LEFT JOIN forums AS f ON f.ID = t.ForumID
76
-    LEFT JOIN forums_posts AS p ON p.ID = (
77
-          SELECT MAX(ID)
78
-          FROM forums_posts
79
-          WHERE TopicID = s.TopicID
71
+  (SELECT 'forums', s.`TopicID`, lr.`PostID`, f.`ID`, f.`Name`, t.`Title`, p.`ID`, p.`AddedTime`, p_lr.`Body`, p_lr.`EditedTime`, um.`ID`, um.`Username`, ui.`Avatar`, p_lr.`EditedUserID`
72
+  FROM `users_subscriptions` AS s
73
+    LEFT JOIN `forums_last_read_topics` AS lr ON lr.`UserID` = $LoggedUser[ID] AND s.`TopicID` = lr.`TopicID`
74
+    LEFT JOIN `forums_topics` AS t ON t.`ID` = s.`TopicID`
75
+    LEFT JOIN `forums` AS f ON f.`ID` = t.`ForumID`
76
+    LEFT JOIN `forums_posts` AS p ON p.`ID` = (
77
+          SELECT MAX(`ID`)
78
+          FROM `forums_posts`
79
+          WHERE `TopicID` = s.`TopicID`
80
         )
80
         )
81
-    LEFT JOIN forums_posts AS p_lr ON p_lr.ID = lr.PostID
82
-    LEFT JOIN users_main AS um ON um.ID = p_lr.AuthorID
83
-    LEFT JOIN users_info AS ui ON ui.UserID = um.ID
84
-  WHERE s.UserID = $LoggedUser[ID]" .
85
-    ($ShowUnread ? " AND p.ID > IF(t.IsLocked = '1' AND t.IsSticky = '0'" . ", p.ID, IF(lr.PostID IS NULL, 0, lr.PostID))" : '') .
81
+    LEFT JOIN `forums_posts` AS p_lr ON p_lr.`ID` = lr.`PostID`
82
+    LEFT JOIN `users_main` AS um ON um.`ID` = p_lr.`AuthorID`
83
+    LEFT JOIN `users_info` AS ui ON ui.`UserID` = um.`ID`
84
+  WHERE s.`UserID` = $LoggedUser[ID]" .
85
+    ($ShowUnread ? " AND p.`ID` > IF(t.`IsLocked` = '1' AND t.`IsSticky` = '0'" . ", p.`ID`, IF(lr.`PostID` IS NULL, 0, lr.`PostID`))" : '') .
86
     ' AND ' . Forums::user_forums_sql() . "
86
     ' AND ' . Forums::user_forums_sql() . "
87
-  GROUP BY t.ID)
88
-  ORDER BY LastPostTime DESC
87
+  GROUP BY t.`ID`)
88
+  ORDER BY `LastPostTime` DESC
89
   LIMIT $Limit");
89
   LIMIT $Limit");
90
 
90
 
91
 $Results = $DB->to_array(false, MYSQLI_ASSOC, false);
91
 $Results = $DB->to_array(false, MYSQLI_ASSOC, false);
162
         $Links = 'Artist: <a href="artist.php?id=' . $Result['PageID'] . '">' . display_str($Result['Name']) . '</a>';
162
         $Links = 'Artist: <a href="artist.php?id=' . $Result['PageID'] . '">' . display_str($Result['Name']) . '</a>';
163
         $JumpLink = 'artist.php?id=' . $Result['PageID'] . '&amp;postid=' . $Result['PostID'] . '#post' . $Result['PostID'];
163
         $JumpLink = 'artist.php?id=' . $Result['PageID'] . '&amp;postid=' . $Result['PostID'] . '#post' . $Result['PostID'];
164
         break;
164
         break;
165
+
166
+
165
       case 'collages':
167
       case 'collages':
166
         $Links = 'Collage: <a href="collages.php?id=' . $Result['PageID'] . '">' . display_str($Result['Name']) . '</a>';
168
         $Links = 'Collage: <a href="collages.php?id=' . $Result['PageID'] . '">' . display_str($Result['Name']) . '</a>';
167
         $JumpLink = 'collages.php?action=comments&collageid=' . $Result['PageID'] . '&amp;postid=' . $Result['PostID'] . '#post' . $Result['PostID'];
169
         $JumpLink = 'collages.php?action=comments&collageid=' . $Result['PageID'] . '&amp;postid=' . $Result['PostID'] . '#post' . $Result['PostID'];
168
         break;
170
         break;
171
+
172
+
169
       case 'requests':
173
       case 'requests':
170
         if (!isset($Requests[$Result['PageID']])) {
174
         if (!isset($Requests[$Result['PageID']])) {
171
             continue;
175
             continue;
172
         }
176
         }
177
+
173
         $Request = $Requests[$Result['PageID']];
178
         $Request = $Requests[$Result['PageID']];
174
         $CategoryName = $Categories[$CategoryID - 1];
179
         $CategoryName = $Categories[$CategoryID - 1];
175
 
180
 
176
         $Links = 'Request: ';
181
         $Links = 'Request: ';
177
-        /*
178
-        if ($CategoryName == 'Music' || $CategoryName == 'Audiobooks' || $CategoryName == 'Comedy') {
179
-            $Links .= ($CategoryName == 'Music' ? Artists::display_artists(Requests::get_artists($Result['PageID'])) : '') . '<a href="requests.php?action=view&amp;id=' . $Result['PageID'] . '" dir="ltr">' . $Request['Title'] . " [" . $Request['Year'] . "]</a>";
180
-        } else {
181
-          */
182
             $Links .= '<a href="requests.php?action=view&amp;id=' . $Result['PageID'] . '">' . $Request['Title'] . "</a>";
182
             $Links .= '<a href="requests.php?action=view&amp;id=' . $Result['PageID'] . '">' . $Request['Title'] . "</a>";
183
-        #} # else
184
         $JumpLink = 'requests.php?action=view&amp;id=' . $Result['PageID'] . '&amp;postid=' . $Result['PostID'] . '#post' . $Result['PostID'];
183
         $JumpLink = 'requests.php?action=view&amp;id=' . $Result['PageID'] . '&amp;postid=' . $Result['PostID'] . '#post' . $Result['PostID'];
185
         break;
184
         break;
185
+
186
+
186
       case 'torrents':
187
       case 'torrents':
187
         if (!isset($TorrentGroups[$Result['PageID']])) {
188
         if (!isset($TorrentGroups[$Result['PageID']])) {
188
             continue;
189
             continue;
189
         }
190
         }
191
+
190
         $GroupInfo = $TorrentGroups[$Result['PageID']];
192
         $GroupInfo = $TorrentGroups[$Result['PageID']];
191
-        $Links = 'Torrent: ' . Artists::display_artists($GroupInfo['ExtendedArtists']) . '<a href="torrents.php?id=' . $GroupInfo['ID'] . '" dir="ltr">' . $GroupInfo['Name'] . '</a>';
192
-        if ($GroupInfo['Year'] > 0) {
193
-            $Links .= " [" . $GroupInfo['Year'] . "]";
194
-        }
195
-        if ($GroupInfo['ReleaseType'] > 0) {
196
-            $Links .= " [" . $ReleaseTypes[$GroupInfo['ReleaseType']] . "]";
193
+        $Links = 'Torrent: ' . Artists::display_artists($GroupInfo['ExtendedArtists']) . '<a href="torrents.php?id=' . $GroupInfo['id'] . '" dir="ltr">' . $GroupInfo['title'] . '</a>';
194
+       
195
+        if ($GroupInfo['year'] > 0) {
196
+            $Links .= " [" . $GroupInfo['year'] . "]";
197
         }
197
         }
198
+
198
         $JumpLink = 'torrents.php?id=' . $GroupInfo['ID'] . '&amp;postid=' . $Result['PostID'] . '#post' . $Result['PostID'];
199
         $JumpLink = 'torrents.php?id=' . $GroupInfo['ID'] . '&amp;postid=' . $Result['PostID'] . '#post' . $Result['PostID'];
199
         break;
200
         break;
201
+
202
+
200
       case 'forums':
203
       case 'forums':
201
         $Links = 'Forums: <a href="forums.php?action=viewforum&amp;forumid=' . $Result['ForumID'] . '">' . display_str($Result['ForumName']) . '</a> &gt; ' .
204
         $Links = 'Forums: <a href="forums.php?action=viewforum&amp;forumid=' . $Result['ForumID'] . '">' . display_str($Result['ForumName']) . '</a> &gt; ' .
202
           '<a href="forums.php?action=viewthread&amp;threadid=' . $Result['PageID'] .
205
           '<a href="forums.php?action=viewthread&amp;threadid=' . $Result['PageID'] .
205
           '</a>';
208
           '</a>';
206
         $JumpLink = 'forums.php?action=viewthread&amp;threadid=' . $Result['PageID'] . '&amp;postid=' . $Result['PostID'] . '#post' . $Result['PostID'];
209
         $JumpLink = 'forums.php?action=viewthread&amp;threadid=' . $Result['PageID'] . '&amp;postid=' . $Result['PostID'] . '#post' . $Result['PostID'];
207
         break;
210
         break;
211
+
208
       default:
212
       default:
209
         error(0);
213
         error(0);
210
     } ?>
214
     } ?>

+ 1
- 1
sections/wiki/article.php View File

83
         <form class="search_form" name="articles" action="wiki.php" method="get">
83
         <form class="search_form" name="articles" action="wiki.php" method="get">
84
           <input type="hidden" name="action" value="search" />
84
           <input type="hidden" name="action" value="search" />
85
           <input type="search" placeholder="Search articles" name="search" size="20" />
85
           <input type="search" placeholder="Search articles" name="search" size="20" />
86
-          <input value="Search" type="submit" class="hidden" />
86
+          <input value="Search" type="submit" class="hidden button-primary" />
87
         </form>
87
         </form>
88
 
88
 
89
         <br style="line-height: 10px;" />
89
         <br style="line-height: 10px;" />

+ 1
- 1
sections/wiki/wiki_browse.php View File

68
       <input type="hidden" name="action" value="search" />
68
       <input type="hidden" name="action" value="search" />
69
       <input type="hidden" name="nojump" value="1" />
69
       <input type="hidden" name="nojump" value="1" />
70
       <input type="search" name="search" size="80" />
70
       <input type="search" name="search" size="80" />
71
-      <input value="Search" type="submit" class="hidden" />
71
+      <input value="Search" type="submit" class="hidden button-primary" />
72
     </form>
72
     </form>
73
     <br />
73
     <br />
74
 
74
 

BIN
static/common/logos/torrents.bio.png View File


+ 254
- 217
static/functions/upload.js View File

1
 /**
1
 /**
2
  * Categories
2
  * Categories
3
- * 
3
+ *
4
  * Toggle category metadata.
4
  * Toggle category metadata.
5
  * Displays dynamic selects on upload.php.
5
  * Displays dynamic selects on upload.php.
6
  * These change with each category.
6
  * These change with each category.
7
  */
7
  */
8
 function Categories() {
8
 function Categories() {
9
   let def = [
9
   let def = [
10
-    'javdb', // Accession Number
11
-    'audio', // Version
12
-    'title', // Torrent Title
13
-    'title_rj', // Organism
14
-    'title_jp', // Strain/Variety
15
-    'artists', // Authors(s)
16
-    'studio', // Department/Lab
17
-    'series', // Location
18
-    'year', // Year
19
-    'codec', // License
10
+    "javdb", // Accession Number
11
+    "audio", // Version
12
+    "title", // Torrent Title
13
+    "title_rj", // Organism
14
+    "title_jp", // Strain/Variety
15
+    "artists", // Authors(s)
16
+    "studio", // Department/Lab
17
+    "series", // Location
18
+    "year", // Year
19
+    "codec", // License
20
     // Platform *changes below*
20
     // Platform *changes below*
21
-    'resolution', // Scope *changes below*
21
+    "resolution", // Scope *changes below*
22
     // Format *changes below*
22
     // Format *changes below*
23
-    'archive', // Archive
24
-    'tags', // Tags
25
-    'cover', // Picture
26
-    'mirrors', // Mirrors
27
-    'screenshots', // Publications
28
-    'group_desc', // Torrent Group Description
29
-    'release_desc', // Torrent Description
30
-    'censored', // Aligned/Annotated
31
-    'anon', // Upload Anonymously
32
-  ]
23
+    "archive", // Archive
24
+    "tags", // Tags
25
+    "cover", // Picture
26
+    "mirrors", // Mirrors
27
+    "screenshots", // Publications
28
+    //'seqhash', // Seqhash
29
+    "group_desc", // Torrent Group Description
30
+    "release_desc", // Torrent Description
31
+    "censored", // Aligned/Annotated
32
+    "anon", // Upload Anonymously
33
+  ];
33
 
34
 
34
   let cats = [
35
   let cats = [
35
-    { // Sequences
36
-      'media': {}, // Platform
37
-      'container': {}, // Format
36
+    {
37
+      // Sequences
38
+      media: {}, // Platform
39
+      container: {}, // Format
40
+      seqhash: {}, // Seqhash
38
     },
41
     },
39
-    { // Graphs
40
-      'media_graphs': {}, // Platform
41
-      'container_graphs': {}, // Format
42
+    {
43
+      // Graphs
44
+      media_graphs: {}, // Platform
45
+      container_graphs: {}, // Format
42
     },
46
     },
43
-    { // Systems
44
-      'media_graphs': {}, // Platform
45
-      'container_graphs': {}, // Format
47
+    {
48
+      // Systems
49
+      media_graphs: {}, // Platform
50
+      container_graphs: {}, // Format
46
     },
51
     },
47
-    { // Geometric
48
-      'media_graphs': {}, // Platform
49
-      'container_graphs': {}, // Format
52
+    {
53
+      // Geometric
54
+      media_graphs: {}, // Platform
55
+      container_graphs: {}, // Format
50
     },
56
     },
51
-    { // Scalars/Vectors
52
-      'media_scalars_vectors': {}, // Platform
53
-      'container_scalars_vectors': {}, // Format
57
+    {
58
+      // Scalars/Vectors
59
+      media_scalars_vectors: {}, // Platform
60
+      container_scalars_vectors: {}, // Format
54
     },
61
     },
55
-    { // Patterns
56
-      'media_graphs': {}, // Platform
57
-      'container_graphs': {}, // Format
62
+    {
63
+      // Patterns
64
+      media_graphs: {}, // Platform
65
+      container_graphs: {}, // Format
58
     },
66
     },
59
-    { // Constraints
60
-      'media_graphs': {}, // Platform
61
-      'container_graphs': {}, // Format
67
+    {
68
+      // Constraints
69
+      media_graphs: {}, // Platform
70
+      container_graphs: {}, // Format
62
     },
71
     },
63
-    { // Images
64
-      'media_images': {}, // Platform
65
-      'container_images': {}, // Format
72
+    {
73
+      // Images
74
+      media_images: {}, // Platform
75
+      container_images: {}, // Format
66
     },
76
     },
67
-    { // Spatial
68
-      'media_graphs': {}, // Platform
69
-      'container_spatial': {}, // Format
77
+    {
78
+      // Spatial
79
+      media_graphs: {}, // Platform
80
+      container_spatial: {}, // Format
70
     },
81
     },
71
-    { // Models
72
-      'media_graphs': {}, // Platform
73
-      'container_spatial': {}, // Format
82
+    {
83
+      // Models
84
+      media_graphs: {}, // Platform
85
+      container_spatial: {}, // Format
74
     },
86
     },
75
-    { // Documents
76
-      'media_documents': {}, // Platform
77
-      'container_documents': {}, // Format
87
+    {
88
+      // Documents
89
+      media_documents: {}, // Platform
90
+      container_documents: {}, // Format
78
     },
91
     },
79
-    { // Machine Data
80
-      'media_machine_data': {}, // Platform
81
-      'container': {}, // Format
92
+    {
93
+      // Machine Data
94
+      media_machine_data: {}, // Platform
95
+      container: {}, // Format
82
     },
96
     },
83
-  ]
84
-
85
-  let active = {}
86
-  for (let field of def) active[field] = {}
87
-
88
-  let category = 0
89
-  if ($('input[name="type"]').raw()) category = $('input[name="type"]').raw().value
90
-  if ($('#categories').raw()) category = $('#categories').raw().value
91
-  active = Object.assign(active, cats[category])
92
-
93
-  let hide = el => {
94
-    Array.from($(`#${el.id} input, #${el.id} select, #${el.id} textarea`)).forEach(inp => inp.disabled = true)
95
-    $(el).ghide()
96
-  }
97
-
98
-  let show = el => {
99
-    Array.from($(`#${el.id} input, #${el.id} select, #${el.id} textarea`)).forEach(inp => inp.disabled = false)
100
-    $(el).gshow()
101
-  }
102
-
103
-  let trs = $('#dynamic_form tr')
97
+  ];
98
+
99
+  let active = {};
100
+  for (let field of def) active[field] = {};
101
+
102
+  let category = 0;
103
+  if ($('input[name="type"]').raw())
104
+    category = $('input[name="type"]').raw().value;
105
+  if ($("#categories").raw()) category = $("#categories").raw().value;
106
+  active = Object.assign(active, cats[category]);
107
+
108
+  let hide = (el) => {
109
+    Array.from(
110
+      $(`#${el.id} input, #${el.id} select, #${el.id} textarea`)
111
+    ).forEach((inp) => (inp.disabled = true));
112
+    $(el).ghide();
113
+  };
114
+
115
+  let show = (el) => {
116
+    Array.from(
117
+      $(`#${el.id} input, #${el.id} select, #${el.id} textarea`)
118
+    ).forEach((inp) => (inp.disabled = false));
119
+    $(el).gshow();
120
+  };
121
+
122
+  let trs = $("#dynamic_form tr");
104
   for (let tr of trs) {
123
   for (let tr of trs) {
105
-    let field = tr.id.slice(0, -3)
124
+    let field = tr.id.slice(0, -3);
106
     if (active[field]) {
125
     if (active[field]) {
107
       if (active[field].name) {
126
       if (active[field].name) {
108
-        tr.children[0].innerHTML = active[field].name
127
+        tr.children[0].innerHTML = active[field].name;
109
       }
128
       }
110
 
129
 
111
-      let notes = $(`#${tr.id} p.notes`).raw()
112
-      if (notes) notes.innerHTML = active[field].notes || ''
113
-      show(tr)
130
+      let notes = $(`#${tr.id} p.notes`).raw();
131
+      if (notes) notes.innerHTML = active[field].notes || "";
132
+      show(tr);
114
     } else {
133
     } else {
115
-      hide(tr)
134
+      hide(tr);
116
     }
135
     }
117
   }
136
   }
118
 }
137
 }
119
 
138
 
120
-
121
 /**
139
 /**
122
  * add_tag
140
  * add_tag
123
  */
141
  */
124
 function add_tag() {
142
 function add_tag() {
125
-  if ($('#tags').raw().value == "") {
126
-    $('#tags').raw().value = $('#genre_tags').raw().options[$('#genre_tags').raw().selectedIndex].value;
127
-  } else if ($('#genre_tags').raw().options[$('#genre_tags').raw().selectedIndex].value == '---') {
143
+  if ($("#tags").raw().value == "") {
144
+    $("#tags").raw().value =
145
+      $("#genre_tags").raw().options[
146
+        $("#genre_tags").raw().selectedIndex
147
+      ].value;
148
+  } else if (
149
+    $("#genre_tags").raw().options[$("#genre_tags").raw().selectedIndex]
150
+      .value == "---"
151
+  ) {
128
   } else {
152
   } else {
129
-    $('#tags').raw().value = $('#tags').raw().value + ', ' + $('#genre_tags').raw().options[$('#genre_tags').raw().selectedIndex].value;
153
+    $("#tags").raw().value =
154
+      $("#tags").raw().value +
155
+      ", " +
156
+      $("#genre_tags").raw().options[$("#genre_tags").raw().selectedIndex]
157
+        .value;
130
   }
158
   }
131
 }
159
 }
132
 
160
 
133
-
134
 /**
161
 /**
135
  * AddLogField
162
  * AddLogField
136
  */
163
  */
146
   LogField.name = "logfiles[]";
173
   LogField.name = "logfiles[]";
147
   LogField.size = 50;
174
   LogField.size = 50;
148
 
175
 
149
-  var x = $('#logfields').raw();
176
+  var x = $("#logfields").raw();
150
   x.appendChild(document.createElement("br"));
177
   x.appendChild(document.createElement("br"));
151
   x.appendChild(LogField);
178
   x.appendChild(LogField);
152
   LogCount++;
179
   LogCount++;
153
 }
180
 }
154
 
181
 
155
-
156
 /**
182
 /**
157
  * RemoveLogField
183
  * RemoveLogField
158
  */
184
  */
161
     return;
187
     return;
162
   }
188
   }
163
 
189
 
164
-  var x = $('#logfields').raw();
190
+  var x = $("#logfields").raw();
165
   for (i = 0; i < 2; i++) {
191
   for (i = 0; i < 2; i++) {
166
     x.removeChild(x.lastChild);
192
     x.removeChild(x.lastChild);
167
   }
193
   }
168
   LogCount--;
194
   LogCount--;
169
 }
195
 }
170
 
196
 
171
-
172
 /**
197
 /**
173
  * AddExtraLogField
198
  * AddExtraLogField
174
  */
199
  */
184
   LogField.name = "logfiles_" + id + "[]";
209
   LogField.name = "logfiles_" + id + "[]";
185
   LogField.size = 50;
210
   LogField.size = 50;
186
 
211
 
187
-  var x = $('#logfields_' + id).raw();
212
+  var x = $("#logfields_" + id).raw();
188
   x.appendChild(document.createElement("br"));
213
   x.appendChild(document.createElement("br"));
189
   x.appendChild(LogField);
214
   x.appendChild(LogField);
190
   LogCount++;
215
   LogCount++;
191
 }
216
 }
192
 
217
 
193
-
194
 /**
218
 /**
195
  * RemoveLogField
219
  * RemoveLogField
196
  */
220
  */
199
     return;
223
     return;
200
   }
224
   }
201
 
225
 
202
-  var x = $('#logfields').raw();
226
+  var x = $("#logfields").raw();
203
   for (i = 0; i < 2; i++) {
227
   for (i = 0; i < 2; i++) {
204
     x.removeChild(x.lastChild);
228
     x.removeChild(x.lastChild);
205
   }
229
   }
206
   LogCount--;
230
   LogCount--;
207
 }
231
 }
208
 
232
 
209
-
210
 /**
233
 /**
211
  * AddFormat
234
  * AddFormat
212
  */
235
  */
217
   }
240
   }
218
 
241
 
219
   FormatCount++;
242
   FormatCount++;
220
-  $('#extras').raw().value = FormatCount;
243
+  $("#extras").raw().value = FormatCount;
221
 
244
 
222
   var NewRow = document.createElement("tr");
245
   var NewRow = document.createElement("tr");
223
   NewRow.id = "new_torrent_row" + FormatCount;
246
   NewRow.id = "new_torrent_row" + FormatCount;
224
-  NewRow.setAttribute("style", "border-top-width: 5px; border-left-width: 5px; border-right-width: 5px;");
247
+  NewRow.setAttribute(
248
+    "style",
249
+    "border-top-width: 5px; border-left-width: 5px; border-right-width: 5px;"
250
+  );
225
 
251
 
226
   var NewCell1 = document.createElement("td");
252
   var NewCell1 = document.createElement("td");
227
   NewCell1.setAttribute("class", "label");
253
   NewCell1.setAttribute("class", "label");
240
 
266
 
241
   NewRow = document.createElement("tr");
267
   NewRow = document.createElement("tr");
242
   NewRow.id = "new_format_row" + FormatCount;
268
   NewRow.id = "new_format_row" + FormatCount;
243
-  NewRow.setAttribute("style", "border-left-width: 5px; border-right-width: 5px;");
269
+  NewRow.setAttribute(
270
+    "style",
271
+    "border-left-width: 5px; border-right-width: 5px;"
272
+  );
244
   NewCell1 = document.createElement("td");
273
   NewCell1 = document.createElement("td");
245
   NewCell1.setAttribute("class", "label");
274
   NewCell1.setAttribute("class", "label");
246
   NewCell1.innerHTML = "Extra Format / Bitrate";
275
   NewCell1.innerHTML = "Extra Format / Bitrate";
247
 
276
 
248
   NewCell2 = document.createElement("td");
277
   NewCell2 = document.createElement("td");
249
-  tmp = '<select id="releasetype" name="extra_formats[]"><option value="">---</option>';
278
+  tmp =
279
+    '<select id="releasetype" name="extra_formats[]"><option value="">---</option>';
250
   var formats = ["Saab", "Volvo", "BMW"];
280
   var formats = ["Saab", "Volvo", "BMW"];
251
 
281
 
252
   for (var i in formats) {
282
   for (var i in formats) {
255
 
285
 
256
   tmp += "</select>";
286
   tmp += "</select>";
257
   var bitrates = ["1", "2", "3"];
287
   var bitrates = ["1", "2", "3"];
258
-  tmp += '<select id="releasetype" name="extra_bitrates[]"><option value="">---</option>';
288
+  tmp +=
289
+    '<select id="releasetype" name="extra_bitrates[]"><option value="">---</option>';
259
 
290
 
260
   for (var i in bitrates) {
291
   for (var i in bitrates) {
261
     tmp += '<option value="' + bitrates[i] + '">' + bitrates[i] + "</option>\n";
292
     tmp += '<option value="' + bitrates[i] + '">' + bitrates[i] + "</option>\n";
266
   NewRow.appendChild(NewCell1);
297
   NewRow.appendChild(NewCell1);
267
   NewRow.appendChild(NewCell2);
298
   NewRow.appendChild(NewCell2);
268
 
299
 
269
-
270
   NewRow = document.createElement("tr");
300
   NewRow = document.createElement("tr");
271
   NewRow.id = "new_description_row" + FormatCount;
301
   NewRow.id = "new_description_row" + FormatCount;
272
-  NewRow.setAttribute("style", "border-bottom-width: 5px; border-left-width: 5px; border-right-width: 5px;");
302
+  NewRow.setAttribute(
303
+    "style",
304
+    "border-bottom-width: 5px; border-left-width: 5px; border-right-width: 5px;"
305
+  );
273
   NewCell1 = document.createElement("td");
306
   NewCell1 = document.createElement("td");
274
   NewCell1.setAttribute("class", "label");
307
   NewCell1.setAttribute("class", "label");
275
   NewCell1.innerHTML = "Extra Release Description";
308
   NewCell1.innerHTML = "Extra Release Description";
276
 
309
 
277
   NewCell2 = document.createElement("td");
310
   NewCell2 = document.createElement("td");
278
-  NewCell2.innerHTML = '<textarea name="extra_release_desc[]" id="release_desc" cols="60" rows="4"></textarea>';
311
+  NewCell2.innerHTML =
312
+    '<textarea name="extra_release_desc[]" id="release_desc" cols="60" rows="4"></textarea>';
279
 
313
 
280
   NewRow.appendChild(NewCell1);
314
   NewRow.appendChild(NewCell1);
281
   NewRow.appendChild(NewCell2);
315
   NewRow.appendChild(NewCell2);
282
 }
316
 }
283
 
317
 
284
-
285
 /**
318
 /**
286
  * RemoveFormat
319
  * RemoveFormat
287
  */
320
  */
290
     return;
323
     return;
291
   }
324
   }
292
 
325
 
293
-  $('#extras').raw().value = FormatCount;
326
+  $("#extras").raw().value = FormatCount;
294
 
327
 
295
-  var x = $('#new_torrent_row' + FormatCount).raw();
328
+  var x = $("#new_torrent_row" + FormatCount).raw();
296
   x.parentNode.removeChild(x);
329
   x.parentNode.removeChild(x);
297
 
330
 
298
-  x = $('#new_format_row' + FormatCount).raw();
331
+  x = $("#new_format_row" + FormatCount).raw();
299
   x.parentNode.removeChild(x);
332
   x.parentNode.removeChild(x);
300
 
333
 
301
-  x = $('#new_description_row' + FormatCount).raw();
334
+  x = $("#new_description_row" + FormatCount).raw();
302
   x.parentNode.removeChild(x);
335
   x.parentNode.removeChild(x);
303
 
336
 
304
   FormatCount--;
337
   FormatCount--;
305
 }
338
 }
306
 
339
 
307
-
308
 /**
340
 /**
309
  * AddArtistField
341
  * AddArtistField
310
  */
342
  */
311
 var ArtistCount = 1;
343
 var ArtistCount = 1;
312
 function AddArtistField() {
344
 function AddArtistField() {
313
-  window.getSelection().removeAllRanges()
345
+  window.getSelection().removeAllRanges();
314
   ArtistCount = $('input[name="artists[]"]').length;
346
   ArtistCount = $('input[name="artists[]"]').length;
315
 
347
 
316
   if (ArtistCount >= 200) {
348
   if (ArtistCount >= 200) {
323
   ArtistField.name = "artists[]";
355
   ArtistField.name = "artists[]";
324
   ArtistField.size = 45;
356
   ArtistField.size = 45;
325
 
357
 
326
-  var x = $('#artistfields').raw();
358
+  var x = $("#artistfields").raw();
327
   x.appendChild(document.createElement("br"));
359
   x.appendChild(document.createElement("br"));
328
   x.appendChild(ArtistField);
360
   x.appendChild(ArtistField);
329
-  x.appendChild(document.createTextNode('\n'));
361
+  x.appendChild(document.createTextNode("\n"));
330
 
362
 
331
   if ($("#artist_0").data("gazelle-autocomplete")) {
363
   if ($("#artist_0").data("gazelle-autocomplete")) {
332
-    $(ArtistField).on('focus', function () {
364
+    $(ArtistField).on("focus", function () {
333
       $(ArtistField).autocomplete({
365
       $(ArtistField).autocomplete({
334
-        serviceUrl: ARTIST_AUTOCOMPLETE_URL
366
+        serviceUrl: ARTIST_AUTOCOMPLETE_URL,
335
       });
367
       });
336
     });
368
     });
337
   }
369
   }
338
   ArtistCount++;
370
   ArtistCount++;
339
 }
371
 }
340
 
372
 
341
-
342
 /**
373
 /**
343
  * RemoveArtistField
374
  * RemoveArtistField
344
  */
375
  */
345
 function RemoveArtistField() {
376
 function RemoveArtistField() {
346
-  window.getSelection().removeAllRanges()
377
+  window.getSelection().removeAllRanges();
347
   ArtistCount = $('input[name="artists[]"]').length;
378
   ArtistCount = $('input[name="artists[]"]').length;
348
 
379
 
349
   if (ArtistCount == 1) {
380
   if (ArtistCount == 1) {
350
     return;
381
     return;
351
   }
382
   }
352
 
383
 
353
-  var x = $('#artistfields').raw();
384
+  var x = $("#artistfields").raw();
354
   for (i = 0; i < 3; i++) {
385
   for (i = 0; i < 3; i++) {
355
     x.removeChild(x.lastChild);
386
     x.removeChild(x.lastChild);
356
   }
387
   }
357
   ArtistCount--;
388
   ArtistCount--;
358
 }
389
 }
359
 
390
 
360
-
361
 /**
391
 /**
362
  * AddScreenshotField
392
  * AddScreenshotField
363
  */
393
  */
364
 function AddScreenshotField() {
394
 function AddScreenshotField() {
365
-  var sss = $('[name="screenshots[]"]')
366
-  if (sss.length >= 10) return
395
+  var sss = $('[name="screenshots[]"]');
396
+  if (sss.length >= 10) return;
367
 
397
 
368
   var ScreenshotField = document.createElement("input");
398
   var ScreenshotField = document.createElement("input");
369
   ScreenshotField.type = "text";
399
   ScreenshotField.type = "text";
371
   ScreenshotField.name = "screenshots[]";
401
   ScreenshotField.name = "screenshots[]";
372
   ScreenshotField.size = 45;
402
   ScreenshotField.size = 45;
373
 
403
 
374
-  var a = document.createElement("a")
375
-  a.className = "brackets"
376
-  a.innerHTML = "−"
377
-  a.onclick = function () { RemoveScreenshotField(this) }
404
+  var a = document.createElement("a");
405
+  a.className = "brackets";
406
+  a.innerHTML = "−";
407
+  a.onclick = function () {
408
+    RemoveScreenshotField(this);
409
+  };
378
 
410
 
379
-  var x = $('#screenshots').raw()
380
-  var y = document.createElement("div")
411
+  var x = $("#screenshots").raw();
412
+  var y = document.createElement("div");
381
   y.appendChild(ScreenshotField);
413
   y.appendChild(ScreenshotField);
382
-  y.appendChild(document.createTextNode('\n'));
414
+  y.appendChild(document.createTextNode("\n"));
383
   y.appendChild(a);
415
   y.appendChild(a);
384
   x.appendChild(y);
416
   x.appendChild(y);
385
 }
417
 }
386
 function RemoveScreenshotField(el) {
418
 function RemoveScreenshotField(el) {
387
-  var sss = $('[name="screenshots[]"]')
388
-  el.parentElement.remove()
419
+  var sss = $('[name="screenshots[]"]');
420
+  el.parentElement.remove();
389
 }
421
 }
390
 
422
 
391
-
392
 /**
423
 /**
393
  * AnimeAutofill
424
  * AnimeAutofill
394
  */
425
  */
395
 function AnimeAutofill() {
426
 function AnimeAutofill() {
396
   var map = {
427
   var map = {
397
-    artist: 'artist_0',
398
-    title: 'title',
399
-    title_rj: 'title_rj',
400
-    title_jp: 'title_jp',
401
-    year: 'year',
402
-    description: 'album_desc'
403
-  }
404
-
405
-  var aid = $('#anidb').raw().value
406
-  $.getJSON('/api.php?action=autofill&cat=anime&aid=' + aid, function (data) {
407
-    if (data.status != "success") return
428
+    artist: "artist_0",
429
+    title: "title",
430
+    title_rj: "title_rj",
431
+    title_jp: "title_jp",
432
+    year: "year",
433
+    description: "album_desc",
434
+  };
435
+
436
+  var aid = $("#anidb").raw().value;
437
+  $.getJSON("/api.php?action=autofill&cat=anime&aid=" + aid, function (data) {
438
+    if (data.status != "success") return;
408
     for (i in data.response) {
439
     for (i in data.response) {
409
-      if (map[i] && !($('#' + map[i]).raw().value)) {
410
-        $('#' + map[i]).raw().value = data.response[i]
440
+      if (map[i] && !$("#" + map[i]).raw().value) {
441
+        $("#" + map[i]).raw().value = data.response[i];
411
       }
442
       }
412
     }
443
     }
413
-  })
444
+  });
414
 }
445
 }
415
 
446
 
416
-
417
 /**
447
 /**
418
  * JavAutofill
448
  * JavAutofill
419
  */
449
  */
420
 function JavAutofill() {
450
 function JavAutofill() {
421
   var map = {
451
   var map = {
422
-    cn: 'javdb',
423
-    artists: 'artists',
424
-    title: 'title',
425
-    title_jp: 'title_jp',
426
-    year: 'year',
427
-    studio: 'studio',
428
-    image: 'image',
429
-    tags: 'tags',
430
-    description: 'album_desc'
431
-  }
432
-
433
-  var cn = $('#javdb_tr #catalogue').raw().value.toUpperCase()
434
-  $.getJSON('/api.php?action=autofill&cat=jav&cn=' + cn, function (data) {
452
+    cn: "javdb",
453
+    artists: "artists",
454
+    title: "title",
455
+    title_jp: "title_jp",
456
+    year: "year",
457
+    studio: "studio",
458
+    image: "image",
459
+    tags: "tags",
460
+    description: "album_desc",
461
+  };
462
+
463
+  var cn = $("#javdb_tr #catalogue").raw().value.toUpperCase();
464
+  $.getJSON("/api.php?action=autofill&cat=jav&cn=" + cn, function (data) {
435
     if (data.status != "success") {
465
     if (data.status != "success") {
436
-      $('#catalogue').raw().value = 'Failed'
437
-      return
466
+      $("#catalogue").raw().value = "Failed";
467
+      return;
438
     } else {
468
     } else {
439
-      $('#catalogue').raw().value = data.response.cn
469
+      $("#catalogue").raw().value = data.response.cn;
440
     }
470
     }
441
 
471
 
442
     for (i in data.response) {
472
     for (i in data.response) {
443
       if (Array.isArray(data.response[i])) {
473
       if (Array.isArray(data.response[i])) {
444
         for (j in data.response[i]) {
474
         for (j in data.response[i]) {
445
-          if (i == 'artists') {
446
-            if (!($('#' + map[i] + '_' + j).raw())) {
447
-              AddArtistField()
475
+          if (i == "artists") {
476
+            if (!$("#" + map[i] + "_" + j).raw()) {
477
+              AddArtistField();
448
             }
478
             }
449
-            $('#' + map[i] + '_' + j).raw().value = data.response[i][j]
479
+            $("#" + map[i] + "_" + j).raw().value = data.response[i][j];
450
           }
480
           }
451
-          if (map[i] == 'tags' && !($('#' + map[i]).raw().value)) {
452
-            $('#' + map[i]).raw().value = data.response[i].join(', ')
481
+          if (map[i] == "tags" && !$("#" + map[i]).raw().value) {
482
+            $("#" + map[i]).raw().value = data.response[i].join(", ");
453
           }
483
           }
454
         }
484
         }
455
       }
485
       }
456
 
486
 
457
-      if (map[i] && $('#' + map[i]).raw() && !($('#' + map[i]).raw().value)) {
458
-        $('#' + map[i]).raw().value = data.response[i]
487
+      if (map[i] && $("#" + map[i]).raw() && !$("#" + map[i]).raw().value) {
488
+        $("#" + map[i]).raw().value = data.response[i];
459
       }
489
       }
460
     }
490
     }
461
 
491
 
462
     if (data.response.screens.length) {
492
     if (data.response.screens.length) {
463
-      $('#album_desc').raw().value = ('[spoiler=Automatically located thumbs][img]' + data.response.screens.join('[/img][img]') + '[/img][/spoiler]\n\n') + $('#album_desc').raw().value
493
+      $("#album_desc").raw().value =
494
+        "[spoiler=Automatically located thumbs][img]" +
495
+        data.response.screens.join("[/img][img]") +
496
+        "[/img][/spoiler]\n\n" +
497
+        $("#album_desc").raw().value;
464
     }
498
     }
465
-  })
499
+  });
466
 }
500
 }
467
 
501
 
468
-
469
 /**
502
 /**
470
  * MangaAutofill
503
  * MangaAutofill
471
  */
504
  */
472
 function MangaAutofill() {
505
 function MangaAutofill() {
473
   var map = {
506
   var map = {
474
-    artists: 'artists',
475
-    title: 'title',
476
-    title_jp: 'title_jp',
477
-    year: 'year',
478
-    tags: 'tags',
479
-    lang: 'lang',
480
-    cover: 'image',
481
-    circle: 'series',
482
-    pages: 'pages',
483
-    description: 'release_desc'
484
-  }
485
-
486
-  var nh = $('#ehentai_tr #catalogue').raw().value
487
-  $.getJSON('/api.php?action=autofill&cat=manga&url=' + nh, function (data) {
507
+    artists: "artists",
508
+    title: "title",
509
+    title_jp: "title_jp",
510
+    year: "year",
511
+    tags: "tags",
512
+    lang: "lang",
513
+    cover: "image",
514
+    circle: "series",
515
+    pages: "pages",
516
+    description: "release_desc",
517
+  };
518
+
519
+  var nh = $("#ehentai_tr #catalogue").raw().value;
520
+  $.getJSON("/api.php?action=autofill&cat=manga&url=" + nh, function (data) {
488
     if (data.status != "success") {
521
     if (data.status != "success") {
489
-      $('#catalogue').raw().value = 'Failed'
490
-      return
522
+      $("#catalogue").raw().value = "Failed";
523
+      return;
491
     }
524
     }
492
 
525
 
493
     for (i in data.response) {
526
     for (i in data.response) {
494
       if (Array.isArray(data.response[i])) {
527
       if (Array.isArray(data.response[i])) {
495
         for (j in data.response[i]) {
528
         for (j in data.response[i]) {
496
-          if (i == 'artists') {
497
-            if (!($('#' + map[i] + '_' + j).raw())) {
498
-              AddArtistField()
529
+          if (i == "artists") {
530
+            if (!$("#" + map[i] + "_" + j).raw()) {
531
+              AddArtistField();
499
             }
532
             }
500
-            $('#' + map[i] + '_' + j).raw().value = data.response[i][j]
533
+            $("#" + map[i] + "_" + j).raw().value = data.response[i][j];
501
           }
534
           }
502
-          if (map[i] == 'tags' && !($('#' + map[i]).raw().value)) {
503
-            $('#' + map[i]).raw().value = data.response[i].join(', ')
535
+          if (map[i] == "tags" && !$("#" + map[i]).raw().value) {
536
+            $("#" + map[i]).raw().value = data.response[i].join(", ");
504
           }
537
           }
505
         }
538
         }
506
       }
539
       }
507
 
540
 
508
-      if (map[i] && $('#' + map[i]).raw() && (!($('#' + map[i]).raw().value) || $('#' + map[i]).raw().value == '---')) {
509
-        $('#' + map[i]).raw().value = data.response[i]
541
+      if (
542
+        map[i] &&
543
+        $("#" + map[i]).raw() &&
544
+        (!$("#" + map[i]).raw().value || $("#" + map[i]).raw().value == "---")
545
+      ) {
546
+        $("#" + map[i]).raw().value = data.response[i];
510
       }
547
       }
511
     }
548
     }
512
-  })
549
+  });
513
 }
550
 }
514
 
551
 
515
-
516
 /**
552
 /**
517
  * SetResolution
553
  * SetResolution
518
  */
554
  */
519
 function SetResolution() {
555
 function SetResolution() {
520
-  if ($('#ressel').raw().value != 'Other') {
521
-    $('#resolution').raw().value = $('#ressel').raw().value
522
-    $('#resolution').ghide()
556
+  if ($("#ressel").raw().value != "Other") {
557
+    $("#resolution").raw().value = $("#ressel").raw().value;
558
+    $("#resolution").ghide();
523
   } else {
559
   } else {
524
-    $('#resolution').raw().value = ''
525
-    $('#resolution').gshow()
526
-    $('#resolution').raw().readOnly = false
560
+    $("#resolution").raw().value = "";
561
+    $("#resolution").gshow();
562
+    $("#resolution").raw().readOnly = false;
527
   }
563
   }
528
 }
564
 }
529
 
565
 
530
-
531
 /**
566
 /**
532
  * initAutofill
567
  * initAutofill
533
  */
568
  */
534
 function initAutofill() {
569
 function initAutofill() {
535
-  $('[autofill]').each(function (i, el) {
536
-    el.addEventListener('click', function (event) {
537
-      ({ 'douj': MangaAutofill, 'anime': AnimeAutofill, 'jav': JavAutofill })[el.attributes['autofill'].value]()
538
-    })
539
-  })
570
+  $("[autofill]").each(function (i, el) {
571
+    el.addEventListener("click", function (event) {
572
+      ({ douj: MangaAutofill, anime: AnimeAutofill, jav: JavAutofill }[
573
+        el.attributes["autofill"].value
574
+      ]());
575
+    });
576
+  });
540
 }
577
 }
541
 
578
 
542
 $(function () {
579
 $(function () {
543
   Categories();
580
   Categories();
544
   initAutofill();
581
   initAutofill();
545
-  $(document).on('click', '.add_artist_button', AddArtistField);
546
-  $(document).on('click', '.remove_artist_button', RemoveArtistField);
547
-})
582
+  $(document).on("click", ".add_artist_button", AddArtistField);
583
+  $(document).on("click", ".remove_artist_button", RemoveArtistField);
584
+});

+ 0
- 23
static/functions/vendor/biojs/cytoscape.js
File diff suppressed because it is too large
View File


+ 0
- 1335
static/functions/vendor/biojs/ntseq.js
File diff suppressed because it is too large
View File


+ 30
- 72
static/styles/bookish/scss/colors.scss View File

17
 $lb800: #0277bd;
17
 $lb800: #0277bd;
18
 $lb900: #01579b;
18
 $lb900: #01579b;
19
 
19
 
20
+/* Skeleton CSS */
21
+$SkeletonDefault: #33c3f0;
22
+$SkeletonFocus: #1eaedb;
23
+$SkeletonHalfdark: scale-color($SkeletonFocus, $lightness: -50%);
24
+
20
 /* The shadow under floating elements */
25
 /* The shadow under floating elements */
21
 $shadow: 2px 2px 10px -2px slategray;
26
 $shadow: 2px 2px 10px -2px slategray;
22
 
27
 
24
  * Common elements
29
  * Common elements
25
  */
30
  */
26
 
31
 
27
-.head {
28
-    background: #b3e5fc;
29
-    color: black;
30
-    padding: 0.5em 1rem;
31
-}
32
-
33
-/* Alternating tables */
34
-#request_table .request:nth-of-type(even) {
35
-    background: white;
36
-}
37
-
38
-#request_table .request:nth-of-type(odd) {
39
-    background: whitesmoke;
40
-}
41
-
42
 /**
32
 /**
43
  * RGB color intensity border
33
  * RGB color intensity border
44
  * For semi-transparent elements,
34
  * For semi-transparent elements,
51
 /**
41
 /**
52
  * Fancy torrent search input
42
  * Fancy torrent search input
53
  */
43
  */
54
-@mixin common-elements() {
55
-    border: none;
56
-    background: white;
57
-    font-size: 100%;
58
-    margin: 0 0.25rem;
59
-    padding: 0.5rem;
60
-    outline: none;
61
-}
62
-
63
-input,
64
-input[type="search"],
65
-input[type="text"] {
66
-    @include common-elements;
67
-    border-bottom: 1px solid rgba(0, 0, 0, 0.1);
68
-    transition: ease-in-out 0.1s;
69
-
70
-    &:focus {
71
-        border-bottom: 1px solid $lb100;
72
-    }
73
-}
74
-
75
-select,
76
-input[type="select"] {
77
-    @include common-elements;
78
-    border: 1px solid rgba(0, 0, 0, 0.1);
79
-    border-radius: 0;
80
-
81
-    appearance: none;
82
-    -webkit-appearance: none;
83
-    -moz-appearance: none;
84
-}
85
 
44
 
86
 checkbox,
45
 checkbox,
87
 input[type="checkbox"] {
46
 input[type="checkbox"] {
93
     border: none;
52
     border: none;
94
 }
53
 }
95
 
54
 
96
-/* Buttons */
97
-button:not(.editor-toolbar button),
98
-input[type="button"],
99
-input[type="submit"] {
100
-    background: $lb200;
101
-    border: none;
102
-    border-radius: 0.25rem;
103
-    box-shadow: $shadow;
104
-    margin: 0 0.25rem;
105
-    padding: 0.75rem 1rem;
106
-    cursor: pointer;
107
-
108
-    &:hover {
109
-        background: $lb50;
110
-    }
111
-
112
-    &:focus {
113
-        background: $lb300;
114
-    }
115
-}
116
-
117
 /**
55
 /**
118
  * Alerts, Toolbox, etc.
56
  * Alerts, Toolbox, etc.
119
  * Needs one unified error display
57
  * Needs one unified error display
120
  * (torrent form, API keys use their own)
58
  * (torrent form, API keys use their own)
121
  */
59
  */
60
+@mixin alertbar($bg) {
61
+    background: change-color($bg, $alpha: 0.25);
62
+    /* box-shadow: $shadow; */
63
+    text-align: center;
64
+    color: black;
65
+    font-weight: bold;
66
+    /* font-size: 0.95rem; */
67
+    width: 33%;
68
+    margin: 2em auto;
69
+    padding: 1rem;
70
+    border-radius: 4px;
71
+    border: 1px solid $bg;
72
+}
73
+
74
+/*
122
 @mixin alertbar($bg) {
75
 @mixin alertbar($bg) {
123
     background: $bg;
76
     background: $bg;
124
     box-shadow: $shadow;
77
     box-shadow: $shadow;
125
     text-align: center;
78
     text-align: center;
126
     color: black;
79
     color: black;
127
     font-weight: bold;
80
     font-weight: bold;
128
-    /* font-size: 0.95rem; */
81
+    /* font-size: 0.95rem; * /
129
     width: 33%;
82
     width: 33%;
130
     margin: 2em auto;
83
     margin: 2em auto;
131
     padding: 1rem;
84
     padding: 1rem;
132
 }
85
 }
86
+*/
133
 
87
 
134
 .alertbar {
88
 .alertbar {
135
-    @include alertbar($lb100);
89
+    @include alertbar(gold);
90
+    /* @include alertbar($lb100); */
136
 
91
 
137
     .warning {
92
     .warning {
138
-        background: #ffe0b2;
93
+        background: orange;
94
+        /* background: #ffe0b2; */
139
     }
95
     }
140
 
96
 
141
     .error {
97
     .error {
142
-        background: #ffcdd2;
98
+        background: red;
99
+        /* background: #ffcdd2; */
143
     }
100
     }
144
 }
101
 }
145
 
102
 
146
 .token_error {
103
 .token_error {
147
-    @include alertbar(#ffcdd2);
104
+    @include alertbar(pink);
105
+    /* @include alertbar(#ffcdd2); */
148
 }
106
 }
149
 
107
 
150
 .modbar a {
108
 .modbar a {

+ 11
- 2
static/styles/bookish/scss/fonts.scss View File

27
     text-align: center;
27
     text-align: center;
28
 }
28
 }
29
 
29
 
30
+/* Section headers ("box" class heading) */
31
+.head {
32
+    padding: 0.5em 0;
33
+    font-size: 120%;
34
+    border-bottom: 1px solid #e1e1e1;
35
+    margin-bottom: 1rem;
36
+}
37
+
30
 /* Links */
38
 /* Links */
31
 a {
39
 a {
32
     color: black;
40
     color: black;
34
 }
42
 }
35
 
43
 
36
 a:hover {
44
 a:hover {
37
-    color: $lb900;
45
+    color: $SkeletonFocus;
46
+    /* color: $lb900; */
38
     text-decoration: none;
47
     text-decoration: none;
39
 }
48
 }
40
 
49
 
94
 }
103
 }
95
 
104
 
96
 ul {
105
 ul {
97
-    margin-left: 1rem;
106
+    margin-left: 0.5rem;
98
 }
107
 }
99
 
108
 
100
 /* Markdown Extra new features */
109
 /* Markdown Extra new features */

+ 20
- 72
static/styles/bookish/scss/layout.scss View File

1
-/*
2
- * Body
3
- */
4
-
5
-* {
6
-    margin: 0;
7
-    padding: 0;
8
-}
9
-
10
-body {
11
-    /* min-width: 800px; */
12
-}
13
-
14
-ol {
15
-    margin-left: 1rem;
16
-}
17
-
18
 /*
1
 /*
19
  * Basic structure
2
  * Basic structure
20
  */
3
  */
26
     width: 100%;
9
     width: 100%;
27
 }
10
 }
28
 
11
 
29
-.head {
30
-    margin-bottom: 0.5rem;
31
-}
32
-
33
 #content {
12
 #content {
34
     margin: auto;
13
     margin: auto;
35
     margin-top: 2rem;
14
     margin-top: 2rem;
47
 
26
 
48
 /* Logo */
27
 /* Logo */
49
 #logo {
28
 #logo {
50
-    background: url("/static/common/logos/bookish.png") no-repeat center;
29
+    background: url("/static/common/logos/torrents.bio.png") no-repeat center;
51
     background-size: contain;
30
     background-size: contain;
52
     width: 250px;
31
     width: 250px;
53
     height: 50px;
32
     height: 50px;
54
-    margin: 0 0 0 10%;
33
+    margin: 0.5rem 0 0.25rem 10%;
55
 
34
 
56
     a {
35
     a {
57
         border: none;
36
         border: none;
65
     }
44
     }
66
 }
45
 }
67
 
46
 
68
-/* Content container */
69
-.box {
70
-    background-color: white;
71
-    /* border: 2px solid rgba(0, 0, 0, 0.01); */
72
-    margin: auto;
73
-    margin-bottom: 1rem;
74
-    width: 100%;
75
-}
76
-
77
 /* Main column and sidebar */
47
 /* Main column and sidebar */
78
 @mixin column-flex($width) {
48
 @mixin column-flex($width) {
79
     display: flex;
49
     display: flex;
85
 }
55
 }
86
 
56
 
87
 .main_column {
57
 .main_column {
88
-    @include column-flex(65%);
58
+    @include column-flex(64%);
89
 
59
 
90
     table {
60
     table {
91
         margin-bottom: 1rem;
61
         margin-bottom: 1rem;
93
 }
63
 }
94
 
64
 
95
 .sidebar {
65
 .sidebar {
96
-    @include column-flex(35%);
66
+    @include column-flex(34%);
97
     float: right;
67
     float: right;
98
 }
68
 }
99
 
69
 
70
+/* Box: soon to be <section> */
71
+.box {
72
+    margin-bottom: 1rem;
73
+}
74
+
100
 /* Links */
75
 /* Links */
101
 div.linkbox {
76
 div.linkbox {
102
     text-align: center;
77
     text-align: center;
103
     padding: 0.5rem;
78
     padding: 0.5rem;
104
 }
79
 }
105
 
80
 
106
-.pad {
107
-    padding: 0 !important;
108
-    /* padding: 1rem; */
109
-
110
-    h3,
111
-    h4 {
112
-        margin-top: 0;
113
-        padding-top: 0;
114
-    }
115
-}
116
-
117
 /* Misc */
81
 /* Misc */
118
 .torrents_nomatch {
82
 .torrents_nomatch {
119
     margin-top: 1rem;
83
     margin-top: 1rem;
128
     margin-top: 1rem;
92
     margin-top: 1rem;
129
 }
93
 }
130
 
94
 
131
-/* Torrents page */
95
+/**
96
+ * Torrents page
97
+ */
98
+
132
 .show_torrents {
99
 .show_torrents {
133
     width: 21px;
100
     width: 21px;
134
     height: 28px;
101
     height: 28px;
171
     border: none;
138
     border: none;
172
 }
139
 }
173
 
140
 
174
-.torrent_table tr {
175
-    /* vertical-align: top; */
176
-    vertical-align: middle;
177
-}
178
-
179
 .torrent_table .number_column {
141
 .torrent_table .number_column {
180
     text-align: center;
142
     text-align: center;
181
 }
143
 }
182
 
144
 
183
-.torrent_table,
184
-.torrent_table td {
185
-    border: none;
186
-}
187
-
188
-/* Text elements */
189
-h1,
190
-h2,
191
-h3,
192
-h4 {
193
-    margin: 0.5em 0;
194
-    font-weight: bold;
195
-}
145
+/**
146
+ * Text elements
147
+ */
196
 
148
 
197
 p {
149
 p {
198
-    margin: 1em 0.5rem;
150
+    margin-bottom: 1rem;
199
 }
151
 }
200
 
152
 
201
 li {
153
 li {
202
-    margin: 0.5em 2rem;
154
+    margin: 0 1rem;
203
 }
155
 }
204
 
156
 
205
 .torrent_title {
157
 .torrent_title {
286
 
238
 
287
 .center_poll {
239
 .center_poll {
288
     height: 0.75rem;
240
     height: 0.75rem;
289
-    background: $lb50;
241
+    background: $SkeletonDefault;
242
+    /* background: $lb50; */
290
     border-radius: 0;
243
     border-radius: 0;
291
     float: left;
244
     float: left;
292
     margin: 0.25rem 0;
245
     margin: 0.25rem 0;
355
     }
308
     }
356
     */
309
     */
357
 }
310
 }
358
-
359
-/* User and torrent stats */
360
-.chart {
361
-    max-height: 30rem;
362
-}

+ 11
- 10
static/styles/bookish/scss/menus.scss View File

3
  */
3
  */
4
 
4
 
5
 #menu {
5
 #menu {
6
-    background-color: $lb900;
6
+    background-color: $SkeletonHalfdark;
7
+    /* background-color: $lb900; */
7
     font-size: 1rem;
8
     font-size: 1rem;
8
     text-align: center;
9
     text-align: center;
9
     width: 100%;
10
     width: 100%;
36
     max-width: 2.5rem;
37
     max-width: 2.5rem;
37
 }
38
 }
38
 
39
 
39
-#menu ul li a.active {
40
-    background-color: $lb700;
40
+#menu ul li a:active {
41
+    background-color: $SkeletonFocus;
42
+    /* background-color: $lb700; */
41
 }
43
 }
42
 
44
 
43
 #menu ul li a:hover {
45
 #menu ul li a:hover {
44
-    background-color: $lb700;
46
+    background-color: $SkeletonFocus;
47
+    /* background-color: $lb700; */
45
     color: white;
48
     color: white;
46
     text-decoration: none;
49
     text-decoration: none;
47
 }
50
 }
48
 
51
 
49
 /* Dropdown */
52
 /* Dropdown */
50
 #menu .nav_dropdown {
53
 #menu .nav_dropdown {
51
-    background: #01579b;
54
+    background-color: $SkeletonHalfdark;
52
     margin-top: 0;
55
     margin-top: 0;
53
 }
56
 }
54
 
57
 
55
 .nav_dropdown > div {
58
 .nav_dropdown > div {
56
     box-shadow: $shadow;
59
     box-shadow: $shadow;
57
     position: absolute;
60
     position: absolute;
58
-    background-color: #01579b;
61
+    background-color: $SkeletonHalfdark;
59
     width: 100%;
62
     width: 100%;
60
     z-index: 99999;
63
     z-index: 99999;
61
     margin-top: 2.5rem;
64
     margin-top: 2.5rem;
85
 
88
 
86
 #searchbars {
89
 #searchbars {
87
     text-align: center;
90
     text-align: center;
88
-    background-color: $lb200;
89
-    box-shadow: $shadow;
90
     box-sizing: content-box;
91
     box-sizing: content-box;
91
     padding: 0.5rem 10%;
92
     padding: 0.5rem 10%;
92
     display: flex;
93
     display: flex;
133
 }
134
 }
134
 
135
 
135
 #searchbars ul li ul li {
136
 #searchbars ul li ul li {
136
-    margin: 0 0 0 0;
137
+    margin: 0;
137
     padding: 0;
138
     padding: 0;
138
     display: block;
139
     display: block;
139
     width: 100%;
140
     width: 100%;
152
  */
153
  */
153
 #userinfo {
154
 #userinfo {
154
     color: black;
155
     color: black;
155
-    padding: 0.5em 0;
156
+    /* padding: 0.5em 0; */
156
     width: 100%;
157
     width: 100%;
157
     text-align: center;
158
     text-align: center;
158
 }
159
 }

+ 65
- 76
static/styles/bookish/scss/tables.scss View File

1
-@mixin center-all {
1
+/**
2
+ * Tables
3
+ */
4
+
5
+@mixin alternating-rows {
6
+    tr:nth-child(2n) {
7
+        background: whitesmoke;
8
+    }
9
+
10
+    tr:nth-child(2n-1) {
11
+        background: white;
12
+    }
2
 }
13
 }
3
 
14
 
15
+/* Every table */
4
 table {
16
 table {
5
-    /* border: 2px solid rgba(0, 0, 0, 0.01); */
6
-    border-collapse: collapse;
7
     width: 100%;
17
     width: 100%;
8
 
18
 
9
-    /*
10
-    * {
11
-        vertical-align: middle;
19
+    th {
20
+        font-size: 120%;
12
     }
21
     }
13
-    */
14
 
22
 
15
-    tr {
16
-        background-color: white;
23
+    td,
24
+    td:first-child {
25
+        padding: 0.5rem !important;
17
     }
26
     }
27
+}
18
 
28
 
19
-    td,
20
-    th {
21
-        padding: 0.5rem;
22
-        text-align: left;
29
+/* Special tables */
30
+.torrent_table,
31
+.collage_table,
32
+.request_table,
33
+.top10_table {
34
+    @include alternating-rows;
35
+
36
+    th,
37
+    td {
38
+        border-bottom: 1px solid #e1e1e1;
39
+    }
40
+}
41
+
42
+.torrent_table,
43
+.collage_table {
44
+    div.tags {
45
+        font-weight: normal;
46
+        max-width: 500px;
47
+    }
48
+
49
+    span {
50
+        float: right;
23
     }
51
     }
24
 }
52
 }
25
 
53
 
26
 /**
54
 /**
27
  * Torrent form
55
  * Torrent form
28
  */
56
  */
57
+
29
 .torrent_form,
58
 .torrent_form,
30
 #dynamic_form {
59
 #dynamic_form {
31
     /* margin-bottom: 2rem; */
60
     /* margin-bottom: 2rem; */
39
     }
68
     }
40
 }
69
 }
41
 
70
 
42
-/* Classes */
71
+/**
72
+ * colhead
73
+ * The main table heading.
74
+ */
75
+
43
 .colhead {
76
 .colhead {
44
-    background: $lb100;
77
+    padding: 0.5em 0;
78
+    border-bottom: 1px solid #e1e1e1;
79
+    font-size: 120%;
45
     font-weight: bold;
80
     font-weight: bold;
46
-    color: black;
47
-}
48
-
49
-td.colhead,
50
-.colhead td,
51
-.colhead th {
52
-    padding-left: 10px;
53
-    padding-right: 10px;
54
 }
81
 }
55
 
82
 
56
 .colhead .sign,
83
 .colhead .sign,
66
     font-weight: bold;
93
     font-weight: bold;
67
 }
94
 }
68
 
95
 
69
-.colhead_dark {
70
-    background: $lb100;
71
-    color: black;
72
-}
73
-
74
 /* Torrent and collage tables */
96
 /* Torrent and collage tables */
75
-.torrent_table,
76
-.collage_table {
77
-    tr.group {
78
-        background-color: white;
79
-
80
-        td.center:first-child {
81
-            padding: 3px;
82
-            width: 21px;
83
-        }
84
-    }
85
-
86
-    tr.group_torrent {
87
-        background-color: white;
88
-
89
-        span {
90
-            float: right;
91
-        }
92
-    }
93
-
94
-    tr.torrent {
95
-        background-color: white;
96
-    }
97
-
98
-    tr.torrent:nth-child(2n),
99
-    tr.row:nth-child(2n) {
100
-        background-color: whitesmoke;
101
-    }
102
-
103
-    tr.torrent:nth-child(2n-1),
104
-    tr.row:nth-child(2n-1) {
105
-        background-color: white;
106
-    }
107
-
108
-    tr .center,
109
-    td {
110
-        vertical-align: middle;
111
-        /* text-align: center; */
112
-    }
113
-    div.tags {
114
-        font-weight: normal;
115
-        max-width: 500px;
116
-    }
117
-}
118
-
119
 .torrent_table .group_torrent .torrent span {
97
 .torrent_table .group_torrent .torrent span {
120
     font-weight: normal;
98
     font-weight: normal;
121
     float: right;
99
     float: right;
122
 }
100
 }
123
 
101
 
124
-/* Forums */
102
+/**
103
+ * Forums
104
+ */
105
+
106
+@mixin forum-post($color) {
107
+    background-color: $color;
108
+    border-bottom: 1px solid #e1e1e1;
109
+    font-size: 120%;
110
+}
111
+
125
 .forum_post .colhead_dark {
112
 .forum_post .colhead_dark {
126
-    background: $lb100;
113
+    @include forum-post(white);
114
+    /* background: $lb100; */
127
 }
115
 }
128
 
116
 
129
 .forum_post.staff_post .colhead_dark {
117
 .forum_post.staff_post .colhead_dark {
130
-    background: $lb200;
118
+    @include forum-post(whitesmoke);
119
+    /* background: $lb200; */
131
 }
120
 }
132
 
121
 
133
 .forum_post.sticky_post {
122
 .forum_post.sticky_post {
134
-    border: 2px solid $lb200;
123
+    border: 2px solid $SkeletonDefault;
135
 }
124
 }
136
 
125
 
137
 td.label {
126
 td.label {

+ 1
- 0
static/styles/global/global.scss View File

8
 @import "scss/layout";
8
 @import "scss/layout";
9
 @import "scss/log";
9
 @import "scss/log";
10
 @import "scss/settings";
10
 @import "scss/settings";
11
+@import "scss/skeleton-fixes";
11
 @import "scss/tables";
12
 @import "scss/tables";

+ 1
- 1
static/styles/global/scss/debug.scss View File

29
     border-radius: 100px;
29
     border-radius: 100px;
30
 }
30
 }
31
 
31
 
32
-/*
32
+/**
33
  * Fix long filename tables overflowing (Chrome only).
33
  * Fix long filename tables overflowing (Chrome only).
34
  * Stop various release page containers from overflowing with long input.
34
  * Stop various release page containers from overflowing with long input.
35
  * !! Be sure to test all major browsers before changing this section. !!
35
  * !! Be sure to test all major browsers before changing this section. !!

+ 0
- 1
static/styles/global/scss/fonts.scss View File

1
 html {
1
 html {
2
     font-size: 16px;
2
     font-size: 16px;
3
     line-height: 1.6;
3
     line-height: 1.6;
4
-    /* line-height: 1.6; */
5
 }
4
 }
6
 
5
 
7
 /*
6
 /*

+ 28
- 0
static/styles/global/scss/layout.scss View File

1
+/*
2
+ * Body
3
+ */
4
+
5
+* {
6
+    margin: 0;
7
+    padding: 0;
8
+}
9
+
1
 /*
10
 /*
2
  * Flex elements
11
  * Flex elements
3
  */
12
  */
50
     &.upload_notice {
59
     &.upload_notice {
51
         @include transparent-border($R: 255, $A: 0.5);
60
         @include transparent-border($R: 255, $A: 0.5);
52
         margin: 1rem auto;
61
         margin: 1rem auto;
62
+        padding-top: 1rem;
53
         text-align: center;
63
         text-align: center;
54
     }
64
     }
55
 
65
 
67
     }
77
     }
68
 }
78
 }
69
 
79
 
80
+/**
81
+ * Footer
82
+ */
83
+
84
+footer {
85
+    margin-top: 2rem;
86
+    width: 100%;
87
+
88
+    p {
89
+        text-align: center;
90
+    }
91
+}
92
+
70
 /*
93
 /*
71
  * Misc
94
  * Misc
72
  */
95
  */
184
         height: 2rem;
207
         height: 2rem;
185
     }
208
     }
186
 }
209
 }
210
+
211
+/* User and torrent stats */
212
+.chart {
213
+    max-height: 30rem;
214
+}

+ 20
- 0
static/styles/global/scss/legacy.scss View File

47
     outline: none;
47
     outline: none;
48
 }
48
 }
49
 
49
 
50
+/* 2021-07-24
50
 select {
51
 select {
51
     padding: 5px 10px;
52
     padding: 5px 10px;
52
     background-color: white;
53
     background-color: white;
58
     -moz-appearance: none;
59
     -moz-appearance: none;
59
     appearance: none;
60
     appearance: none;
60
 }
61
 }
62
+*/
61
 
63
 
62
 h2 .group_cat {
64
 h2 .group_cat {
63
     height: 16px;
65
     height: 16px;
129
     cursor: pointer;
131
     cursor: pointer;
130
 }
132
 }
131
 
133
 
134
+/* 2021-07-24
132
 button,
135
 button,
133
 input[type="button"],
136
 input[type="button"],
134
 input[type="submit"] {
137
 input[type="submit"] {
139
     border: none;
142
     border: none;
140
     color: #000;
143
     color: #000;
141
 }
144
 }
145
+*/
142
 
146
 
143
 .spoilerButton {
147
 .spoilerButton {
144
     cursor: pointer;
148
     cursor: pointer;
582
  * Fix long release descriptions overflowing containers (all browsers).
586
  * Fix long release descriptions overflowing containers (all browsers).
583
  * Fix flowing issues in the report resolving pages.
587
  * Fix flowing issues in the report resolving pages.
584
  */
588
  */
589
+/* 2021-07-24
585
 .wrap_overflow,
590
 .wrap_overflow,
586
 .filelist_table td,
591
 .filelist_table td,
587
 .reportinfo_table,
592
 .reportinfo_table,
593
     word-break: break-word;
598
     word-break: break-word;
594
     hyphens: auto;
599
     hyphens: auto;
595
 }
600
 }
601
+*/
596
 
602
 
597
 .filelist_table td:first-child {
603
 .filelist_table td:first-child {
598
     word-break: break-all;
604
     word-break: break-all;
1051
 }
1057
 }
1052
 */
1058
 */
1053
 
1059
 
1060
+/* 2021-07-24
1054
 .flex {
1061
 .flex {
1055
     display: flex;
1062
     display: flex;
1056
 }
1063
 }
1064
+*/
1057
 
1065
 
1066
+/* 2021-07-24
1058
 .flex > .grow {
1067
 .flex > .grow {
1059
     flex-grow: 1;
1068
     flex-grow: 1;
1060
 }
1069
 }
1070
+*/
1061
 
1071
 
1072
+/* 2021-07-24
1062
 .flex > .shrink {
1073
 .flex > .shrink {
1063
     flex-shrink: 1;
1074
     flex-shrink: 1;
1064
 }
1075
 }
1076
+*/
1065
 
1077
 
1078
+/* 2021-07-24
1066
 input[type="search"] {
1079
 input[type="search"] {
1067
     -webkit-appearance: textfield;
1080
     -webkit-appearance: textfield;
1068
 }
1081
 }
1082
+*/
1069
 
1083
 
1070
 #lightbox > img {
1084
 #lightbox > img {
1071
     max-width: 100%;
1085
     max-width: 100%;
1089
     display: flex;
1103
     display: flex;
1090
 }
1104
 }
1091
 
1105
 
1106
+/* 2021-07-24
1092
 #publickey {
1107
 #publickey {
1093
     width: initial;
1108
     width: initial;
1094
     font-family: monospace;
1109
     font-family: monospace;
1095
 }
1110
 }
1111
+*/
1096
 
1112
 
1097
 .hidden {
1113
 .hidden {
1098
     display: none;
1114
     display: none;
1103
     width: 400px;
1119
     width: 400px;
1104
 }
1120
 }
1105
 
1121
 
1122
+/* 2021-07-24
1106
 #dbcrypt {
1123
 #dbcrypt {
1107
     position: fixed;
1124
     position: fixed;
1108
     top: 10px;
1125
     top: 10px;
1109
     right: 10px;
1126
     right: 10px;
1110
 }
1127
 }
1128
+*/
1111
 
1129
 
1130
+/* 2021-07-24
1112
 #dbcrypt:after {
1131
 #dbcrypt:after {
1113
     content: "!";
1132
     content: "!";
1114
     display: block;
1133
     display: block;
1122
     background: red;
1141
     background: red;
1123
     border-radius: 100px;
1142
     border-radius: 100px;
1124
 }
1143
 }
1144
+*/

+ 162
- 0
static/styles/global/scss/skeleton-fixes.scss View File

1
+/**
2
+ * Fixes needed to use skeleton.css
3
+ * to its best no-fuss advantage
4
+ */
5
+
6
+/* Set heading fonts 50% of default and bump down a level */
7
+@mixin heading-attributes {
8
+    letter-spacing: -1px !important;
9
+    margin: 1rem 0 !important;
10
+}
11
+
12
+h1:not(#logo) {
13
+    font-size: 1.8rem !important;
14
+    @include heading-attributes;
15
+}
16
+
17
+h2 {
18
+    font-size: 1.5rem !important;
19
+    @include heading-attributes;
20
+}
21
+
22
+h3 {
23
+    font-size: 1.2rem !important;
24
+    @include heading-attributes;
25
+}
26
+
27
+h4 {
28
+    font-size: 0.9rem !important;
29
+    @include heading-attributes;
30
+}
31
+
32
+h5 {
33
+    font-size: 0.75rem !important;
34
+    @include heading-attributes;
35
+}
36
+
37
+h6 {
38
+    font-size: 0.75rem !important;
39
+    @include heading-attributes;
40
+}
41
+
42
+/* Larger than phablet */
43
+@media (min-width: 550px) {
44
+    h1 {
45
+        font-size: 1.8rem !important;
46
+    }
47
+
48
+    h2 {
49
+        font-size: 1.5rem !important;
50
+    }
51
+
52
+    h3 {
53
+        font-size: 1.2rem !important;
54
+    }
55
+
56
+    h4 {
57
+        font-size: 0.9rem !important;
58
+    }
59
+
60
+    h5 {
61
+        font-size: 0.75rem !important;
62
+    }
63
+
64
+    h6 {
65
+        font-size: 0.75rem !important;
66
+    }
67
+}
68
+
69
+/* Forum list headings */
70
+table.forum_index {
71
+    h4 {
72
+        margin: 0 !important;
73
+    }
74
+}
75
+
76
+/* Checkbox and radio labels */
77
+label,
78
+legend {
79
+    display: inline !important;
80
+}
81
+
82
+/* Tables usually containing forms */
83
+/* browse */
84
+table.torrent_search,
85
+/* request search */ table.torrent_requests,
86
+/* forum list */ table.forum_index,
87
+/* upload form */ table.torrent_form,
88
+/* requests? */ table.request_form,
89
+/* new request */ form#request_form,
90
+/* forum thread */ table.new_thread,
91
+/* toolbox */ table.admin_tools,
92
+/* BP */ table.store_table,
93
+/* rule sections */ div.rule_table,
94
+/* client rules */ table.clients_table,
95
+/* login */ table.login_form,
96
+/* requests? */form.create_form,
97
+/* top10 */ form.search_form,
98
+/* edit collage */ table.collage_edit,
99
+/* start user management */
100
+table#user_info_box,
101
+table#warn_user_box,
102
+table#user_lock_account,
103
+table#user_privs_box,
104
+table#session_box,
105
+table#donation_box,
106
+table#donor_points_box,
107
+table#submit_box,
108
+/* end user management */
109
+/* notif filters */ form[name="notification"],
110
+/* wiki search */ table.wiki_browse,
111
+/* better.php */ table.better_list {
112
+    th,
113
+    td {
114
+        border-bottom: 0 !important;
115
+        padding: 0.25rem !important;
116
+    }
117
+}
118
+
119
+/* Duplicate input rules here */
120
+input,
121
+input[type="search"],
122
+input[type="text"] {
123
+    margin: 0 !important;
124
+}
125
+
126
+input,
127
+textarea,
128
+select,
129
+fieldset {
130
+    margin-bottom: 0 !important;
131
+}
132
+
133
+/* Block elements */
134
+pre,
135
+blockquote,
136
+dl,
137
+figure,
138
+table,
139
+ul,
140
+ol,
141
+form {
142
+    margin-bottom: 0 !important;
143
+}
144
+
145
+/* Inline code */
146
+code {
147
+    padding: 0 !important;
148
+}
149
+
150
+/* Unordered lists */
151
+ul {
152
+    list-style: circle outside !important;
153
+}
154
+
155
+/* Nested lists */
156
+ul ul,
157
+ul ol,
158
+ol ol,
159
+ol ul {
160
+    margin: 0 !important;
161
+    font-size: 100% !important;
162
+}

+ 19
- 9
static/styles/public/scss/public.scss View File

1
+/* Skeleton CSS */
2
+$SkeletonDefault: #33c3f0;
3
+$SkeletonFocus: #1eaedb;
4
+$SkeletonHalfdark: scale-color($SkeletonFocus, $lightness: -50%);
5
+
1
 * {
6
 * {
2
     margin: 0;
7
     margin: 0;
3
     padding: 0;
8
     padding: 0;
49
 }
54
 }
50
 
55
 
51
 ul {
56
 ul {
52
-    margin-left: 2rem;
57
+    margin-left: 0.5rem;
58
+
59
+    li {
60
+        margin-bottom: 0;
61
+    }
53
 
62
 
54
     &.p li {
63
     &.p li {
55
         margin-bottom: 1rem;
64
         margin-bottom: 1rem;
64
 /**
73
 /**
65
  * Inputs
74
  * Inputs
66
  */
75
  */
67
-
76
+/*
68
 input[type="text"],
77
 input[type="text"],
69
 input[type="password"],
78
 input[type="password"],
70
 input[type="email"] {
79
 input[type="email"] {
119
     text-align: right;
128
     text-align: right;
120
     padding-right: 5px;
129
     padding-right: 5px;
121
 }
130
 }
131
+*/
122
 
132
 
123
 /**
133
 /**
124
  * Layout
134
  * Layout
126
 
136
 
127
 header,
137
 header,
128
 footer {
138
 footer {
129
-    height: 2rem;
130
-    line-height: 2rem;
139
+    height: 2.5rem;
140
+    line-height: 2.5rem;
131
     width: 100%;
141
     width: 100%;
132
-    background: #01579b;
142
+    background: $SkeletonHalfdark;
133
     position: fixed;
143
     position: fixed;
134
     left: 0;
144
     left: 0;
135
 
145
 
156
 }
166
 }
157
 
167
 
158
 main {
168
 main {
159
-    width: 250px;
169
+    width: 25%;
160
     height: calc(80% - 60px);
170
     height: calc(80% - 60px);
161
     margin: 0 auto;
171
     margin: 0 auto;
162
     padding: 10% 0;
172
     padding: 10% 0;
163
 }
173
 }
164
 
174
 
165
 #logo {
175
 #logo {
166
-    width: 250px;
176
+    /* width: 250px; */
167
     height: 50px;
177
     height: 50px;
168
-    background-image: url("/static/common/logos/bookish.png");
178
+    background-image: url("/static/common/logos/torrents.bio.png");
169
     background-repeat: no-repeat;
179
     background-repeat: no-repeat;
170
     background-position: center;
180
     background-position: center;
171
     background-size: contain;
181
     background-size: contain;
215
     content: "℠";
225
     content: "℠";
216
     font-size: 0.75rem;
226
     font-size: 0.75rem;
217
     font-weight: normal;
227
     font-weight: normal;
218
-    margin-left: 100%;
228
+    margin-left: 93%;
219
 }
229
 }

+ 24
- 0
templates/input/passphrase.html View File

1
+<input
2
+  type="password"
3
+  name="{{ name|default('password') }}"
4
+  id="{{ id|default('password') }}"
5
+  placeholder="{{ placeholder|default('passphrase') }}"
6
+  minlength="{{ pw_min|default('15') }}"
7
+  maxlength="{{ pw_max|default('10000') }}"
8
+  pattern=".{ {{ pw_min }},{{ pw_max }} }"
9
+  class="inputtext"
10
+  autocomplete="off"
11
+  required="required"
12
+/>
13
+
14
+<strong id="pass_match"></strong>
15
+
16
+{% if advice == true %}
17
+<p>
18
+  Any password {{ pw_min }} characters or longer is accepted, but a strong password
19
+  <ul>
20
+    <li>is a pass<em>phrase</em> of mixed case with many small words,</li>
21
+    <li>that contains complex characters including Unicode and emoji.</li>
22
+  </ul>
23
+</p>
24
+{% endif %}

+ 14
- 0
templates/torrent_form/mirrors.html View File

1
+<tr id="mirrors_tr">
2
+  <td>
3
+    <label for="mirrors">{{ db.name }}</label>
4
+  </td>
5
+
6
+  <td>
7
+    <textarea
8
+      rows="2"
9
+      name="mirrors"
10
+      id="mirrors"
11
+      {# Needs to be all on one line #}
12
+      placeholder="{{ db.desc }}">{{ mirrors }}</textarea>
13
+  </td>
14
+</tr>

+ 16
- 0
templates/torrent_form/picture.html View File

1
+<tr id="cover_tr">
2
+  <td>
3
+    <label for="image">{{db.name }}</label>
4
+  </td>
5
+
6
+  <td>
7
+    <input
8
+      type="text"
9
+      id="image"
10
+      name="image"
11
+      size="60"
12
+      placeholder="{{ db.desc }}"
13
+      value="{{ picture }}"
14
+    />
15
+  </td>
16
+</tr>

+ 54
- 0
templates/torrent_form/seqhash.html View File

1
+<tr id="seqhash_tr">
2
+  <td>
3
+    <label for="seqhash">{{ db.name }}</label>
4
+    {#
5
+    <br />
6
+    <a class="add_artist_button brackets" onclick="AddArtistField()">+</a>
7
+    <a class="remove_artist_button brackets" onclick="RemoveArtistField()">&minus;</a>
8
+    #}
9
+  </td>
10
+
11
+  <td>
12
+    <textarea
13
+      rows="2"
14
+      name="seqhash"
15
+      id="seqhash"
16
+      {# Needs to be all on one line #}
17
+      placeholder="{{ db.desc }}">{{ seqhash }}</textarea>
18
+
19
+    <input type="radio" id="dna" name="seqhash_meta1" value="DNA" checked /> DNA
20
+    {# <label for="dna">DNA</label> #}
21
+
22
+    &emsp;
23
+
24
+    <input type="radio" id="rna" name="seqhash_meta1" value="RNA" /> RNA
25
+    {# <label for="rna">RNA</label> #}
26
+
27
+    &emsp;
28
+
29
+    <input type="radio" id="protein" name="seqhash_meta1" value="PROTEIN" /> Protein
30
+    {# <label for="protein">Protein</label> #}
31
+
32
+    <br />
33
+
34
+    <input type="radio" id="linear" name="seqhash_meta2" value="false" checked /> Linear
35
+    {# <label for="linear">Linear</label> #}
36
+
37
+    &emsp;
38
+
39
+    <input type="radio" id="circular" name="seqhash_meta2" value="true" /> Circular
40
+    {# <label for="circular">Circular</label> #}
41
+
42
+    <br />
43
+
44
+    <input type="radio" id="double_stranded" name="seqhash_meta3" value="true" checked /> Double-Stranded
45
+    {# <label for="double_stranded">Double-Stranded</label> #}
46
+
47
+    &emsp;
48
+
49
+    <input type="radio" id="single_stranded" name="seqhash_meta3" value="false" /> Single-Stranded
50
+    {# <label for="single_stranded">Single-Stranded</label> #}
51
+
52
+    <p>{{ db.note|raw }}</p>
53
+  </td>
54
+</tr>

+ 2
- 2
templates/torrent_form/version.html View File

10
       name="version"
10
       name="version"
11
       size="12"
11
       size="12"
12
       pattern="\d+\.*\d*\.*\d*"
12
       pattern="\d+\.*\d*\.*\d*"
13
-      placeholder="{{ db.desc}}"
13
+      placeholder="{{ db.desc }}"
14
       value="{{ version }}"
14
       value="{{ version }}"
15
     />
15
     />
16
 
16
 
17
-    <p>{{ note }}</p>
17
+    <p>{{ db.note|raw }}</p>
18
   </td>
18
   </td>
19
 </tr>
19
 </tr>

+ 53
- 0
templates/wiki/browse.html View File

1
+<section class="wiki_search">
2
+  <p>Search the wiki for user created tutorials and information.</p>
3
+
4
+  <form class="search_form" name="wiki" action="wiki.php" method="get">
5
+    <input type="hidden" name="action" value="search" />
6
+    <input type="hidden" name="nojump" value="1" />
7
+    <input type="search" name="search" size="80" />
8
+    <input value="Search" type="submit" class="hidden button-primary" />
9
+  </form>
10
+  <br />
11
+
12
+  <p>
13
+    Additionally, you can manually browse through the articles by their first letter.
14
+  </p>
15
+  
16
+  <span>
17
+    {% for letter in 'a'..'z' %}
18
+    <a href="wiki.php?action=browse&amp;letter={{ letter }}"
19
+      >{{ letter|upper }}</a
20
+    >&nbsp;&nbsp; {% endfor %}
21
+    <a href="wiki.php?action=browse&amp;letter=1">All</a>&nbsp;&nbsp;
22
+  </span>
23
+</section>
24
+
25
+<section class="wiki_results">
26
+  <div class="header">
27
+    <h2>{{ title }}</h2>
28
+  </div>
29
+  <div class="linkbox">
30
+    <a href="wiki.php?action=create" class="brackets">Create</a>
31
+  </div>
32
+
33
+
34
+  <table width="100%" style="margin-bottom: 10px">
35
+    <tr class="colhead">
36
+      <td>Article</td>
37
+      <td>Last updated on</td>
38
+      <td>Last edited by</td>
39
+    </tr>
40
+    {% for article in articles %}
41
+    <tr>
42
+      <td>
43
+        <a href="wiki.php?action=article&amp;id={{ article.ID }}"
44
+          >{{ article.Title }}</a
45
+        >
46
+      </td>
47
+      <td>{{ article.Date }}</td>
48
+      <td>{{ article.Author|user_url }}</td>
49
+    </tr>
50
+    {% endfor %}
51
+  </table>
52
+
53
+</section>

+ 0
- 49
templates/wiki/browse.twig View File

1
-{% macro letter_box(show_search = true) %}
2
-    <div class="box pad center">
3
-        {% if show_search %}
4
-        <p>Search the wiki for user created tutorials and information.</p>
5
-        <form class="search_form" name="wiki" action="wiki.php" method="get">
6
-            <input type="hidden" name="action" value="search" />
7
-            <input type="hidden" name="nojump" value="1" />
8
-            <input type="search" name="search" size="80" />
9
-            <input value="Search" type="submit" class="hidden" />
10
-        </form>
11
-        <br />
12
-        <p>Additionally, you can manually browse through the articles by their first letter.</p>
13
-        {% endif %}
14
-        <span>
15
-            {% for letter in 'a'..'z' %}
16
-            <a href="wiki.php?action=browse&amp;letter={{ letter }}">{{ letter|upper }}</a>&nbsp;&nbsp;
17
-            {% endfor %}
18
-            <a href="wiki.php?action=browse&amp;letter=1">All</a>&nbsp;&nbsp;
19
-        </span>
20
-    </div>
21
-{% endmacro %}
22
-
23
-<div class="thin">
24
-    <div class="header">
25
-        <h2>{{ title }}</h2>
26
-    </div>
27
-    <div class="linkbox">
28
-        <a href="wiki.php?action=create" class="brackets">Create</a>
29
-    </div>
30
-
31
-    {{ _self.letter_box() }}
32
-
33
-    <table width="100%" style="margin-bottom: 10px;">
34
-        <tr class="colhead">
35
-            <td>Article</td>
36
-            <td>Last updated on</td>
37
-            <td>Last edited by</td>
38
-        </tr>
39
-        {% for article in articles %}
40
-        <tr>
41
-            <td><a href="wiki.php?action=article&amp;id={{ article.ID }}">{{ article.Title }}</a></td>
42
-            <td>{{ article.Date }}</td>
43
-            <td>{{ article.Author|user_url }}</td>
44
-        </tr>
45
-        {% endfor %}
46
-    </table>
47
-
48
-    {{ _self.letter_box(false) }}
49
-</div>

Loading…
Cancel
Save