updated mythtv library

This commit is contained in:
Erik Kristensen 2010-08-18 21:22:46 -04:00
parent 6a26761cc7
commit cc5de9acf4
32 changed files with 4513 additions and 640 deletions

View File

@ -3,6 +3,7 @@ import sys
import signal
import mythtv
import mythboxee
from mythboxee import MythBoxee
# DEBUG #
#mc.GetApp().GetLocalConfig().SetValue("dbconn", "")
@ -12,5 +13,5 @@ import mythboxee
mc.ActivateWindow(14001)
# Lets go ahead and launch the app
mythboxee.Launch()
MythBoxee()

View File

@ -4,267 +4,344 @@ import mythtv
from mythtv import MythError
from operator import itemgetter, attrgetter
mbbe = None
mbdb = None
config = mc.GetApp().GetLocalConfig()
class MythBoxee:
logLevel = 1
version = "4.0.beta"
titles = []
recordings = []
idbanners = {}
shows = {}
userAgent = "MythBoxee v4.0.beta"
tvdb_apikey = "6BEAB4CB5157AAE0"
be = None
db = None
recs = None
titles = []
recordings = []
banners = {}
shows = {}
series = {}
def DiscoverBackend():
mc.ShowDialogNotification("DiscoverBackend")
pin = config.GetValue("pin")
dbconn = config.GetValue("dbconn")
if not pin:
pin = 0000
try:
db = mythtv.MythDB(SecurityPin=pin)
except Exception, e:
mc.ShowDialogNotification(e.message)
if e.ename == 'DB_CREDENTIALS' and count < 3:
mc.ActivateWindow(14002)
mc.GetWindow(14002).GetControl(6020).SetVisible(False)
mc.GetWindow(14002).GetControl(6010).SetVisible(True)
mc.GetWindow(14002).GetControl(6011).SetFocus()
elif e.ename == 'DB_CONNECTION' or e.ename == 'DB_CREDENTIALS' and count > 3:
mc.ActivateWindow(14002)
mc.GetWindow(14002).GetControl(6010).SetVisible(False)
mc.GetWindow(14002).GetControl(6020).SetVisible(True)
mc.GetWindow(14002).GetControl(6021).SetFocus()
return False
else:
mc.ShowDialogNotification(str(db.dbconn))
config.SetValue("dbconn", str(db.dbconn))
return True
def Launch():
# If dbconn isn't set, we'll assume we haven't found the backend.
if not config.GetValue("dbconn"):
discoverBackend = False
while discoverBackend is False:
discoverBackend = DiscoverBackend()
# Parse our DB info
dbconn = config.GetValue("dbconn")
dbconf = eval(dbconn)
# Now that the backend has been discovered, lets connect.
try:
mbdb = mythtv.MythDB(**dbconf)
except MythError, e:
print e.message
mc.ShowDialogNotification("Failed to connect to the MythTV Backend")
else:
mbbe = mythtv.MythBE(db=mbdb)
mc.ActivateWindow(14010)
"""
DiscoverBackend - just as it sounds
def LoadShows():
del titles[:]
del recordings[:]
idbanners.clear()
shows.clear()
Attempt to discover the MythTV Backend using UPNP protocol, once found
try and gather MySQL database connection information using default PIN
via the XML interface. If that fails then prompt user to enter their
custom SecurityPin, if we fail to gather database information that way
finally prompt user to enter their credentials manually.
"""
def DiscoverBackend():
self.log("def(DiscoverBackend)")
config = mc.GetApp().GetLocalConfig()
sg = mc.Http()
html = sg.Get("http://" + config.GetValue("server") + ":6544/Myth/GetRecorded")
results = re.compile("<Program title=\"(.*?)\" subTitle=\"(.*?)\".*?endTime=\"(.*?)\" airdate=\"(.*?)\" startTime=\"(.*?)\".*?>(.*?)<Channel.*?chanId=\"(.*?)\".*?>").findall(html)
for title,subtitle,endtime,airdate,starttime,desc,chanid in results:
if title not in titles:
titles.append(title)
idbanners[title] = GetSeriesIDBanner(title)
shows[title] = []
pin = self.config.GetValue("pin")
dbconn = self.config.GetValue("dbconn")
single = [title,subtitle,desc,chanid,airdate,starttime,endtime]
recordings.append(single)
if not pin:
pin = 0000
try:
self.db = mythtv.MythDB(SecurityPin=pin)
except Exception, e:
if e.ename == 'DB_CREDENTIALS' and count < 2:
mc.ActivateWindow(14002)
mc.GetWindow(14002).GetControl(6020).SetVisible(False)
mc.GetWindow(14002).GetControl(6010).SetVisible(True)
mc.GetWindow(14002).GetControl(6011).SetFocus()
elif e.ename == 'DB_CONNECTION' or e.ename == 'DB_CREDENTIALS' and count > 3:
mc.ActivateWindow(14002)
mc.GetWindow(14002).GetControl(6010).SetVisible(False)
mc.GetWindow(14002).GetControl(6020).SetVisible(True)
mc.GetWindow(14002).GetControl(6021).SetFocus()
return False
else:
self.config.SetValue("dbconn", str(self.db.dbconn))
return True
"""
Lets make a connection to the backend!
"""
def __init__(self):
self.config = mc.GetApp().GetLocalConfig()
self.log("def(__init__)")
# If this is the first time the app is being run, lets set some default options.
if not self.config.GetValue("firstrun"):
self.config.SetValue("SortBy", "Original Air Date")
self.config.SetValue("SortDir", "Descending")
self.config.SetValue("firstrun", "1")
# If dbconn isn't set, we'll assume we haven't found the backend.
if not self.config.GetValue("dbconn"):
discoverBackend = False
while discoverBackend is False:
print "discover"
discoverBackend = self.DiscoverBackend()
# Parse our DB info
dbconn = self.config.GetValue("dbconn")
dbconf = eval(dbconn)
# Now that the backend has been discovered, lets connect.
try:
self.db = mythtv.MythDB(**dbconf)
except MythError, e:
print e.message
mc.ShowDialogNotification("Failed to connect to the MythTV Backend")
else:
self.be = mythtv.MythBE(db=self.db)
"""
GetRecordings - Pulls all of the recordings out of the backend.
This function also creates some dictionarys and lists of information
that is used throughout the app for different functions.
"""
def GetRecordings(self):
self.titles = []
self.banners = {}
self.series = {}
self.shows = {}
self.log("def(GetRecordings)")
self.recs = self.be.getRecordings()
shows[title].append(single)
x=0
for recording in self.recs:
if recording.title not in self.titles:
self.titles.append(str(recording.title))
self.banners[str(recording.title)] = self.GetRecordingArtwork(str(recording.title))
self.series[str(recording.title)] = self.GetRecordingSeriesID(str(recording.title))
self.shows[str(recording.title)] = []
single = [str(recording.title), str(recording.subtitle), str(recording.description), str(recording.chanid), str(recording.airdate), str(recording.starttime), str(recording.endtime), x]
self.shows[str(recording.title)].append(single)
x = x + 1
self.titles.sort()
titles.sort()
items = mc.ListItems()
for title in self.titles:
item = mc.ListItem( mc.ListItem.MEDIA_UNKNOWN )
item.SetLabel(str(title))
item.SetThumbnail(self.banners[title])
item.SetProperty("videos", str(len(self.shows[title])))
item.SetProperty("seriesid", str(self.series[title]))
items.append(item)
mc.GetWindow(14001).GetList(1030).SetItems(items)
def GetRecordingArtwork(self, title):
sg = mc.Http()
sg.SetUserAgent('MythBoxee v4.0.beta')
html = sg.Get("http://www.thetvdb.com/api/GetSeries.php?seriesname=" + str(title.replace(" ", "%20")))
banners = re.compile("<banner>(.*?)</banner>").findall(html)
try:
artwork = "http://www.thetvdb.com/banners/" + banners[0]
except:
artwork = "mb_artwork_error.png"
self.log("def(GetRecordingArtwork): " + str(artwork))
return artwork
def GetRecordingSeriesID(self, title):
sg = mc.Http()
sg.SetUserAgent(self.userAgent)
html = sg.Get("http://www.thetvdb.com/api/GetSeries.php?seriesname=" + title.replace(" ", "%20"))
series = re.compile("<seriesid>(.*?)</seriesid>").findall(html)
try:
seriesid = series[0]
except:
seriesid = 00000
self.log("def(GetRecordingSeriesID): title[" + title + "] - seriesid[" + str(seriesid) + "]")
return seriesid
"""
DisplayShow
"""
def DisplayShow(self):
recordingList = mc.GetWindow(14001).GetList(1030)
item = recordingList.GetItem(recordingList.GetFocusedItem())
title = item.GetLabel()
# Save the Latest Show Title to what was clicked
# this way the show window has a way to load the data.
self.config.SetValue("LatestShowTitle", title)
self.config.SetValue("LatestShowID", item.GetProperty("seriesid"))
self.log("def(DisplaySingleShow): Title[" + title + "]")
# Show the Single Show Window
mc.ActivateWindow(14002)
itemList = mc.ListItems()
itemList.append(item)
mc.GetWindow(14002).GetList(2070).SetItems(itemList)
"""
LoadShow
items = mc.ListItems()
for title in titles:
Launch function to gather and setup the recordings for a single show.
"""
def LoadShow(self):
title = self.config.GetValue("LatestShowTitle")
seriesid = self.config.GetValue("LatestShowID")
self.log("def(LoadSingleShow): Title[" + title + "]")
self.SetSortableOptions()
self.SetSeriesDetails(title, seriesid)
self.LoadShowRecordings(title)
"""
LoadShowRecordings
Determine which show is being displayed and find all the recordings for it.
Then populate the recording list for the singular show for viewer to watch.
"""
def LoadShowRecordings(self, title):
sortBy = self.config.GetValue("SortBy")
sortDir = self.config.GetValue("SortDir")
episodes = None
if sortBy == "Original Air Date" and sortDir == "Ascending":
episodes = sorted(self.shows[title], key=itemgetter(4))
elif sortBy == "Original Air Date" and sortDir == "Descending":
episodes = sorted(self.shows[title], key=itemgetter(4), reverse=True)
elif sortBy == "Recorded Date" and sortDir == "Ascending":
episodes = sorted(self.shows[title], key=itemgetter(5))
elif sortBy == "Recorded Date" and sortDir == "Descending":
episodes = sorted(self.shows[title], key=itemgetter(5), reverse=True)
elif sortBy == "Title" and sortDir == "Ascending":
episodes = sorted(self.shows[title], key=itemgetter(1))
elif sortBy == "Title" and sortDir == "Descending":
episodes = sorted(self.shows[title], key=itemgetter(1), reverse=True)
else:
episodes = self.shows[title]
showitems = mc.ListItems()
for title,subtitle,desc,chanid,airdate,starttime,endtime,ref in episodes:
print title
recording = self.recs[ref]
#showitem = mc.ListItem( mc.ListItem.MEDIA_VIDEO_EPISODE )
#showitem = mc.ListItem( mc.ListItem.MEDIA_UNKNOWN )
showitem = mc.ListItem()
showitem.SetLabel(str(recording.subtitle))
showitem.SetTitle(str(recording.subtitle))
showitem.SetTVShowTitle(str(recording.title))
showitem.SetDescription(str(desc))
showitem.SetProperty("starttime", str(starttime))
showitem.SetProperty("ref", str(ref))
try:
date = str(airdate).split("-")
showitem.SetDate(int(date[0]), int(date[1]), int(date[2]))
except:
showitem.SetDate(2010, 01, 01)
dbconf = eval(self.config.GetValue("dbconn"))
#showitem.SetThumbnail("http://192.168.1.210:6544/Myth/GetPreviewImage?ChanId=1050&StartTime=2010-08-05%2021:00:00")
#showitem.SetThumbnail("http://192.168.1.210:6544/Myth/GetPreviewImage?ChanId=" + chanid + "&StartTime=" + starttime.replace("T", "%20"))
showitem.SetThumbnail("http://" + dbconf['DBHostName'] + ":6544/Myth/GetPreviewImage?ChanId=" + chanid + "&StartTime=" + starttime.replace(" ", "%20"))
#showitem.SetPath("http://" + dbconf['DBHostName'] + ":6544/Myth/GetRecording?ChanId=" + chanid + "&StartTime=" + starttime.replace("T", "%20"))
showitem.SetPath("smb://guest:guest@192.168.1.210/recordings/1050_20100709010000.mpg")
showitems.append(showitem)
mc.GetWindow(14002).GetList(2040).SetItems(mc.ListItems())
mc.GetWindow(14002).GetList(2040).SetItems(showitems)
"""
SetShowOptions
Setup the show options; sort by, sort direction, watched vs unwatched
"""
def SetSortableOptions(self):
sortable = ['Original Air Date', 'Recorded Date', 'Title']
items = mc.ListItems()
for sorttype in sortable:
item = mc.ListItem( mc.ListItem.MEDIA_UNKNOWN )
item.SetLabel(sorttype)
items.append(item)
mc.GetWindow(14002).GetList(2051).SetItems(items)
mc.GetWindow(14002).GetList(2051).SetSelected(1, True)
sortableby = ['Ascending', 'Descending']
items = mc.ListItems()
for sorttype in sortableby:
item = mc.ListItem( mc.ListItem.MEDIA_UNKNOWN )
item.SetLabel(sorttype)
items.append(item)
mc.GetWindow(14002).GetList(2061).SetItems(items)
mc.GetWindow(14002).GetList(2061).SetSelected(1, True)
def SetSeriesDetails(self, title, seriesid):
sg = mc.Http()
sg.SetUserAgent(self.userAgent)
html = sg.Get("http://thetvdb.com/api/" + self.tvdb_apikey + "/series/" + seriesid + "/")
overview = re.compile("<Overview>(.*?)</Overview>").findall(html)
poster = re.compile("<poster>(.*?)</poster>").findall(html)
items = mc.ListItems()
item = mc.ListItem( mc.ListItem.MEDIA_UNKNOWN )
item.SetLabel(title)
item.SetThumbnail(idbanners[title][1])
item.SetProperty("seriesid", idbanners[title][0])
items.append(item)
mc.GetWindow(14000).GetList(13).SetItems(items)
def LoadSingleShow():
config = mc.GetApp().GetLocalConfig()
ilist = mc.GetActiveWindow().GetList(13)
item = ilist.GetItem(ilist.GetFocusedItem())
name = item.GetLabel()
config.SetValue("seriesid", item.GetProperty("seriesid"))
config.SetValue("show", name)
mc.ActivateWindow(14001)
SetSortables()
GetSetSeriesDetails(name, item.GetProperty("seriesid"))
LoadSeriesEpisodes(name)
def SetSortables():
config.SetValue("SortBy", "Recorded Date")
config.SetValue("SortDir", "Descending")
sortable = ['Original Air Date', 'Recorded Date', 'Title']
items = mc.ListItems()
for sorttype in sortable:
item = mc.ListItem( mc.ListItem.MEDIA_UNKNOWN )
item.SetLabel(sorttype)
items.append(item)
mc.GetActiveWindow().GetList(2014).SetItems(items)
mc.GetActiveWindow().GetList(2014).SetSelected(1, True)
sortableby = ['Ascending', 'Descending']
items = mc.ListItems()
for sorttype in sortableby:
item = mc.ListItem( mc.ListItem.MEDIA_UNKNOWN )
item.SetLabel(sorttype)
items.append(item)
item.SetTitle(title)
try:
item.SetDescription(overview[0])
item.SetProperty("description", overview[0])
except:
item.SetDescription("No Description")
item.SetProperty("description", "No Description")
mc.GetActiveWindow().GetList(2015).SetItems(items)
mc.GetActiveWindow().GetList(2015).SetSelected(1, True)
def ShowEpisodeDetails():
print "ShowEpisodeDetails"
def SortBySeriesEpisodes():
sortByItems = sortByItemNumber = mc.GetWindow(14001).GetList(2014).GetSelected()
sortDirectionItems = sortDirectionItemNumber = mc.GetWindow(14001).GetList(2015).GetSelected()
mc.GetActiveWindow().GetList(2014).UnselectAll()
mc.GetActiveWindow().GetList(2014).SetSelected(mc.GetActiveWindow().GetList(2014).GetFocusedItem(), True)
config.SetValue("SortBy", mc.GetActiveWindow().GetList(2014).GetItem(mc.GetActiveWindow().GetList(2014).GetFocusedItem()).GetLabel())
LoadSeriesEpisodes(config.GetValue("name"))
def SortDirSeriesEpisodes():
sortByItems = sortByItemNumber = mc.GetWindow(14001).GetList(2014).GetSelected()
mc.GetActiveWindow().GetList(2015).UnselectAll()
mc.GetActiveWindow().GetList(2015).SetSelected(mc.GetActiveWindow().GetList(2015).GetFocusedItem(), True)
config.SetValue("SortDir", mc.GetActiveWindow().GetList(2015).GetItem(mc.GetActiveWindow().GetList(2015).GetFocusedItem()).GetLabel())
LoadSeriesEpisodes(config.GetValue("name"))
def GetSeriesIDBanner(name):
sg = mc.Http()
sg.SetUserAgent('MythBoxee v3.0.beta')
html = sg.Get("http://www.thetvdb.com/api/GetSeries.php?seriesname=" + name.replace(" ", "%20"))
series = re.compile("<seriesid>(.*?)</seriesid>").findall(html)
banners = re.compile("<banner>(.*?)</banner>").findall(html)
show = []
if series:
show.append(series[0])
show.append("http://www.thetvdb.com/banners/" + banners[0])
else:
show.append("00000")
show.append("http://192.168.1.210/")
return show
def GetSetSeriesDetails(name, seriesid):
sg = mc.Http()
sg.SetUserAgent('MythBoxee v3.0.beta')
html = sg.Get("http://thetvdb.com/api/6BEAB4CB5157AAE0/series/" + seriesid + "/")
overview = re.compile("<Overview>(.*?)</Overview>").findall(html)
poster = re.compile("<poster>(.*?)</poster>").findall(html)
items = mc.ListItems()
item = mc.ListItem( mc.ListItem.MEDIA_UNKNOWN )
item.SetLabel(name)
item.SetTitle(name)
if overview:
item.SetDescription(overview[0])
item.SetProperty("description", overview[0])
item.SetThumbnail("http://www.thetvdb.com/banners/" + poster[0])
items.append(item)
mc.GetWindow(14001).GetList(21).SetItems(items)
def LoadSeriesEpisodes(name):
config = mc.GetApp().GetLocalConfig()
config.SetValue("name", name)
showitems = mc.ListItems()
sortBy = config.GetValue("SortBy")
sortDir = config.GetValue("SortDir")
print shows[name]
if sortBy == "Original Air Date" and sortDir == "Ascending":
episodes = sorted(shows[name], key=itemgetter(4))
elif sortBy == "Original Air Date" and sortDir == "Descending":
episodes = sorted(shows[name], key=itemgetter(4), reverse=True)
elif sortBy == "Recorded Date" and sortDir == "Ascending":
episodes = sorted(shows[name], key=itemgetter(5))
elif sortBy == "Recorded Date" and sortDir == "Descending":
episodes = sorted(shows[name], key=itemgetter(5), reverse=True)
elif sortBy == "Title" and sortDir == "Ascending":
episodes = sorted(shows[name], key=itemgetter(1))
elif sortBy == "Title" and sortDir == "Descending":
episodes = sorted(shows[name], key=itemgetter(1), reverse=True)
else:
episodes = shows[name]
for title,subtitle,desc,chanid,airdate,starttime,endtime in episodes:
showitem = mc.ListItem( mc.ListItem.MEDIA_VIDEO_EPISODE )
showitem.SetLabel(subtitle)
showitem.SetTitle(subtitle)
showitem.SetTVShowTitle(name)
showitem.SetDescription(desc)
date = airdate.split("-")
showitem.SetProperty("starttime", starttime)
showitem.SetDate(int(date[0]), int(date[1]), int(date[2]))
showitem.SetThumbnail("http://" + config.GetValue("server") + ":6544/Myth/GetPreviewImage?ChanId=" + chanid + "&StartTime=" + starttime.replace("T", "%20"))
showitem.SetPath("http://" + config.GetValue("server") + ":6544/Myth/GetRecording?ChanId=" + chanid + "&StartTime=" + starttime.replace("T", "%20"))
showitems.append(showitem)
mc.GetActiveWindow().GetList(2013).SetItems(showitems)
def GetServer():
config = mc.GetApp().GetLocalConfig()
server = config.GetValue("server")
response = mc.ShowDialogKeyboard("Enter IP Address of MythTV Backend Server", server, False)
url = "http://" + response + ":6544/Myth/GetServDesc"
if VerifyServer(url) == True:
config.SetValue("server", response)
def VerifyServer(url):
config = mc.GetApp().GetLocalConfig()
http = mc.Http()
data = http.Get(url)
if http.GetHttpResponseCode() == 200:
config.SetValue("verified", "1")
return True
else:
return False
try:
item.SetThumbnail("http://www.thetvdb.com/banners/" + poster[0])
except:
item.SetThumbnail("mb_poster_error.png")
items.append(item)
mc.GetWindow(14002).GetList(2070).SetItems(items)
def PlayRecording(self):
self.log("def(PlayRecording): ")
sl = mc.GetWindow(14002).GetList(2040)
item = sl.GetItem(sl.GetFocusedItem())
ref = item.GetProperty("ref")
file = self.recs[int(ref)].open('r', self.db)
mc.ShowDialogNotification(item.GetProperty("ref"))
mc.ShowDialogNotification("Playing: " + item.GetLabel())
def log(self, message):
if self.logLevel >= 2:
mc.ShowDialogNotification(message)
if self.logLevel >= 1:
mc.LogInfo(">>> MythBoxee (" + self.version + ")\: " + message)
print ">>> MythBoxee (" + self.version + ")\: " + message

