Help with importing SageTV (Movies and TV Shows) recordings into XBMC?
#1
Question 
Could anyone point towards a means of importing sagetv recordings into xbmc with a minimum of hassle?

All the programs I've found so far are geared towards finding the episode name given the series and season/episode #'s. I'm trying to go the other way around, finding the season/episode given just the series name and episode name.

In the end, I'd like sagetv to be in the background recording shows and xbmc library pulling those episodes into the tv section.
Reply
#2
+1 for this. Does anyone have any tips for scraping sagetv recorded TV shows?
XBMC.MyLibrary (add anything to the library)
ForTheLibrary (Argus TV & XBMC Library PVR Integration)
SageTV & XBMC PVR Integration
Reply
#3
pendragon Wrote:Could anyone point towards a means of importing sagetv recordings into xbmc with a minimum of hassle?

All the programs I've found so far are geared towards finding the episode name given the series and season/episode #'s. I'm trying to go the other way around, finding the season/episode given just the series name and episode name.

In the end, I'd like sagetv to be in the background recording shows and xbmc library pulling those episodes into the tv section.

There's a program called MythicalLibrarian which is designed for MythTV but it does have a filemode where it just reads the filenames in a folder and imports into XBMC.

From Wiki:
mythicalLibrarian is a highly versitile tool designed to assign season and episode numbers to television shows based on show title and episode title so they are easily recognized by XBMC or Boxee. mythicalLibrarian interfaces with TheTvDb to gain information about the target file.
Mythbuntu doesn't need viruses - we have Sudo
Reply
#4
Thanks, but if i'm understanding the Wiki correctly, Mythical Librarian does not run on Windows. I need Windows support in this case.

Any other ideas?
XBMC.MyLibrary (add anything to the library)
ForTheLibrary (Argus TV & XBMC Library PVR Integration)
SageTV & XBMC PVR Integration
Reply
#5
I have an addon I wrote for SageTV. It doesn't import to the library, but it reads all of the metadata and presents the SageTV shows in a library-type view with descriptions, etc. It's much better than simply browsing the folder, and could be a starting point to a full scraper. I'll post it later when I'm home.
Reply
#6
Yes, I would very interested in your plugin! Please keep us posted.
XBMC.MyLibrary (add anything to the library)
ForTheLibrary (Argus TV & XBMC Library PVR Integration)
SageTV & XBMC PVR Integration
Reply
#7
bradvido88 Wrote:Thanks, but if i'm understanding the Wiki correctly, Mythical Librarian does not run on Windows. I need Windows support in this case.

Any other ideas?

Correct..you didn't mention what OS you were using and there's a Sage Linux version so you would have to run it using VMware. MythLib is the only one I've seen that does what you want. I just tried out my installation of Sickbeard which has manually processing with an Episode I renamed "Chuck - Chuck Versus the Tic Tack" but it didn't make the match in theTVDB.
Mythbuntu doesn't need viruses - we have Sudo
Reply
#8
Here is the code for my addon. A few things to note:

1) It requires having the Sage webserver and API installed as this creates the xml files with metadata
2) Since I've only been using this myself I haven't setup a proper "Settings" file yet, so you need to put your Sage server URL and port in the code (only one time at the top, and it reads it everywhere else needed), with username and password
3) In the "categories" function it calls the addDir function twice, once for all shows and once for The Daily Show. I have those as examples, you could just use the all shows to list everything, or create as many other folders as you'd like by copying the Daily Show line. You can do this with a specific show, category, or any search you can perform in the SageTV web interface. You just run the search, and then click the XML link to get the URL for the XML file. So you can have folders for a show, for the 10 most recent recordings, anything you want really.
4) One other edit you need: in the last line of the Videolinks function change the paths to whatever suits your system. This just changes the local paths in the SageTV XML to smb paths for XBMC. If you're running SageTV on the same machine it isn't needed.

I have a bunch of comments on how things are working since I was learning Python on the fly while writing this, that should help answer any questions, but let me know if something's not working and I can try to help.

