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 */ 22 23declare(strict_types=0); 24 25namespace Ampache\Module\Api\Method; 26 27use Ampache\Config\AmpConfig; 28use Ampache\Repository\Model\Catalog; 29use Ampache\Repository\Model\Podcast_Episode; 30use Ampache\Repository\Model\Song; 31use Ampache\Repository\Model\User; 32use Ampache\Repository\Model\Video; 33use Ampache\Module\Api\Api; 34use Ampache\Module\Song\Deletion\SongDeleterInterface; 35use Ampache\Module\System\Session; 36 37/** 38 * Class CatalogFileMethod 39 * @package Lib\ApiMethods 40 */ 41final class CatalogFileMethod 42{ 43 private const ACTION = 'catalog_file'; 44 45 /** 46 * catalog_file 47 * MINIMUM_API_VERSION=420000 48 * 49 * Perform actions on local catalog files. 50 * Single file versions of catalog add, clean and verify. 51 * Make sure you remember to urlencode those file names! 52 * 53 * @param array $input 54 * file = (string) urlencode(FULL path to local file) 55 * task = (string) 'add', 'clean', 'verify', 'remove' (can be comma separated) 56 * catalog = (integer) $catalog_id) 57 * @return boolean 58 */ 59 public static function catalog_file(array $input) 60 { 61 if (!Api::check_access('interface', 50, User::get_from_username(Session::username($input['auth']))->id, self::ACTION, $input['api_format'])) { 62 return false; 63 } 64 if (!Api::check_parameter($input, array('catalog', 'file', 'task'), self::ACTION)) { 65 return false; 66 } 67 $file = (string) html_entity_decode($input['file']); 68 $task = explode(',', (string)$input['task']); 69 if (!$task) { 70 $task = array(); 71 } 72 73 // confirm that a valid task is going to happen 74 if (!AmpConfig::get('delete_from_disk') && in_array('remove', $task)) { 75 Api::error(T_('Enable: delete_from_disk'), '4703', self::ACTION, 'system', $input['api_format']); 76 77 return false; 78 } 79 if (!file_exists($file) && !in_array('clean', $task)) { 80 /* HINT: Requested object string/id/type ("album", "myusername", "some song title", 1298376) */ 81 Api::error(sprintf(T_('Not Found: %s'), $file), '4704', self::ACTION, 'file', $input['api_format']); 82 83 return false; 84 } 85 foreach ($task as $item) { 86 if (!in_array($item, array('add', 'clean', 'verify', 'remove'))) { 87 /* HINT: Requested object string/id/type ("album", "myusername", "some song title", 1298376) */ 88 Api::error(sprintf(T_('Bad Request: %s'), $item), '4710', self::ACTION, 'task', $input['api_format']); 89 90 return false; 91 } 92 } 93 $catalog_id = (int) $input['catalog']; 94 $catalog = Catalog::create_from_id($catalog_id); 95 if ($catalog->id < 1) { 96 /* HINT: Requested object string/id/type ("album", "myusername", "some song title", 1298376) */ 97 Api::error(sprintf(T_('Not Found: %s'), $catalog_id), '4704', self::ACTION, 'catalog', $input['api_format']); 98 99 return false; 100 } 101 switch ($catalog->gather_types) { 102 case 'podcast': 103 $type = 'podcast_episode'; 104 $media = new Podcast_Episode(Catalog::get_id_from_file($file, $type)); 105 break; 106 case 'clip': 107 case 'tvshow': 108 case 'movie': 109 case 'personal_video': 110 $type = 'video'; 111 $media = new Video(Catalog::get_id_from_file($file, $type)); 112 break; 113 case 'music': 114 default: 115 $type = 'song'; 116 $media = new Song(Catalog::get_id_from_file($file, $type)); 117 break; 118 } 119 120 if ($catalog->catalog_type == 'local') { 121 foreach ($task as $item) { 122 define('API', true); 123 unset($SSE_OUTPUT); 124 switch ($item) { 125 case 'clean': 126 if ($media->id) { 127 $catalog->clean_file($file, $type); 128 } 129 break; 130 case 'verify': 131 if ($media->id) { 132 Catalog::update_media_from_tags($media, array($type)); 133 } 134 break; 135 case 'add': 136 if (!$media->id) { 137 $catalog->add_file($file, array()); 138 } 139 break; 140 case 'remove': 141 if ($media->id) { 142 $media->remove(); 143 } 144 break; 145 } 146 } 147 Api::message('successfully started: ' . $task . ' for ' . $file, $input['api_format']); 148 } else { 149 Api::error(T_('Not Found'), '4704', self::ACTION, 'catalog', $input['api_format']); 150 } 151 Session::extend($input['auth']); 152 153 return true; 154 } 155 156 /** 157 * @deprecated 158 */ 159 public static function getSongDeleter(): SongDeleterInterface 160 { 161 global $dic; 162 163 return $dic->get(SongDeleterInterface::class); 164 } 165} 166