[mythtv] [PATCH] abstract IMDB queries into external scripts

Tim Harvey tharvey at alumni.calpoly.edu
Mon Jan 19 06:10:20 EST 2004


Attached is a patch that abstracts out the IMDB queries in the MythVideo
plugin and supports the functionality via external scripts.  There are 3
files:
   Mythvideo.txt - patch for videomanager.cpp/.h and mythvideo.pro
   Scripts.bz2 - default imdb script and readme.  Extract in the
mythvideo directory with a 'tar -xjvf scripts.bz2' before you do a 'make
install'.

(By the way, I create my patches using cvs -diff, but this doesn't seem
to deal with new files such as the scripts.  How can I take care of this
so that the new files get created with the patch?)

I've patched the MythVideo Makefile so that it creates a directory for
the scripts in /usr/local/share/mythtv/mythvideo/scripts.

The actual IMDB query functionally should not have 'changed' with this
patch, just the underlying architecture changes.  This will allow easier
updates to the IMDB query if say they change things 'again' and it
breaks.  No recompiles will be needed.  In addition alternate scripts
could be created which use other sites or different types of queries.

Please let me know what you think.  Any feedback is greatly appreciated.

If the general consensus is that this is a good thing, I'll followup
with some enhancements to the script and a settings menu to allow the
choosing of available scripts etc.

Tim
-------------- next part --------------
? mythvideo/scripts
Index: mythvideo/mythvideo.pro
===================================================================
RCS file: /var/lib/mythcvs/mythvideo/mythvideo/mythvideo.pro,v
retrieving revision 1.15
diff -u -r1.15 mythvideo.pro
--- mythvideo/mythvideo.pro	30 Oct 2003 06:40:54 -0000	1.15
+++ mythvideo/mythvideo.pro	19 Jan 2004 11:03:16 -0000
@@ -16,8 +16,10 @@
 installfiles.files = videomenu.xml video_settings.xml
 installimages.path = $${PREFIX}/share/mythtv/themes/default
 installimages.files = images/*.png
+installimages.path = $${PREFIX}/share/mythtv/mythvideo/scripts
+installimages.files = scripts/*
 
-INSTALLS += installfiles uifiles installimages
+INSTALLS += installfiles uifiles installimages installscripts
 
 # Input
 
Index: mythvideo/videomanager.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythvideo/mythvideo/videomanager.cpp,v
retrieving revision 1.24
diff -u -r1.24 videomanager.cpp
--- mythvideo/videomanager.cpp	18 Jan 2004 17:34:04 -0000	1.24
+++ mythvideo/videomanager.cpp	19 Jan 2004 11:03:16 -0000
@@ -35,7 +35,7 @@
 
     noUpdate = false;
     curIMDBNum = "";
-    ratingCountry = "USA";
+    ratingCountry = gContext->GetSetting("MovieRatingCountry", "USA");
     curitem = NULL;
     curitemMovie = "";
     can_do_page_down = false;
@@ -204,6 +204,7 @@
     updateML = false;
 }
 
+/*
 // Replace the numeric character references
 // See http://www.w3.org/TR/html4/charset.html#h-5.3.1
 static void replaceNumCharRefs(QString &str)
@@ -340,6 +341,7 @@
     return listing;
 
 }
+*/
 
 void VideoManager::updateBackground(void)
 {
@@ -358,6 +360,7 @@
     setPaletteBackgroundPixmap(myBackground);
 }
 
