Gazelle/classes/torrents.class.php

936 lines
28 KiB
PHP
Raw Normal View History

2012-10-11 08:00:15 +00:00
<?
class Torrents {
2013-02-11 08:00:34 +00:00
const FilelistDelim = 0xF7; // Hex for &divide; Must be the same as phrase_boundary in sphinx.conf!
2012-10-11 08:00:15 +00:00
/*
* Function to get data and torrents for an array of GroupIDs.
* In places where the output from this is merged with sphinx filters, it will be in a different order.
*
* @param array $GroupIDs
* @param boolean $Return if false, nothing is returned. For priming cache.
* @param boolean $GetArtists if true, each group will contain the result of
* Artists::get_artists($GroupID), in result[$GroupID]['ExtendedArtists']
* @param boolean $Torrents if true, each group contains a list of torrents, in result[$GroupID]['Torrents']
*
* @return array each row of the following format:
* GroupID => (
2013-02-25 21:16:55 +00:00
* ID
2012-10-11 08:00:15 +00:00
* Name
* Year
* RecordLabel
* CatalogueNumber
* TagList
* ReleaseType
* VanityHouse
2013-02-25 21:16:55 +00:00
* WikiImage
* CategoryID
2012-10-11 08:00:15 +00:00
* Torrents => {
* ID => {
* GroupID, Media, Format, Encoding, RemasterYear, Remastered,
* RemasterTitle, RemasterRecordLabel, RemasterCatalogueNumber, Scene,
* HasLog, HasCue, LogScore, FileCount, FreeTorrent, Size, Leechers,
2012-10-28 08:00:19 +00:00
* Seeders, Snatched, Time, HasFile, PersonalFL, IsSnatched
2012-10-11 08:00:15 +00:00
* }
* }
2012-12-06 08:00:17 +00:00
* Artists => {
* {
* id, name, aliasid // Only main artists
* }
* }
2012-10-11 08:00:15 +00:00
* ExtendedArtists => {
* [1-6] => { // See documentation on Artists::get_artists
* id, name, aliasid
* }
* }
2012-12-06 08:00:17 +00:00
* Flags => {
* IsSnatched
* }
2012-10-11 08:00:15 +00:00
*/
public static function get_groups($GroupIDs, $Return = true, $GetArtists = true, $Torrents = true) {
2012-10-28 08:00:19 +00:00
global $DB, $Cache, $Debug;
2012-10-27 08:00:09 +00:00
// Make sure there's something in $GroupIDs, otherwise the SQL
// will break
if (count($GroupIDs) == 0) {
2013-07-05 08:00:39 +00:00
return array('matches' => array(), 'notfound' => array());
2012-10-27 08:00:09 +00:00
}
2012-10-28 08:00:19 +00:00
2012-11-01 08:00:21 +00:00
$Found = $NotFound = array_flip($GroupIDs);
2012-10-11 08:00:15 +00:00
$Key = $Torrents ? 'torrent_group_' : 'torrent_group_light_';
foreach ($GroupIDs as $GroupID) {
2012-10-30 08:00:18 +00:00
$Data = $Cache->get_value($Key.$GroupID, true);
2013-02-18 08:00:22 +00:00
if (!empty($Data) && (@$Data['ver'] == CACHE::GROUP_VERSION)) {
2012-10-11 08:00:15 +00:00
unset($NotFound[$GroupID]);
$Found[$GroupID] = $Data['d'];
}
}
2013-07-05 08:00:39 +00:00
$IDs = implode(',', array_flip($NotFound));
2012-10-11 08:00:15 +00:00
/*
Changing any of these attributes returned will cause very large, very dramatic site-wide chaos.
Do not change what is returned or the order thereof without updating:
torrents, artists, collages, bookmarks, better, the front page,
and anywhere else the get_groups function is used.
2013-02-25 21:16:55 +00:00
Update self::array_group(), too
2012-10-11 08:00:15 +00:00
*/
2012-10-16 08:00:18 +00:00
if (count($NotFound) > 0) {
2013-06-06 08:01:03 +00:00
$DB->query("
SELECT
g.ID, g.Name, g.Year, g.RecordLabel, g.CatalogueNumber, g.TagList, g.ReleaseType, g.VanityHouse, g.WikiImage, g.CategoryID
FROM torrents_group AS g
WHERE g.ID IN ($IDs)");
2012-10-11 08:00:15 +00:00
2013-04-30 18:18:07 +00:00
while ($Group = $DB->next_record(MYSQLI_ASSOC, true)) {
2012-10-11 08:00:15 +00:00
unset($NotFound[$Group['ID']]);
$Found[$Group['ID']] = $Group;
$Found[$Group['ID']]['Torrents'] = array();
$Found[$Group['ID']]['Artists'] = array();
}
2012-10-16 08:00:18 +00:00
// Orphan torrents. There shouldn't ever be any
if (count($NotFound) > 0) {
foreach (array_keys($NotFound) as $GroupID) {
unset($Found[$GroupID]);
}
}
2012-10-11 08:00:15 +00:00
if ($Torrents) {
2013-06-06 08:01:03 +00:00
$DB->query("
SELECT
ID, GroupID, Media, Format, Encoding, RemasterYear, Remastered, RemasterTitle,
RemasterRecordLabel, RemasterCatalogueNumber, Scene, HasLog, HasCue, LogScore,
FileCount, FreeTorrent, Size, Leechers, Seeders, Snatched, Time, ID AS HasFile
FROM torrents AS t
WHERE GroupID IN($IDs)
ORDER BY GroupID, Remastered, (RemasterYear != 0) DESC, RemasterYear, RemasterTitle,
2012-10-11 08:00:15 +00:00
RemasterRecordLabel, RemasterCatalogueNumber, Media, Format, Encoding, ID");
2013-04-30 18:18:07 +00:00
while ($Torrent = $DB->next_record(MYSQLI_ASSOC, true)) {
2012-10-11 08:00:15 +00:00
$Found[$Torrent['GroupID']]['Torrents'][$Torrent['ID']] = $Torrent;
2012-10-30 08:00:18 +00:00
}
2013-02-22 08:00:24 +00:00
2012-10-30 08:00:18 +00:00
// Cache it all
2013-02-25 21:16:55 +00:00
foreach ($Found as $GroupID => $GroupInfo) {
2013-07-05 08:00:39 +00:00
$Cache->cache_value("torrent_group_$GroupID",
2013-02-25 21:16:55 +00:00
array('ver' => CACHE::GROUP_VERSION, 'd' => $GroupInfo), 0);
2013-07-05 08:00:39 +00:00
$Cache->cache_value("torrent_group_light_$GroupID",
2013-02-25 21:16:55 +00:00
array('ver' => CACHE::GROUP_VERSION, 'd' => $GroupInfo), 0);
2012-10-11 08:00:15 +00:00
}
2012-10-28 08:00:19 +00:00
2012-10-11 08:00:15 +00:00
} else {
foreach ($Found as $Group) {
2013-02-25 21:16:55 +00:00
$Cache->cache_value('torrent_group_light_'.$Group['ID'], array('ver' => CACHE::GROUP_VERSION, 'd' => $Found[$Group['ID']]), 0);
2012-10-11 08:00:15 +00:00
}
}
}
if ($GetArtists) {
$Artists = Artists::get_artists($GroupIDs);
} else {
$Artists = array();
}
if ($Return) { // If we're interested in the data, and not just caching it
2012-10-16 08:00:18 +00:00
foreach ($Artists as $GroupID => $Data) {
2012-10-11 08:00:15 +00:00
if (array_key_exists(1, $Data) || array_key_exists(4, $Data) || array_key_exists(6, $Data)) {
2012-10-16 08:00:18 +00:00
$Found[$GroupID]['Artists'] = isset($Data[1]) ? $Data[1] : null; // Only use main artists (legacy)
for ($i = 1; $i <= 6; $i++) {
$Found[$GroupID]['ExtendedArtists'][$i] = isset($Data[$i]) ? $Data[$i] : null;
}
2012-10-11 08:00:15 +00:00
}
else {
$Found[$GroupID]['ExtendedArtists'] = false;
}
}
2012-10-16 08:00:18 +00:00
// Fetch all user specific torrent properties
foreach ($Found as &$Group) {
2012-12-06 08:00:17 +00:00
$Group['Flags'] = array('IsSnatched' => false);
2012-10-16 08:00:18 +00:00
if (!empty($Group['Torrents'])) {
2012-12-06 08:00:17 +00:00
foreach ($Group['Torrents'] as &$Torrent) {
self::torrent_properties($Torrent, $Group['Flags']);
}
2012-10-16 08:00:18 +00:00
}
}
2012-10-28 08:00:19 +00:00
2013-07-05 08:00:39 +00:00
$Matches = array('matches' => $Found, 'notfound' => array_flip($NotFound));
2012-10-11 08:00:15 +00:00
return $Matches;
}
}
2013-02-25 21:16:55 +00:00
/**
* Returns a reconfigured array from a Torrent Group
*
* Use this with extract() instead of the volatile list($GroupID, ...)
* Then use the variables $GroupID, $GroupName, etc
*
* @example extract(Torrents::array_group($SomeGroup));
* @param array $Group torrent group
* @return array Re-key'd array
*/
public static function array_group (array &$Group)
{
return array(
'GroupID' => $Group['ID'],
'GroupName' => $Group['Name'],
'GroupYear' => $Group['Year'],
'GroupCategoryID' => $Group['CategoryID'],
'GroupRecordLabel' => $Group['RecordLabel'],
'GroupCatalogueNumber' => $Group['CatalogueNumber'],
'GroupVanityHouse' => $Group['VanityHouse'],
'GroupFlags' => $Group['Flags'],
'TagList' => $Group['TagList'],
'ReleaseType' => $Group['ReleaseType'],
'WikiImage' => $Group['WikiImage'],
'Torrents' => $Group['Torrents'],
'Artists' => $Group['Artists'],
'ExtendedArtists' => $Group['ExtendedArtists']
);
}
2012-10-11 08:00:15 +00:00
2012-10-16 08:00:18 +00:00
/**
* Supplements a torrent array with information that only concerns certain users and therefore cannot be cached
*
* @param array $Torrent torrent array preferably in the form used by Torrents::get_groups() or get_group_info()
* @param int $TorrentID
*/
2012-12-06 08:00:17 +00:00
public static function torrent_properties(&$Torrent, &$Flags) {
$Torrent['PersonalFL'] = empty($Torrent['FreeTorrent']) && self::has_token($Torrent['ID']);
if ($Torrent['IsSnatched'] = self::has_snatched($Torrent['ID'])) {
$Flags['IsSnatched'] = true;
}
2012-10-16 08:00:18 +00:00
}
2012-10-11 08:00:15 +00:00
/*
* Write to the group log.
*
* @param int $GroupID
* @param int $TorrentID
* @param int $UserID
* @param string $Message
* @param boolean $Hidden Currently does fuck all. TODO: Fix that.
*/
public static function write_group_log($GroupID, $TorrentID, $UserID, $Message, $Hidden) {
2013-06-18 08:00:48 +00:00
global $DB, $Time;
2013-06-06 08:01:03 +00:00
$DB->query("
INSERT INTO group_log
(GroupID, TorrentID, UserID, Info, Time, Hidden)
VALUES
($GroupID, $TorrentID, $UserID, '".db_string($Message)."', '".sqltime()."', $Hidden)");
2012-10-11 08:00:15 +00:00
}
/**
* Delete a torrent.
*
* @param int $ID The ID of the torrent to delete.
* @param int $GroupID Set it if you have it handy, to save a query. Otherwise, it will be found.
* @param string $OcelotReason The deletion reason for ocelot to report to users.
*/
2013-06-06 08:01:03 +00:00
public static function delete_torrent($ID, $GroupID = 0, $OcelotReason = -1) {
2012-10-11 08:00:15 +00:00
global $DB, $Cache, $LoggedUser;
if (!$GroupID) {
2013-06-06 08:01:03 +00:00
$DB->query("
SELECT GroupID, UserID
FROM torrents
2013-07-05 08:00:39 +00:00
WHERE ID = '$ID'");
2012-10-11 08:00:15 +00:00
list($GroupID, $UploaderID) = $DB->next_record();
}
if (empty($UserID)) {
2013-06-06 08:01:03 +00:00
$DB->query("
SELECT UserID
FROM torrents
2013-07-05 08:00:39 +00:00
WHERE ID = '$ID'");
2012-10-11 08:00:15 +00:00
list($UserID) = $DB->next_record();
}
2013-07-05 08:00:39 +00:00
$RecentUploads = $Cache->get_value("recent_uploads_$UserID");
2012-10-11 08:00:15 +00:00
if (is_array($RecentUploads)) {
foreach ($RecentUploads as $Key => $Recent) {
if ($Recent['ID'] == $GroupID) {
2013-07-05 08:00:39 +00:00
$Cache->delete_value("recent_uploads_$UserID");
2012-10-11 08:00:15 +00:00
}
}
}
2013-05-16 16:15:57 +00:00
2013-06-06 08:01:03 +00:00
$DB->query("
SELECT info_hash
FROM torrents
2013-07-05 08:00:39 +00:00
WHERE ID = $ID");
2012-10-11 08:00:15 +00:00
list($InfoHash) = $DB->next_record(MYSQLI_BOTH, false);
2013-06-06 08:01:03 +00:00
$DB->query("
DELETE FROM torrents
2013-07-05 08:00:39 +00:00
WHERE ID = $ID");
2012-10-11 08:00:15 +00:00
Tracker::update_tracker('delete_torrent', array('info_hash' => rawurlencode($InfoHash), 'id' => $ID, 'reason' => $OcelotReason));
$Cache->decrement('stats_torrent_count');
2013-06-06 08:01:03 +00:00
$DB->query("
SELECT COUNT(ID)
FROM torrents
2013-07-05 08:00:39 +00:00
WHERE GroupID = '$GroupID'");
2012-10-11 08:00:15 +00:00
list($Count) = $DB->next_record();
if ($Count == 0) {
Torrents::delete_group($GroupID);
} else {
Torrents::update_hash($GroupID);
}
// Torrent notifications
2013-06-06 08:01:03 +00:00
$DB->query("
SELECT UserID
FROM users_notify_torrents
2013-07-05 08:00:39 +00:00
WHERE TorrentID = '$ID'");
2013-04-30 18:18:07 +00:00
while (list($UserID) = $DB->next_record()) {
2013-07-05 08:00:39 +00:00
$Cache->delete_value("notifications_new_$UserID");
2012-10-11 08:00:15 +00:00
}
2013-06-06 08:01:03 +00:00
$DB->query("
DELETE FROM users_notify_torrents
2013-07-05 08:00:39 +00:00
WHERE TorrentID = '$ID'");
2012-10-11 08:00:15 +00:00
2013-06-06 08:01:03 +00:00
$DB->query("
UPDATE reportsv2
SET
2013-07-05 08:00:39 +00:00
Status = 'Resolved',
LastChangeTime = '".sqltime()."',
ModComment = 'Report already dealt with (torrent deleted)'
2013-06-06 08:01:03 +00:00
WHERE TorrentID = $ID
2012-10-11 08:00:15 +00:00
AND Status != 'Resolved'");
$Reports = $DB->affected_rows();
if ($Reports) {
$Cache->decrement('num_torrent_reportsv2', $Reports);
}
2013-06-06 08:01:03 +00:00
$DB->query("
DELETE FROM torrents_files
WHERE TorrentID = '$ID'");
$DB->query("
DELETE FROM torrents_bad_tags
2013-07-05 08:00:39 +00:00
WHERE TorrentID = $ID");
2013-06-06 08:01:03 +00:00
$DB->query("
DELETE FROM torrents_bad_folders
2013-07-05 08:00:39 +00:00
WHERE TorrentID = $ID");
2013-06-06 08:01:03 +00:00
$DB->query("
DELETE FROM torrents_bad_files
2013-07-05 08:00:39 +00:00
WHERE TorrentID = $ID");
2013-06-06 08:01:03 +00:00
$DB->query("
DELETE FROM torrents_cassette_approved
2013-07-05 08:00:39 +00:00
WHERE TorrentID = $ID");
2013-06-06 08:01:03 +00:00
$DB->query("
DELETE FROM torrents_lossymaster_approved
2013-07-05 08:00:39 +00:00
WHERE TorrentID = $ID");
2013-06-06 08:01:03 +00:00
$DB->query("
DELETE FROM torrents_lossyweb_approved
2013-07-05 08:00:39 +00:00
WHERE TorrentID = $ID");
2012-11-01 08:00:21 +00:00
// Tells Sphinx that the group is removed
2013-06-06 08:01:03 +00:00
$DB->query("
REPLACE INTO sphinx_delta (ID, Time)
VALUES ($ID, UNIX_TIMESTAMP())");
2012-11-01 08:00:21 +00:00
2013-07-05 08:00:39 +00:00
$Cache->delete_value("torrent_download_$ID");
$Cache->delete_value("torrent_group_$GroupID");
$Cache->delete_value("torrents_details_$GroupID");
2012-10-11 08:00:15 +00:00
}
/**
* Delete a group, called after all of its torrents have been deleted.
* IMPORTANT: Never call this unless you're certain the group is no longer used by any torrents
*
* @param int $GroupID
*/
public static function delete_group($GroupID) {
global $DB, $Cache;
2013-06-06 08:01:03 +00:00
Misc::write_log("Group $GroupID automatically deleted (No torrents have this group).");
2012-10-11 08:00:15 +00:00
2013-06-06 08:01:03 +00:00
$DB->query("
SELECT CategoryID
FROM torrents_group
2013-07-05 08:00:39 +00:00
WHERE ID = '$GroupID'");
2012-10-11 08:00:15 +00:00
list($Category) = $DB->next_record();
if ($Category == 1) {
$Cache->decrement('stats_album_count');
}
$Cache->decrement('stats_group_count');
2013-05-16 16:15:57 +00:00
2012-10-11 08:00:15 +00:00
// Collages
2013-06-06 08:01:03 +00:00
$DB->query("
SELECT CollageID
FROM collages_torrents
2013-07-05 08:00:39 +00:00
WHERE GroupID = '$GroupID'");
2013-07-10 00:08:53 +00:00
if ($DB->has_results()) {
2012-10-11 08:00:15 +00:00
$CollageIDs = $DB->collect('CollageID');
2013-06-06 08:01:03 +00:00
$DB->query("
UPDATE collages
2013-07-05 08:00:39 +00:00
SET NumTorrents = NumTorrents - 1
2013-06-18 08:00:48 +00:00
WHERE ID IN (".implode(', ', $CollageIDs).')');
2013-06-06 08:01:03 +00:00
$DB->query("
DELETE FROM collages_torrents
2013-07-05 08:00:39 +00:00
WHERE GroupID = '$GroupID'");
2012-10-11 08:00:15 +00:00
foreach ($CollageIDs as $CollageID) {
2013-07-05 08:00:39 +00:00
$Cache->delete_value("collage_$CollageID");
2012-10-11 08:00:15 +00:00
}
2013-07-05 08:00:39 +00:00
$Cache->delete_value("torrent_collages_$GroupID");
2012-10-11 08:00:15 +00:00
}
// Artists
// Collect the artist IDs and then wipe the torrents_artist entry
2013-06-06 08:01:03 +00:00
$DB->query("
SELECT ArtistID
FROM torrents_artists
2013-07-05 08:00:39 +00:00
WHERE GroupID = $GroupID");
2012-10-11 08:00:15 +00:00
$Artists = $DB->collect('ArtistID');
2013-06-06 08:01:03 +00:00
$DB->query("
DELETE FROM torrents_artists
2013-07-05 08:00:39 +00:00
WHERE GroupID = '$GroupID'");
2012-10-11 08:00:15 +00:00
foreach ($Artists as $ArtistID) {
2013-05-16 08:00:10 +00:00
if (empty($ArtistID)) {
continue;
}
2012-10-11 08:00:15 +00:00
// Get a count of how many groups or requests use the artist ID
2013-05-16 08:00:10 +00:00
$DB->query("
SELECT COUNT(ag.ArtistID)
FROM artists_group as ag
2013-07-05 08:00:39 +00:00
LEFT JOIN requests_artists AS ra ON ag.ArtistID = ra.ArtistID
2013-05-16 08:00:10 +00:00
WHERE ra.ArtistID IS NOT NULL
AND ag.ArtistID = '$ArtistID'");
2012-10-11 08:00:15 +00:00
list($ReqCount) = $DB->next_record();
2013-05-16 08:00:10 +00:00
$DB->query("
SELECT COUNT(ag.ArtistID)
FROM artists_group as ag
2013-07-05 08:00:39 +00:00
LEFT JOIN torrents_artists AS ta ON ag.ArtistID = ta.ArtistID
2013-05-16 08:00:10 +00:00
WHERE ta.ArtistID IS NOT NULL
AND ag.ArtistID = '$ArtistID'");
2012-10-11 08:00:15 +00:00
list($GroupCount) = $DB->next_record();
if (($ReqCount + $GroupCount) == 0) {
//The only group to use this artist
Artists::delete_artist($ArtistID);
} else {
//Not the only group, still need to clear cache
2013-07-05 08:00:39 +00:00
$Cache->delete_value("artist_groups_$ArtistID");
2012-10-11 08:00:15 +00:00
}
}
// Requests
2013-06-06 08:01:03 +00:00
$DB->query("
SELECT ID
FROM requests
2013-07-05 08:00:39 +00:00
WHERE GroupID = '$GroupID'");
2012-10-11 08:00:15 +00:00
$Requests = $DB->collect('ID');
2013-06-06 08:01:03 +00:00
$DB->query("
UPDATE requests
SET GroupID = NULL
WHERE GroupID = '$GroupID'");
2012-10-11 08:00:15 +00:00
foreach ($Requests as $RequestID) {
2013-07-05 08:00:39 +00:00
$Cache->delete_value("request_$RequestID");
2012-10-11 08:00:15 +00:00
}
2013-07-05 08:00:39 +00:00
$DB->query("
DELETE FROM torrents_group
WHERE ID = '$GroupID'");
$DB->query("
DELETE FROM torrents_tags
WHERE GroupID = '$GroupID'");
$DB->query("
DELETE FROM torrents_tags_votes
WHERE GroupID = '$GroupID'");
$DB->query("
DELETE FROM torrents_comments
WHERE GroupID = '$GroupID'");
$DB->query("
DELETE FROM bookmarks_torrents
WHERE GroupID = '$GroupID'");
$DB->query("
DELETE FROM wiki_torrents
WHERE PageID = '$GroupID'");
2012-10-11 08:00:15 +00:00
2013-07-05 08:00:39 +00:00
$Cache->delete_value("torrents_details_$GroupID");
$Cache->delete_value("torrent_group_$GroupID");
$Cache->delete_value("groups_artists_$GroupID");
2012-10-11 08:00:15 +00:00
}
/**
2013-07-05 08:00:39 +00:00
* Update the cache and sphinx delta index to keep everything up-to-date.
2012-10-11 08:00:15 +00:00
*
* @param int $GroupID
*/
public static function update_hash($GroupID) {
global $DB, $Cache;
2013-05-16 08:00:10 +00:00
$DB->query("
UPDATE torrents_group
2013-07-05 08:00:39 +00:00
SET TagList = (
SELECT REPLACE(GROUP_CONCAT(tags.Name SEPARATOR ' '), '.', '_')
2013-05-16 08:00:10 +00:00
FROM torrents_tags AS t
2013-07-05 08:00:39 +00:00
INNER JOIN tags ON tags.ID = t.TagID
WHERE t.GroupID = '$GroupID'
2013-05-16 08:00:10 +00:00
GROUP BY t.GroupID
)
2013-07-05 08:00:39 +00:00
WHERE ID = '$GroupID'");
2012-10-11 08:00:15 +00:00
2012-11-03 08:00:19 +00:00
// Fetch album vote score
2013-06-06 08:01:03 +00:00
$DB->query("
SELECT Score
FROM torrents_votes
2013-07-05 08:00:39 +00:00
WHERE GroupID = $GroupID");
2013-07-10 00:08:53 +00:00
if ($DB->has_results()) {
2012-11-03 08:00:19 +00:00
list($VoteScore) = $DB->next_record();
} else {
$VoteScore = 0;
}
// Fetch album artists
2013-05-16 08:00:10 +00:00
$DB->query("
SELECT GROUP_CONCAT(aa.Name separator ' ')
2012-11-03 08:00:19 +00:00
FROM torrents_artists AS ta
2013-07-05 08:00:39 +00:00
JOIN artists_alias AS aa ON aa.AliasID = ta.AliasID
WHERE ta.GroupID = $GroupID
2013-05-16 08:00:10 +00:00
AND ta.Importance IN ('1', '4', '5', '6')
2012-11-03 08:00:19 +00:00
GROUP BY ta.GroupID");
2013-07-10 00:08:53 +00:00
if ($DB->has_results()) {
2012-11-03 08:00:19 +00:00
list($ArtistName) = $DB->next_record(MYSQLI_NUM, false);
} else {
$ArtistName = '';
}
2013-05-16 08:00:10 +00:00
$DB->query("
REPLACE INTO sphinx_delta
2012-11-01 08:00:21 +00:00
(ID, GroupID, GroupName, TagList, Year, CategoryID, Time, ReleaseType, RecordLabel,
2012-11-03 08:00:19 +00:00
CatalogueNumber, VanityHouse, Size, Snatched, Seeders, Leechers, LogScore, Scene,
HasLog, HasCue, FreeTorrent, Media, Format, Encoding, RemasterYear, RemasterTitle,
RemasterRecordLabel, RemasterCatalogueNumber, FileList, VoteScore, ArtistName)
2012-10-11 08:00:15 +00:00
SELECT
2012-11-01 08:00:21 +00:00
t.ID, g.ID, Name, TagList, Year, CategoryID, UNIX_TIMESTAMP(t.Time), ReleaseType,
RecordLabel, CatalogueNumber, VanityHouse, Size >> 10 AS Size, Snatched, Seeders,
Leechers, LogScore, CAST(Scene AS CHAR), CAST(HasLog AS CHAR), CAST(HasCue AS CHAR),
CAST(FreeTorrent AS CHAR), Media, Format, Encoding,
RemasterYear, RemasterTitle, RemasterRecordLabel, RemasterCatalogueNumber,
2013-02-23 08:00:22 +00:00
REPLACE(FileList, '_', ' ') AS FileList, $VoteScore, '".db_string($ArtistName)."'
2012-10-11 08:00:15 +00:00
FROM torrents AS t
2013-07-05 08:00:39 +00:00
JOIN torrents_group AS g ON g.ID = t.GroupID
WHERE g.ID = $GroupID");
2012-10-11 08:00:15 +00:00
2013-05-16 08:00:10 +00:00
/* $DB->query("
INSERT INTO sphinx_delta
(ID, ArtistName)
SELECT torrents.ID, artists.ArtistName
FROM (
2012-11-01 08:00:21 +00:00
SELECT
2013-05-16 08:00:10 +00:00
GroupID,
GROUP_CONCAT(aa.Name separator ' ') AS ArtistName
2012-11-01 08:00:21 +00:00
FROM torrents_artists AS ta
2013-07-05 08:00:39 +00:00
JOIN artists_alias AS aa ON aa.AliasID = ta.AliasID
WHERE ta.GroupID = $GroupID
2013-05-16 08:00:10 +00:00
AND ta.Importance IN ('1', '4', '5', '6')
2012-11-01 08:00:21 +00:00
GROUP BY ta.GroupID
) AS artists
2013-05-16 08:00:10 +00:00
JOIN torrents USING(GroupID)
2013-07-05 08:00:39 +00:00
ON DUPLICATE KEY UPDATE ArtistName = VALUES(ArtistName)");
2012-11-03 08:00:19 +00:00
*/
2013-07-05 08:00:39 +00:00
$Cache->delete_value("torrents_details_$GroupID");
$Cache->delete_value("torrent_group_$GroupID");
2012-10-11 08:00:15 +00:00
$ArtistInfo = Artists::get_artist($GroupID);
foreach ($ArtistInfo as $Importances => $Importance) {
foreach ($Importance as $Artist) {
2012-11-20 08:00:19 +00:00
$Cache->delete_value('artist_groups_'.$Artist['id']); //Needed for at least freeleech change, if not others.
2012-10-11 08:00:15 +00:00
}
}
2013-07-05 08:00:39 +00:00
$Cache->delete_value("groups_artists_$GroupID");
2012-10-11 08:00:15 +00:00
}
2013-02-11 08:00:34 +00:00
/**
2013-07-05 08:00:39 +00:00
* Regenerate a torrent's file list from its meta data,
2013-02-11 08:00:34 +00:00
* update the database record and clear relevant cache keys
*
* @param int $TorrentID
*/
public static function regenerate_filelist($TorrentID) {
global $DB, $Cache;
2013-05-01 08:00:16 +00:00
$DB->query("
SELECT tg.ID,
2013-02-11 08:00:34 +00:00
tf.File
FROM torrents_files AS tf
2013-07-05 08:00:39 +00:00
JOIN torrents AS t ON t.ID = tf.TorrentID
JOIN torrents_group AS tg ON tg.ID = t.GroupID
WHERE tf.TorrentID = $TorrentID");
2013-07-10 00:08:53 +00:00
if ($DB->has_results()) {
2013-02-11 08:00:34 +00:00
list($GroupID, $Contents) = $DB->next_record(MYSQLI_NUM, false);
2013-02-25 21:16:55 +00:00
if (Misc::is_new_torrent($Contents)) {
2013-03-17 08:00:17 +00:00
$Tor = new BencodeTorrent($Contents);
2013-05-16 08:00:10 +00:00
$FilePath = (isset($Tor->Dec['info']['files']) ? Format::make_utf8($Tor->get_name()) : '');
2013-02-25 21:16:55 +00:00
} else {
$Tor = new TORRENT(unserialize(base64_decode($Contents)), true);
2013-05-16 08:00:10 +00:00
$FilePath = (isset($Tor->Val['info']->Val['files']) ? Format::make_utf8($Tor->get_name()) : '');
2013-02-25 21:16:55 +00:00
}
2013-02-11 08:00:34 +00:00
list($TotalSize, $FileList) = $Tor->file_list();
2013-05-01 08:00:16 +00:00
foreach ($FileList as $File) {
2013-02-11 08:00:34 +00:00
$TmpFileList[] = self::filelist_format_file($File);
}
2013-02-15 08:00:35 +00:00
$FileString = implode("\n", $TmpFileList);
2013-05-16 08:00:10 +00:00
$DB->query("
UPDATE torrents
SET Size = $TotalSize, FilePath = '".db_string($FilePath)."', FileList = '".db_string($FileString)."'
WHERE ID = $TorrentID");
2013-07-05 08:00:39 +00:00
$Cache->delete_value("torrents_details_$GroupID");
2013-02-11 08:00:34 +00:00
}
}
/**
* Return UTF-8 encoded string to use as file delimiter in torrent file lists
*/
public static function filelist_delim() {
static $FilelistDelimUTF8;
if (isset($FilelistDelimUTF8)) {
return $FilelistDelimUTF8;
}
return $FilelistDelimUTF8 = utf8_encode(chr(self::FilelistDelim));
}
/**
* Create a string that contains file info in a format that's easy to use for Sphinx
*
* @param array $File (File size, File name)
2013-02-25 08:00:45 +00:00
* @return string with the format .EXT sSIZEs NAME DELIMITER
2013-02-11 08:00:34 +00:00
*/
public static function filelist_format_file($File) {
list($Size, $Name) = $File;
2013-05-16 08:00:10 +00:00
$Name = Format::make_utf8(strtr($Name, "\n\r\t", ' '));
2013-02-11 08:00:34 +00:00
$ExtPos = strrpos($Name, '.');
2013-02-23 08:00:22 +00:00
// Should not be $ExtPos !== false. Extensionless files that start with a . should not get extensions
2013-05-16 08:00:10 +00:00
$Ext = ($ExtPos ? trim(substr($Name, $ExtPos + 1)) : '');
2013-02-15 08:00:35 +00:00
return sprintf("%s s%ds %s %s", ".$Ext", $Size, $Name, self::filelist_delim());
2013-02-11 08:00:34 +00:00
}
2013-02-25 08:00:45 +00:00
/**
* Create a string that contains file info in the old format for the API
*
* @param string $File string with the format .EXT sSIZEs NAME DELIMITER
* @return string with the format NAME{{{SIZE}}}
*/
public static function filelist_old_format($File) {
$File = self::filelist_get_file($File);
return $File['name'] . '{{{' . $File['size'] . '}}}';
}
2013-02-11 08:00:34 +00:00
/**
* Translate a formatted file info string into a more useful array structure
*
* @param string $File string with the format .EXT sSIZEs NAME DELIMITER
* @return file info array with the keys 'ext', 'size' and 'name'
*/
public static function filelist_get_file($File) {
// Need this hack because filelists are always display_str()ed
$DelimLen = strlen(display_str(self::filelist_delim())) + 1;
list($FileExt, $Size, $Name) = explode(' ', $File, 3);
if ($Spaces = strspn($Name, ' ')) {
$Name = str_replace(' ', '&nbsp;', substr($Name, 0, $Spaces)) . substr($Name, $Spaces);
}
2013-06-06 08:01:03 +00:00
return array(
'ext' => $FileExt,
'size' => substr($Size, 1, -1),
'name' => substr($Name, 0, -$DelimLen)
);
2013-02-11 08:00:34 +00:00
}
2012-10-11 08:00:15 +00:00
/**
* Format the information about a torrent.
* @param $Data an array a subset of the following keys:
* Format, Encoding, HasLog, LogScore HasCue, Media, Scene, RemasterYear
* RemasterTitle, FreeTorrent, PersonalFL
* @param boolean $ShowMedia if false, Media key will be omitted
* @param boolean $ShowEdition if false, RemasterYear/RemasterTitle will be omitted
*/
public static function torrent_info($Data, $ShowMedia = false, $ShowEdition = false) {
$Info = array();
2013-07-05 08:00:39 +00:00
if (!empty($Data['Format'])) {
$Info[] = $Data['Format'];
}
if (!empty($Data['Encoding'])) {
$Info[] = $Data['Encoding'];
}
2012-10-11 08:00:15 +00:00
if (!empty($Data['HasLog'])) {
$Str = 'Log';
if (!empty($Data['LogScore'])) {
2013-07-05 08:00:39 +00:00
$Str .= ' ('.$Data['LogScore'].'%)';
2012-10-11 08:00:15 +00:00
}
2013-05-16 08:00:10 +00:00
$Info[] = $Str;
2012-10-11 08:00:15 +00:00
}
2013-07-05 08:00:39 +00:00
if (!empty($Data['HasCue'])) {
$Info[] = 'Cue';
}
if ($ShowMedia && !empty($Data['Media'])) {
$Info[] = $Data['Media'];
}
if (!empty($Data['Scene'])) {
$Info[] = 'Scene';
}
2012-10-11 08:00:15 +00:00
if ($ShowEdition) {
$EditionInfo = array();
2013-07-05 08:00:39 +00:00
if (!empty($Data['RemasterYear'])) {
$EditionInfo[] = $Data['RemasterYear'];
}
if (!empty($Data['RemasterTitle'])) {
$EditionInfo[] = $Data['RemasterTitle'];
}
if (count($EditionInfo)) {
$Info[] = implode(' ', $EditionInfo);
}
}
if ($Data['IsSnatched']) {
$Info[] = Format::torrent_label('Snatched!');
}
if ($Data['FreeTorrent'] == '1') {
$Info[] = Format::torrent_label('Freeleech!');
}
if ($Data['FreeTorrent'] == '2') {
$Info[] = Format::torrent_label('Neutral Leech!');
}
if ($Data['PersonalFL']) {
$Info[] = Format::torrent_label('Personal Freeleech!');
}
2012-10-11 08:00:15 +00:00
return implode(' / ', $Info);
}
/**
2013-07-05 08:00:39 +00:00
* Will freeleech / neutral leech / normalise a set of torrents
2012-10-11 08:00:15 +00:00
*
2013-07-05 08:00:39 +00:00
* @param array $TorrentIDs An array of torrent IDs to iterate over
2012-10-11 08:00:15 +00:00
* @param int $FreeNeutral 0 = normal, 1 = fl, 2 = nl
* @param int $FreeLeechType 0 = Unknown, 1 = Staff picks, 2 = Perma-FL (Toolbox, etc.), 3 = Vanity House
*/
public static function freeleech_torrents($TorrentIDs, $FreeNeutral = 1, $FreeLeechType = 0) {
global $DB, $Cache, $LoggedUser;
if (!is_array($TorrentIDs)) {
$TorrentIDs = array($TorrentIDs);
}
2013-05-16 08:00:10 +00:00
$DB->query("
UPDATE torrents
SET FreeTorrent = '$FreeNeutral', FreeLeechType = '$FreeLeechType'
WHERE ID IN (".implode(', ', $TorrentIDs).')');
$DB->query('
SELECT ID, GroupID, info_hash
FROM torrents
2013-07-05 08:00:39 +00:00
WHERE ID IN ('.implode(', ', $TorrentIDs).')
ORDER BY GroupID ASC');
2012-10-11 08:00:15 +00:00
$Torrents = $DB->to_array(false, MYSQLI_NUM, false);
$GroupIDs = $DB->collect('GroupID');
foreach ($Torrents as $Torrent) {
list($TorrentID, $GroupID, $InfoHash) = $Torrent;
Tracker::update_tracker('update_torrent', array('info_hash' => rawurlencode($InfoHash), 'freetorrent' => $FreeNeutral));
2013-07-05 08:00:39 +00:00
$Cache->delete_value("torrent_download_$TorrentID");
2013-05-16 08:00:10 +00:00
Misc::write_log($LoggedUser['Username']." marked torrent $TorrentID freeleech type $FreeLeechType!");
Torrents::write_group_log($GroupID, $TorrentID, $LoggedUser['ID'], "marked as freeleech type $FreeLeechType!", 0);
2012-10-11 08:00:15 +00:00
}
foreach ($GroupIDs as $GroupID) {
Torrents::update_hash($GroupID);
}
}
2012-10-20 08:00:36 +00:00
2012-10-11 08:00:15 +00:00
/**
* Convenience function to allow for passing groups to Torrents::freeleech_torrents()
*
* @param array $GroupIDs the groups in question
* @param int $FreeNeutral see Torrents::freeleech_torrents()
* @param int $FreeLeechType see Torrents::freeleech_torrents()
*/
public static function freeleech_groups($GroupIDs, $FreeNeutral = 1, $FreeLeechType = 0) {
global $DB;
if (!is_array($GroupIDs)) {
$GroupIDs = array($GroupIDs);
}
2013-05-16 08:00:10 +00:00
$DB->query('
SELECT ID
FROM torrents
WHERE GroupID IN ('.implode(', ', $GroupIDs).')');
2013-07-10 00:08:53 +00:00
if ($DB->has_results()) {
2012-10-11 08:00:15 +00:00
$TorrentIDs = $DB->collect('ID');
Torrents::freeleech_torrents($TorrentIDs, $FreeNeutral, $FreeLeechType);
}
}
2012-10-28 08:00:19 +00:00
2012-10-16 08:00:18 +00:00
/**
* Check if the logged in user has an active freeleech token
*
* @param int $TorrentID
* @return true if an active token exists
*/
public static function has_token($TorrentID) {
global $DB, $Cache, $LoggedUser;
2012-10-28 08:00:19 +00:00
if (empty($LoggedUser)) {
2012-10-16 08:00:18 +00:00
return false;
}
static $TokenTorrents;
$UserID = $LoggedUser['ID'];
if (!isset($TokenTorrents)) {
2013-07-05 08:00:39 +00:00
$TokenTorrents = $Cache->get_value("users_tokens_$UserID");
2012-10-16 08:00:18 +00:00
if ($TokenTorrents === false) {
2013-05-16 08:00:10 +00:00
$DB->query("
SELECT TorrentID
FROM users_freeleeches
2013-07-05 08:00:39 +00:00
WHERE UserID = $UserID
AND Expired = 0");
2012-10-16 08:00:18 +00:00
$TokenTorrents = array_fill_keys($DB->collect('TorrentID', false), true);
2013-07-05 08:00:39 +00:00
$Cache->cache_value("users_tokens_$UserID", $TokenTorrents);
2012-10-16 08:00:18 +00:00
}
}
return isset($TokenTorrents[$TorrentID]);
}
2012-10-20 08:00:36 +00:00
/**
* Check if the logged in user can use a freeleech token on this torrent
*
* @param int $Torrent
2013-02-25 21:16:55 +00:00
* @return boolen True if user is allowed to use a token
2012-10-20 08:00:36 +00:00
*/
public static function can_use_token($Torrent) {
global $LoggedUser;
2012-10-28 08:00:19 +00:00
if (empty($LoggedUser)) {
2012-10-20 08:00:36 +00:00
return false;
}
return ($LoggedUser['FLTokens'] > 0
&& $Torrent['Size'] < 1073741824
&& !$Torrent['PersonalFL']
&& empty($Torrent['FreeTorrent'])
&& $LoggedUser['CanLeech'] == '1');
}
2012-10-28 08:00:19 +00:00
2013-02-22 08:00:24 +00:00
2013-02-28 08:00:29 +00:00
public static function has_snatched($TorrentID, $AllUsers = false) {
2012-10-27 08:00:09 +00:00
global $DB, $Cache, $LoggedUser;
2013-02-28 08:00:29 +00:00
if (!$AllUsers && (empty($LoggedUser) || !$LoggedUser['ShowSnatched'])) {
2012-10-28 08:00:19 +00:00
return false;
2012-10-27 08:00:09 +00:00
}
2012-10-28 08:00:19 +00:00
$UserID = $LoggedUser['ID'];
$Buckets = 64;
$LastBucket = $Buckets - 1;
$BucketID = $TorrentID & $LastBucket;
static $SnatchedTorrents = array(), $LastUpdate = 0;
if (empty($SnatchedTorrents)) {
$SnatchedTorrents = array_fill(0, $Buckets, false);
2013-07-05 08:00:39 +00:00
$LastUpdate = $Cache->get_value("users_snatched_{$UserID}_lastupdate") ?: 0;
2013-04-15 08:00:54 +00:00
} elseif (isset($SnatchedTorrents[$BucketID][$TorrentID])) {
2012-10-28 08:00:19 +00:00
return true;
2012-10-27 08:00:09 +00:00
}
2012-10-28 08:00:19 +00:00
// Torrent was not found in the previously inspected snatch lists
$CurSnatchedTorrents =& $SnatchedTorrents[$BucketID];
2012-11-06 08:00:20 +00:00
if ($CurSnatchedTorrents === false) {
2012-10-28 08:00:19 +00:00
$CurTime = time();
// This bucket hasn't been checked before
2013-07-05 08:00:39 +00:00
$CurSnatchedTorrents = $Cache->get_value("users_snatched_{$UserID}_$BucketID", true);
2012-10-28 08:00:19 +00:00
if ($CurSnatchedTorrents === false || $CurTime - $LastUpdate > 1800) {
2012-10-30 08:00:18 +00:00
$Updated = array();
if ($CurSnatchedTorrents === false || $LastUpdate == 0) {
for ($i = 0; $i < $Buckets; $i++) {
$SnatchedTorrents[$i] = array();
}
2012-10-28 08:00:19 +00:00
// Not found in cache. Since we don't have a suitable index, it's faster to update everything
2013-06-06 08:01:03 +00:00
$DB->query("
SELECT fid, tstamp AS TorrentID
FROM xbt_snatched
WHERE uid = '$UserID'");
2012-10-30 08:00:18 +00:00
while (list($ID) = $DB->next_record(MYSQLI_NUM, false)) {
$SnatchedTorrents[$ID & $LastBucket][(int)$ID] = true;
}
$Updated = array_fill(0, $Buckets, true);
2012-10-28 08:00:19 +00:00
} elseif (isset($CurSnatchedTorrents[$TorrentID])) {
// Old cache, but torrent is snatched, so no need to update
return true;
} else {
// Old cache, check if torrent has been snatched recently
2013-06-06 08:01:03 +00:00
$DB->query("
SELECT fid
FROM xbt_snatched
WHERE uid = '$UserID'
AND tstamp >= $LastUpdate");
2012-10-30 08:00:18 +00:00
while (list($ID) = $DB->next_record(MYSQLI_NUM, false)) {
$CurBucketID = $ID & $LastBucket;
2012-10-28 08:00:19 +00:00
if ($SnatchedTorrents[$CurBucketID] === false) {
2013-07-05 08:00:39 +00:00
$SnatchedTorrents[$CurBucketID] = $Cache->get_value("users_snatched_{$UserID}_$CurBucketID", true);
2012-10-30 08:00:18 +00:00
if ($SnatchedTorrents[$CurBucketID] === false) {
$SnatchedTorrents[$CurBucketID] = array();
}
2012-10-28 08:00:19 +00:00
}
2012-10-30 08:00:18 +00:00
$SnatchedTorrents[$CurBucketID][(int)$ID] = true;
$Updated[$CurBucketID] = true;
2012-10-28 08:00:19 +00:00
}
}
for ($i = 0; $i < $Buckets; $i++) {
if ($Updated[$i]) {
2013-07-05 08:00:39 +00:00
$Cache->cache_value("users_snatched_{$UserID}_$i", $SnatchedTorrents[$i], 0);
2012-10-28 08:00:19 +00:00
}
}
2013-07-05 08:00:39 +00:00
$Cache->cache_value("users_snatched_{$UserID}_lastupdate", $CurTime, 0);
2012-10-29 08:00:20 +00:00
$LastUpdate = $CurTime;
2012-10-28 08:00:19 +00:00
}
}
return isset($CurSnatchedTorrents[$TorrentID]);
2012-10-27 08:00:09 +00:00
}
2013-04-02 08:00:31 +00:00
2013-03-17 08:00:17 +00:00
public static function edition_string(array $Torrent, array $Group) {
if ($Torrent['Remastered'] && $Torrent['RemasterYear'] != 0) {
$EditionName = $Torrent['RemasterYear'];
2013-04-13 08:00:19 +00:00
$AddExtra = ' - ';
if ($Torrent['RemasterRecordLabel']) {
$EditionName .= $AddExtra . display_str($Torrent['RemasterRecordLabel']);
$AddExtra = ' / ';
}
if ($Torrent['RemasterCatalogueNumber']) {
$EditionName .= $AddExtra . display_str($Torrent['RemasterCatalogueNumber']);
$AddExtra = ' / ';
}
if ($Torrent['RemasterTitle']) {
$EditionName .= $AddExtra . display_str($Torrent['RemasterTitle']);
$AddExtra = ' / ';
}
2013-03-17 08:00:17 +00:00
$EditionName .= $AddExtra . display_str($Torrent['Media']);
} else {
2013-07-05 08:00:39 +00:00
$AddExtra = ' / ';
2013-04-13 08:00:19 +00:00
if (!$Torrent['Remastered']) {
2013-07-05 08:00:39 +00:00
$EditionName = 'Original Release';
2013-04-13 08:00:19 +00:00
if ($Group['RecordLabel']) {
$EditionName .= $AddExtra . $Group['RecordLabel'];
$AddExtra = ' / ';
}
if ($Group['CatalogueNumber']) {
$EditionName .= $AddExtra . $Group['CatalogueNumber'];
$AddExtra = ' / ';
}
2013-03-17 08:00:17 +00:00
} else {
2013-05-16 08:00:10 +00:00
$EditionName = 'Unknown Release(s)';
2013-03-17 08:00:17 +00:00
}
$EditionName .= $AddExtra . display_str($Torrent['Media']);
}
return $EditionName;
}
2012-10-11 08:00:15 +00:00
}
?>