pjc 5 years ago
parent
commit
764f0bb113
2 changed files with 166 additions and 1 deletions
  1. 164
    0
      _packages/web-seeds/create.php
  2. 2
    1
      design/publicheader.php

+ 164
- 0
_packages/web-seeds/create.php View File

1
+<?php
2
+
3
+function safe_b64encode($string) {
4
+  $data = base64_encode($string);
5
+  $data = str_replace(array('+','/','='),array('-','_',''),$data);
6
+  return $data;
7
+}
8
+
9
+class Torrent {
10
+  public $metadata;
11
+  public $name;
12
+  public $id;
13
+  
14
+  function __construct ($url_or_file) {
15
+    $this->name = urldecode(end(explode('/', $url_or_file)));
16
+    $this->id = safe_b64encode($url_or_file);
17
+
18
+    $filesize = (int) array_change_key_case(
19
+      get_headers($url_or_file, TRUE))['content-length'];
20
+    $piece_size = $this->get_piece_size($filesize);
21
+    $log = getcwd() . "/log/" . $this->id;
22
+
23
+    # now create the actual torrent
24
+    $this->metadata = array(
25
+        'announce' => 'http://academictorrents.com/announce.php',
26
+        'encoding' => 'UTF-8',
27
+        'info' => array(
28
+            'length'       => $filesize,
29
+            'name'         => $this->name,
30
+            'pieces'       => $this->make_pieces($url_or_file, $piece_size,
31
+                                                 $filesize, $log),
32
+            'piece length' => $piece_size,
33
+        ),
34
+        'url-list' => array($url_or_file),
35
+    );
36
+    $this->save();
37
+  }
38
+
39
+  static function bencode($var) {
40
+    if (is_int($var)) {
41
+      return 'i' . $var . 'e';
42
+    } else if (is_string($var)) {
43
+      return strlen($var) . ':' . $var;
44
+    } else if (is_array($var)) {
45
+      # must distinguish between dict and list
46
+      for ($i = 0; $i < count($var); $i++) {
47
+        # if dict, cannot index using ints?
48
+        if (!isset($var[$i])) {
49
+          $dictionary = $var;
50
+          ksort($dictionary);
51
+          $ret = 'd';
52
+          foreach ($dictionary as $key => $value) {
53
+            $ret .= Torrent::bencode($key) . Torrent::bencode($value);
54
+          }
55
+          return $ret . 'e';
56
+        }
57
+      }
58
+      $ret = 'l';
59
+      foreach ($var as $value) {
60
+        $ret .= Torrent::bencode($value);
61
+      }
62
+      return $ret . 'e';
63
+    }
64
+  }
65
+
66
+  private function get_piece_size($filesize) {
67
+    $piece_length = 524288;
68
+    while (ceil($filesize / $piece_length) == 1) {
69
+        $piece_length /= 2;
70
+    }
71
+    while (ceil($filesize / $piece_length) > 1500) {
72
+        $piece_length *= 2;
73
+    }
74
+    return $piece_length;
75
+  }
76
+
77
+  private function make_pieces($url, $piece_length, $filesize, $logfile) {
78
+    if (($fp = fopen($url, 'r')) == FALSE) {
79
+        return FALSE;
80
+    }
81
+    $pieces = '';
82
+    $part = '';
83
+
84
+    $position = 0;
85
+    $i = 0;
86
+    while ($position < $filesize) {
87
+      $bytes_read = 0;
88
+      # fread doesn't actually read in the correct number of bytes
89
+      # piece together multiple freads
90
+      while ($bytes_read < $piece_length && $position < $filesize) {
91
+        $this_part = fread($fp, min($piece_length, $filesize - $position));
92
+        $bytes_read += strlen($this_part);
93
+        $position += strlen($this_part);
94
+        $part .= $this_part;
95
+      }
96
+      $next_part = substr($part, $piece_length);
97
+      $part = substr($part, 0, $piece_length);
98
+      $piece = sha1($part, $raw_output=TRUE);
99
+      $pieces .= $piece;
100
+
101
+      $part = $next_part;
102
+
103
+      if ($position > $filesize) {
104
+        $position = $filesize;
105
+      }
106
+      # log progress every 5 pieces
107
+      if ($i++ % 5 == 0 || $position == $filesize) {
108
+        $log = fopen($logfile, "w");
109
+        fwrite($log, $position . '/' . $filesize);
110
+        fflush($f);
111
+        fclose($log);
112
+      }
113
+    }
114
+    fflush($f);
115
+    fclose($fp);
116
+    return $pieces;
117
+  }
118
+
119
+  private function save() {
120
+    $dir = getcwd() . "/torrents/" . $this->id; 
121
+    mkdir($dir);
122
+    $f = fopen($dir . "/" . $this->name . ".torrent", "w");
123
+    fwrite($f, Torrent::bencode($this->metadata));
124
+    fflush($f);
125
+    fclose($f);
126
+  }
127
+}
128
+
129
+/*
130
+ create:
131
+ 1. Input: GET variables url-encoded string "url".
132
+ 2. Creates log for "id" in ./log/ for the download.
133
+ 3. Streamingly creates torrent, updating log.
134
+ 4. Dumps finished torrent file in ./torrents/
135
+*/
136
+
137
+# Main
138
+if (isset($_GET["url"]) && filter_var($_GET["url"], FILTER_VALIDATE_URL)) {
139
+  $logname = getcwd() . "/log/" . safe_b64encode($_GET["url"]);
140
+
141
+  # if log exists, don't start new torrent
142
+  if (file_exists($logname)) {
143
+    # check status; return "done", or "processing"
144
+    $contents = explode("/", stream_get_contents(fopen($logname, "r")));
145
+    $progress = intval($contents[0]);
146
+    $total = intval($contents[1]);
147
+    if ($progress==$total) {
148
+      echo(json_encode(array(
149
+        'status' => 'OK',
150
+        'msg' => "Torrent complete!")));
151
+    } else {
152
+      echo(json_encode(array(
153
+        'status' => 'OK',
154
+        'msg' => "Torrent already processing!")));
155
+    }    
156
+  } else {
157
+    $torrent = new Torrent($_GET["url"]);
158
+  }
159
+} else {
160
+  echo(json_encode(array(
161
+    'status' => 'ERROR',
162
+    'msg' => "Requires GET variable 'url'")));
163
+};
164
+?>

+ 2
- 1
design/publicheader.php View File

33
 <?php if (OPEN_REGISTRATION) { ?>
33
 <?php if (OPEN_REGISTRATION) { ?>
34
  | <a href="register.php">Register</a>
34
  | <a href="register.php">Register</a>
35
 <?php } ?>
35
 <?php } ?>
36
+| <a href="mailto:help@biotorrents.de?subject=[TxID <?= strtoupper(bin2hex(random_bytes(2))) ?>] Vague subject lines ignored">Support</a>
36
 </span></div>
37
 </span></div>
37
 <div id="content">
38
 <div id="content">
38
 
39
 
39
     <!-- todo: Put index page stats here -->
40
     <!-- todo: Put index page stats here -->
40
-    <?php #include('/sections/login/stats.php'); ?>
41
+    <?php #include('/sections/login/stats.php');?>
41
 
42
 
42
   <table class="layout" id="maincontent">
43
   <table class="layout" id="maincontent">
43
     <tr>
44
     <tr>

Loading…
Cancel
Save