Passed
Push — master ( 3c5a6f...e94730 )
by Pauli
09:42 queued 11s
created

ArtistBusinessLayer::findNotRecentPlay()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
nc 1
nop 3
1
<?php declare(strict_types=1);
2
3
/**
4
 * ownCloud - Music app
5
 *
6
 * This file is licensed under the Affero General Public License version 3 or
7
 * later. See the COPYING file.
8
 *
9
 * @author Morris Jobke <[email protected]>
10
 * @author Pauli Järvinen <[email protected]>
11
 * @copyright Morris Jobke 2013, 2014
12
 * @copyright Pauli Järvinen 2017 - 2020
13
 */
14
15
namespace OCA\Music\BusinessLayer;
16
17
use \OCA\Music\AppFramework\BusinessLayer\BusinessLayer;
18
use \OCA\Music\AppFramework\Core\Logger;
19
20
use \OCA\Music\Db\Artist;
21
use \OCA\Music\Db\ArtistMapper;
22
use \OCA\Music\Db\SortBy;
23
24
use \OCA\Music\Utility\Util;
25
26
/**
27
 * Base class functions with the actually used inherited types to help IDE and Scrutinizer:
28
 * @method Artist find(int $trackId, string $userId)
29
 * @method Artist[] findAll(string $userId, int $sortBy=SortBy::None, int $limit=null, int $offset=null)
30
 * @method Artist[] findAllByName(string $name, string $userId, bool $fuzzy=false, int $limit=null, int $offset=null)
31
 * @method Artist[] findById(int[] $ids, string $userId=null, bool $preserveOrder=false)
32
 * @phpstan-extends BusinessLayer<Artist>
33
 */
34
class ArtistBusinessLayer extends BusinessLayer {
35
	protected $mapper; // eclipse the definition from the base class, to help IDE and Scrutinizer to know the actual type
36
	private $logger;
37
38
	public function __construct(ArtistMapper $artistMapper, Logger $logger) {
39
		parent::__construct($artistMapper);
40
		$this->mapper = $artistMapper;
41
		$this->logger = $logger;
42
	}
43
44
	/**
45
	 * Finds all artists who have at least one album
46
	 * @param string $userId the name of the user
47
	 * @param integer $sortBy sort order of the result set
48
	 * @return Artist[] artists
49
	 */
50
	public function findAllHavingAlbums($userId, $sortBy=SortBy::None) {
51
		return $this->mapper->findAllHavingAlbums($userId, $sortBy);
52
	}
53
54
	/**
55
	 * Returns all artists filtered by genre
56
	 * @param int $genreId the genre to include
57
	 * @param string $userId the name of the user
58
	 * @param int|null $limit
59
	 * @param int|null $offset
60
	 * @return Artist[] artists
61
	 */
62
	public function findAllByGenre($genreId, $userId, $limit=null, $offset=null) {
63
		return $this->mapper->findAllByGenre($genreId, $userId, $limit, $offset);
64
	}
65
66
	/**
67
	 * Find most frequently played artists, judged by the total play count of the contained tracks
68
	 * @return Artist[]
69
	 */
70
	public function findFrequentPlay(string $userId, ?int $limit=null, ?int $offset=null) : array {
71
		$countsPerArtist = $this->mapper->getArtistTracksPlayCount($userId, $limit, $offset);
72
		$ids = \array_keys($countsPerArtist);
73
		return $this->findById($ids, $userId, /*preserveOrder=*/true);
74
	}
75
76
	/**
77
	 * Find most recently played artists
78
	 * @return Artist[]
79
	 */
80
	public function findRecentPlay(string $userId, ?int $limit=null, ?int $offset=null) : array {
81
		$playTimePerArtist = $this->mapper->getLatestArtistPlayTimes($userId, $limit, $offset);
82
		$ids = \array_keys($playTimePerArtist);
83
		return $this->findById($ids, $userId, /*preserveOrder=*/true);
84
	}
85
86
	/**
87
	 * Find least recently played artists
88
	 * @return Artist[]
89
	 */
90
	public function findNotRecentPlay(string $userId, ?int $limit=null, ?int $offset=null) : array {
91
		$playTimePerArtist = $this->mapper->getFurthestArtistPlayTimes($userId, $limit, $offset);
92
		$ids = \array_keys($playTimePerArtist);
93
		return $this->findById($ids, $userId, /*preserveOrder=*/true);
94
	}
95
96
	/**
97
	 * Adds an artist if it does not exist already or updates an existing artist
98
	 * @param string|null $name the name of the artist
99
	 * @param string $userId the name of the user
100
	 * @return Artist The added/updated artist
101
	 */
102
	public function addOrUpdateArtist($name, $userId) {
103
		$artist = new Artist();
104
		$artist->setName(Util::truncate($name, 256)); // some DB setups can't truncate automatically to column max size
105
		$artist->setUserId($userId);
106
		$artist->setHash(\hash('md5', \mb_strtolower($name ?? '')));
107
		return $this->mapper->updateOrInsert($artist);
108
	}
109
110
	/**
111
	 * Use the given file as cover art for an artist if there exists an artist
112
	 * with name matching the file name.
113
	 * @param \OCP\Files\File $imageFile
114
	 * @param string $userId
115
	 * @return int|false artistId of the modified artist if the file was set as cover for an artist;
116
	 *                   false if no artist was modified
117
	 */
118
	public function updateCover($imageFile, $userId) {
119
		$name = \pathinfo($imageFile->getName(), PATHINFO_FILENAME);
120
		$matches = $this->findAllByName(/** @scrutinizer ignore-type */ $name, $userId);
121
122
		if (!empty($matches)) {
123
			$artist = $matches[0];
124
			$artist->setCoverFileId($imageFile->getId());
125
			$this->mapper->update($artist);
126
			return $artist->getId();
127
		}
128
129
		return false;
130
	}
131
132
	/**
133
	 * Match the given files by file name to the artist names. If there is a matching
134
	 * artist with no cover image already set, the matched file is set to be used as
135
	 * cover for this artist.
136
	 * @param \OCP\Files\File[] $imageFiles
137
	 * @param string $userId
138
	 * @return bool true if any artist covers were updated; false otherwise
139
	 */
140
	public function updateCovers($imageFiles, $userId) {
141
		$updated = false;
142
143
		// construct a lookup table for the images as there may potentially be
144
		// a huge amount of them
145
		$imageLut = [];
146
		foreach ($imageFiles as $imageFile) {
147
			$imageLut[\pathinfo($imageFile->getName(), PATHINFO_FILENAME)] = $imageFile;
148
		}
149
150
		$artists = $this->findAll($userId);
151
152
		foreach ($artists as $artist) {
153
			if ($artist->getCoverFileId() === null && isset($imageLut[$artist->getName()])) {
154
				$artist->setCoverFileId($imageLut[$artist->getName()]->getId());
155
				$this->mapper->update($artist);
156
				$updated = true;
157
			}
158
		}
159
160
		return $updated;
161
	}
162
163
	/**
164
	 * removes the given cover art files from artists
165
	 * @param integer[] $coverFileIds the file IDs of the cover images
166
	 * @param string[]|null $userIds the users whose music library is targeted; all users are targeted if omitted
167
	 * @return Artist[] artists which got modified, empty array if none
168
	 */
169
	public function removeCovers($coverFileIds, $userIds=null) {
170
		return $this->mapper->removeCovers($coverFileIds, $userIds);
171
	}
172
}
173