Skip to content

Commit

Permalink
Change 'ProgramInfo::catType' from a string to an enum
Browse files Browse the repository at this point in the history
This is done to prevent mistakes such as invalid values being stored
and used. Converting over exposed a bug in the handling of Dish
Network content (theme) values which would have caused Sports
programmes to be identified as a 'series' and News programmes to be
identified as 'sports'. Hopefully such bugs will become much harder to
introduce in future since enums in C++ provide greater type safety than
strings or ints.

The change ended up being much bigger than I first expected, I've been
as careful as possible to avoid regressions but I cannot test every
possible combination and code path. If you notice a bug please file a ticket,
don't assume that someone else will do so.
  • Loading branch information
stuartm committed Apr 13, 2013
1 parent 0dd1d3e commit bff1559
Show file tree
Hide file tree
Showing 19 changed files with 146 additions and 131 deletions.
58 changes: 43 additions & 15 deletions mythtv/libs/libmyth/programinfo.cpp
Expand Up @@ -81,6 +81,29 @@ static void set_flag(uint32_t &flags, int flag_to_set, bool is_set)
flags |= flag_to_set;
}

QString myth_category_type_to_string(ProgramInfo::CategoryType category_type)
{
static const char *cattype[] =
{ "", "movie", "series", "sports", "tvshow", };

if ((category_type > ProgramInfo::kCategoryNone) &&
(category_type < sizeof(cattype)))
return QString(cattype[category_type]);

return "";
}

ProgramInfo::CategoryType string_to_myth_category_type(const QString &category_type)
{
static const char *cattype[] =
{ "", "movie", "series", "sports", "tvshow", };

for (uint i = 1; i < 5; i++)
if (category_type == cattype[i])
return (ProgramInfo::CategoryType) i;
return ProgramInfo::kCategoryNone;
}

/** \fn ProgramInfo::ProgramInfo(void)
* \brief Null constructor.
*/
Expand Down Expand Up @@ -112,7 +135,7 @@ ProgramInfo::ProgramInfo(void) :
seriesid(),
programid(),
inetref(),
catType(),
catType(kCategoryNone),


