Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2025 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include "learnservice.h"
24 :
25 : #include <QJsonArray>
26 : #include <QJsonDocument>
27 : #include <QJsonObject>
28 : #include <QBuffer>
29 : #include <QLocale>
30 :
31 : #include "dataformatter.h"
32 : #include "learnerrors.h"
33 : #include "log.h"
34 :
35 : using namespace muse;
36 : using namespace muse::learn;
37 : using namespace muse::network;
38 :
39 0 : static Playlist parsePlaylist(const QJsonDocument& playlistDoc)
40 : {
41 0 : Playlist result;
42 :
43 0 : QJsonObject obj = playlistDoc.object();
44 0 : QString preferredPlaylistTag = QLocale().name();
45 0 : QJsonArray items = obj.value(preferredPlaylistTag).toArray();
46 0 : if (items.isEmpty()) {
47 0 : items = obj.value("default").toArray();
48 : }
49 :
50 0 : for (const QJsonValue itemVal : items) {
51 0 : QJsonObject itemObj = itemVal.toObject();
52 :
53 0 : PlaylistItem item;
54 0 : item.title = itemObj.value("title").toString();
55 0 : item.author = itemObj.value("author").toString();
56 0 : item.url = itemObj.value("url").toString();
57 0 : item.thumbnailUrl = itemObj.value("thumbnailUrl").toString();
58 0 : item.durationSecs = itemObj.value("durationSecs").toInt();
59 :
60 0 : result << item;
61 0 : }
62 :
63 0 : return result;
64 0 : }
65 :
66 0 : void LearnService::refreshPlaylists()
67 : {
68 0 : auto startedPlaylistCallBack = [this](const RetVal<Playlist>& result) {
69 0 : if (!result.ret) {
70 0 : LOGE() << "Unable to get started playlist: " << result.ret.toString();
71 0 : return;
72 : }
73 :
74 0 : if (m_startedPlaylist == result.val) {
75 0 : return;
76 : }
77 :
78 0 : m_startedPlaylist = result.val;
79 0 : m_startedPlaylistChannel.send(m_startedPlaylist);
80 0 : };
81 :
82 0 : auto advancedPlaylistCallBack = [this](const RetVal<Playlist>& result) {
83 0 : if (!result.ret) {
84 0 : LOGE() << "Unable to get advanced playlist: " << result.ret.toString();
85 0 : return;
86 : }
87 :
88 0 : if (m_advancedPlaylist == result.val) {
89 0 : return;
90 : }
91 :
92 0 : m_advancedPlaylist = result.val;
93 0 : m_advancedPlaylistChannel.send(m_advancedPlaylist);
94 0 : };
95 :
96 0 : downloadPlaylist(configuration()->startedPlaylistUrl(), startedPlaylistCallBack);
97 0 : downloadPlaylist(configuration()->advancedPlaylistUrl(), advancedPlaylistCallBack);
98 0 : }
99 :
100 0 : Playlist LearnService::startedPlaylist() const
101 : {
102 0 : return m_startedPlaylist;
103 : }
104 :
105 0 : async::Channel<Playlist> LearnService::startedPlaylistChanged() const
106 : {
107 0 : return m_startedPlaylistChannel;
108 : }
109 :
110 0 : Playlist LearnService::advancedPlaylist() const
111 : {
112 0 : return m_advancedPlaylist;
113 : }
114 :
115 0 : async::Channel<Playlist> LearnService::advancedPlaylistChanged() const
116 : {
117 0 : return m_advancedPlaylistChannel;
118 : }
119 :
120 0 : void LearnService::downloadPlaylist(const QUrl& playlistUrl, std::function<void(RetVal<Playlist>)> callBack)
121 : {
122 0 : TRACEFUNC;
123 :
124 0 : if (!m_networkManager) {
125 0 : m_networkManager = networkManagerCreator()->makeNetworkManager();
126 : }
127 :
128 0 : RequestHeaders headers = configuration()->headers();
129 0 : auto playlistInfoData = std::make_shared<QBuffer>();
130 :
131 0 : RetVal<Progress> progress = m_networkManager->get(playlistUrl, playlistInfoData, headers);
132 0 : if (!progress.ret) {
133 0 : callBack(progress.ret);
134 0 : return;
135 : }
136 :
137 0 : progress.val.finished().onReceive(this, [callBack, playlistInfoData](const muse::ProgressResult& res) {
138 0 : if (!res.ret) {
139 0 : callBack(res.ret);
140 0 : return;
141 : }
142 :
143 0 : QJsonDocument playlistInfoDoc = QJsonDocument::fromJson(playlistInfoData->data());
144 :
145 0 : RetVal<Playlist> result;
146 0 : result.ret = make_ret(Ret::Code::Ok);
147 0 : result.val = parsePlaylist(playlistInfoDoc);
148 :
149 0 : callBack(result);
150 0 : });
151 0 : }
|