mirror of
https://github.com/WhatCD/Gazelle.git
synced 2024-12-13 19:06:27 +00:00
Empty commit
This commit is contained in:
parent
7d7c7fcd7e
commit
57b88f03c1
409
classes/class_bencode.php
Normal file
409
classes/class_bencode.php
Normal file
@ -0,0 +1,409 @@
|
||||
<?
|
||||
/**
|
||||
* If we're running a 32bit PHP version, we use small objects to store ints.
|
||||
* Overhead from the function calls is small enough to not worry about
|
||||
*/
|
||||
class Int64 {
|
||||
private $Num;
|
||||
|
||||
public function __construct($Val) {
|
||||
$this->Num = $Val;
|
||||
}
|
||||
|
||||
public static function make($Val) {
|
||||
return PHP_INT_SIZE === 4 ? new Int64($Val) : (int)$Val;
|
||||
}
|
||||
|
||||
public static function get($Val) {
|
||||
return PHP_INT_SIZE === 4 ? $Val->Num : $Val;
|
||||
}
|
||||
|
||||
public static function is_int($Val) {
|
||||
return is_int($Val) || (is_object($Val) && get_class($Val) === 'Int64');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The encode class is simple and straightforward. The only thing to
|
||||
* note is that empty dictionaries are represented by boolean trues
|
||||
*/
|
||||
class BEnc {
|
||||
private $DefaultKeys = array( // Get rid of everything except these keys to save some space
|
||||
'created by', 'creation date', 'encoding', 'info');
|
||||
private $Data;
|
||||
public $Enc;
|
||||
|
||||
/**
|
||||
* Encode an arbitrary array (usually one that's just been decoded)
|
||||
*
|
||||
* @param array $Arg the thing to encode
|
||||
* @param mixed $Keys string or array with keys in the input array to encode or true to encode everything
|
||||
* @return bencoded string representing the content of the input array
|
||||
*/
|
||||
public function encode($Arg = false, $Keys = false) {
|
||||
if ($Arg === false) {
|
||||
$Data =& $this->Dec;
|
||||
} else {
|
||||
$Data =& $Arg;
|
||||
}
|
||||
if ($Keys === true) {
|
||||
$this->Data = $Data;
|
||||
} else if ($Keys === false) {
|
||||
$this->Data = array_intersect_key($Data, array_flip($this->DefaultKeys));
|
||||
} else if (is_array($Keys)) {
|
||||
$this->Data = array_intersect_key($Data, array_flip($Keys));
|
||||
} else {
|
||||
$this->Data = isset($Data[$Keys]) ? $Data[$Keys] : false;
|
||||
}
|
||||
if (!$this->Data) {
|
||||
return false;
|
||||
}
|
||||
$this->Enc = $this->_benc();
|
||||
return $this->Enc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal encoding function that does the actual job
|
||||
*
|
||||
* @return bencoded string
|
||||
*/
|
||||
private function _benc() {
|
||||
if (!is_array($this->Data)) {
|
||||
if (Int64::is_int($this->Data)) { // Integer
|
||||
return 'i'.Int64::get($this->Data).'e';
|
||||
}
|
||||
if ($this->Data === true) { // Empty dictionary
|
||||
return 'de';
|
||||
}
|
||||
return strlen($this->Data).':'.$this->Data; // String
|
||||
}
|
||||
if (empty($this->Data) || Int64::is_int(key($this->Data))) {
|
||||
$IsDict = false;
|
||||
} else {
|
||||
$IsDict = true;
|
||||
ksort($this->Data); // Dictionaries must be sorted
|
||||
}
|
||||
$Ret = $IsDict ? 'd' : 'l';
|
||||
foreach ($this->Data as $Key => $Value) {
|
||||
if ($IsDict) {
|
||||
$Ret .= strlen($Key).':'.$Key;
|
||||
}
|
||||
$this->Data = $Value;
|
||||
$Ret .= $this->_benc();
|
||||
}
|
||||
return $Ret.'e';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The decode class is simple and straightforward. The only thing to
|
||||
* note is that empty dictionaries are represented by boolean trues
|
||||
*/
|
||||
class BEncDec extends BEnc {
|
||||
private $Data;
|
||||
private $Length;
|
||||
private $Pos = 0;
|
||||
public $Dec = array();
|
||||
public $ExitOnError = true;
|
||||
const SnipLength = 40;
|
||||
|
||||
/**
|
||||
* Decode prepararations
|
||||
*
|
||||
* @param string $Arg bencoded string or path to bencoded file to decode
|
||||
* @param bool $IsPath needs to be true if $Arg is a path
|
||||
* @return decoded data with a suitable structure
|
||||
*/
|
||||
function __construct($Arg = false, $IsPath = false) {
|
||||
if ($Arg === false) {
|
||||
if (empty($this->Enc)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if ($IsPath === true) {
|
||||
return $this->bdec_file($Arg);
|
||||
}
|
||||
$this->Data = $Arg;
|
||||
}
|
||||
return $this->decode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes a bencoded file
|
||||
*
|
||||
* @param $Path path to bencoded file to decode
|
||||
* @return decoded data with a suitable structure
|
||||
*/
|
||||
public function bdec_file($Path = false) {
|
||||
if (empty($Path)) {
|
||||
return false;
|
||||
}
|
||||
if (!$this->Data = @file_get_contents($Path, FILE_BINARY)) {
|
||||
return $this->error("Error: file '$Path' could not be opened.\n");
|
||||
}
|
||||
return $this->decode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes a string with bencoded data
|
||||
*
|
||||
* @param mixed $Arg bencoded data or false to decode the content of $this->Data
|
||||
* @return decoded data with a suitable structure
|
||||
*/
|
||||
public function decode($Arg = false) {
|
||||
if ($Arg !== false) {
|
||||
$this->Data = $Arg;
|
||||
} else if (!$this->Data) {
|
||||
$this->Data = $this->Enc;
|
||||
}
|
||||
if (!$this->Data) {
|
||||
return false;
|
||||
}
|
||||
$this->Length = strlen($this->Data);
|
||||
$this->Pos = 0;
|
||||
$this->Dec = $this->_bdec();
|
||||
if ($this->Pos < $this->Length) {
|
||||
// Not really necessary, but if the torrent is invalid, it's better to warn than to silently truncate it
|
||||
return $this->error();
|
||||
}
|
||||
return $this->Dec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal decoding function that does the actual job
|
||||
*
|
||||
* @return decoded data with a suitable structure
|
||||
*/
|
||||
private function _bdec() {
|
||||
switch ($this->Data[$this->Pos]) {
|
||||
|
||||
case 'i':
|
||||
$this->Pos++;
|
||||
$Value = substr($this->Data, $this->Pos, strpos($this->Data, 'e', $this->Pos) - $this->Pos);
|
||||
if (!ctype_digit($Value) && !($Value[0] == '-' && ctype_digit(substr($Value, 1)))) {
|
||||
return $this->error();
|
||||
}
|
||||
$this->Pos += strlen($Value) + 1;
|
||||
return Int64::make($Value);
|
||||
|
||||
case 'l':
|
||||
$Value = array();
|
||||
$this->Pos++;
|
||||
while ($this->Data[$this->Pos] != 'e') {
|
||||
if ($this->Pos >= $this->Length) {
|
||||
return $this->error();
|
||||
}
|
||||
$Value[] = $this->_bdec();
|
||||
}
|
||||
$this->Pos++;
|
||||
return $Value;
|
||||
|
||||
case 'd':
|
||||
$Value = array();
|
||||
$this->Pos++;
|
||||
while ($this->Data[$this->Pos] != 'e') {
|
||||
$Length = substr($this->Data, $this->Pos, strpos($this->Data, ':', $this->Pos) - $this->Pos);
|
||||
if (!ctype_digit($Length)) {
|
||||
return $this->error();
|
||||
}
|
||||
$this->Pos += strlen($Length) + $Length + 1;
|
||||
$Key = substr($this->Data, $this->Pos - $Length, $Length);
|
||||
if ($this->Pos >= $this->Length) {
|
||||
return $this->error();
|
||||
}
|
||||
$Value[$Key] = $this->_bdec();
|
||||
}
|
||||
$this->Pos++;
|
||||
// Use boolean true to keep track of empty dictionaries
|
||||
return empty($Value) ? true : $Value;
|
||||
|
||||
default:
|
||||
$Length = substr($this->Data, $this->Pos, strpos($this->Data, ':', $this->Pos) - $this->Pos);
|
||||
if (!ctype_digit($Length)) {
|
||||
return $this->error(); // Even if the string is likely to be decoded correctly without this check, it's malformed
|
||||
}
|
||||
$this->Pos += strlen($Length) + $Length + 1;
|
||||
return substr($this->Data, $this->Pos - $Length, $Length);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert everything to the correct data types and optionally escape strings
|
||||
*
|
||||
* @param bool $Escape whether to escape the textual data
|
||||
* @param mixed $Data decoded data or false to use the $Dec property
|
||||
* @return decoded data with more useful data types
|
||||
*/
|
||||
public function dump($Escape = true, $Data = false) {
|
||||
if ($Data === false) {
|
||||
$Data = $this->Dec;
|
||||
}
|
||||
if (Int64::is_int($Data)) {
|
||||
return Int64::get($Data);
|
||||
}
|
||||
if (is_bool($Data)) {
|
||||
return array();
|
||||
}
|
||||
if (is_array($Data)) {
|
||||
$Output = array();
|
||||
foreach ($Data as $Key => $Val) {
|
||||
$Output[$Key] = $this->dump($Escape, $Val);
|
||||
}
|
||||
return $Output;
|
||||
}
|
||||
return $Escape ? htmlentities($Data) : $Data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display an error and halt the operation unless the $ExitOnError property is false
|
||||
*
|
||||
* @param string $ErrMsg the error message to display
|
||||
*/
|
||||
private function error($ErrMsg = false) {
|
||||
static $ErrorPos;
|
||||
if ($this->Pos === $ErrorPos) {
|
||||
// The recursive nature of the class requires this to avoid duplicate error messages
|
||||
return false;
|
||||
}
|
||||
if ($ErrMsg === false) {
|
||||
printf("Malformed string. Invalid character at pos 0x%X: %s\n",
|
||||
$this->Pos, str_replace(array("\r","\n"), array('',' '), htmlentities(substr($this->Data, $this->Pos, self::SnipLength))));
|
||||
} else {
|
||||
echo $ErrMsg;
|
||||
}
|
||||
if ($this->ExitOnError) {
|
||||
exit();
|
||||
}
|
||||
$ErrorPos = $this->Pos;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Torrent class that contains some convenient functions related to torrent meta data
|
||||
*/
|
||||
class BEncTorrent extends BEncDec {
|
||||
private $PathKey = 'path';
|
||||
public $Files = array();
|
||||
public $Size = 0;
|
||||
|
||||
/**
|
||||
* Create a list of the files in the torrent and their sizes as well as the total torrent size
|
||||
*
|
||||
* @return array with a list of files and file sizes
|
||||
*/
|
||||
public function file_list() {
|
||||
if (empty($this->Dec)) {
|
||||
return false;
|
||||
}
|
||||
$InfoDict =& $this->Dec['info'];
|
||||
if (!isset($InfoDict['files'])) {
|
||||
// Single-file torrent
|
||||
$this->Files = array(
|
||||
$this->Size = (Int64::is_int($InfoDict['length'])
|
||||
? Int64::get($InfoDict['length'])
|
||||
: $InfoDict['length']),
|
||||
$this->Files = (isset($InfoDict['name.utf-8'])
|
||||
? $InfoDict['name.utf-8']
|
||||
: $InfoDict['name'])
|
||||
);
|
||||
} else {
|
||||
if (isset($InfoDict['path.utf-8']['files'][0])) {
|
||||
$this->PathKey = 'path.utf-8';
|
||||
}
|
||||
foreach ($InfoDict['files'] as $File) {
|
||||
$TmpPath = array();
|
||||
foreach ($File[$this->PathKey] as $SubPath) {
|
||||
$TmpPath[] = $SubPath;
|
||||
}
|
||||
$CurSize = (Int64::is_int($File['length'])
|
||||
? Int64::get($File['length'])
|
||||
: $File['length']);
|
||||
$this->Files[] = array($CurSize, implode('/', $TmpPath));
|
||||
$this->Size += $CurSize;
|
||||
}
|
||||
}
|
||||
uasort($this->Files, function($a, $b) {
|
||||
return strnatcasecmp($a[1], $b[1]);
|
||||
});
|
||||
return array($this->Size, $this->Files);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find out the name of the torrent
|
||||
*
|
||||
* @return string torrent name
|
||||
*/
|
||||
public function get_name() {
|
||||
if (empty($this->Dec)) {
|
||||
return false;
|
||||
}
|
||||
if (isset($this->Dec['info']['name.utf-8'])) {
|
||||
return $this->Dec['info']['name.utf-8'];
|
||||
}
|
||||
return $this->Dec['info']['name'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Find out the total size of the torrent
|
||||
*
|
||||
* @return string torrent size
|
||||
*/
|
||||
public function get_size() {
|
||||
if (empty($this->Files)) {
|
||||
if (empty($this->Dec)) {
|
||||
return false;
|
||||
}
|
||||
$FileList = $this->file_list();
|
||||
}
|
||||
return $FileList[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the "private" flag is present in the torrent
|
||||
*
|
||||
* @return true if the "private" flag is set
|
||||
*/
|
||||
public function is_private() {
|
||||
if (empty($this->Dec)) {
|
||||
return false;
|
||||
}
|
||||
return isset($this->Dec['info']['private']) && Int64::get($this->Dec['info']['private']) == 1;
|
||||
}
|
||||
/**
|
||||
* Add the "private" flag to the torrent
|
||||
*
|
||||
* @return true if a change was required
|
||||
*/
|
||||
public function make_private() {
|
||||
if (empty($this->Dec)) {
|
||||
return false;
|
||||
}
|
||||
if ($this->is_private()) {
|
||||
return false;
|
||||
}
|
||||
$this->Dec['info']['private'] = Int64::make(1);
|
||||
ksort($this->Dec['info']);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the torrent's info hash
|
||||
*
|
||||
* @return info hash in hexadecimal form
|
||||
*/
|
||||
public function info_hash() {
|
||||
if (empty($this->Dec) || !isset($this->Dec['info'])) {
|
||||
return false;
|
||||
}
|
||||
return sha1($this->encode(false, 'info'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the announce URL to a torrent
|
||||
*/
|
||||
public static function add_announce_url($Data, $Url) {
|
||||
return 'd8:announce'.strlen($Url).':'.$Url . substr($Data, 1);
|
||||
}
|
||||
}
|
||||
?>
|
@ -400,5 +400,16 @@ public static function display_array($Array, $Escape = array()) {
|
||||
}
|
||||
return $Array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for a : in the beginning of a torrent meta data string
|
||||
* to see if it's stored in the old base64-encoded format
|
||||
*
|
||||
* @param string $Torrent the torrent data
|
||||
* @return true if the torrent is stored in binary format
|
||||
*/
|
||||
public static function is_new_torrent(&$Data) {
|
||||
return strpos(substr($Data, 0, 10), ':') !== false;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
@ -315,6 +315,19 @@ function to_array($Key = false, $Type = MYSQLI_BOTH, $Escape = true) {
|
||||
return $Return;
|
||||
}
|
||||
|
||||
// Loops through the result set, collecting the $ValField column into an array with $KeyField as keys
|
||||
function to_pair($KeyField, $ValField, $Escape = true) {
|
||||
$Return = array();
|
||||
while ($Row = mysqli_fetch_array($this->QueryID)) {
|
||||
if ($Escape !== false) {
|
||||
$Row = Misc::display_array($Row[$ValField], $Escape);
|
||||
}
|
||||
$Return[$Row[$KeyField]] = $Row[$ValField];
|
||||
}
|
||||
mysqli_data_seek($this->QueryID, 0);
|
||||
return $Return;
|
||||
}
|
||||
|
||||
// Loops through the result set, collecting the $Key column into an array
|
||||
function collect($Key, $Escape = true) {
|
||||
$Return = array();
|
||||
@ -336,7 +349,7 @@ function get_query_id() {
|
||||
|
||||
function beginning() {
|
||||
mysqli_data_seek($this->QueryID, 0);
|
||||
$this->Row = 0;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
|
211
classes/class_torrentsdl.php
Normal file
211
classes/class_torrentsdl.php
Normal file
@ -0,0 +1,211 @@
|
||||
<?
|
||||
/**
|
||||
* Class for functions related to the features involving torrent downloads
|
||||
*/
|
||||
class TorrentsDL {
|
||||
const ChunkSize = 100;
|
||||
private $QueryResult;
|
||||
private $QueryRowNum = 0;
|
||||
private $Zip;
|
||||
private $IDBoundaries;
|
||||
private $FailedFiles = array();
|
||||
private $NumAdded = 0;
|
||||
private $NumFound = 0;
|
||||
private $Size = 0;
|
||||
private $Title;
|
||||
|
||||
/**
|
||||
* Create a Zip object and store the query results
|
||||
*
|
||||
* @param mysqli_result $QueryResult results from a query on the collector pages
|
||||
* @param string $Title name of the collection that will be created
|
||||
*/
|
||||
public function __construct(&$QueryResult, $Title) {
|
||||
Zip::unlimit(); // Need more memory and longer timeout
|
||||
$this->QueryResult = $QueryResult;
|
||||
$this->Title = $Title;
|
||||
$this->Zip = new Zip(Misc::file_string($Title));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the results from a DB query in smaller chunks to save memory
|
||||
*
|
||||
* @param string $Key the key to use in the result hash map
|
||||
* @return array with results and torrent group IDs or false if there are no results left
|
||||
*/
|
||||
public function get_downloads($Key) {
|
||||
global $DB;
|
||||
$GroupIDs = $Downloads = array();
|
||||
$OldQuery = $DB->get_query_id();
|
||||
$DB->set_query_id($this->QueryResult);
|
||||
if (!isset($this->IDBoundaries)) {
|
||||
if ($Key == 'TorrentID') {
|
||||
$this->IDBoundaries = false;
|
||||
} else {
|
||||
$this->IDBoundaries = $DB->to_pair($Key, 'TorrentID', false);
|
||||
}
|
||||
}
|
||||
$Found = 0;
|
||||
while ($Download = $DB->next_record(MYSQLI_ASSOC, false)) {
|
||||
if (!$this->IDBoundaries || $Download['TorrentID'] == $this->IDBoundaries[$Download[$Key]]) {
|
||||
$Found++;
|
||||
$Downloads[$Download[$Key]] = $Download;
|
||||
$GroupIDs[$Download['TorrentID']] = $Download['GroupID'];
|
||||
if ($Found >= self::ChunkSize) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->NumFound += $Found;
|
||||
$DB->set_query_id($OldQuery);
|
||||
if (empty($Downloads)) {
|
||||
return false;
|
||||
}
|
||||
return array($Downloads, $GroupIDs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a file to the zip archive
|
||||
*
|
||||
* @param string $Content file content
|
||||
* @param array $FileInfo file info stored as an array with at least the keys
|
||||
* Artist, Name, Year, Media, Format, Encoding and TorrentID
|
||||
* @param string $FolderName folder name
|
||||
*/
|
||||
public function add_file($Content, $FileInfo, $FolderName = '') {
|
||||
$FileName = self::construct_file_name($FileInfo['Artist'], $FileInfo['Name'], $FileInfo['Year'], $FileInfo['Media'], $FileInfo['Format'], $FileInfo['Encoding'], $FileInfo['TorrentID']);
|
||||
$this->Size += $FileInfo['Size'];
|
||||
$this->NumAdded++;
|
||||
$this->Zip->add_file($Content, ($FolderName ? "$FolderName/" : "") . $FileName);
|
||||
usleep(25000); // We don't want to send much faster than the client can receive
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a file to the list of files that could not be downloaded
|
||||
*
|
||||
* @param array $FileInfo file info stored as an array with at least the keys Artist, Name and Year
|
||||
*/
|
||||
public function fail_file($FileInfo) {
|
||||
$this->FailedFiles[] = $FileInfo['Artist'] . $FileInfo['Name'] . " $FileInfo[Year]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a file to the list of files that did not match the user's format or quality requirements
|
||||
*
|
||||
* @param array $FileInfo file info stored as an array with at least the keys Artist, Name and Year
|
||||
*/
|
||||
public function skip_file($FileInfo) {
|
||||
$this->SkippedFiles[] = $FileInfo['Artist'] . $FileInfo['Name'] . " $FileInfo[Year]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a summary to the archive and include a list of files that could not be added. Close the zip archive
|
||||
*
|
||||
* @param int $Analyzed number of files that were analyzed (e.g. number of groups in a collage)
|
||||
* @param int $Skips number of files that did not match any of the user's criteria
|
||||
*/
|
||||
public function finalize($FilterStats = true) {
|
||||
$this->Zip->add_file($this->summary($FilterStats), "Summary.txt");
|
||||
if (!empty($this->FailedFiles)) {
|
||||
$this->Zip->add_file($this->errors(), "Errors.txt");
|
||||
}
|
||||
$this->Zip->close_stream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Produce a summary text over the collector results
|
||||
*
|
||||
* @param bool $FilterStats whether to include filter stats in the report
|
||||
* @return summary text
|
||||
*/
|
||||
public function summary($FilterStats) {
|
||||
global $LoggedUser, $ScriptStartTime;
|
||||
$Time = number_format(1000 * (microtime(true) - $ScriptStartTime), 2)." ms";
|
||||
$Used = Format::get_size(memory_get_usage(true));
|
||||
$Date = date("M d Y, H:i");
|
||||
$NumSkipped = count($this->SkippedFiles);
|
||||
return "Collector Download Summary for $this->Title - ".SITE_NAME."\r\n"
|
||||
. "\r\n"
|
||||
. "User: $LoggedUser[Username]\r\n"
|
||||
. "Passkey: $LoggedUser[torrent_pass]\r\n"
|
||||
. "\r\n"
|
||||
. "Time: $Time\r\n"
|
||||
. "Used: $Used\r\n"
|
||||
. "Date: $Date\r\n"
|
||||
. "\r\n"
|
||||
. ($FilterStats !== false
|
||||
? "Torrent groups analyzed: $this->NumFound\r\n"
|
||||
. "Torrent groups filtered: $NumSkipped\r\n"
|
||||
: "")
|
||||
. "Torrents downloaded: $this->NumAdded\r\n"
|
||||
. "\r\n"
|
||||
. "Total size of torrents (ratio hit): ".Format::get_size($this->Size)."\r\n"
|
||||
. ($NumSkipped
|
||||
? "\r\n"
|
||||
. "Albums unavailable within your criteria (consider making a request for your desired format):\r\n"
|
||||
. implode("\r\n", $this->SkippedFiles) . "\r\n"
|
||||
: "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a list of files that could not be added to the archive
|
||||
*
|
||||
* @return list of files
|
||||
*/
|
||||
public function errors() {
|
||||
return "A server error occurred. Please try again at a later time.\r\n"
|
||||
. "\r\n"
|
||||
. "The following torrents could not be downloaded:\r\n"
|
||||
. implode("\r\n", $this->FailedFiles) . "\r\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine a bunch of torrent info into a standardized file name
|
||||
*
|
||||
* @params most input variables are mostly self-explanatory
|
||||
* @param int $TorrentID if given, append "-TorrentID" to torrent name
|
||||
* @param bool $TxtExtension whether to use .txt or .torrent as file extension
|
||||
* @return file name with at most 180 characters that is valid on most systems
|
||||
*/
|
||||
public static function construct_file_name($Artist, $Album, $Year, $Media, $Format, $Encoding, $TorrentID = false, $TxtExtension = false) {
|
||||
$TorrentName = Misc::file_string($Album);
|
||||
if ($Year > 0) {
|
||||
$TorrentName .= " - $Year";
|
||||
}
|
||||
$TorrentInfo = array();
|
||||
if ($Media != '') {
|
||||
$TorrentInfo[] = $Media;
|
||||
}
|
||||
if ($Format != '') {
|
||||
$TorrentInfo[] = $Format;
|
||||
}
|
||||
if ($Encoding != '') {
|
||||
$TorrentInfo[] = $Encoding;
|
||||
}
|
||||
if (!empty($TorrentInfo)) {
|
||||
$TorrentInfo = " (" . Misc::file_string(implode(" - ", $TorrentInfo)) . ")";
|
||||
} else {
|
||||
$TorrentInfo = "";
|
||||
}
|
||||
|
||||
if (!$TorrentName) {
|
||||
$TorrentName = "No Name";
|
||||
} else if (strlen($TorrentName . $TorrentInfo) <= 197) {
|
||||
$TorrentName = Misc::file_string($Artist) . $TorrentName;
|
||||
}
|
||||
|
||||
// Leave some room to the user in case the file system limits the path length
|
||||
$MaxLength = $TxtExtension ? 196 : 192;
|
||||
if ($TorrentID) {
|
||||
$MaxLength -= 8;
|
||||
}
|
||||
$TorrentName = Format::cut_string($TorrentName . $TorrentInfo, $MaxLength, true, false);
|
||||
if ($TorrentID) {
|
||||
$TorrentName .= "-$TorrentID";
|
||||
}
|
||||
if ($TxtExtension) {
|
||||
return "$TorrentName.txt";
|
||||
}
|
||||
return "$TorrentName.torrent";
|
||||
}
|
||||
}
|
@ -19,7 +19,7 @@
|
||||
|
||||
* First, construct the archive:
|
||||
|
||||
$Zip = new ZIP('FileName');
|
||||
$Zip = new Zip('FileName');
|
||||
|
||||
Adds the headers so that add_file can stream and we don't need to create a massive buffer.
|
||||
open_stream(); was integrated into the constructor to conform with Object-Oriented Standards.
|
||||
@ -59,7 +59,7 @@
|
||||
//------------- Detailed example -------------//
|
||||
|
||||
require('classes/class_zip.php');
|
||||
$Zip = new ZIP('FileName');
|
||||
$Zip = new Zip('FileName');
|
||||
$Name = 'Ubuntu-8.10';
|
||||
$Zip->add_file($TorrentData, 'Torrents/'.Misc::file_string($Name).'.torrent');
|
||||
$Zip->add_file(file_get_contents('zip.php'), 'zip.php');
|
||||
@ -90,7 +90,7 @@ function dostime($TimeStamp = 0) {
|
||||
}
|
||||
*/
|
||||
|
||||
class ZIP {
|
||||
class Zip {
|
||||
public $ArchiveSize = 0; //Total size
|
||||
public $ArchiveFiles = 0; // Total files
|
||||
private $Structure = ''; // Structure saved to memory
|
||||
@ -99,7 +99,7 @@ class ZIP {
|
||||
|
||||
public function __construct ($ArchiveName='Archive') {
|
||||
header("Content-type: application/octet-stream"); //Stream download
|
||||
header("Content-disposition: attachment; filename=\"".urlencode($ArchiveName).".zip\""); //Name the archive
|
||||
header("Content-disposition: attachment; filename=\"$ArchiveName.zip\""); //Name the archive - Should not be urlencoded
|
||||
}
|
||||
|
||||
public static function unlimit () {
|
||||
@ -112,7 +112,7 @@ public function add_file ($FileData, $ArchivePath, $TimeStamp = 0) {
|
||||
/* File header */
|
||||
$this->Data = "\x50\x4b\x03\x04"; // PK signature
|
||||
$this->Data .= "\x14\x00"; // Version requirements
|
||||
$this->Data .= "\x00\x00"; // Bit flag
|
||||
$this->Data .= "\x00\x08"; // Bit flag - 0x8 = UTF-8 file names
|
||||
$this->Data .= "\x08\x00"; // Compression
|
||||
//$this->Data .= dostime($TimeStamp); //Last modified
|
||||
$this->Data .= "\x00\x00\x00\x00";
|
||||
@ -147,9 +147,9 @@ public function add_file ($FileData, $ArchivePath, $TimeStamp = 0) {
|
||||
|
||||
/* Central Directory Structure */
|
||||
$CDS = "\x50\x4b\x01\x02"; // CDS signature
|
||||
$CDS .="\x00\x00"; // Constructor version
|
||||
$CDS .="\x14\x00"; // Constructor version
|
||||
$CDS .="\x14\x00"; // Version requirements
|
||||
$CDS .="\x00\x00"; // Bit flag
|
||||
$CDS .="\x00\x08"; // Bit flag - 0x8 = UTF-8 file names
|
||||
$CDS .="\x08\x00"; // Compression
|
||||
$CDS .="\x00\x00\x00\x00"; // Last modified
|
||||
$CDS .= pack("V",$CRC32); // CRC-32
|
||||
|
@ -90,6 +90,18 @@
|
||||
case 'Format':
|
||||
$FileName = 'class_format';
|
||||
break;
|
||||
case 'LastFM':
|
||||
$FileName = 'class_lastfm';
|
||||
break;
|
||||
case 'MASS_USER_BOOKMARKS_EDITOR':
|
||||
$FileName = 'class_mass_user_bookmarks_editor';
|
||||
break;
|
||||
case 'MASS_USER_TORRENTS_EDITOR':
|
||||
$FileName = 'class_mass_user_torrents_editor';
|
||||
break;
|
||||
case 'MASS_USER_TORRENTS_TABLE_VIEW':
|
||||
$FileName = 'class_mass_user_torrents_table_view';
|
||||
break;
|
||||
case 'Misc':
|
||||
$FileName = 'class_misc';
|
||||
break;
|
||||
@ -104,8 +116,8 @@
|
||||
case 'SphinxQL_Result':
|
||||
$FileName = 'class_sphinxql';
|
||||
break;
|
||||
case 'Tracker':
|
||||
$FileName = 'class_tracker';
|
||||
case 'TEXTAREA_PREVIEW':
|
||||
$FileName = 'class_textarea_preview';
|
||||
break;
|
||||
case 'Tools':
|
||||
$FileName = 'class_tools';
|
||||
@ -113,29 +125,23 @@
|
||||
case 'Torrents':
|
||||
$FileName = 'class_torrents';
|
||||
break;
|
||||
case 'TorrentsDL':
|
||||
$FileName = 'class_torrentsdl';
|
||||
break;
|
||||
case 'Tracker':
|
||||
$FileName = 'class_tracker';
|
||||
break;
|
||||
case 'Users':
|
||||
$FileName = 'class_users';
|
||||
break;
|
||||
case 'View':
|
||||
$FileName = 'class_view';
|
||||
break;
|
||||
case 'MASS_USER_TORRENTS_EDITOR':
|
||||
$FileName = 'class_mass_user_torrents_editor';
|
||||
break;
|
||||
case 'MASS_USER_BOOKMARKS_EDITOR':
|
||||
$FileName = 'class_mass_user_bookmarks_editor';
|
||||
break;
|
||||
case 'MASS_USER_TORRENTS_TABLE_VIEW':
|
||||
$FileName = 'class_mass_user_torrents_table_view';
|
||||
break;
|
||||
case 'TEXTAREA_PREVIEW':
|
||||
$FileName = 'class_textarea_preview';
|
||||
break;
|
||||
case 'Votes':
|
||||
$FileName = 'class_votes';
|
||||
break;
|
||||
case 'LastFM':
|
||||
$FileName = 'class_lastfm';
|
||||
case 'Zip':
|
||||
$FileName = 'class_zip';
|
||||
break;
|
||||
default:
|
||||
die("Couldn't import class " . $ClassName);
|
||||
|
@ -1,14 +0,0 @@
|
||||
USE gazelle;
|
||||
|
||||
CREATE TABLE `artist_comments` (
|
||||
`ID` int(10) NOT NULL AUTO_INCREMENT,
|
||||
`ArtistID` int(10) NOT NULL,
|
||||
`AuthorID` int(10) NOT NULL,
|
||||
`AddedTime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`Body` mediumtext COLLATE utf8_bin,
|
||||
`EditedUserID` int(10) DEFAULT NULL,
|
||||
`EditedTime` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`ID`),
|
||||
KEY `TopicID` (`ArtistID`),
|
||||
KEY `AuthorID` (`AuthorID`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
|
@ -53,9 +53,16 @@
|
||||
!is_number($_REQUEST['artistid']) ||
|
||||
$_REQUEST['preference'] > 2 ||
|
||||
count($_REQUEST['list']) == 0
|
||||
) { error(0); }
|
||||
) {
|
||||
error(0);
|
||||
}
|
||||
|
||||
if(!check_perms('zip_downloader')){ error(403); }
|
||||
if (!check_perms('zip_downloader')) {
|
||||
error(403);
|
||||
}
|
||||
|
||||
require(SERVER_ROOT.'/classes/class_bencode.php');
|
||||
require(SERVER_ROOT.'/classes/class_torrent.php');
|
||||
|
||||
$Preferences = array('RemasterTitle DESC', 'Seeders ASC', 'Size ASC');
|
||||
|
||||
@ -66,7 +73,9 @@
|
||||
list($ArtistName) = $DB->next_record(MYSQLI_NUM, false);
|
||||
|
||||
$DB->query("SELECT GroupID, Importance FROM torrents_artists WHERE ArtistID='$ArtistID'");
|
||||
if($DB->record_count() == 0) { error(404); }
|
||||
if ($DB->record_count() == 0) {
|
||||
error(404);
|
||||
}
|
||||
$Releases = $DB->to_array('GroupID', MYSQLI_ASSOC, false);
|
||||
$GroupIDs = array_keys($Releases);
|
||||
|
||||
@ -110,96 +119,67 @@
|
||||
}
|
||||
$SQL .= "ELSE 100 END AS Rank,
|
||||
t.GroupID,
|
||||
t.ID,
|
||||
t.ID AS TorrentID,
|
||||
t.Media,
|
||||
t.Format,
|
||||
t.Encoding,
|
||||
tg.ReleaseType,
|
||||
IF(t.RemasterYear=0,tg.Year,t.RemasterYear),
|
||||
IF(t.RemasterYear=0,tg.Year,t.RemasterYear) AS Year,
|
||||
tg.Name,
|
||||
t.Size
|
||||
FROM torrents AS t
|
||||
JOIN torrents_group AS tg ON tg.ID=t.GroupID AND tg.CategoryID='1' AND tg.ID IN (".implode(',',$GroupIDs).")
|
||||
ORDER BY t.GroupID ASC, Rank DESC, t.$Preference";
|
||||
|
||||
$DB->query($SQL);
|
||||
$Downloads = $DB->to_array('1',MYSQLI_NUM,false);
|
||||
$Artists = Artists::get_artists($GroupIDs, false);
|
||||
$Skips = array();
|
||||
$TotalSize = 0;
|
||||
if(count($Downloads)) {
|
||||
foreach($Downloads as $Download) {
|
||||
$TorrentIDs[] = $Download[2];
|
||||
}
|
||||
$DB->query("SELECT TorrentID, file FROM torrents_files WHERE TorrentID IN (".implode(',', $TorrentIDs).")");
|
||||
$Torrents = $DB->to_array('TorrentID',MYSQLI_ASSOC,false);
|
||||
}
|
||||
$DownloadsQ = $DB->query($SQL);
|
||||
$Collector = new TorrentsDL($DownloadsQ, $ArtistName);
|
||||
|
||||
require(SERVER_ROOT.'/classes/class_torrent.php');
|
||||
require(SERVER_ROOT.'/classes/class_zip.php');
|
||||
$Zip = new ZIP(Misc::file_string($ArtistName));
|
||||
foreach($Downloads as $Download) {
|
||||
list($Rank, $GroupID, $TorrentID, $Media, $Format, $Encoding, $ReleaseType, $Year, $Album, $Size) = $Download;
|
||||
$Artist = Artists::display_artists($Artists[$GroupID],false,true,false);
|
||||
if ($Rank == 100) {
|
||||
$Skips[] = $Artist.$Album.' '.$Year;
|
||||
while (list($Downloads, $GroupIDs) = $Collector->get_downloads('GroupID')) {
|
||||
$Debug->log_var($Downloads, '$Downloads');
|
||||
$Debug->log_var($GroupIDs, '$GroupIDs');
|
||||
$Artists = Artists::get_artists($GroupIDs);
|
||||
$TorrentFilesQ = $DB->query("SELECT TorrentID, File FROM torrents_files WHERE TorrentID IN (".implode(',', array_keys($GroupIDs)).")", false);
|
||||
if (is_int($TorrentFilesQ)) {
|
||||
// Query failed. Let's not create a broken zip archive
|
||||
foreach ($GroupIDs as $GroupID) {
|
||||
$Download =& $Downloads[$GroupID];
|
||||
$Download['Artist'] = Artists::display_artists($Artists[$GroupID], false, true, false);
|
||||
$Collector->fail_file($Download);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
while (list($TorrentID, $TorrentFile) = $DB->next_record(MYSQLI_NUM, false)) {
|
||||
$GroupID = $GroupIDs[$TorrentID];
|
||||
$Download =& $Downloads[$GroupID];
|
||||
$Download['Artist'] = Artists::display_artists($Artists[$Download['GroupID']], false, true, false);
|
||||
if ($Download['Rank'] == 100) {
|
||||
$Collector->skip_file($Download);
|
||||
continue;
|
||||
}
|
||||
if ($Releases[$GroupID]['Importance'] == 1) {
|
||||
$ReleaseTypeName = $ReleaseTypes[$ReleaseType];
|
||||
$ReleaseTypeName = $ReleaseTypes[$Download['ReleaseType']];
|
||||
} else if ($Releases[$GroupID]['Importance'] == 2) {
|
||||
$ReleaseTypeName = "Guest Appearance";
|
||||
} else if ($Releases[$GroupID]['Importance'] == 3) {
|
||||
$ReleaseTypeName = "Remixed By";
|
||||
}
|
||||
$TotalSize += $Size;
|
||||
$Contents = unserialize(base64_decode($Torrents[$TorrentID]['file']));
|
||||
if (Misc::is_new_torrent($TorrentFile)) {
|
||||
$TorEnc = BEncTorrent::add_announce_url($TorrentFile, ANNOUNCE_URL."/$LoggedUser[torrent_pass]/announce");
|
||||
} else {
|
||||
$Contents = unserialize(base64_decode($TorrentFile));
|
||||
$Tor = new TORRENT($Contents, true);
|
||||
$Tor->set_announce_url(ANNOUNCE_URL.'/'.$LoggedUser['torrent_pass'].'/announce');
|
||||
$Tor->set_announce_url(ANNOUNCE_URL."/$LoggedUser[torrent_pass]/announce");
|
||||
unset($Tor->Val['announce-list']);
|
||||
|
||||
// We need this section for long file names :/
|
||||
$TorrentName='';
|
||||
$TorrentInfo='';
|
||||
$TorrentName = Misc::file_string($Artist.$Album);
|
||||
if ($Year > 0) { $TorrentName.=' - '.Misc::file_string($Year); }
|
||||
if ($Media != '') { $TorrentInfo .= Misc::file_string($Media); }
|
||||
if ($Format != '') {
|
||||
if ($TorrentInfo!='') { $TorrentInfo .= ' - '; }
|
||||
$TorrentInfo .= Misc::file_string($Format);
|
||||
$TorEnc = $Tor->enc();
|
||||
}
|
||||
if ($Encoding!='') {
|
||||
if ($TorrentInfo != '') { $TorrentInfo.=' - '; }
|
||||
$TorrentInfo .= Misc::file_string($Encoding);
|
||||
$Collector->add_file($TorEnc, $Download, $ReleaseTypeName);
|
||||
unset($Download);
|
||||
}
|
||||
if ($TorrentInfo != '') { $TorrentInfo = " ($TorrentInfo)"; }
|
||||
if (strlen($TorrentName) + strlen($TorrentInfo) + 3 > 200) {
|
||||
$TorrentName = Misc::file_string($Album).(($Year>0)?(' - '.Misc::file_string($Year)):'');
|
||||
}
|
||||
$FileName = Format::cut_string($TorrentName.$TorrentInfo, 180, true, false);
|
||||
|
||||
$Zip->add_file($Tor->enc(), $ReleaseTypeName.'/'.$FileName.'.torrent');
|
||||
}
|
||||
$Analyzed = count($Downloads);
|
||||
$Skipped = count($Skips);
|
||||
$Downloaded = $Analyzed - $Skipped;
|
||||
$Time = number_format(((microtime(true)-$ScriptStartTime)*1000),5).' ms';
|
||||
$Used = Format::get_size(memory_get_usage(true));
|
||||
$Date = date('M d Y, H:i');
|
||||
$Zip->add_file('Collector Download Summary - '.SITE_NAME."\r\n\r\nUser:\t\t$LoggedUser[Username]\r\nPasskey:\t$LoggedUser[torrent_pass]\r\n\r\nTime:\t\t$Time\r\nUsed:\t\t$Used\r\nDate:\t\t$Date\r\n\r\nTorrents Analyzed:\t\t$Analyzed\r\nTorrents Filtered:\t\t$Skipped\r\nTorrents Downloaded:\t$Downloaded\r\n\r\nTotal Size of Torrents (Ratio Hit): ".Format::get_size($TotalSize)."\r\n\r\nAlbums Unavailable within your criteria (consider making a request for your desired format):\r\n".implode("\r\n",$Skips), 'Summary.txt');
|
||||
$Settings = array(implode(':',$_REQUEST['list']),$_REQUEST['preference']);
|
||||
$Zip->close_stream();
|
||||
|
||||
$Collector->finalize();
|
||||
$Settings = array(implode(':', $_REQUEST['list']), $_REQUEST['preference']);
|
||||
if (!isset($LoggedUser['Collector']) || $LoggedUser['Collector'] != $Settings) {
|
||||
$DB->query("SELECT SiteOptions FROM users_info WHERE UserID='".$LoggedUser['ID']."'");
|
||||
list($Options) = $DB->next_record(MYSQLI_NUM,false);
|
||||
$Options = unserialize($Options);
|
||||
$Options['Collector'] = $Settings;
|
||||
$DB->query("UPDATE users_info SET SiteOptions='".db_string(serialize($Options))."' WHERE UserID='$LoggedUser[ID]'");
|
||||
$Cache->begin_transaction('user_info_heavy_'.$LoggedUser['ID']);
|
||||
$Cache->insert('Collector',$Settings);
|
||||
$Cache->commit_transaction(0);
|
||||
Users::update_site_options($LoggedUser['ID'], array('Collector' => $Settings));
|
||||
}
|
||||
|
||||
define('IE_WORKAROUND_NO_CACHE_HEADERS', 1);
|
||||
|
@ -53,9 +53,16 @@
|
||||
!is_number($_REQUEST['collageid']) ||
|
||||
$_REQUEST['preference'] > 2 ||
|
||||
count($_REQUEST['list']) == 0
|
||||
) { error(0); }
|
||||
) {
|
||||
error(0);
|
||||
}
|
||||
|
||||
if(!check_perms('zip_downloader')){ error(403); }
|
||||
if (!check_perms('zip_downloader')) {
|
||||
error(403);
|
||||
}
|
||||
|
||||
require(SERVER_ROOT.'/classes/class_bencode.php');
|
||||
require(SERVER_ROOT.'/classes/class_torrent.php');
|
||||
|
||||
$Preferences = array('RemasterTitle DESC', 'Seeders ASC', 'Size ASC');
|
||||
|
||||
@ -105,11 +112,11 @@
|
||||
}
|
||||
$SQL .= "ELSE 100 END AS Rank,
|
||||
t.GroupID,
|
||||
t.ID,
|
||||
t.ID AS TorrentID,
|
||||
t.Media,
|
||||
t.Format,
|
||||
t.Encoding,
|
||||
IF(t.RemasterYear=0,tg.Year,t.RemasterYear),
|
||||
IF(t.RemasterYear=0,tg.Year,t.RemasterYear) AS Year,
|
||||
tg.Name,
|
||||
t.Size
|
||||
FROM torrents AS t
|
||||
@ -117,79 +124,46 @@
|
||||
INNER JOIN torrents_group AS tg ON tg.ID=t.GroupID AND tg.CategoryID='1'
|
||||
ORDER BY t.GroupID ASC, Rank DESC, t.$Preference";
|
||||
|
||||
$DB->query($SQL);
|
||||
$Downloads = $DB->to_array('1',MYSQLI_NUM,false);
|
||||
$Artists = Artists::get_artists($DB->collect('GroupID'), false);
|
||||
$Skips = array();
|
||||
$TotalSize = 0;
|
||||
$DownloadsQ = $DB->query($SQL);
|
||||
$Collector = new TorrentsDL($DownloadsQ, $CollageName);
|
||||
|
||||
if(count($Downloads)) {
|
||||
foreach($Downloads as $Download) {
|
||||
$TorrentIDs[] = $Download[2];
|
||||
while (list($Downloads, $GroupIDs) = $Collector->get_downloads('GroupID')) {
|
||||
$Artists = Artists::get_artists($GroupIDs);
|
||||
$TorrentFilesQ = $DB->query("SELECT TorrentID, File FROM torrents_files WHERE TorrentID IN (".implode(',', array_keys($GroupIDs)).")", false);
|
||||
if (is_int($TorrentFilesQ)) {
|
||||
// Query failed. Let's not create a broken zip archive
|
||||
foreach ($GroupIDs as $GroupID) {
|
||||
$Download =& $Downloads[$GroupID];
|
||||
$Download['Artist'] = Artists::display_artists($Artists[$GroupID], false, true, false);
|
||||
$Collector->fail_file($Download);
|
||||
}
|
||||
$DB->query("SELECT TorrentID, file FROM torrents_files WHERE TorrentID IN (".implode(',', $TorrentIDs).")");
|
||||
$Torrents = $DB->to_array('TorrentID',MYSQLI_ASSOC,false);
|
||||
}
|
||||
|
||||
require(SERVER_ROOT.'/classes/class_torrent.php');
|
||||
require(SERVER_ROOT.'/classes/class_zip.php');
|
||||
$Zip = new ZIP(Misc::file_string($CollageName));
|
||||
foreach($Downloads as $Download) {
|
||||
list($Rank, $GroupID, $TorrentID, $Media, $Format, $Encoding, $Year, $Album, $Size) = $Download;
|
||||
$Artist = Artists::display_artists($Artists[$GroupID],false,true,false);
|
||||
if ($Rank == 100) {
|
||||
$Skips[] = $Artist.$Album.' '.$Year;
|
||||
continue;
|
||||
}
|
||||
$TotalSize += $Size;
|
||||
$Contents = unserialize(base64_decode($Torrents[$TorrentID]['file']));
|
||||
while (list($TorrentID, $TorrentFile) = $DB->next_record(MYSQLI_NUM, false)) {
|
||||
$GroupID = $GroupIDs[$TorrentID];
|
||||
$Download =& $Downloads[$GroupID];
|
||||
$Download['Artist'] = Artists::display_artists($Artists[$Download['GroupID']], false, true, false);
|
||||
if ($Download['Rank'] == 100) {
|
||||
$Collector->skip_file($Download);
|
||||
continue;
|
||||
}
|
||||
if (Misc::is_new_torrent($TorrentFile)) {
|
||||
$TorEnc = BEncTorrent::add_announce_url($TorrentFile, ANNOUNCE_URL."/$LoggedUser[torrent_pass]/announce");
|
||||
} else {
|
||||
$Contents = unserialize(base64_decode($TorrentFile));
|
||||
$Tor = new TORRENT($Contents, true);
|
||||
$Tor->set_announce_url(ANNOUNCE_URL.'/'.$LoggedUser['torrent_pass'].'/announce');
|
||||
$Tor->set_announce_url(ANNOUNCE_URL."/$LoggedUser[torrent_pass]/announce");
|
||||
unset($Tor->Val['announce-list']);
|
||||
|
||||
// We need this section for long file names :/
|
||||
$TorrentName='';
|
||||
$TorrentInfo='';
|
||||
$TorrentName = Misc::file_string($Artist.$Album);
|
||||
if ($Year > 0) { $TorrentName.=' - '.Misc::file_string($Year); }
|
||||
if ($Media != '') { $TorrentInfo .= Misc::file_string($Media); }
|
||||
if ($Format != '') {
|
||||
if ($TorrentInfo!='') { $TorrentInfo .= ' - '; }
|
||||
$TorrentInfo .= Misc::file_string($Format);
|
||||
$TorEnc = $Tor->enc();
|
||||
}
|
||||
if ($Encoding!='') {
|
||||
if ($TorrentInfo != '') { $TorrentInfo.=' - '; }
|
||||
$TorrentInfo .= Misc::file_string($Encoding);
|
||||
$Collector->add_file($TorEnc, $Download);
|
||||
unset($Download);
|
||||
}
|
||||
if ($TorrentInfo != '') { $TorrentInfo = " ($TorrentInfo)"; }
|
||||
if (strlen($TorrentName) + strlen($TorrentInfo) + 3 > 200) {
|
||||
$TorrentName = Misc::file_string($Album).(($Year>0)?(' - '.Misc::file_string($Year)):'');
|
||||
}
|
||||
$FileName = $TorrentName.$TorrentInfo;
|
||||
$FileName = Format::cut_string($FileName, 192, true, false);
|
||||
|
||||
$Zip->add_file($Tor->enc(), $FileName.'.torrent');
|
||||
}
|
||||
$Analyzed = count($Downloads);
|
||||
$Skipped = count($Skips);
|
||||
$Downloaded = $Analyzed - $Skipped;
|
||||
$Time = number_format(((microtime(true)-$ScriptStartTime)*1000),5).' ms';
|
||||
$Used = Format::get_size(memory_get_usage(true));
|
||||
$Date = date('M d Y, H:i');
|
||||
$Zip->add_file('Collector Download Summary - '.SITE_NAME."\r\n\r\nUser:\t\t$LoggedUser[Username]\r\nPasskey:\t$LoggedUser[torrent_pass]\r\n\r\nTime:\t\t$Time\r\nUsed:\t\t$Used\r\nDate:\t\t$Date\r\n\r\nTorrents Analyzed:\t\t$Analyzed\r\nTorrents Filtered:\t\t$Skipped\r\nTorrents Downloaded:\t$Downloaded\r\n\r\nTotal Size of Torrents (Ratio Hit): ".Format::get_size($TotalSize)."\r\n\r\nAlbums Unavailable within your criteria (consider making a request for your desired format):\r\n".implode("\r\n",$Skips), 'Summary.txt');
|
||||
$Settings = array(implode(':',$_REQUEST['list']),$_REQUEST['preference']);
|
||||
$Zip->close_stream();
|
||||
|
||||
$Collector->finalize();
|
||||
$Settings = array(implode(':', $_REQUEST['list']), $_REQUEST['preference']);
|
||||
if (!isset($LoggedUser['Collector']) || $LoggedUser['Collector'] != $Settings) {
|
||||
$DB->query("SELECT SiteOptions FROM users_info WHERE UserID='$LoggedUser[ID]'");
|
||||
list($Options) = $DB->next_record(MYSQLI_NUM,false);
|
||||
$Options = unserialize($Options);
|
||||
$Options['Collector'] = $Settings;
|
||||
$DB->query("UPDATE users_info SET SiteOptions='".db_string(serialize($Options))."' WHERE UserID='$LoggedUser[ID]'");
|
||||
$Cache->begin_transaction('user_info_heavy_'.$LoggedUser['ID']);
|
||||
$Cache->insert('Collector',$Settings);
|
||||
$Cache->commit_transaction(0);
|
||||
Users::update_site_options($LoggedUser['ID'], array('Collector' => $Settings));
|
||||
}
|
||||
|
||||
define('IE_WORKAROUND_NO_CACHE_HEADERS', 1);
|
||||
|
@ -24,7 +24,6 @@
|
||||
$TorrentPass = $_REQUEST['torrent_pass'];
|
||||
$AuthKey = $_REQUEST['authkey'];
|
||||
}
|
||||
require(SERVER_ROOT.'/classes/class_torrent.php');
|
||||
|
||||
$TorrentID = $_REQUEST['id'];
|
||||
|
||||
@ -147,58 +146,25 @@
|
||||
|
||||
$DB->query("SELECT File FROM torrents_files WHERE TorrentID='$TorrentID'");
|
||||
|
||||
list($Contents) = $DB->next_record(MYSQLI_NUM, array(0));
|
||||
list($Contents) = $DB->next_record(MYSQLI_NUM, false);
|
||||
if (Misc::is_new_torrent($Contents)) {
|
||||
require(SERVER_ROOT.'/classes/class_bencode.php');
|
||||
$TorEnc = BEncTorrent::add_announce_url($Contents, ANNOUNCE_URL."/$TorrentPass/announce");
|
||||
} else {
|
||||
require(SERVER_ROOT.'/classes/class_torrent.php');
|
||||
$Contents = unserialize(base64_decode($Contents));
|
||||
$Tor = new TORRENT($Contents, true); // New TORRENT object
|
||||
// Set torrent announce URL
|
||||
$Tor->set_announce_url(ANNOUNCE_URL.'/'.$TorrentPass.'/announce');
|
||||
$Tor->set_announce_url(ANNOUNCE_URL."/$TorrentPass/announce");
|
||||
// Remove multiple trackers from torrent
|
||||
unset($Tor->Val['announce-list']);
|
||||
// Remove web seeds (put here for old torrents not caught by previous commit
|
||||
unset($Tor->Val['url-list']);
|
||||
// Remove libtorrent resume info
|
||||
unset($Tor->Val['libtorrent_resume']);
|
||||
// Torrent name takes the format of Artist - Album - YYYY (Media - Format - Encoding)
|
||||
|
||||
$TorrentName='';
|
||||
$TorrentInfo='';
|
||||
|
||||
$TorrentName = $Info['PlainArtists'];
|
||||
|
||||
$TorrentName.=$Name;
|
||||
|
||||
if ($Year>0) { $TorrentName.=' - '.$Year; }
|
||||
|
||||
if ($Media!='') { $TorrentInfo.=$Media; }
|
||||
|
||||
if ($Format!='') {
|
||||
if ($TorrentInfo!='') { $TorrentInfo.=' - '; }
|
||||
$TorrentInfo.=$Format;
|
||||
$TorEnc = $Tor->enc();
|
||||
}
|
||||
|
||||
if ($Encoding!='') {
|
||||
if ($TorrentInfo!='') { $TorrentInfo.=' - '; }
|
||||
$TorrentInfo.=$Encoding;
|
||||
}
|
||||
|
||||
// Let's try to shorten the filename intelligently before chopping it off
|
||||
if (strlen($TorrentName) + strlen($TorrentInfo) + 3 > 200) {
|
||||
$TorrentName = $Name . (($Year>0)?(' - '.$Year):'');
|
||||
}
|
||||
|
||||
if ($TorrentInfo!='') { $TorrentName.=' ('.$TorrentInfo.')'; }
|
||||
|
||||
if(!empty($_GET['mode']) && $_GET['mode'] == 'bbb'){
|
||||
$TorrentName = $Artists.' -- '.$Name;
|
||||
}
|
||||
|
||||
if (!$TorrentName) { $TorrentName="No Name"; }
|
||||
|
||||
$FileName = ($Browser == 'Internet Explorer') ? urlencode(Misc::file_string($TorrentName)) : Misc::file_string($TorrentName);
|
||||
$MaxLength = $DownloadAlt ? 192 : 196;
|
||||
$FileName = Format::cut_string($FileName, $MaxLength, true, false);
|
||||
$FileName = $DownloadAlt ? $FileName.'.txt' : $FileName.'.torrent';
|
||||
|
||||
$FileName = TorrentsDL::construct_file_name($Info['PlainArtists'], $Name, $Year, $Media, $Format, $Encoding, false, $DownloadAlt);
|
||||
|
||||
if($DownloadAlt) {
|
||||
header('Content-Type: text/plain; charset=utf-8');
|
||||
@ -207,6 +173,6 @@
|
||||
}
|
||||
header('Content-disposition: attachment; filename="'.$FileName.'"');
|
||||
|
||||
echo $Tor->enc();
|
||||
echo $TorEnc;
|
||||
|
||||
define('IE_WORKAROUND_NO_CACHE_HEADERS', 1);
|
||||
|
@ -12,9 +12,10 @@
|
||||
$User = Users::user_info($UserID);
|
||||
$Perms = Permissions::get_permissions($User['PermissionID']);
|
||||
$UserClass = $Perms['Class'];
|
||||
list($UserID, $Username) = array_values($User);
|
||||
|
||||
require(SERVER_ROOT.'/classes/class_bencode.php');
|
||||
require(SERVER_ROOT.'/classes/class_torrent.php');
|
||||
require(SERVER_ROOT.'/classes/class_zip.php');
|
||||
|
||||
if (empty($_GET['type'])) {
|
||||
error(0);
|
||||
@ -47,84 +48,52 @@
|
||||
}
|
||||
}
|
||||
|
||||
ZIP::unlimit();
|
||||
|
||||
$DB->query("SELECT
|
||||
t.ID,
|
||||
$DownloadsQ = $DB->query("SELECT
|
||||
t.ID AS TorrentID,
|
||||
DATE_FORMAT(".$Month.",'%Y - %m') AS Month,
|
||||
t.GroupID,
|
||||
t.Media,
|
||||
t.Format,
|
||||
t.Encoding,
|
||||
IF(t.RemasterYear=0,tg.Year,t.RemasterYear),
|
||||
IF(t.RemasterYear=0,tg.Year,t.RemasterYear) AS Year,
|
||||
tg.Name,
|
||||
t.Size
|
||||
FROM torrents as t
|
||||
JOIN torrents_group AS tg ON t.GroupID=tg.ID
|
||||
".$SQL."
|
||||
GROUP BY t.ID");
|
||||
$Downloads = $DB->to_array(0, MYSQLI_NUM, false);
|
||||
$Artists = Artists::get_artists($DB->collect('GroupID'));
|
||||
GROUP BY TorrentID");
|
||||
|
||||
if (!empty($Downloads)) {
|
||||
$DB->query("SELECT TorrentID, File FROM torrents_files WHERE TorrentID IN (".implode(',', array_keys($Downloads)).")");
|
||||
$TorrentFiles = $DB->to_array(0, MYSQLI_NUM, false);
|
||||
$Collector = new TorrentsDL($DownloadsQ, "$Username's ".ucfirst($_GET['type']));
|
||||
|
||||
while (list($Downloads, $GroupIDs) = $Collector->get_downloads('TorrentID')) {
|
||||
$Artists = Artists::get_artists($GroupIDs);
|
||||
$TorrentIDs = array_keys($GroupIDs);
|
||||
$TorrentFilesQ = $DB->query("SELECT TorrentID, File FROM torrents_files WHERE TorrentID IN (".implode(',', $TorrentIDs).")", false);
|
||||
if (is_int($TorrentFilesQ)) {
|
||||
// Query failed. Let's not create a broken zip archive
|
||||
foreach ($TorrentIDs as $TorrentID) {
|
||||
$Download =& $Downloads[$TorrentID];
|
||||
$Download['Artist'] = Artists::display_artists($Artists[$Download['GroupID']], false, true, false);
|
||||
$Collector->fail_file($Download);
|
||||
}
|
||||
list($UserID, $Username) = array_values(Users::user_info($UserID));
|
||||
$Zip = new ZIP($Username.'\'s '.ucfirst($_GET['type']));
|
||||
foreach ($Downloads as $Download) {
|
||||
list($TorrentID, $Month, $GroupID, $Media, $Format, $Encoding, $Year, $Album, $Size) = $Download;
|
||||
if (!isset($TorrentFiles[$TorrentID])) {
|
||||
continue;
|
||||
}
|
||||
$Artist = Artists::display_artists($Artists[$GroupID],false,true,false);
|
||||
$Contents = unserialize(base64_decode($TorrentFiles[$TorrentID][1]));
|
||||
while (list($TorrentID, $TorrentFile) = $DB->next_record(MYSQLI_NUM, false)) {
|
||||
$Download =& $Downloads[$TorrentID];
|
||||
$Download['Artist'] = Artists::display_artists($Artists[$Download['GroupID']], false, true, false);
|
||||
if (Misc::is_new_torrent($TorrentFile)) {
|
||||
$TorEnc = BEncTorrent::add_announce_url($TorrentFile, ANNOUNCE_URL."/$LoggedUser[torrent_pass]/announce");
|
||||
} else {
|
||||
$Contents = unserialize(base64_decode($TorrentFile));
|
||||
$Tor = new TORRENT($Contents, true);
|
||||
$Tor->set_announce_url(ANNOUNCE_URL.'/'.$LoggedUser['torrent_pass'].'/announce');
|
||||
$Tor->set_announce_url(ANNOUNCE_URL."/$LoggedUser[torrent_pass]/announce");
|
||||
unset($Tor->Val['announce-list']);
|
||||
|
||||
$TorrentName = '';
|
||||
$TorrentInfo = '';
|
||||
$TorrentName = $Artist;
|
||||
$TorrentName .= $Album;
|
||||
|
||||
if ($Year > 0) {
|
||||
$TorrentName .= ' - '.$Year;
|
||||
$TorEnc = $Tor->enc();
|
||||
}
|
||||
|
||||
if ($Media != '') {
|
||||
$TorrentInfo .= $Media;
|
||||
$Collector->add_file($TorEnc, $Download, $Download['Month']);
|
||||
unset($Download);
|
||||
}
|
||||
|
||||
if ($Format != '') {
|
||||
if ($TorrentInfo != '') {
|
||||
$TorrentInfo .= ' - ';
|
||||
}
|
||||
$TorrentInfo .= $Format;
|
||||
}
|
||||
|
||||
if ($Encoding!='') {
|
||||
if ($TorrentInfo != '') {
|
||||
$TorrentInfo .= ' - ';
|
||||
}
|
||||
$TorrentInfo .= $Encoding;
|
||||
}
|
||||
|
||||
if ($TorrentInfo != '') {
|
||||
$TorrentName .= ' ('.$TorrentInfo.')';
|
||||
}
|
||||
|
||||
if (!$TorrentName) {
|
||||
$TorrentName = "No Name";
|
||||
}
|
||||
|
||||
$FileName = Misc::file_string($TorrentName);
|
||||
if ($Browser == 'Internet Explorer') {
|
||||
$FileName = urlencode($FileName);
|
||||
}
|
||||
$FileName .= '.torrent';
|
||||
$Zip->add_file($Tor->enc(), Misc::file_string($Month).'/'.$FileName);
|
||||
}
|
||||
$Zip->close_stream();
|
||||
$Collector->finalize(false);
|
||||
|
||||
define('IE_WORKAROUND_NO_CACHE_HEADERS', 1);
|
||||
|
Loading…
Reference in New Issue
Block a user