From 7126d517131b4971b9731eadeb0ae0638cf8acf1 Mon Sep 17 00:00:00 2001
From: Banana
Date: Sun, 30 Aug 2026 15:56:56 +0200
Subject: [PATCH] remove imdb scraper and replace it with metacritic for movies
for now
Signed-off-by: Banana
---
CHANGELOG | 6 +-
documentation/tool-imdbweb.md | 19 -
documentation/tool-metacritic.md | 18 +
upgrade/from-version-1.8.1.md | 37 ++
upgrade/from-version-1.8.md | 2 +-
webclient/config/config-imdbweb.php.default | 50 ---
.../config/config-metacritic.php.default | 50 +++
webclient/config/config.php.default | 2 +-
webclient/i18n/deu.ini | 28 +-
webclient/i18n/eng.ini | 28 +-
...imdbweb.class.php => metacritic.class.php} | 335 +++++++-----------
...imdbweb.html => tool-metacriticMovie.html} | 16 +-
webclient/view/default/tool/tool-imdbweb.php | 223 ------------
...imdbweb.html => tool-metacriticMovie.html} | 20 +-
.../default/tool/tool-metacriticMovie.php | 187 ++++++++++
15 files changed, 469 insertions(+), 552 deletions(-)
delete mode 100644 documentation/tool-imdbweb.md
create mode 100644 documentation/tool-metacritic.md
create mode 100644 upgrade/from-version-1.8.1.md
delete mode 100644 webclient/config/config-imdbweb.php.default
create mode 100644 webclient/config/config-metacritic.php.default
rename webclient/lib/{imdbweb.class.php => metacritic.class.php} (50%)
rename webclient/view/98/tool/{tool-imdbweb.html => tool-metacriticMovie.html} (60%)
delete mode 100644 webclient/view/default/tool/tool-imdbweb.php
rename webclient/view/default/tool/{tool-imdbweb.html => tool-metacriticMovie.html} (70%)
create mode 100644 webclient/view/default/tool/tool-metacriticMovie.php
diff --git a/CHANGELOG b/CHANGELOG
index 3caf258..331303c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,4 +1,8 @@
-x.x.x - Terraniux Underground
+1.9.0 - Terraniux Underground 2026-08-30
+ * Config Update: See upgrade/from-version-1.8.1.md
+ * DB Update (non breaking): See upgrade/from-version-1.8.1.md
+ * Removed IMDB web parser since IMDB does not like cli tools anymore.
+ * Added: Metacritic as a replacement for IMDB. See upgrade/from-version-1.8.1.md
1.8.1 - Harobed Village 2026-01-06
* Config Update: See upgrade/from-version-1.8.md
diff --git a/documentation/tool-imdbweb.md b/documentation/tool-imdbweb.md
deleted file mode 100644
index 0b8358a..0000000
--- a/documentation/tool-imdbweb.md
+++ /dev/null
@@ -1,19 +0,0 @@
-# IMDB web parser tool
-
-It provides easy searching for a movie entry within https://www.imdb.com.
-Creating a new one with the selected fields or updating an existing one.
-
-You can search the exact imdb id, which is in tt* format of an entry url.
-It searches for movies only.
-
-Which fields are available for you to select, are configured in the config.imdbweb.php file to make it
-easier since not every field the tool provides are needed.
-Follow the comments in the file for more details.
-
-An option to make the target fields automatically selected by default to given values is also available
-in the config file.
-
-# Setup
-
-Rename the `config-imdbweb.php.default` to `config-imdbweb.php` in the config folder.
-Follow the comments to update the settings. Add the tool to your collection.
diff --git a/documentation/tool-metacritic.md b/documentation/tool-metacritic.md
new file mode 100644
index 0000000..2779a3b
--- /dev/null
+++ b/documentation/tool-metacritic.md
@@ -0,0 +1,18 @@
+# Metacritic web parser tool
+
+Since IMDB does not like terminal clients, Metacritic it is for now.
+
+There is no search for now.
+Search manuall and then copy the part after `movie/` from the URL and use this for the data fetch.
+
+Which fields are available for you to select, are configured in the `config.metacritic.php` file to make it
+easier since not every field the tool provides are needed.
+Follow the comments in the file for more details.
+
+An option to make the target fields automatically selected by default to given values is also available
+in the config file.
+
+# Setup
+
+Rename the `config-metacritic.php.default` to `config-metacritic.php` in the config folder.
+Follow the comments to update the settings. Add the tool to your collection.
diff --git a/upgrade/from-version-1.8.1.md b/upgrade/from-version-1.8.1.md
new file mode 100644
index 0000000..f913205
--- /dev/null
+++ b/upgrade/from-version-1.8.1.md
@@ -0,0 +1,37 @@
+# Config change
+
+Updated `BROWSER_AGENT` string. See default config file for its new value.
+
+# DB changes
+
+Run each line against your bibliotheca DB.
+
+Replace `#REPLACEME#` with your table prefix. Default is bib
+
+```
+UPDATE `#REPLACEME#_tool` SET `name` = 'Metacritic Movie', `action` = 'metacriticMovie' WHERE `bib_tool`.`id` = 1;
+```
+
+```
+INSERT INTO `#REPLACEME#_sys_fields` (`id`, `identifier`, `displayname`, `type`, `searchtype`, `createstring`, `inputValidation`, `value`, `apiinfo`, `created`, `modified`, `modificationuser`, `owner`, `group`, `rights`) VALUES (NULL, 'metacritic', 'sysfield.metacritic', 'text', 'entrySingleText', '`metacritic` varchar(4) NULL DEFAULT NULL', '', '', 'string 4', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, '1', '1', 'rw-r--r--');
+```
+
+# Remove not needed folders and files
+
+The following files and direcotries should be deleted.
+
+```
+config/config-imdbweb.php
+config/config-imdbweb.php.default
+lib/imdbweb.class.php
+systemout/imdb
+view/default/tool-imdbweb.html
+view/default/tool-imdbweb.php
+view/98/tool-imdbweb.html
+view/98/tool-imdbweb.php
+```
+
+# Tool changes
+
+Since IMDB scraping is not working anymore, Metracritic does it for now.
+It replaces IMDB and needs only the initial setup. See the tool documentation for that.
diff --git a/upgrade/from-version-1.8.md b/upgrade/from-version-1.8.md
index f774337..3d6d954 100644
--- a/upgrade/from-version-1.8.md
+++ b/upgrade/from-version-1.8.md
@@ -6,7 +6,7 @@ Updated BROWSER_AGENT string. See default config file for its new value.
Run each line against your bibliotheca DB.
-Replace #REPLACEME# with your table prefix. Default is bib
+Replace `#REPLACEME#` with your table prefix. Default is bib
```
UPDATE `#REPLACEME#_sys_fields` SET `createstring` = '`imdbrating` varchar(4) NULL DEFAULT NULL', `apiinfo` = 'string 4' WHERE `#REPLACEME#_sys_fields`.`identifier` = 'imdbrating';
diff --git a/webclient/config/config-imdbweb.php.default b/webclient/config/config-imdbweb.php.default
deleted file mode 100644
index 1692bda..0000000
--- a/webclient/config/config-imdbweb.php.default
+++ /dev/null
@@ -1,50 +0,0 @@
- bibFieldName
- * TOOL_IMDBWEB_BROWSERSTRING a current browser agent string. Should be updated from time to time. See default config file.
- * TOOL_IMDBWEB_BROWSER_ACCEPT_LANG should define in which language the content returns
- */
-const TOOL_IMDBWEB_ATTRIBUTES = array(
- 'runtime', 'rating', 'genres', 'title', 'originalTitle', 'year', 'plot', 'synopses', 'directors',
- 'writers', 'cast', 'coverImage'
-);
-const TOOL_IMDBWEB_FIELDS_TO = array(
- 'cast' => 'actors', 'synopses' => 'content', 'directors' => 'directors', 'genres' => 'genres',
- 'plot' => 'description', 'rating' => 'imdbrating', 'runtime' => 'runtime', 'originalTitle' => 'title',
- 'writers' => 'writers', 'year' => 'year', 'title' => 'localizedTitle', 'coverImage' => 'coverimage'
-);
-
-// reuse existing constants but define it to the tool
-const TOOL_IMDBWEB_BROWSER_AGENT = BROWSER_AGENT;
-const TOOL_IMDBWEB_BROWSER_ACCEPT = BROWSER_ACCEPT;
-const TOOL_IMDBWEB_BROWSER_ACCEPT_LANG = BROWSER_ACCEPT_LANG;
-const TOOL_IMDBWEB_CACHE_STORAGE = PATH_SYSTEMOUT.'/imdb';
diff --git a/webclient/config/config-metacritic.php.default b/webclient/config/config-metacritic.php.default
new file mode 100644
index 0000000..9ee3c6d
--- /dev/null
+++ b/webclient/config/config-metacritic.php.default
@@ -0,0 +1,50 @@
+ bibFieldName
+ * TOOL_METACRITIC_BROWSER_AGENT A current browser agent string. See default config file.
+ * TOOL_METACRITIC_BROWSER_ACCEPT Browser accept request string. See default config file.
+ * TOOL_METACRITIC_BROWSER_ACCEPT_LANG Defines in which language the content returns
+ * TOOL_METACRITIC_CACHE_STORAGE Cache storage path
+ */
+const TOOL_METACRITIC_ATTRIBUTES_MOVIE = array(
+ 'description', 'datePublished', 'ratingValue', 'genre', 'name', 'actor', 'duration', 'director'
+);
+const TOOL_METACRITIC_FIELDS_TO_MOVIE = array(
+ 'actor' => 'actors', 'director' => 'directors', 'genre' => 'genres',
+ 'description' => 'description', 'ratingValue' => 'metacritic', 'duration' => 'runtime',
+ 'name' => 'title', 'datePublished' => 'year'
+);
+
+// reuse existing constants but define it to the tool
+const TOOL_METACRITIC_BROWSER_AGENT = BROWSER_AGENT;
+const TOOL_METACRITIC_BROWSER_ACCEPT = BROWSER_ACCEPT;
+const TOOL_METACRITIC_BROWSER_ACCEPT_LANG = BROWSER_ACCEPT_LANG;
+const TOOL_METACRITIC_CACHE_STORAGE = PATH_SYSTEMOUT.'/metacritic';
diff --git a/webclient/config/config.php.default b/webclient/config/config.php.default
index 81c20cf..c7d9b5c 100644
--- a/webclient/config/config.php.default
+++ b/webclient/config/config.php.default
@@ -75,6 +75,6 @@ const ANON_GROUP_ID = '3';
const RESULTS_PER_PAGE = 24;
# CURL browser settings
-const BROWSER_AGENT = 'Mozilla/5.0 (X11; Linux x86_64; rv:146.0) Gecko/20100101 Firefox/146.0';
+const BROWSER_AGENT = 'Mozilla/5.0 (X11; Linux x86_64; rv:154.0) Gecko/20100101 Firefox/154.0';
const BROWSER_ACCEPT = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8';
const BROWSER_ACCEPT_LANG = 'en-US,en;q=0.5';
diff --git a/webclient/i18n/deu.ini b/webclient/i18n/deu.ini
index 784ad36..873960e 100644
--- a/webclient/i18n/deu.ini
+++ b/webclient/i18n/deu.ini
@@ -258,6 +258,7 @@ sysfield.imdbrating = "IMDB Wertung"
sysfield.isbn = "ISBN"
sysfield.languages = "Sprachen"
sysfield.localizedTitle = "Lokalisierter Titel"
+sysfield.metacritic = "Metascore"
sysfield.missingtemplate = "Fehlende Feldvorlage:"
sysfield.modified = "Bearbeitet"
sysfield.os = "Betriebssystem und Version"
@@ -276,23 +277,26 @@ sysfield.year = "Jahr"
tags.headline.tagsfor = "Tags für:"
+tool.headline.using = "Verwendung von %s in Sammlung: %s"
+tool.limitations = "Einschränkungen"
+tool.limitations.override = "Daten werden überschrieben."
+tool.message.missingFiles = "Benötige Tooldateien können nicht gefunden werden."
+
tool.gameinfo = "Dies ist eine Sammlung von Webseiten, die unterschiedliche Informationen über Spiele anbieten."
tool.googlebooks.save = reuse.global.save
tool.googlebooks.search = reuse.global.search
tool.googlebooks.searchIsbn = "ISBN Suche"
tool.googlebooks.select = reuse.global.none
-tool.headline.using = "Verwendung von %s in Sammlung: %s"
-tool.imdb.fetch = "Datenbezug"
-tool.imdb.imdbid = "IMDB ID"
-tool.imdb.posters = "Film Poster"
-tool.imdb.save = reuse.global.save
-tool.imdb.search = reuse.global.search
-tool.imdb.search.hint = "Suche funktioniert mit der IMDB Film ID. Auf IMDB manuell suchen und davon die ID (tt*) aus der URL nehmen."
-tool.imdb.search.missingid = "IMDB Suchinformation fehlen."
-tool.imdb.select.none = reuse.global.none
-tool.limitations = "Einschränkungen"
-tool.limitations.override = "Daten werden überschrieben."
-tool.message.missingFiles = "Benötige Tooldateien können nicht gefunden werden."
+
+tool.metacritic.fetch = "Datenbezug"
+tool.metacritic.id = "URL Teil"
+tool.metacritic.posters = "Film Poster"
+tool.metacritic.save = reuse.global.save
+tool.metacritic.search = reuse.global.search
+tool.metacritic.search.hint = "Suche funktioniert mit dem Teil der URL nach /movie/. Auf Metacritic manuell suchen und dann diesen Teils aus der URL nehmen."
+tool.metacritic.search.missingid = "Metacritic Suchinformation fehlen."
+tool.metacritic.select.none = reuse.global.none
+
tool.music.input.albumTitle = "Album/Titel"
tool.music.input.artist = "Künstler"
tool.music.limitations.override = "Daten werden überschrieben; keine Platzhaltersuche oder Teilwörter."
diff --git a/webclient/i18n/eng.ini b/webclient/i18n/eng.ini
index 1e43e49..9bc4aa8 100644
--- a/webclient/i18n/eng.ini
+++ b/webclient/i18n/eng.ini
@@ -258,6 +258,7 @@ sysfield.imdbrating = "IMDB rating"
sysfield.isbn = "ISBN"
sysfield.languages = "Languages"
sysfield.localizedTitle = "Localized title"
+sysfield.metacritic = "Metascore"
sysfield.missingtemplate = "Missing template for:"
sysfield.modified = "Modified"
sysfield.os = "Operating system and version"
@@ -276,23 +277,26 @@ sysfield.year = "Year"
tags.headline.tagsfor = "Tags for:"
+tool.headline.using = "Using %s with collection: %s"
+tool.limitations = "Limitations"
+tool.limitations.override = "Data will be overwritten"
+tool.message.missingFiles = "Required tool files can not be found."
+
tool.gameinfo = "This is a collection of websites which provide different kind of information about games."
tool.googlebooks.save = reuse.global.save
tool.googlebooks.search = reuse.global.search
tool.googlebooks.searchIsbn = "Search ISBN"
tool.googlebooks.select = reuse.global.none
-tool.headline.using = "Using %s with collection: %s"
-tool.imdb.fetch = "Fetch"
-tool.imdb.imdbid = "IMDB ID"
-tool.imdb.posters = "Movie posters"
-tool.imdb.save = reuse.global.save
-tool.imdb.search = reuse.global.search
-tool.imdb.search.hint = "Seach works with the imdb movie ID (the tt* in the url) after searching manually on imdb itself."
-tool.imdb.search.missingid = "IMDB search result information missing."
-tool.imdb.select.none = reuse.global.none
-tool.limitations = "Limitations"
-tool.limitations.override = "Data will be overwritten"
-tool.message.missingFiles = "Required tool files can not be found."
+
+tool.metacritic.fetch = "Fetch"
+tool.metacritic.id = "Url part"
+tool.metacritic.posters = "Movie posters"
+tool.metacritic.save = reuse.global.save
+tool.metacritic.search = reuse.global.search
+tool.metacritic.search.hint = "Seach works with the url part from Metacritic URL after /movie/."
+tool.metacritic.search.missingid = "Metacritic search result information missing."
+tool.metacritic.select.none = reuse.global.none
+
tool.music.input.albumTitle = "Album/Title"
tool.music.input.artist = "Artist"
tool.music.limitations.override = "Data will be overwritten; No wildcardsearch or partial words."
diff --git a/webclient/lib/imdbweb.class.php b/webclient/lib/metacritic.class.php
similarity index 50%
rename from webclient/lib/imdbweb.class.php
rename to webclient/lib/metacritic.class.php
index 71b8700..dcc18e1 100644
--- a/webclient/lib/imdbweb.class.php
+++ b/webclient/lib/metacritic.class.php
@@ -19,80 +19,58 @@
*/
/**
- * Class IMDBWEB
+ * Class Metacritic
*
- * Based on the idea of https://github.com/FabianBeiner/PHP-IMDB-Grabber/
- * But since the web srcaping does not work anymore, here is an own implementation
- *
- * Main and important action is at _processData
+ * Retrive the HTML from a metacritic URL and parse the json+ld information
*/
-class IMDBWEB {
+
+class Metacritic {
/**
* Set this to true if you run into problems.
*/
private bool $_DEBUG = false;
/**
- * @var string The user agent used to make curl calls
+ * @var string The user agent used to make curl calls
*/
- private mixed $_BROWSER_AGENT = '';
+ private string $_BROWSER_AGENT = '';
/**
- * @var string The user agent lang used to make curl calls
- */
- private mixed $_BROWSER_LANG = '';
+ * @var string The user agent lang used to make curl calls
+ */
+ private string $_BROWSER_LANG = '';
/**
- * @var string The user agent accept used to make curl calls
- */
- private mixed $_BROWSER_ACCEPT = '';
+ * @var string The user agent accept used to make curl calls
+ */
+ private string $_BROWSER_ACCEPT = '';
/**
- * This is used to get the base informations
- *
- * A good start for further URLs is: https://www.imdb.com/title/%s/reference/
- * @var string The imdb URL to get the HTML from
- */
- private string $_FULLCREDITS_URL = 'https://www.imdb.com/title/%s/fullcredits/';
+ * @var string The directory to store cache files
+ */
+ private string $_CACHE_DIR = "";
/**
- * This is used to get more text
- * Not implemented yet.
- *
- * A good start for further URLs is: https://www.imdb.com/title/%s/reference/
- * @var string The imdb URL to get the HTML from
- */
- private string $_REFERENCE_URL = "https://www.imdb.com/title/%s/reference/";
+ * @var array The fields to return
+ */
+ private array $_attributes;
- /**
- * @var string The directory to store cache files
- */
- private string $_CACHE_DIR = "";
+ private string $_BASE_URL_MOVIES = 'https://www.metacritic.com/movie/%s/';
/**
- * @var int Maximum cache time.
- */
+ * @var int Maximum cache time.
+ */
private int $_CACHE_TIME = 1440;
- /**
- * @var array The fields to return
- */
- private array $_attributes;
-
- /**
- * ImdbWeb constructor
- *
- * @param array $options
- */
public function __construct(array $options) {
if (isset($options['debug']) && !empty($options['debug'])) {
$this->_DEBUG = true;
}
- $this->_CACHE_DIR = $options['storage'];
- if (!is_writable($this->_CACHE_DIR) && !mkdir($this->_CACHE_DIR)) {
+ $this->_CACHE_DIR = $options['storage'];
+ if (!is_writable($this->_CACHE_DIR) && !mkdir($this->_CACHE_DIR)) {
Summoner::sysLog("[ERROR] Missing directory or write access: ".$this->_CACHE_DIR);
- }
+ }
$this->_BROWSER_AGENT = $options['browserAgent'];
$this->_BROWSER_LANG = $options['browserLang'];
@@ -104,20 +82,11 @@ class IMDBWEB {
}
}
- /**
- * Not really a search. Since this does only really work with a given imdb ID an exact
- * URL is called and processed.
- * Decides if the data will called of cache is used.
- * Does return the data based on $this->_attributes
- *
- * @param string $search
- * @return array
- */
- public function search(string $search): array {
+ public function fetch(string $urlPart): array {
$ret = array();
- if (empty($search)) return $ret;
- $url = sprintf($this->_FULLCREDITS_URL, $search);
+ if (empty($urlPart)) return $ret;
+ $url = sprintf($this->_BASE_URL_MOVIES, $urlPart);
if ($this->_DEBUG) Summoner::sysLog("[DEBUG] ".__METHOD__." using url : " . $url);
// Does a cache of this movie exist?
@@ -151,44 +120,67 @@ class IMDBWEB {
}
/**
- * Retrieve the title cover from the given URL and return a tmp file
+ * execute a curl call to the given $url
*
- * @param string $url
+ * @param string $url The request url
* @return string
*/
- public function downloadCover(string $url): string {
- $ret = "";
-
- $_tmpFile = tempnam(sys_get_temp_dir(), "bibliotheca-");
- $fh = fopen($_tmpFile,"w+");
- if($this->_DEBUG) {
- Summoner::sysLog('[DEBUG] '.__METHOD__.' url '.Summoner::cleanForLog($url));
- }
-
- if($fh !== false) {
+ private function _curlCall(string $url): string {
+ $ret = '';
- // modified curl call for fetching an image
- $ch = curl_init($url);
- curl_setopt($ch, CURLOPT_FILE, $fh);
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+ curl_setopt($ch, CURLOPT_MAXREDIRS, 2);
+ curl_setopt($ch, CURLOPT_USERAGENT, $this->_BROWSER_AGENT);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array(
+ 'Accept: ' . $this->_BROWSER_ACCEPT,
+ 'Accept-Charset: utf-8, iso-8859-1;q=0.5',
+ 'Accept-Language: ' . $this->_BROWSER_LANG)
+ );
+ curl_setopt($ch, CURLOPT_REFERER, 'https://www.metacritic.com');
- curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
- curl_setopt($ch, CURLOPT_TIMEOUT, 30);
- curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
- curl_setopt($ch, CURLOPT_MAXREDIRS, 3);
- curl_setopt($ch, CURLOPT_USERAGENT, $this->_BROWSER_AGENT);
+ if ($this->_DEBUG) {
+ $_headers = array();
+ curl_setopt($ch, CURLOPT_VERBOSE, true);
+ curl_setopt($ch, CURLOPT_HEADERFUNCTION,
+ function ($curl, $header) use (&$_headers) {
+ $len = strlen($header);
+ $header = explode(':', $header, 2);
+ if (count($header) < 2) { // ignore invalid headers
+ return $len;
+ }
+ $_headers[strtolower(trim($header[0]))][] = trim($header[1]);
+ return $len;
+ }
+ );
+ }
- curl_exec($ch);
- curl_close($ch);
+ $do = curl_exec($ch);
+ if (!curl_errno($ch)) {
+ $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+ if ($http_code == 200) {
+ if (is_string($do) === true) {
+ $ret = $do;
+ }
+ } else {
+ Summoner::sysLog('[WARN] ' . __METHOD__ . ' non 200 return status ' . Summoner::cleanForLog($http_code));
+ }
+ }
+ curl_close($ch);
- $ret = $_tmpFile;
+ if ($this->_DEBUG) {
+ Summoner::sysLog('[DEBUG] ' . __METHOD__ . ' headers ' . Summoner::cleanForLog($_headers));
}
- fclose($fh);
return $ret;
}
/**
- * The html from $this->_REFERENCE_URL should contain a script with the id __NEXT_DATA__
+ * The html from the curl call should contain application/ld+json
* and it holds a json object with all the information we currently need.
*
* @param string $data
@@ -197,13 +189,13 @@ class IMDBWEB {
private function _extractData(string $data): string {
$ret = "";
- $m = preg_match('~id="__NEXT_DATA__".*?>([^<]+)~s', $data, $matches);
+ $m = preg_match('~type="application/ld\+json".*?>([^<]+)~s', $data, $matches);
if(!empty($m)) {
$ret = $matches[1];
} elseif($this->_DEBUG) {
- Summoner::sysLog("[DEBUG] ".__METHOD__." no script with id __NEXT_DATA__ found.");
+ Summoner::sysLog("[DEBUG] ".__METHOD__." no script with type application/ld+json found.");
}
- //Summoner::sysLog("[DEBUG] ".__METHOD__." extracted json data.".Summoner::cleanForLog($ret));
+ Summoner::sysLog("[DEBUG] ".__METHOD__." extracted json data.".Summoner::cleanForLog($ret));
return $ret;
}
@@ -221,11 +213,14 @@ class IMDBWEB {
Summoner::sysLog("[DEBUG] ".__METHOD__." can not decode json. ".json_last_error_msg());
return $ret;
}
- if(isset($jsonData["props"]["pageProps"]["contentData"]["data"]["title"])) {
+
+ if(isset($jsonData["name"])) {
foreach($this->_attributes as $att) {
$_m = "_get_".$att;
if(method_exists($this, $_m)) {
- $ret[$att] = $this->$_m($jsonData["props"]["pageProps"]["contentData"]["data"]["title"]);
+ $ret[$att] = $this->$_m($jsonData);
+ } elseif (isset($jsonData[$att])) {
+ $ret[$att] = $jsonData[$att];
} else {
$ret[$att] = "";
}
@@ -235,156 +230,66 @@ class IMDBWEB {
return $ret;
}
- private function _get_runtime(array $data): string {
- $t = $this->_retrieveDataFromArray(array("runtime","seconds"),$data);
- return floor($t / 60);
- }
-
- private function _get_rating(array $data): string {
- return $this->_retrieveDataFromArray(array("ratingsSummary","aggregateRating"), $data);
- }
-
- private function _get_title(array $data): string {
- return $this->_retrieveDataFromArray(array("titleText","text"), $data);
- }
-
- private function _get_originalTitle(array $data): string {
- return $this->_retrieveDataFromArray(array("originalTitleText","text"), $data);
- }
-
- private function _get_year(array $data): string {
- return $this->_retrieveDataFromArray(array("releaseYear","year"), $data);
- }
-
- private function _get_plot(array $data): string {
- return $this->_retrieveDataFromArray(array("plot","plotText","plainText"),$data);
+ private function _get_ratingValue(array $data): string {
+ $t = $this->_retrieveDataFromArray(array("aggregateRating","ratingValue"),$data);
+ return $t;
}
- private function _get_synopses(array $data): string {
- return $this->_retrieveDataFromArray(array("synopses","edges",0,"node","plotText","plaidHtml"), $data);
+ private function _get_genre(array $data): array {
+ $ret = array();
+ foreach($data['genre'] as $g) {
+ $ret[] = $g;
+ }
+ return $ret;
}
- private function _get_coverImage(array $data): string {
- return $this->_retrieveDataFromArray(array("primaryImage","url"), $data);
+ private function _get_actor(array $data): array {
+ $ret = array();
+ foreach($data['actor'] as $e) {
+ $ret[] = $e['name'];
+ }
+ return $ret;
}
- private function _get_genres(array $data): array {
+ private function _get_director(array $data): array {
$ret = array();
- foreach($data["titleGenres"]["genres"] as $g) {
- $ret[] = $g["genre"]["text"];
+ foreach($data['director'] as $e) {
+ $ret[] = $e['name'];
}
return $ret;
}
- /**
- * Looks like there is a unique id for director(s)
- * amzn1.imdb.concept.name_credit_category.ace5cb4c-8708-4238-9542-04641e7c8171
- *
- * @param array $data
- * @return array
- */
- private function _get_directors(array $data): array {
- return $this->_resolveCreditGroupings($data, "amzn1.imdb.concept.name_credit_category.ace5cb4c-8708-4238-9542-04641e7c8171");
+ private function _get_datePublished(array $data): string {
+ $ret = '';
+ if(isset($data['datePublished'])) {
+ $time = strtotime($data['datePublished']);
+ $ret = date('Y', $time);
+ }
+ return $ret;
}
- /**
- * Looks like there is a unique id for writer(s)
- * amzn1.imdb.concept.name_credit_category.c84ecaff-add5-4f2e-81db-102a41881fe3
- *
- * @param array $data
- * @return array
- */
- private function _get_writers(array $data): array {
- return $this->_resolveCreditGroupings($data, "amzn1.imdb.concept.name_credit_category.c84ecaff-add5-4f2e-81db-102a41881fe3");
- }
- /**
- * Looks like there is a unique id for the cast
- * amzn1.imdb.concept.name_credit_group.7caf7d16-5db9-4f4f-8864-d4c6e711c686
- *
- * @param array $data
- * @return array
- */
- private function _get_cast(array $data): array {
- return $this->_resolveCreditGroupings($data, "amzn1.imdb.concept.name_credit_group.7caf7d16-5db9-4f4f-8864-d4c6e711c686");
- }
/**
- * Extract the information from the creditGroupings array.
+ * The duration something like this: PT2M11S
+ * It is https://iso8601.com/#duration but wrong?
+ * The above example is from a movie which is 2h and 11m
+ * and NOT 2m 11s
*
* @param array $data
- * @param string $gId
* @return array
*/
- private function _resolveCreditGroupings(array $data, string $gId): array {
- $ret = array();
- foreach($data["creditGroupings"]["edges"] as $edge) {
- $_gid = $this->_retrieveDataFromArray(array("node", "grouping", "groupingId"), $edge);
- if($_gid == $gId) {
- foreach($edge["node"]["credits"]["edges"] as $e) {
- $ret[] = $this->_retrieveDataFromArray(array("node", "name", "nameText", "text"), $e);
- }
- break;
- }
- }
- return $ret;
- }
-
- /**
- * execute a curl call to the given $url
- *
- * @param string $url The request url
- * @return string
- */
- private function _curlCall(string $url): string {
+ private function _get_duration(array $data): string {
$ret = '';
-
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
- curl_setopt($ch, CURLOPT_TIMEOUT, 30);
- curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
- curl_setopt($ch, CURLOPT_MAXREDIRS, 2);
- curl_setopt($ch, CURLOPT_USERAGENT, $this->_BROWSER_AGENT);
- curl_setopt($ch, CURLOPT_HTTPHEADER, array(
- 'Accept: ' . $this->_BROWSER_ACCEPT,
- 'Accept-Charset: utf-8, iso-8859-1;q=0.5',
- 'Accept-Language: ' . $this->_BROWSER_LANG)
- );
- curl_setopt($ch, CURLOPT_REFERER, 'https://www.imdb.com');
-
- if ($this->_DEBUG) {
- $_headers = array();
- curl_setopt($ch, CURLOPT_VERBOSE, true);
- curl_setopt($ch, CURLOPT_HEADERFUNCTION,
- function ($curl, $header) use (&$_headers) {
- $len = strlen($header);
- $header = explode(':', $header, 2);
- if (count($header) < 2) { // ignore invalid headers
- return $len;
- }
- $_headers[strtolower(trim($header[0]))][] = trim($header[1]);
- return $len;
- }
- );
- }
-
- $do = curl_exec($ch);
- if (!curl_errno($ch)) {
- $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
- if ($http_code == 200) {
- if (is_string($do) === true) {
- $ret = $do;
- }
+ if(isset($data['duration'])) {
+ try {
+ $interval = new DateInterval($data['duration']);
+ $ret = $interval->format("%i")*60;
+ $ret = $ret+$interval->format("%s"); // not very cool...
+ } catch (Exception $e) {
+ Summoner::sysLog("[DEBUG] ".__METHOD__." can not duration ".$data['duration']);
}
}
- curl_close($ch);
-
- if ($this->_DEBUG) {
- Summoner::sysLog('[DEBUG] ' . __METHOD__ . ' headers ' . Summoner::cleanForLog($_headers));
- }
-
return $ret;
}
diff --git a/webclient/view/98/tool/tool-imdbweb.html b/webclient/view/98/tool/tool-metacriticMovie.html
similarity index 60%
rename from webclient/view/98/tool/tool-imdbweb.html
rename to webclient/view/98/tool/tool-metacriticMovie.html
index 4f9876d..e944bc1 100644
--- a/webclient/view/98/tool/tool-imdbweb.html
+++ b/webclient/view/98/tool/tool-metacriticMovie.html
@@ -1,29 +1,29 @@
t('tool.limitations'); ?>
t('tool.limitations.override'); ?>
- t('tool.imdb.search.hint'); ?>
+ t('tool.metacritic.search.hint'); ?>
- t('tool.imdb.posters'); ?> impawardst('tool.metacritic.posters'); ?> impawards
@@ -46,7 +46,7 @@
?>
-
+
diff --git a/webclient/view/default/tool/tool-imdbweb.php b/webclient/view/default/tool/tool-imdbweb.php
deleted file mode 100644
index e920711..0000000
--- a/webclient/view/default/tool/tool-imdbweb.php
+++ /dev/null
@@ -1,223 +0,0 @@
- TOOL_IMDBWEB_SEARCH,
- 'showFields' => TOOL_IMDBWEB_FIELDS,
- 'storage' => PATH_SYSTEMOUT,
- 'browserAgent' => TOOL_IMDBWEB_BROWSER_AGENT,
- 'browserLang' => TOOL_IMDBWEB_BROWSER_ACCEPT_LANG,
- 'browserAccept' => TOOL_IMDBWEB_BROWSER_ACCEPT,
- 'debug' => false
-));
-*/
-
-require_once 'lib/imdbweb.class.php';
-if(file_exists(PATH_ABSOLUTE.'/config/config-imdbweb.php')) {
- require_once 'config/config-imdbweb.php';
-}
-$IMDB = new IMDBWEB(array(
- 'storage' => TOOL_IMDBWEB_CACHE_STORAGE,
- 'browserAgent' => TOOL_IMDBWEB_BROWSER_AGENT,
- 'browserLang' => TOOL_IMDBWEB_BROWSER_ACCEPT_LANG,
- 'browserAccept' => TOOL_IMDBWEB_BROWSER_ACCEPT,
- 'attributes' => TOOL_IMDBWEB_ATTRIBUTES,
- 'debug' => DEBUG
-));
-
-
-$TemplateData['movieData'] = array();
-$TemplateData['saveToSelection'] = '';
-$TemplateData['showMatchingForm'] = false;
-
-// prepare fields to save into selection
-// create one time and then reuse it
-$collectionFields = $ManangeCollectionsFields->getExistingFields(false, true);
-if(!empty($collectionFields)) {
- foreach ($collectionFields as $k=>$v) {
- $TemplateData['saveToSelection'] .= "\n";
- }
-}
-
-if(isset($_POST['submitFormSearch'])) {
- $fdata = $_POST['fdata'];
- if (!empty($fdata)) {
- // this is the imdb id
- $search = trim($fdata['search']);
- $search = Summoner::validate($search, "nospace") ? $search : false;
-
- if (!empty($search)) {
- $mData = $IMDB->search($search);
-
- if (!empty($mData)) {
- $TemplateData['movieData'] = $mData;
- $TemplateData['movieImdbId'] = $search;
- $TemplateData['showMatchingForm'] = true;
- } else {
- $TemplateData['message']['content'] = $I18n->t('global.message.nothingFound');
- $TemplateData['message']['status'] = "error";
- }
- }
- else {
- $TemplateData['message']['content'] = $I18n->t('global.message.invalidSearchTerm');
- $TemplateData['message']['status'] = "error";
- }
- }
-}
-
-if(isset($_POST['submitFormSave'])) {
- $fdata = $_POST['fdata'];
- if (!empty($fdata)) {
- $_imdbId = $fdata['imdbId'];
- $_imdbId = Summoner::validate($_imdbId,'nospace') ? $_imdbId : false;
-
- if(!empty($_imdbId)) {
- // why search again?
- // Cache is used, so not really a new search and the data stays the same without a roundtrip
- // thriugh the requsts
- $mData = $IMDB->search($_imdbId);
-
- if (!empty($mData)) {
- $TemplateData['movieImdbId'] = $_imdbId;
-
- // build data array based on submit
- // see creation log for structure
- $_data = array();
- foreach($fdata['into'] as $k=>$v) {
- if(!empty($v)) {
- $_t = $mData[$k];
-
- // multiple selections format for field type lookup_multiple
- if(is_array($_t)) {
- $_t = implode(",", $_t);
- }
-
- if(isset($collectionFields[$v])) {
- $_data[$v] = $collectionFields[$v];
- $_data[$v]['valueToSave'] = $_t;
-
- // special case for cover image since there is no POST and FILES
- if($k == "coverImage") {
- $fieldData = array();
-
- $_f = $IMDB->downloadCover($_t);
- if($_f && is_file($_f)) {
- $_e = UPLOAD_ERR_OK;
- // build _FILES based on regular add form
- $fieldData['name'][$_data[$v]['identifier']] = 'cover.jpg';
- $fieldData['type'][$_data[$v]['identifier']] = mime_content_type($_f);
- $fieldData['size'][$_data[$v]['identifier']] = filesize($_f);
- $fieldData['tmp_name'][$_data[$v]['identifier']] = $_f;
- $fieldData['error'][$_data[$v]['identifier']] = UPLOAD_ERR_OK;
- $fieldData['rebuildUpload'][$_data[$v]['identifier']] = true;
- }
-
- $_data[$v]['uploadData'] = $fieldData;
- }
- }
- }
- }
-
- $_r = $Tools->getDefaultCreationInfo();
- if(!empty($TemplateData['editEntry'])) {
- // update existing one
- $do = $Manageentry->create($_data,
- $_r['id'],
- $_r['group'],
- $_r['rights'],
- $TemplateData['editEntry']['id']
- );
- $TemplateData['message']['content'] = $I18n->t('global.message.dataSaved');
- }
- else {
- // create into loaded collection
- $do = $Manageentry->create($_data,
- $_r['id'],
- $_r['group'],
- $_r['rights']
- );
- $TemplateData['message']['content'] = $I18n->t('global.message.dataSaved')." ".$I18n->t('global.view')."";
- }
-
- if(!empty($do)) {
- $TemplateData['message']['status'] = "success";
- }
- else {
- $TemplateData['message']['content'] = $I18n->t('global.message.couldNotBeSaved');
- $TemplateData['message']['status'] = "error";
- }
- } else {
- $TemplateData['message']['content'] = $I18n->t('global.message.nothingFound');
- $TemplateData['message']['status'] = "error";
- }
- }
- else {
- $TemplateData['message']['content'] = $I18n->t('tool.imdb.search.missingid');
- $TemplateData['message']['status'] = "error";
- }
- }
-}
-
-
-/**
- * Helper function. Takes the prebuild options for the target selection field and search for a matching key.
- * Since the optionString is prebuild, avoiding looping over and over again, the selection needs to be done
- * by search and replace.
- * Checks if TOOL_IMDBWEB_FIELDS_TO is defined and a matching key=>value pair is available
- *
- * @param string $optionString
- * @param string $imdbKey
- * @return string
- */
-function toolMethod_GetTargetSelection(string $optionString, string $imdbKey): string {
- if(defined('TOOL_IMDBWEB_FIELDS_TO') & !empty($imdbKey)) {
- if(isset(TOOL_IMDBWEB_FIELDS_TO[$imdbKey])) {
- $_k = "sel_".TOOL_IMDBWEB_FIELDS_TO[$imdbKey];
- $optionString = str_replace($_k,'selected="selected"',$optionString);
- }
- }
-
- return $optionString;
-}
-
-/**
- * Make the given mixed data displayable as a string
- *
- * @param mixed $value
- * @return string
- */
-function toolMethod_DisplayValues(mixed $value): string {
- $ret = $value;
- if(is_array($value)) {
- $ret = implode(", ", $value);
- }
- return $ret;
-}
diff --git a/webclient/view/default/tool/tool-imdbweb.html b/webclient/view/default/tool/tool-metacriticMovie.html
similarity index 70%
rename from webclient/view/default/tool/tool-imdbweb.html
rename to webclient/view/default/tool/tool-metacriticMovie.html
index 585bf47..c58db14 100644
--- a/webclient/view/default/tool/tool-imdbweb.html
+++ b/webclient/view/default/tool/tool-metacriticMovie.html
@@ -1,26 +1,26 @@
t('tool.limitations'); ?>
t('tool.limitations.override'); ?>
- t('tool.imdb.search.hint'); ?>
+ t('tool.metacritic.search.hint'); ?>
- t('tool.imdb.posters'); ?> impawardst('tool.metacritic.posters'); ?> impawards