Skip to content

Commit

Permalink
Merge pull request #113 from phunkyfish/support-providers
Browse files Browse the repository at this point in the history
Support PVR providers
  • Loading branch information
phunkyfish authored Oct 10, 2021
2 parents d2102bd + 0c64eb6 commit 3ebb5ab
Show file tree
Hide file tree
Showing 11 changed files with 266 additions and 34 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
[![Coverity Scan Build Status](https://scan.coverity.com/projects/5120/badge.svg)](https://scan.coverity.com/projects/5120)

# Demo PVR
Demo PVR client addon for [Kodi](https://kodi.tv)
Demo PVR client addon for [Kodi](https://kodi.tv). The add-on is aimed at both PVR add-on devs and at XBMC skin developers.

For more information on the relationship of the data and the UI see [here](pvr.demo/README.md)

## Build instructions

Expand Down
121 changes: 101 additions & 20 deletions pvr.demo/PVRDemoAddonSettings.xml

Large diffs are not rendered by default.

35 changes: 25 additions & 10 deletions pvr.demo/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
pvr.demo.extras
===============
Dummy data and files to be used with the PVR Demo Add-on. This is aimed at XBMC skin developers.
# PVR Demo Data
Dummy data and files to be used with the PVR Demo Add-on.

This package was originally put together by Jezz_X. I just updated paths to keep it working in XBMC 13 and added the following:
## Icons
There are 11 icons used for the channels. The same icons are used for TV and Radio.

- dummy recordings
- replaced the first tv channel (stream not working anymore)
- added more of the available genre colors in the epg
- added genre colors doc file
## PVR Channel Data types

### Usage
Extract the contents of this file and copy it over into the pvr demo addons install directory (PVRDemoAddonSettings.xml needs to be overwritten). After that go into settings/livetv/general and select "Reset the PVR database" to get the new info.
The relationship between Providers, Channels, Channel Groups and Recordings are as follow:
- *Providers*:
- Are independent of TV or Radio. A PVR add-on can create custom providers, it is also a provider itself.
- *Channels*:
- Can specify a provider ID. If one is not specified, its provider will default to the PVR add-on as the provider
- *Channel Groups*:
- can contain either TV channels or Radio channels
- *Recordings*:
- Can specify a channel ID and/or a provider ID. The fallback order is `Channel -> Custom Provider -> Addon provider`.

### Channels and Providers behaviour for Recordings

#### /Directory1/
The first four TV and Radio recordings (1-4) have a channel ID set as per PVR API 5.0.0. For these recordings the channel name and icon should be visible when inspecting the recordings in the UI. They also have provider IDs set, but as this is a fallback used in the absence of Channel IDs, the provider will not be visible.

#### /Directory2/
The next 3 TV and Radio recordings (5-7) have a provider ID set as per PVR API 8.0.0. Neither channel name or channel ID are set. For these recordings the provider name and icon (custom provider used) should be visible when inspecting the recordings in the UI.

#### /Directory3/
The next 3 TV and Radio recordings (8-10) don't have a channel ID or a provider ID set, but do have channel name set. For these recordings the PVR add-on name and icon (add-on provider used) should be visible when inspecting the recordings in the UI.
5 changes: 4 additions & 1 deletion pvr.demo/addon.xml.in
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<addon
id="pvr.demo"
version="20.2.0"
version="20.3.0"
name="PVR Demo Client"
provider-name="Pulse-Eight Ltd., Team Kodi">
<requires>@ADDON_DEPENDS@</requires>
Expand All @@ -13,6 +13,9 @@
<license>GPL-2.0-or-later</license>
<source>https://github.com/kodi-pvr/pvr.demo</source>
<forum>https://forum.kodi.tv/forumdisplay.php?fid=173</forum>
<assets>
<icon>icon.png</icon>
</assets>
<summary lang="af_ZA">Demo PVR Kliënt</summary>
<summary lang="am_ET">የ PVR ደንበኛ ናሙና</summary>
<summary lang="be_BY">Дэманстрацыя кліента PVR</summary>
Expand Down
5 changes: 5 additions & 0 deletions pvr.demo/changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
v20.3.0
- Add icon add-on
- Add icons for providers
- Add Support for PVR Providers

v20.2.0
- Kodi API to 8.0.0
- Add supports recordings delete capability
Expand Down
Binary file added pvr.demo/data/p01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pvr.demo/data/p02.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pvr.demo/data/p03.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pvr.demo/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
111 changes: 109 additions & 2 deletions src/PVRDemo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ PVR_ERROR CPVRDemo::GetCapabilities(kodi::addon::PVRCapabilities& capabilities)
capabilities.SetSupportsRecordingsRename(false);
capabilities.SetSupportsRecordingsLifetimeChange(false);
capabilities.SetSupportsDescrambleInfo(false);
capabilities.SetSupportsProviders(true);

return PVR_ERROR_NO_ERROR;
}
Expand Down Expand Up @@ -162,6 +163,32 @@ PVR_ERROR CPVRDemo::GetEPGTagStreamProperties(
return PVR_ERROR_NO_ERROR;
}

PVR_ERROR CPVRDemo::GetProvidersAmount(int& amount)
{
amount = m_providers.size();

return PVR_ERROR_NO_ERROR;
}

PVR_ERROR CPVRDemo::GetProviders(kodi::addon::PVRProvidersResultSet& results)
{
for (const auto& provider : m_providers)
{
kodi::addon::PVRProvider kodiProvider;

kodiProvider.SetUniqueId(provider.iProviderId);
kodiProvider.SetName(provider.strProviderName);
kodiProvider.SetType(provider.providerType);
kodiProvider.SetIconPath(provider.strIconPath);
kodiProvider.SetCountries(provider.countries);
kodiProvider.SetLanguages(provider.languages);

results.Add(kodiProvider);
}

return PVR_ERROR_NO_ERROR;
}

PVR_ERROR CPVRDemo::GetChannelsAmount(int& amount)
{
amount = m_channels.size();
Expand All @@ -186,6 +213,9 @@ PVR_ERROR CPVRDemo::GetChannels(bool bRadio, kodi::addon::PVRChannelsResultSet&
kodiChannel.SetIsHidden(false);
kodiChannel.SetHasArchive(channel.bArchive);

/* PVR API 8.0.0 */
kodiChannel.SetClientProviderUid(channel.iProviderId);

results.Add(kodiChannel);
}
}
Expand Down Expand Up @@ -293,7 +323,10 @@ PVR_ERROR CPVRDemo::GetRecordings(bool deleted, kodi::addon::PVRRecordingsResult
kodiRecording.SetDirectory(recording.strDirectory);

/* TODO: PVR API 5.0.0: Implement this */
kodiRecording.SetChannelUid(PVR_CHANNEL_INVALID_UID);
kodiRecording.SetChannelUid(recording.iChannelId);

/* PVR API 8.0.0 */
kodiRecording.SetClientProviderUid(recording.iProviderId);

results.Add(kodiRecording);
}
Expand Down Expand Up @@ -415,9 +448,23 @@ bool CPVRDemo::LoadDemoData(void)
return false;
}

/* load providers */
int iUniqueProviderId = 0;
XMLElement* pElement = pRootElement->FirstChildElement("providers");
if (pElement)
{
for (const XMLElement* pProviderNode = pElement->FirstChildElement(); pProviderNode != nullptr;
pProviderNode = pProviderNode->NextSiblingElement())
{
PVRDemoProvider provider;
if (ScanXMLProviderData(pProviderNode, ++iUniqueProviderId, provider))
m_providers.emplace_back(provider);
}
}

/* load channels */
int iUniqueChannelId = 0;
XMLElement* pElement = pRootElement->FirstChildElement("channels");
pElement = pRootElement->FirstChildElement("channels");
if (pElement)
{
for (const XMLElement* pChannelNode = pElement->FirstChildElement(); pChannelNode != nullptr;
Expand Down Expand Up @@ -532,6 +579,54 @@ std::string CPVRDemo::GetRecordingURL(const kodi::addon::PVRRecording& recording
return "";
}

bool CPVRDemo::ScanXMLProviderData(const XMLNode* pProviderNode,
int iUniqueProviderId,
PVRDemoProvider& provider)
{
std::string strTmp;
provider.iProviderId = iUniqueProviderId;

/* provider name */
if (!XMLGetString(pProviderNode, "name", strTmp))
return false;
provider.strProviderName = strTmp;

/* provider type */
if (!XMLGetString(pProviderNode, "type", strTmp))
return false;
kodi::tools::StringUtils::ToLower(strTmp);
if (strTmp == "addon")
provider.providerType = PVR_PROVIDER_TYPE_ADDON;
else if (strTmp == "satellite")
provider.providerType = PVR_PROVIDER_TYPE_SATELLITE;
else if (strTmp == "cable")
provider.providerType = PVR_PROVIDER_TYPE_CABLE;
else if (strTmp == "aerial")
provider.providerType = PVR_PROVIDER_TYPE_AERIAL;
else if (strTmp == "iptv")
provider.providerType = PVR_PROVIDER_TYPE_IPTV;
else
provider.providerType = PVR_PROVIDER_TYPE_UNKNOWN;

/* provider icon path */
if (!XMLGetString(pProviderNode, "iconPath", strTmp))
provider.strIconPath = m_strDefaultIcon;
else
provider.strIconPath = ClientPath() + strTmp;

/* provider countries */
if (!XMLGetString(pProviderNode, "countries", strTmp))
return false;
provider.countries = kodi::tools::StringUtils::Split(strTmp, PROVIDER_STRING_TOKEN_SEPARATOR);

/* provider languages */
if (!XMLGetString(pProviderNode, "languages", strTmp))
return false;
provider.languages = kodi::tools::StringUtils::Split(strTmp, PROVIDER_STRING_TOKEN_SEPARATOR);

return true;
}

bool CPVRDemo::ScanXMLChannelData(const XMLNode* pChannelNode,
int iUniqueChannelId,
PVRDemoChannel& channel)
Expand Down Expand Up @@ -573,6 +668,10 @@ bool CPVRDemo::ScanXMLChannelData(const XMLNode* pChannelNode,

XMLGetBoolean(pChannelNode, "archive", channel.bArchive);

/* provider id */
channel.iProviderId = PVR_PROVIDER_INVALID_UID;
XMLGetInt(pChannelNode, "provider", channel.iProviderId);

return true;
}

Expand Down Expand Up @@ -751,6 +850,14 @@ bool CPVRDemo::ScanXMLRecordingData(const XMLNode* pRecordingNode,
}
}

/* channel id */
recording.iChannelId = PVR_CHANNEL_INVALID_UID;
XMLGetInt(pRecordingNode, "channel", recording.iChannelId);

/* provider id */
recording.iProviderId = PVR_PROVIDER_INVALID_UID;
XMLGetInt(pRecordingNode, "provider", recording.iProviderId);

return true;
}

Expand Down
19 changes: 19 additions & 0 deletions src/PVRDemo.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ struct PVRDemoChannel
std::string strIconPath;
std::string strStreamURL;
std::vector<PVRDemoEpgEntry> epg;
int iProviderId;
};

struct PVRDemoRecording
Expand All @@ -64,6 +65,8 @@ struct PVRDemoRecording
std::string strEpisodeName;
std::string strDirectory;
time_t recordingTime;
int iChannelId;
int iProviderId;
};