View File

@ -1,21 +1,329 @@
import mc
import re
import mythtv
from mythtv import MythError
from operator import itemgetter, attrgetter
class MythBoxee:
be = None
db = None
def DiscoverBackend():
config = mc.GetApp().GetLocalConfig()
mc.ShowDialogNotification("DiscoverBackend")
pin = config.GetValue("pin")
dbconn = config.GetValue("dbconn")
def CreateConnection():
try:
pin = mc.GetApp().GetLocalConfig().GetValue("pin")
if not pin:
pin = 0000
try:
self.db = mythtv.MythDB(SecurityPin=pin)
except Exception, e:
mc.ShowDialogNotification(e.message)
if e.ename == 'DB_CREDENTIALS' and count < 3:
mc.ActivateWindow(14002)
mc.GetWindow(14002).GetControl(6020).SetVisible(False)
mc.GetWindow(14002).GetControl(6010).SetVisible(True)
mc.GetWindow(14002).GetControl(6011).SetFocus()
elif e.ename == 'DB_CONNECTION' or e.ename == 'DB_CREDENTIALS' and count > 3:
mc.ActivateWindow(14002)
mc.GetWindow(14002).GetControl(6010).SetVisible(False)
mc.GetWindow(14002).GetControl(6020).SetVisible(True)
mc.GetWindow(14002).GetControl(6021).SetFocus()
return False
else:
mc.ShowDialogNotification(str(self.db.dbconn))
config.SetValue("dbconn", str(self.db.dbconn))
return True
def __init__(self):
config = mc.GetApp().GetLocalConfig()
# If dbconn isn't set, we'll assume we haven't found the backend.
if not config.GetValue("dbconn"):
discoverBackend = False
while discoverBackend is False:
discoverBackend = self.DiscoverBackend()
# Parse our DB info
dbconn = config.GetValue("dbconn")
dbconf = eval(dbconn)
# Now that the backend has been discovered, lets connect.
try:
self.db = mythtv.MythDB(**dbconf)
except MythError, e:
print e.message
mc.ShowDialogNotification("Failed to connect to the MythTV Backend")
else:
self.be = mythtv.MythBE(db=self.db)
mc.ActivateWindow(14010)
mbbe = None
mbdb = None
config = mc.GetApp().GetLocalConfig()
titles = []
recordings = []
idbanners = {}
shows = {}
def DiscoverBackend1():
mc.ShowDialogNotification("DiscoverBackend")
pin = config.GetValue("pin")
dbconn = config.GetValue("dbconn")
if not pin:
pin = 0000
try:
db = mythtv.MythDB(SecurityPin=pin)
except Exception, e:
if e.ename == 'DB_CREDENTIALS':
mc.ShowDialogNotification("Unable to connect, try to manually set the security pin.")
mc.ActivateWindow(14006)
mc.GetWindow(14006).GetControl(6010).SetVisible(True)
mc.GetWindow(14006).GetControl(6020).SetVisible(False)
mc.GetWindow(14006).GetControl(6011).SetFocus()
elif e.ename == 'DB_CONNECTION':
mc.ActivateWindow(14006)
mc.GetWindow(14006).GetControl(6010).SetVisible(False)
mc.GetWindow(14006).GetControl(6020).SetVisible(True)
mc.GetWindow(14006).GetControl(6021).SetFocus()
mc.ShowDialogNotification(e.message)
if e.ename == 'DB_CREDENTIALS' and count < 3:
mc.ActivateWindow(14002)
mc.GetWindow(14002).GetControl(6020).SetVisible(False)
mc.GetWindow(14002).GetControl(6010).SetVisible(True)
mc.GetWindow(14002).GetControl(6011).SetFocus()
elif e.ename == 'DB_CONNECTION' or e.ename == 'DB_CREDENTIALS' and count > 3:
mc.ActivateWindow(14002)
mc.GetWindow(14002).GetControl(6010).SetVisible(False)
mc.GetWindow(14002).GetControl(6020).SetVisible(True)
mc.GetWindow(14002).GetControl(6021).SetFocus()
return False
else:
mc.ShowDialogNotification(str(db.dbconn))
config.SetValue("dbconn", str(db.dbconn))
return True
def Launch():
# If dbconn isn't set, we'll assume we haven't found the backend.
if not config.GetValue("dbconn"):
discoverBackend = False
while discoverBackend is False:
discoverBackend = DiscoverBackend()
# Parse our DB info
dbconn = config.GetValue("dbconn")
dbconf = eval(dbconn)
# Now that the backend has been discovered, lets connect.
try:
mbdb = mythtv.MythDB(**dbconf)
except MythError, e:
print e.message
mc.ShowDialogNotification("Failed to connect to the MythTV Backend")
else:
mbbe = mythtv.MythBE(db=mbdb)
mc.ActivateWindow(14010)
def LoadShows():
del titles[:]
del recordings[:]
idbanners.clear()
shows.clear()
config = mc.GetApp().GetLocalConfig()
sg = mc.Http()
html = sg.Get("http://" + config.GetValue("server") + ":6544/Myth/GetRecorded")
results = re.compile("<Program title=\"(.*?)\" subTitle=\"(.*?)\".*?endTime=\"(.*?)\" airdate=\"(.*?)\" startTime=\"(.*?)\".*?>(.*?)<Channel.*?chanId=\"(.*?)\".*?>").findall(html)
for title,subtitle,endtime,airdate,starttime,desc,chanid in results:
if title not in titles:
titles.append(title)
idbanners[title] = GetSeriesIDBanner(title)
shows[title] = []
single = [title,subtitle,desc,chanid,airdate,starttime,endtime]
recordings.append(single)
shows[title].append(single)
titles.sort()
items = mc.ListItems()
for title in titles:
item = mc.ListItem( mc.ListItem.MEDIA_UNKNOWN )
item.SetLabel(title)
item.SetThumbnail(idbanners[title][1])
item.SetProperty("seriesid", idbanners[title][0])
items.append(item)
mc.GetWindow(14000).GetList(13).SetItems(items)
def LoadSingleShow():
config = mc.GetApp().GetLocalConfig()
ilist = mc.GetActiveWindow().GetList(13)
item = ilist.GetItem(ilist.GetFocusedItem())
name = item.GetLabel()
config.SetValue("seriesid", item.GetProperty("seriesid"))
config.SetValue("show", name)
mc.ActivateWindow(14001)
SetSortables()
GetSetSeriesDetails(name, item.GetProperty("seriesid"))
LoadSeriesEpisodes(name)
def SetSortables():
config.SetValue("SortBy", "Recorded Date")
config.SetValue("SortDir", "Descending")
sortable = ['Original Air Date', 'Recorded Date', 'Title']
items = mc.ListItems()
for sorttype in sortable:
item = mc.ListItem( mc.ListItem.MEDIA_UNKNOWN )
item.SetLabel(sorttype)
items.append(item)
mc.GetActiveWindow().GetList(2014).SetItems(items)
mc.GetActiveWindow().GetList(2014).SetSelected(1, True)
sortableby = ['Ascending', 'Descending']
items = mc.ListItems()
for sorttype in sortableby:
item = mc.ListItem( mc.ListItem.MEDIA_UNKNOWN )
item.SetLabel(sorttype)
items.append(item)
mc.GetActiveWindow().GetList(2015).SetItems(items)
mc.GetActiveWindow().GetList(2015).SetSelected(1, True)
def ShowEpisodeDetails():
print "ShowEpisodeDetails"
def SortBySeriesEpisodes():
sortByItems = sortByItemNumber = mc.GetWindow(14001).GetList(2014).GetSelected()
sortDirectionItems = sortDirectionItemNumber = mc.GetWindow(14001).GetList(2015).GetSelected()
mc.GetActiveWindow().GetList(2014).UnselectAll()
mc.GetActiveWindow().GetList(2014).SetSelected(mc.GetActiveWindow().GetList(2014).GetFocusedItem(), True)
config.SetValue("SortBy", mc.GetActiveWindow().GetList(2014).GetItem(mc.GetActiveWindow().GetList(2014).GetFocusedItem()).GetLabel())
LoadSeriesEpisodes(config.GetValue("name"))
def SortDirSeriesEpisodes():
sortByItems = sortByItemNumber = mc.GetWindow(14001).GetList(2014).GetSelected()
mc.GetActiveWindow().GetList(2015).UnselectAll()
mc.GetActiveWindow().GetList(2015).SetSelected(mc.GetActiveWindow().GetList(2015).GetFocusedItem(), True)
config.SetValue("SortDir", mc.GetActiveWindow().GetList(2015).GetItem(mc.GetActiveWindow().GetList(2015).GetFocusedItem()).GetLabel())
LoadSeriesEpisodes(config.GetValue("name"))
def GetSeriesIDBanner(name):
sg = mc.Http()
sg.SetUserAgent('MythBoxee v3.0.beta')
html = sg.Get("http://www.thetvdb.com/api/GetSeries.php?seriesname=" + name.replace(" ", "%20"))
series = re.compile("<seriesid>(.*?)</seriesid>").findall(html)
banners = re.compile("<banner>(.*?)</banner>").findall(html)
show = []
if series:
show.append(series[0])
show.append("http://www.thetvdb.com/banners/" + banners[0])
else:
show.append("00000")
show.append("http://192.168.1.210/")
return show
def GetSetSeriesDetails(name, seriesid):
sg = mc.Http()
sg.SetUserAgent('MythBoxee v3.0.beta')
html = sg.Get("http://thetvdb.com/api/6BEAB4CB5157AAE0/series/" + seriesid + "/")
overview = re.compile("<Overview>(.*?)</Overview>").findall(html)
poster = re.compile("<poster>(.*?)</poster>").findall(html)
items = mc.ListItems()
item = mc.ListItem( mc.ListItem.MEDIA_UNKNOWN )
item.SetLabel(name)
item.SetTitle(name)
if overview:
item.SetDescription(overview[0])
item.SetProperty("description", overview[0])
item.SetThumbnail("http://www.thetvdb.com/banners/" + poster[0])
items.append(item)
mc.GetWindow(14001).GetList(21).SetItems(items)
def LoadSeriesEpisodes(name):
config = mc.GetApp().GetLocalConfig()
config.SetValue("name", name)
showitems = mc.ListItems()
sortBy = config.GetValue("SortBy")
sortDir = config.GetValue("SortDir")
print shows[name]
if sortBy == "Original Air Date" and sortDir == "Ascending":
episodes = sorted(shows[name], key=itemgetter(4))
elif sortBy == "Original Air Date" and sortDir == "Descending":
episodes = sorted(shows[name], key=itemgetter(4), reverse=True)
elif sortBy == "Recorded Date" and sortDir == "Ascending":
episodes = sorted(shows[name], key=itemgetter(5))
elif sortBy == "Recorded Date" and sortDir == "Descending":
episodes = sorted(shows[name], key=itemgetter(5), reverse=True)
elif sortBy == "Title" and sortDir == "Ascending":
episodes = sorted(shows[name], key=itemgetter(1))
elif sortBy == "Title" and sortDir == "Descending":
episodes = sorted(shows[name], key=itemgetter(1), reverse=True)
else:
episodes = shows[name]
for title,subtitle,desc,chanid,airdate,starttime,endtime in episodes:
showitem = mc.ListItem( mc.ListItem.MEDIA_VIDEO_EPISODE )
showitem.SetLabel(subtitle)
showitem.SetTitle(subtitle)
showitem.SetTVShowTitle(name)
showitem.SetDescription(desc)
date = airdate.split("-")
showitem.SetProperty("starttime", starttime)
showitem.SetDate(int(date[0]), int(date[1]), int(date[2]))
showitem.SetThumbnail("http://" + config.GetValue("server") + ":6544/Myth/GetPreviewImage?ChanId=" + chanid + "&StartTime=" + starttime.replace("T", "%20"))
showitem.SetPath("http://" + config.GetValue("server") + ":6544/Myth/GetRecording?ChanId=" + chanid + "&StartTime=" + starttime.replace("T", "%20"))
showitems.append(showitem)
mc.GetActiveWindow().GetList(2013).SetItems(showitems)
def GetServer():
config = mc.GetApp().GetLocalConfig()
server = config.GetValue("server")
response = mc.ShowDialogKeyboard("Enter IP Address of MythTV Backend Server", server, False)
url = "http://" + response + ":6544/Myth/GetServDesc"
if VerifyServer(url) == True:
config.SetValue("server", response)
def VerifyServer(url):
config = mc.GetApp().GetLocalConfig()
http = mc.Http()
data = http.Get(url)
if http.GetHttpResponseCode() == 200:
config.SetValue("verified", "1")
return True
else:
return False

