Browse Source

Add Skeleton CSS support, mostly

biotorrents 3 years ago
parent
commit
1530171f7b

+ 1
- 1
classes/config.template.php View File

382
 
382
 
383
 # Attempt to support the Seqhash algorithm
383
 # Attempt to support the Seqhash algorithm
384
 # https://blog.libredna.org/post/seqhash/
384
 # https://blog.libredna.org/post/seqhash/
385
-ENV::setPub('FEATURE_SEQHASH', true);
385
+ENV::setPub('FEATURE_BIOPHP', true);
386
 
386
 
387
 
387
 
388
 /**
388
 /**

+ 5
- 3
classes/env.class.php View File

137
      * toArray
137
      * toArray
138
      *
138
      *
139
      * Takes an object and returns an array.
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
140
      * @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
141
      */
143
      */
142
-    public function toArray(object $obj)
144
+    public function toArray($obj)
143
     {
145
     {
144
         if (is_object($obj)) {
146
         if (is_object($obj)) {
145
             $obj = (array) $obj;
147
             $obj = (array) $obj;
242
      * string(32) "52963afccc006d2bce3c890ad9e8f73a"
244
      * string(32) "52963afccc006d2bce3c890ad9e8f73a"
243
      *
245
      *
244
      * @param string $fn Callback function
246
      * @param string $fn Callback function
245
-     * @param object $obj Object to operate on
247
+     * @param object|string $obj Object or property to operate on
246
      * @return object $RAO Mapped RecursiveArrayObject
248
      * @return object $RAO Mapped RecursiveArrayObject
247
      */
249
      */
248
-    public function map(string $fn = '', object $obj = null)
250
+    public function map(string $fn = '', $obj = null)
249
     {
251
     {
250
         # Set a default function if desired
252
         # Set a default function if desired
251
         if (empty($fn) && !is_object($fn)) {
253
         if (empty($fn) && !is_object($fn)) {

+ 1
- 1
classes/security.class.php View File

65
         }
65
         }
66
 
66
 
67
         # blake3
67
         # blake3
68
-        if ($ENV->FEATURE_SEQHASH && !extension_loaded('blake3')) {
68
+        if ($ENV->FEATURE_BIOPHP && !extension_loaded('blake3')) {
69
             error('Please install and enable the php-blake3 extension.');
69
             error('Please install and enable the php-blake3 extension.');
70
         }
70
         }
71
 
71
 

+ 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
-}

+ 41
- 15
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
 
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']);
774
          */
774
          */
775
         function formatSelect($trID = '', $Label = '', $Torrent = [], $FileTypes = [])
775
         function formatSelect($trID = '', $Label = '', $Torrent = [], $FileTypes = [])
776
         {
776
         {
777
+            #var_dump($FileTypes);
777
             echo <<<HTML
778
             echo <<<HTML
778
             <tr id="$trID">
779
             <tr id="$trID">
779
               <td>
780
               <td>
781
                   $Label
782
                   $Label
782
                 <label>
783
                 <label>
783
               </td>
784
               </td>
784
-              
785
+
785
               <td>
786
               <td>
786
                 <select id="container" name="container">
787
                 <select id="container" name="container">
787
                   <option value="Autofill">Autofill</option>
788
                   <option value="Autofill">Autofill</option>
788
 HTML;
789
 HTML;
789
 
790
 
790
-            foreach ($FileTypes as $Type => $Extensions) {
791
-                echo "<option value='$Type'";
791
+            foreach ($FileTypes as $FileType) {
792
+                foreach ($FileType as $Type => $Extensions) {
793
+                    echo "<option value='$Type'";
792
 
794
 
793
-                if ($Type === ($Torrent['Container'] ?? false)) {
794
-                    echo ' selected';
795
-                }
795
+                    if ($Type === ($Torrent['Container'] ?? false)) {
796
+                        echo ' selected';
797
+                    }
796
 
798
 
797
-                echo ">$Type</option>\n";
799
+                    echo ">$Type</option>\n";
800
+                }
798
             }
801
             }
802
+        
799
 
803
 
800
             echo <<<HTML
804
             echo <<<HTML
801
                 </select>
805
                 </select>
832
             $Label = 'Format',
836
             $Label = 'Format',
833
             $Torrent = $Torrent,
837
             $Torrent = $Torrent,
834
             #$FileTypes = array_column($ENV->META, $Formats)
838
             #$FileTypes = array_column($ENV->META, $Formats)
839
+            $FileTypes = $ENV->CATS->{2}->Formats
835
         );
840
         );
836
 
841
 
837
 
842
 
842
             $trID = 'container_scalars_vectors_tr',
847
             $trID = 'container_scalars_vectors_tr',
843
             $Label = 'Format',
848
             $Label = 'Format',
844
             $Torrent = $Torrent,
849
             $Torrent = $Torrent,
845
-            $FileTypes = $ENV->flatten($ENV->CATS->{5}->Formats)
850
+            #$FileTypes = $ENV->flatten($ENV->CATS->{5}->Formats)
851
+            $FileTypes = $ENV->CATS->{5}->Formats
846
         );
852
         );
847
 
853
 
848
 
854
 
853
             $trID = 'container_images_tr',
859
             $trID = 'container_images_tr',
854
             $Label = 'Format',
860
             $Label = 'Format',
855
             $Torrent = $Torrent,
861
             $Torrent = $Torrent,
856
-            $FileTypes = array_merge($this->ImgFormats, $this->PlainFormats)
862
+            #$FileTypes = array_merge($this->ImgFormats)
863
+            $FileTypes = $ENV->CATS->{8}->Formats
857
         );
864
         );
858
 
865
 
859
 
866
 
864
             $trID = 'container_spatial_tr',
871
             $trID = 'container_spatial_tr',
865
             $Label = 'Format',
872
             $Label = 'Format',
866
             $Torrent = $Torrent,
873
             $Torrent = $Torrent,
867
-            $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
868
         );
