From f724c5934c63c64a0085c3dbe4cd3c3fc58f1318 Mon Sep 17 00:00:00 2001 From: Julian Scheel Date: Tue, 2 Feb 2016 11:04:45 +0100 Subject: [PATCH] OctonetData: Implement channel list parsing Retrieve json formatted channel list from Octonet server and generate channels for kodi. Signed-off-by: Julian Scheel --- CMakeLists.txt | 9 +++- src/OctonetData.cpp | 127 ++++++++++++++++++++++++++++++++++++++++++++ src/OctonetData.h | 56 +++++++++++++++++++ src/client.cpp | 40 +++----------- 4 files changed, 198 insertions(+), 34 deletions(-) create mode 100644 src/OctonetData.cpp create mode 100644 src/OctonetData.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c68515a..8796b7a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,21 +2,26 @@ project(pvr.octonet) cmake_minimum_required(VERSION 2.6) +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}) enable_language(CXX) find_package(kodi REQUIRED) find_package(kodiplatform REQUIRED) find_package(platform REQUIRED) +find_package(JsonCpp REQUIRED) include_directories( ${kodiplatform_INCLUDE_DIRS} ${platform_INCLUDE_DIRS} - ${KODI_INCLUDE_DIR}) + ${KODI_INCLUDE_DIR} + ${JSONCPP_INCLUDE_DIRS}) set(DEPLIBS - ${platform_LIBRARIES}) + ${platform_LIBRARIES} + ${JSONCPP_LIBRARIES}) set(OCTONET_SOURCES + src/OctonetData.cpp src/client.cpp) build_addon(pvr.octonet OCTONET DEPLIBS) diff --git a/src/OctonetData.cpp b/src/OctonetData.cpp new file mode 100644 index 0000000..36b873e --- /dev/null +++ b/src/OctonetData.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2015 Julian Scheel + * Copyright (C) 2015 jusst technologies GmbH + * Copyright (C) 2015 Digital Devices GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + */ + +#include +#include + +#include + +#include "OctonetData.h" +#include "platform/util/StringUtils.h" + +using namespace ADDON; + +OctonetData::OctonetData() +{ + serverAddress = octonetAddress; + channels.clear(); + + if (loadChannelList()) + kodi->QueueNotification(QUEUE_INFO, "%d channels loaded.", channels.size()); +} + +OctonetData::~OctonetData(void) +{ + channels.clear(); +} + +bool OctonetData::loadChannelList() +{ + std::string jsonContent; + void *f = kodi->OpenFile(("http://" + serverAddress + "/channellist.lua?select=json").c_str(), 0); + if (!f) + return false; + + char buf[1024]; + while (int read = kodi->ReadFile(f, buf, 1024)) + jsonContent.append(buf, read); + + kodi->CloseFile(f); + + Json::Value root; + Json::Reader reader; + + if (!reader.parse(jsonContent, root, false)) + return false; + + const Json::Value groupList = root["GroupList"]; + for (unsigned int i = 0; i < groupList.size(); i++) { + const Json::Value channelList = groupList[i]["ChannelList"]; + for (unsigned int j = 0; j < channelList.size(); j++) { + const Json::Value channel = channelList[j]; + OctonetChannel chan; + + chan.name = channel["Title"].asString(); + chan.url = "rtsp://" + serverAddress + "/" + channel["Request"].asString(); + chan.radio = false; + +#if 0 /* Would require a 64 bit identifier */ + std::string id = channel["ID"].asString(); + size_t strip; + /* Strip colons from id */ + while ((strip = id.find(":")) != std::string::npos) + id.erase(strip, 1); + + std::stringstream ids(id); + ids >> chan.id; +#endif + chan.id = 1000 + channels.size(); + channels.push_back(chan); + } + } + + return true; +} + +void *OctonetData::Process(void) +{ + return NULL; +} + +int OctonetData::getChannelCount(void) +{ + return channels.size(); +} + +PVR_ERROR OctonetData::getChannels(ADDON_HANDLE handle, bool bRadio) +{ + for (unsigned int i = 0; i < channels.size(); i++) + { + OctonetChannel &channel = channels.at(i); + if (channel.radio == bRadio) + { + PVR_CHANNEL chan; + memset(&chan, 0, sizeof(PVR_CHANNEL)); + + chan.iUniqueId = channel.id; + chan.bIsRadio = channel.radio; + chan.iChannelNumber = i; + strncpy(chan.strChannelName, channel.name.c_str(), strlen(channel.name.c_str())); + strncpy(chan.strStreamURL, channel.url.c_str(), strlen(channel.url.c_str())); + strcpy(chan.strInputFormat, "video/x-mpegts"); + chan.bIsHidden = false; + + pvr->TransferChannelEntry(handle, &chan); + } + } + return PVR_ERROR_NO_ERROR; +} diff --git a/src/OctonetData.h b/src/OctonetData.h new file mode 100644 index 0000000..f2a5277 --- /dev/null +++ b/src/OctonetData.h @@ -0,0 +1,56 @@ +#pragma once + +/* + * Copyright (C) 2015 Julian Scheel + * Copyright (C) 2015 jusst technologies GmbH + * Copyright (C) 2015 Digital Devices GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + */ + +#include + +#include "platform/threads/threads.h" +#include "platform/util/StdString.h" +#include "client.h" + +struct OctonetChannel +{ + std::string name; + std::string url; + bool radio; + int id; +}; + +class OctonetData : public PLATFORM::CThread +{ + public: + OctonetData(void); + virtual ~OctonetData(void); + + virtual int getChannelCount(void); + virtual PVR_ERROR getChannels(ADDON_HANDLE handle, bool bRadio); + + protected: + virtual bool loadChannelList(void); + + virtual void *Process(void); + + private: + std::string serverAddress; + std::vector channels; +}; diff --git a/src/client.cpp b/src/client.cpp index d5b2719..7252f35 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -26,6 +26,8 @@ #include #include +#include "OctonetData.h" + using namespace ADDON; /* setting variables with defaults */ @@ -36,6 +38,8 @@ ADDON_STATUS addonStatus = ADDON_STATUS_UNKNOWN; CHelper_libXBMC_addon *kodi = NULL; CHelper_libXBMC_pvr *pvr = NULL; +OctonetData *data = NULL; + /* KODI Core Addon functions * see xbmc_addon_dll.h */ @@ -72,6 +76,8 @@ ADDON_STATUS ADDON_Create(void *callbacks, void* props) kodi->Log(LOG_DEBUG, "%s: Creating octonet pvr addon", __func__); ADDON_ReadSettings(); + data = new OctonetData; + addonStatus = ADDON_STATUS_OK; return addonStatus; } @@ -177,42 +183,12 @@ PVR_ERROR OpenDialogChannelScan(void) { return PVR_ERROR_NOT_IMPLEMENTED; } int GetChannelsAmount(void) { - // FIXME: This is a dummy - return 2; + return data->getChannelCount(); } PVR_ERROR GetChannels(ADDON_HANDLE handle, bool bRadio) { - // FIXME: This is a dummy - if (!bRadio) { - PVR_CHANNEL chan; - memset(&chan, 0, sizeof(PVR_CHANNEL)); - - chan.iUniqueId = 1; - chan.bIsRadio = bRadio; - chan.iChannelNumber = 1; - snprintf(chan.strChannelName, sizeof(chan.strChannelName) - 1, - "Das Erste"); - snprintf(chan.strStreamURL, sizeof(chan.strStreamURL) - 1, - "rtsp://172.27.1.40:8554/channel/1"); - - pvr->TransferChannelEntry(handle, &chan); - } else { - PVR_CHANNEL chan; - memset(&chan, 0, sizeof(PVR_CHANNEL)); - - chan.iUniqueId = 2; - chan.bIsRadio = bRadio; - chan.iChannelNumber = 2; - snprintf(chan.strChannelName, sizeof(chan.strChannelName) - 1, - "NDR 2"); - snprintf(chan.strStreamURL, sizeof(chan.strStreamURL) - 1, - "rtsp://172.27.1.40:8554/channel/10"); - - pvr->TransferChannelEntry(handle, &chan); - } - - return PVR_ERROR_NO_ERROR; + return data->getChannels(handle, bRadio); } PVR_ERROR DeleteChannel(const PVR_CHANNEL& channel) { return PVR_ERROR_NOT_IMPLEMENTED; }