View File

@ -1,35 +1,35 @@
K 25
svn:wc:ra_dav:version-url
V 67
/svn/!svn/ver/24521/tags/release-0-23/mythtv/bindings/python/MythTV
V 69
/svn/!svn/ver/25397/tags/release-0-23-1/mythtv/bindings/python/MythTV
END
MythStatic.py
K 25
svn:wc:ra_dav:version-url
V 81
/svn/!svn/ver/24521/tags/release-0-23/mythtv/bindings/python/MythTV/MythStatic.py
V 83
/svn/!svn/ver/25397/tags/release-0-23-1/mythtv/bindings/python/MythTV/MythStatic.py
END
MythData.py
K 25
svn:wc:ra_dav:version-url
V 79
/svn/!svn/ver/24521/tags/release-0-23/mythtv/bindings/python/MythTV/MythData.py
V 81
/svn/!svn/ver/25397/tags/release-0-23-1/mythtv/bindings/python/MythTV/MythData.py
END
MythBase.py
K 25
svn:wc:ra_dav:version-url
V 79
/svn/!svn/ver/24521/tags/release-0-23/mythtv/bindings/python/MythTV/MythBase.py
V 81
/svn/!svn/ver/25397/tags/release-0-23-1/mythtv/bindings/python/MythTV/MythBase.py
END
MythFunc.py
K 25
svn:wc:ra_dav:version-url
V 79
/svn/!svn/ver/24521/tags/release-0-23/mythtv/bindings/python/MythTV/MythFunc.py
V 81
/svn/!svn/ver/25397/tags/release-0-23-1/mythtv/bindings/python/MythTV/MythFunc.py
END
__init__.py
K 25
svn:wc:ra_dav:version-url
V 79
/svn/!svn/ver/24521/tags/release-0-23/mythtv/bindings/python/MythTV/__init__.py
V 81
/svn/!svn/ver/25397/tags/release-0-23-1/mythtv/bindings/python/MythTV/__init__.py
END

