Ask TiVo's MFS database for your Now Showing List, including title, description, and date and time the show aired.
Curious about what's showing? Want to keep track of your television viewing habits (or at least what's been recorded for you) over time? You can ask the TiVo MFS with some pretty trivial data mining. We'll start with the Now Showing List and everything TiVo knows about the shows we currently have queued up for watching. We'll write the title, description, and date and time the show aired to a file and save it. You can even automate this using cron [Hack #44] and write the files to your PC's NFS-mounted [Hack #56] drive if you are truly serious about archiving that data.
Let's go over what we already know. We know that recorded programs are all held in /Recording/NowShowingByTitle, and we know that each of these programs has all the information we want somewhere in its closure of objects. Therefore, we can easily find the date the show aired, the name of the program, and the name of the episode.
Before we write the code, let's actually find all this information in the closure listed in [Hack #89]. The date and time the show aired are listed in the top Recording object under StartDate and StartTime; conveniently, this is listed under the FSID of the object in /Recording/NowShowingByTitle. The rest of the information seems to be in the Program object. The path between the Recording object and the Program object seems to pass through Showing. We want to grab the Recording object, follow through the Showing attribute to a Showing object, and follow that out to a Program attribute.
Seems simple enough. All we need to do is express this in Tcl. The heart of the program just makes use of mfs commands to maneuver through the directories and then uses dbobj commands to dig into the database. To get a rundown of some of the commands that people know about (remember that these things are discovered, not documented), take a gander at Table 7-2 and Table 7-3.
Filesystem command |
Purpose |
---|---|
mfs find <path> |
Look for an item in the MFS and return its FSID and type |
mfs mkdir <path> |
Make a named directory |
mfs rmdir <path> |
Remove a named directory |
mfs streamsize <fsid> |
Get the size of a recording stream |
mfs moddate <fsid> |
Return the last time an object was modified, in seconds since the Unix epoch time |
mfs size <fsid> |
Return the size of a given MFS object |
mfs scan <path> [-start string] [-count number] [-backward] |
List up to a certain number of items in a specific MFS directory that optionally starts with a specified string |
Database object command |
Purpose |
---|---|
dbobj equal <dbobj> <dbobj> |
Test the equality of two database objects |
dbobj <dbobj> fsid |
Return the FSID of a database object |
dbobj <dbobj> subobjid |
Return the subobjid of a database object |
dbobj <dbobj> type |
Return the type of a database object |
dbobj <dbobj> attrs |
Return the attributes of a database object |
Dbobj <dbobj> attrtype <attr> |
Get the type of an attribute of a database |
dbobj <dbobj> get [-noerror] <attr> [<index>] |
Get the value of a specific attribute of this type |
dbobj <dbobj> add <attr> <tclobj> |
Append an attribute of a given name to a database object |
Dbobj <dbobj> remove <attr> [<tclobj>] |
Remove the last attribute of a given name from a database object |
dbobj <dbobj> delete |
Delete a particular database object (be careful with this one) |
dbobj <dbobj> clear |
Clear out a particular database object |
dbobj <dbobj> removeat <attr> <index> |
Remove a specific attribute from a database object. The index is used when there are multiple attributes with the same name |
dbobj <dbobj> copyfrom <dbobj> |
Copy a database object |
|
#!/tvbin/tivosh # include code to do a timezone conversion back into our time format source /var/hack/lib/tcl/tivotime.tcl # open the database set db [dbopen] # pull out the first 50 recorded shows from the database set recdir "/Recording/NowShowingByTitle" transaction { set files [mfs scan $recdir -count 50] } while { [llength $files] > 0 } { # iterate through the shows we extracted foreach rec $files { # grab the FSID of the program from the list set fsid [lindex $rec 0] transaction { # get the object that represents this recording and the # object that represents this episode. set recordingobj [db $db openid $fsid] set episodeobj [dbobj [dbobj $recordingobj get Showing][RETURN] get Program] # pull out the date the show aired # convert it to something a bit more # human-readable using the tivotime library set showtime [::tivotime::converttime \ [dbobj $recordingobj get StartDate] \ [dbobj $recordingobj get StartTime] ] set showtime [clock format $showtime -format "%m/%d/%Y %H:%M"] # pull out the show's name and episode title regsub -all "\[\{\}\]" [dbobj $episodeobj get Title] ""[RETURN] programname regsub -all "\[\{\}\]" [dbobj $episodeobj get[RETURN] EpisodeTitle] episodename } # output a pipe (|) delimited list containing the date, # show name, and episode title puts "$showtime | $programname | $episodename" } # and grab the next 50 television shows set lastName [lindex [lindex $files end] 1] transaction { set files [mfs scan $recdir -start $lastName -count 50] } if { $lastName == [lindex [lindex $files 0] 1] } { set files [lrange $files 1 end] } }
Save the code as nowshowing.tcl in TiVo's /var/hack/bin directory and make it executable:
bash-2.02# chmod 755 /var/hack/bin/nowshowing.tcl
From TiVo's command line Section 3.3, invoke the script, like so:
bash-2.02# /var/hack/bin/nowshowing.tcl 06/07/2003 21:29 | 2003 MTV Movie Awards | 05/20/2003 19:59 | 24 | Day 2: 7:00 - 8:00AM 06/05/2003 18:59 | The Amazing Race 4 | It Doesn't Say Anything About First Come, First Served. And We're Bigger 12/02/2001 15:59 | The Armenians: A Story of Survival | 06/02/2003 01:59 | Coming Attractions | 05/14/2003 18:59 | Dawson's Creek | All Good Things ... Must Come to an End 05/07/2003 18:59 | Dawson's Creek | Joey Potter and Capeside Redemption 04/30/2003 18:59 | Dawson's Creek | Goodbye, Yellow Brick Road 04/16/2003 18:59 | Dawson's Creek | Lovelines 04/09/2003 18:59 | Dawson's Creek | Love Bites 02/12/2003 19:59 | Dawson's Creek | Castaways 02/05/2003 19:59 | Dawson's Creek | Clean and Sober 01/15/2003 19:59 | Dawson's Creek | Day Out of Days 12/11/2002 19:59 | Dawson's Creek | Merry Mayhem 11/20/2002 19:59 | Dawson's Creek | Everything Put Together Falls Apart 11/13/2002 19:59 | Dawson's Creek | Spiderwebs 11/06/2002 19:59 | Dawson's Creek | Ego Tripping at the Gates of Hell 10/30/2002 19:59 | Dawson's Creek | Living Dead Girl 10/23/2002 18:59 | Dawson's Creek | The Impostors 10/16/2002 18:59 | Dawson's Creek | Instant Karma! 06/07/2003 02:59 | East Meets West | Sushi 303 06/04/2003 14:29 | Epicurious | Dim Sum 06/05/2003 01:29 | Food 911 | Two Guys, a Girl and a Brisket! 06/04/2003 01:29 | Food 911 | Empanadas to Go 06/02/2003 19:59 | For Love or Money | 06/05/2003 03:29 | The Galloping Gourmet | Mantay 05/13/2003 18:59 | Gilmore Girls | Here Comes the Son 05/06/2003 18:59 | Gilmore Girls | Say Goodnight, Gracie 06/04/2003 15:29 | Great Chefs of the World | Stuffed Mushrooms; Hazelnut Napoleon 06/04/2003 14:59 | Great Chefs of the World | Shrimp Ceviche; Lamb; Banana Pudding 04/18/2003 19:59 | John Doe | Remote Control 06/04/2003 19:59 | Junkyard Wars | Manic Mud Racers 06/06/2003 23:37 | Late Night With Conan O'Brien | 05/25/2003 20:59 | Single in the Hamptons | 03/02/2003 16:59 | Smallville | Rosetta 02/23/2003 16:59 | Smallville | Fever 02/16/2003 16:59 | Smallville | Prodigal 02/09/2003 16:59 | Smallville | Rush 06/08/2003 14:59 | Star Trek: The Next Generation | A Fistful of Datas 05/07/2003 19:59 | The West Wing | Commencement 04/23/2003 19:59 | The West Wing | Evidence of Things Not Seen 02/26/2003 20:59 | The West Wing | Red Haven's on Fire 02/19/2003 20:59 | The West Wing | California 47th
To capture the Now Playing List as a pipe-delimited text file, use the > redirect symbol and supply the name of a file to which to write. For example, sending output to a file called nowshowing.out in the /var/out directory would look like this:
bash-2.02# /var/hack/bin/nowshowing.tcl > /var/out/nowshowing.out
Top |