1 /*
2 * Copyright © 2015-2016 Antti Lamminsalo
3 *
4 * This file is part of Orion.
5 *
6 * Orion is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with Orion. If not, see <http://www.gnu.org/licenses/>.
13 */
14
15 #include "vodmanager.h"
16 #include <QSettings>
17 #include <QCoreApplication>
18 #include <cmath>
19
VodManager(QObject * parent)20 VodManager::VodManager(QObject *parent) :
21 QObject(parent),
22 netman(NetworkManager::getInstance())
23 {
24 qmlRegisterInterface<VodListModel>("VodListModel");
25 _model = new VodListModel(this);
26
27 connect(netman, &NetworkManager::broadcastsOperationFinished, this, &VodManager::onSearchFinished);
28 connect(netman, &NetworkManager::m3u8OperationBFinished, this, &VodManager::streamsGetFinished);
29 connect(netman, &NetworkManager::vodChatPieceGetOperationFinished, this, &VodManager::vodChatPieceGetOperationFinished);
30
31 QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName());
32 int numLastPositions = settings.beginReadArray("lastPositions");
33 for (int i = 0; i < numLastPositions; i++) {
34 settings.setArrayIndex(i);
35 const QString channel = settings.value("channel").toString();
36 const QString vod = settings.value("vod").toString();
37 const quint64 lastPosition = settings.value("position").toULongLong();
38
39 vodLastPlaybackPositionLoaded(channel, vod, lastPosition, i);
40 }
41 settings.endArray();
42
43 emit modelChanged();
44 }
45
getInstance()46 VodManager *VodManager::getInstance() {
47 static VodManager *instance = new VodManager();
48 return instance;
49 }
50
~VodManager()51 VodManager::~VodManager()
52 {
53 saveSettings();
54 delete _model;
55 }
56
search(const quint64 channelId,const quint32 offset,const quint32 limit)57 void VodManager::search(const quint64 channelId, const quint32 offset, const quint32 limit)
58 {
59 if (offset == 0) {
60 _model->clear();
61 emit searchStarted();
62 }
63
64 netman->getBroadcasts(channelId, offset, limit);
65 }
66
onSearchFinished(QList<Vod * > items)67 void VodManager::onSearchFinished(QList<Vod *> items)
68 {
69 _model->addAll(items);
70
71 qDeleteAll(items);
72 items.clear();
73
74 emit searchFinished();
75 }
76
getModel() const77 VodListModel *VodManager::getModel() const
78 {
79 return _model;
80 }
81
saveSettings()82 void VodManager::saveSettings() {
83 //Save
84 QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName());
85
86 //Write last positions
87 int nextLastPositionEntry = settings.beginReadArray("lastPositions");
88 settings.endArray();
89
90 settings.beginWriteArray("lastPositions");
91 for (auto channelEntry = channelVodLastPositions.begin(); channelEntry != channelVodLastPositions.end(); channelEntry++) {
92 auto & vods = channelEntry.value();
93 for (auto vodEntry = vods.begin(); vodEntry != vods.end(); vodEntry++) {
94 auto & lastPosition = vodEntry.value();
95 if (lastPosition.modified) {
96 if (lastPosition.settingsIndex == -1) {
97 lastPosition.settingsIndex = nextLastPositionEntry++;
98 }
99
100 settings.setArrayIndex(lastPosition.settingsIndex);
101 settings.setValue("channel", channelEntry.key());
102 settings.setValue("vod", vodEntry.key());
103 settings.setValue("position", vodEntry.value().lastPosition);
104 }
105 }
106 }
107 settings.endArray();
108
109 }
110
getGame() const111 QString VodManager::getGame() const
112 {
113 return game;
114 }
115
getBroadcasts(QString vod)116 void VodManager::getBroadcasts(QString vod)
117 {
118 //Remove leading NaN characters
119 vod.remove(QRegExp("[^0-9]"));
120
121 netman->getBroadcastPlaybackStream(vod);
122 }
123
getVodChatPiece(quint64 vodId,quint64 offset)124 void VodManager::getVodChatPiece(quint64 vodId, quint64 offset) {
125 netman->getVodChatPiece(vodId, offset);
126 }
127
getNextVodChatPiece(quint64 vodId,QString cursor)128 void VodManager::getNextVodChatPiece(quint64 vodId, QString cursor) {
129 netman->getNextVodChatPiece(vodId, cursor);
130 }
131
cancelLastVodChatRequest()132 void VodManager::cancelLastVodChatRequest() {
133 netman->cancelLastVodChatRequest();
134 }
135
resetVodChat()136 void VodManager::resetVodChat() {
137 netman->resetVodChat();
138 }
139
setVodLastPlaybackPosition(const QString & channel,const QString & vod,quint64 position)140 void VodManager::setVodLastPlaybackPosition(const QString & channel, const QString & vod, quint64 position) {
141 auto channelEntry = channelVodLastPositions.find(channel);
142 if (channelEntry == channelVodLastPositions.end()) {
143 channelEntry = channelVodLastPositions.insert(channel, QMap<QString, LastPosition>());
144 }
145
146 auto & vodMap = channelEntry.value();
147 auto vodEntry = vodMap.find(vod);
148 if (vodEntry != vodMap.end()) {
149 vodEntry.value().lastPosition = position;
150 vodEntry.value().modified = true;
151 if (std::fabs(static_cast<double>(vodEntry.value().lastPosition) - static_cast<double>(position)) >= 10) {
152 saveSettings();
153 }
154 } else {
155 // -1 index to be replaced at settings save time
156 vodMap.insert(vod, {position, true, -1});
157 saveSettings();
158 }
159
160 emit vodLastPositionUpdated(channel, vod, position);
161 }
162
vodLastPlaybackPositionLoaded(const QString & channel,const QString & vod,quint64 position,int settingsIndex)163 void VodManager::vodLastPlaybackPositionLoaded(const QString & channel, const QString & vod, quint64 position, int settingsIndex) {
164 auto channelEntry = channelVodLastPositions.find(channel);
165 if (channelEntry == channelVodLastPositions.end()) {
166 channelEntry = channelVodLastPositions.insert(channel, QMap<QString, LastPosition>());
167 }
168
169 auto & vodMap = channelEntry.value();
170 vodMap.remove(vod);
171 vodMap.insert(vod, {position, false, settingsIndex});
172 }
173
getVodLastPlaybackPosition(const QString & channel,const QString & vod)174 QVariant VodManager::getVodLastPlaybackPosition(const QString & channel, const QString & vod) {
175 auto channelEntry = channelVodLastPositions.find(channel);
176 if (channelEntry == channelVodLastPositions.end()) {
177 return QVariant();
178 }
179
180 auto & vodMap = channelEntry.value();
181 auto vodEntry = vodMap.find(vod);
182 if (vodEntry == vodMap.end()) {
183 return QVariant();
184 }
185
186 return vodEntry.value().lastPosition;
187 }
188
getChannelVodsLastPlaybackPositions(const QString & channel)189 QVariantMap VodManager::getChannelVodsLastPlaybackPositions(const QString & channel) {
190 QVariantMap out;
191 auto channelEntry = channelVodLastPositions.find(channel);
192 if (channelEntry != channelVodLastPositions.end()) {
193 auto & vodMap = channelEntry.value();
194 for (auto vodEntry = vodMap.constBegin(); vodEntry != vodMap.constEnd(); vodEntry++) {
195 out.insert(vodEntry.key(), vodEntry.value().lastPosition);
196 }
197 }
198 return out;
199 }
200