View File

@ -1,15 +1,15 @@
10
dir
25361
http://svn.mythtv.org/svn/tags/release-0-23/mythtv/bindings/python/MythTV
25726
http://svn.mythtv.org/svn/tags/release-0-23-1/mythtv/bindings/python/MythTV
http://svn.mythtv.org/svn
2010-05-05T00:45:58.150174Z
24420
wagnerrp
2010-07-22T02:21:00.112292Z
25396
gigem
@ -32,11 +32,11 @@ file
2010-07-16T22:31:04.000000Z
c362740b39721bf47554a27b8dcb7255
2010-01-30T01:25:12.140142Z
23365
wagnerrp
2010-08-18T01:49:43.000000Z
2645324c83c882ef4d85662fe2c3c9d7
2010-07-22T02:21:00.112292Z
25396
gigem
has-props
@ -58,7 +58,7 @@ has-props
233
261
MythData.py
file
@ -66,10 +66,10 @@ file
2010-07-16T22:31:04.000000Z
ea13afe13bb398e11e7895be6654e06e
2010-04-21T04:46:55.439637Z
24220
2010-08-18T01:49:43.000000Z
f973584ab4647d8e5f7a0eb16d51bf16
2010-06-07T00:03:02.104550Z
25014
wagnerrp
has-props
@ -92,7 +92,7 @@ has-props
57313
57441
ttvdb
dir
@ -103,7 +103,7 @@ file
2010-07-16T22:31:04.000000Z
2010-08-18T01:49:43.000000Z
4e2f2010af14b04d6ebb3ead0606faa1
2010-05-05T00:45:58.150174Z
24420
@ -137,10 +137,10 @@ file
2010-07-16T22:31:04.000000Z
80c438b974b0dadaed423f9308c04912
2010-03-31T19:07:44.868318Z
23878
2010-08-18T01:49:43.000000Z
3f6f4d43c4dc47e8c6ab2ab747d8042f
2010-05-23T19:52:40.992320Z
24818
wagnerrp
has-props
@ -163,7 +163,7 @@ has-props
41463
41550
tmdb
dir
@ -174,10 +174,10 @@ file
2010-07-16T22:31:04.000000Z
5c15a4df6a8f262fb7bdd3f91b32119a
2010-05-03T05:03:57.011023Z
24346
2010-08-18T01:49:43.000000Z
fc69a94c478228940c6be7eee98a8903
2010-06-22T03:35:41.632640Z
25154
wagnerrp
has-props
@ -200,5 +200,5 @@ has-props
1464
1532

View File

@ -175,7 +175,7 @@ class FileTransfer( MythBEConn ):
if not self.open:
return
self.control.backendCommand('QUERY_FILETRANSFER '\
+BACKEND_SEP.join([str(self.sockno), 'JOIN']))
+BACKEND_SEP.join([str(self.sockno), 'DONE']))
self.socket.shutdown(1)
self.socket.close()
self.open = False
@ -526,6 +526,8 @@ class Program( DictData ):
if type != 'r':
raise MythFileError(MythError.FILE_FAILED_WRITE, self.filename,
'Program () objects cannot be opened for writing')
if not self.filename.startswith('myth://'):
self.filename = 'myth://%s/%s' % (self.hostname, self.filename)
return ftopen(self.filename, 'r')
class Record( DBDataWrite ):

View File