struct PVRDemoTimer
Expand All @@ -85,6 +88,16 @@ struct PVRDemoChannelGroup
std::vector<int> members;
};

struct PVRDemoProvider
{
int iProviderId;
std::string strProviderName;
PVR_PROVIDER_TYPE providerType;
std::string strIconPath;
std::vector<std::string> countries;
std::vector<std::string> languages;
};

namespace tinyxml2
{
class XMLNode;
Expand Down Expand Up @@ -123,6 +136,8 @@ class ATTRIBUTE_HIDDEN CPVRDemo : public kodi::addon::CAddonBase,
PVR_ERROR GetEPGTagStreamProperties(
const kodi::addon::PVREPGTag& tag,
std::vector<kodi::addon::PVRStreamProperty>& properties) override;
PVR_ERROR GetProvidersAmount(int& amount) override;
PVR_ERROR GetProviders(kodi::addon::PVRProvidersResultSet& results) override;
PVR_ERROR GetChannelGroupsAmount(int& amount) override;
PVR_ERROR GetChannelGroups(bool bRadio, kodi::addon::PVRChannelGroupsResultSet& results) override;
PVR_ERROR GetChannelGroupMembers(const kodi::addon::PVRChannelGroup& group,
Expand Down Expand Up @@ -150,6 +165,9 @@ class ATTRIBUTE_HIDDEN CPVRDemo : public kodi::addon::CAddonBase,

private:
PVR_ERROR CallMenuHook(const kodi::addon::PVRMenuhook& menuhook);
bool ScanXMLProviderData(const tinyxml2::XMLNode* pProviderNode,
int iUniqueProviderId,
PVRDemoProvider& provider);
bool ScanXMLChannelData(const tinyxml2::XMLNode* pChannelNode,
int iUniqueChannelId,
PVRDemoChannel& channel);
Expand All @@ -170,6 +188,7 @@ class ATTRIBUTE_HIDDEN CPVRDemo : public kodi::addon::CAddonBase,
const std::string& strTag,
bool& bBoolValue);

std::vector<PVRDemoProvider> m_providers;
std::vector<PVRDemoChannelGroup> m_groups;
std::vector<PVRDemoChannel> m_channels;
std::vector<PVRDemoRecording> m_recordings;
Expand Down

0 comments on commit 3ebb5ab

Please sign in to comment.