TTKMusicPlayer  4.3.0.0
TTKMusicPlayer imitates Kugou UI, the music player uses of qmmp core library based on Qt for windows and linux
musicunityqueryinterface.cpp
Go to the documentation of this file.
2 
3 static constexpr const char *QUERY_MODULE_X = "*";
4 static constexpr const char *QUERY_MODULE_A = "A";
5 static constexpr const char *QUERY_MODULE_B = "B";
6 static constexpr const char *QUERY_MODULE_C = "C";
7 static constexpr const char *QUERY_MODULE_D = "D";
8 static constexpr const char *QUERY_MODULE_E = "E";
9 static constexpr const char *QUERY_PLUGINS_URL = "resource/plugins";
10 
11 static bool checkModule(const QString &module)
12 {
13  return module == QUERY_MODULE_X ||
14  module == QUERY_MODULE_A ||
15  module == QUERY_MODULE_B ||
16  module == QUERY_MODULE_C ||
17  module == QUERY_MODULE_D ||
18  module == QUERY_MODULE_E;
19 }
20 
21 
22 struct Data
23 {
24  QString m_ua;
25  QString m_url;
26  QString m_body;
27  QString m_quality;
28  QString m_module;
29 };
30 
31 static void parseSongPropertyX(QNetworkRequest *request, TTK::MusicSongInformation *info, int bitrate)
32 {
33  const QByteArray &bytes = TTK::syncNetworkQueryForGet(request);
34  if(bytes.isEmpty())
35  {
36  return;
37  }
38 
39  bool found = false;
40  QJsonParseError ok;
41  const QJsonDocument &json = QJsonDocument::fromJson(bytes, &ok);
43  {
44  QVariantMap value = json.toVariant().toMap();
45  if(value["code"].toInt() == 0 || value["code"].toInt() == 200)
46  {
48  prop.m_url = value["url"].toString();
49  prop.m_size = TTK_DEFAULT_STR;
51  prop.m_bitrate = bitrate;
52 
53  if(prop.isEmpty())
54  {
55  prop.m_url = value["data"].toString();
56  }
57 
58  if(!prop.isEmpty())
59  {
60  found = true;
61  info->m_songProps.append(prop);
62  }
63  }
64  }
65 
66  if(!found)
67  {
68  TTK_INFO_STREAM("Not found metainfo, buffer is" << bytes);
69  }
70 }
71 
72 static void parseSongPropertyA(QNetworkRequest *request, TTK::MusicSongInformation *info, int bitrate, const QString &quality)
73 {
74  const QByteArray &bytes = TTK::syncNetworkQueryForGet(request);
75  if(bytes.isEmpty())
76  {
77  return;
78  }
79 
80  bool found = false;
81  QJsonParseError ok;
82  const QJsonDocument &json = QJsonDocument::fromJson(bytes, &ok);
84  {
85  QVariantMap value = json.toVariant().toMap();
86  if(value["code"].toInt() == 0 || value["code"].toInt() == 200)
87  {
89  prop.m_url = value["url"].toString();
90  prop.m_size = TTK_DEFAULT_STR;
92  prop.m_bitrate = bitrate;
93 
94  if(prop.isEmpty())
95  {
96  prop.m_url = value["data"].toString();
97  }
98 
99  const QVariantMap &extra = value["extra"].toMap();
100  if(!extra.isEmpty())
101  {
102  value = extra;
103  }
104 
105  const QVariantMap &q = value["quality"].toMap();
106  if(q["target"].toString().contains(quality, Qt::CaseInsensitive) &&
107  q["result"].toString().contains(quality, Qt::CaseInsensitive) && !prop.isEmpty())
108  {
109  found = true;
110  info->m_songProps.append(prop);
111  }
112  }
113  }
114 
115  if(!found)
116  {
117  TTK_INFO_STREAM("Not found metainfo, buffer is" << bytes);
118  }
119 }
120 
121 static void parseSongPropertyB(QNetworkRequest *request, TTK::MusicSongInformation *info, int bitrate)
122 {
123  const QByteArray &bytes = TTK::syncNetworkQueryForGet(request);
124  if(bytes.isEmpty())
125  {
126  return;
127  }
128 
129  bool found = false;
130  QJsonParseError ok;
131  const QJsonDocument &json = QJsonDocument::fromJson(bytes, &ok);
133  {
134  QVariantMap value = json.toVariant().toMap();
135  if(value.contains("url"))
136  {
138  prop.m_url = value["url"].toString();
139  prop.m_size = value.contains("size") ? TTK::Number::sizeByteToLabel(value["size"].toInt()) : TTK_DEFAULT_STR;
141  prop.m_bitrate = value.contains("br") ? value["br"].toInt() : bitrate;
142 
143  if(prop.isEmpty())
144  {
145  prop.m_url = value["data"].toString();
146  }
147 
148  if(!prop.isEmpty())
149  {
150  found = true;
151  info->m_songProps.append(prop);
152  }
153  }
154  }
155 
156  if(!found)
157  {
158  TTK_INFO_STREAM("Not found metainfo, buffer is" << bytes);
159  }
160 }
161 
162 static void parseSongPropertyC(QNetworkRequest *request, TTK::MusicSongInformation *info, int bitrate, const QString &quality)
163 {
164  const QByteArray &bytes = TTK::syncNetworkQueryForGet(request);
165  if(bytes.isEmpty())
166  {
167  return;
168  }
169 
170  bool found = false;
171  QJsonParseError ok;
172  const QJsonDocument &json = QJsonDocument::fromJson(bytes, &ok);
174  {
175  QVariantMap value = json.toVariant().toMap();
176  if(value["code"].toInt() == 0 || value["code"].toInt() == 200)
177  {
179  prop.m_url = value["url"].toString();
180  prop.m_size = TTK_DEFAULT_STR;
182  prop.m_bitrate = bitrate;
183 
184  if(prop.isEmpty())
185  {
186  prop.m_url = value["data"].toString();
187  }
188 
189  const QString &q = value["quality"].toString();
190  if(q.contains(quality, Qt::CaseInsensitive) && !prop.isEmpty())
191  {
192  found = true;
193  info->m_songProps.append(prop);
194  }
195  }
196  }
197 
198  if(!found)
199  {
200  TTK_INFO_STREAM("Not found metainfo, buffer is" << bytes);
201  }
202 }
203 
204 static void parseSongPropertyD(QNetworkRequest *request, TTK::MusicSongInformation *info, int bitrate)
205 {
206  const QByteArray &bytes = TTK::syncNetworkQueryForGet(request);
207  if(bytes.isEmpty())
208  {
209  return;
210  }
211 
212  bool found = true;
214  prop.m_url = bytes;
215  prop.m_size = TTK_DEFAULT_STR;
217  prop.m_bitrate = bitrate;
218  info->m_songProps.append(prop);
219 
220  if(!found)
221  {
222  TTK_INFO_STREAM("Not found metainfo, buffer is" << bytes);
223  }
224 }
225 
226 static void parseSongPropertyE(QNetworkRequest *request, const QString &body, TTK::MusicSongInformation *info, int bitrate)
227 {
228  const QByteArray &bytes = TTK::syncNetworkQueryForPost(request, body.toUtf8());
229  if(bytes.isEmpty())
230  {
231  return;
232  }
233 
234  bool found = false;
235  QJsonParseError ok;
236  const QJsonDocument &json = QJsonDocument::fromJson(bytes, &ok);
238  {
239  QVariantMap value = json.toVariant().toMap();
240  if(value["code"].toInt() == 0 || value["code"].toInt() == 200)
241  {
243  prop.m_url = value["url"].toString();
244  prop.m_size = TTK_DEFAULT_STR;
246  prop.m_bitrate = bitrate;
247 
248  if(prop.isEmpty())
249  {
250  prop.m_url = value["data"].toString();
251  }
252 
253  if(!prop.isEmpty())
254  {
255  found = true;
256  info->m_songProps.append(prop);
257  }
258  }
259  }
260 
261  if(!found)
262  {
263  TTK_INFO_STREAM("Not found metainfo, buffer is" << bytes);
264  }
265 }
266 
267 
268 void ReqUnityInterface::parseFromSongProperty(TTK::MusicSongInformation *info, const QString &type, const QString &id, int bitrate)
269 {
270  QByteArray bytes;
271  QFile file(APPCACHE_DIR_FULL + QUERY_PLUGINS_URL);
272  if(file.open(QIODevice::ReadOnly))
273  {
274  TTK_INFO_STREAM("Load server unity plugins using local resource config");
275  bytes = file.readAll();
276  file.close();
277  }
278  else
279  {
280  TTK_ERROR_STREAM("Load server unity plugins resource config failed");
281  return;
282  }
283 
284  bool found = false;
285  QJsonParseError ok;
286  const QJsonDocument &json = QJsonDocument::fromJson(bytes, &ok);
288  {
289  const QVariantList &datas = json.toVariant().toList();
290  for(const QVariant &var : qAsConst(datas))
291  {
292  if(var.isNull())
293  {
294  continue;
295  }
296 
297  const QVariantMap &value = var.toMap();
298  const bool option = value["option"].toBool();
299 
300  if(!option)
301  {
302  continue;
303  }
304 
305  for(const TTK::MusicSongProperty &prop : qAsConst(info->m_songProps))
306  {
307  if(prop.m_bitrate == bitrate)
308  {
309  continue;
310  }
311  }
312 
313  const QVariantMap &serverMap = value["server"].toMap();
314  const QVariantMap &qualityMap = value["quality"].toMap();
315  if(!serverMap.contains(type) || !qualityMap.contains(QString::number(bitrate)))
316  {
317  continue;
318  }
319 
320  Data v;
321  v.m_ua = value["ua"].toString();
322  v.m_quality = qualityMap[QString::number(bitrate)].toString();
323 
324  for(const QString &module : value.keys())
325  {
326  if(!checkModule(module))
327  {
328  continue;
329  }
330 
331  v.m_module = module;
332  break;
333  }
334 
335  QNetworkRequest request;
336  if(v.m_module != QUERY_MODULE_E)
337  {
338  v.m_url = TTK::Algorithm::mdII(value[v.m_module].toString(), false).arg(serverMap[type].toString(), id, v.m_quality);
339  }
340  else
341  {
342  if(!value.contains("body"))
343  {
344  continue;
345  }
346 
347  TTK::setContentTypeHeader(&request, "application/json");
348  v.m_url = TTK::Algorithm::mdII(value[v.m_module].toString(), false);
349  v.m_body = TTK::Algorithm::mdII(value["body"].toString(), false).arg(serverMap[type].toString(), id, v.m_quality);
350  }
351 
352  if(v.m_url.isEmpty())
353  {
354  continue;
355  }
356 
357  request.setUrl(v.m_url);
358  TTK::setSslConfiguration(&request);
359 
360  const QVariantMap &headerMap = value["headers"].toMap();
361  if(!headerMap.isEmpty())
362  {
363  for(const QString &header : headerMap.keys())
364  {
365  request.setRawHeader(header.toUtf8(), TTK::Algorithm::mdII(headerMap[header].toString(), false).toUtf8());
366  }
367  }
368 
369  found = true;
370  if(!v.m_ua.isEmpty())
371  {
372  request.setRawHeader("User-Agent", TTK::Algorithm::mdII(v.m_ua, false).toUtf8());
373  }
374 
375  if(v.m_module == QUERY_MODULE_X)
376  {
377  TTK_INFO_STREAM("Parse song in X module, url:" << v.m_url);
378  parseSongPropertyX(&request, info, bitrate);
379  }
380  else if(v.m_module == QUERY_MODULE_A)
381  {
382  TTK_INFO_STREAM("Parse song in A module, url:" << v.m_url);
383  parseSongPropertyA(&request, info, bitrate, v.m_quality);
384  }
385  else if(v.m_module == QUERY_MODULE_B)
386  {
387  TTK_INFO_STREAM("Parse song in B module, url:" << v.m_url);
388  parseSongPropertyB(&request, info, bitrate);
389  }
390  else if(v.m_module == QUERY_MODULE_C)
391  {
392  TTK_INFO_STREAM("Parse song in C module, url:" << v.m_url);
393  parseSongPropertyC(&request, info, bitrate, v.m_quality);
394  }
395  else if(v.m_module == QUERY_MODULE_D)
396  {
397  TTK_INFO_STREAM("Parse song in D module, url:" << v.m_url);
398  parseSongPropertyD(&request, info, bitrate);
399  }
400  else if(v.m_module == QUERY_MODULE_E)
401  {
402  TTK_INFO_STREAM("Parse song in E module, url:" << v.m_url << v.m_body);
403  parseSongPropertyE(&request, v.m_body, info, bitrate);
404  }
405  }
406  }
407 
408  if(!found)
409  {
410  TTK_INFO_STREAM("Not found available server unity plugins");
411  }
412 }
TTK_MODULE_EXPORT QByteArray syncNetworkQueryForPost(QNetworkRequest *request, const QByteArray &data)
static constexpr const char * QUERY_MODULE_E
TTK_MODULE_EXPORT void setSslConfiguration(QNetworkRequest *request, QSslSocket::PeerVerifyMode mode=QSslSocket::VerifyNone) noexcept
#define TTK_DEFAULT_STR
Definition: ttkglobal.h:276
QVariant toVariant() const
The class of the music song property.
Definition: musicobject.h:242
static QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error=0)
static constexpr const char * QUERY_PLUGINS_URL
static constexpr const char * QUERY_MODULE_X
static constexpr const char * QUERY_MODULE_B
static void parseSongPropertyC(QNetworkRequest *request, TTK::MusicSongInformation *info, int bitrate, const QString &quality)
MusicSongPropertyList m_songProps
Definition: musicobject.h:314
TTK_MODULE_EXPORT QString sizeByteToLabel(qint64 size)
static void parseSongPropertyX(QNetworkRequest *request, TTK::MusicSongInformation *info, int bitrate)
TTK_MODULE_EXPORT QByteArray syncNetworkQueryForGet(QNetworkRequest *request)
static bool checkModule(const QString &module)
#define MP3_FILE_SUFFIX
Definition: musicobject.h:58
static constexpr const char * QUERY_MODULE_C
ParseError error
#define APPCACHE_DIR_FULL
Definition: musicobject.h:140
#define qAsConst
Definition: ttkqtglobal.h:57
#define TTK_INFO_STREAM(msg)
Definition: ttklogger.h:74
bool isEmpty() const noexcept
Definition: musicobject.h:255
The class of the music meta.
TTK_MODULE_EXPORT void setContentTypeHeader(QNetworkRequest *request, const QByteArray &data={}) noexcept
static constexpr const char * QUERY_MODULE_A
#define TTK_BN_320
Definition: ttkglobal.h:431
static constexpr const char * QUERY_MODULE_D
TTK_MODULE_EXPORT QString toString(Record type) noexcept
static void parseSongPropertyA(QNetworkRequest *request, TTK::MusicSongInformation *info, int bitrate, const QString &quality)
static void parseSongPropertyE(QNetworkRequest *request, const QString &body, TTK::MusicSongInformation *info, int bitrate)
static void parseSongPropertyD(QNetworkRequest *request, TTK::MusicSongInformation *info, int bitrate)
static void parseSongPropertyB(QNetworkRequest *request, TTK::MusicSongInformation *info, int bitrate)
#define FLAC_FILE_SUFFIX
Definition: musicobject.h:60
void parseFromSongProperty(TTK::MusicSongInformation *info, const QString &type, const QString &id, int bitrate)
#define TTK_ERROR_STREAM(msg)
Definition: ttklogger.h:76
TTK_MODULE_EXPORT QString mdII(const QString &data, bool encode)
The class of the music song information.
Definition: musicobject.h:300