@ -392,13 +392,16 @@ class MythBE( FileOps ):
'filenames' is a dictionary, where the values are the file sizes.
"""
def walk(self, host, sg, root, path):
dn, fn, fs = self.getSGList(host, sg, root+path+'/')
res = [list(dn), dict(zip(fn, fs))]
res = self.getSGList(host, sg, root+path+'/')
if res < 0:
return {}
dlist = list(res[0])
res = [dlist, dict(zip(res[1],res[2]))]
if path == '':
res = {'/':res}
else:
res = {path:res}
for d in dn:
for d in dlist:
res.update(walk(self, host, sg, root, path+'/'+d))
return res
@ -820,7 +823,7 @@ class MythDB( MythDBBase ):
def getGuideData(self, chanid, date):
return self.searchGuide(chanid=chanid,
custom=('DATE(starttime)=%s',date))
custom=(('DATE(starttime)=%s',date),))
def getSetting(self, value, hostname=None):
if not hostname:
@ -996,7 +999,7 @@ class MythVideo( MythDBBase ):
tpath = sgfold[0][1:]+'/'+sgfile
# filter by extension
if tpath.rsplit('.',1)[1].lower() not in extensions:
if tpath.rsplit('.',1)[-1].lower() not in extensions:
#print 'skipping: '+tpath
continue

View File

@ -4,9 +4,10 @@
Contains any static and global variables for MythTV Python Bindings
"""
OWN_VERSION = (0,23,1,0)
SCHEMA_VERSION = 1254
MVSCHEMA_VERSION = 1032
NVSCHEMA_VERSION = 1004
PROTO_VERSION = 56
PROTO_VERSION = 23056
PROGRAM_FIELDS = 47
BACKEND_SEP = '[]:[]'

View File

@ -36,6 +36,9 @@ if version_info >= (2, 6): # 2.6 or newer
else:
exec(import25)
__version__ = OWN_VERSION
MythStatic.mysqldb = MySQLdb.__version__
if __name__ == '__main__':
banner = 'MythTV Python interactive shell.'
import code

Binary file not shown.

View File

@ -521,12 +521,12 @@ class Program( DictData ):
"""Program.getRecorded() -> Recorded object"""
return Recorded((self.chanid,self.recstartts), db=self.db)
def open(self, type='r'):
def open(self, type='r', dba=None):
"""Program.open(type='r') -> file or FileTransfer object"""
if type != 'r':
raise MythFileError(MythError.FILE_FAILED_WRITE, self.filename,
'Program () objects cannot be opened for writing')
return ftopen(self.filename, 'r')
return ftopen(self.filename, 'r', forceremote=False, nooverwrite=False, db=dba)
class Record( DBDataWrite ):
"""

Binary file not shown.

View File

@ -392,13 +392,16 @@ class MythBE( FileOps ):
'filenames' is a dictionary, where the values are the file sizes.
"""
def walk(self, host, sg, root, path):
dn, fn, fs = self.getSGList(host, sg, root+path+'/')
res = [list(dn), dict(zip(fn, fs))]
res = self.getSGList(host, sg, root+path+'/')
if res < 0:
return {}
dlist = list(res[0])
res = [dlist, dict(zip(res[1],res[2]))]
if path == '':
res = {'/':res}
else:
res = {path:res}
for d in dn:
for d in dlist:
res.update(walk(self, host, sg, root, path+'/'+d))
return res
@ -820,7 +823,7 @@ class MythDB( MythDBBase ):
def getGuideData(self, chanid, date):
return self.searchGuide(chanid=chanid,
custom=('DATE(starttime)=%s',date))
custom=(('DATE(starttime)=%s',date),))
def getSetting(self, value, hostname=None):
if not hostname:
@ -996,7 +999,7 @@ class MythVideo( MythDBBase ):
tpath = sgfold[0][1:]+'/'+sgfile
# filter by extension
if tpath.rsplit('.',1)[1].lower() not in extensions:
if tpath.rsplit('.',1)[-1].lower() not in extensions:
#print 'skipping: '+tpath
continue

Binary file not shown.

View File