+// Copy movie poster to appropriate directory and return full pathname to it
 QString VideoManager::GetMoviePoster(QString movieNum)
 {
     QString movieFile = curitem->Filename();
@@ -382,6 +385,18 @@
     if (movieNum == "Local")
         return(QString("<NULL>"));
 
+    // Obtain movie poster
+    QString exec = gContext->GetSetting("MoviePosterCommandLine", 
+              "/usr/local/share/mythtv/mythvideo/scripts/imdb.pl -P");
+    exec += " " + movieNum;
+
+    // execute external command to obtain url of movie poster
+    QStringList posterurls = QStringList::split('\n', executeExternal(exec));
+    QString filename = "";
+    if (posterurls.size() > 0)
+       filename = posterurls[0];
+
+/*
     QString host = "www.imdb.com";
     QString path = "";
 
@@ -448,6 +463,7 @@
         cout << "MyhVideo: Error parsing poster filename.\n";
         return filename;
     }
+*/
 
     char *home = getenv("HOME");
     QString fileprefix = QString(home) + "/.mythtv";
@@ -462,21 +478,61 @@
     if (!dir.exists())
         dir.mkdir(fileprefix);
 
-    //cout << "Copying (" << filename << ")...";
+    if (debug > 0) {
+        cout << "Copying (" << filename << ")...";
+    }
     QUrlOperator *op = new QUrlOperator();
-    op->copy(QString("http://" + host + path + filename),
-             "file:" + fileprefix);
-    //cout << "Done.\n";
+//    op->copy(QString("http://" + host + path + filename),
+//             "file:" + fileprefix);
+    op->copy(filename, "file:" + fileprefix);
+    if (debug > 0) {
+        cout << "Done.\n";
+    }
 
     filename = filename.right(filename.length() - filename.findRev("/") - 1);
     fileprefix = fileprefix + "/" + filename;
 
     return fileprefix;
-
 }
 
 void VideoManager::GetMovieData(QString movieNum)
 {
+    QString exec = gContext->GetSetting("MovieDataCommandLine", 
+              "/usr/local/share/mythtv/mythvideo/scripts/imdb.pl -D");
+    exec += " " + movieNum;
+
+    // execute external command to obtain list of possible movie matches 
+    QString results = executeExternal(exec);
+
+    // parse results
+    QMap<QString,QString> data;
+    QStringList lines = QStringList::split('\n', results);
+    if (lines.size() > 0) {
+        for (QStringList::Iterator it = lines.begin();it != lines.end(); ++it) {
+            int sep = (*it).find(':');
+            QString name = (*it).left(sep);
+            QString vale = (*it).mid(sep+1);
+            data[name] = vale;
+        }
+        // set known values 
+        curitem->setTitle(data["Title"]);
+        curitem->setYear(data["Year"].toInt());
+        curitem->setDirector(data["Director"]);
+        curitem->setPlot(data["Plot"]);
+        curitem->setUserRating(data["UserRating"].toFloat());
+        curitem->setRating(data["MovieRating"]);
+        curitem->setLength(data["Runtime"].toInt());
+        curitem->setInetRef(movieNumber);
+        QString movieCoverFile = "";
+        movieCoverFile = GetMoviePoster(movieNumber);
+        curitem->setCoverFile(movieCoverFile);
+    } else {
+        ResetCurrentItem();
+    }
+
+    curitem->updateDatabase(db);
+    RefreshMovieList();
+/*
     movieNumber = movieNum;
     QString host = "www.imdb.com";
 
@@ -490,12 +546,63 @@
     //cout << "Outputting Movie Data Page\n" << res << endl;
 
     ParseMovieData(res);
+*/
+}
+
+// Execute an external command and return results in string
+QString VideoManager::executeExternal(QString cmdline) 
+{
+    FILE* pipe = popen(cmdline.latin1(), "r");
+    char line[500];
+    QString ret;
+    while (fgets(line, sizeof(line)-1, pipe)) {
+       ret += line; 
+    } 
+    pclose(pipe);
+    if (debug > 0) {
+        cout << "Executed: '" << cmdline << "': " << ret.length() 
+             << " byte result:\n" << ret << "<END>" << endl;
+    }
+
+    return ret;
 }
 
-// Obtain a movie listing via popular website(s)
+// Obtain a movie listing via popular website(s) and populates movieList map
+//   returns: -1 - 0 matches
+//             1 - only 1 match, movieNumber set to id 
+//             2 - more than 1 possible match movieList populates with id/name's
 int VideoManager::GetMovieListing(QString movieName)
 {
     int ret = -1;
+
+    QString exec = gContext->GetSetting("MovieListCommandLine", 
+              "/usr/local/share/mythtv/mythvideo/scripts/imdb.pl -M");
+    exec += " " + movieName;
+
+    // execute external command to obtain list of possible movie matches 
+    QString results = executeExternal(exec);
+
+    // parse results
+    movieList.clear();
+    QStringList lines = QStringList::split('\n', results);
+    if (lines.size() > 0) {
+        for (QStringList::Iterator it = lines.begin();it != lines.end(); ++it) {
+            int sep = (*it).find(':');
+            QString movieid = (*it).left(sep);
+            QString moviename = (*it).mid(sep+1);
+
+            // if only a single match, assume this is it
+            if (lines.size() == 1) {
+                movieNumber = movieid;
+                return 1;
+            }
+            movieList[movieid] = moviename;
+        }
+    } else {
+       return -1;
+    }
+
+/*
     QString host = "us.imdb.com";
     theMovieName = movieName;
 
@@ -509,8 +616,7 @@
     isbusy = false;
 
     // If URL has been redirected to a movie then it was an only match 
-    if (url.find("title/tt") != -1) 
-    {
+    if (url.find("title/tt") != -1) {
         int fnd = url.find("title/tt") + 8;
         movieNumber = url.mid(fnd, url.findRev("/") - fnd);
         return 1;  // this does a re-request but simplest for now
@@ -546,6 +652,7 @@
             //cout << it.data() << endl;
         }
     }
+*/
 
     movieList["manual"] = tr("Manually Enter IMDB #");
     movieList["reset"] = tr("Reset Entry");
@@ -555,6 +662,7 @@
     return ret;
 }
 
