00001
00007 #include "iptvchannel.h"
00008
00009 #include <qdeepcopy.h>
00010
00011
00012 #include "mythcontext.h"
00013 #include "mythdbcon.h"
00014 #include "iptvchannelfetcher.h"
00015 #include "iptvfeederwrapper.h"
00016
00017 #define LOC QString("IPTVChan(%1): ").arg(GetCardID())
00018 #define LOC_ERR QString("IPTVChan(%1), Error: ").arg(GetCardID())
00019
00020 IPTVChannel::IPTVChannel(TVRec *parent,
00021 const QString &videodev)
00022 : DTVChannel(parent),
00023 m_videodev(QDeepCopy<QString>(videodev)),
00024 m_feeder(new IPTVFeederWrapper()),
00025 m_lock(true)
00026 {
00027 VERBOSE(VB_CHANNEL, LOC + "ctor");
00028 }
00029
00030 IPTVChannel::~IPTVChannel()
00031 {
00032 VERBOSE(VB_CHANNEL, LOC + "dtor -- begin");
00033 if (m_feeder)
00034 {
00035 delete m_feeder;
00036 m_feeder = NULL;
00037 }
00038 VERBOSE(VB_CHANNEL, LOC + "dtor -- end");
00039 }
00040
00041 bool IPTVChannel::Open(void)
00042 {
00043 VERBOSE(VB_CHANNEL, LOC + "Open() -- begin");
00044 QMutexLocker locker(&m_lock);
00045 VERBOSE(VB_CHANNEL, LOC + "Open() -- locked");
00046
00047 if (!InitializeInputs())
00048 {
00049 VERBOSE(VB_IMPORTANT, LOC_ERR + "InitializeInputs() failed");
00050 return false;
00051 }
00052
00053 if (m_freeboxchannels.empty())
00054 {
00055 QString content = IPTVChannelFetcher::DownloadPlaylist(
00056 m_videodev, true);
00057 m_freeboxchannels = IPTVChannelFetcher::ParsePlaylist(content);
00058 VERBOSE(VB_IMPORTANT, LOC + QString("Loaded %1 channels from %2")
00059 .arg(m_freeboxchannels.size())
00060 .arg(m_videodev));
00061 }
00062
00063 bool open = IsOpen();
00064 VERBOSE(VB_CHANNEL, LOC + "Open() -- end");
00065 return open;
00066 }
00067
00068 void IPTVChannel::Close(void)
00069 {
00070 VERBOSE(VB_CHANNEL, LOC + "Close() -- begin");
00071 QMutexLocker locker(&m_lock);
00072 VERBOSE(VB_CHANNEL, LOC + "Close() -- locked");
00073
00074 VERBOSE(VB_CHANNEL, LOC + "Close() -- end");
00075 }
00076
00077 bool IPTVChannel::IsOpen(void) const
00078 {
00079 VERBOSE(VB_CHANNEL, LOC + "IsOpen() -- begin");
00080 QMutexLocker locker(&m_lock);
00081 VERBOSE(VB_CHANNEL, LOC + "IsOpen() -- locked");
00082 bool open = m_freeboxchannels.size() > 0;
00083 VERBOSE(VB_CHANNEL, LOC + "IsOpen() -- end");
00084 return open;
00085 }
00086
00087 bool IPTVChannel::SetChannelByString(const QString &channum)
00088 {
00089 VERBOSE(VB_CHANNEL, LOC + "SetChannelByString() -- begin");
00090 QMutexLocker locker(&m_lock);
00091 VERBOSE(VB_CHANNEL, LOC + "SetChannelByString() -- locked");
00092
00093 InputMap::const_iterator it = inputs.find(currentInputID);
00094 if (it == inputs.end())
00095 return false;
00096
00097 uint mplexid_restriction;
00098 if (!IsInputAvailable(currentInputID, mplexid_restriction))
00099 return false;
00100
00101
00102 if (!GetChanInfo(channum).isValid())
00103 {
00104 VERBOSE(VB_IMPORTANT, LOC_ERR +
00105 QString("SetChannelByString(%1)").arg(channum) +
00106 " Invalid channel");
00107 return false;
00108 }
00109
00110 if (!(*it)->externalChanger.isEmpty() && !ChangeExternalChannel(channum))
00111 return false;
00112
00113
00114 curchannelname = QDeepCopy<QString>(channum);
00115
00116
00117 SetDTVInfo( 0, 0,
00118 0,
00119 0, 1);
00120
00121 VERBOSE(VB_CHANNEL, LOC + "SetChannelByString() -- end");
00122 return true;
00123 }
00124
00125 IPTVChannelInfo IPTVChannel::GetChanInfo(
00126 const QString &channum, uint sourceid) const
00127 {
00128 VERBOSE(VB_CHANNEL, LOC + "GetChanInfo() -- begin");
00129 QMutexLocker locker(&m_lock);
00130 VERBOSE(VB_CHANNEL, LOC + "GetChanInfo() -- locked");
00131
00132 IPTVChannelInfo dummy;
00133 QString msg = LOC_ERR + QString("GetChanInfo(%1) failed").arg(channum);
00134
00135 if (channum.isEmpty())
00136 {
00137 VERBOSE(VB_IMPORTANT, msg);
00138 return dummy;
00139 }
00140
00141 if (!sourceid)
00142 {
00143 InputMap::const_iterator it = inputs.find(currentInputID);
00144 if (it == inputs.end())
00145 {
00146 VERBOSE(VB_IMPORTANT, msg);
00147 return dummy;
00148 }
00149 sourceid = (*it)->sourceid;
00150 }
00151
00152 MSqlQuery query(MSqlQuery::InitCon());
00153 query.prepare(
00154 "SELECT freqid, name "
00155 "FROM channel "
00156 "WHERE channum = :CHANNUM AND "
00157 " sourceid = :SOURCEID");
00158
00159 query.bindValue(":CHANNUM", channum);
00160 query.bindValue(":SOURCEID", sourceid);
00161
00162 if (!query.exec() || !query.isActive())
00163 {
00164 MythContext::DBError("fetching chaninfo", query);
00165 VERBOSE(VB_IMPORTANT, msg);
00166 return dummy;
00167 }
00168
00169 while (query.next())
00170 {
00171
00172 const QString freqid = query.value(0).toString();
00173 fbox_chan_map_t::const_iterator it;
00174 if (!freqid.isEmpty())
00175 {
00176 it = m_freeboxchannels.find(freqid);
00177 if (it != m_freeboxchannels.end())
00178 return *it;
00179 }
00180
00181
00182 const QString name = QString::fromUtf8(query.value(1).toString());
00183 for (it = m_freeboxchannels.begin();
00184 it != m_freeboxchannels.end(); ++it)
00185 {
00186 if ((*it).m_name == name)
00187 return *it;
00188 }
00189 }
00190
00191 VERBOSE(VB_IMPORTANT, msg);
00192 return dummy;
00193 }
00194
00195