filesize(0ULL),
Expand Down Expand Up @@ -340,7 +363,7 @@ ProgramInfo::ProgramInfo(
seriesid(_seriesid),
programid(_programid),
inetref(_inetref),
catType(),
catType(kCategoryNone),

filesize(_filesize),

Expand Down Expand Up @@ -456,7 +479,7 @@ ProgramInfo::ProgramInfo(
seriesid(_seriesid),
programid(_programid),
inetref(_inetref),
catType(),
catType(kCategoryNone),

filesize(0ULL),

Expand Down Expand Up @@ -529,7 +552,7 @@ ProgramInfo::ProgramInfo(

const QString &_seriesid,
const QString &_programid,
const QString &_catType,
const CategoryType _catType,

float _stars,
uint _year,
Expand Down Expand Up @@ -729,7 +752,7 @@ ProgramInfo::ProgramInfo(
seriesid(_seriesid),
programid(_programid),
inetref(_inetref),
catType(),
catType(kCategoryNone),

filesize(0ULL),

Expand Down Expand Up @@ -1049,7 +1072,6 @@ void ProgramInfo::clone(const ProgramInfo &other,
seriesid.detach();
programid.detach();
inetref.detach();
catType.detach();

sortTitle.detach();
inUseForWhat.detach();
Expand Down Expand Up @@ -1086,7 +1108,7 @@ void ProgramInfo::clear(void)
seriesid.clear();
programid.clear();
inetref.clear();
catType.clear();
catType = kCategoryNone;

sortTitle.clear();

Expand Down Expand Up @@ -1630,7 +1652,7 @@ void ProgramInfo::ToMap(InfoMap &progMap,
progMap["seriesid"] = seriesid;
progMap["programid"] = programid;
progMap["inetref"] = inetref;
progMap["catType"] = catType;
progMap["catType"] = myth_category_type_to_string(catType);

progMap["year"] = year ? QString::number(year) : "";

Expand Down Expand Up @@ -1710,6 +1732,12 @@ uint ProgramInfo::GetSecondsInRecording(void) const
return (uint) ((recsecs>0) ? recsecs : max(duration,int64_t(0)));
}

/// \brief Returns catType as a string
QString ProgramInfo::GetCategoryTypeString(void) const
{
return myth_category_type_to_string(catType);
}

/// \brief Returns last frame in position map or 0
uint64_t ProgramInfo::QueryLastFrameInPosMap(void) const
{
Expand Down Expand Up @@ -1737,7 +1765,7 @@ bool ProgramInfo::IsGeneric(void) const
(programid.isEmpty() && subtitle.isEmpty() &&
description.isEmpty()) ||
(!programid.isEmpty() && programid.endsWith("0000")
&& catType == "series");
&& catType == kCategorySeries);
}

QString ProgramInfo::toString(const Verbosity v, QString sep, QString grp)
Expand Down Expand Up @@ -1826,7 +1854,7 @@ bool ProgramInfo::LoadProgramFromRecorded(
{
// These items are not initialized below so they need to be cleared
// if we're loading in a different program into this ProgramInfo
catType.clear();
catType = kCategoryNone;
lastInUseTime = MythDate::current().addSecs(-4 * 60 * 60);
rectype = kNotRecording;
oldrecstatus = rsUnknown;
Expand Down Expand Up @@ -1999,7 +2027,7 @@ bool ProgramInfo::IsSameProgram(const ProgramInfo& other) const
if (title.compare(other.title, Qt::CaseInsensitive) != 0)
return false;

if (catType == "series")
if (catType == kCategorySeries)
{
if (programid.endsWith("0000"))
return false;
Expand Down Expand Up @@ -2606,9 +2634,9 @@ void ProgramInfo::SaveDVDBookmark(const QStringList &fields) const
*
* \return string category_type
*/
QString ProgramInfo::QueryCategoryType(void) const
ProgramInfo::CategoryType ProgramInfo::QueryCategoryType(void) const
{
QString ret;
CategoryType ret;

MSqlQuery query(MSqlQuery::InitCon());

Expand All @@ -2622,7 +2650,7 @@ QString ProgramInfo::QueryCategoryType(void) const

if (query.exec() && query.next())
{
ret = query.value(0).toString();
ret = string_to_myth_category_type(query.value(0).toString());
}

return ret;
Expand Down Expand Up @@ -4678,7 +4706,7 @@ bool LoadFromProgram(

query.value(13).toString(), // seriesid
query.value(14).toString(), // programid
query.value(18).toString(), // catType
string_to_myth_category_type(query.value(18).toString()), // catType

query.value(16).toDouble(), // stars
query.value(15).toUInt(), // year
Expand Down
17 changes: 12 additions & 5 deletions mythtv/libs/libmyth/programinfo.h
Expand Up @@ -73,6 +73,9 @@ class MPUBLIC ProgramInfo
{
friend int pginfo_init_statics(void);
public:
enum CategoryType { kCategoryNone, kCategoryMovie, kCategorySeries,
kCategorySports, kCategoryTVShow };

/// Null constructor
ProgramInfo(void);
/// Copy constructor
Expand Down Expand Up @@ -190,7 +193,7 @@ class MPUBLIC ProgramInfo

const QString &seriesid,
const QString &programid,
const QString &catType,
const CategoryType catType,

float stars,
uint year,
Expand Down Expand Up @@ -401,7 +404,8 @@ class MPUBLIC ProgramInfo
QString GetSeriesID(void) const { return seriesid; }
QString GetProgramID(void) const { return programid; }
QString GetInetRef(void) const { return inetref; }
QString GetCategoryType(void) const { return catType; }
CategoryType GetCategoryType(void) const { return catType; }
QString GetCategoryTypeString(void) const;
int GetRecordingPriority(void) const { return recpriority; }
int GetRecordingPriority2(void) const { return recpriority2; }
float GetStars(void) const { return stars; }
Expand Down Expand Up @@ -486,7 +490,7 @@ class MPUBLIC ProgramInfo
void SetSeriesID( const QString &id) { seriesid = id; }
void SetProgramID( const QString &id) { programid = id; }
void SetCategory( const QString &cat) { category = cat; }
void SetCategoryType( const QString &type) { catType = type; }
void SetCategoryType( const CategoryType type) { catType = type; }
void SetRecordingPriority(int priority) { recpriority = priority; }
void SetRecordingPriority2(int priority) { recpriority2 = priority; }
void SetRecordingRuleID(uint id) { recordid = id; }
Expand Down Expand Up @@ -526,7 +530,7 @@ class MPUBLIC ProgramInfo
uint QueryMplexID(void) const;
QDateTime QueryBookmarkTimeStamp(void) const;
uint64_t QueryBookmark(void) const;
QString QueryCategoryType(void) const;
CategoryType QueryCategoryType(void) const;
QStringList QueryDVDBookmark(const QString &serialid) const;
bool QueryIsEditing(void) const;
bool QueryIsInUse(QStringList &byWho) const;
Expand Down Expand Up @@ -673,7 +677,7 @@ class MPUBLIC ProgramInfo
QString seriesid;
QString programid;
QString inetref;
QString catType;
CategoryType catType;

uint64_t filesize;

Expand Down Expand Up @@ -813,6 +817,9 @@ class MPUBLIC PMapDBReplacement

MPUBLIC QString format_season_and_episode(int seasEp, int digits = -1);

MPUBLIC QString myth_category_type_to_string(ProgramInfo::CategoryType category_type);
MPUBLIC ProgramInfo::CategoryType string_to_myth_category_type(const QString &type);

Q_DECLARE_METATYPE(ProgramInfo*)

#endif // MYTHPROGRAM_H_
Expand Down
2 changes: 1 addition & 1 deletion mythtv/libs/libmythbase/mythversion.h
Expand Up @@ -12,7 +12,7 @@
/// Update this whenever the plug-in ABI changes.
/// Including changes in the libmythbase, libmyth, libmythtv, libmythav* and
/// libmythui class methods in exported headers.
#define MYTH_BINARY_VERSION "0.27.20130404-1"
#define MYTH_BINARY_VERSION "0.27.20130413-1"

/** \brief Increment this whenever the MythTV network protocol changes.
*
Expand Down
10 changes: 5 additions & 5 deletions mythtv/libs/libmythmetadata/metadatafactory.cpp
Expand Up @@ -611,15 +611,15 @@ LookupType GuessLookupType(ProgramInfo *pginfo)
{
LookupType ret = kUnknownVideo;

QString catType = pginfo->GetCategoryType();
if (catType.isEmpty())
ProgramInfo::CategoryType catType = pginfo->GetCategoryType();
if (catType == ProgramInfo::kCategoryNone)
catType = pginfo->QueryCategoryType();

if ((!pginfo->GetSubtitle().isEmpty() || pginfo->GetEpisode() > 0) &&
(catType == "series" || catType == "tvshow" ||
catType == "show"))
(catType == ProgramInfo::kCategorySeries ||
catType == ProgramInfo::kCategoryTVShow))
ret = kProbableTelevision;
else if (catType == "movie" || catType == "film")
else if (catType == ProgramInfo::kCategoryMovie)
ret = kProbableMovie;
else if (pginfo->GetSeason() > 0 || pginfo->GetEpisode() > 0 ||
!pginfo->GetSubtitle().isEmpty())
Expand Down

0 comments on commit bff1559

Please sign in to comment.