+/*
 void VideoManager::ParseMovieData(QString data)
 {
     movieTitle = parseData(data, "<title>", "(");
@@ -586,16 +694,16 @@
     QString movieCoverFile = "";
     movieCoverFile = GetMoviePoster(movieNumber);
 
-    /*
-    cout << "      Title:\t" << movieTitle << endl;
-    cout << "       Year:\t" << movieYear << endl;
-    cout << "   Director:\t" << movieDirector << endl;
-    cout << "       Plot:\t" << moviePlot << endl;
-    cout << "User Rating:\t" << movieUserRating << endl;
-    cout << "     Rating:\t" << movieRating << endl;
-    cout << "    Runtime:\t" << movieRuntime << endl;
-    cout << " Cover File:\t" << movieCoverFile << endl;
-    */
+    if (debug > 0) {
+       cout << "      Title:\t" << movieTitle << endl;
+       cout << "       Year:\t" << movieYear << endl;
+       cout << "   Director:\t" << movieDirector << endl;
+       cout << "       Plot:\t" << moviePlot << endl;
+       cout << "User Rating:\t" << movieUserRating << endl;
+       cout << "     Rating:\t" << movieRating << endl;
+       cout << "    Runtime:\t" << movieRuntime << endl;
+       cout << " Cover File:\t" << movieCoverFile << endl;
+    }
 
     if (movieTitle == "<NULL>")
         ResetCurrentItem();
@@ -614,6 +722,7 @@
     curitem->updateDatabase(db);
     RefreshMovieList();
 }
+*/
 
 void VideoManager::grayOut(QPainter *tmp)
 {
@@ -1409,9 +1518,14 @@
     QPainter p(this);
     if (m_state == SHOWING_MAINWINDOW || m_state == SHOWING_EDITWINDOW)
     {
+       // TODO: TSH - I think I would rather be passing the query scripts the 
+       //       raw filename and let them decide what they want to do with it
        QString movieTitle = curitem->Title();
        movieTitle.replace(QRegExp(" "), "+");
        movieTitle.replace(QRegExp("_"), "+");
+       movieTitle.replace(QRegExp("\'"), "");
+       movieTitle.replace(QRegExp("\""), "");
+       movieTitle.replace(QRegExp("&"), "");
        m_state = SHOWING_EDITWINDOW;
  
        backup.flush();
Index: mythvideo/videomanager.h
===================================================================
RCS file: /var/lib/mythcvs/mythvideo/mythvideo/videomanager.h,v
retrieving revision 1.9
diff -u -r1.9 videomanager.h
--- mythvideo/videomanager.h	18 Jan 2004 17:34:04 -0000	1.9
+++ mythvideo/videomanager.h	19 Jan 2004 11:03:16 -0000
@@ -45,7 +45,7 @@
     void pageDown();
     void pageUp();
     void exitWin();
-    void GetMovieListingTimeOut();
+//    void GetMovieListingTimeOut();
 
   protected:
     void paintEvent(QPaintEvent *);
@@ -69,9 +69,11 @@
     XMLParse *theme;
     QDomElement xmldata;
 
+/*
     QString parseData(QString, QString, QString);
     QString parseDataAnchorEnd(QString, QString, QString);
     QMap<QString, QString> parseMovieList(QString);
+*/
     void ResetCurrentItem();
 
     void RefreshMovieList();
@@ -79,9 +81,10 @@
     void GetMovieData(QString);
     int GetMovieListing(QString);
     QString GetMoviePoster(QString);
-    void ParseMovieData(QString);
+//    void ParseMovieData(QString);
     QMap<QString, QString> movieList;
     QString curIMDBNum;
+    QString executeExternal(QString cmdline); 
 
     void updateBackground(void);
     void updateList(QPainter *);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: scripts.bz2
Type: application/octet-stream
Size: 3057 bytes
Desc: not available
Url : http://mythtv.org/pipermail/mythtv-dev/attachments/20040119/02eacd32/scripts.obj


More information about the mythtv-dev mailing list