Monday, January 16, 2012

MythTV - 'lastwatched'

About six months ago I decided to finally consolidate all my stored media and organise a media box for myself. I dabbled with a few different applications and finally settled ,on a recommendation from a friend, on MythTV.

MythTV is a great application and can do a lot more than I'm using it for, but I've found it's pretty well supported, easy to setup and maintain, and has quite a usable and 'pretty' interface. It can also be controlled from my phone ( I haven't yet purchased a remote ), which is very handy too.

I'm running FreeBSD 9.0 RC2 with mythtv 0.24.1 from ports, along with a few home-grown patches. I haven't yet setup a tuner, but I intend to in the not too distant future.

There are a few little niggly things that are missing in MythTV and I have been slowly hacking away at the code to add them and correct a few other strange behaviours.

The following patch adds a 'lastwatched' field to the metadata along with a patch for the network remote ( this isn't the official one, it's just one I found online somewhere ).

**If you're going to patch MythTV with this patch, add an extra field to the 'videometadata' table named 'lastwatched' of type 'timestamp' ( not null default '0000-00-00 00:00:00' ... or something similar).




--- /usr/ports/multimedia/mythtv/work/mythtv-0.24.1/libs/libmythmetadata/metadatacommon.cpp     2011-05-16 06:57:52.000000000 +1000
+++ libs/libmythmetadata/metadatacommon.cpp 2011-10-31 20:05:30.000000000 +1000
@@ -39,6 +39,7 @@ MetadataLookup::MetadataLookup(void) :
m_inetref(),
m_tmsref(),
m_imdb(),
+ m_lastwatched(),
m_people(),
m_studios(),
m_homepage(),
@@ -81,7 +82,7 @@ MetadataLookup::MetadataLookup(
const uint runtimesecs,
QString inetref,
QString tmsref,
- QString imdb,
+ QString imdb,const QDateTime lastwatched,
const PeopleMap people,
const QStringList studios,
const QString homepage,
@@ -122,6 +123,7 @@ MetadataLookup::MetadataLookup(
m_inetref(inetref),
m_tmsref(tmsref),
m_imdb(imdb),
+ m_lastwatched(lastwatched),
m_people(people),
m_studios(studios),
m_homepage(homepage),
@@ -174,6 +176,7 @@ void MetadataLookup::toMap(MetadataMap &
"yyyy-MM-dd hh:mm");
metadataMap["releasedate"] = m_releasedate.toString(dateformat);
metadataMap["lastupdated"] = m_lastupdated.toString(dateformat);
+ metadataMap["lastwatched"] = m_lastwatched.toString(dateformat);

metadataMap["runtime"] = QString::number(m_runtime) +
QObject::tr(" Minutes");
@@ -204,6 +207,7 @@ MetadataLookup* ParseMetadataItem(const
float userrating = 0;
QDate releasedate;
QDateTime lastupdated;
+ QDateTime lastwatched;
PeopleMap people;
ArtworkMap artwork;

@@ -226,6 +230,9 @@ MetadataLookup* ParseMetadataItem(const
lastupdated = RFC822TimeToQDateTime(item.
firstChildElement("lastupdated").text());

+ lastwatched = RFC822TimeToQDateTime(item.
+ firstChildElement("lastwatched").text());
+
userrating = item.firstChildElement("userrating").text().toFloat();
tracknum = item.firstChildElement("tracknum").text().toUInt();
popularity = item.firstChildElement("popularity").text().toUInt();
@@ -365,8 +372,7 @@ MetadataLookup* ParseMetadataItem(const
tagline, description, season, episode, certification, countries,
popularity, budget, revenue, album, tracknum, system, year,
releasedate, lastupdated, runtime, runtimesecs, inetref,
- tmsref, imdb, people, studios, homepage, trailerURL, artwork,
- DownloadMap());
+ tmsref, imdb, lastwatched, people, studios, homepage, trailerURL, artwork, DownloadMap());
}

PeopleMap ParsePeople(QDomElement people)
--- /usr/ports/multimedia/mythtv/work/mythtv-0.24.1/libs/libmythmetadata/metadatacommon.h 2011-05-16 06:57:52.000000000 +1000
+++ libs/libmythmetadata/metadatacommon.h 2011-10-31 20:05:59.000000000 +1000
@@ -119,12 +119,13 @@ class MPUBLIC MetadataLookup : public QO
QString inetref,
QString tmsref,
QString imdb,
+ const QDateTime lastwatched,
const PeopleMap people,
const QStringList studios,
const QString homepage,
const QString trailerURL,
const ArtworkMap artwork,
- DownloadMap downloads);
+ DownloadMap downloads );

void toMap(MetadataMap &map);

@@ -273,6 +274,8 @@ class MPUBLIC MetadataLookup : public QO
QString m_tmsref;
QString m_imdb;

