]> 91.132.146.200 Git - bibliotheca-php.git/commitdiff
adding musicbrainz as a grabber
authorBanana <mail@bananas-playground.net>
Thu, 8 Jul 2021 11:25:28 +0000 (13:25 +0200)
committerBanana <mail@bananas-playground.net>
Thu, 8 Jul 2021 11:25:28 +0000 (13:25 +0200)
14 files changed:
CHANGELOG
TODO
documentation/tool-imdbweb.txt
documentation/tool-musicbrainz.txt [new file with mode: 0644]
upgrade/from-version-1.1.txt [new file with mode: 0644]
webclient/config/config-imdbweb.php.default
webclient/config/config-musicbrainz.php.default [new file with mode: 0644]
webclient/lib/manageentry.class.php
webclient/lib/musicbrainz.class.php [new file with mode: 0644]
webclient/lib/summoner.class.php
webclient/view/default/manageentry/manageentry.php
webclient/view/default/tool/tool-imdbweb.php
webclient/view/default/tool/tool-musicbrainz.html [new file with mode: 0644]
webclient/view/default/tool/tool-musicbrainz.php [new file with mode: 0644]

index ee0f4c849e25ea46ce9cff33265e778281bb5968..2f9f71d2321ca082b5d7071bd83c84de5fd0c278 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,4 +1,7 @@
-1.x - NyLeve's Falls
+1.x - NyLeve's Falls (TBD)
+       * Updated requirements information
+       * Added Musicbrainz grabber
+       * Added new field: artist
 
 1.1 - Vortex Rikers 20210530
        * Cleanup and merge to one config file. Read upgrade
diff --git a/TODO b/TODO
index 5640edac7a076ad055dbb35324e853629fc1d4cb..24044d6e8b1fa5547e1f91642f1a58fd0e0c586a 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,3 +1,4 @@
+* User friendly setup
 * stats overview page. amount of entries. file / cache and db storage. Version info and where to find it.
 * User and groupmanagement: Check where a user or group is used!
 * Better error handling and display while adding / update and delete
index e3c4b29f1ddfbd8c2df25ac5964c92fabf8e508e..9ca69aea3f71e0ee24519f9c5bb25991e9999133 100644 (file)
@@ -12,4 +12,9 @@ Which fields are available for you to select, are configured in the config.imdbw
 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.
+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.
diff --git a/documentation/tool-musicbrainz.txt b/documentation/tool-musicbrainz.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/upgrade/from-version-1.1.txt b/upgrade/from-version-1.1.txt
new file mode 100644 (file)
index 0000000..baa84bf
--- /dev/null
@@ -0,0 +1,5 @@
+# DB changes. Run each line against your bibliotheca DB.
+# Replace #REPLACEME# with your table prefix. Default is bib
+INSERT INTO `#REPLACEME#_tool` (`id`, `name`, `description`, `action`, `target`, `owner`, `group`, `rights`) VALUES (NULL, 'Musicbrainz', 'Album infos', 'musicbrainz', '_self', '1', '1', 'rw-r--r--');
+INSERT INTO `#REPLACEME#_sys_fields` (`id`, `identifier`, `displayname`, `type`, `searchtype`, `createstring`, `inputValidation`, `value`, `apiinfo`, `created`, `modified`, `modificationuser`, `owner`, `group`, `rights`) VALUES (NULL, 'artist', 'Artist', 'text', 'entrySingleText', '`artists` varchar(128) NULL DEFAULT NULL', '', NULL, 'string 128', NOW(), NOW(), NULL, '1', '1', 'rw-r--r--');
+UPDATE `#REPLACEME#_sys_fields` SET `type` = 'year' WHERE `bib_sys_fields`.`id` = 14;
index 187b95bab747329fa2a7a30a16fd17da801656c0..4f59616f8c26c3dd3bffe05136321e5cd0dc11cc 100644 (file)
@@ -1,6 +1,24 @@
 <?php
