mirror of
https://github.com/NNTmux/newznab-tmux.git
synced 2026-08-28 17:01:16 +00:00
1004 lines
30 KiB
PHP
1004 lines
30 KiB
PHP
<?php
|
|
require_once NN_LIBS . 'rarinfo/par2info.php';
|
|
require_once NN_LIBS . 'rarinfo/archiveinfo.php';
|
|
|
|
use newznab\db\Settings;
|
|
use newznab\utility\Utility;
|
|
|
|
/**
|
|
* This class handles all post processing performed during update_releases process.
|
|
*/
|
|
class PostProcess
|
|
{
|
|
|
|
/**
|
|
* @var newznab\db\Settings
|
|
*/
|
|
public $pdo;
|
|
|
|
/**
|
|
* @var bool
|
|
*/
|
|
public $echooutput;
|
|
|
|
/**
|
|
* Default constructor.
|
|
*
|
|
* @param bool $echooutput
|
|
*/
|
|
public function __construct($echooutput = false)
|
|
{
|
|
$this->echooutput = (NN_ECHOCLI && $echooutput);;
|
|
$s = new \Sites();
|
|
$this->site = $s->get();
|
|
$this->pdo = new Settings();
|
|
$this->mediafileregex = 'AVI|VOB|MKV|MP4|TS|WMV|MOV|M4V|F4V|MPG|MPEG|M2TS';
|
|
$this->audiofileregex = 'MP3|AAC|OGG';
|
|
$this->mp3SavePath = WWW_DIR.'covers/audio/';
|
|
}
|
|
|
|
/**
|
|
* Perform all post processing.
|
|
*/
|
|
public function processAll()
|
|
{
|
|
$this->processAdditional();
|
|
$this->processNfos();
|
|
$this->processSpotNab();
|
|
$this->processUnwanted();
|
|
$this->processMovies();
|
|
$this->processMusic();
|
|
$this->processBooks();
|
|
$this->processGames();
|
|
$this->processTv();
|
|
$this->processMusicFromMediaInfo();
|
|
$this->processOtherMiscCategory();
|
|
$this->processUnknownCategory();
|
|
}
|
|
|
|
public function processUnwanted()
|
|
{
|
|
$r = new Releases;
|
|
$currTime_ori = $this->pdo->queryOneRow("SELECT NOW() as now");
|
|
|
|
//
|
|
// Delete any passworded releases
|
|
//
|
|
if($this->pdo->getSetting('deletepasswordedrelease') == 1)
|
|
{
|
|
echo "PostPrc : Removing unwanted releases\n";
|
|
$result = $this->pdo->query("select id from releases where passwordstatus > 0");
|
|
foreach ($result as $row)
|
|
$r->delete($row["id"]);
|
|
}
|
|
|
|
//
|
|
// Delete any releases which are older than site's release retention days
|
|
//
|
|
if($this->pdo->getSetting('releaseretentiondays') != 0)
|
|
{
|
|
echo "PostPrc : Deleting releases older than ".$this->pdo->getSetting('releaseretentiondays')." days\n";
|
|
|
|
$result = $this->pdo->query(sprintf("select id from releases where postdate < %s - interval %d day", $this->pdo->escapeString($currTime_ori["now"]), $this->pdo->getSetting('releaseretentiondays')));
|
|
foreach ($result as $row)
|
|
$r->delete($row["id"]);
|
|
}
|
|
|
|
//
|
|
// Delete any audiopreviews older than site->audiopreviewprune days
|
|
//
|
|
if($this->pdo->getSetting('audiopreviewprune') > 0)
|
|
{
|
|
$result = $this->pdo->query(sprintf("select guid from releases where categoryid in (select id from category where parentid = ".Category::CAT_PARENT_MUSIC.") and haspreview = 2 and adddate < %s - interval %d day", $this->pdo->escapeString($currTime_ori["now"]), $this->pdo->getSetting('audiopreviewprune')));
|
|
|
|
if (sizeof($result) > 0)
|
|
{
|
|
echo "PostPrc : Deleting ".count($result)." audio previews older than ".$this->pdo->getSetting('audiopreviewprune')." days\n";
|
|
foreach ($result as $row)
|
|
{
|
|
$r->updateHasPreview($row["guid"], 0);
|
|
$this->deleteAudioSample($row["guid"]);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Delete any releases suspected of being spam/virus
|
|
//
|
|
if($this->pdo->getSetting('removespam') != 0)
|
|
{
|
|
$spamIDs = array();
|
|
|
|
//
|
|
// all releases where the only file inside the rars is *.exe and they are not in the PC category
|
|
//
|
|
$sql = "select releasefiles.releaseid as id from releasefiles inner join ( select releaseid, count(*) as totnum from releasefiles group by releaseid ) x on x.releaseid = releasefiles.releaseid and x.totnum = 1 inner join releases on releases.id = releasefiles.releaseid left join releasenfo on releasenfo.releaseid = releases.id where (releasefiles.name like '%.exe' or releasefiles.name like '%.scr') and (releases.categoryid not in (select id from category where parentid = ".Category::CAT_PARENT_PC.") or (releases.categoryid in (select id from category where parentid = ".Category::CAT_PARENT_PC.") and releasenfo.id is null)) group by releasefiles.releaseid";
|
|
$result = $this->pdo->query($sql);
|
|
$spamIDs = array_merge($result, $spamIDs);
|
|
|
|
//
|
|
// all releases containing exe not in permitted categories
|
|
//
|
|
if ($this->pdo->getSetting('exepermittedcategories') != '')
|
|
{
|
|
$sql = sprintf("select releasefiles.releaseid as id from releasefiles inner join releases on releases.id = releasefiles.releaseid left join releasenfo on releasenfo.releaseid = releases.id where releasefiles.name like '%%.exe' and releases.categoryid not in (%s) group by releasefiles.releaseid", $this->pdo->getSetting('exepermittedcategories'));
|
|
$result = $this->pdo->query($sql);
|
|
$spamIDs = array_merge($result, $spamIDs);
|
|
}
|
|
|
|
//
|
|
// delete all releases which contain a file with password.url in it
|
|
//
|
|
$sql = "select distinct releasefiles.releaseid as id from releasefiles where name = 'password.url'";
|
|
$result = $this->pdo->query($sql);
|
|
$spamIDs = array_merge($result, $spamIDs);
|
|
|
|
//
|
|
// all releases where the only file inside the rars is *.rar
|
|
//
|
|
$sql = "select releasefiles.releaseid as id from releasefiles inner join ( select releaseid, count(*) as totnum from releasefiles group by releaseid ) x on x.releaseid = releasefiles.releaseid and x.totnum = 1 inner join releases on releases.id = releasefiles.releaseid where releasefiles.name like '%.rar' group by releasefiles.releaseid";
|
|
$result = $this->pdo->query($sql);
|
|
$spamIDs = array_merge($result, $spamIDs);
|
|
|
|
//
|
|
// all audio which contains a file with .exe in
|
|
//
|
|
$sql = "select distinct r.id from releasefiles rf inner join releases r on r.id = rf.releaseid and r.categoryid in (select id from category where parentid = ".Category::CAT_PARENT_MUSIC.") where (rf.name like '%.exe' or rf.name like '%.bin')";
|
|
$result = $this->pdo->query($sql);
|
|
$spamIDs = array_merge($result, $spamIDs);
|
|
|
|
if (count($spamIDs) > 0)
|
|
{
|
|
echo "PostPrc : Deleting ".count($spamIDs)." spam releases\n" ;
|
|
foreach ($spamIDs as $row)
|
|
$r->delete($row["id"]);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Process nfo files
|
|
*/
|
|
public function processNfos()
|
|
{
|
|
if ($this->pdo->getSetting('lookupnfo') == 1)
|
|
{
|
|
$nfo = new Nfo($this->echooutput);
|
|
$nfo->processNfoFiles(500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Process Global IDs
|
|
*/
|
|
public function processSpotNab()
|
|
{
|
|
$spotnab = new SpotNab();
|
|
$processed = $spotnab->processGID(500);
|
|
if ($processed > 0)
|
|
printf("PostPrc : Updating GID in releases table %d release(s) updated\n", $processed);
|
|
$spotnab->auto_post_discovery();
|
|
$spotnab->fetch_discovery();
|
|
$spotnab->fetch();
|
|
$spotnab->post();
|
|
$spotnab->auto_clean();
|
|
}
|
|
|
|
/**
|
|
* Lookup imdb if enabled
|
|
*/
|
|
public function processMovies()
|
|
{
|
|
if ($this->pdo->getSetting('lookupimdb') == 1)
|
|
{
|
|
$movie = new Movie($this->echooutput);
|
|
$movie->processMovieReleases();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Lookup music if enabled
|
|
*/
|
|
public function processMusic()
|
|
{
|
|
if ($this->pdo->getSetting('lookupmusic') == 1)
|
|
{
|
|
$music = new Music($this->echooutput);
|
|
$music->processMusicReleases();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Lookup book if enabled
|
|
*/
|
|
public function processBooks()
|
|
{
|
|
if ($this->pdo->getSetting('lookupbooks') == 1)
|
|
{
|
|
$book = new Book($this->echooutput);
|
|
$book->processBookReleases();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Lookup games if enabled
|
|
*/
|
|
public function processGames()
|
|
{
|
|
if ($this->pdo->getSetting('lookupgames') == 1)
|
|
{
|
|
$console = new Console($this->echooutput);
|
|
$console->processConsoleReleases();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Work out any categories which were not assigned by regex or determinecategory
|
|
* Done in post process as releasevideo/audio will have been performed by now.
|
|
*/
|
|
public function processUnknownCategory()
|
|
{
|
|
$sql = sprintf("select id from releases where categoryid = %d", Category::CAT_NOT_DETERMINED);
|
|
$result = $this->pdo->query($sql);
|
|
$rescount = sizeof($result);
|
|
if ($rescount > 0)
|
|
{
|
|
echo "PostPrc : Attempting to fix ".$rescount." uncategorised release(s)\n";
|
|
|
|
$sql = sprintf("update releases inner join releasevideo rv on rv.releaseid = releases.id set releases.categoryid = %d where imdbid is not null and categoryid = %d and videocodec = 'XVID'", Category::CAT_MOVIE_SD, Category::CAT_NOT_DETERMINED);
|
|
$this->pdo->queryExec($sql);
|
|
|
|
$sql = sprintf("update releases inner join releasevideo rv on rv.releaseid = releases.id set releases.categoryid = %d where imdbid is not null and categoryid = %d and videocodec = 'V_MPEG4/ISO/AVC'", Category::CAT_MOVIE_HD, Category::CAT_NOT_DETERMINED);
|
|
$this->pdo->queryExec($sql);
|
|
|
|
$sql = sprintf("update releases set categoryid = %d where categoryid = %d", Category::CAT_MISC_OTHER, Category::CAT_NOT_DETERMINED);
|
|
$this->pdo->queryExec($sql);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Process all TV related releases which will assign their series/episode/rage data
|
|
*/
|
|
public function processTv()
|
|
{
|
|
if ($this->pdo->getSetting('lookupanidb') == 1)
|
|
{
|
|
$anidb = new AniDB($this->echooutput);
|
|
$anidb->animetitlesUpdate();
|
|
$anidb->processAnimeReleases();
|
|
}
|
|
|
|
if ($this->pdo->getSetting('lookuptvrage') == 1)
|
|
{
|
|
$tvrage = new TVRage($this->echooutput);
|
|
$tvrage->processTvReleases(($this->pdo->getSetting('lookuptvrage') ==1));
|
|
}
|
|
|
|
if ($this->pdo->getSetting('lookupthetvdb') == 1)
|
|
{
|
|
$thetvdb = new TheTVDB($this->echooutput);
|
|
$thetvdb->processReleases();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Process releases without a proper name
|
|
*/
|
|
public function processOtherMiscCategory()
|
|
{
|
|
$p = null;
|
|
if($this->pdo->getSetting('updatecleanup') == 1)
|
|
{
|
|
$p = new Parsing(false, true, false);
|
|
$p->cleanup();
|
|
}
|
|
|
|
if($this->pdo->getSetting('updateparsing') == 1)
|
|
{
|
|
if ($p == null)
|
|
$p = new Parsing(false, true, false);
|
|
$p->process();
|
|
}
|
|
|
|
if($this->pdo->getSetting('removespecial') == 1)
|
|
{
|
|
if ($p == null)
|
|
$p = new Parsing(false, true, false);
|
|
$p->removeSpecial();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check for passworded releases, RAR contents and Sample/Media info
|
|
*/
|
|
public function processAdditional($numtoProcess = 100)
|
|
{
|
|
|
|
$maxattemptstocheckpassworded = 5;
|
|
$processVideoSample = ($this->pdo->getSetting('ffmpegpath') != '') ? true : false;
|
|
$processMediainfo = ($this->pdo->getSetting('mediainfopath') != '') ? true : false;
|
|
$processPasswords = ($this->pdo->getSetting('unrarpath') != '') ? true : false;
|
|
$processAudioSample = ($this->pdo->getSetting('saveaudiopreview') == 1) ? true : false;
|
|
|
|
$tmpPath = $this->pdo->getSetting('tmpunrarpath');
|
|
if (substr($tmpPath, -strlen( '/' ) ) != '/')
|
|
{
|
|
$tmpPath = $tmpPath.'/';
|
|
}
|
|
|
|
if (!file_exists($tmpPath))
|
|
mkdir($tmpPath, 0766, true);
|
|
|
|
$nntp = new NNTP;
|
|
$nzb = new NZB;
|
|
|
|
//
|
|
// Get out all releases which have not been checked more than max attempts for password.
|
|
//
|
|
$sql = sprintf("select r.id, r.guid, r.name, c.disablepreview from releases r
|
|
left join category c on c.id = r.categoryid
|
|
where (r.passwordstatus between %d and -1)
|
|
or (r.haspreview = -1 and c.disablepreview = 0) order by r.postdate desc limit %d ", ($maxattemptstocheckpassworded + 1) * -1, $numtoProcess);
|
|
$result = $this->pdo->query($sql);
|
|
|
|
$iteration = $rescount = sizeof($result);
|
|
if ($rescount > 0)
|
|
{
|
|
echo "PostPrc : Performing additional post processing on last ".$rescount." releases ...";
|
|
$nntpconnected = false;
|
|
|
|
foreach ($result as $rel)
|
|
{
|
|
echo $iteration--.".";
|
|
|
|
// Per release defaults
|
|
$passStatus = array(Releases::PASSWD_NONE);
|
|
$blnTookMediainfo = false;
|
|
$blnTookSample = ($rel['disablepreview'] == 1) ? true : false; //only attempt sample if not disabled
|
|
|
|
if ($blnTookSample)
|
|
$this->pdo->queryExec(sprintf("update releases set haspreview = 0 where id = %d", $rel['id']));
|
|
|
|
//
|
|
// Go through the binaries for this release looking for a rar, a sample, and a mediafile
|
|
//
|
|
$nzbInfo = new nzbInfo;
|
|
$norar = 0;
|
|
|
|
// only load nzbs and check for rar files if we are doing something with them.
|
|
if ($processVideoSample || $processMediainfo || $processPasswords || $processAudioSample)
|
|
{
|
|
$nzbfile = $nzb->NZBPath($rel['guid'], $this->pdo->getSetting('nzbpath'));
|
|
if (!$nzbInfo->loadFromFile($nzbfile))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
foreach($nzbInfo->nzb as $nzbsubject)
|
|
{
|
|
if (preg_match("/\w\.r00/i", $nzbsubject['subject']))
|
|
$norar= 1;
|
|
}
|
|
}
|
|
|
|
// attempt to process video sample file
|
|
if(!empty($nzbInfo->samplefiles) && $processVideoSample && $blnTookSample === false)
|
|
{
|
|
$sampleFile = $nzbInfo->samplefiles[0]; //first detected sample
|
|
$sampleMsgids = array_slice($sampleFile['segments'], 0, 1); //get first segment, increase to get more of the sample
|
|
$sampleGroup = $sampleFile['groups'][0];
|
|
|
|
//echo "PostPrc : Fetching ".implode($sampleMsgids, ', ')." from {$sampleGroup}\n";
|
|
if (!$nntpconnected)
|
|
$nntpconnected = $nntp->doConnect();
|
|
|
|
$sampleBinary = $nntp->getMessages($sampleGroup, $sampleMsgids);
|
|
if ($sampleBinary === false)
|
|
echo "\nPostPrc : Couldnt fetch sample\n";
|
|
else
|
|
{
|
|
$samplefile = $tmpPath.'sample.avi';
|
|
|
|
file_put_contents($samplefile, $sampleBinary);
|
|
|
|
$blnTookSample = $this->getSample($tmpPath, $this->pdo->getSetting('ffmpegpath'), $rel['guid']);
|
|
if ($blnTookSample)
|
|
$this->updateReleaseHasPreview($rel['guid']);
|
|
|
|
unlink($samplefile);
|
|
}
|
|
unset($sampleBinary);
|
|
}
|
|
|
|
// attempt to process loose media file
|
|
if(!empty($nzbInfo->mediafiles) && (($processVideoSample && $blnTookSample === false) || $processMediainfo))
|
|
{
|
|
$mediaFile = $nzbInfo->mediafiles[0]; //first detected media file
|
|
$mediaMsgids = array_slice($mediaFile['segments'], 0, 2); //get first two segments
|
|
$mediaGroup = $mediaFile['groups'][0];
|
|
|
|
//echo "PostPrc : Fetching ".implode($mediaMsgids, ', ')." from {$mediaGroup}\n";
|
|
if (!$nntpconnected)
|
|
$nntpconnected = $nntp->doConnect();
|
|
|
|
$mediaBinary = $nntp->getMessages($mediaGroup, $mediaMsgids);
|
|
if ($mediaBinary === false)
|
|
echo "\nPostPrc : Couldnt fetch media file\n";
|
|
else
|
|
{
|
|
$mediafile = $tmpPath.'sample.avi';
|
|
|
|
file_put_contents($mediafile, $mediaBinary);
|
|
|
|
if ($processVideoSample && $blnTookSample === false)
|
|
{
|
|
$blnTookSample = $this->getSample($tmpPath, $this->pdo->getSetting('ffmpegpath'), $rel['guid']);
|
|
if ($blnTookSample)
|
|
$this->updateReleaseHasPreview($rel['guid']);
|
|
}
|
|
|
|
if ($processMediainfo)
|
|
$blnTookMediainfo = $this->getMediainfo($tmpPath, $this->pdo->getSetting('mediainfopath'), $rel['id']);
|
|
|
|
unlink($mediafile);
|
|
}
|
|
unset($mediaBinary);
|
|
}
|
|
|
|
// attempt to process audio sample file
|
|
if(!empty($nzbInfo->audiofiles) && $processAudioSample && $blnTookSample === false)
|
|
{
|
|
$audioFile = $nzbInfo->audiofiles[0]; //first detected audio file
|
|
$audioMsgids = array_slice($audioFile['segments'], 0, 1); //get first segment
|
|
$audioGroup = $audioFile['groups'][0];
|
|
|
|
//echo "PostPrc : Fetching ".implode($audioMsgids, ', ')." from {$audioGroup}\n";
|
|
if (!$nntpconnected)
|
|
$nntpconnected = $nntp->doConnect();
|
|
|
|
$audioBinary = $nntp->getMessages($audioGroup, $audioMsgids);
|
|
if ($audioBinary === false)
|
|
echo "\nPostPrc : Couldnt fetch audio sample\n";
|
|
else
|
|
{
|
|
$audiofile = $tmpPath.'sample.mp3';
|
|
|
|
file_put_contents($audiofile, $audioBinary);
|
|
|
|
$blnTookSample = $this->getAudioSample($tmpPath, $rel['guid']);
|
|
if ($blnTookSample !== false)
|
|
$this->updateReleaseHasPreview($rel['guid'], 2);
|
|
|
|
if ($processMediainfo)
|
|
$blnTookMediainfo = $this->getMediainfo($tmpPath, $this->pdo->getSetting('mediainfopath'), $rel['id']);
|
|
|
|
if ($this->pdo->getSetting('lamepath') != "")
|
|
$this->lameAudioSample($this->pdo->getSetting('lamepath'), $rel['guid']);
|
|
|
|
unlink($audiofile);
|
|
}
|
|
unset($audioBinary);
|
|
}
|
|
|
|
if (!empty($nzbInfo->rarfiles) && ($this->pdo->getSetting('checkpasswordedrar') > 0 || (($processVideoSample || $processAudioSample) && $blnTookSample === false) || $processMediainfo))
|
|
{
|
|
$mysqlkeepalive = 0;
|
|
foreach($nzbInfo->rarfiles as $rarFile)
|
|
{
|
|
//dont process any more rars if a passworded rar has been detected and the site is set to automatically delete them
|
|
if ($this->pdo->getSetting('deletepasswordedrelease') == 1 && max($passStatus) == Releases::PASSWD_RAR)
|
|
{
|
|
echo "-Skipping processing of rar {$rarFile['subject']} as this release has already been marked as passworded.\n";
|
|
continue;
|
|
}
|
|
|
|
$rarMsgids = array_slice($rarFile['segments'], 0, 1); //get first segment
|
|
$rarGroup = $rarFile['groups'][0];
|
|
|
|
//echo "PostPrc : Fetching ".implode($rarMsgids, ', ')." from {$rarGroup} (".++$mysqlkeepalive.")\n";
|
|
if (!$nntpconnected)
|
|
$nntpconnected = $nntp->doConnect();
|
|
|
|
$fetchedBinary = $nntp->getMessages($rarGroup, $rarMsgids);
|
|
if ($fetchedBinary === false)
|
|
{
|
|
//echo "\nPostPrc : Failed fetching rar file\n";
|
|
$this->pdo->queryExec(sprintf("update releases set passwordstatus = passwordstatus - 1 where id = %d", $rel['id']));
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
$relFiles = $this->processReleaseFiles($fetchedBinary, $rel['id']);
|
|
|
|
if ($this->pdo->getSetting('checkpasswordedrar') > 0 && $processPasswords)
|
|
{
|
|
$passStatus[] = $this->processReleasePasswords($fetchedBinary, $tmpPath, $this->pdo->getSetting('unrarpath'), $this->pdo->getSetting('checkpasswordedrar'));
|
|
}
|
|
|
|
// we need to unrar the fetched binary if checkpasswordedrar wasnt 2
|
|
if ($this->pdo->getSetting('checkpasswordedrar') < 2 && $processPasswords)
|
|
{
|
|
$rarfile = $tmpPath.'rarfile.rar';
|
|
file_put_contents($rarfile, $fetchedBinary);
|
|
$execstring = '"'.$this->pdo->getSetting('unrarpath').'" e -ai -ep -c- -id -r -kb -p- -y -inul "'.$rarfile.'" "'.$tmpPath.'"';
|
|
$output = Utility::runCmd($execstring, false, true);
|
|
unlink($rarfile);
|
|
}
|
|
|
|
if ($processVideoSample && $blnTookSample === false)
|
|
{
|
|
$blnTookSample = $this->getSample($tmpPath, $this->pdo->getSetting('ffmpegpath'), $rel['guid']);
|
|
if ($blnTookSample)
|
|
$this->updateReleaseHasPreview($rel['guid']);
|
|
}
|
|
|
|
$blnTookAudioSample = false;
|
|
if ($processAudioSample && $blnTookSample === false)
|
|
{
|
|
$blnTookSample = $this->getAudioSample($tmpPath, $rel['guid']);
|
|
if ($blnTookSample)
|
|
{
|
|
$blnTookAudioSample = true;
|
|
$this->updateReleaseHasPreview($rel['guid'], 2);
|
|
}
|
|
}
|
|
|
|
if ($processMediainfo && $blnTookMediainfo === false)
|
|
{
|
|
$blnTookMediainfo = $this->getMediainfo($tmpPath, $this->pdo->getSetting('mediainfopath'), $rel['id']);
|
|
}
|
|
|
|
//
|
|
// Has to be done after mediainfo
|
|
//
|
|
if ($blnTookAudioSample && $this->pdo->getSetting('lamepath') != "")
|
|
$this->lameAudioSample($this->pdo->getSetting('lamepath'), $rel['guid']);
|
|
|
|
if ($mysqlkeepalive % 25 == 0)
|
|
$this->pdo->query("select 1");
|
|
}
|
|
|
|
//clean up all files
|
|
foreach(glob($tmpPath.'*') as $v)
|
|
{
|
|
unlink($v);
|
|
}
|
|
|
|
} //end foreach msgid
|
|
}
|
|
elseif(empty($nzbInfo->rarfiles) && $norar == 1)
|
|
{
|
|
$passStatus[] = Releases::PASSWD_POTENTIAL;
|
|
}
|
|
|
|
$hpsql = '';
|
|
if (!$blnTookSample)
|
|
$hpsql = ', haspreview = 0';
|
|
|
|
$sql = sprintf("update releases set passwordstatus = %d %s where id = %d", max($passStatus), $hpsql, $rel["id"]);
|
|
$this->pdo->queryExec($sql);
|
|
|
|
} //end foreach result
|
|
|
|
if ($nntpconnected)
|
|
{
|
|
$nntp->doQuit();
|
|
}
|
|
|
|
echo "\n";
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Work out all files contained inside a rar
|
|
*/
|
|
public function processReleaseFiles($fetchedBinary, $relid)
|
|
{
|
|
$retval = array();
|
|
$rar = new \ArchiveInfo();
|
|
$rf = new ReleaseFiles;
|
|
|
|
$rar->setData($fetchedBinary, true);
|
|
if ($rar->error)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
$files = $rar->getArchiveFileList();
|
|
if ($files !== false)
|
|
{
|
|
foreach ($files as $file)
|
|
{
|
|
if (isset($file['name']))
|
|
{
|
|
$rf->add($relid, utf8_encode($file['name']), (isset($file['size']) ? $file['size'] : ""), (isset($file['date']) ? $file['date'] : ""), (isset($file['pass']) ? $file['pass'] : "") );
|
|
$retval[] = $file['name'];
|
|
}
|
|
}
|
|
}
|
|
|
|
unset($fetchedBinary);
|
|
return $retval;
|
|
}
|
|
|
|
|
|
/**
|
|
* Work out if a release is passworded
|
|
*/
|
|
public function processReleasePasswords($fetchedBinary, $tmpPath, $unrarPath, $checkpasswordedrar)
|
|
{
|
|
$passStatus = Releases::PASSWD_NONE;
|
|
$potentiallypasswordedfileregex = "/\.(ace|cab|tar|gz|url)$/i";
|
|
$definetlypasswordedfileregex = "/password\.url/i";
|
|
$rar = new ArchiveInfo();
|
|
$filecount = 0;
|
|
|
|
$rarfile = $tmpPath.'rarfile.rar';
|
|
file_put_contents($rarfile, $fetchedBinary);
|
|
|
|
if ($rar->open($rarfile))
|
|
{
|
|
$rarsummary = $rar->getSummary(true, false);
|
|
if ((isset($rarsummary["is_encrypted"]) && $rarsummary["is_encrypted"] != 0) || !empty($rar->isEncrypted))
|
|
{
|
|
$passStatus = Releases::PASSWD_RAR;
|
|
}
|
|
else
|
|
{
|
|
$files = $rar->getArchiveFileList();
|
|
|
|
if ($files !== false)
|
|
{
|
|
foreach ($files as $file)
|
|
{
|
|
if (isset($file['pass']) && isset($file["name"]))
|
|
{
|
|
$filecount++;
|
|
//
|
|
// individual file rar passworded
|
|
//
|
|
if ($file['pass'] == true || preg_match($definetlypasswordedfileregex, $file["name"]))
|
|
{
|
|
$passStatus = Releases::PASSWD_RAR;
|
|
}
|
|
|
|
//
|
|
// individual file looks suspect
|
|
//
|
|
elseif (preg_match($potentiallypasswordedfileregex, $file["name"]) && $passStatus != Releases::PASSWD_RAR)
|
|
{
|
|
$passStatus = Releases::PASSWD_POTENTIAL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Deep Checking
|
|
//
|
|
if ($checkpasswordedrar == 2)
|
|
{
|
|
|
|
$israr = $this->isRar($rarfile);
|
|
for ($i=0;$i<sizeof($israr);$i++)
|
|
{
|
|
if (preg_match('/\\\\/',$israr[$i]))
|
|
{
|
|
$israr[$i] = ltrim((strrchr($israr[$i],"\\")),"\\");
|
|
}
|
|
}
|
|
|
|
$execstring = '"'.$unrarPath.'" e -ai -ep -c- -id -r -kb -p- -y -inul "'.$rarfile.'" "'.$tmpPath.'"';
|
|
$output = Utility::runCmd($execstring, false, true);
|
|
|
|
// delete the rar
|
|
@unlink($rarfile);
|
|
|
|
// ok, now we have all the files extracted from the rar into the tempdir and
|
|
// the rar file deleted, now to loop through the files and recursively unrar
|
|
// if any of those are rars, we don't trust their names and we test every file
|
|
// for the rar header
|
|
for ($i=0;$i<sizeof($israr);$i++)
|
|
{
|
|
// even though its in the rar filelist there may not have been enough data
|
|
// to extract this file so dont attempt to read the file if it doesnt exist
|
|
if (!file_exists($tmpPath.$israr[$i]))
|
|
continue;
|
|
|
|
$tmp = $this->isRar($tmpPath.$israr[$i]);
|
|
|
|
if (is_array($tmp))
|
|
// it's a rar
|
|
{
|
|
for ($x=0;$x<sizeof($tmp);$x++)
|
|
{
|
|
if (preg_match('/\\\\/',$tmp[$x]))
|
|
{
|
|
$tmp[$x] = ltrim((strrchr($tmp[$x],"\\")),"\\");
|
|
}
|
|
$israr[] = $tmp[$x];
|
|
}
|
|
|
|
$execstring = '"'.$unrarPath.'" e -ai -ep -c- -id -r -kb -p- -y -inul "'.$tmpPath.$israr[$i].'" "'.$tmpPath.'"';
|
|
$output2 = Utility::runCmd($execstring, false, true);
|
|
@unlink($tmpPath.$israr[$i]);
|
|
}
|
|
else
|
|
{
|
|
if ($tmp == 1 || $tmp == 2)
|
|
{
|
|
$passStatus = Releases::PASSWD_RAR;
|
|
@unlink($tmpPath.$israr[$i]);
|
|
}
|
|
}
|
|
unset($tmp);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@unlink($rarfile);
|
|
unset($fetchedBinary);
|
|
return $passStatus;
|
|
}
|
|
|
|
/**
|
|
* Work out if a rar is passworded
|
|
*/
|
|
public function isRar($rarfile)
|
|
{
|
|
// returns 0 if not rar
|
|
// returns 1 if encrypted rar
|
|
// returns 2 if passworded rar
|
|
// returns array of files in the rar if normal rar
|
|
$filelist = array();
|
|
$rar = new ArchiveInfo;
|
|
if ($rar->open($rarfile))
|
|
{
|
|
if (!empty($rar->isEncrypted))
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
$files = $rar->getArchiveFileList();
|
|
foreach ($files as $file)
|
|
{
|
|
if (isset($file['pass']) && isset($file["name"]))
|
|
{
|
|
$filelist[] = $file['name'];
|
|
if ($file['pass'] == true)
|
|
//
|
|
// individual file rar passworded
|
|
//
|
|
{
|
|
return 2;
|
|
// passworded
|
|
}
|
|
}
|
|
}
|
|
return ($filelist);
|
|
// normal rar
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
// not a rar
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Work out all files contained inside a rar
|
|
*/
|
|
public function getMediainfo($ramdrive,$mediainfo,$releaseID)
|
|
{
|
|
$retval = false;
|
|
$mediafiles = glob($ramdrive.'*.*');
|
|
if (is_array($mediafiles))
|
|
{
|
|
foreach($mediafiles as $mediafile)
|
|
{
|
|
if (preg_match("/\.(".$this->mediafileregex.'|'.$this->audiofileregex.")$/i",$mediafile))
|
|
{
|
|
$execstring = '"'.$mediainfo.'" --Output=XML "'.$mediafile.'"';
|
|
$xmlarray = Utility::runCmd($execstring);
|
|
|
|
if (is_array($xmlarray))
|
|
{
|
|
$xmlarray = implode("\n",$xmlarray);
|
|
$re = new ReleaseExtra();
|
|
$re->addFull($releaseID,$xmlarray);
|
|
$re->addFromXml($releaseID,$xmlarray);
|
|
$retval = true;
|
|
}
|
|
else
|
|
{
|
|
echo "PostPrc : Failed to process mediainfo for ".$mediafile." release (".$releaseID.")\n";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
echo "PostPrc: Couldn't open temp drive ".$ramdrive."\n";
|
|
}
|
|
return $retval;
|
|
}
|
|
|
|
/**
|
|
* Get a sample from a release using ffmpeg
|
|
*/
|
|
public function getSample($ramdrive, $ffmpeginfo, $releaseguid)
|
|
{
|
|
$ri = new ReleaseImage();
|
|
$retval = false;
|
|
|
|
$samplefiles = glob($ramdrive.'*.*');
|
|
if (is_array($samplefiles))
|
|
{
|
|
foreach($samplefiles as $samplefile)
|
|
{
|
|
if (preg_match("/\.(".$this->mediafileregex.")$/i",$samplefile))
|
|
{
|
|
//1.0
|
|
//$execstring = '"'.$ffmpeginfo.'" -sameq -i "'.$samplefile.'" -vframes 300 "'.$ramdrive.'zzzz%03d.jpg"';
|
|
|
|
//1.1
|
|
//$execstring = '"'.$ffmpeginfo.'" -i "'.$samplefile.'" -qscale:v 1 -vframes 300 "'.$ramdrive.'zzzz%03d.jpg"';
|
|
|
|
//2.0
|
|
//$execstring = '"'.$ffmpeginfo.'" -i "'.$samplefile.'" -vframes 300 "'.$ramdrive.'zzzz%03d.jpg"';
|
|
|
|
//1.x
|
|
$execstring = '"'.$ffmpeginfo.'" -q:v 0 -i "'.$samplefile.'" -vframes 300 "'.$ramdrive.'zzzz%03d.jpg"';
|
|
|
|
Utility::runCmd($execstring, false, true);
|
|
$all_files = scandir($ramdrive,1);
|
|
if(preg_match("/zzzz\d{3}\.jpg/",$all_files[1]))
|
|
{
|
|
$ri->saveImage($releaseguid.'_thumb', $ramdrive.$all_files[1], $ri->imgSavePath, 800, 600);
|
|
$retval = true;
|
|
}
|
|
|
|
//clean up all files
|
|
foreach(glob($ramdrive.'*.jpg') as $v)
|
|
{
|
|
unlink($v);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
echo "PostPrc: Couldn't open temp drive ".$ramdrive."\n";
|
|
}
|
|
return $retval;
|
|
}
|
|
|
|
/**
|
|
* Has to be performed after mediainfo, as lame strips id3 tags.
|
|
*/
|
|
public function lameAudioSample($lameinfo, $releaseguid)
|
|
{
|
|
$returnval = false;
|
|
|
|
$minacceptableencodefilesize = 10000;
|
|
$samplefile = $this->mp3SavePath.$releaseguid.'.mp3';
|
|
$samplefileogg = $this->mp3SavePath.$releaseguid.'.ogg';
|
|
$ffmpeginfo = $this->pdo->getSetting('ffmpegpath');
|
|
|
|
if (file_exists($samplefile))
|
|
{
|
|
$outfile = $this->mp3SavePath.$releaseguid.'_l.mp3';
|
|
$outfileogg = $this->mp3SavePath.$releaseguid.'_l.ogg';
|
|
|
|
//
|
|
// lame the sample down to 96kb and replace it. alternatives could be
|
|
// V8 for low quality variable.
|
|
//
|
|
|
|
$execstring = '"'.$lameinfo.'" -b 96 "'.$samplefile.'" "'.$outfile.'"';
|
|
$execstringogg = '"'.$ffmpeginfo.'" -i "'.$samplefile.'" -acodec libvorbis "'.$outfileogg.'"';
|
|
$output = Utility::runCmd($execstring, false, true);
|
|
$output = Utility::runCmd($execstringogg, false, true);
|
|
|
|
//
|
|
// lame can create bad/small files if the source was corrupt
|
|
// if it creates a file thats surprisingly small, then ignore it and retain
|
|
// original
|
|
//
|
|
if (file_exists($outfile))
|
|
{
|
|
if (filesize($outfile) < $minacceptableencodefilesize)
|
|
unlink($outfile);
|
|
else
|
|
{
|
|
unlink($samplefile);
|
|
rename($outfile, $samplefile);
|
|
|
|
$returnval = true;
|
|
}
|
|
}
|
|
if (file_exists($outfileogg))
|
|
{
|
|
if (filesize($outfileogg) < $minacceptableencodefilesize)
|
|
unlink($outfileogg);
|
|
else
|
|
{
|
|
rename($outfileogg, $samplefileogg);
|
|
$returnval = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $returnval;
|
|
}
|
|
|
|
/**
|
|
* Get an audio sample from a release.
|
|
*/
|
|
public function getAudioSample($ramdrive, $releaseguid)
|
|
{
|
|
$retval = false;
|
|
|
|
$audiofiles = glob($ramdrive.'*.*');
|
|
if (is_array($audiofiles))
|
|
{
|
|
foreach($audiofiles as $audiofile)
|
|
{
|
|
if (preg_match("/\.(".$this->audiofileregex.")$/i",$audiofile))
|
|
{
|
|
if (copy($audiofile, $this->mp3SavePath.$releaseguid.'.mp3') !== false)
|
|
$retval = true;
|
|
else
|
|
echo "PostPrc : Failed to get audio sample from ".$audiofile."\n";
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
echo "PostPrc: Couldn't open temp drive ".$ramdrive."\n";
|
|
}
|
|
return $retval;
|
|
}
|
|
|
|
/**
|
|
* Delete an audio sample from a release.
|
|
*/
|
|
public function deleteAudioSample($releaseguid)
|
|
{
|
|
$preview = $this->mp3SavePath.$releaseguid.'.mp3';
|
|
if (file_exists($preview))
|
|
unlink($preview);
|
|
}
|
|
|
|
/**
|
|
* Update release to indicate a preview has been obtained.
|
|
*/
|
|
public function updateReleaseHasPreview($guid, $prevtype=1)
|
|
{
|
|
$rel = new Releases;
|
|
$rel->updateHasPreview($guid, $prevtype);
|
|
}
|
|
|
|
/**
|
|
* Process untagged music releases using information from mediainfo if config permits.
|
|
*/
|
|
public function processMusicFromMediaInfo()
|
|
{
|
|
$processMediainfo = ($this->pdo->getSetting('mediainfopath') != '') ? true : false;
|
|
$processAudioSample = ($this->pdo->getSetting('saveaudiopreview') == 1) ? true : false;
|
|
$processMusic = ($this->pdo->getSetting('lookupmusic') == 1) ? true : false;
|
|
|
|
if ($processMusic && $processMediainfo && $processAudioSample)
|
|
{
|
|
$music = new Music($this->echooutput);
|
|
$ret = $music->processMusicReleaseFromMediaInfo();
|
|
return $ret;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|