+ const QDateTime m_lastwatched;
+
// People - Video
const PeopleMap m_people;
const QStringList m_studios;
--- /usr/ports/multimedia/mythtv/work/mythtv-0.24.1/libs/libmyth/programinfo.cpp 2011-05-16 06:57:52.000000000 +1000
+++ libs/libmyth/programinfo.cpp 2011-10-31 17:32:40.000000000 +1000
@@ -2310,12 +2310,9 @@ void ProgramInfo::SaveWatched(bool watch

MSqlQuery query(MSqlQuery::InitCon());
query.prepare("UPDATE videometadata"
- " SET watched = :WATCHEDFLAG"
- " WHERE title = :TITLE"
- " AND subtitle = :SUBTITLE"
- " AND filename = :FILENAME ;");
- query.bindValue(":TITLE", title);
- query.bindValue(":SUBTITLE", subtitle);
+ " SET watched = :WATCHEDFLAG,"
+ " lastwatched = NOW()"
+ " WHERE filename = :FILENAME ;");
query.bindValue(":FILENAME", url);
query.bindValue(":WATCHEDFLAG", watched);

--- /usr/ports/multimedia/mythtv/work/mythtv-0.24.1/libs/libmythmetadata/videometadata.cpp 2011-05-16 06:57:52.000000000 +1000
+++ libs/libmythmetadata/videometadata.cpp 2011-11-03 10:58:37.000000000 +1000
@@ -100,6 +100,7 @@ class VideoMetadataImp
const QString &plot, float userrating,
const QString &rating, int length,
int season, int episode, const QDate &insertdate,
+ const QDateTime &lastwatched,
int id, ParentalLevel::Level showlevel, int categoryID,
int childID, bool browse, bool watched,
const QString &playcommand, const QString &category,
@@ -116,7 +117,7 @@ class VideoMetadataImp
m_screenshot(screenshot), m_banner(banner), m_fanart(fanart),
m_host(host), m_categoryID(categoryID), m_childID(childID),
m_year(year), m_releasedate(releasedate), m_length(length), m_season(season),
- m_episode(episode), m_insertdate(insertdate), m_showlevel(showlevel),
+ m_episode(episode), m_insertdate(insertdate), m_lastwatched(lastwatched), m_showlevel(showlevel),
m_browse(browse), m_watched(watched), m_id(id),
m_userrating(userrating), m_processed(processed)
{
@@ -174,6 +175,7 @@ class VideoMetadataImp
m_userrating = rhs.m_userrating;
m_host = rhs.m_host;
m_processed = rhs.m_processed;
+ m_lastwatched = rhs.m_lastwatched;

// No DB vars
m_sort_key = rhs.m_sort_key;
@@ -318,6 +320,8 @@ class VideoMetadataImp
bool GetProcessed() const { return m_processed; }
void SetProcessed(bool processed) { m_processed = processed; }

+ QDateTime GetLastwatched() const { return m_lastwatched; }
+
////////////////////////////////

void SaveToDatabase();
@@ -373,6 +377,7 @@ class VideoMetadataImp
int m_season;
int m_episode;
QDate m_insertdate;
+ QDateTime m_lastwatched;
ParentalLevel::Level m_showlevel;
bool m_browse;
bool m_watched;
@@ -463,7 +468,7 @@ void VideoMetadataImp::Reset()
QString(), VIDEO_PLOT_DEFAULT, 0.0,
VIDEO_RATING_DEFAULT, 0,
VideoMetadata::FilenameToMeta(m_filename, 2).toInt(),
- VideoMetadata::FilenameToMeta(m_filename, 3).toInt(), QDate(), m_id,
+ VideoMetadata::FilenameToMeta(m_filename, 3).toInt(), QDate(),QDateTime(), m_id,
ParentalLevel::plLowest, 0, -1, true, false, "", "",
VideoMetadata::genre_list(), VideoMetadata::country_list(),
VideoMetadata::cast_list(), m_host, false);
@@ -573,6 +578,7 @@ void VideoMetadataImp::fromDBRow(MSqlQue
m_host = query.value(29).toString();
m_insertdate = query.value(30).toDate();
m_processed = query.value(31).toBool();
+ m_lastwatched = query.value(32).toDateTime();

VideoCategory::GetCategory().get(m_categoryID, m_category);

@@ -1069,7 +1075,7 @@ VideoMetadata::VideoMetadata(const QStri
int year, const QDate &releasedate, const QString &inetref,
const QString &homepage, const QString &director, const QString &studio,
const QString &plot, float userrating, const QString &rating,
- int length, int season, int episode, const QDate &insertdate,
+ int length, int season, int episode, const QDate &insertdate, const QDateTime &lastwatched,
int id, ParentalLevel::Level showlevel, int categoryID,
int childID, bool browse, bool watched,
const QString &playcommand, const QString &category,
@@ -1081,7 +1087,7 @@ VideoMetadata::VideoMetadata(const QStri
m_imp = new VideoMetadataImp(filename, hash, trailer, coverfile, screenshot, banner,
fanart, title, subtitle, tagline, year, releasedate, inetref,
homepage, director, studio, plot, userrating, rating, length,
- season, episode, insertdate, id, showlevel, categoryID, childID,
+ season, episode, insertdate, lastwatched, id, showlevel, categoryID, childID,
browse, watched, playcommand, category, genres, countries, cast,
host, processed);
}
@@ -1222,6 +1228,7 @@ void VideoMetadata::toMap(MetadataMap &m
metadataMap["browseable"] = GetDisplayBrowse(GetBrowse());
metadataMap["watched"] = GetDisplayWatched(GetWatched());
metadataMap["processed"] = GetDisplayProcessed(GetProcessed());
+ metadataMap["lastwatched"] = GetLastwatched().toString(gCoreContext->GetSetting("DateFormat"));
metadataMap["category"] = GetCategory();
}

@@ -1262,6 +1269,7 @@ void ClearMap(MetadataMap &metadataMap)
metadataMap["watched"] = "";
metadataMap["category"] = "";
metadataMap["processed"] = "";
+ metadataMap["lastwatched"] = "";
}

bool VideoMetadata::HasSortKey() const
@@ -1499,6 +1507,11 @@ void VideoMetadata::SetProcessed(bool pr
m_imp->SetProcessed(processed);
}

+QDateTime VideoMetadata::GetLastwatched() const
+{
+ return m_imp->GetLastwatched();
+}
+
const QString &VideoMetadata::GetPlayCommand() const
{
return m_imp->getPlayCommand();
--- /usr/ports/multimedia/mythtv/work/mythtv-0.24.1/libs/libmythmetadata/videometadata.h 2011-05-16 06:57:52.000000000 +1000
+++ libs/libmythmetadata/videometadata.h 2011-10-31 19:57:02.000000000 +1000
@@ -79,6 +79,7 @@ class MPUBLIC VideoMetadata
int season = 0,
int episode = 0,
const QDate &insertdate = QDate(),
+ const QDateTime &lastwatched = QDateTime(),
int id = 0,
ParentalLevel::Level showlevel = ParentalLevel::plLowest,
int categoryID = 0,
@@ -170,6 +171,8 @@ class MPUBLIC VideoMetadata
bool GetProcessed() const;
void SetProcessed(bool processed);

+ QDateTime GetLastwatched() const;
+
const QString &GetPlayCommand() const;
void SetPlayCommand(const QString &playCommand);

--- /usr/ports/multimedia/mythtv/work/mythtv-0.24.1/libs/libmythmetadata/videometadatalistmanager.cpp 2011-05-16 06:57:52.000000000 +1000
+++ libs/libmythmetadata/videometadatalistmanager.cpp 2011-10-31 17:46:15.000000000 +1000
@@ -115,7 +115,7 @@ void VideoMetadataListManager::loadAllFr
"userrating, length, filename, hash, showlevel, "
"coverfile, inetref, homepage, childid, browse, watched, "
"playcommand, category, intid, trailer, screenshot, banner, fanart, "
- "subtitle, tagline, season, episode, host, insertdate, processed "
+ "subtitle, tagline, season, episode, host, insertdate, processed,lastwatched "
" FROM videometadata");

query.prepare(BaseMetadataQuery);
--- /usr/ports/multimedia/mythtv/work/mythtv-0.24.1/libs/libmythmetadata/videoscan.cpp 2011-05-16 06:57:52.000000000 +1000
+++ ./libs/libmythmetadata/videoscan.cpp 2011-10-31 19:58:26.000000000 +1000
@@ -278,7 +278,7 @@ class VideoScannerThread : public QThrea
0.0, VIDEO_RATING_DEFAULT, 0,
VideoMetadata::FilenameToMeta(p->first, 2).toInt(),
VideoMetadata::FilenameToMeta(p->first, 3).toInt(),
- QDate::currentDate(),
+ QDate::currentDate(), QDateTime::currentDateTime(),
0, ParentalLevel::plLowest);

VERBOSE(VB_GENERAL, QString("Adding : %1 : %2 : %3")
--- /usr/ports/multimedia/mythtv/work/mythtv-0.24.1/programs/mythfrontend/networkcontrol.cpp 2011-05-16 06:57:52.000000000 +1000
+++ programs/mythfrontend/networkcontrol.cpp 2011-11-26 11:20:51.000000000 +1000
@@ -1186,7 +1186,9 @@ void NetworkControl::customEvent(QEvent
NetworkControlClient * ncc = nc->getClient();
if (ncc)
{
- sendReplyToClient(ncc, reply);
+ int index = clients.indexOf(ncc);
+ if (index >= 0)
+ sendReplyToClient(ncc, reply);
}
else //send to all clients
{

No comments: