Automate the mundane for sanity sake (part 3)

The other day I noticed that many of the records in my local My Movies database were missing the DVD release date, I also noticed that most of them had their Disc IDs, Disc IDs are 64 bit CRCs calculated over content on a disc; there is a algorithm used for DVDs and another used for CDs.

In the case of DVDs the IDvdInfo2::GetDiscID method in the DirectX 9 classes give you access to this value, but I digress.

With the above knowledge in hand I decided to write a script that looks up the release date on the windows media website based on the DVD Id in the my movies database, if the result I got back had a title that matched what I had in the database it was OK to update the release date.

So how did I go about doing this? well I enabled a sniffer, inserted a DVD, opened Windows Media Player and saw it make a outgoing connection to metaservices.windowsmedia.com.

Then I took a copy of netcat, had it bind to the appropriate port on localhost, updated my host file so that it pointed metaservices.windowsmedia.com at my instance of netcat and captured the request (I knew being a security consultant could come in handy some day ).

Turns out its a simple HTTP GET with the DVD Id on the query string, so with this tidbit of information I removed the host file entry I added then replayed the captured request (the simple get), this got me back a XML document (a dvdid.xml, see dvdxml.com for more information on these) that described the movie and voila there is the DVD release date we needed.

OK, now to understand the database layout used by my movies, I open up my handy dandy copy of Access and see a tblDiscs with a nvcDiscIdSideA field, match these two up and I should be good to go.

Long story short, I put together the bellow script and got most of my release dates filled in.

Function GetDVDMDR(szDVDId)
 Dim szUrl, szSvrName, szVersion, szLocal, oXML
 Dim oHttp

 szSvrName = "metaservices.windowsmedia.com"
 szLocale = Hex(GetLocale())
 szVersion = "10.0.0.3646"
 'szUrl="http://" & szSvrName & "/dvdwizard/DVDWizard.asp?locale=" & szLocale & "&version=" & szVersion & "&dvdid=" & szDVDId
 szUrl="http://" & szSvrName & "/dvdinfo/GetMDRDVD.asp?dvdid=" & szDVDId & "&version=" & szVersion & "&locale=" & szLocale & "&requestid=B1D219EA-4FC8-40- 9F-BF05-D52E0FED2FDB"

 Set oHttp = CreateObject("Microsoft.XMLHTTP")
 oHttp.open "GET", szURL, FALSE
 oHttp.setRequestHeader "Content-Type","text/xml"
 oHttp.send ""

 set oXML = oHttp.responseXML

 Set GetDVDMDR = oXML
End Function

Function GetTextFromNode(oXML, szNode)
 Dim oNode

 if oXML is nothing = False Then
  Set oNode = oXML.selectSingleNode(szNode)
 
  if oNode is nothing = False Then
   GetTextFromNode = oNode.text
  End If
 End If
End Function

Function CleanUpTitle(szTitle)
 Dim iPos
 ' Remove all [] be lazy and assume if we see a [ its the end of the title.
 iPos = Instr(1, szTitle, "[") - 1

 If iPos>0 Then
  szTitle = Mid(szTitle, 1,iPos)
 End If

 ' Remove all () be lazy and assume if we see a ( its the end of the title.
 iPos = Instr(1, szTitle, "(") - 1

 If iPos>0 Then
  szTitle = Mid(szTitle, 1,iPos)
 End If

 CleanUpTitle = Trim(szTitle)
End Function

Function MyFormatDate(szDate)
 Dim iYear, iDay, iMonth, iPos, iPos2

 iYear = Trim(Mid(szDate, 1, 4))
 
 iMonth = Trim(Mid(szDate, 6, 2))

 iDay = Trim(Mid(szDate, 9, 2))

 if iYear <> "" AND iDay <> "" AND iMonth <> "" Then
  MyFormatDate = iMonth & "/" & iDay & "/" & iYear 
 Else
  MyDormatDate = ""
 End If
End Function


'Setup Logging
Dim oFSO, oFile, ForWriting
Dim szGile

ForWriting = 2
szFile = "C:\test.log"

' Create the File System Object and the log file
Set oFSO = CreateObject("Scripting.FileSystemObject")

Set oFile = oFSO.CreateTextFile(szFile)

'Define Constants
Dim dbroot, dbfile, dbname
dbroot = "\\mce-server\Movies\My Movies"
dbfile = "mymovies.mdb"

