TTKMusicPlayer  4.2.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_PLUGINS_URL = "resource/plugins";
4 static constexpr const char *QUERY_MODULE_A = "A";
5 static constexpr const char *QUERY_MODULE_B = "B";
6 
8 {
9  QString m_ua;
10  QString m_url;
11  QString m_key;
12  QString m_quality;
13  int m_bitrate;
14 };
15 
16 static QString makeQualityValue(const QString &type, int bitrate) noexcept
17 {
18  if(type == QUERY_MODULE_A)
19  {
20  switch(bitrate)
21  {
22  case TTK_BN_128: return "128k";
23  case TTK_BN_320: return "320k";
24  case TTK_BN_1000: return "flac";
25  default: return {};
26  }
27  }
28  else if(type == QUERY_MODULE_B)
29  {
30  switch(bitrate)
31  {
32  case TTK_BN_128: return "128";
33  case TTK_BN_320: return "320";
34  case TTK_BN_1000: return "999";
35  default: return {};
36  }
37  }
38  return {};
39 }
40 
41 static QString makeModuleValue(const QString &type, const QString &module) noexcept
42 {
43  if(type == QUERY_MODULE_A)
44  {
45  if(module == QUERY_WY_INTERFACE) return "wy";
46  else if(module == QUERY_KG_INTERFACE) return "kg";
47  else if(module == QUERY_KW_INTERFACE) return "kw";
48  else return {};
49  }
50  else if(type == QUERY_MODULE_B)
51  {
52  if(module == QUERY_WY_INTERFACE) return "wangyi";
53  else if(module == QUERY_KG_INTERFACE) return "kugou";
54  else if(module == QUERY_KW_INTERFACE) return "kuwo";
55  else return {};
56  }
57  return {};
58 }
59 
61 {
62  for(const TTK::MusicSongProperty &prop : qAsConst(info->m_songProps))
63  {
64  if(prop.m_bitrate == module.m_bitrate)
65  {
66  return;
67  }
68  }
69 
70  TTK_INFO_STREAM("Parse song in A module, url:" << module.m_url);
71 
72  QNetworkRequest request;
73  if(!module.m_ua.isEmpty())
74  {
75  request.setRawHeader("User-Agent", TTK::Algorithm::mdII(module.m_ua, false).toUtf8());
76  }
77  request.setRawHeader("X-Request-Key", TTK::Algorithm::mdII(module.m_key, false).toUtf8());
78  request.setUrl(module.m_url);
79  TTK::setSslConfiguration(&request);
80 
81  const QByteArray &bytes = TTK::syncNetworkQueryForGet(&request);
82  if(bytes.isEmpty())
83  {
84  return;
85  }
86 
87  QJsonParseError ok;
88  const QJsonDocument &json = QJsonDocument::fromJson(bytes, &ok);
90  {
91  QVariantMap value = json.toVariant().toMap();
92  if(value["code"].toInt() == 0 || value["code"].toInt() == 200)
93  {
95  prop.m_url = value["data"].toString();
96  prop.m_size = TTK_DEFAULT_STR;
98  prop.m_bitrate = module.m_bitrate;
99 
100  if(prop.isEmpty())
101  {
102  prop.m_url = value["url"].toString();
103  }
104 
105  if(prop.isEmpty())
106  {
107  return;
108  }
109 
110  const QVariantMap &extra = value["extra"].toMap();
111  if(!extra.isEmpty())
112  {
113  value = extra;
114  }
115 
116  value = value["quality"].toMap();
117  if(value.isEmpty())
118  {
119  return;
120  }
121 
122  if(value["target"].toString().contains(module.m_quality, Qt::CaseInsensitive) &&
123  value["result"].toString().contains(module.m_quality, Qt::CaseInsensitive))
124  {
125  info->m_songProps.append(prop);
126  }
127  }
128  }
129 }
130 
132 {
133  for(const TTK::MusicSongProperty &prop : qAsConst(info->m_songProps))
134  {
135  if(prop.m_bitrate == module.m_bitrate)
136  {
137  return;
138  }
139  }
140 
141  TTK_INFO_STREAM("Parse song in B module, url:" << module.m_url);
142 
143  QNetworkRequest request;
144  if(!module.m_ua.isEmpty())
145  {
146  request.setRawHeader("User-Agent", TTK::Algorithm::mdII(module.m_ua, false).toUtf8());
147  }
148  request.setUrl(module.m_url);
149  TTK::setSslConfiguration(&request);
150 
151  const QByteArray &bytes = TTK::syncNetworkQueryForGet(&request);
152  if(bytes.isEmpty())
153  {
154  return;
155  }
156 
157  QJsonParseError ok;
158  const QJsonDocument &json = QJsonDocument::fromJson(bytes, &ok);
160  {
161  QVariantMap value = json.toVariant().toMap();
162  if(value.contains("url"))
163  {
165  prop.m_url = value["url"].toString();
166  prop.m_size = TTK_DEFAULT_STR;
168  prop.m_bitrate = module.m_bitrate;
169 
170  if(!prop.isEmpty())
171  {
172  info->m_songProps.append(prop);
173  }
174  }
175  }
176 }
177 
178 
179 void ReqUnityInterface::parseFromSongProperty(TTK::MusicSongInformation *info, const QString &type, const QString &id, int bitrate)
180 {
181  QByteArray bytes;
182  QFile file(APPCACHE_DIR_FULL + QUERY_PLUGINS_URL);
183  if(file.open(QIODevice::ReadOnly))
184  {
185  TTK_INFO_STREAM("Load server unity plugins using local resource config");
186  bytes = file.readAll();
187  file.close();
188  }
189  else
190  {
191  TTK_ERROR_STREAM("Load server unity plugins resource config failed");
192  return;
193  }
194 
195  QJsonParseError ok;
196  const QJsonDocument &json = QJsonDocument::fromJson(bytes, &ok);
198  {
199  const QVariantList &datas = json.toVariant().toList();
200  for(const QVariant &var : qAsConst(datas))
201  {
202  if(var.isNull())
203  {
204  continue;
205  }
206 
207  const QVariantMap &value = var.toMap();
208  const bool option = value["option"].toBool();
209 
210  if(!option)
211  {
212  continue;
213  }
214 
215  const QString &ua = value["ua"].toString();
216  const QString &key = value["key"].toString();
217 
218  for(const QString &module : value.keys())
219  {
220  ServerModule v;
221  v.m_url = value[module].toString();
222  if(v.m_url.isEmpty())
223  {
224  continue;
225  }
226 
227  const QString &server = makeModuleValue(module, type);
228  const QString &quality = makeQualityValue(module, bitrate);
229  if(server.isEmpty() || quality.isEmpty())
230  {
231  continue;
232  }
233 
234  v.m_ua = ua;
235  v.m_key = key;
236  v.m_quality = quality;
237  v.m_bitrate = bitrate;
238  v.m_url = TTK::Algorithm::mdII(v.m_url, false).arg(server, id, quality);
239 
240  if(module == QUERY_MODULE_A)
241  {
242  parseSongPropertyA(info, v);
243  }
244  else if(module == QUERY_MODULE_B)
245  {
246  parseSongPropertyB(info, v);
247  }
248  }
249  }
250  }
251 }
static QString makeQualityValue(const QString &type, int bitrate) noexcept
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:237
static QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error=0)
static constexpr const char * QUERY_PLUGINS_URL
static constexpr const char * QUERY_KG_INTERFACE
static constexpr const char * QUERY_MODULE_B
static QString makeModuleValue(const QString &type, const QString &module) noexcept
MusicSongPropertyList m_songProps
Definition: musicobject.h:309
TTK_MODULE_EXPORT QByteArray syncNetworkQueryForGet(QNetworkRequest *request)
#define TTK_BN_1000
Definition: ttkglobal.h:434
#define MP3_FILE_SUFFIX
Definition: musicobject.h:57
ParseError error
#define APPCACHE_DIR_FULL
Definition: musicobject.h:135
#define qAsConst
Definition: ttkqtglobal.h:57
static constexpr const char * QUERY_WY_INTERFACE
#define TTK_INFO_STREAM(msg)
Definition: ttklogger.h:74
static constexpr wchar_t key[]
bool isEmpty() const noexcept
Definition: musicobject.h:250
static constexpr const char * QUERY_MODULE_A
#define TTK_BN_320
Definition: ttkglobal.h:431
static constexpr const char * QUERY_KW_INTERFACE
static void parseSongPropertyB(TTK::MusicSongInformation *info, const ServerModule &module)
TTK_MODULE_EXPORT QString toString(Record type) noexcept
#define FLAC_FILE_SUFFIX
Definition: musicobject.h:59
void parseFromSongProperty(TTK::MusicSongInformation *info, const QString &type, const QString &id, int bitrate)
#define TTK_ERROR_STREAM(msg)
Definition: ttklogger.h:76
static void parseSongPropertyA(TTK::MusicSongInformation *info, const ServerModule &module)
TTK_MODULE_EXPORT QString mdII(const QString &data, bool encode)
The class of the music song information.
Definition: musicobject.h:295
#define TTK_BN_128
Definition: ttkglobal.h:428