From 2b23fd419438f0454993a3eb77062d2e797ffbce Mon Sep 17 00:00:00 2001 From: Darko Date: Wed, 16 Sep 2015 12:37:58 +0200 Subject: [PATCH] update import.php in misc/testing folder. Remove scripts and classes not used in newznab-tmux. --- misc/testing/Tests/test_blacklist.php | 494 -------- misc/testing/deletereleases.php | 75 -- misc/testing/removespecial.php | 10 - misc/testing/update_cleanup.php | 9 - misc/testing/update_parsing.php | 9 - misc/update_scripts/import.php | 3 +- newznab/controllers/Parsing.php | 1498 ------------------------- newznab/controllers/PostProcess.php | 1001 ----------------- newznab/controllers/PowerProcess.php | 808 ------------- 9 files changed, 2 insertions(+), 3905 deletions(-) delete mode 100644 misc/testing/Tests/test_blacklist.php delete mode 100644 misc/testing/deletereleases.php delete mode 100644 misc/testing/removespecial.php delete mode 100644 misc/testing/update_cleanup.php delete mode 100644 misc/testing/update_parsing.php delete mode 100644 newznab/controllers/Parsing.php delete mode 100644 newznab/controllers/PostProcess.php delete mode 100644 newznab/controllers/PowerProcess.php diff --git a/misc/testing/Tests/test_blacklist.php b/misc/testing/Tests/test_blacklist.php deleted file mode 100644 index 8ac18bdc1..000000000 --- a/misc/testing/Tests/test_blacklist.php +++ /dev/null @@ -1,494 +0,0 @@ -array('min'=>31457280, 'max'=>PHP_INT_MAX), - # TV High Def (HD) set a 40MB Min restriction - Category::CAT_TV_HD=>array('min'=>41943040, 'max'=>PHP_INT_MAX), - # Movies Standard Def (SD) set a 50MB Min restriction - Category::CAT_MOVIE_SD=>array('min'=>52428800, 'max'=>PHP_INT_MAX), - # Movies High Def (HD) set a 80MB Min restriction - Category::CAT_MOVIE_HD=>array('min'=>83886080, 'max'=>PHP_INT_MAX), - # Movies Other set a 30MB Min restriction - Category::CAT_MOVIE_OTHER=>array('min'=>31457280, 'max'=>PHP_INT_MAX), - # Bluray movies, 350MB Min restriction - Category::CAT_MOVIE_BLURAY=>array('min'=>367001600, 'max'=>PHP_INT_MAX), -); - -# Throttle cleanup/searching by performing batches... the larger -# the number, the faster processing will go, but will demand more -# system memory... -$batch=500; - -# Throttle -# The throttle allows a scan of your database without impacting performance -# to the public who may or may not be using your database. it also reduces -# the cpu demand of the cleanup. Set this value to 0 if your system is -# private and dedicated to yourself for the best speed. It identifies -# the number of seconds to sleep for between each batch -$throttle=0.5; - -# This blacklist is an aray of regular expressions that you can use -# to test with (sometimes it's easier to update a table infront of -# you as a developer then going back and making a database change -# and then returning to run the script. -$blacklist = array( - # random string of crap - array("groupname"=>"alt.binaries.*", "regex"=>'^[a-z0-9]{1,80}([0-9-]+$|$)'), - # Missing blacklist catching of foreign content - array("groupname"=>"alt.binaries.*", "regex"=>'[-.](FR|DE|ITA)[-.]'), - # Common German Keywords - array("groupname"=>"alt.binaries.*", "regex"=>'(^|[.\/ \-]+)(ohne|das|der|und|fuer|ersten|leicht|meinem|zum|aus|dem|blitzlicht|alle|grosse|blitzen|ich|zed|sed)([.\/ \-]+|$)'), - # random string of crap in alt.binaries.sounds.mp3, and alt.binaries.multimedia - array("groupname"=>"alt.binaries.*", "regex"=>'^[a-z0-9]{5} [0-9]{8} [0-9]{3}$'), - # random crap like: acef826f-6c8b-405c-b7f2-c9c143d726a8 - array("groupname"=>"alt.binaries.*", "regex"=>'^[a-z0-9]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12}$'), - array("groupname"=>"alt.binaries.*", "regex"=>'^[a-z0-9.]+\.BDR$'), - array("groupname"=>"alt.binaries.*", "regex"=>'^\([0-9.]+\)$'), - - # Password protected content that was marked by the poster - array("groupname"=>"alt.binaries.*", "regex"=>'\[password\]'), -); - -# Test DB Data; if you plan on using this, you need to set the $use_NNReleasesDB to false -$test_headers = array( - # Set id's to 0 so id's are purged unessisarily when testing - array('ID'=>0, 'groupname'=>"alt.binaries.multimedia", 'name'=>"1204odayrtgh6j7app"), - array('ID'=>0, 'groupname'=>"alt.binaries.multimedia", 'name'=>"BB555"), - array('ID'=>0, 'groupname'=>"alt.binaries.multimedia", 'name'=>"bnedhe8utrh5tnbg9"), - array('ID'=>0, 'groupname'=>"alt.binaries.multimedia", 'name'=>"Uoaaqunio-396653289-201212201118"), - array('ID'=>0, 'groupname'=>"alt.binaries.multimedia", 'name'=>"acef826f-6c8b-405c-b7f2-c9c143d726a8"), - array('ID'=>0, 'groupname'=>"alt.binaries.multimedia", 'name'=>"ich26389"), - array('ID'=>0, 'groupname'=>"alt.binaries.multimedia", 'name'=>"GkTNPvg3"), - array('ID'=>0, 'groupname'=>"alt.binaries.multimedia", 'name'=>"RVL 25 12 2012 G O M S BDR"), - array('ID'=>0, 'groupname'=>"alt.binaries.multimedia", 'name'=>"25 12 2012 M S R BDR"), - array('ID'=>0, 'groupname'=>"alt.binaries.multimedia", 'name'=>"23YKC 20121212 013"), -); - -function handleError($errno, $errstr, $errfile, $errline, array $errcontext) -{ - // this function makes it easier to catch regular expression errors - // found - if (0 === error_reporting()) { - return false; - } - throw new ErrorException($errstr, 0, $errno, $errfile, $errline); -} -set_error_handler('handleError'); - -function get_block($offset, $batch) -{ - global $use_NNReleasesDB; - static $retrieved=false; - if(!$use_NNReleasesDB){ - // use a retrieved boolean for test data so content - // is only fetched once. - if(!$retrieved && $offset > 0){ - return Null; - } - global $test_headers; - // toggle retrieved content on test data - $retrieved=true; - return $test_headers; - } - - $catsql = "SELECT releases.*,groups.name as groupname FROM " - ."releases LEFT JOIN groups on releases.groupID = groups.ID "; - $db = new Settings(); - return $db->query($catsql.sprintf(' LIMIT %d,%d', $offset, $batch)); -} - -$db = new Settings(); - -$errcnt=0; -$total=0; -$offset=0; - -# Dictionary -$pspelldict=[]; - -# Completion Refernece Time in past -$completionRef = strtotime("-$completionSec seconds"); - -# Scan header for spelling...; at least 1 word has to match the spelling -if($use_spellCheck && !function_exists('pspell_check')){ - echo "Note: Disabling spell checking as it is not available in your PHP installation.\n"; - echo " Consider the following to enable it:"; - echo " ubuntu #> sudo apt-get install php5-pspell\n"; - echo " redhat #> yum install php-pspell\n"; - echo " other #> # re-compile php with --with-pspell flag\n"; - $use_spellCheck=false; -} - -$binaries = new Binaries(); -if($use_NNRegexDB) - # Over-ride Blacklist up top and use database - $blacklist = $binaries->getBlacklist(true); - -while($res=get_block($offset, $batch)){ - - $subtotal=count($res); - $total+=$subtotal; - - $release = new Releases(); - $category = new Category(); - - // Track error count changes - $_errcnt=$errcnt; - foreach ($res as $header) - { - // if a white list is detected we now are required to - // only accept the entry if it matches at least 1 whitelist - // while a blacklist will over-ride all - $whitelist = []; - $matches_whitelist = false; - - foreach ($blacklist as $bl) - { - // opttype = 1 -> Blacklist (Default) - // opttype = 2 -> Whitelist - $opttype = Binaries::OPTYPE_BLACKLIST; - if (array_key_exists ('opttype' , $bl)){ - $opttype = intval($bl['opttype']); - } - - // Regular expression - $regex = $bl['regex']; - - // Default msgcol is subject - $msgcol = Binaries::BLACKLIST_FIELD_SUBJECT; - $parse = $header['name']; - if (array_key_exists ('msgcol' , $bl)){ - $msgcol = intval($bl['msgcol']); - } - - switch($msgcol) - { - case Binaries::BLACKLIST_FIELD_FROM: - if(!array_key_exists ('fromname' , $bl)){ - # we only process fromname if we found it... otherwise we keep going - continue; - } - $parse = $header['fromname']; - break; - case Binaries::BLACKLIST_FIELD_MESSAGEID: - # unsupported; you can't get this information from an already - # populated database - continue; - }; - - if ($opttype == Binaries::OPTYPE_WHITELIST){ - // at least 1 whitelist found... - // this means we have to match it or be rejected - $whitelist[] = $regex; - } - - try - { - $group_check = preg_match('/^'.$bl['groupname'].'$/i', $header['groupname']); - } - catch(Exception $e) - { - # Support letting the user know when there is a bad - # regular expression entry abort futher checks - $strerr=str_pad((int) $errcnt,2," ",STR_PAD_LEFT); - echo "$strerr. id=".$bl["id"]. - ", group=".$header["groupname"]."\n"; - echo " regex='".$bl["groupname"]."'\n"; - echo " error=".$e->getMessage()."\n\n"; - exit(1); - } - - if ($group_check) - { - try - { - $blacklist_check = preg_match('/'.$regex.'/i', $parse); - // White lists react in the invert manner... something that - // doesn't match causes us to keep going - if($opttype == Binaries::OPTYPE_WHITELIST && $blacklist_check){ - // invert check since it's a good thing we matched - $blacklist_check=false; - // Flag that we matched the white list - $matches_whitelist = true; - } - } - catch(Exception $e) - { - # Support letting the user know when there is a bad - # regular expression entry abort futher checks - $strerr=str_pad((int) $errcnt,2," ",STR_PAD_LEFT); - if(isset($bl["id"])) - echo "$strerr. id=".$bl["id"].", "; - echo " name=".$header["name"]."\n"; - echo " regex=$regex\n"; - echo " error=".$e->getMessage()."\n\n"; - exit(1); - } - - if ($blacklist_check) - { - $errcnt++; - echo 'BL: /'.$bl['regex'].'/i matched '.$header['ID'].'/'.$header['name']. - " (".$header['groupname'].")\n"; - if ($purgeMatched && isset($header['ID']) && $header['ID'] > 0){ - // Support purging if enabled - $release->delete($header['ID']); - } - # ensure whitelist flags are off to avoid extra processing - # at the end of this loop (Below) - $whitelist = []; - break; - } - - if($use_CategorySizeRestrictions == true && $header['categoryID']) - { - $sizes = null; - if($use_NNCategorySizeRestrictions){ - $sizes = $category->getSizeRangeById($header['categoryID']); - }else if (array_key_exists ($header['categoryID'], $categoryRestrictions)){ - $sizes = $categoryRestrictions[$header['categoryID']]; - } - if(is_array($sizes)){ - # Restrictions are in place - $totalSize=intval($header['size']); - if(!($totalSize >= $sizes['min'] && $totalSize < $sizes['max'])) - { - $errcnt++; - echo 'BL: size restrictions '.$header['ID'].'/'.$header['name']. - " (".$header['groupname'].")\n"; - if ($purgeMatched && isset($header['ID']) && $header['ID'] > 0){ - // Support purging if enabled - $release->delete($header['ID']); - } - # ensure whitelist flags are off to avoid extra processing - # at the end of this loop (Below) - $whitelist = []; - break; - } - } - } - - if($use_CompletionRestrictions == true){ - $lastUpdate=strtotime($header['updatedate']); - $completion=intval($header['completion']); - - if($completion < $completionAllowable && $lastUpdate < $completionRef) - { - $errcnt++; - echo 'BL: incomplete '.$header['ID'].'/'.$header['name']. - " (".$header['groupname'].")\n"; - if ($purgeMatched && isset($header['ID']) && $header['ID'] > 0){ - // Support purging if enabled - $release->delete($header['ID']); - } - # ensure whitelist flags are off to avoid extra processing - # at the end of this loop (Below) - $whitelist = []; - break; - } - } - - if($use_spellCheck == true && - $opttype == Binaries::OPTYPE_BLACKLIST && - $msgcol == Binaries::BLACKLIST_FIELD_SUBJECT){ - - # Track matched - $matched=0; - # First extract the words - $keywords = preg_split('/[^a-z0-9]+/i', $parse); - foreach($spellCheckLang as $lang){ - if (!array_key_exists ($lang , $pspelldict)) - $pspelldict[$lang] = pspell_new($lang); - foreach($keywords as $kw){ - foreach($spellExceptions as $exception){ - if(preg_match('/'.$exception.'/i', $kw)){ - $matched++; - break; - } - } - if($matched>0)break; - - if(pspell_check($pspelldict[$lang], $kw)){ - $matched++; - break; - } - } - # we only need to match once to presume the data - # is good - if($matched>0)break; - } - # how did we do for spelling matches - if(!$matched){ - $errcnt++; - echo 'BL: due to bad spelling '.$header['ID'].'/'.$header['name']. - " (".$header['groupname'].")\n"; - if ($purgeMatched && isset($header['ID']) && $header['ID'] > 0){ - // Support purging if enabled - $release->delete($header['ID']); - } - # ensure whitelist flags are off to avoid extra processing - # at the end of this loop (Below) - $whitelist = []; - break; - } - } - } - } - - # We parsed entire matching list entries at this point.. now we need - # to handle the whitelist (if it was enabled) - if(count($whitelist) > 0 && !$matches_whitelist) - { - $errcnt++; - $first_loop=true; - foreach ($whitelist as $entry){ - if($first_loop) - { - $first_loop=false; - } - else - { - echo '\n'; - } - echo 'WL: /'.$bl['regex'].'/i'; - } - echo ' failed to match '.$header['ID'].'/'.$header['name']. - " (".$header['groupname'].")\n"; - - if ($purgeMatched && $header['ID'] > 0){ - // Support purging if enabled - $release->delete($header['ID']); - } - } - } - if(!$purgeMatched || $_errcnt==$errcnt){ - # No changes... update batch - $offset+=$batch; - } - - if($subtotal == $batch){ - // Presume there is more content to come - // throttle request - if($throttle > 0.0){ - sleep($throttle); - } - } -} -echo "Scanned $total record(s), $errcnt match(es) found.\n"; -if($errcnt >0){ - if(!$purgeMatched){ - echo "Note: This scan was performed in a safe read-only mode.\n"; - echo " If you are satisfied with the output as being 'garbage/spam'\n". - " then consider editing this file and setting the \$purgeMatched flag to 'true'\n"; - }else{ - echo "Note: This scan was performed in a write mode; all content matched was removed.\n"; - } -} -exit(($errcnt>0)?1:0); diff --git a/misc/testing/deletereleases.php b/misc/testing/deletereleases.php deleted file mode 100644 index 76c44bdfd..000000000 --- a/misc/testing/deletereleases.php +++ /dev/null @@ -1,75 +0,0 @@ -query($sql); -echo "about to delete ".count($rel)." release(s)"; - -foreach ($rel as $r) -{ - $releases->delete($r['ID']); -} diff --git a/misc/testing/removespecial.php b/misc/testing/removespecial.php deleted file mode 100644 index d8cf6e324..000000000 --- a/misc/testing/removespecial.php +++ /dev/null @@ -1,10 +0,0 @@ -removeSpecial(); diff --git a/misc/testing/update_cleanup.php b/misc/testing/update_cleanup.php deleted file mode 100644 index 42ae22da9..000000000 --- a/misc/testing/update_cleanup.php +++ /dev/null @@ -1,9 +0,0 @@ -cleanup(); \ No newline at end of file diff --git a/misc/testing/update_parsing.php b/misc/testing/update_parsing.php deleted file mode 100644 index 713422151..000000000 --- a/misc/testing/update_parsing.php +++ /dev/null @@ -1,9 +0,0 @@ -process(); diff --git a/misc/update_scripts/import.php b/misc/update_scripts/import.php index cc20566b3..c7af7d730 100644 --- a/misc/update_scripts/import.php +++ b/misc/update_scripts/import.php @@ -6,6 +6,7 @@ use newznab\db\Settings; use newznab\utility\Utility; $releases = new Releases(); +$releaseImage = new ReleaseImage(); $db = new Settings(); $cat = new Categorize(); $releaseRegex = new ReleaseRegex(); @@ -116,7 +117,7 @@ foreach ($filestoprocess as $nzbFile) { if (!file_exists($errorpath)) mkdir($errorpath); if (!file_exists($errorpath . basename($nzbFile))) rename($nzbFile, $errorpath . basename($nzbFile)); } - $releases->delete($relid); + $releases->deleteSingle(['g' => $relguid, 'i' => $relid], $nzb, $releaseImage); } } else { $numbins = 0; diff --git a/newznab/controllers/Parsing.php b/newznab/controllers/Parsing.php deleted file mode 100644 index 39648c03e..000000000 --- a/newznab/controllers/Parsing.php +++ /dev/null @@ -1,1498 +0,0 @@ -other releases into real names. - */ -class Parsing -{ - /** - * @var newznab\db\Settings - */ - public $pdo; - - /** - * Default constructor. - * - * @param bool $echoonly - * @param bool $limited - * @param bool $verbose - */ - public function __construct($echoonly = false, $limited = true, $verbose = false) - { - $this->echoonly = $echoonly; - $this->limited = $limited; - $this->verbose = $verbose; - $this->releasestocheck = 0; - $this->numupdated = 0; - $this->numcleaned = 0; - $this->numnuked = 0; - $this->nummiscd = 0; - $this->nfosprocessed = 0; - $this->parsprocessed = 0; - $this->releasefilesprocessed = 0; - $this->cleanup = ['nuke' => [], 'misc' => []]; - $this->pdo = new Settings(); - } - - /** - * Performing parsing. - */ - public function process() - { - - // Default query for both full db and last 4 hours. - $sql = "SELECT r.searchname, r.name, r.fromname, r.id as rid, r.categoryid, r.guid, r.postdate, - rn.id as nfoid, - g.name as groupname, - GROUP_CONCAT(rf.name) as filenames - FROM releases r - LEFT JOIN releasenfo rn ON (rn.releaseid = r.id) - LEFT JOIN groups g ON (g.id = r.groupid) - LEFT JOIN releasefiles rf ON (rf.releaseid = r.id) - WHERE r.categoryid in (' . Category::CAT_TV_OTHER . ',' . Category::CAT_MOVIE_OTHER . ',' . Category::CAT_MISC_OTHER . ',' . Category::CAT_XXX_OTHER . ') - %s - GROUP BY r.id"; - - $res = $this->pdo->query(sprintf($sql, $this->limited ? "AND r.adddate BETWEEN NOW() - INTERVAL 4 HOUR AND NOW()" : "")); - $this->releasestocheck = sizeof($res); - if ($res) { - echo "PostPrc : Parsing last " . $this->releasestocheck . " releases in the Other-Misc categories\n"; - foreach ($res as $rel) { - $tempname = $foundName = $methodused = ''; - - //Knoc.One - if (preg_match("/KNOC.ONE/i", $rel['name'])) { - $title = ''; - $items = preg_split("/(\.| )/", $rel['name']); - foreach ($items as $value) { - if (preg_match("/^[a-z]+$/i", $value)) { - $len = strlen($value); - if ($len > 2) { - $title .= substr($value, -2) . substr($value, 0, -2) . " "; - } elseif ($len = 2) { - $title .= substr($value, -1) . substr($value, 0, -1) . " "; - } else { - $title .= $value . " "; - } - } else { - $title .= $value . " "; - } - } - $foundName = $title; - $methodused = "Knoc.One"; - $this->determineCategory($rel, $foundName, $methodused); - } - - /// - ///Use the Nfo to try to get the proper Releasename. - /// - $nfo = $this->pdo->queryOneRow(sprintf("select uncompress(nfo) as nfo from releasenfo where releaseid = %d", $rel['rid'])); - if ($nfo && $foundName == "") { - $this->nfosprocessed++; - $nfo = $nfo['nfo']; - - //LOUNGE releases - if (preg_match('/([a-z0-9.]+\.MBLURAY)/i', $nfo, $matches)) { - $foundName = $matches[1]; - $methodused = "LOUNGE"; - $this->determineCategory($rel, $foundName, $methodused); - } - - //AsianDVDClub releases - if (preg_match('/adc-[a-z0-9]{1,10}/', $rel['name'])) { - if (preg_match('/.*\(\d{4}\).*/i', $nfo, $matches)) { - $foundName = $matches[0]; - $methodused = "AsianDVDClub"; - $this->determineCategory($rel, $foundName, $methodused); - } - } - - //ACOUSTiC releases - if (preg_match('/ACOUSTiC presents \.\.\..*?([a-z0-9].*?\(.*?\))/is', $nfo, $matches)) { - $foundName = $matches[1] . ".MBLURAY"; - $methodused = "ACOUSTiC "; - $this->determineCategory($rel, $foundName, $methodused); - } - - //Japhson releases - if (preg_match('/Japhson/i', $nfo, $matches)) { - $movie = new Movie(); - $imdbID = null; - if (preg_match('/tt(\d{7})/i', $nfo, $matches)) { - $imdbId = $matches[1]; - $movCheck = $movie->fetchImdbProperties($imdbId); - $foundName = $movCheck['title']; - if (!preg_match('/(19|20)\d{2}/i', $foundName)) { - $foundName = $foundName . "." . $movCheck['year']; - } - if (preg_match('/language.*?\b([a-z0-9]+)\b/i', $nfo, $matches)) { - if (!preg_match('/English/i', $matches[1])) { - $foundName = $foundName . "." . $matches[1]; - } - } - if (preg_match('/audio.*?\b(\w+)\b/i', $nfo, $matches)) { - if (preg_match('/(Chinese|German|Dutch|Spanish|Hebrew|Finnish|Norwegian)/i', $matches[1])) { - $foundName = $foundName . "." . $matches[1]; - } - } - if (preg_match('/(video|resolution|video res).*?(1080|720|816|820|272|1280 @|528|1920)/i', $nfo, $matches)) { - if ($matches[2] == '1280 @') { - $matches[2] = '720'; - } - if ($matches[2] == '1920') { - $matches[2] = '1080'; - } - $foundName = $foundName . "." . $matches[2]; - } - if (preg_match('/source.*?\b(DVD9|DVD5|BDRIP|DVD\-?RIP|BLURAY)\b/i', $nfo, $matches)) { - $foundName = $foundName . "." . $matches[1]; - } - if (preg_match('/(video|resolution|video res).*?(XVID|X264|WMV)/i', $nfo, $matches)) { - $foundName = $foundName . "." . $matches[2]; - } - if (preg_match('/audio.*?\b(DTS|AC3)\b/i', $nfo, $matches)) { - $foundName = $foundName . "." . $matches[1]; - } - $foundName = $foundName . "-Japhson"; - $methodused = "Japhson"; - $this->determineCategory($rel, $foundName, $methodused); - } - } - - //AIHD releases - if (preg_match('/ALWAYS iN HiGH/i', $nfo, $matches)) { - $movie = new Movie(); - $imdbID = null; - if (preg_match('/tt(\d{7})/i', $nfo, $matches)) { - $imdbId = $matches[1]; - $movCheck = $movie->fetchImdbProperties($imdbId); - $foundName = $movCheck['title']; - if (!preg_match('/(19|20)\d{2}/i', $foundName)) { - $foundName = $foundName . "." . $movCheck['year']; - } - if (preg_match('/L\.([a-z0-9]+)\b/i', $nfo, $matches)) { - if (!preg_match('/En/i', $matches[1])) { - $foundName = $foundName . "." . $matches[1]; - } - } - if (preg_match('/(V).*?(1080|720|816|820|272|1280 @|528|1920)/i', $nfo, $matches)) { - if ($matches[2] == '1280 @') { - $matches[2] = '720'; - } - if ($matches[2] == '1920') { - $matches[2] = '1080'; - } - $foundName = $foundName . "." . $matches[2]; - } - if (preg_match('/V.*?\b(DVD9|DVD5|BDRIP|DVD\-?RIP|BLURAY)\b/i', $nfo, $matches)) { - $foundName = $foundName . "." . $matches[1]; - } - if (preg_match('/(V).*?(XVID|X264|WMV)/i', $nfo, $matches)) { - $foundName = $foundName . "." . $matches[2]; - } - if (preg_match('/A.*?\b(DTS|AC3)\b/i', $nfo, $matches)) { - $foundName = $foundName . "." . $matches[1]; - } - $foundName = $foundName . "-AIHD"; - $methodused = "AIHD"; - $this->determineCategory($rel, $foundName, $methodused); - } - } - - //IMAGiNE releases - if (preg_match('/\*\s+([a-z0-9]+(?:\.|_| )[a-z0-9\.\_\- ]+ \- imagine)\s+\*/i', $nfo, $matches)) { - $foundName = $matches[1]; - $methodused = "imagine"; - $this->determineCategory($rel, $foundName, $methodused); - } - - //LEGION releases - if (preg_match('/([a-z0-9 \.\-]+LEGi0N)/is', $nfo, $matches) && $foundName == "") { - $foundName = $matches[1]; - $methodused = "Legion"; - $this->determineCategory($rel, $foundName, $methodused); - } - - //SWAGGER releases - if (preg_match('/(S W A G G E R|swg.*?nfo)/i', $nfo) && $foundName == "") { - if (preg_match('/presents.*?([a-z0-9].*?\((19|20)\d{2}\))/is', $nfo, $matches)) { - $foundName = $matches[1]; - } - if (preg_match('/language.*?\b([a-z0-9]+)\b/i', $nfo, $matches)) { - if ($matches[1] != "english") { - $foundName = $foundName . "." . $matches[1]; - } - } - if (preg_match('/resolution.*?(1080|720)/i', $nfo, $matches)) { - $foundName = $foundName . ".BluRay." . $matches[1]; - } - if (preg_match('/video.*?\b([a-z0-9]+)\b/i', $nfo, $matches)) { - $foundName = $foundName . "." . $matches[1]; - } - if (preg_match('/audio.*?\b([a-z0-9]+)\b/i', $nfo, $matches)) { - $foundName = $foundName . "." . $matches[1]; - } - $foundName = $foundName . "-SWAGGER"; - $methodused = "SWAGGER"; - $this->determineCategory($rel, $foundName, $methodused); - } - - //cm8 releases - if (preg_match('/([a-z0-9]+(?:\.|_| )[a-z0-9\.\_\- \'\)\(]+\-(futv|crimson|qcf|runner|clue|ftp|episode|momentum|PFA|topaz|vision|tdp|haggis|nogrp|shirk|imagine|santi|sys|deimos|ltu|ficodvdr|cm8|dvdr|Nodlabs|aaf|sprinter|exvid|flawl3ss|rx|magicbox|done|unveil))\b/i', $nfo, $matches) && $foundName == "") { - //echo "this: ".$matches[1]."\n"; - $foundName = $matches[1]; - $methodused = "cm8"; - $this->determineCategory($rel, $foundName, $methodused); - } - - //river - if (preg_match('/([a-z0-9\.\_\-]+\-(webios|river|w4f|sometv|ngchd|C4|gf|bov|26k|ftw))\b/i', $nfo, $matches) && $foundName == "") { - $foundName = $matches[1]; - $methodused = "river-1"; - $this->determineCategory($rel, $foundName, $methodused); - } - if (preg_match('/([a-z0-9]+(?:\.|_| )[a-z0-9\.\_\- \'\)\(]+\-(CiA|Anarchy|RemixHD|FTW|Revott|WAF|CtrlHD|Telly|Nif|Line|NPW|Rude|EbP|CRisC|SHK|AssAss1ns|Leverage|BBW|NPW))\b/i', $nfo, $matches) && $foundName == "") { - $foundName = $matches[1]; - $methodused = "river-2"; - $this->determineCategory($rel, $foundName, $methodused); - } - if (preg_match('/([a-z0-9]+(?:\.|_| )[a-z0-9\.\_\- \'\)\(]+\-(XPD|RHyTM))\b/i', $nfo, $matches) && $foundName == "") { - $foundName = $matches[1]; - $methodused = "river-3"; - $this->determineCategory($rel, $foundName, $methodused); - } - if (preg_match('/(-PROD$|-BOV$|-NMR$|$-HAGGiS|-JUST$|CRNTV$|-MCA$|int$|-DEiTY$|-VoMiT$|-iNCiTE$|-BRUTUS$|-DCN$|-saints$|-sfm$|-lol$|-fov$|-logies$|-c4tv$|-fqm$|-jetset$|-ils$|-miragetv$|-gfvid$|-btl$|-terra$)/i', $rel['searchname']) && $foundName == "") { - $foundName = $rel['searchname']; - $methodused = "river-4"; - $this->determineCategory($rel, $foundName, $methodused); - } - - //SANTi releases - if (preg_match('/\b([a-z0-9]+(?:\.|_| )[a-z0-9\.\_\- \']+\-santi)\b/i', $nfo, $matches) && $foundName == "") { - $foundName = $matches[1]; - $methodused = "SANTi"; - $this->determineCategory($rel, $foundName, $methodused); - } - - //INSPiRAL releases - if (preg_match('/^([a-z0-9]+(?:\.|_| )[a-z0-9\.\_\- ]+ \- INSPiRAL)\s+/im', $nfo, $matches) && $foundName == "") { - $foundName = $matches[1]; - $methodused = "INSPiRAL"; - $this->determineCategory($rel, $foundName, $methodused); - } - - //CIA releases - if (preg_match('/Release NAME.*?\:.*?([a-z0-9][a-z0-9\.\ ]+)\b.*?([a-z0-9][a-z0-9\.\ ]+\-CIA)\b/is', $nfo, $matches) && $foundName == "") { - $foundName = $matches[1] . $matches[2]; - $methodused = "CIA"; - $this->determineCategory($rel, $foundName, $methodused); - } - - //HDChina releases - if (preg_match('/HDChina/', $nfo) && $foundName == "") { - if (preg_match('/Disc Title\:.*?\b([a-z0-9\ \.\-\_()]+\-HDChina)/i', $nfo, $matches)) { - $foundName = $matches[1]; - $methodused = "HDChina"; - $this->determineCategory($rel, $foundName, $methodused); - } - } - - //Pringles - if (preg_match('/PRiNGLES/', $nfo) && $foundName == "") { - if (preg_match('/is giving you.*?\b([a-z0-9 ]+)\s/i', $nfo, $matches)) { - $foundName = $matches[1]; - $foundName = rtrim($foundName); - $foundName = ltrim($foundName); - } - if (preg_match('/this release.*?((19|20)\d{2})/i', $nfo, $matches)) { - $foundName = $foundName . "." . $matches[1]; - $foundName = rtrim($foundName); - } - if (preg_match('/\[x\] (Danish|Norwegian|Swedish|Finish|Other)/i', $nfo, $matches)) { - $foundName = $foundName . "." . $matches[1]; - } - if (preg_match('/\[x\] (DVD9|DVD5)/i', $nfo, $matches)) { - $foundName = $foundName . "." . $matches[1]; - } - $foundName = $foundName . "-PRiNGLES"; - $methodused = "Pringles"; - $this->determineCategory($rel, $foundName, $methodused); - } - - //Fairlight releases - if (preg_match('/\/Team FairLight/', $nfo) && $foundName == "") { - $title = null; - $os = null; - $method = null; - if (preg_match('/\b([a-z0-9\ \- \_()\.]+) \(c\)/i', $nfo, $matches)) { - $title = $matches['1']; - $foundName = $title; - } - $foundName = $foundName . "-FLT"; - $methodused = "FairLight"; - $this->determineCategory($rel, $foundName, $methodused); - } - - //CORE releases - if (preg_match('/Supplied.*?\:.*?(CORE)/', $nfo) || preg_match('/Packaged.*?\:.*?(CORE)/', $nfo) && $foundName == "") { - $title = null; - $os = null; - $method = null; - if (preg_match('/\b([a-z0-9\.\-\_\+\ ]+) \*[a-z0-9]+\*/i', $nfo, $matches)) { - $title = $matches['1']; - $foundName = $title; - } - if (preg_match('/Crack\/.*?\:.*?([a-z]+)/i', $nfo, $matches)) { - $method = $matches['1']; - $foundName = $foundName . " " . $method; - } - if (preg_match('/OS.*?\:.*?([a-z]+)/i', $nfo, $matches)) { - $os = $matches['1']; - $foundName = $foundName . " " . $os; - } - $foundName = $foundName . "-CORE"; - $methodused = "CORE"; - $this->determineCategory($rel, $foundName, $methodused); - } - - //CompleteRelease - if (preg_match('/Complete name.*?([a-z0-9].*?\-[a-z0-9]+)\b/i', $nfo, $matches) && $foundName == "") { - $foundName = $matches[1]; - $methodused = "CompleteRelease"; - $this->determineCategory($rel, $foundName, $methodused); - } - - //Livesets - if (preg_match('/\nLivesets.*?\n.*?\n.*?\n.*?\n.*?\n(?P\w.*?)\n(?P\w.*?)\n/im', $nfo, $matches) && $foundName == "") { - $artist = $matches['name']; - $title = $matches['album']; - $source = null; - $year = null; - if (preg_match('/Year.*?\:{1,2} ?(?P(19|20)\d{2})/i', $nfo, $matches)) { - $year = $matches[1]; - } elseif (preg_match('/date.*?\:.*?(?P(19|20)\d{2})/i', $nfo, $matches)) { - $year = $matches[1]; - } - if (preg_match('/(web|cable|sat)/i', $title)) { - $source = ""; - } elseif (preg_match('/Source.*?\:{1,2} ?(?P.*?)(\s{2,}|\s{1,})/i', $nfo, $matches)) { - $source = $matches[1]; - if ($source == "Satellite") { - $source = "Sat"; - } - } - if ($artist) { - $tempname = $artist; - if ($title) { - $tempname = $tempname . "-" . $title; - } - if ($source) { - $tempname = $tempname . "-" . $source; - } - if ($year) { - $tempname = $tempname . "-" . $year; - } - $tempname = preg_replace("/[^a-zA-Z,0-9,\-,\s]/", "", $tempname); - $foundName = $tempname; - $methodused = "Live Sets"; - $this->determineCategory($rel, $foundName, $methodused); - } - } - - //Typical scene regex - if (preg_match('/(?PSource[\s\.]*?:|fix for nuke)?(?:\s|\]|\[)?(?P[a-z0-9\'\-]+(?:\.|_)[a-z0-9\.\-_\'&]+\-[a-z0-9&]+)(?:\s|\[|\])/i', $nfo, $matches) && $foundName == "") { - if (empty($matches['source'])) { - if (!preg_match('/usenet\-space/i', $matches['name'])) { - $foundName = $matches['name']; - $methodused = "Scene"; - $this->determineCategory($rel, $foundName, $methodused); - } - } - } - } - - //The Big One - if (preg_match_all('/([a-z0-9\ ]+)\.{1,}(\:|\[)(?P.*)(\s{2}|\s{1})/i', $nfo, $matches) && $foundName == "") { - $lut = []; - foreach ($matches[1] as $key => $k) { - $lut[str_replace(' ', '', strtolower(trim($k)))] = trim($matches[3][$key]); - } - $year = null; - $vidsource = null; - $series = null; - $season = null; - $episode = null; - $language = null; - $artist = null; - $source = null; - - foreach ($lut as $k => $v) { - $v = rtrim($v); - if (!$year && preg_match('/((19|20)\d{2})/', $v, $matches)) { - $year = $matches[1]; - } - if (!$vidsource && preg_match('/(xvid|x264|h264|wmv|divx)/i', $v, $matches)) { - $vidsource = $matches[1]; - } - - if (!$season && preg_match('/(season|seizon).*?(\d{1,3})/i', $v, $matches)) { - $season = $matches[2]; - } - if (!$episode && preg_match('/(Episode|ep).*?(\d{1,3})/i', $v, $matches)) { - $episode = $matches[2]; - } - } - - if (isset ($lut['artist'])) { - $del = "-"; - if (isset ($lut['artist'])) { - $lut['artist'] = trim($lut['artist'], " "); - $tempname = $lut['artist']; - } - if (isset ($lut['title'])) { - $tempname = $tempname . $del . $lut['title']; - } - if (isset ($lut['album']) && !isset ($lut['title'])) { - $tempname = $tempname . $del . $lut['album']; - } - if (isset ($lut['track']) && !isset ($lut['title']) && !isset ($lut['album'])) { - $tempname = $tempname . $del . $lut['track']; - } - if (!isset ($lut['source'])) { - $lut['source'] = 'WEB'; - } - if (isset ($lut['source']) && !preg_match('/SAT/i', $tempname)) { - $tempname = $tempname . $del . $lut['source']; - } - if (!preg_match('/(19|20)\d{2}/', $tempname) && $year) { - $tempname = $tempname . $del . $year; - } - if (isset ($lut['ripper'])) { - $tempname = $tempname . $del . $lut['ripper']; - } - $tempname = preg_replace("/[^a-zA-Z,0-9,\-,\&,\s]/", "", $tempname); - $tempname = preg_replace("/[ ]{2,}/", "", $tempname); - $methodused = "The Big One Music"; - $foundName = $tempname; - $this->determineCategory($rel, $foundName, $methodused); - } else if (isset ($lut['title'])) { - $del = " "; - if (isset ($lut['series'])) { - $tempname = $lut['series']; - } - $tempname = $tempname . $del . $lut['title']; - if ($season && $episode) { - $tempname = $tempname . $del . "S" . str_pad($season, 2, '0', STR_PAD_LEFT) . 'E' . str_pad($episode, 2, '0', STR_PAD_LEFT); - } else { - if ($season) { - $tempname = $tempname . $del . "S" . $season; - } - if ($episode) { - $tempname = $tempname . $del . "Ep" . $episode; - } - } - if (isset ($lut['source']) && !preg_match('/SAT/i', $lut['title'])) { - $tempname = $tempname . $del . $lut['source']; - } - if (!preg_match('/(19|20)\d{2}/', $tempname) && $year) { - $tempname = $tempname . $del . $year; - } - if (isset($lut['language'])) { - $tempname = $tempname . $del . $lut['language']; - } - if ($vidsource) { - $tempname = $tempname . $del . $vidsource; - } - $tempname = preg_replace("/ /", " ", $tempname); - $tempname = preg_replace("/[^a-zA-Z,0-9,\-,\&,\s]/", " ", $tempname); - $tempname = preg_replace("/[ ]+/", " ", $tempname); - $methodused = "The Big One Other"; - $foundName = $tempname; - $this->determineCategory($rel, $foundName, $methodused); - } - } - - /// - ///unable to extract releasename from nfo, try the rar file - /// - if ($rel['filenames'] && $foundName == '') { - $this->releasefilesprocessed++; - $files = explode(',', $rel['filenames']); - if (![$files]) { - $files = [$files]; - } - - // Scene regex - $sceneRegex = '/([a-z0-9\'\-\.\_\(\)\+\ ]+\-[a-z0-9\'\-\.\_\(\)\ ]+)(.*?\\\\.*?|)\.(?:\w{3,4})$/i'; - - foreach ($files AS $file) { - // Petje Releases - if (preg_match('/Petje \/', $rel['fromname'], $matches3) && $foundName == '') { - if (preg_match('/.*\.(mkv|avi|mp4|wmv|divx)/', $file, $matches4)) { - $array_new = explode('\\', $matches4[0]); - foreach ($array_new as $item) { - if (preg_match('/.*\((19|20\d{2})\)$/', $item, $matched)) { - //echo $matched[0].".720p.x264-Petje"; - //print_r($matched); - $foundName = $matched[0] . ".720p.x264-Petje"; - $methodused = "Petje"; - $this->determineCategory($rel, $foundName, $methodused); - break 2; - } - } - } - } - - //3D Remux - if (preg_match('/.*Remux\.mkv/', $file, $matches4)) { - $foundName = str_replace(".mkv", "", $matches4[0]); - $methodused = "3D Remux"; - $this->determineCategory($rel, $foundName, $methodused); - } - //QoQ Extended - if (preg_match('/Q\-sbuSLN.*/i', $file, $matches4)) { - $new1 = preg_match('/( )?(\.wmv|\.divx|\.avi|\.mkv)/i', $matches4[0], $matched); - $new2 = str_replace($matched[0], "", $matches4[0]); - $foundName = strrev($new2); - $methodused = "QoQ Extended"; - $this->determineCategory($rel, $foundName, $methodused); - } - // Directory\Title.Year.Format.Group.mkv - if (preg_match('/(?<=\\\).*?BLURAY.(1080|720)P.*?KNORLOADING(?=\.MKV)/i', $file, $matches3) && $foundName == '') { - $foundName = $matches3['0']; - $methodused = "a.b.hdtv.x264"; - $this->determineCategory($rel, $foundName, $methodused); - } - // ReleaseGroup.Title.Format.mkv - if (preg_match('/(?<=swg_|swghd\-|lost\-|veto\-|kaka\-|abd\-|airline\-|daa\-|data\-|japhson\-|ika\-|lng\-|nrdhd\-|saimorny\-|sparks\-|ulshd\-|nscrns\-|ifpd\-|invan\-|an0\-|besthd\-|muxhd\-|s7\-).*?((1080|720)|P)(?=\.MKV)/i', $file, $matches3) && $foundName == '') { - $foundName = str_replace("_", ".", $matches3['0']); - $methodused = "a.b.hdtv.x264"; - $this->determineCategory($rel, $foundName, $methodused); - } - // Title.Format.ReleaseGroup.mkv - if (preg_match('/.*?(1080|720)(|P).(SON)/i', $file, $matches3) && $foundName == '') { - $foundName = str_replace("_", ".", $matches3['0']); - $methodused = "a.b.hdtv.x264"; - $this->determineCategory($rel, $foundName, $methodused); - } - - //epubmobi - if (preg_match('/.*\.(epub|mobi|azw3|pdf|prc|lit|rtf|azw|cbr|doc)/', $file, $matches4)) { - $foundName = str_replace(".doc", "", str_replace(".cbr", "", str_replace(".prc", "", str_replace(".pdf", "", str_replace(".azw3", "", str_replace(".mobi", "", str_replace(".epub", "", str_replace(".rtf", "", str_replace(".azw", "", str_replace(".lit", "", $matches4[0])))))))))); - $methodused = "EpubMobi"; - $this->determineCategory($rel, $foundName, $methodused); - } - - //Reversed name - if (preg_match('/[a-z0-9\(\)\'\!\,\.\-\ \_]+(BEW|p027|p0801)[a-z0-9\(\)\,\'\!\ \-\.]+/i', $file, $matches4)) - { - $new1 = preg_match('/( )?(\.m2ts|\.wmv|\.avi|.mp4|\.mkv)/i', $matches4[0], $matched); - $new2 = str_replace($matched[0], "", $matches4[0]); - $foundName = strrev($new2); - $methodused = "Reversed"; - $this->determineCategory($rel, $foundName, $methodused); - } - - //Check rarfile contents for a scene name - if (preg_match($sceneRegex, $file, $matches) && $foundName == '') { - //Simply Releases Toppers - if (preg_match('/(\\\\)(?P.*?ReleaseS Toppers)/', $file, $matches1) && $foundName == '') { - $foundName = $matches1['name']; - $methodused = "Release Files-1"; - $this->determineCategory($rel, $foundName, $methodused); - - } - //Scene format no folder. - if (preg_match('/^([a-z0-9\.\_\- ]+\-[a-z0-9\_]+)(\\\\|)$/i', $matches[1]) && $foundName == '') { - if (strlen($matches['1']) >= 15) { - $foundName = $matches['1']; - $methodused = "Scene format no folder."; - $this->determineCategory($rel, $foundName, $methodused); - } - } - - //Check to see if file is inside of a folder. Use folder name if it is - if (preg_match('/^(.*?\\\\)(.*?\\\\|)(.*?)$/i', $file, $matches1) && $foundName == '') { - If (preg_match('/^([a-z0-9\.\_\- ]+\-[a-z0-9\_]+)(\\\\|)$/i', $matches1['1'], $res)) { - $foundName = $res['1']; - $methodused = "Release Files-1"; - $this->determineCategory($rel, $foundName, $methodused); - } - If (preg_match('/(?!UTC)([a-z0-9]+[a-z0-9\.\_\- \'\)\(]+(\d{4}|HDTV).*?\-[a-z0-9]+)/i', $matches1['1'], $res) && $foundName == '') { - $foundName = $res['1']; - $methodused = "Release Files-2"; - $this->determineCategory($rel, $foundName, $methodused); - } - If (preg_match('/^([a-z0-9\.\_\- ]+\-[a-z0-9\_]+)(\\\\|)$/i', $matches1['2'], $res) && $foundName == '') { - $foundName = $res['1']; - $methodused = "Release Files-3"; - $this->determineCategory($rel, $foundName, $methodused); - } - If (preg_match('/^([a-z0-9\.\_\- ]+\-(?:.+)\(html\))\\\\/i', $matches1['1'], $res) && $foundName == '') { - $foundName = $res['1']; - $methodused = "Release Files-4"; - $this->determineCategory($rel, $foundName, $methodused); - } - - } - If (preg_match('/(?!UTC)([a-z0-9]+[a-z0-9\.\_\- \'\)\(]+(\d{4}|HDTV).*?\-[a-z0-9]+)/i', $file, $matches2) && $foundName == '') { - $foundName = $matches2['1']; - $methodused = "Release Files-4"; - $this->determineCategory($rel, $foundName, $methodused); - } - } - } - - //RAR file contents release name matching - - /*if (sizeof($files) > 0 && $foundName == '') - { - echo "RAR checking\n"; - //Loop through releaseFiles to find a match - foreach($files as $rarFile) - { - //echo "-{$rarFile}\n"; - if ($foundName == '') - { - //Lookup name via reqid (filename) - if (preg_match('/\.(avi|mkv|mp4|mov|wmv|iso|img|gcm|ps3|wad|ac3|nds|bin|cue|mdf)/i', $rarFile)) - { - $this->pdo->getSetting('reqidurl; - $lookupUrl = 'http://allfilled/query.php?t=alt.binaries.srrdb&reqid='.urlencode(basename($rarFile)); - echo '-lookup: '.$lookupUrl."\n"; - $xml = Utility::getUrl(['url' => $lookupUrl]); - //$xml = false; - - if ($xml !== false) - { - $xmlObj = @simplexml_load_string($xml); - $arrXml = objectsIntoArray($xmlObj); - - if (isset($arrXml["item"]) && is_array($arrXml["item"]) && isset($arrXml["item"]["@attributes"]) && is_array($arrXml["item"]["@attributes"])) - { - $foundName = $arrXml["item"]["@attributes"]["title"]; - } - } - } - } - } - }*/ - - } - - // do par check if user has elected for downloading extra stuff - if ($this->pdo->getSetting('unrarpath') != '' && $foundName == "") { - $nzb = new NZB(); - $nzbfile = $nzb->NZBPath($rel['guid']); - $nzbInfo = new nzbInfo; - $nzbInfo->loadFromFile($nzbfile); - if (!empty($nzbInfo->parfiles) && empty($nzbInfo->rarfiles) && empty($nzbInfo->audiofiles)) { - $nntp = new NNTP; - $nntp->doConnect(); - - if ($this->verbose) echo "Checking Par\n"; - foreach ($nzbInfo->parfiles as $parfile) { - $this->parsprocessed++; - $parBinary = $nntp->getMessages($parfile['groups'][0], $parfile['segments'], $this->verbose); - if ($parBinary) { - $par2 = new Par2info(); - $par2->setData($parBinary); - if (!$par2->error) { - $parFiles = $par2->getFileList(); - foreach ($parFiles as $file) { - if (isset($file['name']) && (preg_match('/.*part0*1\.rar$/iS', $file['name'], $matches) || preg_match('/(?!part0*1)\.rar$/iS', $file['name'], $matches) || preg_match('/\.001$/iS', $file['name'], $matches))) { - $foundName = preg_replace('/^(.*)(\.part0*1\.rar|\.rar|\.001)$/i', '\1', $file['name']); - $methodused = "Par file"; - $this->determineCategory($rel, $foundName, $methodused); - break; - } - } - } - } - unset($parBinary); - - if ($foundName != "") - break; - } - $nntp->doQuit(); - } - } - - /// - /// This is a last ditch effort, build a ReleaseName from the Nfo - /// - if ($nfo && ($foundName == "" || $methodused == 'Scene format no folder.')) { - //LastNfoAttempt - if (preg_match('/tt(\d{7})/i', $nfo, $matches) && $foundName == "") { - $movie = new Movie(); - $imdbId = $matches[1]; - $movCheck = $movie->fetchImdbProperties($imdbId); - $buffer = Utility::getUrl(['url' => 'http://akas.imdb.com/title/tt' . $imdbId . '/']); - if (!preg_match('/content\=\"video\.tv\_show\"/i', $buffer)) { - if (isset($movCheck['title'])) { - $foundName = $movCheck['title']; - if (!preg_match('/(19|20)\d{2}/i', $foundName)) { - $foundName = $foundName . "." . (isset($movCheck['year']) ? $movCheck['year'] : ""); - } - if (preg_match('/language.*?\b([a-z0-9]+)\b/i', $nfo, $matches)) { - if (!preg_match('/English/i', $matches[1])) { - $foundName = $foundName . "." . $matches[1]; - } - } - if (preg_match('/audio.*?\b(\w+)\b/i', $nfo, $matches)) { - if (preg_match('/(Chinese|German|Dutch|Spanish|Hebrew|Finnish|Norwegian)/i', $matches[1])) { - $foundName = $foundName . "." . $matches[1]; - } - } - if (preg_match('/(video|resolution|video res).*?(1080|720|816|820|272|1280 @|528|1920)/i', $nfo, $matches)) { - if ($matches[2] == '1280 @') { - $matches[2] = '720'; - } - if ($matches[2] == '1920') { - $matches[2] = '1080'; - } - $foundName = $foundName . "." . $matches[2]; - } - if (preg_match('/source.*?\b(DVD9|DVD5|BDRIP|DVD\-?RIP|BLURAY|BD)\b/i', $nfo, $matches)) { - if ($matches[1] == 'BD') { - $matches[1] = 'Bluray.x264'; - } - $foundName = $foundName . "." . $matches[1]; - } - if (preg_match('/(video|resolution|video res).*?(XVID|X264|WMV)/i', $nfo, $matches)) { - $foundName = $foundName . "." . $matches[2]; - } - if (preg_match('/audio.*?\b(DTS|AC3)\b/i', $nfo, $matches)) { - $foundName = $foundName . "." . $matches[1]; - } - - $foundName = $foundName . "-NoGroup"; - $methodused = "LastNfoAttempt"; - $this->determineCategory($rel, $foundName, $methodused); - } - } - } - } - - if ($foundName == '' && $this->verbose) { - echo "ReleaseID: " . $rel["rid"] . "\n" . - " Group: " . $rel["groupname"] . "\n" . - " Old Name: " . $rel["name"] . "\n" . - " Old SearchName: " . $rel["searchname"] . "\n" . - " Status: No new name found.\n\n"; - } - } - } - - if ($this->verbose) { - echo $this->releasestocheck . " releases checked\n" . - $this->nfosprocessed . " of " . $this->releasestocheck . " releases had nfo's processed\n" . - $this->parsprocessed . " of " . $this->releasestocheck . " releases had par's processed\n" . - $this->releasefilesprocessed . " of " . $this->releasestocheck . " releases had releasefiles processed\n" . - $this->numupdated . " of " . $this->releasestocheck . " releases " . ($this->releasestocheck > 0 ? (floor($this->numupdated / $this->releasestocheck * 100)) . "%" : "") . " changed\n"; - } - } - - /** - * Work out the category based on the name, resets to null if no category matched. - */ - private function determineCategory($rel, &$foundName, &$methodused) - { - $categoryID = null; - $category = new Categorize(); - $categoryID = $category->determineCategory($rel['groupname'], $foundName); - if (($methodused == 'a.b.hdtv.x264') && ($rel['groupname'] == 'alt.binaries.hdtv.x264')) { - $categoryID = Category::CAT_MOVIE_HD; - } - if (($categoryID == $rel['categoryid'] || $categoryID == '7900') || ($foundName == $rel['name'] || $foundName == $rel['searchname'])) { - $foundName = null; - $methodused = null; - } else { - $foundName = str_replace(''', '', trim(html_entity_decode($foundName))); - $name = str_replace(' ', '_', $foundName); - $searchname = str_replace('_', ' ', $foundName); - echo - PHP_EOL . - ColorCLI::headerOver('ReleaseID: ') . ColorCLI::primaryOver($rel['rid']) . PHP_EOL . - ColorCLI::headerOver(' Group: ') . ColorCLI::primaryOver($rel['groupname']) . PHP_EOL . - ColorCLI::headerOver(' Old Name: ') . ColorCLI::primaryOver($rel['name']) . PHP_EOL . - ColorCLI::headerOver(' Old SearchName: ') . ColorCLI::primaryOver($rel['searchname']) . PHP_EOL . - ColorCLI::headerOver(' New Name: ') . ColorCLI::primaryOver($name) . PHP_EOL . - ColorCLI::headerOver(' New SearchName: ') . ColorCLI::primaryOver($searchname) . PHP_EOL . - ColorCLI::headerOver(' Old Cat: ') . ColorCLI::primaryOver($rel['categoryid']) . PHP_EOL . - ColorCLI::headerOver(' New Cat: ') . ColorCLI::primaryOver($categoryID) . PHP_EOL . - ColorCLI::headerOver(' Method: ') . ColorCLI::primaryOver($methodused) . PHP_EOL ; - if (!$this->echoonly) { - $this->pdo->queryExec(sprintf("update releases SET name = %s, searchname = %s, categoryid = %d, imdbid = NULL, rageid = -1, bookinfoid = NULL, musicinfoid = NULL, consoleinfoid = NULL WHERE releases.id = %d", $this->pdo->escapeString($name), $this->pdo->escapeString($searchname), $categoryID, $rel['rid'])); - } - $this->numupdated++; - } - } - - /** - * Perform cleanup of names and categories. - */ - public function cleanup() - { - echo "PostPrc : Performing cleanup \n"; - $catsql = "select id from groups"; - $res = $this->pdo->query($catsql); - foreach ($res as $r2) { - $sql = sprintf("select r.id, name, searchname, categoryid, size, totalpart, musicinfoid, preid, groupid, rn.id as nfoid from releases r left outer join releasenfo rn ON rn.releaseid = r.id where groupid = %d", $r2['id']) . " %s "; - $unbuf = $this->pdo->queryDirect(sprintf($sql, ($this->limited ? " and r.adddate BETWEEN NOW() - INTERVAL 1 DAY AND NOW() " : ""))); - - while ($r = $this->pdo->getAssocArray($unbuf)) { - /// - ///This Section will remove releases based on specific criteria - /// - - //Remove releases if they include Parts info in the release name, as they are not full releases. - if (preg_match('/(\[|\()\d{1,4}\/\d{1,4}(\]|\))/', $r['name'])) { - $this->handleClean($r, "Modifying Release due to Parts in Release Name: " . $r['name'] . " - ", true); - continue; - } - - //Remove releases if they include file of in the release name, as they are not full releases. - if (preg_match('/file \d+ of \d+/i', $r['name'])) { - $this->handleClean($r, "Modifying Release due to File of in Release Name: " . $r['name'] . " - ", true); - continue; - } - - //Remove releases if they include file of in the release name, as they are not full releases. - if (preg_match('/\[\d+ of \d+\]/i', $r['name'])) { - $this->handleClean($r, "Modifying Release due to 23 of 23 in Release Name: " . $r['name'] . " - ", true); - continue; - } - - //Remove releases if the name is numbers only. - if (preg_match('/^[0-9\.\ \-\_\[\]\(\)\@\#]+$/', $r['name'])) { - $this->handleClean($r, "Modifying Release because it is Number Only in Release Name: " . $r['name'] . " - "); - continue; - } - - //Remove releases if it starts with a IMDBID. - if (preg_match('/^tt\d{6}/i', $r['name'])) { - $this->handleClean($r, "Modifying Release because it starts with a IMDB id: " . $r['name'] . " - "); - continue; - } - - //Remove releases if the name contains http(s): . - if (preg_match('/http(s|)\:/i', $r['name'])) { - $this->handleClean($r, "Modifying Release because it contains HTTP in the Release Name: " . $r['name'] . " - ", true); - continue; - } - - //Remove releases if the name contains http(s): . - // try stripos, its faster than preg_match - if (preg_match('/sample/i', $r['name']) && $r['categoryid'] > 5000 && $r['categoryid'] < 5999) { - $this->handleClean($r, "Modifying Release because it contains Sample in the Release Name: " . $r['name'] . " - ", true); - continue; - } - - /// - ///End of Remove by name section - /// - - /// - ///This section will cleanup releases based on the category and things such as release size and release name length - /// - - switch ($r['categoryid']) { - //CONSOLE - case Category::CAT_GAME_NDS: //NDS - if ($r['size'] < 2000000) { - $this->handleClean($r, "Modifying Release Due to NDS Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 11 && !preg_match('/\([a-z]{2,3}\)/i', $r['name']) && !$r['preid']) { - $this->handleClean($r, "Modifying Release Due to NDS Release Length: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_GAME_PSP: //PSP - if ($r['size'] < 100000 && $r['name'] != 'DLC') { - $this->handleClean($r, "Modifying Release Due to PSP Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 13 && !$r['preid']) { - $this->handleClean($r, "Modifying Release PSP Due to Release Length: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_GAME_WII: //Wii - if ($r['size'] < 9000000 && $r['totalpart'] < 10) { - $this->handleClean($r, "Modifying Release Wii Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 14 && !$r['preid']) { - $this->handleClean($r, "Modifying Release Wii ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_GAME_XBOX: //Xbox - if ($r['size'] < 1500000) { - $this->handleClean($r, "Modifying Release Xbox Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 14 && !$r['preid']) { - $this->handleClean($r, "Modifying Release Xbox ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_GAME_XBOX360: //Xbox 360 - if ($r['size'] < 50000000) { - $this->handleClean($r, "Modifying Release Xbox360 Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 14 && !$r['preid']) { - $this->handleClean($r, "Modifying Release Xbox360 ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_GAME_WIIWARE: //WiiWare + VC - if ($r['size'] < 1000000 && $r['totalpart'] <= 1) { - $this->handleClean($r, "Modifying Release Wiiware Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 14 && !$r['preid']) { - $this->handleClean($r, "Modifying Release Wiiware ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_GAME_XBOX360DLC: //Xbox 360DLC - if ($r['size'] < 50000000) { - //I Haven't figured out what to do for this group yet... - //handleClean($r,true); - continue; - } - if (strlen($r['name']) < 16 && !$r['preid']) { - $this->handleClean($r, "Modifying Release Xbox 360 DLC ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_GAME_PS3: //PS3 - if ($r['size'] < 100000) { - $this->handleClean($r, "Modifying Release Due to PS3 Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 14 && !$r['preid']) { - $this->handleClean($r, "Modifying Release PS3 Due to Release Length: " . $r['name'] . " - "); - continue; - } - break; - - //MOVIES - case Category::CAT_MOVIE_FOREIGN: //Foreign Movies - if (($r['size'] < 10000000 || $r['totalpart'] <= 6) && !preg_match('/(fix|pack)/i', $r['name'])) { - $this->handleClean($r, "Modifying Release Foreign Movie Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 16 && !preg_match('/(fix|pack|\b((19|20)\d{2})\b)/i', $r['name']) && !$r['preid']) { - $this->handleClean($r, "Modifying Release Foreign Movies ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_MOVIE_OTHER: //Other Movies - if (($r['size'] < 10000000 || $r['totalpart'] <= 6) && !preg_match('/(fix|pack)/i', $r['name'])) { - $this->handleClean($r, "Modifying Release Other Movies Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 24 && !preg_match('/(fix|pack|\b((19|20)\d{2})\b)/i', $r['name']) && !$r['preid']) { - $this->handleClean($r, "Modifying Release Other Movies ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_MOVIE_SD: //SD Movies - if (($r['size'] < 10000000 || $r['totalpart'] <= 6) && !preg_match('/(fix|pack)/i', $r['name'])) { - $this->handleClean($r, "Modifying Release SD Movie Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 21 && !preg_match('/(fix|pack|\b((19|20)\d{2})\b)/i', $r['name']) && !$r['preid']) { - $this->handleClean($r, "Modifying Release SD Movies ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_MOVIE_HD: //HD Movies - if (($r['size'] < 60000000 || $r['totalpart'] <= 6) && !preg_match('/(fix|pack)/i', $r['name'])) { - $this->handleClean($r, "Modifying Release HD Movie Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 21 && !preg_match('/(fix|pack|\b((19|20)\d{2})\b)/i', $r['name']) && !$r['preid']) { - $this->handleClean($r, "Modifying Release HD Movies ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_MOVIE_BLURAY: //Bluray Movies - if (($r['size'] < 60000000 || $r['totalpart'] <= 6) && !preg_match('/(fix|pack)/i', $r['name'])) { - $this->handleClean($r, "Modifying Release Bluray Movie Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 21 && !preg_match('/(fix|pack|\b((19|20)\d{2})\b)/i', $r['name']) && !$r['preid']) { - $this->handleClean($r, "Modifying Release Bluray Movies ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_MOVIE_3D: //3D Movies - if (($r['size'] < 60000000 || $r['totalpart'] <= 6) && !preg_match('/(fix|pack)/i', $r['name'])) { - $this->handleClean($r, true); - continue; - } - if (strlen($r['name']) < 15 && !preg_match('/(fix|pack|\b((19|20)\d{2})\b)/i', $r['name']) && !$r['preid']) { - $this->handleClean($r, "Modifying Release 3D Movies ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - //AUDIO - case Category::CAT_MUSIC_MP3: // MP3 - if (preg_match('/m3u/i', $r['name'])) { - $this->handleClean($r, "Modifying Release Audio MP3 Due to M3U in the name: " . $r['name'] . " - ", true); - continue; - } - if ($r['size'] < 5000000) { - $this->handleClean($r, "Modifying Release Audio MP3 Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 25 && !preg_match('/(discography|\b((19|20)\d{2})\b)/i', $r['name']) && $r['musicinfoid'] == '-2' && !$r['preid']) { - $this->handleClean($r, "Modifying Release Audio MP3 ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_MUSIC_VIDEO: // Video - if ($r['size'] < 10000000) { - $this->handleClean($r, "Modifying Release Audio Video Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 20 && !preg_match('/(discography|\b((19|20)\d{2})\b)/i', $r['name']) && $r['musicinfoid'] == '-2' && !$r['preid']) { - //echo "Modifying Release Audio Video ReleaseLEN: ".$r['name']." - "; - //handleClean($r); not sure what to - continue; - } - break; - - case Category::CAT_MUSIC_AUDIOBOOK: // Audiobook - if ($r['size'] < 10000000) { - $this->handleClean($r, "Modifying Release Audiobook Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 20 && !preg_match('/(discography|\b((19|20)\d{2})\b)/i', $r['name']) && $r['musicinfoid'] == '-2' && !$r['preid']) { - $this->handleClean($r, "Modifying Release Audiobook ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_MUSIC_LOSSLESS: // Lossless - if ($r['size'] < 10000000) { - //echo "Modifying Release Audio Lossless Size: ".$r['name']." - "; - //handleClean($r,true); - continue; - } - if (strlen($r['name']) < 20 && !preg_match('/(discography|\b((19|20)\d{2})\b)/i', $r['name']) && $r['musicinfoid'] == '-2' && !$r['preid']) { - //echo "Modifying Release Audio Lossless ReleaseLEN: ".$r['name']." - "; - //handleClean($r); - continue; - } - break; - - // PC - case Category::CAT_PC_0DAY: // 0Day - if ($r['size'] < 1500000) { - $this->handleClean($r, "Modifying Release PC 0Day Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 20 && $r['nfoid'] == null && !$r['preid']) { - $this->handleClean($r, "Modifying Release PC 0Day ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_PC_ISO: // ISO - if ($r['size'] < 1000000) { - $this->handleClean($r, "Modifying Release PC ISO Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 20 && !$r['preid']) { - $this->handleClean($r, "Modifying Release PC ISO ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_PC_MAC: // Mac - if ($r['size'] < 500000) { - $this->handleClean($r, "Modifying Release PC Mac Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 15 && !$r['preid']) { - //echo "Modifying Release PC Mac ReleaseLEN: ".$r['name']." - "; - //handleClean($r); Not sure about this yet - continue; - } - break; - - case Category::CAT_PC_MOBILEOTHER: // Mobile Other - if ($r['size'] < 500000) { - $this->handleClean($r, "Modifying Release PC Mobile Other Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 20 && !$r['preid']) { - $this->handleClean($r, "Modifying Release PC Mobile Other ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_PC_GAMES: // Games - if ($r['size'] < 1000000) { - $this->handleClean($r, "Modifying Release PC Games Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 15 && !$r['preid']) { - //echo "Modifying Release PC Games ReleaseLEN: ".$r['name']." - "; - //handleClean($r); Not sure about this yet - - continue; - } - break; - - case Category::CAT_PC_MOBILEIOS: // Ios - if ($r['size'] < 600000) { - $this->handleClean($r, "Modifying Release PC Ios Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 21 && !$r['preid']) { - $this->handleClean($r, "Modifying Release PC Ios ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_PC_MOBILEANDROID: // Android - if ($r['size'] < 600000) { - $this->handleClean($r, "Modifying Release PC Android Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 15 && !$r['preid']) { - //echo "Modifying Release PC Android ReleaseLEN: ".$r['name']." - "; - //handleClean($r); Not sure about this yet - continue; - } - break; - - // TV - case Category::CAT_TV_FOREIGN: // Foreign - if ($r['size'] < 20000000 && !preg_match('/(fix|pack)/i', $r['name'])) { - $this->handleClean($r, "Modifying Release TV Foreign Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 18 && !$r['preid']) { - $this->handleClean($r, "Modifying Release TV Foreign ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_TV_SD: // SD - if ($r['size'] < 20000000 && !preg_match('/(fix|pack)/i', $r['name'])) { - $this->handleClean($r, "Modifying Release TV SD Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 20 && !$r['preid']) { - $this->handleClean($r, "Modifying Release TV SD ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_TV_HD: // HD - if ($r['size'] < 20000000 && !preg_match('/(fix|pack)/i', $r['name'])) { - $this->handleClean($r, "Modifying Release TV HD Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 15 && !$r['preid']) { - $this->handleClean($r, "Modifying Release TV HD ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_TV_OTHER: // Other - if ($r['size'] < 20000000 && !preg_match('/(fix|pack)/i', $r['name'])) { - $this->handleClean($r, "Modifying Release TV Other Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 15 && !$r['preid']) { - $this->handleClean($r, "Modifying Release TV Other ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_TV_SPORT: // Sport - if ($r['size'] < 20000000 && !preg_match('/(fix|pack)/i', $r['name'])) { - $this->handleClean($r, "Modifying Release TV Sport Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 19 && !$r['preid']) { - $this->handleClean($r, "Modifying Release TV Sport ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_TV_ANIME: // Anime - if ($r['size'] < 20000000 && !preg_match('/(fix|pack)/i', $r['name'])) { - $this->handleClean($r, "Modifying Release TV Anime Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 15 && !$r['preid']) { - $this->handleClean($r, "Modifying Release TV Anime ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_TV_DOCU: // Docu - if ($r['size'] < 20000000 && !preg_match('/(fix|pack)/i', $r['name'])) { - $this->handleClean($r, "Modifying Release TV Docu Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 15 && !$r['preid']) { - $this->handleClean($r, "Modifying Release TV Docu ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - // XXX - case Category::CAT_XXX_DVD: // DVD - if ($r['size'] < 20000000 && !preg_match('/(fix|pack)/i', $r['name'])) { - $this->handleClean($r, "Modifying Release XXX DVD Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 20 && !$r['preid']) { - $this->handleClean($r, "Modifying Release XXX DVD ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_XXX_WMV: // WMV - if ($r['size'] < 20000000 && !preg_match('/(fix|pack)/i', $r['name'])) { - $this->handleClean($r, "Modifying Release XXX WMV Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 20 && !$r['preid']) { - $this->handleClean($r, "Modifying Release XXX WMV ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_XXX_XVID: // XVID - if ($r['size'] < 20000000 && !preg_match('/(fix|pack)/i', $r['name'])) { - $this->handleClean($r, "Modifying Release XXX XVID Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 14 && !$r['preid']) { - $this->handleClean($r, "Modifying Release XXX XVID ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_XXX_X264: // X264 - if ($r['size'] < 20000000 && !preg_match('/(fix|pack)/i', $r['name'])) { - $this->handleClean($r, "Modifying Release XXX X264 Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 15 && !$r['preid']) { - $this->handleClean($r, "Modifying Release XXX X264 ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_XXX_PACK: // PACK - if ($r['size'] < 20000000 && !preg_match('/(fix|pack)/i', $r['name'])) { - $this->handleClean($r, "Modifying Release XXX PACK Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 15 && !$r['preid']) { - $this->handleClean($r, "Modifying Release XXX PACK ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_XXX_IMAGESET: // IMAGESET - if ($r['size'] < 3000000 && !preg_match('/(fix|pack)/i', $r['name'])) { - $this->handleClean($r, "Modifying Release XXX IMAGESET Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 15 && !$r['preid']) { - $this->handleClean($r, "Modifying Release XXX IMAGESET ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_BOOK_EBOOK: // Ebook - if ($r['size'] < 50000 && !preg_match('/(fix|pack)/i', $r['name'])) { - $this->handleClean($r, "Modifying Release Misc Ebook Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 12 && !$r['preid']) { - $this->handleClean($r, "Modifying Release Misc Ebook ReleaseLEN: " . $r['name'] . " - "); - continue; - } - break; - - case Category::CAT_BOOK_COMICS: // Comic - if ($r['size'] < 50000 && !preg_match('/(fix|pack)/i', $r['name'])) { - //echo "Modifying Release MISC Comic Size: ".$r['name']." - "; - //handleClean($r,true); - continue; - } - if (strlen($r['name']) < 7 && !$r['preid']) { - //echo "Modifying Release MISC Comic ReleaseLEN: ".$r['name']." - "; - //handleClean($r); - continue; - } - break; - - //OTHER - case Category::CAT_MISC_OTHER: - if ($r['size'] < 1000000 && !preg_match('/(fix|pack)/i', $r['name'])) { - $this->handleClean($r, "Modifying Release Misc Other Size: " . $r['name'] . " - ", true); - continue; - } - if (strlen($r['name']) < 15 && !$r['preid']) { - //echo "Modifying Release MISC Other ReleaseLEN: ".$r['name']." - "; - //handleClean($r); Not sure what to do with this - continue; - } - break; - } - /// - ///End of Remove by name section - /// - - } - - $this->doClean(); - gc_collect_cycles(); - } - } - - /** - * Stores reason code and id of item to be cleaned. - */ - private function handleClean($row, $reason = "", $forceNuke = false) - { - if (!$forceNuke) { - $this->cleanup['misc'][$row['id']] = true; - if ($this->verbose) echo $reason . "Moving to Misc Other\n"; - } else { - $this->cleanup['nuke'][$row['id']] = true; - if ($this->verbose) echo $reason . "Removing Release\n"; - } - } - - /** - * Perform cleanup of all items in arrays. - */ - private function doClean() - { - - $this->numnuked += count($this->cleanup['nuke']); - $this->nummiscd += count($this->cleanup['misc']); - - if (!$this->echoonly) { - $releases = new \Releases(['Settings' => $this->pdo]); - foreach (array_keys($this->cleanup['nuke']) as $id) { - $releases->delete($id); - } - - if (count($this->cleanup['misc'])) { - $sql = 'update releases set categoryid = ' . Category::CAT_MISC_OTHER . ' where categoryid != ' . Category::CAT_MISC_OTHER . ' and id in (' . implode(array_keys($this->cleanup['misc']), ',') . ')'; - $this->pdo->queryExec($sql); - } - } - - $this->cleanup = array('nuke' => [], 'misc' => []); - } - - /** - * Removes funky chars from beginning and end of string - */ - public function removeSpecial() - { - $sql = "select id, searchname from releases where 1 = 1 "; - $sql .= ($this->limited ? "AND adddate BETWEEN NOW() - INTERVAL 1 DAY AND NOW()" : ""); - $sql .= " order by postdate desc"; - - $res = $this->pdo->queryDirect($sql); - while ($r = $this->pdo->getAssocArray($res)) { - $oldname = $r['searchname']; - - if (preg_match('/^(\:|\"|\-| )+/', $r['searchname'])) { - while (preg_match('/^(\:|\"|\-| |\_)+/', $r['searchname'])) { - $r['searchname'] = substr($r['searchname'], 1); - } - $this->updateName($r['id'], $oldname, $r['searchname']); - } - if (preg_match('/^000\-/', $r['searchname'])) { - while (preg_match('/^000\-/', $r['searchname'])) { - $r['searchname'] = substr($r['searchname'], 4); - } - $this->updateName($r['id'], $oldname, $r['searchname']); - } - if (preg_match('/(\:|\"|\-| |\/)$/', $r['searchname'])) { - while (preg_match('/(\:|\"|\-| |\/)$/', $r['searchname'])) { - $r['searchname'] = substr($r['searchname'], 0, -1); - } - $this->updateName($r['id'], $oldname, $r['searchname']); - } - if (preg_match('/\"/', $r['searchname'])) { - while (preg_match('/\"/', $r['searchname'])) { - $r['searchname'] = str_replace('"', '', $r['searchname']); - } - $this->updateName($r['id'], $oldname, $r['searchname']); - } - if (preg_match('/\-\d{1}$/', $r['searchname'])) { - while (preg_match('/\-\d{1}$/', $r['searchname'])) { - $r['searchname'] = preg_replace('/\-\d{1}$/', '', $r['searchname']); - } - $this->updateName($r['id'], $oldname, $r['searchname']); - } - if (preg_match('/\!+.*?mom.*?\!+/i', $r['searchname'])) { - while (preg_match('/\!+.*?mom.*?\!+/i', $r['searchname'])) { - $r['searchname'] = preg_replace('/\!+.*?mom.*?\!+/i', '', $r['searchname']); - } - $this->updateName($r['id'], $oldname, $r['searchname']); - } - if (preg_match('/(\\/)/i', $r['searchname'])) { - while (preg_match('/(\\/)/i', $r['searchname'])) { - $r['searchname'] = preg_replace('/(\\/)/i', '', $r['searchname']); - } - $this->updateName($r['id'], $oldname, $r['searchname']); - } - } - } - - /** - * update a release name - * - * @param $id - * @param $oldname - * @param $newname - */ - private function updateName($id, $oldname, $newname) - { - if ($this->verbose) - echo sprintf("OLD : %s\nNEW : %s\n\n", $oldname, $newname); - - if (!$this->echoonly) - $this->pdo->queryExec(sprintf("update releases set name=%s, searchname = %s WHERE id = %d", $this->pdo->escapeString($newname), $this->pdo->escapeString($newname), $id)); - } -} diff --git a/newznab/controllers/PostProcess.php b/newznab/controllers/PostProcess.php deleted file mode 100644 index 95d0a6c5d..000000000 --- a/newznab/controllers/PostProcess.php +++ /dev/null @@ -1,1001 +0,0 @@ -echooutput = (NN_ECHOCLI && $echooutput);; - $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 = []; - - // - // 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(); - } - } - - /** - * 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 Books($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 = []; - $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;$iisRar($tmpPath.$israr[$i]); - - if (is_array($tmp)) - // it's a rar - { - for ($x=0;$xopen($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; - } -} diff --git a/newznab/controllers/PowerProcess.php b/newznab/controllers/PowerProcess.php deleted file mode 100644 index 86f23e6a7..000000000 --- a/newznab/controllers/PowerProcess.php +++ /dev/null @@ -1,808 +0,0 @@ - - * @link https://github.com/lordgnu/PowerProcess - * @license MIT License - * @version 2.0 - * - * @copyright - * Copyright (c) 2011 Don Bauer - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -class PowerProcess { - const CALLBACK_STOP_PROPOGATION = -1; - const CALLBACK_IGNORE = 0; - const CALLBACK_CONTINUE = 1; - const CALLBACK_SHUTDOWN = 2; - const CALLBACK_RESTART = 3; - - /** - * Current PowerProcess version - * - * @var string - */ - public static $version = '2.1'; - - /** - * Data store for data that is to be passed to the child process which is to be spawned - * - * @var mixed - */ - public $threadData; - - /** - * Boolean variable which determines whether or not to shutdown the control process (parent) - * - * @var boolean - */ - public $complete; - - /** - * Callback array for setting callback functions based on signals that can be sent to the parent process - * - * @var array - */ - public $callbacks; - - /** - * The name of the current thread. Used by WhoAmI() - * - * @var string - */ - public $currentThread; - - /** - * Whether to log internal debug message - * - * @var boolean - */ - public $debugLogging; - - /** - * The maximum number of concurrent threads that can be running at any given time. - * - * This setting has an impact on performance for PowerProcess so play - * with it on the system you are on to determine a good value. - * 10 is a good place to start - * - * @var integer - */ - public $maxThreads; - - /** - * Array which stores the thread data for the control process (parent) to manage running child threads - * - * @var array - */ - public $myThreads; - - /** - * Session id of parent session when process is daemonized - * - * @var integer - */ - public $parentSID; - - /** - * The pid of the parent process - * - * Used after a process is forked to - * determine whether the new thread is to run the thread code - * - * @var integer - */ - public $parentPID; - - /** - * Sleep timer in micro seconds for the parent process to sleep between status checks using Tick() - * - * @var integer - */ - public $tickCount = 100; - - /** - * Whether to add a timestamp to log output - * - * @var boolean - */ - public $timeStampLogs = true; - - /** - * The maximum number of seconds a thread will be allowed to run. - * - * Set to 0 to disable a time limit (use with caution) - * - * @var integer - */ - public $threadTimeLimit; - - /** - * Location to log information messages to. - * - * Can be a file or php://stdout, php://stderr. - * Set to false to disable - * - * @var mixed - */ - public $logTo; - - /** - * When logging is enabled, this points to the socket in which to write log messages. - * - * @var resource - */ - public $logSocket; - - /** - * Signals to install for SignalDispatcher. - * - * You can use any signal constant PNCTL supports - * @link http://us3.php.net/manual/en/pcntl.constants.php - * - * @var array - */ - public $signalArray = array( - SIGUSR1, // User-Defined 1 - SIGUSR2 // User-Defined 2 - ); - - static public function SignalName($signal) { - switch ($signal) { - case SIGHUP: - return 'SIGHUP'; - case SIGINT: - return 'SIGINT'; - case SIGQUIT: - return 'SIGQUIT'; - case SIGILL: - return 'SIGILL'; - case SIGTRAP: - return 'SIGTRAP'; - case SIGABRT: - return 'SIGABRT'; - case SIGIOT: - return 'SIGIOT'; - case SIGBUS: - return 'SIGBUS'; - case SIGFPE: - return 'SIGFPE'; - case SIGUSR1: - return 'SIGUSR1'; - case SIGSEGV: - return 'SIGSEGV'; - case SIGUSR2: - return 'SIGUSR2'; - case SIGPIPE: - return 'SIGPIPE'; - case SIGALRM: - return 'SIGALRM'; - case SIGTERM: - return 'SIGTERM'; - case SIGSTKFLT: - return 'SIGSTKFLT'; - case SIGCLD: - return 'SIGCLD'; - case SIGCHLD: - return 'SIGCHLD'; - case SIGCONT: - return 'SIGCONT'; - case SIGTSTP: - return 'SIGTSTP'; - case SIGTTIN: - return 'SIGTTIN'; - case SIGTTOU: - return 'SIGTTOU'; - case SIGURG: - return 'SIGURG'; - case SIGXCPU: - return 'SIGXCPU'; - case SIGXFSZ: - return 'SIGXFSZ'; - case SIGVTALRM: - return 'SIGVTALRM'; - case SIGPROF: - return 'SIGPROF'; - case SIGWINCH: - return 'SIGWINCH'; - case SIGPOLL: - return 'SIGPOLL'; - case SIGIO: - return 'SIGIO'; - case SIGPWR: - return 'SIGPWR'; - case SIGSYS: - return 'SIGSYS'; - case SIGBABY: - return 'SIGBABY'; - case SIG_BLOCK: - return 'SIG_BLOCK'; - case SIG_UNBLOCK: - return 'SIG_UNBLOCK'; - case SIG_SETMASK: - return 'SIG_SETMASK'; - default: - return "Signal # {$signal}"; - } - } - - /** - * PowerProcess constructor. - * - * Returns an instanced PowerProcess object or dies on failure - * - * @param integer $maxThreads Max number of concurrent threads to allow at any given time - * @param integer $threadTimeLimit Maximum number of seconds a thread is allowed to live - * @param boolean $daemon Whether to start as a deamon or just a normal script - * @param string $logTo What stream to log output to - * @param boolean $debugLogging Whether to enable debug logging - * - * @return object Instanced PowerProcess object - */ - public function __construct($maxThreads = 10, $threadTimeLimit = 300, $daemon = false, $logTo = false, $debugLogging = false) { - if (function_exists('pcntl_fork') && function_exists('posix_getpid')) { - // Set the current thread name - $this->currentThread = 'CONTROL'; - - // Set the max threads setting - $this->SetMaxThreads($maxThreads); - - // Set the thread time limit setting - $this->SetThreadTimeLimit($threadTimeLimit); - - // Init the logger - $this->InitializeLogger($logTo, $debugLogging); - - if ($daemon) { - // Attempt to daemonize - if (!$this->Daemonize()) { - die("Could not daemonize"); - } else { - $this->Log("Daemonized successfully",true); - } - } else { - // Register control process PID - $this->parentPID = $this->GetPID(); - $this->parentSID = false; - $this->Log("Parent PID detected as {$this->parentPID}",true); - } - - // The the complete flag to false - $this->complete = false; - - // Install the signal handler - $this->InstallSignalHandler(); - - // Init the Thread Queue - $this->myThreads = []; - - // Log completion of startup - $this->Log("Startup process complete",true); - } else { - die("PowerProcess requires both the POSIX and PCNTL extensions to operate.\n"); - } - } - - /** - * Frees up memory - */ - public function __destruct() { - unset($this->callbacks); - unset($this->myThreads); - - // Handle any remaining signals - pcntl_signal_dispatch(); - - $this->RemoveLogger(); - } - - /** - * Executes specified program in the current process space - * - * @param string $process Path to the binary process to execute - * @param array $args Array of argument strings to pass to the program - */ - public function Exec($process, $args = null) { - if ($args == null) { - pcntl_exec($process); - } else { - pcntl_exec($process, $args); - } - } - - /** - * Returns the PID of the current process - * - * @return integer - */ - public function GetPID() { - return posix_getpid(); - } - - /** - * Returns the PID of the process that spawned this one - * - * @return integer - */ - public function GetControlPID() { - return posix_getppid(); - } - - /** - * Get the status of a running thread by name or PID - * - * @param string|integer $name The name or PID of the process for which you want status information - * @return array|boolean - */ - public function GetThreadStatus($name = false) { - if ($name === false) return false; - if (isset($this->myThreads[$name])) { - return $this->myThreads[$name]; - } else { - return false; - } - } - - /** - * Determine whether the control process is daemonized - * - * @return boolean - */ - public function IsDaemon() { - return $this->parentSID !== false; - } - - /** - * Log a message - * - * @param string $msg The message to log - * @param boolean $internal Whether this is an internal debug logging message - */ - public function Log($msg, $internal = false) { - if ($this->logSocket !== false) { - if (!$internal || $this->debugLogging) { - if ($this->timeStampLogs) { - fwrite($this->logSocket, sprintf("[%s][%-22s] %s\n", date("Y-m-d H:i:s"), $this->WhoAmI(), $msg)); - } else { - fwrite($this->logSocket, sprintf("[%-22s] %s\n", $this->WhoAmI(), $msg)); - } - } - } - } - - /** - * Restarts the control process - */ - public function Restart() { - // Build Path of Script - if (isset($_SERVER['_'])) { - $cmd = $_SERVER['_']; - $this->Log("Attempting to restart using {$cmd}",true); - } else { - $this->Log("Can not restart - Shutting down", true); - return $this->Shutdown(); - } - - // Wait for threads to complete - while ($this->ThreadCount()) { - $this->CheckThreads(); - $this->Tick(); - } - - // Remove the first arg if this is a stand-alone - if ($cmd == $_SERVER['argv'][0]) unset($_SERVER['argv'][0]); - - // Execute Restart - $this->Exec($cmd, $_SERVER['argv']); - $this->Shutdown(true); - return self::CALLBACK_IGNORE; - } - - /** - * Registers a callback function for the signal dispatcher or for special signals used by PowerProcess - * - * Special signals are: - * - 'shutdown' : Triggered on completion of the Shutdown() method - * - 'threadotl' : Triggered on killing a thread due to exceeding time limit - * - * @param int|string $signal The signal to register a callback for - * @param callback $callback The callback function - */ - public function RegisterCallback($signal, $callback = false) { - if ($callback !== false) $this->callbacks[$signal][] = $callback; - - // Register with PCNTL - if (is_int($signal)) { - $this->Log("Registering signal {$signal} with dispatcher",true); - pcntl_signal($signal, array(&$this, 'SignalDispatch')); - - // Unblock the Signal - pcntl_sigprocmask(SIG_UNBLOCK,array($signal)); - } - } - - /** - * Determines whether we should be running the control code or the thread code - * - * @return boolean - */ - public function RunControlCode() { - $this->Tick(); - if (!$this->complete) { - return $this->ControlCheck(); - } else { - $this->SignalDispatch('shutdown'); - return false; - } - } - - /** - * Determines whether we should be running the child code - * - * @return boolean - */ - public function RunThreadCode() { - return !$this->ControlCheck(); - } - - /** - * Send a signal to a process - * - * @param integer $pid - * @param integer $signal - */ - public function SendSignal($pid = 0, $signal = 0) { - if ($signal > 0 && $pid > 0) { - return posix_kill($pid, $signal) && pcntl_signal_dispatch(); - } else { - return false; - } - } - - /** - * Set the max number of threads that can be running concurrently - * - * @param integer $maxThreads The max number of threads to run concurrently - */ - public function SetMaxThreads($maxThreads = 10) { - $this->maxThreads = $maxThreads; - } - - /** - * Set the max number of seconds a thread can run before being terminated - * - * @param integer $threadTimeLimit The max number of seconds a thread can run - */ - public function SetThreadTimeLimit($threadTimeLimit = 300) { - $this->threadTimeLimit = $threadTimeLimit; - } - - /** - * Initiates the shutdown procedure for PowerProcess - * - * @param boolean $exit When set to true, Shutdown causes the script to exit - */ - public function Shutdown($exit = false) { - $this->Log("Initiating shutdown",true); - - while ($this->ThreadCount()) { - $this->CheckThreads(); - $this->Tick(); - } - - $this->complete = true; - - // Send custom shutdown signal - $this->SignalDispatch('shutdown'); - - $this->Log("Shutdown Complete"); - if ($exit) exit; - - return self::CALLBACK_IGNORE; - } - - /** - * Determines if a new process can be spawned - * - * @return boolean - */ - public function SpawnReady() { - $this->Tick(); - return ($this->ThreadCount() < $this->maxThreads); - } - - /** - * Spawn a new thread - * - * @param string $name The name of the thread to be spawned - * @param boolean $returnPid Whether to return the pid instead of boolean - * - * @return boolean|integer - */ - public function SpawnThread($name = false, $returnPid = false) { - // Check to make sure we can spawn another thread - if (!$this->SpawnReady()) { - $this->Log("The maximum number of threads are already running",true); - $this->Tick(); - return false; - } - - if ($name !== false) { - // Check to make sure there is not already a named thread with this name - if ($this->GetThreadStatus($name) !== false) { - $this->Log("There is already a thread named '{$name}' running",true); - $this->Tick(); - return false; - } - } - - $pid = pcntl_fork(); - - if ($pid) { - // We are the control thread so log the child in a queue - $index = ($name === false) ? $pid : $name; - $name = ($name === false) ? "THREAD:{$pid}" : $name; - $this->myThreads[$index] = array( - 'pid' => $pid, - 'time' => time(), - 'name' => $name - ); - $this->Log("Spawned thread: {$name}",true); - $this->Tick(); - return ($returnPid) ? $pid : true; - } else { - // We are the child thread so change the current thread var - $this->currentThread = ($name === false) ? "THREAD:".$this->GetPID() : $name; - return ($returnPid) ? $pid : true; - } - } - - /** - * Get the count of running threads - * - * @return integer - */ - public function ThreadCount() { - return count($this->myThreads); - } - - /** - * Process signals to be dispatched and sleep for a number of microseconds - */ - public function Tick() { - // Dispatch Pending Signals - pcntl_signal_dispatch(); - - // Check Running Threads - if ($this->parentPID == $this->GetPID()) $this->CheckThreads(); - - // Tick - usleep($this->tickCount); - } - - /** - * Get the name of the current thread - * - * @return string The name of the current thread - */ - public function WhoAmI() { - return $this->currentThread; - } - - // All Private Functions Below Here - /** - * Checks all running threads to make sure they are still running and their time limit has not been exceeded - * - * If a thread has exceeded it's time limit, this method will kill that process - * and dispatch the special signal 'threadotl' - */ - private function CheckThreads() { - foreach ($this->myThreads as $i => $thread) { - // Check to make sure the process is still running - if ($this->PIDDead($thread['pid']) != 0) { - // Thread is Dead - unset($this->myThreads[$i]); - } elseif ($this->threadTimeLimit > 0) { - if (time() - $thread['time'] > $this->threadTimeLimit) { - $this->KillThread($thread['pid']); - $this->Log("Thread {$thread['name']} has exceeded the thread time limit",true); - $this->SignalDispatch('threadotl'); - unset($this->myThreads[$i]); - } - } - } - } - - /** - * Check if the current process is the control process - * - * @return boolean - */ - private function ControlCheck() { - return $this->parentPID == $this->GetPID(); - } - - /** - * Attempts to daemonize the current process - * - * @return integer - */ - private function Daemonize() { - $this->Log("Attempting to Daemonize",true); - - // First need to fork - $pid = pcntl_fork(); - - // Tick to catch signals - $this->Tick(); - - if ($pid < 0) exit; // Error - if ($pid) exit; // Parent - - $this->parentSID = posix_setsid(); - - // Need to reset the parent PID - $this->parentPID = $this->GetPID(); - $this->Log("Parent PID {$this->parentPID}",true); - $this->Log("Parent SID {$this->parentSID}",true); - - return ($this->parentSID > 0); - } - - /** - * Initialize the logging stream if enabled - * - * @param string|boolean $logTo The path or stream to log to or false to disable - */ - private function InitializeLogger($logTo, $debugLogging) { - if ($logTo !== false) { - $this->logSocket = @fopen($logTo, 'w'); - $this->debugLogging = $debugLogging; - } else { - $this->logSocket = false; - $this->debugLogging = false; - } - } - - /** - * Installs the default signal handlers - */ - private function InstallSignalHandler() { - // Register the callback for thread completion - $this->RegisterCallback(SIGCHLD, array($this,'CheckThreads')); - $this->Log("SIGCHLD callback registered",true); - - // Register the callback for restart requests - $this->RegisterCallback(SIGHUP, array($this, 'Restart')); - $this->Log("SIGHUP callback registered",true); - - // Register the callback for shutdown requests - $this->RegisterCallback(SIGTERM, array($this, 'Shutdown')); - $this->Log("SIGTERM callback registered",true); - - // Install the signal handler - foreach ($this->signalArray as $signal) $this->RegisterCallback($signal); - $this->Log("Signal Dispatcher installed",true); - } - - /** - * Kill a thread by PID - * - * @param integer $pid The PID of the thread to kill - */ - private function KillThread($pid = 0) { - $this->SendSignal($pid, SIGTERM); - } - - /** - * Determine whether a child pid has exited - * - * Returns the PID of child which exited or 0 - * - * @param integer $pid The PID to check - * @return integer - */ - private function PIDDead($pid = 0) { - if ($pid > 0) { - return pcntl_waitpid($pid, $status, WUNTRACED OR WNOHANG); - } else { - return 0; - } - } - - /** - * Closes the logging stream - */ - private function RemoveLogger() { - if ($this->logSocket) { - @fclose($this->logSocket); - } - } - - /** - * Handles dispatching of signals to user-defined callbacks - * - * @param integer|string $signal - */ - public function SignalDispatch($signal) { - // Log Dispatch - $signalName = self::SignalName($signal); - $this->Log("Received signal: {$signalName}",true); - - // Check the callback array for this signal number - if (isset($this->callbacks[$signal])) { - // Execute the callback - $callStack = $this->callbacks[$signal]; - - // Run last added callbacks first (FILO) - $i = count($callStack); - while ($callback = array_pop($callStack)) { - $this->Log("Running Callback[{$i}] for signal: {$signalName}", true); - --$i; - $status = call_user_func($callback); - - // Check if we should continue - if ($status == self::CALLBACK_STOP_PROPOGATION) { - // Break out of loop - $this->Log("Callback[{$i}] for signal '{$signalName}' has stopped propogation of further callbacks", true); - break; - } - - // OK, now switch on the status - switch ($status) { - case self::CALLBACK_RESTART: - $this->Restart(); - break; - case self::CALLBACK_SHUTDOWN: - $this->Shutdown(); - break; - case self::CALLBACK_IGNORE: - case self::CALLBACK_CONTINUE: - // Do nothing :: Continue propogation - break; - default: - $this->Log("Callback[{$i}] for signal '{$signalName}' did not return a valid status"); - } - - // Continue the loop - } - } else { - // No callback registered - $this->Log("There is no callback registered for signal {$signalName}",true); - } - - // Handle SIGTERM for threads - if ($signal == 15) exit(0); - } - -}