' Define Variables
Dim szDVDId, oXML, oDVDXML
Dim DbEngine, Currentdb, RecordSet, sQuery
Dim bIsOKDVDXML, bIsRoughlyConsistent

' Open DB
Set DbEngine = CreateObject("DAO.DbEngine.36")
Set CurrentDb = DbEngine.OpenDatabase(dbroot & "\" & dbfile, False, False)

' Find all titles 
sQuery = "SELECT tblDiscs.nvcDiscIdSideA, tblDiscs.nvcLocation, tblTitles.nvcOriginalTitle, tblTitles.datDVDRelease FROM tblTitles INNER JOIN tblDiscs ON tblTitles.intID = tblDiscs.intTitle;"
Set RecordSet = CurrentDb.OpenRecordset(sQuery)

' Enumerate through all found titles and if appropriate get the dvd release date
While Not RecordSet.EOF
 szDVDId = RecordSet("nvcDiscIdSideA")

 if szDVDId <> "" Then
  ' My Movies stores the DiscId wrong, fix-it
  WScript.Echo "Looking up metadata for '" & szDVDId & "'"
  szDVDId=Replace(szDVDId , "-", "|")

  ' Lookup the WM metadata for this discid
  Set oXML=GetDVDMDR(szDVDId)

  Set oDVDXML=oXML.selectSingleNode("//METADATA/MDR-DVD")

  ' Check to see if this is a OK dvdid.xml
  ' OK dvdid's have title, releasedate, mpaaa and genre IMHO
  szTitle = Trim(GetTextFromNode(oDVDXML, "//dvdTitle"))
  szReleaseDate = MyFormatDate(GetTextFromNode(oDVDXML, "//releaseDate"))
  szMPAARating = Trim(GetTextFromNode(oDVDXML, "//MPAARating"))
  szGenre = Trim(GetTextFromNode(oDVDXML, "//genre"))

  if (szTitle = "" AND szReleaseDate = "" AND szMPAARating = "" AND szGenre = "") Then
   bIsOKDVDXML=False
   oFile.WriteLine("XML Empty or Bad," & szTitle &"," & szDVDId)
  Else
   bIsOKDVDXML=True
  End If

  ' Check if data in DB and in XML is roughly consitent, eg title match (lame), smarts later
  if CleanUpTitle(szTitle) = RecordSet("nvcOriginalTitle") Then
   bIsRoughlyConsistent = True
  Else
   bIsRoughlyConsistent = False
   oFile.WriteLine("Not Roughly Consistent," & szTitle &"," & szDVDId)
  End If

  ' If above is OK save xml to tblDiscs.nvcLocation?

  ' If above is OK check if we need to update MPAA, Genre, Release Date
  if bIsRoughlyConsistent = True Then
   ' 11/7/2006 cars
   If IsNull(RecordSet("datDVDRelease")) Then
    If szReleaseDate <> "" then
     WScript.Echo " ! Updating date in record..."
     RecordSet.Edit()
     RecordSet("datDVDRelease").Value = szReleaseDate
     RecordSet.Update()
     oFile.WriteLine("Updated Date," & szTitle & "," & szDVDId)
    End If
   End If
  End If  

  ' Debug print
  If bIsOKDVDXML = True Then
   WScript.Echo " Title       : " & szTitle
   WScript.Echo " Title [clean] : " & CleanUpTitle(szTitle)
   WScript.Echo " Release Date  : " & szReleaseDate
   WScript.Echo " MPAA Rating   : " & szMPAARating
   WScript.Echo " Genre       : " & szGenre
   WScript.Echo " Is Consistent : " & bIsRoughlyConsistent
   'WScript.Echo oDVDXML.xml
  End If
 End If
     RecordSet.MoveNext
Wend

Set RecordSet = Nothing
oFile.Close

 

I should make note that although this is just simulating the same sort of transaction that happens on disc insertion with Windows Media Player, and provides access tot he same information the Media Player SDK provides I have not confirmed the terms of use with of the web service with Microsoft so dont presume because I posted this its OK to do what I did, this just represents me blowing a couple hours while my wife was shopping .

Print | posted on Monday, March 12, 2007 9:01 PM

Feedback

No comments posted yet.
Title  
Name  
Email
Url
Comments   
Please add 7 and 4 and type the answer here: