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\Preference;
27use Ampache\Repository\Model\User;
28use Ampache\Repository\Model\Wanted;
29use Exception;
30use Requests;
31
32class AmpacheHeadphones
33{
34    public $name        = 'Headphones';
35    public $categories  = 'wanted';
36    public $description = 'Automatically download accepted Wanted List albums with Headphones';
37    public $url         = 'https://github.com/rembo10/headphones/';
38    public $version     = '000001';
39    public $min_ampache = '360030';
40    public $max_ampache = '999999';
41
42    // These are internal settings used by this class, run this->load to fill them out
43    private $api_url;
44    private $api_key;
45
46    /**
47     * Constructor
48     * This function does nothing...
49     */
50    public function __construct()
51    {
52        $this->description = T_('Automatically download accepted Wanted List albums with Headphones');
53
54        return true;
55    } // constructor
56
57    /**
58     * install
59     * This is a required plugin function. It inserts our preferences
60     * into Ampache
61     */
62    public function install()
63    {
64
65        // Check and see if it's already installed (they've just hit refresh, those dorks)
66        if (Preference::exists('headphones_api_url')) {
67            return false;
68        }
69
70        Preference::insert('headphones_api_url', T_('Headphones URL'), '', 25, 'string', 'plugins', $this->name);
71        Preference::insert('headphones_api_key', T_('Headphones API key'), '', 25, 'string', 'plugins', $this->name);
72
73        return true;
74    } // install
75
76    /**
77     * uninstall
78     * This is a required plugin function. It removes our preferences from
79     * the database returning it to its original form
80     */
81    public function uninstall()
82    {
83        Preference::delete('headphones_api_url');
84        Preference::delete('headphones_api_key');
85
86        return true;
87    } // uninstall
88
89    /**
90     * upgrade
91     * This is a recommended plugin function
92     */
93    public function upgrade()
94    {
95        return true;
96    } // upgrade
97
98    /**
99     * process_wanted
100     * This takes care of auto-download accepted Wanted List albums
101     * @param Wanted $wanted
102     * @return boolean
103     */
104    public function process_wanted($wanted)
105    {
106        set_time_limit(0);
107
108        $headartist = json_decode($this->headphones_call('getArtist', array(
109            'id' => $wanted->artist_mbid
110        )));
111
112        // No artist info, need to add artist to Headphones first. Can be long!
113        if (!$headartist->artist) {
114            $this->headphones_call('addArtist', array(
115                'id' => $wanted->artist_mbid
116            ));
117        }
118
119        return ($this->headphones_call('queueAlbum', array(
120                'id' => $wanted->mbid
121            )) == 'OK');
122    } // process_wanted
123
124    /**
125     * @param $command
126     * @param $params
127     * @return boolean
128     */
129    protected function headphones_call($command, $params)
130    {
131        if (empty($this->api_url) || empty($this->api_key)) {
132            debug_event(self::class, 'Headphones url or api key missing', 3);
133
134            return false;
135        }
136
137        $url = $this->api_url . '/api?apikey=' . $this->api_key . '&cmd=' . $command;
138        foreach ($params as $key => $value) {
139            $url .= '&' . $key . '=' . urlencode($value);
140        }
141
142        debug_event(self::class, 'Headphones api call: ' . $url, 5);
143        try {
144            // We assume Headphone server is local, don't use proxy here
145            $request = Requests::get($url, array(), array(
146                'timeout' => 600
147            ));
148        } catch (Exception $error) {
149            debug_event(self::class, 'Headphones api http exception: ' . $error->getMessage(), 1);
150
151            return false;
152        }
153
154        return $request->body;
155    }
156
157    /**
158     * load
159     * This loads up the data we need into this object, this stuff comes
160     * from the preferences.
161     * @param User $user
162     * @return boolean
163     */
164    public function load($user)
165    {
166        $user->set_preferences();
167        $data = $user->prefs;
168        // load system when nothing is given
169        if (!strlen(trim($data['headphones_api_url'])) || !strlen(trim($data['headphones_api_key']))) {
170            $data                       = array();
171            $data['headphones_api_url'] = Preference::get_by_user(-1, 'headphones_api_url');
172            $data['headphones_api_key'] = Preference::get_by_user(-1, 'headphones_api_key');
173        }
174
175        if (strlen(trim($data['headphones_api_url']))) {
176            $this->api_url = rtrim(trim($data['headphones_api_url']), '/');
177        } else {
178            debug_event(self::class, 'No Headphones url, auto download skipped', 3);
179
180            return false;
181        }
182        if (strlen(trim($data['headphones_api_key']))) {
183            $this->api_key = trim($data['headphones_api_key']);
184        } else {
185            debug_event(self::class, 'No Headphones api key, auto download skipped', 3);
186
187            return false;
188        }
189
190        return true;
191    } // load
192}
193