876
         );
869
 
877
 
870
 
878
 
875
             $trID = 'container_documents_tr',
883
             $trID = 'container_documents_tr',
876
             $Label = 'Format',
884
             $Label = 'Format',
877
             $Torrent = $Torrent,
885
             $Torrent = $Torrent,
878
-            $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
879
         );
888
         );
880
 
889
 
881
 
890
 
886
             $trID = 'archive_tr',
895
             $trID = 'archive_tr',
887
             $Label = 'Archive',
896
             $Label = 'Archive',
888
             $Torrent = $Torrent,
897
             $Torrent = $Torrent,
889
-            $FileTypes = $this->Archives
898
+            # $ENV->Archives nests -1 deep
899
+            $FileTypes = [$ENV->META->Formats->Archives]
890
         );
900
         );
891
 
901
 
892
 
902
 
1081
         }
1091
         }
1082
 
1092
 
1083
 
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
+
1084
         /**
1110
         /**
1085
          * Torrent group description
1111
          * Torrent group description
1086
          *
1112
          *

+ 9
- 1
classes/util.php View File

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
- 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
         ],

+ 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";

+ 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>

+ 1
- 5
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">

+ 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
 

+ 18
- 18
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">
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) {

+ 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 }

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

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)

+ 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
- 58
static/styles/bookish/scss/colors.scss View File

24
  * Common elements
24
  * Common elements
25
  */
25
  */
26
 
26
 
27
-.head {
28
-    background: #b3e5fc;
29
-    color: black;
30
-    padding: 0.5em 1rem;
31
-}
32
-
33
 /* Alternating tables */
27
 /* Alternating tables */
34
 #request_table .request:nth-of-type(even) {
28
 #request_table .request:nth-of-type(even) {
35
     background: white;
29
     background: white;
51
 /**
45
 /**
52
  * Fancy torrent search input
46
  * Fancy torrent search input
53
  */
47
  */
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
 
48
 
86
 checkbox,
49
 checkbox,
87
 input[type="checkbox"] {
50
 input[type="checkbox"] {
93
     border: none;
56
     border: none;
94
 }
57
 }
95
 
58
 
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
 /**
59
 /**
118
  * Alerts, Toolbox, etc.
60
  * Alerts, Toolbox, etc.
119
  * Needs one unified error display
61
  * Needs one unified error display

+ 8
- 0
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;

+ 2
- 47
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;
85
 }
64
 }
86
 
65
 
87
 .main_column {
66
 .main_column {
88
-    @include column-flex(65%);
67
+    @include column-flex(64%);
89
 
68
 
90
     table {
69
     table {
91
         margin-bottom: 1rem;
70
         margin-bottom: 1rem;
93
 }
72
 }
94
 
73
 
95
 .sidebar {
74
 .sidebar {
96
-    @include column-flex(35%);
75
+    @include column-flex(34%);
97
     float: right;
76
     float: right;
98
 }
77
 }
99
 
78
 
103
     padding: 0.5rem;
82
     padding: 0.5rem;
104
 }
83
 }
105
 
84
 
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 */
85
 /* Misc */
118
 .torrents_nomatch {
86
 .torrents_nomatch {
119
     margin-top: 1rem;
87
     margin-top: 1rem;
171
     border: none;
139
     border: none;
172
 }
140
 }
173
 
141
 
