Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Genre and sub genre mapping #276

Merged
merged 1 commit into from
Dec 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ set(NEXTPVR_SOURCES src/addon.cpp
src/buffers/ClientTimeshift.cpp
src/buffers/RecordingBuffer.cpp
src/buffers/CircularBuffer.cpp
src/utilities/GenreMapper.cpp
src/utilities/SettingsMigration.cpp
src/buffers/Seeker.cpp)

Expand All @@ -50,6 +51,7 @@ set(NEXTPVR_HEADERS src/addon.h
src/buffers/RecordingBuffer.h
src/buffers/CircularBuffer.h
src/buffers/Seeker.h
src/utilities/GenreMapper.h
src/utilities/SettingsMigration.h
src/utilities/XMLUtils.h)

Expand Down
83 changes: 83 additions & 0 deletions pvr.nextpvr/resources/genre-mapping.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<translations>
<!-- standard DVB mappings -->
<genre name="Movie / Drama" type="16" subtype="0"/>
<genre name="Detective / Thriller" type="16" subtype="1"/>
<genre name="Adventure / Western / War" type="16" subtype="2"/>
<genre name="Science fiction / Fantasy / Horror" type="16" subtype="3"/>
<genre name="Comedy" type="16" subtype="4"/>
<genre name="Soap / Melodrama / Folkloric" type="16" subtype="5"/>
<genre name="Romance" type="16" subtype="6"/>
<genre name="Serious / Classical /Religious / Historical movie / Drama" type="16" subtype="7"/>
<genre name="Adult movie / Drama" type="16" subtype="8"/>
<genre name="News / Current affairs" type="32" subtype="0"/>
<genre name="News / Weather report" type="32" subtype="1"/>
<genre name="News magazine" type="32" subtype="2"/>
<genre name="Documentary" type="32" subtype="3"/>
<genre name="Discussion / Interview / Debate" type="32" subtype="4"/>
<genre name="Show / Game show" type="48" subtype="0"/>
<genre name="Game show / Quiz / Contest" type="48" subtype="1"/>
<genre name="Variety show" type="48" subtype="2"/>
<genre name="Talk show" type="48" subtype="3"/>
<genre name="Sports" type="64" subtype="0"/>
<genre name="Special event" type="64" subtype="1"/>
<genre name="Sports magazine" type="64" subtype="2"/>
<genre name="Football / Soccer" type="64" subtype="3"/>
<genre name="Tennis / Squash" type="64" subtype="4"/>
<genre name="Team sports" type="64" subtype="5"/>
<genre name="Athletics" type="64" subtype="6"/>
<genre name="Motor sport" type="64" subtype="7"/>
<genre name="Water sport" type="64" subtype="8"/>
<genre name="Winter sports" type="64" subtype="9"/>
<genre name="Equestrian" type="64" subtype="10"/>
<genre name="Martial sports" type="64" subtype="11"/>
<genre name="Childrens / Youth" type="80" subtype="0"/>
<genre name="Pre-school children&apos;s programmes" type="80" subtype="1"/>
<genre name="Entertainment programmes for 6 To14" type="80" subtype="2"/>
<genre name="Entertainment programmes for 10 to 16" type="80" subtype="3"/>
<genre name="Informational / Educational / School programmes" type="80" subtype="4"/>
<genre name="Cartoons / Puppets" type="80" subtype="5"/>
<genre name="Music / Ballet / Dance" type="96" subtype="0"/>
<genre name="Rock / Pop" type="96" subtype="1"/>
<genre name="Serious music / Classical music" type="96" subtype="2"/>
<genre name="Folk / Traditional music" type="96" subtype="3"/>
<genre name="Jazz" type="96" subtype="4"/>
<genre name="Musical / Opera" type="96" subtype="5"/>
<genre name="Ballet" type="96" subtype="6"/>
<genre name="Arts / Culture" type="112" subtype="0"/>
<genre name="Performing srts" type="112" subtype="1"/>
<genre name="Fine arts" type="112" subtype="2"/>
<genre name="Religion" type="112" subtype="3"/>
<genre name="Popular culture / Traditional arts" type="112" subtype="4"/>
<genre name="Literature" type="112" subtype="5"/>
<genre name="Film / Cinema" type="112" subtype="6"/>
<genre name="Experimental film / video" type="112" subtype="7"/>
<genre name="Broadcasting / Press" type="112" subtype="8"/>
<genre name="New media" type="112" subtype="9"/>
<genre name="Arts / Culture magazines" type="112" subtype="10"/>
<genre name="Fashion" type="112" subtype="11"/>
<genre name="Social / Political / Economics" type="128" subtype="0"/>
<genre name="Magazines / Reports / Documentary" type="128" subtype="1"/>
<genre name="Economics / Social advisory" type="128" subtype="2"/>
<genre name="Remarkable people" type="128" subtype="3"/>
<genre name="Education / Science / Factual" type="144" subtype="0"/>
<genre name="Nature / Animals / Environment" type="144" subtype="1"/>
<genre name="Technology / Natural sciences" type="144" subtype="2"/>
<genre name="Medicine / Physiology / Psychology" type="144" subtype="3"/>
<genre name="Foreign countries / Expeditions" type="144" subtype="4"/>
<genre name="Social / Spiritual sciences" type="144" subtype="5"/>
<genre name="Further education" type="144" subtype="6"/>
<genre name="Languages" type="144" subtype="7"/>
<genre name="Leisure / Hobbies" type="160" subtype="0"/>
<genre name="Tourism / Travel" type="160" subtype="1"/>
<genre name="Handicraft" type="160" subtype="2"/>
<genre name="Motoring" type="160" subtype="3"/>
<genre name="Fitness &amp; Health" type="160" subtype="4"/>
<genre name="Cooking" type="160" subtype="5"/>
<genre name="Advertisement / Shopping" type="160" subtype="6"/>
<genre name="Gardening" type="160" subtype="7"/>
<genre name="Original language" type="176" subtype="0"/>
<genre name="Black &amp; white" type="176" subtype="1"/>
<genre name="Unpublished" type="176" subtype="2"/>
<genre name="Live broadcast" type="176" subtype="3"/>
<genre name="Drama" type="240" subtype="0"/>
</translations>
35 changes: 17 additions & 18 deletions src/EPG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ using namespace NextPVR::utilities;
/************************************************************/
/** EPG handling */

