#include #include "../maintenance.h" #include #include #include #include #include #include #include #include class SiNetworkInformationMerger : public SiNetworkInformationParser { public: SiNetworkInformationMerger(DatabaseClient * co) : commonObjects(co) { } bool HandleTable(DVBSI::NetworkPtr n) { Logger()->messagebf(LOG_DEBUG, "Network Id: %d Name: %s", n->NetworkId, *n->Name); for (const auto & ts : n->TransportStreams) { Logger()->messagebf(LOG_DEBUG, "\tTransport Stream Id: %d Original Network Id: %d", ts->TransportStreamId, ts->OriginalNetworkId); for (const auto & s : ts->Services) { Logger()->messagebf(LOG_DEBUG, "\t\tService Id: %d Service Type: %d", s.ServiceId, s.ServiceType); } if (ts->Terrestrial) { Logger()->messagebf(LOG_DEBUG, "\t\tDVB-T: Frequency: %d", ts->Terrestrial->Frequency); } } DatabaseClient::TxHelper tx(commonObjects); SqlMergeTask mergeNetwork("postgres", "networks"); CreateColumns(boost::bind(&DatabaseClient::SqlMergeColumnsInserter, &mergeNetwork, _1, _2)); std::vector networks = { n }; mergeNetwork.sources.insert(new ContainerIterator>(&networks)); mergeNetwork.loadComplete(commonObjects); mergeNetwork.execute(NULL); SqlMergeTask mergeTransports("postgres", "transportstreams"); CreateColumns(boost::bind(&DatabaseClient::SqlMergeColumnsInserter, &mergeTransports, _1, _2)); mergeTransports.sources.insert(new ContainerIterator(&n->TransportStreams)); mergeTransports.loadComplete(commonObjects); mergeTransports.execute(NULL); SqlMergeTask mergeDvbt("postgres", "delivery_dvbt"); CreateColumns(boost::bind(&DatabaseClient::SqlMergeColumnsInserter, &mergeDvbt, _1, _2)); for (const auto & s : n->TransportStreams) { if (s->Terrestrial) { mergeDvbt.sources.insert(new SingleIterator(&s->Terrestrial)); } } mergeDvbt.loadComplete(commonObjects); mergeDvbt.execute(NULL); SqlMergeTask mergeServices("postgres", "services"); CreateColumns(boost::bind(&DatabaseClient::SqlMergeColumnsInserter, &mergeServices, _1, _2)); for (const auto & s : n->TransportStreams) { mergeServices.sources.insert(new ContainerIterator(&s->Services)); } mergeServices.loadComplete(commonObjects); mergeServices.execute(NULL); return false; } private: DatabaseClient * commonObjects; }; void Maintenance::UpdateNetwork(short type, const Ice::Current & ice) { auto ic = ice.adapter->getCommunicator(); auto devs = P2PVR::DevicesPrx::checkedCast(ice.adapter->createProxy(ic->stringToIdentity("GlobalDevices"))); auto si = P2PVR::SIPrx::checkedCast(ice.adapter->createProxy(ic->stringToIdentity("SI"))); auto siparser = new SiNetworkInformationMerger(this); TemporarayIceAdapterObject parser(ice.adapter, siparser); if (!devs) { throw std::runtime_error("bad proxy(s)"); } auto transport = si->GetDeliveryForSi(); if (transport) { P2PVR::TunerPrx tuner; try { tuner = devs->GetTunerAny(type, transport); tuner->SendNetworkInformation(parser); devs->ReleaseTuner(tuner); return; } catch (const P2PVR::NoSuitableDeviceAvailable &) { Logger()->messagebf(LOG_WARNING, "%s: Failed to get a suitable tuner", __PRETTY_FUNCTION__); throw; } catch (const std::exception & ex) { Logger()->messagebf(LOG_WARNING, "%s: Failed to fetch network information: %s", __PRETTY_FUNCTION__, ex.what()); devs->ReleaseTuner(tuner); throw; } catch (...) { Logger()->messagebf(LOG_WARNING, "%s: Failed to fetch network information", __PRETTY_FUNCTION__); devs->ReleaseTuner(tuner); throw; } } // If we can't do that, do a complete scan auto tuner = devs->GetPrivateTuner(type); tuner->ScanAndSendNetworkInformation(parser); devs->ReleaseTuner(tuner); }