1 /* SimilarArtists.cpp */
2 
3 /* Copyright (C) 2011-2020 Michael Lugmair (Lucio Carreras)
4  *
5  * This file is part of sayonara player
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11 
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16 
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include "SimilarArtists.h"
22 #include "Utils/MetaData/Artist.h"
23 #include "Utils/Utils.h"
24 #include "Utils/FileUtils.h"
25 #include "Utils/Compressor/Compressor.h"
26 #include "Utils/StandardPaths.h"
27 
28 #include <QDir>
29 #include <QMap>
30 #include <QStringList>
31 
32 namespace
33 {
getFilename(const QString & artist)34 	QString getFilename(const QString& artist)
35 	{
36 		const auto similarArtistPath = Util::similarArtistsPath();
37 
38 		const auto dir = QDir(similarArtistPath);
39 		const auto files = dir.entryList(
40 			QStringList {"*.comp"},
41 			static_cast<QDir::Filters>(QDir::Files)
42 		);
43 
44 		if(files.isEmpty())
45 		{
46 			return QString();
47 		}
48 
49 		const auto targetName = artist + ".comp";
50 		for(const auto& filename : files)
51 		{
52 			if(filename.compare(targetName, Qt::CaseInsensitive) == 0)
53 			{
54 				return dir.filePath(targetName);
55 			}
56 		}
57 
58 		return QString();
59 	}
60 }
61 
62 QMap<QString, double>
getSimilarArtists(const QString & artist)63 SimilarArtists::getSimilarArtists(const QString& artist)
64 {
65 	QMap<QString, double> similarArtistsMap;
66 	const auto filename = getFilename(artist);
67 	if(filename.isEmpty())
68 	{
69 		return similarArtistsMap;
70 	}
71 
72 	QByteArray content;
73 	const auto success = Util::File::readFileIntoByteArray(filename, content);
74 	if(!success)
75 	{
76 		return similarArtistsMap;
77 	}
78 
79 	const auto decomp = Compressor::decompress(content);
80 	if(decomp.isEmpty())
81 	{
82 		return similarArtistsMap;
83 	}
84 
85 	const auto similarArtists = QString::fromLocal8Bit(decomp).split("\n");
86 	for(const auto& similarArtist : similarArtists)
87 	{
88 		const auto lst = similarArtist.split('\t');
89 		if(lst.size() < 3)
90 		{
91 			continue;
92 		}
93 
94 		const auto& match = lst[0];
95 		const auto& artistName = lst[2];
96 
97 		similarArtistsMap[artistName] = match.toDouble();
98 	}
99 
100 	return similarArtistsMap;
101 }
102 
getSimilarArtistNames(const QString & artist)103 QStringList SimilarArtists::getSimilarArtistNames(const QString& artist)
104 {
105 	return QStringList(getSimilarArtists(artist).keys());
106 }
107