ETA: To "install" this just create a folder called SageTV in your addons directory, and copy the code below into a file named Default.py and the xml file into a file called addon.xml

Code:
import urllib,urllib2,re
import xbmc,xbmcplugin,xbmcgui
from xml.dom.minidom import parse

def CATEGORIES():
        strUrl = 'http://user:password@serverIPaddress:serverport'
        addDir('All Shows', strUrl + '/sage/Recordings?xml=yes',2,'')
        addDir('The Daily Show',strUrl + '/sage/Search?searchType=TVFiles&SearchString=Daily%20show&DVD=on&sort2=airdate_asc&TimeRange=0&pagelen=100&sort1=title_asc&filename=&Video=on&search_fields=title&xml=yes',2,'')

def VIDEOLINKS(url,name):
        #Videolinks gets called immediately after adddir, so the timeline is categories, adddir, and then videolinks
        #Videolinks then calls addlink in a loop
        #print 'this is when videolinks gets called'
        # print url
        # print name
        req = urllib.urlopen(url)
        content = parse(req)    
        # Writing some code here to test xml parsing
        for showlist in content.getElementsByTagName('show'):
          strTitle = ''
          strEpisode = ''
          strDescription = ''
          strGenre = ''
          strAirdate = ''
          #print 'showlist: '+showlist[0]
          for shownode in showlist.childNodes:
            # Get the title of the show
            if shownode.nodeName == 'title':
              strTitle = shownode.toxml()
              strTitle = strTitle.replace('<title>','')
              strTitle = strTitle.replace('</title>','')
              strTitle = strTitle.replace('&amp;','&')
              #print 'showtitle: '+strTitle
            # Get the episode name
            if shownode.nodeName == 'episode':
              strEpisode = shownode.toxml()
              strEpisode = strEpisode.replace('<episode>','')
              strEpisode = strEpisode.replace('</episode>','')
              strEpisode = strEpisode.replace('&amp;','&')
              #print 'episode: '+strEpisode
            # Get the show description
            if shownode.nodeName == 'description':
              strDescription = shownode.toxml()
              strDescription = strDescription.replace('<description>','')
              strDescription = strDescription.replace('</description>','')
              strDescription = strDescription.replace('&amp;','&')
              #print 'description: '+strDescription
            # Get the category to use for genre
            if shownode.nodeName == 'category':
              strGenre = shownode.toxml()
              strGenre = strGenre.replace('<category>','')
              strGenre = strGenre.replace('</category>','')
              strGenre = strGenre.replace('&amp;','&')
              #print 'Genre: '+strGenre
            # Get the airdate to use for Aired
            if shownode.nodeName == 'originalAirDate':
              strAirdate = shownode.toxml()
              strAirdate = strAirdate.replace('<originalAirDate>','')
              strAirdate = strAirdate.replace('</originalAirDate>','')
              strAirdate = strAirdate[:10]
              #print 'Airdate: '+strAirdate
              # now that we have the title, episode, genre and description, create a showname string depending on which ones you have
              # if there is no episode name use the description in the title
            if len(strEpisode) == 0:
              strShowname = strTitle+' - '+strDescription
              strPlot = strDescription
              # else if there is an episode use that
            elif len(strEpisode) > 0:
              if name == 'All Shows' or name == 'Sports':
                strShowname = strTitle+' - '+strEpisode
              elif name != 'All Shows' and name != 'Sports':
                strShowname = strEpisode
              strPlot = strDescription
              #print strShowname
            if shownode.nodeName == 'airing':
              for shownode1 in shownode.childNodes:
                if shownode1.nodeName == 'mediafile':
                  for shownode2 in shownode1.childNodes:
                    if shownode2.nodeName == 'segmentList':
                      shownode3 =  shownode2.childNodes[1]
                      print shownode3.getAttribute('filePath')
                      strFilepath = shownode3.getAttribute('filePath')
                      addLink(strShowname,strFilepath.replace('D:\\SageTV\\','smb://sagetv/SageRecordings/'),strPlot,'',strGenre,strAirdate,strTitle)
                
