updated mythtv library
This commit is contained in:
parent
6a26761cc7
commit
cc5de9acf4
|
@ -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()
|
||||
|
||||
|
|
415
mythboxee.py
415
mythboxee.py
|
@ -4,31 +4,47 @@ 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"
|
||||
|
||||
userAgent = "MythBoxee v4.0.beta"
|
||||
tvdb_apikey = "6BEAB4CB5157AAE0"
|
||||
|
||||
be = None
|
||||
db = None
|
||||
|
||||
recs = None
|
||||
titles = []
|
||||
recordings = []
|
||||
idbanners = {}
|
||||
banners = {}
|
||||
shows = {}
|
||||
series = {}
|
||||
|
||||
|
||||
"""
|
||||
DiscoverBackend - just as it sounds
|
||||
|
||||
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():
|
||||
mc.ShowDialogNotification("DiscoverBackend")
|
||||
self.log("def(DiscoverBackend)")
|
||||
|
||||
pin = config.GetValue("pin")
|
||||
dbconn = config.GetValue("dbconn")
|
||||
pin = self.config.GetValue("pin")
|
||||
dbconn = self.config.GetValue("dbconn")
|
||||
|
||||
if not pin:
|
||||
pin = 0000
|
||||
|
||||
try:
|
||||
db = mythtv.MythDB(SecurityPin=pin)
|
||||
self.db = mythtv.MythDB(SecurityPin=pin)
|
||||
except Exception, e:
|
||||
mc.ShowDialogNotification(e.message)
|
||||
if e.ename == 'DB_CREDENTIALS' and count < 3:
|
||||
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)
|
||||
|
@ -40,84 +56,225 @@ def DiscoverBackend():
|
|||
mc.GetWindow(14002).GetControl(6021).SetFocus()
|
||||
return False
|
||||
else:
|
||||
mc.ShowDialogNotification(str(db.dbconn))
|
||||
config.SetValue("dbconn", str(db.dbconn))
|
||||
self.config.SetValue("dbconn", str(self.db.dbconn))
|
||||
return True
|
||||
|
||||
|
||||
def Launch():
|
||||
"""
|
||||
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 config.GetValue("dbconn"):
|
||||
if not self.config.GetValue("dbconn"):
|
||||
discoverBackend = False
|
||||
while discoverBackend is False:
|
||||
discoverBackend = DiscoverBackend()
|
||||
print "discover"
|
||||
discoverBackend = self.DiscoverBackend()
|
||||
|
||||
# Parse our DB info
|
||||
dbconn = config.GetValue("dbconn")
|
||||
dbconn = self.config.GetValue("dbconn")
|
||||
dbconf = eval(dbconn)
|
||||
|
||||
# Now that the backend has been discovered, lets connect.
|
||||
try:
|
||||
mbdb = mythtv.MythDB(**dbconf)
|
||||
self.db = 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)
|
||||
self.be = mythtv.MythBE(db=self.db)
|
||||
|
||||
"""
|
||||
GetRecordings - Pulls all of the recordings out of the backend.
|
||||
|
||||
def LoadShows():
|
||||
del titles[:]
|
||||
del recordings[:]
|
||||
idbanners.clear()
|
||||
shows.clear()
|
||||
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 = {}
|
||||
|
||||
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] = []
|
||||
self.log("def(GetRecordings)")
|
||||
|
||||
single = [title,subtitle,desc,chanid,airdate,starttime,endtime]
|
||||
recordings.append(single)
|
||||
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)] = []
|
||||
|
||||
titles.sort()
|
||||
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()
|
||||
|
||||
items = mc.ListItems()
|
||||
for title in titles:
|
||||
for title in self.titles:
|
||||
item = mc.ListItem( mc.ListItem.MEDIA_UNKNOWN )
|
||||
item.SetLabel(title)
|
||||
item.SetThumbnail(idbanners[title][1])
|
||||
item.SetProperty("seriesid", idbanners[title][0])
|
||||
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(14000).GetList(13).SetItems(items)
|
||||
mc.GetWindow(14001).GetList(1030).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)
|
||||
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)
|
||||
|
||||
SetSortables()
|
||||
GetSetSeriesDetails(name, item.GetProperty("seriesid"))
|
||||
LoadSeriesEpisodes(name)
|
||||
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
|
||||
|
||||
|
||||
def SetSortables():
|
||||
config.SetValue("SortBy", "Recorded Date")
|
||||
config.SetValue("SortDir", "Descending")
|
||||
"""
|
||||
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
|
||||
|
||||
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:
|
||||
|
@ -125,8 +282,8 @@ def SetSortables():
|
|||
item.SetLabel(sorttype)
|
||||
items.append(item)
|
||||
|
||||
mc.GetActiveWindow().GetList(2014).SetItems(items)
|
||||
mc.GetActiveWindow().GetList(2014).SetSelected(1, True)
|
||||
mc.GetWindow(14002).GetList(2051).SetItems(items)
|
||||
mc.GetWindow(14002).GetList(2051).SetSelected(1, True)
|
||||
|
||||
sortableby = ['Ascending', 'Descending']
|
||||
items = mc.ListItems()
|
||||
|
@ -135,136 +292,56 @@ def SetSortables():
|
|||
item.SetLabel(sorttype)
|
||||
items.append(item)
|
||||
|
||||
mc.GetActiveWindow().GetList(2015).SetItems(items)
|
||||
mc.GetActiveWindow().GetList(2015).SetSelected(1, True)
|
||||
mc.GetWindow(14002).GetList(2061).SetItems(items)
|
||||
mc.GetWindow(14002).GetList(2061).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):
|
||||
def SetSeriesDetails(self, title, seriesid):
|
||||
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 + "/")
|
||||
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(name)
|
||||
item.SetTitle(name)
|
||||
if overview:
|
||||
item.SetLabel(title)
|
||||
item.SetTitle(title)
|
||||
try:
|
||||
item.SetDescription(overview[0])
|
||||
item.SetProperty("description", overview[0])
|
||||
except:
|
||||
item.SetDescription("No Description")
|
||||
item.SetProperty("description", "No Description")
|
||||
|
||||
try:
|
||||
item.SetThumbnail("http://www.thetvdb.com/banners/" + poster[0])
|
||||
except:
|
||||
item.SetThumbnail("mb_poster_error.png")
|
||||
|
||||
items.append(item)
|
||||
|
||||
mc.GetWindow(14001).GetList(21).SetItems(items)
|
||||
mc.GetWindow(14002).GetList(2070).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
|
||||
|
||||
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
|
||||
|
|
336
mythboxy.py
336
mythboxy.py
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 ):
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 = '[]:[]'
|
||||
|
|
|
@ -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.
|
@ -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.
|
@ -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.
|
@ -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.
|
@ -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.
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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."""
|
|
@ -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 ):
|
||||
"""
|
|
@ -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>
|
|
@ -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">
|
||||
<control type="group" id="1010">
|
||||
<control type="image" id="1011">
|
||||
<width>1280</width>
|
||||
<height>720</height>
|
||||
<visible>Control.IsVisible(2000)</visible>
|
||||
<texture>mb_bg_setup.png</texture>
|
||||
</control>
|
||||
<control type="image">
|
||||
<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="group" id="1020">
|
||||
<control type="image" id="1021">
|
||||
<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>
|
||||
<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,11 +76,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>
|
||||
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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">
|
||||
<!--
|
||||
<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="group" id="2020">
|
||||
<control type="image" id="202060">
|
||||
<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>
|
||||
<control type="grouplist" id="2000">
|
||||
<posy>9</posy>
|
||||
<posx>1110</posx>
|
||||
<itemgap>20</itemgap>
|
||||
<ondown>2013</ondown>
|
||||
<orientation>horizontal</orientation>
|
||||
</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,15 +241,18 @@ 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="group" id="2050">
|
||||
<control type="label">
|
||||
<posx>1079</posx>
|
||||
<posy>75</posy>
|
||||
|
@ -289,15 +262,15 @@ import mythboxee
|
|||
<textcolor>FF999999</textcolor>
|
||||
</control>
|
||||
|
||||
<control type="list" id="2014">
|
||||
<control type="list" id="2051">
|
||||
<posx>1070</posx>
|
||||
<posy>100</posy>
|
||||
<width>164</width>
|
||||
<height>100</height>
|
||||
<onleft>2013</onleft>
|
||||
<onleft>2040</onleft>
|
||||
<onright>-</onright>
|
||||
<onup>-</onup>
|
||||
<ondown>2015</ondown>
|
||||
<ondown>2061</ondown>
|
||||
<itemlayout width="164" height="27">
|
||||
<control type="label">
|
||||
<description>title</description>
|
||||
|
@ -325,11 +298,11 @@ import mythboxee
|
|||
<info>ListItem.Label</info>
|
||||
<font>font16</font>
|
||||
<textcolor>FFFFFFFF</textcolor>
|
||||
<visible>Control.HasFocus(2014)</visible>
|
||||
<visible>Control.HasFocus(2051)</visible>
|
||||
<selectedcolor>FFFFFFFF</selectedcolor>
|
||||
</control>
|
||||
<control type="label">
|
||||
<visible>!Control.HasFocus(2014)</visible>
|
||||
<visible>!Control.HasFocus(2051)</visible>
|
||||
<description>title</description>
|
||||
<posx>9</posx>
|
||||
<posy>0</posy>
|
||||
|
@ -348,8 +321,12 @@ import mythboxee
|
|||
</content>
|
||||
</control>
|
||||
|
||||
</control>
|
||||
|
||||
<!-- end SORT LIST -->
|
||||
|
||||
<control type="group" id="2060">
|
||||
|
||||
<control type="label">
|
||||
<posx>1079</posx>
|
||||
<posy>200</posy>
|
||||
|
@ -359,14 +336,14 @@ import mythboxee
|
|||
<textcolor>FF999999</textcolor>
|
||||
</control>
|
||||
|
||||
<control type="list" id="2015">
|
||||
<control type="list" id="2061">
|
||||
<posx>1070</posx>
|
||||
<posy>225</posy>
|
||||
<width>164</width>
|
||||
<height>100</height>
|
||||
<onleft>2013</onleft>
|
||||
<onleft>2040</onleft>
|
||||
<onright>-</onright>
|
||||
<onup>2014</onup>
|
||||
<onup>2051</onup>
|
||||
<ondown>-</ondown>
|
||||
<itemlayout width="164" height="27">
|
||||
<control type="label">
|
||||
|
@ -395,11 +372,11 @@ import mythboxee
|
|||
<info>ListItem.Label</info>
|
||||
<font>font16</font>
|
||||
<textcolor>FFFFFFFF</textcolor>
|
||||
<visible>Control.HasFocus(2015)</visible>
|
||||
<visible>Control.HasFocus(2061)</visible>
|
||||
<selectedcolor>FFFFFFFF</selectedcolor>
|
||||
</control>
|
||||
<control type="label">
|
||||
<visible>!Control.HasFocus(2015)</visible>
|
||||
<visible>!Control.HasFocus(2061)</visible>
|
||||
<description>title</description>
|
||||
<posx>9</posx>
|
||||
<posy>0</posy>
|
||||
|
@ -418,9 +395,12 @@ import mythboxee
|
|||
</content>
|
||||
</control>
|
||||
|
||||
</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 |
Loading…
Reference in New Issue