174
-.torrent_table tr {
175
-    /* vertical-align: top; */
176
-    vertical-align: middle;
177
-}
178
-
179
 .torrent_table .number_column {
142
 .torrent_table .number_column {
180
     text-align: center;
143
     text-align: center;
181
 }
144
 }
186
 }
149
 }
187
 
150
 
188
 /* Text elements */
151
 /* Text elements */
189
-h1,
190
-h2,
191
-h3,
192
-h4 {
193
-    margin: 0.5em 0;
194
-    font-weight: bold;
195
-}
196
-
197
 p {
152
 p {
198
     margin: 1em 0.5rem;
153
     margin: 1em 0.5rem;
199
 }
154
 }

+ 33
- 27
static/styles/bookish/scss/tables.scss View File

2
 }
2
 }
3
 
3
 
4
 table {
4
 table {
5
-    /* border: 2px solid rgba(0, 0, 0, 0.01); */
6
-    border-collapse: collapse;
7
     width: 100%;
5
     width: 100%;
8
 
6
 
9
-    /*
10
-    * {
11
-        vertical-align: middle;
7
+    th {
8
+        font-size: 120%;
12
     }
9
     }
13
-    */
14
 
10
 
11
+    /*
15
     tr {
12
     tr {
16
         background-color: white;
13
         background-color: white;
17
     }
14
     }
18
-
19
-    td,
20
-    th {
21
-        padding: 0.5rem;
22
-        text-align: left;
23
-    }
15
+    */
24
 }
16
 }
25
 
17
 
26
 /**
18
 /**
39
     }
31
     }
40
 }
32
 }
41
 
33
 
42
-/* Classes */
34
+/**
35
+ * colhead
36
+ * The main table heading.
37
+ */
43
 .colhead {
38
 .colhead {
44
-    background: $lb100;
39
+    padding: 0.5em 0;
40
+    border-bottom: 1px solid #e1e1e1;
41
+    font-size: 120%;
45
     font-weight: bold;
42
     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
 }
43
 }
55
 
44
 
56
 .colhead .sign,
45
 .colhead .sign,
66
     font-weight: bold;
55
     font-weight: bold;
67
 }
56
 }
68
 
57
 
69
-.colhead_dark {
70
-    background: $lb100;
71
-    color: black;
58
+/* Torrent and collage tables */
59
+.torrent_table,
60
+.collage_table {
61
+    tr:nth-child(2n) {
62
+        background-color: whitesmoke;
63
+    }
64
+
65
+    tr:nth-child(2n-1) {
66
+        background-color: white;
67
+    }
68
+
69
+    div.tags {
70
+        font-weight: normal;
71
+        max-width: 500px;
72
+    }
73
+
74
+    span {
75
+        float: right;
76
+    }
72
 }
77
 }
73
 
78
 
74
-/* Torrent and collage tables */
79
+/*
75
 .torrent_table,
80
 .torrent_table,
76
 .collage_table {
81
 .collage_table {
77
     tr.group {
82
     tr.group {
108
     tr .center,
113
     tr .center,
109
     td {
114
     td {
110
         vertical-align: middle;
115
         vertical-align: middle;
111
-        /* text-align: center; */
116
+        /* text-align: center; * /
112
     }
117
     }
113
     div.tags {
118
     div.tags {
114
         font-weight: normal;
119
         font-weight: normal;
115
         max-width: 500px;
120
         max-width: 500px;
116
     }
121
     }
117
 }
122
 }
123
+*/
118
 
124
 
119
 .torrent_table .group_torrent .torrent span {
125
 .torrent_table .group_torrent .torrent span {
120
     font-weight: normal;
126
     font-weight: normal;

+ 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
 /*

+ 9
- 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
  */

+ 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
+*/

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

1
+/**
2
+ * Fixes needed to use skeleton.css
3
+ * to its best 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
+table.forum_index {
70
+    h4 {
71
+        margin: 0 !important;
72
+    }
73
+}
74
+
75
+label,
76
+legend {
77
+    display: inline !important;
78
+}
79
+
80
+table.torrent_search,
81
+table.torrent_requests {
82
+    th,
83
+    td {
84
+        border-bottom: 0 !important;
85
+        padding: 0.25rem !important;
86
+    }
87
+}
88
+
89
+input,
90
+input[type="search"],
91
+input[type="text"] {
92
+    margin: 0 !important;
93
+}
94
+
95
+ul {
96
+    list-style: circle !important;
97
+}
98
+
99
+pre,
100
+blockquote,
101
+dl,
102
+figure,
103
+table,
104
+p,
105
+ul,
106
+ol,
107
+form {
108
+    margin-bottom: 0 !important;
109
+}
110
+
111
+code {
112
+    padding: 0 !important;
113
+}

+ 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>

Loading…
Cancel
Save