1<?php 2/* 3 * vim:set softtabstop=4 shiftwidth=4 expandtab: 4 * 5 * LICENSE: GNU Affero General Public License, version 3 (AGPL-3.0-or-later) 6 * Copyright 2001 - 2020 Ampache.org 7 * 8 * This program is free software: you can redistribute it and/or modify 9 * it under the terms of the GNU Affero General Public License as published by 10 * the Free Software Foundation, either version 3 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU Affero General Public License for more details. 17 * 18 * You should have received a copy of the GNU Affero General Public License 19 * along with this program. If not, see <https://www.gnu.org/licenses/>. 20 * 21 */ 22declare(strict_types=0); 23 24namespace Ampache\Plugin; 25 26use Ampache\Repository\Model\Art; 27use Ampache\Repository\Model\Preference; 28use Ampache\Repository\Model\User; 29use Exception; 30use Requests; 31 32class AmpacheDiscogs 33{ 34 public $name = 'Discogs'; 35 public $categories = 'metadata'; 36 public $description = 'Discogs metadata integration'; 37 public $url = 'http://www.discogs.com'; 38 public $version = '000001'; 39 public $min_ampache = '370021'; 40 public $max_ampache = '999999'; 41 42 private $api_key; 43 private $secret; 44 45 /** 46 * Constructor 47 * This function does nothing 48 */ 49 public function __construct() 50 { 51 $this->description = T_('Discogs metadata integration'); 52 53 return true; 54 } 55 56 /** 57 * install 58 * This is a required plugin function 59 */ 60 public function install() 61 { 62 if (Preference::exists('discogs_api_key')) { 63 return false; 64 } 65 Preference::insert('discogs_api_key', T_('Discogs consumer key'), '', 75, 'string', 'plugins', $this->name); 66 Preference::insert('discogs_secret_api_key', T_('Discogs secret'), '', 75, 'string', 'plugins', $this->name); 67 68 return true; 69 } // install 70 71 /** 72 * uninstall 73 * This is a required plugin function 74 */ 75 public function uninstall() 76 { 77 Preference::delete('discogs_api_key'); 78 Preference::delete('discogs_secret_api_key'); 79 80 return true; 81 } // uninstall 82 83 /** 84 * load 85 * This is a required plugin function; here it populates the prefs we 86 * need for this object. 87 * @param User $user 88 * @return boolean 89 */ 90 public function load($user) 91 { 92 $user->set_preferences(); 93 $data = $user->prefs; 94 // load system when nothing is given 95 if (!strlen(trim($data['discogs_api_key'])) || !strlen(trim($data['discogs_secret_api_key']))) { 96 $data = array(); 97 $data['discogs_api_key'] = Preference::get_by_user(-1, 'discogs_api_key'); 98 $data['discogs_secret_api_key'] = Preference::get_by_user(-1, 'discogs_secret_api_key'); 99 } 100 101 if (strlen(trim($data['discogs_api_key']))) { 102 $this->api_key = trim($data['discogs_api_key']); 103 } else { 104 debug_event(self::class, 'No Discogs api key, metadata plugin skipped', 3); 105 106 return false; 107 } 108 if (strlen(trim($data['discogs_secret_api_key']))) { 109 $this->secret = trim($data['discogs_secret_api_key']); 110 } else { 111 debug_event(self::class, 'No Discogs secret, metadata plugin skipped', 3); 112 113 return false; 114 } 115 116 return true; 117 } // load 118 119 /** 120 * @param $query 121 * @return mixed 122 */ 123 protected function query_discogs($query) 124 { 125 $url = 'https://api.discogs.com/' . $query; 126 $url .= (strpos($query, '?') !== false) ? '&' : '?'; 127 $url .= 'key=' . $this->api_key . '&secret=' . $this->secret; 128 debug_event(self::class, 'Discogs request: ' . $url, 5); 129 $request = Requests::get($url); 130 131 return json_decode($request->body, true); 132 } 133 134 /** 135 * @param $artist 136 * @return mixed 137 */ 138 protected function search_artist($artist) 139 { 140 $query = "database/search?type=artist&title=" . rawurlencode($artist) . "&per_page=10"; 141 142 return $this->query_discogs($query); 143 } 144 145 /** 146 * @param integer $object_id 147 * @return mixed 148 */ 149 protected function get_artist($object_id) 150 { 151 $query = "artists/" . $object_id; 152 153 return $this->query_discogs($query); 154 } 155 156 /** 157 * @param $artist 158 * @param $album 159 * @return mixed 160 */ 161 protected function search_album($artist, $album) 162 { 163 $query = "database/search?type=master&release_title=" . rawurlencode($album) . "&artist=" . rawurlencode($artist) . "&per_page=10"; 164 165 return $this->query_discogs($query); 166 } 167 168 /** 169 * @param integer $object_id 170 * @return mixed 171 */ 172 protected function get_album($object_id) 173 { 174 $query = "masters/" . $object_id; 175 176 return $this->query_discogs($query); 177 } 178 179 /** 180 * get_metadata 181 * Returns song metadata for what we're passed in. 182 * @param array $gather_types 183 * @param array $media_info 184 * @return array|null 185 */ 186 public function get_metadata($gather_types, $media_info) 187 { 188 debug_event(self::class, 'Getting metadata from Discogs...', 5); 189 190 // MUSIC metadata only 191 if (!in_array('music', $gather_types)) { 192 debug_event(self::class, 'Not a valid media type, skipped.', 5); 193 194 return null; 195 } 196 197 $results = array(); 198 try { 199 if (in_array('artist', $gather_types)) { 200 $artists = $this->search_artist($media_info['title']); 201 if (count($artists['results']) > 0) { 202 $artist = $this->get_artist($artists['results'][0]['id']); 203 if (count($artist['images']) > 0) { 204 $results['art'] = $artist['images'][0]['uri']; 205 } 206 } 207 } else { 208 if (in_array('album', $gather_types)) { 209 $albums = $this->search_album($media_info['artist'], $media_info['title']); 210 if (!empty($albums['results'])) { 211 $album = $this->get_album($albums['results'][0]['id']); 212 if (count($album['images']) > 0) { 213 $results['art'] = $album['images'][0]['uri']; 214 } 215 } 216 } 217 } 218 } catch (Exception $error) { 219 debug_event(self::class, 'Error getting metadata: ' . $error->getMessage(), 1); 220 } 221 222 return $results; 223 } // get_metadata 224 225 /** 226 * @param string $type 227 * @param array $options 228 * @param integer $limit 229 * @return array 230 */ 231 public function gather_arts($type, $options = array(), $limit = 5) 232 { 233 return Art::gather_metadata_plugin($this, $type, $options); 234 } 235} 236