def get_params():
        param=[]
        paramstring=sys.argv[2]
        if len(paramstring)>=2:
                params=sys.argv[2]
                cleanedparams=params.replace('?','')
                if (params[len(params)-1]=='/'):
                        params=params[0:len(params)-2]
                pairsofparams=cleanedparams.split('&')
                param={}
                for i in range(len(pairsofparams)):
                        splitparams={}
                        splitparams=pairsofparams[i].split('=')
                        if (len(splitparams))==2:
                                param[splitparams[0]]=splitparams[1]
                                
        return param

def addLink(name,url,plot,iconimage,genre,airdate,showtitle):
        #print 'This is when addlink gets called'
        #xbmcplugin.setContent(int(sys.argv[1]),'Episodes')
        #xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_DATE)
        # print name
        # print url
        # print plot
        # print iconimage
        ok=True
        liz=xbmcgui.ListItem(name)
        liz.setInfo( type="Video", infoLabels={ "Title": name, "Plot": plot, "Genre": genre, "aired": airdate, "TVShowTitle": showtitle } )
        ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=url,listitem=liz,isFolder=False)
        return ok


def addDir(name,url,mode,iconimage):
        #print sys.argv[0]
        # This line makes the plugin call the main default.py with three arguments, the url, the mode, and the name
        # Since it calls it with arguments, when the get_params function runs first it creates an array with the arguments in it, so that url, name, and mode get assigned in the try section
        # Then since those are assigned and now mode = 2 it calls videolinks with url and name as arguments, which then lists all the files
        u=sys.argv[0]+"?url="+urllib.quote_plus(url)+"&mode="+str(mode)+"&name="+urllib.quote_plus(name)
        #print "u: "+u
        ok=True
        liz=xbmcgui.ListItem(name)
        #liz.setInfo( type="Episodes", infoLabels={ "Title": name } )
        #liz.setIconImage('laworder.png')
        ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=liz,isFolder=True)
        return ok
        
              
params=get_params()
url=None
name=None
mode=None

try:
        url=urllib.unquote_plus(params["url"])
except:
        pass
try:
        name=urllib.unquote_plus(params["name"])
except:
        pass
try:
        mode=int(params["mode"])
except:
        pass

print "Mode: "+str(mode)
print "URL: "+str(url)
print "Name: "+str(name)

if mode==None or url==None or len(url)<1:
        print ""
        CATEGORIES()
      
elif mode==1:
        print ""+url
        INDEX(url)
        
elif mode==2:
        print ""+url
        VIDEOLINKS(url,name)

xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_DATE)
xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_TITLE)
xbmcplugin.setContent(int(sys.argv[1]),'episodes')
xbmcplugin.endOfDirectory(int(sys.argv[1]))

You'll also need the addon.xml to make XBMC see the addon. Code below:

Code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="plugin.program.SageTV"
       name="SageTV"
       version="1.0.0"
       provider-name="">
  <requires>
    <import addon="xbmc.python" version="1.0"/>
  </requires>
  <extension point="xbmc.python.pluginsource"
            library="default.py">
        <provides>video</provides>
  </extension>
  <extension point="xbmc.addon.metadata">
    <platform>all</platform>
    <summary>SageTV plugin</summary>
    <description>connect to SageTV library</description>
  </extension>
</addon>

Hope this works for you, let me know if you have questions.
Reply
#9
Screenshots:

Image

Image
Reply
#10
Looks great. I'll see if I can get it working when I have a chance
XBMC.MyLibrary (add anything to the library)
ForTheLibrary (Argus TV & XBMC Library PVR Integration)
SageTV & XBMC PVR Integration
Reply
#11
The plugin serves its purpose. But i wanted the TV shows/movies to be integrated with XBMC's native library.

I created a script that does it here:
http://forum.xbmc.org/showthread.php?p=661756
XBMC.MyLibrary (add anything to the library)
ForTheLibrary (Argus TV & XBMC Library PVR Integration)
SageTV & XBMC PVR Integration
Reply

Logout Mark Read Team Forum Stats Members Help
Help with importing SageTV (Movies and TV Shows) recordings into XBMC?0