+<?php
+/**
+ * Bibliotheca
+ *
+ * Copyright 2018-2021 Johannes Keßler
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 /**
- * Options for the grabber
+ * Options for the imdb grabber
  *
  * TOOL_IMDBWEB_SEARCH can be 'movie','tv','episode','game','all'. Default is movie
  * TOOL_IMDBWEB_FIELDS is an array to define which fields from IMDB are displayed for selection
diff --git a/webclient/config/config-musicbrainz.php.default b/webclient/config/config-musicbrainz.php.default
new file mode 100644 (file)
index 0000000..6b39797
--- /dev/null
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Bibliotheca
+ *
+ * Copyright 2018-2021 Johannes Keßler
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Options for the musicbrainz class
+
+ * Currently available fields are:
+ *             album,date,artist,tracks,image,runtime
+ * TOOL_BRAINZ_FIELDS_TO is a array to define which fields should be saved into
+ *             a bibliotheca field. Those or the fields a collection can have. Use the identifier of a field.
+ *             Depends on your settings so make sure everything is setup first. Leave it commented if not needed.
+ * TOOL_BRAINZ_BROWSER_AGENT a current browser agent string. Should be updated from time to time. See default config file.
+ * TOOL_BRAINZ_BROWSER_ACCEPT A string what the browser does accept. Should be updated from time to time. See default config file.
+ * TOOL_BRAINZ_BROWSER_ACCEPT_LANG should define in which language the content returns
+ * TOOL_BRAINZ_RESULT_LIMIT How many entries the search will display
+ */
+
+define('TOOL_BRAINZ_BROWSER_AGENT','Mozilla/5.0 (X11; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0');
+define('TOOL_BRAINZ_BROWSER_ACCEPT','text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8');
+define('TOOL_BRAINZ_BROWSER_ACCEPT_LANG','en-US,en;q=0.5');
+
+define('TOOL_BRAINZ_RESULT_LIMIT',10);
+
+define('TOOL_BRAINZ_FIELDS_TO',
+       array(
+               'album' => 'title','date' => 'year', 'artist' => 'artist', 'image' => 'coverimage', 'tracks' => 'content',
+               'runtime' => 'runtime'
+       )
+);
index 76054a1092c8638517da0ef1d2e608c153001692..a16752acc6d15d5e1926a27d95cfa381e6e98f6f 100644 (file)
@@ -563,14 +563,21 @@ class Manageentry {
        private function _saveField_selection($data, $queryData) {
                return $this->_saveField_text($data, $queryData);
        }
+
        /**
         * Create part of the insert statement for field type year
+        * Uses some simple 4 digit patter to extract the year if the input is
+        * something like 2001-02-03
         *
         * @param array $data Field data
         * @param array $queryData Query data array
         * @return array
         */
        private function _saveField_year($data, $queryData) {
+               preg_match('/[0-9]{4}/', $data['valueToSave'], $matches);
+               if(isset($matches[0]) && !empty($matches[0])) {
+                       $data['valueToSave'] = $matches[0];
+               }
                return $this->_saveField_number($data, $queryData);
        }
 
@@ -585,7 +592,7 @@ class Manageentry {
        private function _saveField_number($data, $queryData) {
                // make sure there is something (int) to save
                if(empty($data['valueToSave'])) {
-                               $data['valueToSave'] = 0;
+                       $data['valueToSave'] = 0;
                }
                $data['valueToSave'] = preg_replace('/[^\p{N}]/u', '', $data['valueToSave']);
                $queryData['init'][] = "`".$data['identifier']."` = '".$this->_DB->real_escape_string($data['valueToSave'])."'";
@@ -630,7 +637,7 @@ class Manageentry {
         * @param array $queryData
         * @return array
         */
-       private function _saveField_upload($data, $queryData) {
+       private function _saveField_upload(array $data, array $queryData): array {
                $_up = $data['uploadData'];
 
                // delete the single upload
@@ -651,7 +658,8 @@ class Manageentry {
                                'identifier' => $data['identifier'],
                                'name' => $newFilename,
                                'tmp_name' => $_up['tmp_name'][$data['identifier']],
-                               'multiple' => false
+                               'multiple' => false,
+                               'rebuildUpload' => $_up['rebuildUpload'][$data['identifier']]
                        );
                }
                return $queryData;
@@ -664,7 +672,7 @@ class Manageentry {
         * @param array $queryData
         * @return array
         */
-       private function _saveField_upload_multiple($data, $queryData) {
+       private function _saveField_upload_multiple(array $data, array $queryData): array {
                $_up = $data['uploadData'];
 
                if(isset($data['deleteData'])) {
@@ -684,7 +692,8 @@ class Manageentry {
                                        'identifier' => $data['identifier'],
                                        'name' => $newFilename,
                                        'tmp_name' => $_up['tmp_name'][$data['identifier']][$k],
-                                       'multiple' => true
+                                       'multiple' => true,
+                                       'rebuildUpload' => $_up['rebuildUpload'][$data['identifier']][$k]
                                );
                        }
                }
@@ -723,7 +732,7 @@ class Manageentry {
         * @param string $insertId Number
         * @throws Exception
         */
-       private function _runAfter_upload($uploadData, $insertId) {
+       private function _runAfter_upload(array $uploadData, string $insertId) {
                if(!empty($uploadData) && !empty($insertId)) {
                        if(DEBUG) error_log("[DEBUG] ".__METHOD__." uploadata: ".var_export($uploadData,true));
                        $_path = PATH_STORAGE.'/'.$this->_collectionId.'/'.$insertId;
@@ -758,7 +767,13 @@ class Manageentry {
                        }
 
                        if(isset($uploadData['tmp_name']) && isset($uploadData['name'])) {
-                               if(!move_uploaded_file($uploadData['tmp_name'],$_path.'/'.$uploadData['identifier'].'-'.$uploadData['name'])) {
+                               // special case if the image is already uploaded and not a real POST/FILES request
+                               if(isset($uploadData['rebuildUpload']) && $uploadData['rebuildUpload'] === true) {
+                                       if(!rename($uploadData['tmp_name'],$_path.'/'.$uploadData['identifier'].'-'.$uploadData['name'])) {
+                                               throw new Exception("Can not rename file to: ".$_path.'/'.$uploadData['identifier'].'-'.$uploadData['name']);
+                                       }
+                               }
+                               elseif(!move_uploaded_file($uploadData['tmp_name'],$_path.'/'.$uploadData['identifier'].'-'.$uploadData['name'])) {
                                        throw new Exception("Can not move file to: ".$_path.'/'.$uploadData['identifier'].'-'.$uploadData['name']);
                                }
                        }
@@ -773,7 +788,7 @@ class Manageentry {
         * @param $data array The entry data from getEditData
         * @return bool
         */
-       private function _isOwner($data) {
+       private function _isOwner(array $data): bool {
                $ret = false;
 
                if($this->_User->param('isRoot')) {
diff --git a/webclient/lib/musicbrainz.class.php b/webclient/lib/musicbrainz.class.php
new file mode 100644 (file)
index 0000000..c7184ef
--- /dev/null
@@ -0,0 +1,329 @@
+<?php
+/**
+ * Bibliotheca
+ *
+ * Copyright 2018-2021 Johannes Keßler
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Class Musicbrainz
+ *
+ * Simple search for an artist and album
+ *
+ * https://musicbrainz.org/doc/Development
+ * https://musicbrainz.org/doc/MusicBrainz_API/Examples
+ * https://musicbrainz.org/doc/MusicBrainz_API/Search
+ * https://musicbrainz.org/doc/MusicBrainz_API
+ */
+class Musicbrainz {
+
+       /**
+        * @var bool DEBUG
+        */
+       private $_DEBUG = false;
+
+       /**
+        * @var string The user agent used to make curl calls
+        */
+       private $_BROWSER_AGENT = '';
+
+       /**
+        * @var string The user agent lang used to make curl calls
+        */
+       private $_BROWSER_LANG = '';
+
+       /**
+        * @var string The user agent accept used to make curl calls
+        */
+       private $_BROWSER_ACCEPT = '';
+
+       /**
+        * @var string The musicbrainz API release endpoint
+        */
+       private $_RELEASE_ENDPOINT = 'http://musicbrainz.org/ws/2/release/';
+
+       /**
+        * @var string The endpoint for images
+        */
+       private $_IMAGE_ENDPOINT = 'http://coverartarchive.org/release/';
+
+       /**
+        * @var int The amount of entries returned for release search
+        */
+       private $_resultLimit = 10;
+
+       /**
+        * Musicbrainz constructor.
+        *
+        * @param $options array
+        */
+       public function __construct(array $options) {
+               if(isset($options['debug']) && !empty($options['debug'])) {
+                       $this->_DEBUG = true;
+               }
+
+               if(isset($options['resultLimit']) && !empty($options['resultLimit'])) {
+                       $this->_resultLimit = $options['resultLimit'];
+               }
+
+               $this->_BROWSER_AGENT = $options['browserAgent'];
+               $this->_BROWSER_LANG = $options['browserLang'];
+               $this->_BROWSER_ACCEPT = $options['browserAccept'];
+       }
+
+
+       /**
+        * Search for a release fpr the given artist and album name
+        *
+        * http://musicbrainz.org/ws/2/release/?query=artist:broilers%20AND%20release:muerte%20AND%20format:CD&fmt=json
+        *
+        * [releaseID] = title - artist - status - date - country - disambiguation - packaging - track-count
+        *
+        *
+        * @param string $artist The artist to search for
+        * @param string $album The album of the artist to search for
+        *
+        * @return array
+        */
+       public function searchForRelease(string $artist, string $album): array {
+               $ret = array();
+
+               if(!empty($artist) && !empty($album)) {
+                       $artist = urlencode($artist);
+                       $album = urlencode($album);
+                       $url = $this->_RELEASE_ENDPOINT;
+                       $url .= '?&fmt=json&limit='.$this->_resultLimit.'&query=';
+                       $url .= 'artist:'.$artist.'%20AND%20release:'.$album.'%20AND%20format:CD';
+
+                       if(DEBUG) error_log("[DEBUG] musicbrainz release url: $url");
+
+                       $do = $this->_curlCall($url);
+                       $data = '';
+                       if(!empty($do)) {
+                               $data = json_decode($do, true);
+                               if(!empty($data)) {
+                                       if(DEBUG) error_log("[DEBUG] musicbrainz releases json data:".var_export($data,true));
+                               }
+                               else {
+                                       error_log("[ERROR] musicbrainz invalid releases json data:".var_export($do,true));
+                               }
+                       }
+
+                       if(!empty($data)) {
+                               if(isset($data['releases'])) {
+                                       foreach($data['releases'] as $release) {
+                                               if(isset($release['title'])
+                                                       && isset($release['status'])
+                                                       && isset($release['date'])
+                                                       && isset($release['country'])
+                                                       && isset($release['artist-credit'][0]['name'])) {
+
+                                                       $ret[$release['id']] = $release['title'].' - '.$release['artist-credit'][0]['name'].'; '.$release['status'].'; '.$release['date'].'; '.$release['country'];
+
+                                                       if(isset($release['disambiguation'])) {
+                                                               $ret[$release['id']] .= '; '.$release['disambiguation'];
+                                                       }
+                                                       if(isset($release['packaging'])) {
+                                                               $ret[$release['id']] .= '; '.$release['packaging'];
+                                                       }
+
+                                                       if(isset($release['track-count'])) {
+                                                               $ret[$release['id']] .= '; tracks: '.$release['track-count'];
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+
+               }
+
+               return $ret;
+       }
+
+       /**
+        * Get the information from musicBrainz by given release ID
+        * https://musicbrainz.org/doc/MusicBrainz_API/Examples#Release
+        *
+        * http://musicbrainz.org/ws/2/release/59211ea4-ffd2-4ad9-9a4e-941d3148024a?inc=recordings&fmt=json
+        *
+        * [album] => title
+        * [date] => date
+        * [artist] => artist-credit name
+        * [tracks] => number - title - min
+        * [image] => img url
+        * [runtime] => summed up runtime in minutes from tracks
+        *
+        * @param string $releaseId
+        * @return array
+        */
+       public function getReleaseInfo(string $releaseId): array {
+               $ret = array();
+
+               if(!empty($releaseId)) {
+                       $url = $this->_RELEASE_ENDPOINT;
+                       $url .= $releaseId;
+                       $url .= '?&fmt=json&inc=recordings+artist-credits';
+
+                       $do = $this->_curlCall($url);
+                       $data = '';
+                       if(!empty($do)) {
+                               $data = json_decode($do, true);
+                               if(!empty($data)) {
+                                       if(DEBUG) error_log("[DEBUG] musicbrainz release json data:".var_export($data,true));
+                               }
+                               else {
+                                       error_log("[ERROR] musicbrainz invalid release json data:".var_export($do,true));
+                               }
+                       }
+
+                       if(!empty($data)) {
+                               $ret['id'] = isset($data['id']) ? $data['id'] : '';
+                               $ret['album'] = isset($data['title']) ? $data['title'] : '';
+                               $ret['date'] = isset($data['date']) ? $data['date'] : '';
+                               $ret['artist'] = isset($data['artist-credit'][0]['name']) ? $data['artist-credit'][0]['name'] : '';
+                               $ret['tracks'] = '';
+                               $ret['image'] = '';
+                               $ret['runtime'] = 0;
+                               foreach($data['media'][0]['tracks'] as $track) {
+                                       $ret['runtime'] += $track['length'];
+                                       $l = $track['length'] / 1000;
+                                       $l = date("i:s",$l);
+                                       $ret['tracks'] .= $track['number'].' - '.$track['title'].' - '.$l."\n";
+                               }
+                               $ret['runtime'] = $ret['runtime'] / 1000;
+                               $ret['runtime'] = date("i",$ret['runtime']);
+
+                               // image
+                               $do = $this->_curlCall($this->_IMAGE_ENDPOINT.$releaseId);
+                               if(!empty($do)) {
+                                       $imageData = json_decode($do, true);
+                                       if(!empty($imageData)) {
+                                               if(DEBUG) error_log("[DEBUG] image release json data:".var_export($imageData,true));
+                                               $ret['image'] = isset($imageData['images'][0]['image']) ? $imageData['images'][0]['image'] : '';
+                                       }
+                                       else {
+                                               error_log("[ERROR] image invalid release json data:".var_export($do,true));
+                                       }
+                               }
+                       }
+               }
+
+               return $ret;
+       }
+
+       /**
+        * Download given URL to a tmp file
+        * make sure to remove the tmp file after use
+        *
+        * @param string $url
+        * @return string
+        */
+       public function downloadCover(string $url): string {
+               $ret = '';
+
+               $_tmpFile = tempnam(sys_get_temp_dir(), "bibliotheca-");
+               $fh = fopen($_tmpFile,"w+");
+               if($fh !== false) {
+
+                       $ch = curl_init($url);
+                       curl_setopt($ch, CURLOPT_FILE, $fh);
+
+                       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) {
+                               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);
+
+                       if($this->_DEBUG) {
+                               error_log('[DEBUG] '.__METHOD__.' headers '.var_export($_headers,true));
+                       }
+
+                       $ret = $_tmpFile;
+               }
+               fclose($fh);
+
+               return $ret;
+       }
+
+       /**
+        * execute a curl call to the given $url
+        *
+        * @param string $url The request url
+        * @param integer $port
+        * @return string
+        */
+       private function _curlCall(string $url, $port=80): 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_PORT, $port);
+               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-Language: '.$this->_BROWSER_LANG)
+               );
+
+               if($this->_DEBUG) {
+                       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(is_string($do) === true) {
+                       $ret = $do;
+               }
+               curl_close($ch);
+
+               if($this->_DEBUG) {
+                       error_log('[DEBUG] '.__METHOD__.' headers '.var_export($_headers,true));
+               }
+
+               return $ret;
+       }
+}
index 86133f452cf2ae10d00a4a5c569c543557e03ee1..ea684dbbf5ca31c29dab1b638ac15e02d6cc0416 100644 (file)
@@ -457,34 +457,7 @@ class Summoner {
        }
 
        /**
-        * execute a curl call to the fiven $url
-        * @param string $url The request url
-        * @param integer $port
-        * @return bool|string
-        */
-       static function curlCall($url,$port=80) {
-               $ret = false;
-
-               $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_PORT, $port);
-
-               $do = curl_exec($ch);
-               if(is_string($do) === true) {
-                       $ret = $do;
-               }
-
-               curl_close($ch);
-
-               return $ret;
-       }
-
-       /**
-        * check if a string strts with a given string
+        * check if a string starts with a given string
         *
         * @param string $haystack
         * @param string $needle
index 3abed0a23db4477cbedacc4da643f1ec8f7541c2..b6fe15de048a58e2ae387f39e11ee91a4512eabd 100644 (file)
@@ -93,12 +93,12 @@ if(!empty($_collection)) {
                                                $_value = trim($fdata[$fieldData['identifier']]);
                                                $fieldData['valueToSave'] = trim($fdata[$fieldData['identifier']]);
                                                $_fieldsToSave[$fieldData['identifier']] = $fieldData;
-                                       } elseif(isset($fupload['name'][$fieldData['identifier']])) {
+                                       } elseif(isset($fupload['name'][$fieldData['identifier']])) { // special case upload
                                                if(isset($fdata[$fieldData['identifier']."_delete"])) {
                                                        $fieldData['deleteData'] = $fdata[$fieldData['identifier']."_delete"];
                                                }
-                                               // special case upload
-                                               // $_FILES data is combined
+
+                                               // $_FILES data is combined if multiple
                                                $fieldData['uploadData'] = $fupload;
 
                                                $_fieldsToSave[$fieldData['identifier']] = $fieldData;
index b3e3601ec76b2dd24aff753dd98167b5f7e6f665..78aeaef9dc582abc53b2cc3160352cc4d8651e3e 100644 (file)
@@ -88,7 +88,7 @@ if(isset($_POST['submitFormSave'])) {
 
                if(!empty($_imdbId)) {
                        try {
-                               $IMDB->search($_imdbId);
+                               $IMDB->search($_imdbId); // cache used
                        }
                        catch (Exception $e) {
                                if(DEBUG) error_log("[DEBUG] imdb search catch: ".$e->getMessage());
diff --git a/webclient/view/default/tool/tool-musicbrainz.html b/webclient/view/default/tool/tool-musicbrainz.html
new file mode 100644 (file)
index 0000000..4a813dd
--- /dev/null
@@ -0,0 +1,75 @@
+<form class="uk-form-horizontal uk-margin-small" method="post" enctype="multipart/form-data">
+       <div class="uk-margin">
+               <label class="uk-form-label" for="artist">Artist</label>
+               <div class="uk-form-controls">
+                       <input class="uk-input" id="artist" type="text" autocomplete="off"
+                              name="fdata[artist]"
+                              value="<?php echo Summoner::ifset($TemplateData['editEntry'], 'artist'); ?>"
+                       >
+               </div>
+       </div>
+       <div class="uk-margin">
+               <label class="uk-form-label" for="album">Album/Title</label>
+               <div class="uk-form-controls">
+                       <input class="uk-input" id="album" type="text" autocomplete="off"
+                              name="fdata[album]"
+                              value="<?php echo Summoner::ifset($TemplateData['editEntry'], 'title'); ?>"
+                       >
+               </div>
+       </div>
+       <div class="uk-margin">
+               <button class="uk-button uk-button-primary" type="submit" name="submitFormSearch">
+                       Search
+               </button>
+       </div>
+</form>
+
+<?php if(!empty($TemplateData['releases'])) { ?>
+<form class="uk-form-horizontal uk-margin-small" method="post" enctype="multipart/form-data">
+       <div class="uk-margin">
+               <div class="uk-form-controls">
+
+                       <?php foreach($TemplateData['releases'] as $k=>$v) { ?>
+
+                       <label><input class="uk-radio" type="radio" name="fdata[rselect]" value="<?php echo $k; ?>"> <?php echo $v; ?></label><br>
+
+                       <?php } ?>
+               </div>
+       </div>
+
+       <div class="uk-margin">
+               <button class="uk-button uk-button-primary" type="submit" name="submitFormReleaseSelect">
+                       Select
+               </button>
+       </div>
+</form>
+<?php } ?>
+
+<?php if(!empty($TemplateData['release'])) { ?>
+<a href="https://musicbrainz.org/release/<?php echo $TemplateData['release']['id']; ?>" target=_blank>Musibrainz release page</a>
+<form class="uk-form-horizontal uk-margin-small" method="post" enctype="multipart/form-data" uk-grid>
+
+       <?php foreach($TemplateData['release'] as $k=>$v) { ?>
+       <input name="fdata[from][<?php echo $k; ?>]" type="hidden" value="<?php echo $v; ?>"  />
+       <div class="uk-width-1-2@s uk-overflow-hidden">
+               <p>
+                       <b><?php echo $k; ?></b><br />
+                       <?php echo nl2br($v); ?>
+               </p>
+       </div>
+       <div class="uk-width-1-2@s">
+               <select class="uk-select" name="fdata[into][<?php echo $k; ?>]">
+                       <option value="">None</option>
+                       <?php echo toolMethod_GetTargetSelection($TemplateData['saveToSelection'],$k); ?>
+               </select>
+       </div>
+
+       <?php } ?>
+
+       <div class="uk-margin">
+               <button class="uk-button uk-button-primary" type="submit" name="submitFormSave">
+                       Save
+               </button>
+       </div>
+</form>
+<?php } ?>
diff --git a/webclient/view/default/tool/tool-musicbrainz.php b/webclient/view/default/tool/tool-musicbrainz.php
new file mode 100644 (file)
index 0000000..a6f50fb
--- /dev/null
@@ -0,0 +1,190 @@
+<?php
+/**
+ * Bibliotheca
+ *
+ * Copyright 2018-2021 Johannes Keßler
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * this is the special file for a tool.
+ * Requirements and more information come from the main tool.php file
+ *
+ * https://musicbrainz.org/doc/Development
+ * http://musicbrainz.org/ws/2/release/?query=artist:broilers%20AND%20release:muerte%20AND%20format:CD&fmt=json
+ * http://musicbrainz.org/ws/2/release/5eb27466-fe5e-4683-aa9c-1ca396741c7c?&fmt=json
+ */
+
+require_once 'lib/musicbrainz.class.php';
+if(file_exists(PATH_ABSOLUTE.'/config/config-musicbrainz.php')) {
+       require_once 'config/config-musicbrainz.php';
+}
+
+$Brainz = new Musicbrainz(array(
+       'resultLimit' => TOOL_BRAINZ_RESULT_LIMIT,
+       'browserAgent' => TOOL_BRAINZ_BROWSER_AGENT,
+       'browserLang' => TOOL_BRAINZ_BROWSER_ACCEPT_LANG,
+       'browserAccept' => TOOL_BRAINZ_BROWSER_ACCEPT,
+       'debug' => true
+));
+
+$TemplateData['releases'] = array();
+$TemplateData['release'] = array();
+$TemplateData['saveToSelection'] = '';
+
+// 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'] .= "<option value='".$k."' sel_".$v['identifier'].">".$v['displayname']."</option>\n";
+       }
+}
+
+if(isset($_POST['submitFormSearch'])) {
+       $fdata = $_POST['fdata'];
+       if (!empty($fdata)) {
+               $artist = trim($fdata['artist']);
+               $artist = Summoner::validate($artist) ? $artist : false;
+               $album = trim($fdata['album']);
+               $album = Summoner::validate($album) ? $album : false;
+
+               if(!empty($artist) && !empty($album)) {
+                       $releaseSearch = $Brainz->searchForRelease($artist, $album);
+
+                       if(!empty($releaseSearch)) {
+                               $TemplateData['releases'] = $releaseSearch;
+                       } else {
+                               $TemplateData['message']['content'] = "Nothing found.";
+                               $TemplateData['message']['status'] = "error";
+                       }
+               }
+               else {
+                       $TemplateData['message']['content'] = "Invalid search term";
+                       $TemplateData['message']['status'] = "error";
+               }
+       }
+}
+
+if(isset($_POST['submitFormReleaseSelect'])) {
+       if (isset($_POST['fdata'])) {
+               $fdata = $_POST['fdata'];
+               if (!empty($fdata)) {
+                       $releaseId = $fdata['rselect'];
+                       if(!empty($releaseId)) {
+                               $releaseInfo = $Brainz->getReleaseInfo($releaseId);
+                               if(!empty($releaseInfo)) {
+                                       $TemplateData['release'] = $releaseInfo;
+                               } else {
+                                       $TemplateData['message']['content'] = "Nothing found.";
+                                       $TemplateData['message']['status'] = "error";
+                               }
+                       }
+               }
+       }
+       else {
+               $TemplateData['message']['content'] = "Invalid selection";
+               $TemplateData['message']['status'] = "error";
+       }
+}
+
+if(isset($_POST['submitFormSave'])) {
+       $fdata = $_POST['fdata'];
+       if (!empty($fdata)) {
+
+               // build data array based on submit
+               // see creation log for structure
+               $_data = array();
+               foreach($fdata['into'] as $k=>$v) {
+                       if(!empty($v) && isset($fdata['from'][$k])) {
+                               if(isset($collectionFields[$v])) {
+
+                                       $_data[$v] = $collectionFields[$v];
+                                       $_data[$v]['valueToSave'] = $fdata['from'][$k];
+
+                                       // special case for image
+                                       if($k == "image") {
+
+                                               $fieldData = array();
+
+                                               $_f = $Brainz->downloadCover($fdata['from'][$k]);
+                                               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'] = "Date saved successfully";
+               }
+               else {
+                       // create into loaded collection
+                       $do = $Manageentry->create($_data,
+                               $_r['id'],
+                               $_r['group'],
+                               $_r['rights']
+                       );
+                       $TemplateData['message']['content'] = "Date saved successfully: 
+                                               <a href='index.php?p=manageentry&collection=".$collection['id']."&id=".$do."'>Here</a>";
+               }
+
+               if(!empty($do)) {
+                       $TemplateData['message']['status'] = "success";
+               }
+               else {
+                       $TemplateData['message']['content'] = "Data could not be saved. See logs for more.";
+                       $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_BRAINZ_FIELDS_TO is defined and a matching key=>value pair is available
+ *
+ * @param string $optionString
+ * @param string $key
+ * @return string
+ */
+function toolMethod_GetTargetSelection(string $optionString, string $key): string {
+       if(defined('TOOL_BRAINZ_FIELDS_TO') & !empty($key)) {
+               if(isset(TOOL_BRAINZ_FIELDS_TO[$key])) {
+                       $_k = "sel_".TOOL_BRAINZ_FIELDS_TO[$key];
+                       $optionString = str_replace($_k,'selected="selected"',$optionString);
+               }
+       }
+
+       return $optionString;
+}