source)){ $p["source"] = constant(Release::class . "::SOURCE_" . $entry->source); } if(isset($entry->quality)){ $p["quality"] = constant(Release::class . "::QUALITY_" . $entry->quality); } if(isset($entry->best)){ $p["best"] = $entry->best; } if(isset($entry->trusted)){ $p["trusted"] = $entry->trusted; } $this->priorities[] = $p; } } foreach (Database::getConfigKey("priority.pedantic.list", [[]]) as $entry){ if($entry{0} === "{"){ $entry = json_decode($entry); $p = []; if(isset($entry->videoCodec)){ $p["videoCodec"] = constant(Release::class . "::VIDEO_CODEC_" . $entry->videoCodec); } if(isset($entry->audioCodec)){ $p["audioCodec"] = constant(Release::class . "::AUDIO_CODEC_" . $entry->audioCodec); } if(isset($entry->crc)){ $p["crc"] = $entry->crc; } $this->pedanticPriorities[] = $p; } } $goldlist = Database::getConfigKey("filter.groups.goldlist", []); foreach ($goldlist as $k => $entry){ $this->goldlist[strtolower($entry)] = count($goldlist) - $k; } $greylist = Database::getConfigKey("filter.groups.greylist", []); foreach ($greylist as $entry){ $this->greylist[strtolower($entry)] = $entry; } $this->pedanticPreferPublic = Database::getConfigKey("priority.pedantic.preferPublic", true); } public function calculatePriority(Release $release){ $bestMatch = PHP_INT_MAX; foreach($this->priorities as $k => $match){ if(isset($match["source"]) and $match["source"] !== $release->getSource()){ continue; } if(isset($match["quality"]) and $match["quality"] !== $release->getQuality()){ continue; } if(isset($match["trusted"]) and $match["trusted"] !== $release->isTrusted()){ continue; } if(isset($match["best"]) and $match["best"] !== $release->isBest()){ continue; } if($bestMatch > $k){ $bestMatch = $k; } } return $bestMatch; } public function calculatePedanticPriority(Release $release){ $bestMatch = PHP_INT_MAX; foreach($this->pedanticPriorities as $k => $match){ if(isset($match["videoCodec"]) and $match["videoCodec"] !== $release->getVideoCodec()){ continue; } if(isset($match["audioCodec"]) and $match["audioCodec"] !== $release->getAudioCodec()){ continue; } if(isset($match["crc"]) and $match["crc"] !== ($release->getCRC() !== null)){ continue; } if($bestMatch > $k){ $bestMatch = $k; } } return $bestMatch; } /** * @param Release[] $listing * @param array $preferGroups * @return Release */ public function findBestRelease(array $listing, array $preferGroups = []){ $best = null; foreach ($listing as $entry){ if($best === null){ $best = $entry; continue; } $old = $best; $best = $this->selectBest($best, $entry, $preferGroups); Downloader::log("\"".$best->getOriginalTitle()."\" is better than \"".($old === $best ? $entry->getOriginalTitle() : $old->getOriginalTitle())."\"", "SELECTOR"); } return $best; } private function isInList(Release $release, array $list){ $c = isset($list[strtolower($release->getGroup())]) ? 1 : 0; foreach(explode("-", strtolower($release->getGroup())) as $i => $k){ if($k != "" and isset($list[$k])){ ++$c; } } return $c; } private function isInPriorityList(Release $release, array $list){ $c = isset($list[strtolower($release->getGroup())]) ? $list[strtolower($release->getGroup())] : 0; foreach(explode("-", strtolower($release->getGroup())) as $i => $k){ if($k != "" and isset($list[$k])){ if($list[$k] > $c){ $c = $list[$k]; } } } return $c; } public function selectBest(Release $e1, Release $e2, array $preferGroups = []){ $groups = []; foreach ($preferGroups as $k){ $groups[strtolower($k)] = $k; } $priority1 = $this->calculatePriority($e1); $priority2 = $this->calculatePriority($e2); if(in_array(pathinfo(trim(strtolower($e1->getOriginalTitle())), PATHINFO_EXTENSION), Database::getConfigKey("filter.extension.greylist", []))){ $priority1 += 10000; } if(in_array(pathinfo(trim(strtolower($e2->getOriginalTitle())), PATHINFO_EXTENSION), Database::getConfigKey("filter.extension.greylist", []))){ $priority2 += 10000; } if($this->isInList($e1, $this->greylist)){ $priority1 += 5000; } if($this->isInList($e2, $this->greylist)){ $priority2 += 5000; } if($this->isInList($e1, $groups)){ $priority1 -= 10000; } if($this->isInList($e2, $groups)){ $priority2 -= 10000; } if($e1->getSource() === $e2->getSource()){ if($d = $this->isInPriorityList($e1, $this->goldlist)){ $priority1 -= 1000; } if($d = $this->isInPriorityList($e2, $this->goldlist)){ $priority2 -= 1000; } } if($priority1 > $priority2){ return $e2; }elseif($priority1 < $priority2){ return $e1; } if($d = $this->isInPriorityList($e1, $this->goldlist)){ $priority1 -= 1000 * $d; } if($d = $this->isInPriorityList($e2, $this->goldlist)){ $priority2 -= 1000 * $d; } if($priority1 > $priority2){ return $e2; }elseif($priority1 < $priority2){ return $e1; } //AAAAHAHHA they are the same! //Now starts the fun part! $ppriority1 = $this->calculatePedanticPriority($e1); $ppriority2 = $this->calculatePedanticPriority($e2); if($ppriority1 > $ppriority2){ return $e2; }elseif($ppriority1 < $ppriority2){ return $e1; } if($this->pedanticPreferPublic){ $e1IsPrivate = Torrent::isPrivateTorrent($e1->getDownloadLink()); $e2IsPrivate = Torrent::isPrivateTorrent($e2->getDownloadLink()); if($e1IsPrivate and !$e2IsPrivate){ return $e2; }else if(!$e1IsPrivate and $e2IsPrivate){ return $e1; } } //This handles v2s... mostly? if($e1->getGroup() === $e2->getGroup() and $e1->getNumber() === $e2->getNumber() and $e1->getQuality() === $e2->getQuality() and $e1->getSource() === $e2->getSource() and $e1->getTitle() === $e2->getTitle() and $e1->getType() === $e2->getType()){ if($e1->getVersion() > $e2->getVersion()){ return $e1; }else if($e1->getVersion() < $e2->getVersion()){ return $e2; } } if($e1->getSeeds() > $e2->getSeeds()){ return $e1; }else if($e1->getSeeds() < $e2->getSeeds()){ return $e2; } if($e1->getUploadDate() < $e2->getUploadDate()){ return $e1; }else if($e1->getUploadDate() > $e2->getUploadDate()){ return $e2; } return $e1; } }