EPG::EPG(const std::shared_ptr<InstanceSettings>& settings, Request& request, Recordings& recordings, Channels& channels) :
EPG::EPG(const std::shared_ptr<InstanceSettings>& settings, Request& request, Recordings& recordings, Channels& channels,GenreMapper& genreMapper) :
m_settings(settings),
m_request(request),
m_recordings(recordings),
m_genreMapper(genreMapper),
m_channels(channels)
{
}
Expand Down Expand Up @@ -51,7 +52,7 @@ PVR_ERROR EPG::GetEPGForChannel(int channelUid, time_t start, time_t end, kodi::
if (m_request.DoMethodRequest(request, doc) == tinyxml2::XML_SUCCESS)
{
tinyxml2::XMLNode* listingsNode = doc.RootElement()->FirstChildElement("listings");
for (tinyxml2::XMLNode* pListingNode = listingsNode->FirstChildElement("l"); pListingNode; pListingNode = pListingNode->NextSiblingElement())
for (const tinyxml2::XMLNode* pListingNode = listingsNode->FirstChildElement("l"); pListingNode; pListingNode = pListingNode->NextSiblingElement())
{
kodi::addon::PVREPGTag broadcast;
std::string title;
Expand Down Expand Up @@ -82,6 +83,14 @@ PVR_ERROR EPG::GetEPGForChannel(int channelUid, time_t start, time_t end, kodi::
broadcast.SetStartTime(stol(startTime));
broadcast.SetUniqueBroadcastId(stoi(endTime));
broadcast.SetEndTime(stol(endTime));

static std::regex yearRegex("^(.+[12]\\d{3})\\n");
std::smatch base_match;
if (std::regex_search(description, base_match, yearRegex))
{
kodi::tools::StringUtils::Replace(description, base_match[0].str(), base_match[1].str() + " ");
}

broadcast.SetPlot(description);

std::string artworkPath;
Expand Down Expand Up @@ -111,23 +120,13 @@ PVR_ERROR EPG::GetEPGForChannel(int channelUid, time_t start, time_t end, kodi::
broadcast.SetGenreSubType(XMLUtils::GetIntValue(pListingNode, "genre_subtype"));

}
std::string allGenres;
if (XMLUtils::GetAdditiveString(pListingNode->FirstChildElement("genres"), "genre", EPG_STRING_TOKEN_SEPARATOR, allGenres, true))
{
if (allGenres.find(EPG_STRING_TOKEN_SEPARATOR) != std::string::npos)
{
if (broadcast.GetGenreType() != EPG_GENRE_USE_STRING)
{
broadcast.SetGenreSubType(EPG_GENRE_USE_STRING);
}
broadcast.SetGenreDescription(allGenres);
}
else if (m_settings->m_genreString && broadcast.GetGenreSubType() != EPG_GENRE_USE_STRING)
{
broadcast.SetGenreDescription(allGenres);
broadcast.SetGenreSubType(EPG_GENRE_USE_STRING);
}

NextPVR::GenreBlock genreBlock = { sGenre, broadcast.GetGenreType(), EPG_EVENT_CONTENTMASK_UNDEFINED };
if (m_genreMapper.ParseAllGenres(pListingNode, genreBlock))
{
broadcast.SetGenreDescription(genreBlock.description);
broadcast.SetGenreType(genreBlock.genreType);
broadcast.SetGenreSubType(genreBlock.genreSubType);
}

int season{EPG_TAG_INVALID_SERIES_EPISODE};
Expand Down
4 changes: 3 additions & 1 deletion src/EPG.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@
#include <kodi/addon-instance/PVR.h>
#include "Channels.h"
#include "Recordings.h"
#include "utilities/GenreMapper.h"

namespace NextPVR
{
const int YEAR_NOT_SET = -1;
class ATTR_DLL_LOCAL EPG
{
public:
EPG(const std::shared_ptr<InstanceSettings>& settings, Request& request, Recordings& recordings, Channels& channels);
EPG(const std::shared_ptr<InstanceSettings>& settings, Request& request, Recordings& recordings, Channels& channels, GenreMapper& genreMapper);
PVR_ERROR GetEPGForChannel(int channelUid, time_t start, time_t end, kodi::addon::PVREPGTagsResultSet& results);

private:
Expand All @@ -31,5 +32,6 @@ namespace NextPVR
Request& m_request;
Recordings& m_recordings;
Channels& m_channels;
GenreMapper& m_genreMapper;
};
} // namespace NextPVR
14 changes: 9 additions & 5 deletions src/Recordings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ using namespace NextPVR::utilities;
/************************************************************/
/** Record handling **/

Recordings::Recordings(const std::shared_ptr<InstanceSettings>& settings, Request& request, Timers& timers, Channels& channels, cPVRClientNextPVR& pvrclient) :
Recordings::Recordings(const std::shared_ptr<InstanceSettings>& settings, Request& request, Timers& timers, Channels& channels,
GenreMapper& genreMapper, cPVRClientNextPVR& pvrclient) :
m_settings(settings),
m_request(request),
m_timers(timers),
m_channels(channels),
m_genreMapper(genreMapper),
m_pvrclient(pvrclient)
{

Expand Down Expand Up @@ -441,11 +443,13 @@ bool Recordings::UpdatePvrRecording(const tinyxml2::XMLNode* pRecordingNode, kod
tag.SetFanartPath(artworkPath + "&prefer=fanart");
tag.SetThumbnailPath(artworkPath + "&prefer=poster");
}
if (XMLUtils::GetAdditiveString(pRecordingNode->FirstChildElement("genres"), "genre", EPG_STRING_TOKEN_SEPARATOR, buffer, true))

NextPVR::GenreBlock genreBlock = { "", EPG_EVENT_CONTENTMASK_UNDEFINED, EPG_EVENT_CONTENTMASK_UNDEFINED };
if (m_genreMapper.ParseAllGenres(pRecordingNode, genreBlock))
{
tag.SetGenreType(EPG_GENRE_USE_STRING);
tag.SetGenreSubType(0);
tag.SetGenreDescription(buffer);
tag.SetGenreDescription(genreBlock.description);
tag.SetGenreType(genreBlock.genreType);
tag.SetGenreSubType(genreBlock.genreSubType);
}

std::string significance;
Expand Down
5 changes: 4 additions & 1 deletion src/Recordings.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "BackendRequest.h"
#include "Timers.h"
#include "utilities/GenreMapper.h"
#include <kodi/addon-instance/PVR.h>


Expand All @@ -21,7 +22,8 @@ namespace NextPVR
{

public:
Recordings(const std::shared_ptr<InstanceSettings>& settings, Request& request, Timers& timers, Channels& channels, cPVRClientNextPVR& pvrclent);
Recordings(const std::shared_ptr<InstanceSettings>& settings, Request& request, Timers& timers, Channels& channels,
GenreMapper& genreMapper, cPVRClientNextPVR& pvrclent);
/* Recording handling **/
PVR_ERROR GetRecordingsAmount(bool deleted, int& amount);
PVR_ERROR GetDriveSpace(uint64_t& total, uint64_t& used);
Expand All @@ -48,6 +50,7 @@ namespace NextPVR
Request& m_request;
Timers& m_timers;
Channels& m_channels;
GenreMapper& m_genreMapper;
cPVRClientNextPVR& m_pvrclient;

// update these at end of counting loop can be called during action
Expand Down
5 changes: 3 additions & 2 deletions src/pvrclient-nextpvr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,10 @@ cPVRClientNextPVR::cPVRClientNextPVR(const CNextPVRAddon& base, const kodi::addo
m_request(m_settings),
m_channels(m_settings, m_request),
m_timers(m_settings, m_request, m_channels, *this),
m_recordings(m_settings, m_request, m_timers, m_channels, *this),
m_recordings(m_settings, m_request, m_timers, m_channels,m_genreMapper, *this),
m_menuhook(m_settings, m_recordings, m_channels, *this),
m_epg(m_settings, m_request, m_recordings, m_channels)
m_genreMapper(m_settings),
m_epg(m_settings, m_request, m_recordings, m_channels, m_genreMapper)
{
if (!kodi::vfs::DirectoryExists(m_settings->m_instanceDirectory))
{
Expand Down
2 changes: 2 additions & 0 deletions src/pvrclient-nextpvr.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "Recordings.h"
#include "InstanceSettings.h"
#include "Timers.h"
#include "utilities/GenreMapper.h"
#include "buffers/ClientTimeshift.h"
#include "buffers/DummyBuffer.h"
#include "buffers/RecordingBuffer.h"
Expand Down Expand Up @@ -156,6 +157,7 @@ class ATTR_DLL_LOCAL cPVRClientNextPVR : public kodi::addon::CInstancePVRClient
EPG m_epg;
MenuHook m_menuhook;
Recordings m_recordings;
GenreMapper m_genreMapper;
Timers m_timers;

void SetConnectionState(PVR_CONNECTION_STATE state, std::string displayMessage = "");
Expand Down
Loading
Loading