@ -4,9 +4,10 @@
Contains any static and global variables for MythTV Python Bindings
"""
OWN_VERSION = (0,23,1,0)
SCHEMA_VERSION = 1254
MVSCHEMA_VERSION = 1032
NVSCHEMA_VERSION = 1004
PROTO_VERSION = 56
PROTO_VERSION = 23056
PROGRAM_FIELDS = 47
BACKEND_SEP = '[]:[]'

Binary file not shown.

View File

@ -36,6 +36,9 @@ if version_info >= (2, 6): # 2.6 or newer
else:
exec(import25)
__version__ = OWN_VERSION
#MythStatic.mysqldb = MySQLdb.__version__
if __name__ == '__main__':
banner = 'MythTV Python interactive shell.'
import code

Binary file not shown.

View File

@ -1,29 +1,29 @@
K 25
svn:wc:ra_dav:version-url
V 72
/svn/!svn/ver/24521/tags/release-0-23/mythtv/bindings/python/MythTV/tmdb
V 74
/svn/!svn/ver/25397/tags/release-0-23-1/mythtv/bindings/python/MythTV/tmdb
END
__init__.py
K 25
svn:wc:ra_dav:version-url
V 84
/svn/!svn/ver/24521/tags/release-0-23/mythtv/bindings/python/MythTV/tmdb/__init__.py
V 86
/svn/!svn/ver/25397/tags/release-0-23-1/mythtv/bindings/python/MythTV/tmdb/__init__.py
END
tmdb_api.py
K 25
svn:wc:ra_dav:version-url
V 84
/svn/!svn/ver/24521/tags/release-0-23/mythtv/bindings/python/MythTV/tmdb/tmdb_api.py
V 86
/svn/!svn/ver/25397/tags/release-0-23-1/mythtv/bindings/python/MythTV/tmdb/tmdb_api.py
END
tmdb_ui.py
K 25
svn:wc:ra_dav:version-url
V 83
/svn/!svn/ver/24521/tags/release-0-23/mythtv/bindings/python/MythTV/tmdb/tmdb_ui.py
V 85
/svn/!svn/ver/25397/tags/release-0-23-1/mythtv/bindings/python/MythTV/tmdb/tmdb_ui.py
END
tmdb_exceptions.py
K 25
svn:wc:ra_dav:version-url
V 91
/svn/!svn/ver/24521/tags/release-0-23/mythtv/bindings/python/MythTV/tmdb/tmdb_exceptions.py
V 93
/svn/!svn/ver/25397/tags/release-0-23-1/mythtv/bindings/python/MythTV/tmdb/tmdb_exceptions.py
END

View File

@ -1,8 +1,8 @@
10
dir
25361
http://svn.mythtv.org/svn/tags/release-0-23/mythtv/bindings/python/MythTV/tmdb
25726
http://svn.mythtv.org/svn/tags/release-0-23-1/mythtv/bindings/python/MythTV/tmdb
http://svn.mythtv.org/svn
@ -32,7 +32,7 @@ file
2010-07-16T22:31:04.000000Z
2010-08-18T01:49:43.000000Z
d41d8cd98f00b204e9800998ecf8427e
2010-01-29T01:39:37.380922Z
23354
@ -66,7 +66,7 @@ file
2010-07-16T22:31:04.000000Z
2010-08-18T01:49:43.000000Z
80afb5dbadea4de7d5ed5d0e1fa956bf
2010-04-29T22:38:50.878564Z
24305
@ -100,7 +100,7 @@ file
2010-07-16T22:31:04.000000Z
2010-08-18T01:49:43.000000Z
89285d26d830a7a0fc71f92e4f60f815
2010-04-12T22:36:01.726283Z
24097
@ -134,7 +134,7 @@ file
2010-07-16T22:31:04.000000Z
2010-08-18T01:49:43.000000Z
d6d57ccfa5baa9fd79eb04eb3b6e7aff
2010-01-29T01:39:37.380922Z
23354

View File

@ -1,41 +1,41 @@
K 25
svn:wc:ra_dav:version-url
V 73
/svn/!svn/ver/24521/tags/release-0-23/mythtv/bindings/python/MythTV/ttvdb
V 75
/svn/!svn/ver/25397/tags/release-0-23-1/mythtv/bindings/python/MythTV/ttvdb
END
tvdb_api.py
K 25
svn:wc:ra_dav:version-url
V 85
/svn/!svn/ver/24521/tags/release-0-23/mythtv/bindings/python/MythTV/ttvdb/tvdb_api.py
V 87
/svn/!svn/ver/25397/tags/release-0-23-1/mythtv/bindings/python/MythTV/ttvdb/tvdb_api.py
END
ttvdb-example.conf
K 25
svn:wc:ra_dav:version-url
V 92
/svn/!svn/ver/24521/tags/release-0-23/mythtv/bindings/python/MythTV/ttvdb/ttvdb-example.conf
V 94
/svn/!svn/ver/25397/tags/release-0-23-1/mythtv/bindings/python/MythTV/ttvdb/ttvdb-example.conf
END
tvdb_ui.py
K 25
svn:wc:ra_dav:version-url
V 84
/svn/!svn/ver/24521/tags/release-0-23/mythtv/bindings/python/MythTV/ttvdb/tvdb_ui.py
V 86
/svn/!svn/ver/25397/tags/release-0-23-1/mythtv/bindings/python/MythTV/ttvdb/tvdb_ui.py
END
__init__.py
K 25
svn:wc:ra_dav:version-url
V 85
/svn/!svn/ver/24521/tags/release-0-23/mythtv/bindings/python/MythTV/ttvdb/__init__.py
V 87
/svn/!svn/ver/25397/tags/release-0-23-1/mythtv/bindings/python/MythTV/ttvdb/__init__.py
END
tvdb_exceptions.py
K 25
svn:wc:ra_dav:version-url
V 92
/svn/!svn/ver/24521/tags/release-0-23/mythtv/bindings/python/MythTV/ttvdb/tvdb_exceptions.py
V 94
/svn/!svn/ver/25397/tags/release-0-23-1/mythtv/bindings/python/MythTV/ttvdb/tvdb_exceptions.py
END
cache.py
K 25
svn:wc:ra_dav:version-url
V 82
/svn/!svn/ver/24521/tags/release-0-23/mythtv/bindings/python/MythTV/ttvdb/cache.py
V 84
/svn/!svn/ver/25397/tags/release-0-23-1/mythtv/bindings/python/MythTV/ttvdb/cache.py
END

View File

@ -1,8 +1,8 @@
10
dir
25361
http://svn.mythtv.org/svn/tags/release-0-23/mythtv/bindings/python/MythTV/ttvdb
25726
http://svn.mythtv.org/svn/tags/release-0-23-1/mythtv/bindings/python/MythTV/ttvdb
http://svn.mythtv.org/svn
@ -32,7 +32,7 @@ file
2010-07-16T22:31:04.000000Z
2010-08-18T01:49:43.000000Z
554f84950a1f7cc2bab09477c3798f18
2010-01-29T01:39:37.380922Z
23354
@ -66,7 +66,7 @@ file
2010-07-16T22:31:04.000000Z
2010-08-18T01:49:43.000000Z
8a9a6d831a1892828eb38318b114f0b0
2010-01-29T01:39:37.380922Z
23354
@ -100,7 +100,7 @@ file
2010-07-16T22:31:04.000000Z
2010-08-18T01:49:43.000000Z
305a22b10a8be8dfef8ff90c399d9a38
2010-01-29T01:39:37.380922Z
23354
@ -134,7 +134,7 @@ file
2010-07-16T22:31:04.000000Z
2010-08-18T01:49:43.000000Z
d41d8cd98f00b204e9800998ecf8427e
2010-01-29T01:39:37.380922Z
23354
@ -168,7 +168,7 @@ file
2010-07-16T22:31:04.000000Z
2010-08-18T01:49:43.000000Z
90ce82c602de1cc41d603c01563d3bfb
2010-01-29T01:39:37.380922Z
23354
@ -202,7 +202,7 @@ file
2010-07-16T22:31:04.000000Z
2010-08-18T01:49:43.000000Z
e904998a5a3c1e088dc5b00a57947127
2010-01-29T01:39:37.380922Z
23354

1868
patches/MythBase.py.orig Executable file

File diff suppressed because it is too large Load Diff

1504
patches/MythData.py.orig Executable file

File diff suppressed because it is too large Load Diff

131
patches/mythbase.patch Normal file
View File

@ -0,0 +1,131 @@
--- mythtv_old/MythBase.py 2010-07-31 08:46:35.000000000 -0400
+++ mythtv/MythBase.py 2010-08-17 21:49:43.000000000 -0400
@@ -7,18 +7,15 @@
from MythStatic import *
import os, re, socket, sys, locale, weakref
-from xml import *
+import xml.etree.cElementTree as etree
from datetime import datetime
from time import sleep, time
from urllib import urlopen
from subprocess import Popen
from sys import version_info
-#import MySQLdb, MySQLdb.cursors
-#MySQLdb.__version__ = tuple([v for v in MySQLdb.__version__.split('.')])
-
-import mysql.connector
-import mysql.connector.cursor
+import MySQLdb, MySQLdb.cursors
+MySQLdb.__version__ = tuple([v for v in MySQLdb.__version__.split('.')])
class DictData( object ):
"""
@@ -742,19 +739,19 @@
del self.hash[index]
del self.data[index]
-class MythDBCursor( mysql.connector.cursor.MySQLCursor ):
+class MythDBCursor( MySQLdb.cursors.Cursor ):
"""
Custom cursor, offering logging and error handling
"""
def __init__(self, connection):
self.log = None
- mysql.connector.cursor.MySQLCursor.__init__(self, connection)
+ MySQLdb.cursors.Cursor.__init__(self, connection)
def execute(self, query, args=None):
- #if MySQLdb.__version__ >= ('1','2','2'):
- # self.connection.ping(True)
- #else:
- # self.connection.ping()
+ if MySQLdb.__version__ >= ('1','2','2'):
+ self.connection.ping(True)
+ else:
+ self.connection.ping()
if self.log == None:
self.log = MythLog('Python Database Connection')
if args:
@@ -762,21 +759,21 @@
else:
self.log(self.log.DATABASE, ' '.join(query.split()))
try:
- return mysql.connector.cursor.MySQLCursor.execute(self, query, args)
+ return MySQLdb.cursors.Cursor.execute(self, query, args)
except Exception, e:
raise MythDBError(MythDBError.DB_RAW, e.args)
def executemany(self, query, args):
- #if MySQLdb.__version__ >= ('1','2','2'):
- # self.connection.ping(True)
- #else:
- # self.connection.ping()
+ if MySQLdb.__version__ >= ('1','2','2'):
+ self.connection.ping(True)
+ else:
+ self.connection.ping()
if self.log == None:
self.log = MythLog('Python Database Connection')
for arg in args:
self.log(self.log.DATABASE, ' '.join(query.split()), str(arg))
try:
- return mysql.connector.cursor.MySQLCursor.executemany(self, query, args)
+ return MySQLdb.cursors.Cursor.executemany(self, query, args)
except Exception, e:
raise MythDBError(MythDBError.DB_RAW, e.args)
@@ -793,23 +790,22 @@
try:
self.log(MythLog.DATABASE, "Attempting connection",
str(dbconn))
- self.db = mysql.connector.connect(user=dbconn['DBUserName'],
- host=dbconn['DBHostName'],
- password=dbconn['DBPassword'],
- db=dbconn['DBName'],
- port=dbconn['DBPort'],
- use_unicode=True,
- charset='utf8')
+ self.db = MySQLdb.connect( user= dbconn['DBUserName'],
+ host= dbconn['DBHostName'],
+ passwd= dbconn['DBPassword'],
+ db= dbconn['DBName'],
+ port= dbconn['DBPort'],
+ use_unicode=True,
+ charset='utf8')
except:
raise MythDBError(MythError.DB_CONNECTION, dbconn)
def cursor(self, log=None, type=MythDBCursor):
- #if MySQLdb.__version__ >= ('1','2','2'):
- # self.db.ping(True)
- #else:
- # self.db.ping()
- #c = self.db.cursor(type)
- c = self.db.cursor()
+ if MySQLdb.__version__ >= ('1','2','2'):
+ self.db.ping(True)
+ else:
+ self.db.ping()
+ c = self.db.cursor(type)
if log:
c.log = log
else:
@@ -1000,6 +996,7 @@
else:
# fall back to UPnP
dbconn = self._listenUPNP(dbconn['SecurityPin'], 5.0)
+
# push data to new settings file
settings = [dbconn[key] for key in \
('SecurityPin','DBHostName','DBUserName',
@@ -1449,7 +1446,7 @@
ind1 = xmlstr.find('xmlns')
ind2 = xmlstr.find('"', ind1+7) + 1
xmlstr = xmlstr[:ind1] + xmlstr[ind2:]
- return etree.ElementTree.fromstring(xmlstr)
+ return etree.fromstring(xmlstr)
def getConnectionInfo(self, pin=0):
"""Return dbconn dict from backend connection info."""

28
patches/mythdata.patch Normal file
View File

@ -0,0 +1,28 @@
--- mythtv_old/MythData.py 2010-08-07 21:55:58.000000000 -0400
+++ mythtv/MythData.py 2010-08-17 21:49:43.000000000 -0400
@@ -175,7 +175,7 @@
if not self.open:
return
self.control.backendCommand('QUERY_FILETRANSFER '\
- +BACKEND_SEP.join([str(self.sockno), 'JOIN']))
+ +BACKEND_SEP.join([str(self.sockno), 'DONE']))
self.socket.shutdown(1)
self.socket.close()
self.open = False
@@ -521,12 +521,14 @@
"""Program.getRecorded() -> Recorded object"""
return Recorded((self.chanid,self.recstartts), db=self.db)
- def open(self, type='r', dba=None):
+ def open(self, type='r'):
"""Program.open(type='r') -> file or FileTransfer object"""
if type != 'r':
raise MythFileError(MythError.FILE_FAILED_WRITE, self.filename,
'Program () objects cannot be opened for writing')
- return ftopen(self.filename, 'r', forceremote=False, nooverwrite=False, db=dba)
+ if not self.filename.startswith('myth://'):
+ self.filename = 'myth://%s/%s' % (self.hostname, self.filename)
+ return ftopen(self.filename, 'r')
class Record( DBDataWrite ):
"""

View File

@ -1,22 +0,0 @@
<?xml version="1.0"?>
<window type="window" id="14001">
<defaultcontrol always="true">9001</defaultcontrol>
<allowoverlay>yes</allowoverlay>
<controls>
<control type="image" id="1001">
<width>1280</width>
<height>720</height>
<texture>mb_bg_setup.png</texture>
<animation effect="fade" start="85" end="85" time="0" condition="true">Conditional</animation>
</control>
<control type="image" id="1002">
<description>logo</description>
<posx>450</posx>
<posy>250</posy>
<width>402</width>
<height>107</height>
<texture flipY="true" flipX="false">logo.png</texture>
<aspectratio>keep</aspectratio>
</control>
</controls>
</window>

View File

@ -1,45 +1,45 @@
<?xml version="1.0"?>
<window type="window" id="14010">
<defaultcontrol always="true">13</defaultcontrol>
<window type="window" id="14001">
<defaultcontrol always="true">1030</defaultcontrol>
<allowoverlay>yes</allowoverlay>
<onload lang="python"><![CDATA[
import mythboxee
from mythboxee import MythBoxee
mb = MythBoxee()
mb.GetRecordings()
]]></onload>
<onunload lang="python">
<![CDATA[
mc.ActivateWindow(10482)
]]>
</onunload>
<controls>
<control type="visualisation" id ="2001">
<width>1280</width>
<height>720</height>
<visible>Control.IsVisible(2000)</visible>
<control type="group" id="1010">
<control type="image" id="1011">
<width>1280</width>
<height>720</height>
<texture>mb_bg_setup.png</texture>
</control>
<control type="image" id="1012">
<description>logo</description>
<posx>450</posx>
<posy>250</posy>
<width>402</width>
<height>107</height>
<texture flipY="true" flipX="false">logo.png</texture>
<aspectratio>keep</aspectratio>
</control>
</control>
<control type="image">
<width>1280</width>
<height>720</height>
<texture>mb_bg.png</texture>
<animation effect="fade" start="85" end="85" time="0" condition="true">Conditional</animation>
<control type="group" id="1020">
<control type="image" id="1021">
<width>1280</width>
<height>720</height>
<texture>mb_bg.png</texture>
</control>
</control>
<control type="grouplist" id="2002">
<posy>11</posy>
<posx>216</posx>
<itemgap>20</itemgap>
<ondown>2000</ondown>
<orientation>horizontal</orientation>
</control>
<!-- SHOW LIST -->
<control type="panel" id="13">
<control type="panel" id="1030">
<posx>22</posx>
<posy>82</posy>
<width>1280</width>
<height>592</height>
<onleft>122</onleft>
<onright>112</onright>
<onleft>-</onleft>
<onright>-</onright>
<onup>-</onup>
<ondown>-</ondown>
<itemlayout width="420" height="120">
@ -66,7 +66,7 @@ mc.ActivateWindow(10482)
<description>show title</description>
<posx>10</posx>
<posy>75</posy>
<width>152</width>
<width>250</width>
<height>60</height>
<align>left</align>
<aligny>top</aligny>
@ -76,16 +76,16 @@ mc.ActivateWindow(10482)
</control>
<control type="label">
<description>videos</description>
<posx>275</posx>
<posx>385</posx>
<posy>76</posy>
<width>152</width>
<height>60</height>
<align>left</align>
<align>right</align>
<aligny>top</aligny>
<label>Recordings: $INFO[ListItem.property(custom:videos)]</label>
<font>font14</font>
<textcolor>FFCCCCCC</textcolor>
</control>
</control>
</itemlayout>
<focusedlayout width="420" height="120">
<control type="togglebutton">
@ -98,7 +98,7 @@ mc.ActivateWindow(10482)
<texturenofocus border="5">mb_item_big_hover.png</texturenofocus>
<alttexturefocus border="5">mb_item_big.png</alttexturefocus>
<alttexturenofocus border="5">mb_item_big.png</alttexturenofocus>
<usealttexture>!Control.HasFocus(13)</usealttexture>
<usealttexture>!Control.HasFocus(1030)</usealttexture>
</control>
<control type="image">
<description>thumbnail</description>
@ -121,13 +121,13 @@ mc.ActivateWindow(10482)
<aspectratio>scale</aspectratio>
<bordertexture>mb_thumb_hover_bg.png</bordertexture>
<bordersize>3</bordersize>
<visible>Control.HasFocus(13)</visible>
<visible>Control.HasFocus(1030)</visible>
</control>
<control type="label">
<description>show title</description>
<posx>10</posx>
<posy>75</posy>
<width>152</width>
<width>250</width>
<height>60</height>
<align>left</align>
<aligny>top</aligny>
@ -138,11 +138,11 @@ mc.ActivateWindow(10482)
</control>
<control type="label">
<description>videos</description>
<posx>275</posx>
<posx>385</posx>
<posy>76</posy>
<width>152</width>
<height>60</height>
<align>left</align>
<align>right</align>
<aligny>top</aligny>
<label>Recordings: $INFO[ListItem.property(custom:videos)]</label>
<font>font14</font>
@ -151,7 +151,7 @@ mc.ActivateWindow(10482)
</control>
</focusedlayout>
<content type="action">
<onclick lang="python"><![CDATA[mythboxee.LoadSingleShow()]]></onclick>
<onclick lang="python"><![CDATA[mb.DisplayShow()]]></onclick>
</content>
</control>
</controls>

View File

View File

@ -65,10 +65,10 @@
<onright>6013</onright>
<onclick lang="python">
<![CDATA[
pin = mc.GetWindow(14006).GetEdit(6011).GetText()
pin = mc.GetWindow(14002).GetEdit(6011).GetText()
mc.GetApp().GetLocalConfig().SetValue("pin", pin)
mc.ShowDialogNotification(pin)
mc.ActivateWindow(14005)
mc.ActivateWindow(14002)
]]>
</onclick>
</control>
@ -169,7 +169,7 @@ mc.CloseWindow()
<onup>6024</onup>
<onright>6026</onright>
<onclick lang="python"><![CDATA[
pin = mc.GetWindow(14006).GetEdit(6003).GetText()
pin = mc.GetWindow(14002).GetEdit(6003).GetText()
mc.GetApp().GetLocalConfig().SetValue("pin", pin)
]]></onclick>
</control>

View File

@ -1,31 +1,45 @@
<?xml version="1.0"?>
<window type="window" id="14011">
<defaultcontrol always="true">2013</defaultcontrol>
<allowoverlay>no</allowoverlay>
<window type="window" id="14002">
<defaultcontrol always="true">2040</defaultcontrol>
<allowoverlay>true</allowoverlay>
<onload lang="python"><![CDATA[
import mythboxee
mb.LoadShow()
]]></onload>
<controls>
<control type="image">
<width>1280</width>
<height>720</height>
<texture>mb_bg.png</texture>
<animation effect="fade" start="85" end="85" time="0" condition="true">Conditional</animation>
<!--
<control type="group" id="2010">
<control type="image" id="2011">
<width>1280</width>
<height>720</height>
<texture>mb_bg_setup.png</texture>
</control>
<control type="image" id="2012">
<description>logo</description>
<posx>450</posx>
<posy>250</posy>
<width>402</width>
<height>107</height>
<texture flipY="true" flipX="false">logo.png</texture>
<aspectratio>keep</aspectratio>
</control>
</control>
<control type="grouplist" id="2000">
<posy>9</posy>
<posx>1110</posx>
<itemgap>20</itemgap>
<ondown>2013</ondown>
<orientation>horizontal</orientation>
-->
<control type="group" id="2020">
<control type="image" id="202060">
<width>1280</width>
<height>720</height>
<texture>mb_bg.png</texture>
</control>
</control>
<control type="group" id="2012">
<control type="group" id="2030">
<description>details box</description>
<posx>28</posx>
<posy>81</posy>
<onleft>-</onleft>
<onright>2013</onright>
<onright>2040</onright>
<onup>-</onup>
<ondown>-</ondown>
<control type="image">
@ -42,7 +56,7 @@ import mythboxee
<posy>10</posy>
<width>253</width>
<height>350</height>
<texture>$INFO[Container(21).ListItem.Thumb]</texture>
<texture>$INFO[Container(2070).ListItem.Thumb]</texture>
<aspectratio>scale</aspectratio>
<fadetime>500</fadetime>
</control>
@ -55,70 +69,24 @@ import mythboxee
<align>left</align>
<aligny>top</aligny>
<scroll>true</scroll>
<label>$INFO[Container(21).ListItem.Label]</label>
<label>$INFO[Container(2070).ListItem.Label]</label>
<font>font16b</font>
<textcolor>FFFEFEFE</textcolor>
<wrapmultiline>true</wrapmultiline>
</control>
<control type="label">
<description>recordings</description>
<visible>!stringcompare(Container(21).ListItem.property(custom:category),movie)</visible>
<posx>22</posx>
<posy>400</posy>
<width>228</width>
<height>20</height>
<align>left</align>
<aligny>top</aligny>
<scroll>true</scroll>
<label>Recordings: $INFO[Container(21).ListItem.property(custom:videos)]</label>
<font>font16b</font>
<textcolor>FFCCCCCC</textcolor>
<wrapmultiline>false</wrapmultiline>
</control>
<control type="textbox">
<visible>!stringcompare(Container(21).ListItem.property(custom:category),movie)</visible>
<description>description</description>
<posx>22</posx>
<posy>430</posy>
<width>228</width>
<height>160</height>
<align>left</align>
<aligny>top</aligny>
<scroll>true</scroll>
<label>$INFO[Container(21).ListItem.property(description)]</label>
<font>font16</font>
<textcolor>FFCCCCCC</textcolor>
<autoscroll delay="3000" time="2000" repeat="10000">Control.HasFocus(2013)</autoscroll>
</control>
<control type="label">
<visible>stringcompare(Container(21).ListItem.property(custom:category),movie)</visible>
<description>videos</description>
<posx>22</posx>
<posy>400</posy>
<width>228</width>
<height>20</height>
<align>left</align>
<aligny>top</aligny>
<scroll>true</scroll>
<label>Recordings: $INFO[Container(21).ListItem.property(custom:videos)]</label>
<font>font16b</font>
<textcolor>FFCCCCCC</textcolor>
<wrapmultiline>false</wrapmultiline>
</control>
<control type="textbox">
<description>description</description>
<visible>stringcompare(Container(21).ListItem.property(custom:category),movie)</visible>
<posx>22</posx>
<posy>430</posy>
<posy>395</posy>
<width>228</width>
<height>160</height>
<height>195</height>
<align>left</align>
<aligny>top</aligny>
<scroll>true</scroll>
<label>$INFO[Container(21).ListItem.property(description)]</label>
<label>$INFO[Container(2070).ListItem.property(description)]</label>
<font>font16</font>
<textcolor>FFCCCCCC</textcolor>
<autoscroll delay="3000" time="2000" repeat="10000">Control.HasFocus(2013)</autoscroll>
<autoscroll delay="3000" time="2000" repeat="10000">Control.HasFocus(2040)</autoscroll>
</control>
</control>
@ -126,18 +94,20 @@ import mythboxee
<!-- begin EPISODES LIST -->
<control type="list" id="2013">
<control type="list" id="2040">
<posx>345</posx>
<posy>82</posy>
<width>700</width>
<height>592</height>
<onleft>2012</onleft>
<onright>2014</onright>
<onup>2000</onup>
<onleft>-</onleft>
<onright>2051</onright>
<onup>-</onup>
<ondown>-</ondown>
<!--
<animation condition="Control.IsVisible(14)" type="Conditional" reversible="false">
<effect end="100" start="0" time="200" type="fade" />
</animation>
-->
<itemlayout width="700" height="85">
<control type="image">
<description>background</description>
@ -208,7 +178,7 @@ import mythboxee
<texturenofocus border="5">mb_item_big_hover.png</texturenofocus>
<alttexturefocus border="5">mb_item_big.png</alttexturefocus>
<alttexturenofocus border="5">mb_item_big.png</alttexturenofocus>
<usealttexture>!Control.HasFocus(2013)</usealttexture>
<usealttexture>!Control.HasFocus(2040)</usealttexture>
</control>
<control type="image">
<description>thumbnail</description>
@ -231,7 +201,7 @@ import mythboxee
<aspectratio>scale</aspectratio>
<bordertexture>mb_thumb_hover_bg.png</bordertexture>
<bordersize>3</bordersize>
<visible>Control.HasFocus(2013)</visible>
<visible>Control.HasFocus(2040)</visible>
</control>
<control type="label">
<description>episode title</description>
@ -271,156 +241,166 @@ import mythboxee
<wrapmultiline>true</wrapmultiline>
</control>
</focusedlayout>
<!--
<content type="action">
<onfocus lang="python"><![CDATA[mythboxee.ShowEpisodeDetails()]]></onfocus>
<onclick lang="python"><![CDATA[mb.PlayRecording()]]></onclick>
</content>
-->
</control>
<!-- end EPISODES LIST -->
<!-- begin SORT LIST -->
<control type="label">
<posx>1079</posx>
<posy>75</posy>
<label>SORT:</label>
<font>font14b</font>
<aligny>top</aligny>
<textcolor>FF999999</textcolor>
</control>
<control type="group" id="2050">
<control type="label">
<posx>1079</posx>
<posy>75</posy>
<label>SORT:</label>
<font>font14b</font>
<aligny>top</aligny>
<textcolor>FF999999</textcolor>
</control>
<control type="list" id="2014">
<posx>1070</posx>
<posy>100</posy>
<width>164</width>
<height>100</height>
<onleft>2013</onleft>
<onright>-</onright>
<onup>-</onup>
<ondown>2015</ondown>
<itemlayout width="164" height="27">
<control type="label">
<description>title</description>
<posx>9</posx>
<posy>0</posy>
<width>146</width>
<height>25</height>
<align>left</align>
<aligny>top</aligny>
<info>ListItem.Label</info>
<font>font16</font>
<textcolor>FF999999</textcolor>
<selectedcolor>FFFFFFFF</selectedcolor>
</control>
</itemlayout>
<focusedlayout width="164" height="27">
<control type="label">
<description>title</description>
<posx>9</posx>
<posy>0</posy>
<width>146</width>
<height>25</height>
<align>left</align>
<aligny>top</aligny>
<info>ListItem.Label</info>
<font>font16</font>
<textcolor>FFFFFFFF</textcolor>
<visible>Control.HasFocus(2014)</visible>
<selectedcolor>FFFFFFFF</selectedcolor>
</control>
<control type="label">
<visible>!Control.HasFocus(2014)</visible>
<description>title</description>
<posx>9</posx>
<posy>0</posy>
<width>146</width>
<height>25</height>
<align>left</align>
<aligny>top</aligny>
<info>ListItem.Label</info>
<font>font16</font>
<textcolor>FF999999</textcolor>
<selectedcolor>FFFFFFFF</selectedcolor>
</control>
</focusedlayout>
<content type="action">
<onclick lang="python"><![CDATA[mythboxee.SortBySeriesEpisodes()]]></onclick>
</content>
<control type="list" id="2051">
<posx>1070</posx>
<posy>100</posy>
<width>164</width>
<height>100</height>
<onleft>2040</onleft>
<onright>-</onright>
<onup>-</onup>
<ondown>2061</ondown>
<itemlayout width="164" height="27">
<control type="label">
<description>title</description>
<posx>9</posx>
<posy>0</posy>
<width>146</width>
<height>25</height>
<align>left</align>
<aligny>top</aligny>
<info>ListItem.Label</info>
<font>font16</font>
<textcolor>FF999999</textcolor>
<selectedcolor>FFFFFFFF</selectedcolor>
</control>
</itemlayout>
<focusedlayout width="164" height="27">
<control type="label">
<description>title</description>
<posx>9</posx>
<posy>0</posy>
<width>146</width>
<height>25</height>
<align>left</align>
<aligny>top</aligny>
<info>ListItem.Label</info>
<font>font16</font>
<textcolor>FFFFFFFF</textcolor>
<visible>Control.HasFocus(2051)</visible>
<selectedcolor>FFFFFFFF</selectedcolor>
</control>
<control type="label">
<visible>!Control.HasFocus(2051)</visible>
<description>title</description>
<posx>9</posx>
<posy>0</posy>
<width>146</width>
<height>25</height>
<align>left</align>
<aligny>top</aligny>
<info>ListItem.Label</info>
<font>font16</font>
<textcolor>FF999999</textcolor>
<selectedcolor>FFFFFFFF</selectedcolor>
</control>
</focusedlayout>
<content type="action">
<onclick lang="python"><![CDATA[mythboxee.SortBySeriesEpisodes()]]></onclick>
</content>
</control>
</control>
<!-- end SORT LIST -->
<control type="label">
<posx>1079</posx>
<posy>200</posy>
<label>SORT DIRECTION:</label>
<font>font14b</font>
<aligny>top</aligny>
<textcolor>FF999999</textcolor>
<control type="group" id="2060">
<control type="label">
<posx>1079</posx>
<posy>200</posy>
<label>SORT DIRECTION:</label>
<font>font14b</font>
<aligny>top</aligny>
<textcolor>FF999999</textcolor>
</control>
<control type="list" id="2061">
<posx>1070</posx>
<posy>225</posy>
<width>164</width>
<height>100</height>
<onleft>2040</onleft>
<onright>-</onright>
<onup>2051</onup>
<ondown>-</ondown>
<itemlayout width="164" height="27">
<control type="label">
<description>title</description>
<posx>9</posx>
<posy>0</posy>
<width>146</width>
<height>25</height>
<align>left</align>
<aligny>top</aligny>
<info>ListItem.Label</info>
<font>font16</font>
<textcolor>FF999999</textcolor>
<selectedcolor>FFFFFFFF</selectedcolor>
</control>
</itemlayout>
<focusedlayout width="164" height="27">
<control type="label">
<description>title</description>
<posx>9</posx>
<posy>0</posy>
<width>146</width>
<height>25</height>
<align>left</align>
<aligny>top</aligny>
<info>ListItem.Label</info>
<font>font16</font>
<textcolor>FFFFFFFF</textcolor>
<visible>Control.HasFocus(2061)</visible>
<selectedcolor>FFFFFFFF</selectedcolor>
</control>
<control type="label">
<visible>!Control.HasFocus(2061)</visible>
<description>title</description>
<posx>9</posx>
<posy>0</posy>
<width>146</width>
<height>25</height>
<align>left</align>
<aligny>top</aligny>
<info>ListItem.Label</info>
<font>font16</font>
<textcolor>FF999999</textcolor>
<selectedcolor>FFFFFFFF</selectedcolor>
</control>
</focusedlayout>
<content type="action">
<onclick lang="python"><![CDATA[mythboxee.SortDirSeriesEpisodes()]]></onclick>
</content>
</control>
</control>
<control type="list" id="2015">
<posx>1070</posx>
<posy>225</posy>
<width>164</width>
<height>100</height>
<onleft>2013</onleft>
<onright>-</onright>
<onup>2014</onup>
<ondown>-</ondown>
<itemlayout width="164" height="27">
<control type="label">
<description>title</description>
<posx>9</posx>
<posy>0</posy>
<width>146</width>
<height>25</height>
<align>left</align>
<aligny>top</aligny>
<info>ListItem.Label</info>
<font>font16</font>
<textcolor>FF999999</textcolor>
<selectedcolor>FFFFFFFF</selectedcolor>
</control>
</itemlayout>
<focusedlayout width="164" height="27">
<control type="label">
<description>title</description>
<posx>9</posx>
<posy>0</posy>
<width>146</width>
<height>25</height>
<align>left</align>
<aligny>top</aligny>
<info>ListItem.Label</info>
<font>font16</font>
<textcolor>FFFFFFFF</textcolor>
<visible>Control.HasFocus(2015)</visible>
<selectedcolor>FFFFFFFF</selectedcolor>
</control>
<control type="label">
<visible>!Control.HasFocus(2015)</visible>
<description>title</description>
<posx>9</posx>
<posy>0</posy>
<width>146</width>
<height>25</height>
<align>left</align>
<aligny>top</aligny>
<info>ListItem.Label</info>
<font>font16</font>
<textcolor>FF999999</textcolor>
<selectedcolor>FFFFFFFF</selectedcolor>
</control>
</focusedlayout>
<content type="action">
<onclick lang="python"><![CDATA[mythboxee.SortDirSeriesEpisodes()]]></onclick>
</content>
</control>
<!-- begin SHOW DETAILS CONTAINER -->
<control type="list" id="21">
<control type="list" id="2070">
<posx>1</posx>
<posy>1</posy>
<width>1</width>
@ -432,24 +412,6 @@ import mythboxee
</control>
<!-- end SHOW DETAILS CONTAINER -->
<!--
<control type="multiimage" id="30">
<description>loading control</description>
<visible>Container(21).IsLoading | Container(13).IsLoading | Container(20).IsLoading</visible>
<animation effect="fade" time="200">VisibleChange</animation>
<posx>538</posx>
<posy>306</posy>
<width>200</width>
<height>200</height>
<imagepath>loading</imagepath>
<timeperimage>80</timeperimage>
<fadetime>10</fadetime>
<pauseatend>0</pauseatend>
<randomize>false</randomize>
<loop>yes</loop>
<aspectratio>keep</aspectratio>
</control>
-->
</controls>
</window>

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB