Skip to content

Commit

Permalink
Work-save
Browse files Browse the repository at this point in the history
Fix things.
Do stuff.
It's Friday and I've had some beers.
Write a new badass PHP logging app that developers will be stealing for years.
I think Multicurl now has a flag to turn of logging.
A recommendations function that isn't fullly actualized.
Shit, I shouldn't swear in public commits...
  • Loading branch information
d8ahazard committed Dec 1, 2018
1 parent f0ce3e5 commit c7f9551
Show file tree
Hide file tree
Showing 10 changed files with 953 additions and 40 deletions.
175 changes: 175 additions & 0 deletions MultiTail.php
@@ -0,0 +1,175 @@
<?php
namespace digitalhigh;


use Exception;
use SplFileObject;

class MultiTail {

public $lineCounts = [];
public $logs;
private $reloadTime;
private $maxLines = 5000;
private $auth;
private $noHeader;


function __construct($logs, $noHeader) {
$this->logs = $logs;
$this->noHeader = $noHeader;
}

public function load() {

}

public function fetch() {
debug("Fetching.");
$logs = $this->logs;
$contents = [];
foreach ($logs as $name => $data) {
$path = $data['path'];
$lineNumber = $data['line'];
$file = new SplFileObject($path);
if (!$file->eof()) {
$file->seek($lineNumber);
while ($file->valid()) {
$parsed = $this->parseLine($file->fgets(), $lineNumber);
if ($parsed && trim($parsed['body'])) {
$parsed['line'] = $lineNumber;
$parsed['doc'] = $name;
$contents[] = $parsed;
}
$lineNumber++;
}
}
$data['line'] = $lineNumber;
$logs[$name] = $data;
$file = null;
}
$this->logs = $logs;
usort($contents, function ($item1, $item2) {
return $item1['stamp'] <=> $item2['stamp'];
});

return array_slice($contents, ($this->maxLines) * -1);
}

private function parseLine($line, $number) {
if ($line == "; <?php die('Access denied'); ?>" . PHP_EOL) return false;
$levels = [
"DEBUG", "INFO", "WARN", "ERROR", "ALERT", "EMERGENCY", "CRITICAL", "NOTICE", "INFORMATIONAL", "PINK",
"ORANGE", "GREEN"
];
$level = "DEBUG";
$stamp = "";
$opp = [];
// Sort out things in brackets

$sploded = explode("]", $line);
foreach ($sploded as $param) {
$param = trim($param);
if ($param[0] !== "[") continue;
$param = ltrim($param, "[");
// Remove param from string
$line = str_replace("[$param]", "", $line);
// See if it's a log level
$levelSet = false;
foreach ($levels as $check) {
if (preg_match("/$check/", strtoupper($param))) {
$level = $check;
$levelSet = true;
}
}
if ($levelSet) continue;
// Otherwise, put it to misc params
$opp[] = $param;
}

// Check the remaining body for JSON
$jsonItem = false;
$ogText = "";
debug("JSON Check.");
if (preg_match('~\[\{.*\}\]~', $line, $json)) {
foreach ($json as $check) {
$result = json_decode($check, true);
if (is_array($result)) {
$jsonItem = $result;
$ogText = $check;
}
}
}

if (preg_match('~\{.*\}~', $line, $json)) {
debug("Found json.");
foreach ($json as $check) {
$result = json_decode($check, true);
if (is_array($result)) {
if (strlen($check) > strlen($ogText)) {
$jsonItem = $result;
$ogText = $check;
}
}
}
}

if ($jsonItem) $line = str_replace($ogText, "[JSON]", $line);

// Check the remaining body for a URL
$link = false;
debug("Url check.");
if (preg_match('#\bhttps?://[^,\s()<>]+(?:\([\w\d]+\)|([^,[:punct:]\s]|/))#', $line, $urls)) {
foreach($urls as $url) {
debug("Found url.");
$url = filter_var($url, FILTER_SANITIZE_URL);
if (filter_var($url, FILTER_VALIDATE_URL)) {
$line = str_replace($url, "[URL]", $line);
$link = $url;
}
if ($link) break;
}
}

// Check the remaining body for XML
debug("Markup check.");
$markups = [];
if (preg_match("/<[\s\S]*?>/", $line, $markup)) {
debug("Found meta.");
foreach ($markup as $tagged) {
if($tagged != strip_tags($tagged)){
$markups["html"] = $tagged;
$line = str_replace($tagged, "[HTML]", $line);
} else {
try {
$xmlObj = simplexml_load_string($tagged);
$line = str_replace($tagged, "[XML]", $line);
$markups["xml"] = $xmlObj;
} catch (Exception $e) {
continue;
}
}
}
}

$line = [
'stamp' => $stamp,
'level' => $level,
'params' => $opp,
'number' => $number,
'body' => $line,
'json' => $jsonItem,
'url' => $link,
'markup' => $markups
];
return $line;
}
}

function debug($msg) {
$debug = $_GET['debug'] ?? false;
if ($debug) {
//echo($msg) . PHP_EOL;
}
}

122 changes: 120 additions & 2 deletions api.php
Expand Up @@ -30,7 +30,6 @@ function analyzeRequest() {
if (!$post) write_log("-------NEW REQUEST RECEIVED-------", "ALERT");
scriptDefaults();
checkDefaults();

if (isset($_GET['revision'])) {
$rev = $GLOBALS['config']->get('general', 'revision', false);
echo $rev ? substr($rev, 0, 8) : "unknown";
Expand Down Expand Up @@ -110,6 +109,13 @@ function initialize() {
echo 'success';
bye();
}

if (isset($_GET['recommend'])) {
header("Content-Type: application/json");
echo json_encode(getRecommendations($_GET['recommend']));
die();
}

if (isset($_GET['test'])) {
$result = [];
$status = testConnection($_GET['test']);
Expand Down Expand Up @@ -4091,7 +4097,8 @@ function buildSWCache() {
$files = array_merge($files, $imgFiles);
$out = [];
foreach($files as $file) {
$file = str_replace(dirname(__FILE__),".",$file);
$hash = md5_file($file);
$file = str_replace(dirname(__FILE__),".",$file) . "?hash=$hash";
$ignore = ["main.js", ".placeholder", "Thumbs.db"];
$add = true;
foreach ($ignore as $check) {
Expand All @@ -4102,6 +4109,7 @@ function buildSWCache() {

// header("Content-Type: text/plain");
// echo join(", \n", $files);
$out = array_unique($out);
file_put_contents("./cacheItems.js", "var cacheData = " . json_encode($out));


Expand All @@ -4122,6 +4130,116 @@ function getDirContents($dir, &$results = array()){
return $results;
}

function getRecommendations($type) {
$response = [];

$server = findDevice(false, false, 'Server');
if (! $server) {
write_log("No server!", "ERROR");
}
$uri = $server['Uri'];
$key = $server['Token'];
write_log("SERVER: ".json_encode($server));
$sections = json_decode($server['Sections'], true);
$sectionId = false;
foreach($sections as $section) {
write_log("Section: ".json_encode($section));
if ($section['type'] == $type) {
$sectionId = $section['id'];
}
}
$user = $_SESSION['plexUserName'];
$urls = [
"user" => "$uri/stats/user?X-Plex-Username=$user&X-Plex-Type=$type&X-Plex-Token=$key",
"popular" => "$uri/stats/library/popular?X-Plex-Token=$key&X-Plex-Type=$type&X-Plex-Container-Size=10000",
//"genres" => "$uri/stats/tag/genre?X-Plex-Token=$key",
"added" => "$uri/library/sections/$sectionId/recentlyAdded?X-Plex-Token=$key",
"unwatched" => "$uri/library/sections/$sectionId/unwatched?X-Plex-Token=$key"
];
if ($type !== 'music') $urls['newest'] = "$uri/library/sections/$sectionId/newest?X-Plex-Token=$key";
$results = (new multiCurl($urls))->process();

$userItems = $results['user']['MediaContainer']['User'][0]['Views'][0][ucfirst($type)][0][ucfirst($type)] ?? [];
$popularItems = $results['popular']['MediaContainer']['Hub'][0]['Video'] ?? [];
write_log("Raw pop: ".json_encode($results['user']));

unset($results['user']);
unset($results['popular']);

$genreCounts = [];
$watchedItems = [];

foreach($userItems as $item) {
array_push($watchedItems, $item['ratingKey']);
$genres = explode("|",$item['genre']);
foreach($genres as $genre) {
$count = ($genreCounts[$genre] ?? 0);
$count++;
$genreCounts[$genre] = $count;
}
}
arsort($genreCounts);

write_log("We have " . count($popularItems) . " items.");
$popularKeys = [];
foreach($popularItems as &$item) {
unset($item['Users']);
array_push($popularKeys, $item['ratingKey']);
}

$rawItems = [];
$rawKeys = [];
$keys = ['art', 'rating', 'year', 'thumb', 'title', 'contentRating', 'ratingKey', 'Genre'];

foreach($results as $section => $result) {
write_log("Looping $section");
$list = $result['MediaContainer']['Video'] ?? [];
foreach ($list as $item) {
$media = [];
$ratingKey = $item['ratingKey'];
if (!in_array($ratingKey, $rawKeys)) {
foreach ($keys as $key) $media[$key] = $item[$key];
$rawItems[] = $media;
array_push($rawKeys, $ratingKey);
}
}
}

$matched = array_values(array_intersect($rawKeys, $popularKeys));
$matched = array_values(array_diff($matched, $watchedItems));
foreach($matched as $find) {
foreach($rawItems as $item) {
if ($item['ratingKey'] == $find) {
write_log("TITLE - ".$item['title']);
}
}
}

$genres = array_slice(array_keys($genreCounts),0, 5);

$recommendedItems = [];
foreach($rawItems as $item) {
$genreSets = $item['Genre'];
$keep = false;
foreach($genreSets as $set) {
if (in_array($set['tag'], $genres)) $keep = true;
}
if (in_array($item['ratingKey'], $watchedItems)) $keep = false;
if ($keep) array_push($recommendedItems, $item);
}

usort($recommendedItems, function ($item1, $item2) {
return $item2['rating'] <=> $item1['rating'];
});


write_log("Matched: ".json_encode($matched));
write_log("Genres: ".json_encode($genres));
write_log("Popular: ".json_encode($recommendedItems));

return $recommendedItems;
}

function buildWidgets($widgets) {
$widgetData = [];
foreach ($widgets as $widget) {
Expand Down

0 comments on commit c7f9551

Please sign in to comment.