MythTV
master
libs
libmythtv
mheg
mhegic.cpp
Go to the documentation of this file.
1
/* MHEG Interaction Channel
2
* Copyright 2011 Lawrence Rust <lvr at softsystem dot co dot uk>
3
*/
4
#include "
mhegic.h
"
5
6
#if QT_VERSION < QT_VERSION_CHECK(5,10,0)
7
// C/C++ lib
8
#include <cstdlib>
9
using
std::getenv;
10
#endif
11
12
// Qt
13
#include <QByteArray>
14
#include <QMutexLocker>
15
#include <QNetworkRequest>
16
#include <QStringList>
17
#include <QScopedPointer>
18
#include <QApplication>
19
20
// Myth
21
#include "
netstream.h
"
22
#include "
mythlogging.h
"
23
#include "
mythcorecontext.h
"
24
25
#define LOC QString("[mhegic] ")
26
27
28
MHInteractionChannel::MHInteractionChannel
(QObject* parent) : QObject(parent)
29
{
30
setObjectName(
"MHInteractionChannel"
);
31
moveToThread(&
NAMThread::manager
());
32
}
33
34
// virtual
35
MHInteractionChannel::~MHInteractionChannel
()
36
{
37
QMutexLocker locker(&
m_mutex
);
38
for
(
const
auto
& req : qAsConst(
m_pending
))
39
req->deleteLater();
40
for
(
const
auto
& req : qAsConst(
m_finished
))
41
req->deleteLater();
42
}
43
44
// Get network status
45
// static
46
MHInteractionChannel::EStatus
MHInteractionChannel::status
()
47
{
48
if
(!
NetStream::isAvailable
())
49
{
50
LOG
(VB_MHEG, LOG_INFO,
LOC
+
"WARN network is unavailable"
);
51
return
kInactive
;
52
}
53
54
if
(!
gCoreContext
->
GetBoolSetting
(
"EnableMHEG"
,
false
))
55
return
kDisabled
;
56
57
#if QT_VERSION < QT_VERSION_CHECK(5,10,0)
58
QStringList
opts
= QString(getenv(
"MYTHMHEG"
)).split(
':'
);
59
#else
60
QStringList
opts
= qEnvironmentVariable(
"MYTHMHEG"
).split(
':'
);
61
#endif
62
if
(
opts
.contains(
"noice"
, Qt::CaseInsensitive))
63
return
kDisabled
;
64
if
(
opts
.contains(
"ice"
, Qt::CaseInsensitive))
65
return
kActive
;
66
return
gCoreContext
->
GetBoolSetting
(
"EnableMHEGic"
,
true
) ?
kActive
:
kDisabled
;
67
}
68
69
static
inline
bool
isCached
(
const
QUrl& url)
70
{
71
return
NetStream::GetLastModified
(url).isValid();
72
}
73
74
// Is a file ready to read?
75
bool
MHInteractionChannel::CheckFile
(
const
QString& csPath,
const
QByteArray &cert)
76
{
77
QUrl url(csPath);
78
QMutexLocker locker(&
m_mutex
);
79
80
// Is it complete?
81
if
(
m_finished
.contains(url))
82
return
true
;
83
84
// Is it pending?
85
if
(
m_pending
.contains(url))
86
return
false
;
// It's pending so unavailable
87
88
// Is it in the cache?
89
if
(
isCached
(url))
90
return
true
;
// It's cached
91
92
// Queue a request
93
LOG
(VB_MHEG, LOG_DEBUG,
LOC
+ QString(
"CheckFile queue %1"
).
arg
(csPath));
94
QScopedPointer< NetStream >
p
(
new
NetStream
(url,
NetStream::kPreferCache
, cert));
95
if
(!
p
|| !
p
->IsOpen())
96
{
97
LOG
(VB_MHEG, LOG_WARNING,
LOC
+ QString(
"CheckFile failed %1"
).
arg
(csPath) );
98
return
false
;
99
}
100
101
connect(
p
.data(), &
NetStream::Finished
,
this
, &
MHInteractionChannel::slotFinished
);
102
m_pending
.insert(url,
p
.take());
103
104
return
false
;
// It's now pending so unavailable
105
}
106
107
// Read a file. -1= error, 0= OK, 1= not ready
108
MHInteractionChannel::EResult
109
MHInteractionChannel::GetFile
(
const
QString &csPath, QByteArray &data,
110
const
QByteArray &cert
/*=QByteArray()*/
)
111
{
112
QUrl url(csPath);
113
QMutexLocker locker(&
m_mutex
);
114
115
// Is it pending?
116
if
(
m_pending
.contains(url))
117
return
kPending
;
118
119
// Is it complete?
120
QScopedPointer< NetStream >
p
(
m_finished
.take(url));
121
if
(
p
)
122
{
123
if
(
p
->GetError() == QNetworkReply::NoError)
124
{
125
data =
p
->ReadAll();
126
LOG
(VB_MHEG, LOG_DEBUG,
LOC
+ QString(
"GetFile finished %1"
).
arg
(csPath) );
127
return
kSuccess
;
128
}
129
130
LOG
(VB_MHEG, LOG_WARNING,
LOC
+ QString(
"GetFile failed %1"
).
arg
(csPath) );
131
return
kError
;
132
}
133
134
// Is it in the cache?
135
if
(
isCached
(url))
136
{
137
LOG
(VB_MHEG, LOG_DEBUG,
LOC
+ QString(
"GetFile cache read %1"
).
arg
(csPath) );
138
139
locker.unlock();
140
141
NetStream
req(url,
NetStream::kAlwaysCache
);
142
if
(req.
WaitTillFinished
(3s) && req.
GetError
() == QNetworkReply::NoError)
143
{
144
data = req.
ReadAll
();
145
LOG
(VB_MHEG, LOG_DEBUG,
LOC
+ QString(
"GetFile cache read %1 bytes %2"
)
146
.
arg
(data.size()).arg(csPath) );
147
return
kSuccess
;
148
}
149
150
LOG
(VB_MHEG, LOG_WARNING,
LOC
+ QString(
"GetFile cache read failed %1"
).
arg
(csPath) );
151
//return kError;
152
// Retry
153
locker.relock();
154
}
155
156
// Queue a download
157
LOG
(VB_MHEG, LOG_DEBUG,
LOC
+ QString(
"GetFile queue %1"
).
arg
(csPath) );
158
p
.reset(
new
NetStream
(url,
NetStream::kPreferCache
, cert));
159
if
(!
p
|| !
p
->IsOpen())
160
{
161
LOG
(VB_MHEG, LOG_WARNING,
LOC
+ QString(
"GetFile failed %1"
).
arg
(csPath) );
162
return
kError
;
163
}
164
165
connect(
p
.data(), &
NetStream::Finished
,
this
, &
MHInteractionChannel::slotFinished
);
166
m_pending
.insert(url,
p
.take());
167
168
return
kPending
;
169
}
170
171
// signal from NetStream
172
void
MHInteractionChannel::slotFinished
(QObject *obj)
173
{
174
auto
*
p
= qobject_cast< NetStream* >(obj);
175
if
(!
p
)
176
return
;
177
178
QUrl url =
p
->Url();
179
180
if
(
p
->GetError() == QNetworkReply::NoError)
181
{
182
LOG
(VB_MHEG, LOG_DEBUG,
LOC
+ QString(
"Finished %1"
).
arg
(url.toString()) );
183
}
184
else
185
{
186
LOG
(VB_MHEG, LOG_WARNING,
LOC
+ QString(
"Finished %1"
).
arg
(
p
->GetErrorString()) );
187
}
188
189
p
->disconnect();
190
191
QMutexLocker locker(&
m_mutex
);
192
193
if
(
m_pending
.remove(url) < 1)
194
LOG
(VB_GENERAL, LOG_WARNING,
LOC
+ QString(
"Finished %1 wasn't pending"
).
arg
(url.toString()) );
195
m_finished
.insert(url,
p
);
196
}
197
198
/* End of file */
LOC
#define LOC
Definition:
mhegic.cpp:25
NetStream::ReadAll
QByteArray ReadAll()
Definition:
netstream.cpp:684
MHInteractionChannel::slotFinished
void slotFinished(QObject *obj)
Definition:
mhegic.cpp:172
isCached
static bool isCached(const QUrl &url)
Definition:
mhegic.cpp:69
MHInteractionChannel::status
static EStatus status()
Definition:
mhegic.cpp:46
MHInteractionChannel::~MHInteractionChannel
~MHInteractionChannel() override
Definition:
mhegic.cpp:35
MHInteractionChannel::kError
@ kError
Definition:
mhegic.h:35
NetStream::GetLastModified
static QDateTime GetLastModified(const QUrl &url)
Definition:
netstream.cpp:728
hardwareprofile.getLink.opts
opts
Definition:
getLink.py:65
MHInteractionChannel::GetFile
EResult GetFile(const QString &csPath, QByteArray &data, const QByteArray &cert=QByteArray())
Definition:
mhegic.cpp:109
MHInteractionChannel::EResult
EResult
Definition:
mhegic.h:35
arg
arg(title).arg(filename).arg(doDelete))
MHInteractionChannel::m_mutex
QMutex m_mutex
Definition:
mhegic.h:46
MHInteractionChannel::m_finished
map_t m_finished
Definition:
mhegic.h:49
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition:
mythlogging.h:23
NetStream::WaitTillFinished
bool WaitTillFinished(std::chrono::milliseconds timeout)
Definition:
netstream.cpp:649
MHInteractionChannel::kSuccess
@ kSuccess
Definition:
mhegic.h:35
MHInteractionChannel::kPending
@ kPending
Definition:
mhegic.h:35
netstream.h
mythlogging.h
MHInteractionChannel::EStatus
EStatus
Definition:
mhegic.h:27
hardwareprofile.config.p
p
Definition:
config.py:33
MHInteractionChannel::m_pending
map_t m_pending
Definition:
mhegic.h:48
NetStream::Finished
void Finished(QObject *)
MHInteractionChannel::kDisabled
@ kDisabled
Definition:
mhegic.h:27
NetStream
Stream content from a URI.
Definition:
netstream.h:30
MHInteractionChannel::CheckFile
bool CheckFile(const QString &csPath, const QByteArray &cert=QByteArray())
Definition:
mhegic.cpp:75
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition:
mythcorecontext.cpp:60
NetStream::GetError
QNetworkReply::NetworkError GetError() const
Definition:
netstream.cpp:666
MythCoreContext::GetBoolSetting
bool GetBoolSetting(const QString &key, bool defaultval=false)
Definition:
mythcorecontext.cpp:926
NetStream::isAvailable
static bool isAvailable()
Public helpers.
Definition:
netstream.cpp:721
mhegic.h
mythcorecontext.h
MHInteractionChannel::MHInteractionChannel
MHInteractionChannel(QObject *parent=nullptr)
Definition:
mhegic.cpp:28
NetStream::kPreferCache
@ kPreferCache
Definition:
netstream.h:35
MHInteractionChannel::kActive
@ kActive
Definition:
mhegic.h:27
NAMThread::manager
static NAMThread & manager()
NetworkAccessManager event loop thread.
Definition:
netstream.cpp:738
MHInteractionChannel::kInactive
@ kInactive
Definition:
mhegic.h:27
NetStream::kAlwaysCache
@ kAlwaysCache
Definition:
netstream.h:35
Generated on Wed Jan 27 2021 03:16:51 for MythTV by
1.8.17