too much to document, look at the source, updates include, caching, logging, laoding screen, performance enhancements, etc
|
@ -1,9 +1,9 @@
|
|||
<app>
|
||||
<id>mythboxy</id>
|
||||
<name>MythBoxy</name>
|
||||
<version>3.0.beta</version>
|
||||
<version>4.0.beta</version>
|
||||
<description>Watch all your MythTV recordings from Boxee.</description>
|
||||
<thumb>http://erikkristensen.com/project/mythboxee/mythboxee_logo.jpg</thumb>
|
||||
<thumb>http://erikkristensen.com/boxee/logo4.jpg</thumb>
|
||||
<media>video</media>
|
||||
<copyright>Erik Kristensen</copyright>
|
||||
<email>erik@erikkristensen.com</email>
|
||||
|
|
14
launch.py
|
@ -1,17 +1,13 @@
|
|||
import mc
|
||||
import sys
|
||||
import signal
|
||||
import mythtv
|
||||
import mythboxee
|
||||
from mythboxee import MythBoxee
|
||||
import time
|
||||
|
||||
# DEBUG #
|
||||
#mc.GetApp().GetLocalConfig().SetValue("dbconn", "")
|
||||
# DEBUG #
|
||||
|
||||
# We'll use this to determine when to reload data.
|
||||
mc.GetApp().GetLocalConfig().SetValue("LastRunTime", str(time.time()))
|
||||
mc.GetApp().GetLocalConfig().SetValue("CurrentShowItemID", "0")
|
||||
|
||||
# Activate Loading Window
|
||||
mc.ActivateWindow(14001)
|
||||
|
||||
# Lets go ahead and launch the app
|
||||
MythBoxee()
|
||||
|
||||
|
|
447
mythboxee.py
|
@ -1,5 +1,8 @@
|
|||
import mc
|
||||
import re
|
||||
import random
|
||||
import time
|
||||
import pickle
|
||||
import mythtv
|
||||
from mythtv import MythError
|
||||
from operator import itemgetter, attrgetter
|
||||
|
@ -8,13 +11,10 @@ from operator import itemgetter, attrgetter
|
|||
class MythBoxee:
|
||||
logLevel = 1
|
||||
version = "4.0.beta"
|
||||
|
||||
userAgent = "MythBoxee v4.0.beta"
|
||||
tvdb_apikey = "6BEAB4CB5157AAE0"
|
||||
|
||||
be = None
|
||||
db = None
|
||||
|
||||
recs = None
|
||||
titles = []
|
||||
recordings = []
|
||||
|
@ -33,7 +33,7 @@ class MythBoxee:
|
|||
finally prompt user to enter their credentials manually.
|
||||
"""
|
||||
def DiscoverBackend():
|
||||
self.log("def(DiscoverBackend)")
|
||||
self.log("def(DiscoverBackend): Start =========================================================")
|
||||
|
||||
pin = self.config.GetValue("pin")
|
||||
dbconn = self.config.GetValue("dbconn")
|
||||
|
@ -45,85 +45,138 @@ class MythBoxee:
|
|||
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()
|
||||
## Jump to Settings Window
|
||||
self.log("def(DiscoverBackend): Error: Database Credentials")
|
||||
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()
|
||||
## Jump to Settings Window
|
||||
self.log("def(DiscoverBackend): Error: Database Connection")
|
||||
self.log("def(DiscoverBackend): End ===========================================================")
|
||||
return False
|
||||
else:
|
||||
# We have a successful connection, save database information
|
||||
self.config.SetValue("dbconn", str(self.db.dbconn))
|
||||
self.log("def(DiscoverBackend): End ===========================================================")
|
||||
return True
|
||||
|
||||
|
||||
"""
|
||||
Lets make a connection to the backend!
|
||||
__init__ - Lets make a connection to the backend!
|
||||
"""
|
||||
def __init__(self):
|
||||
self.config = mc.GetApp().GetLocalConfig()
|
||||
self.log("def(__init__): Start =========================================================")
|
||||
self.log("def(__init__): Version: " + self.version)
|
||||
|
||||
self.log("def(__init__)")
|
||||
self.config = mc.GetApp().GetLocalConfig()
|
||||
|
||||
# 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("Filter", "All")
|
||||
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)
|
||||
# Parse our DB info into useable format
|
||||
dbconf = eval(self.config.GetValue("dbconn"))
|
||||
self.dbconf = dbconf
|
||||
|
||||
# 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")
|
||||
self.log(e.message)
|
||||
else:
|
||||
self.be = mythtv.MythBE(db=self.db)
|
||||
self.GetRecordings()
|
||||
|
||||
self.log("def(__init__): End ===========================================================")
|
||||
|
||||
|
||||
"""
|
||||
GetRecordings - Pulls all of the recordings out of the backend.
|
||||
LoadMain - Loader for Main Window
|
||||
"""
|
||||
def LoadMain(self):
|
||||
self.log("def(LoadMain): Start =========================================================")
|
||||
mc.ShowDialogWait()
|
||||
|
||||
## Put focus on last selected item
|
||||
itemId = int(self.config.GetValue("CurrentShowItemID"))
|
||||
if itemId and itemId != 0:
|
||||
mc.GetWindow(14001).GetList(1030).SetFocusedItem(itemId)
|
||||
|
||||
mainList = mc.GetWindow(14001).GetList(1030)
|
||||
mainListitems = mainList.GetItems()
|
||||
mainLength = len(mainListitems)
|
||||
lastruntime = self.config.GetValue("LastRunTime")
|
||||
|
||||
if mainLength == 0 or lastruntime <= str(time.time() - 3060):
|
||||
# Lets get the recordings
|
||||
self.SetShows()
|
||||
|
||||
mc.HideDialogWait()
|
||||
self.log("def(LoadMain): End ===========================================================")
|
||||
|
||||
|
||||
"""
|
||||
GetRecordings - Pulls all of the recordings out of the backend and prepares them for use in the app.
|
||||
|
||||
This function also creates some dictionarys and lists of information
|
||||
that is used throughout the app for different functions.
|
||||
"""
|
||||
def GetRecordings(self):
|
||||
self.log("def(GetRecordings): Start =========================================================")
|
||||
|
||||
# Empty out crucial info
|
||||
self.titles = []
|
||||
self.banners = {}
|
||||
self.series = {}
|
||||
self.shows = {}
|
||||
|
||||
self.log("def(GetRecordings)")
|
||||
cacheTime = self.config.GetValue("cache.time")
|
||||
|
||||
self.recs = self.be.getRecordings()
|
||||
|
||||
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)] = []
|
||||
if not cacheTime or cacheTime <= str(time.time() - 3600):
|
||||
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
|
||||
single = [str(recording.title), str(recording.subtitle), str(recording.description), str(recording.chanid), str(recording.airdate), str(recording.starttime), str(recording.endtime), recording.getRecorded().watched, x]
|
||||
self.shows[str(recording.title)].append(single)
|
||||
x = x + 1
|
||||
|
||||
# Lets cache our findings for now.
|
||||
self.config.SetValue("cache.time", str(time.time()))
|
||||
self.config.SetValue("cache.titles", pickle.dumps(self.titles))
|
||||
self.config.SetValue("cache.banners", pickle.dumps(self.banners))
|
||||
self.config.SetValue("cache.series", pickle.dumps(self.series))
|
||||
self.config.SetValue("cache.shows", pickle.dumps(self.shows))
|
||||
else:
|
||||
self.titles = pickle.loads(self.config.GetValue("cache.titles"))
|
||||
self.banners = pickle.loads(self.config.GetValue("cache.banners"))
|
||||
self.series = pickle.loads(self.config.GetValue("cache.series"))
|
||||
self.shows = pickle.loads(self.config.GetValue("cache.shows"))
|
||||
|
||||
self.titles.sort()
|
||||
|
||||
self.log("def(GetRecordings): End ===========================================================")
|
||||
|
||||
|
||||
"""
|
||||
SetShows - Populate the Shows List on the Main Window
|
||||
"""
|
||||
def SetShows(self):
|
||||
self.log("def(SetShows): Start =========================================================")
|
||||
items = mc.ListItems()
|
||||
for title in self.titles:
|
||||
item = mc.ListItem( mc.ListItem.MEDIA_UNKNOWN )
|
||||
|
@ -132,55 +185,75 @@ class MythBoxee:
|
|||
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)
|
||||
self.log("def(SetShows): End ===========================================================")
|
||||
|
||||
|
||||
"""
|
||||
GetRecordingArtwork - Get the Artwork for a show.
|
||||
"""
|
||||
def GetRecordingArtwork(self, title):
|
||||
self.log("def(GetRecordingArtwork): Start =========================================================")
|
||||
|
||||
sg = mc.Http()
|
||||
sg.SetUserAgent('MythBoxee v4.0.beta')
|
||||
sg.SetUserAgent(self.userAgent)
|
||||
html = sg.Get("http://www.thetvdb.com/api/GetSeries.php?seriesname=" + str(title.replace(" ", "%20")))
|
||||
banners = re.compile("<banner>(.*?)</banner>").findall(html)
|
||||
|
||||
## Sometimes we can't find the show, so we have to provide our own artwork
|
||||
try:
|
||||
artwork = "http://www.thetvdb.com/banners/" + banners[0]
|
||||
except:
|
||||
artwork = "mb_artwork_error.png"
|
||||
|
||||
self.log("def(GetRecordingArtwork): " + str(artwork))
|
||||
self.log("def(GetRecordingArtwork): URL: " + str(artwork))
|
||||
self.log("def(GetRecordingArtwork): End =========================================================")
|
||||
|
||||
return artwork
|
||||
|
||||
|
||||
"""
|
||||
GetRecordingSeriesID - Get the Series ID of a show.
|
||||
|
||||
TODO: rewrite this entire function
|
||||
"""
|
||||
def GetRecordingSeriesID(self, title):
|
||||
self.log("def(GetRecordingSeriesID): Start =========================================================")
|
||||
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)
|
||||
|
||||
## Sometimes we can't determine the series ID
|
||||
try:
|
||||
seriesid = series[0]
|
||||
except:
|
||||
seriesid = 00000
|
||||
|
||||
self.log("def(GetRecordingSeriesID): title[" + title + "] - seriesid[" + str(seriesid) + "]")
|
||||
|
||||
self.log("def(GetRecordingSeriesID): Title: " + title)
|
||||
self.log("def(GetRecordingSeriesID): SeriesID: " + str(seriesid))
|
||||
self.log("def(GetRecordingSeriesID): End ===========================================================")
|
||||
return seriesid
|
||||
|
||||
|
||||
"""
|
||||
DisplayShow
|
||||
|
||||
TODO: rewrite this entire function
|
||||
"""
|
||||
def DisplayShow(self):
|
||||
self.log("def(DisplaySingleShow): Start =========================================================")
|
||||
|
||||
recordingList = mc.GetWindow(14001).GetList(1030)
|
||||
item = recordingList.GetItem(recordingList.GetFocusedItem())
|
||||
itemId = recordingList.GetFocusedItem()
|
||||
item = recordingList.GetItem(itemId)
|
||||
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 + "]")
|
||||
self.config.SetValue("CurrentShowItemID", str(itemId))
|
||||
self.config.SetValue("CurrentShowTitle", title)
|
||||
self.config.SetValue("CurrentShowID", item.GetProperty("seriesid"))
|
||||
|
||||
# Show the Single Show Window
|
||||
mc.ActivateWindow(14002)
|
||||
|
@ -190,22 +263,34 @@ class MythBoxee:
|
|||
|
||||
mc.GetWindow(14002).GetList(2070).SetItems(itemList)
|
||||
|
||||
self.log("def(DisplaySingleShow): Title[" + title + "]")
|
||||
self.log("def(DisplaySingleShow): Current Show Title: " + title)
|
||||
self.log("def(DisplaySingleShow): Current Show Item ID: " + str(itemId))
|
||||
self.log("def(DisplaySingleShow): Current Show Series ID: " + item.GetProperty("seriesid"))
|
||||
self.log("def(DisplaySingleShow): End ===========================================================")
|
||||
|
||||
|
||||
"""
|
||||
LoadShow
|
||||
|
||||
Launch function to gather and setup the recordings for a single show.
|
||||
LoadShow - init function for Show Window
|
||||
"""
|
||||
def LoadShow(self):
|
||||
title = self.config.GetValue("LatestShowTitle")
|
||||
seriesid = self.config.GetValue("LatestShowID")
|
||||
self.log("def(LoadShow): Start =========================================================")
|
||||
mc.ShowDialogWait()
|
||||
|
||||
## Get Current Show Information
|
||||
title = self.config.GetValue("CurrentShowTitle")
|
||||
seriesid = self.config.GetValue("CurrentShowID")
|
||||
|
||||
self.log("def(LoadSingleShow): Title[" + title + "]")
|
||||
|
||||
## Setup the Show Window and Populate the Window's Lists
|
||||
self.SetSortableOptions()
|
||||
self.SetSeriesDetails(title, seriesid)
|
||||
self.LoadShowRecordings(title)
|
||||
|
||||
mc.HideDialogWait()
|
||||
self.log("def(LoadShow): End ===========================================================")
|
||||
|
||||
|
||||
"""
|
||||
LoadShowRecordings
|
||||
|
@ -214,11 +299,21 @@ class MythBoxee:
|
|||
Then populate the recording list for the singular show for viewer to watch.
|
||||
"""
|
||||
def LoadShowRecordings(self, title):
|
||||
self.log("def(LoadShowRecordings): Start =========================================================")
|
||||
|
||||
## Get current sort and filter settings
|
||||
sortBy = self.config.GetValue("SortBy")
|
||||
sortDir = self.config.GetValue("SortDir")
|
||||
theFilter = self.config.GetValue("Filter")
|
||||
|
||||
self.log("def(LoadShowRecordings): Sort By: " + sortBy)
|
||||
self.log("def(LoadShowRecordings): Sort Dir: " + sortDir)
|
||||
self.log("def(LoadShowRecordings): Filter: " + theFilter)
|
||||
|
||||
## Clear the episodes container
|
||||
episodes = None
|
||||
|
||||
## Sort based on Sorting Criteria
|
||||
if sortBy == "Original Air Date" and sortDir == "Ascending":
|
||||
episodes = sorted(self.shows[title], key=itemgetter(4))
|
||||
elif sortBy == "Original Air Date" and sortDir == "Descending":
|
||||
|
@ -234,69 +329,115 @@ class MythBoxee:
|
|||
else:
|
||||
episodes = self.shows[title]
|
||||
|
||||
## Loop through all our recordings, and add them to the list.
|
||||
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))
|
||||
for title,subtitle,desc,chanid,airdate,starttime,endtime,watched,ref in episodes:
|
||||
#recording = self.recs[ref]
|
||||
|
||||
# Filter the Episodes
|
||||
if theFilter == "Watched" and watched == 0:
|
||||
continue
|
||||
elif theFilter == "Unwatched" and watched == 1:
|
||||
continue
|
||||
|
||||
# Create the Item list and populate it
|
||||
showitem = mc.ListItem( mc.ListItem.MEDIA_VIDEO_EPISODE )
|
||||
showitem.SetLabel(subtitle)
|
||||
showitem.SetTitle(subtitle)
|
||||
showitem.SetTVShowTitle(title)
|
||||
showitem.SetDescription(desc)
|
||||
showitem.SetProperty("starttime", starttime)
|
||||
#showitem.SetProperty("ref", ref)
|
||||
|
||||
## Sometimes dates aren't set, so generate one if not.
|
||||
try:
|
||||
date = str(airdate).split("-")
|
||||
date = 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"))
|
||||
|
||||
## Set the Thumbnail for the ListItem
|
||||
#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.SetThumbnail("http://" + dbconf['DBHostName'] + ":6544/Myth/GetPreviewImage?ChanId=" + chanid + "&StartTime=" + starttime.replace(" ", "%20") + "&random=" + str(random.randrange(1000000, 2000000, 2)))
|
||||
#showitem.SetThumbnail("mb_artwork_error.png")
|
||||
#showitem.SetThumbnail("http://192.168.1.210:6544/Myth/GetPreviewImage?ChanId=" + chanid + "&StartTime=" + starttime.replace(" ", "%20") + "&random=" + str(random.randrange(1000000, 2000000, 2)))
|
||||
#showitem.SetThumbnail("http://192.168.1.210:6544/Myth/GetPreviewImage?ChanId=" + chanid + "&StartTime=" + starttime.replace("T", "%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")
|
||||
# Determine Stream Method, Generate Proper Path
|
||||
streamMethod = self.config.GetValue("StreamMethod")
|
||||
if streamMethod == "XML":
|
||||
time = starttime.replace("T", "%20")
|
||||
path = "http://" + self.dbconf['DBHostName'] + ":6544/Myth/GetRecording?ChanId=" + chanid + "&StartTime=" + time
|
||||
showitem.SetThumbnail("http://" + self.dbconf['DBHostName'] + ":6544/Myth/GetPreviewImage?ChanId=" + chanid + "&StartTime=" + starttime.replace("T", "%20"))
|
||||
elif streamMethod == "SMB":
|
||||
time = starttime.replace("T", "").replace("-", "").replace(":", "").replace(" ","")
|
||||
path = "smb://" + self.config.GetValue("smb.username") + ":" + self.config.GetValue("smb.password") + "@" + self.dbconf["DBHostName"] + "/" + self.config.GetValue("smb.share") + "/" + chanid + "_" + time + ".mpg"
|
||||
|
||||
## Set the Path for the ListItem
|
||||
showitem.SetPath(path)
|
||||
|
||||
self.log("def(LoadShowRecordings): Thumbnail: " + showitem.GetThumbnail())
|
||||
self.log("def(LoadShowRecordings): Path: " + showitem.GetPath())
|
||||
|
||||
showitems.append(showitem)
|
||||
|
||||
mc.GetWindow(14002).GetList(2040).SetItems(mc.ListItems())
|
||||
mc.GetWindow(14002).GetList(2040).SetItems(showitems)
|
||||
|
||||
self.log("def(LoadShowRecordings): End ===========================================================")
|
||||
|
||||
|
||||
"""
|
||||
SetShowOptions
|
||||
|
||||
Setup the show options; sort by, sort direction, watched vs unwatched
|
||||
SetSortableOptions - Setup the show options; sort by, sort direction, watched vs unwatched
|
||||
"""
|
||||
def SetSortableOptions(self):
|
||||
self.log("def(SetSortableOptions): Start =========================================================")
|
||||
|
||||
## Setup Sortable Field Options
|
||||
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(mc.ListItems())
|
||||
mc.GetWindow(14002).GetList(2051).SetItems(items)
|
||||
mc.GetWindow(14002).GetList(2051).SetSelected(1, True)
|
||||
|
||||
## Setup Sortable Direction Options
|
||||
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(mc.ListItems())
|
||||
mc.GetWindow(14002).GetList(2061).SetItems(items)
|
||||
mc.GetWindow(14002).GetList(2061).SetSelected(1, True)
|
||||
|
||||
## Setup Filter Options
|
||||
filters = ['All', 'Watched', 'Unwatched']
|
||||
items = mc.ListItems()
|
||||
for single_filter in filters:
|
||||
item = mc.ListItem( mc.ListItem.MEDIA_UNKNOWN )
|
||||
item.SetLabel(single_filter)
|
||||
items.append(item)
|
||||
mc.GetWindow(14002).GetList(2082).SetItems(mc.ListItems())
|
||||
mc.GetWindow(14002).GetList(2082).SetItems(items)
|
||||
|
||||
## Set the currently selected option in each category
|
||||
mc.GetWindow(14002).GetList(2051).SetSelected(sortable.index(self.config.GetValue("SortBy")), True)
|
||||
mc.GetWindow(14002).GetList(2061).SetSelected(sortableby.index(self.config.GetValue("SortDir")), True)
|
||||
mc.GetWindow(14002).GetList(2082).SetSelected(filters.index(self.config.GetValue("Filter")), True)
|
||||
|
||||
self.log("def(SetSortableOptions): End ===========================================================")
|
||||
|
||||
|
||||
"""
|
||||
SetSeriesDetails - Get Show Series Information
|
||||
|
||||
TODO -- rewrite this entire function
|
||||
"""
|
||||
def SetSeriesDetails(self, title, seriesid):
|
||||
self.log("def(SetSeriesDetails): Start =========================================================")
|
||||
sg = mc.Http()
|
||||
sg.SetUserAgent(self.userAgent)
|
||||
html = sg.Get("http://thetvdb.com/api/" + self.tvdb_apikey + "/series/" + seriesid + "/")
|
||||
|
@ -321,27 +462,163 @@ class MythBoxee:
|
|||
items.append(item)
|
||||
|
||||
mc.GetWindow(14002).GetList(2070).SetItems(items)
|
||||
self.log("def(SetSeriesDetails): End ===========================================================")
|
||||
|
||||
|
||||
def PlayRecording(self):
|
||||
self.log("def(PlayRecording): ")
|
||||
"""
|
||||
FilterEpisodes - Filter the list of Episodes (All, Watched, Unwatched)
|
||||
"""
|
||||
def FilterEpisodes(self):
|
||||
self.log("def(FilterEpisodes): Start =========================================================")
|
||||
|
||||
sl = mc.GetWindow(14002).GetList(2040)
|
||||
item = sl.GetItem(sl.GetFocusedItem())
|
||||
## Figure out how we need to filter
|
||||
FilterItems = FilterItemNumber = mc.GetWindow(14002).GetList(2082).GetSelected()
|
||||
mc.GetWindow(14002).GetList(2082).UnselectAll()
|
||||
mc.GetWindow(14002).GetList(2082).SetSelected(mc.GetWindow(14002).GetList(2082).GetFocusedItem(), True)
|
||||
|
||||
ref = item.GetProperty("ref")
|
||||
## Update the Filter Criteria
|
||||
self.config.SetValue("Filter", mc.GetWindow(14002).GetList(2082).GetItem(mc.GetWindow(14002).GetList(2082).GetFocusedItem()).GetLabel())
|
||||
|
||||
file = self.recs[int(ref)].open('r', self.db)
|
||||
|
||||
mc.ShowDialogNotification(item.GetProperty("ref"))
|
||||
mc.ShowDialogNotification("Playing: " + item.GetLabel())
|
||||
## Now that the filter has changed, reload the list of episodes
|
||||
self.LoadShowRecordings(self.config.GetValue("CurrentShowTitle"))
|
||||
self.log("def(FilterEpisodes): End ===========================================================")
|
||||
|
||||
|
||||
"""
|
||||
SortBy - Sort List of Episodes
|
||||
"""
|
||||
def SortBy(self):
|
||||
self.log("def(SortBy): Start =========================================================")
|
||||
|
||||
## Figure out how we need to Sort
|
||||
sortByItems = sortByItemNumber = mc.GetWindow(14002).GetList(2051).GetSelected()
|
||||
sortDirectionItems = sortDirectionItemNumber = mc.GetWindow(14002).GetList(2061).GetSelected()
|
||||
mc.GetWindow(14002).GetList(2051).UnselectAll()
|
||||
mc.GetWindow(14002).GetList(2051).SetSelected(mc.GetWindow(14002).GetList(2051).GetFocusedItem(), True)
|
||||
|
||||
## Update the Sort Criteria
|
||||
self.config.SetValue("SortBy", mc.GetWindow(14002).GetList(2051).GetItem(mc.GetWindow(14002).GetList(2051).GetFocusedItem()).GetLabel())
|
||||
|
||||
## Now that we have updated the Sort Criteria, reload the shows
|
||||
self.LoadShowRecordings(self.config.GetValue("CurrentShowTitle"))
|
||||
self.log("def(SortBy): End ===========================================================")
|
||||
|
||||
|
||||
"""
|
||||
LoadSettings - Stuff that needs to be executed when settings window is loaded
|
||||
"""
|
||||
def LoadSettings(self):
|
||||
self.log("def(LoadSettings): Start =========================================================")
|
||||
|
||||
## Grab the current StreamMethod
|
||||
streamMethod = self.config.GetValue("StreamMethod")
|
||||
|
||||
self.log("def(LoadSettings): Stream Method: " + streamMethod)
|
||||
|
||||
# Grab and Set the Database Information
|
||||
dbconf = eval(self.config.GetValue("dbconn"))
|
||||
mc.GetWindow(14004).GetEdit(1042).SetText(dbconf['DBHostName'])
|
||||
mc.GetWindow(14004).GetEdit(1043).SetText(dbconf['DBUserName'])
|
||||
mc.GetWindow(14004).GetEdit(1044).SetText(dbconf['DBPassword'])
|
||||
|
||||
# Setup Stream Methods for user to choose
|
||||
methods = ['XML', 'SMB']
|
||||
items = mc.ListItems()
|
||||
for method in methods:
|
||||
item = mc.ListItem( mc.ListItem.MEDIA_UNKNOWN )
|
||||
item.SetLabel(method)
|
||||
items.append(item)
|
||||
mc.GetWindow(14004).GetList(1022).SetItems(items)
|
||||
mc.GetWindow(14004).GetList(1022).SetSelected(methods.index(streamMethod), True)
|
||||
|
||||
# Depending on StreamMethod Enable Options
|
||||
if not streamMethod or streamMethod == "XML":
|
||||
mc.GetWindow(14004).GetControl(1032).SetEnabled(False)
|
||||
mc.GetWindow(14004).GetControl(1033).SetEnabled(False)
|
||||
mc.GetWindow(14004).GetControl(1034).SetEnabled(False)
|
||||
else:
|
||||
if not self.config.GetValue("smb.username"):
|
||||
self.config.SetValue("smb.username", "guest")
|
||||
if not self.config.GetValue("smb.password"):
|
||||
self.config.SetValue("smb.password", "guest")
|
||||
|
||||
self.log("def(LoadSettings): smb.share: " + self.config.GetValue("smb.share"))
|
||||
self.log("def(LoadSettings): smb.username: " + self.config.GetValue("smb.username"))
|
||||
self.log("def(LoadSettings): smb.password: " + self.config.GetValue("smb.password"))
|
||||
|
||||
## Since the Stream Method is SMB enable controls for setting info
|
||||
mc.GetWindow(14004).GetControl(1032).SetEnabled(True)
|
||||
mc.GetWindow(14004).GetControl(1033).SetEnabled(True)
|
||||
mc.GetWindow(14004).GetControl(1034).SetEnabled(True)
|
||||
mc.GetWindow(14004).GetControl(1032).SetFocus()
|
||||
|
||||
## Update the fields with current SMB settings.
|
||||
mc.GetWindow(14004).GetEdit(1032).SetText(self.config.GetValue("smb.share"))
|
||||
mc.GetWindow(14004).GetEdit(1033).SetText(self.config.GetValue("smb.username"))
|
||||
mc.GetWindow(14004).GetEdit(1034).SetText(self.config.GetValue("smb.password"))
|
||||
|
||||
self.log("def(LoadSettings): End ===========================================================")
|
||||
|
||||
|
||||
"""
|
||||
SetStreamMethod - Change the Streaming Method
|
||||
"""
|
||||
def SetStreamMethod(self):
|
||||
self.log("def(SetStreamMethod): Start =========================================================")
|
||||
|
||||
## Figure out what Stream Method the user has selected
|
||||
streamMethodItems = streamMethodItemNumber = mc.GetWindow(14004).GetList(1022).GetSelected()
|
||||
mc.GetWindow(14004).GetList(1022).UnselectAll()
|
||||
mc.GetWindow(14004).GetList(1022).SetSelected(mc.GetWindow(14004).GetList(1022).GetFocusedItem(), True)
|
||||
streamMethod = mc.GetWindow(14004).GetList(1022).GetItem(mc.GetWindow(14004).GetList(1022).GetFocusedItem()).GetLabel()
|
||||
|
||||
## Disabled some UI pieces depending on stream method
|
||||
if not streamMethod or streamMethod == "XML":
|
||||
mc.GetWindow(14004).GetControl(1032).SetEnabled(False)
|
||||
mc.GetWindow(14004).GetControl(1033).SetEnabled(False)
|
||||
mc.GetWindow(14004).GetControl(1034).SetEnabled(False)
|
||||
else:
|
||||
mc.GetWindow(14004).GetControl(1032).SetEnabled(True)
|
||||
mc.GetWindow(14004).GetControl(1033).SetEnabled(True)
|
||||
mc.GetWindow(14004).GetControl(1034).SetEnabled(True)
|
||||
|
||||
## Save the Stream Method
|
||||
self.config.SetValue("StreamMethod", streamMethod)
|
||||
|
||||
## Notify the User
|
||||
mc.ShowDialogNotification("Stream Method Changed to " + streamMethod)
|
||||
|
||||
self.log("def(SetStreamMethod): Stream Method Changed to -- " + streamMethod)
|
||||
self.log("def(SetStreamMethod): End =========================================================")
|
||||
|
||||
|
||||
"""
|
||||
SaveSMBSettings - Saves the SMB settings the user inputted.
|
||||
"""
|
||||
def SaveSMBSettings(self):
|
||||
self.log("def(SetStreamMethod): Start =========================================================")
|
||||
|
||||
## Save SMB settings the user inputted
|
||||
self.config.SetValue("smb.share", mc.GetWindow(14004).GetEdit(1032).GetText())
|
||||
self.config.SetValue("smb.username", mc.GetWindow(14004).GetEdit(1033).GetText())
|
||||
self.config.SetValue("smb.password", mc.GetWindow(14004).GetEdit(1034).GetText())
|
||||
|
||||
## Notify the user that the changes have been saved.
|
||||
mc.ShowDialogNotification("SMB Share Settings Saved")
|
||||
|
||||
self.log("def(SetStreamMethod): End ===========================================================")
|
||||
|
||||
|
||||
"""
|
||||
log - logging function mainly for debugging
|
||||
"""
|
||||
def log(self, message):
|
||||
if self.logLevel >= 3:
|
||||
mc.LogDebug(">>> MythBoxee: " + message)
|
||||
|
||||
if self.logLevel >= 2:
|
||||
mc.ShowDialogNotification(message)
|
||||
|
||||
if self.logLevel >= 1:
|
||||
mc.LogInfo(">>> MythBoxee (" + self.version + ")\: " + message)
|
||||
|
||||
print ">>> MythBoxee (" + self.version + ")\: " + message
|
||||
mc.LogInfo(">>> MythBoxee: " + message)
|
||||
print ">>> MythBoxee: " + message
|
||||
|
|
|
@ -8,6 +8,6 @@ OWN_VERSION = (0,23,1,0)
|
|||
SCHEMA_VERSION = 1254
|
||||
MVSCHEMA_VERSION = 1032
|
||||
NVSCHEMA_VERSION = 1004
|
||||
PROTO_VERSION = 23056
|
||||
PROTO_VERSION = 56
|
||||
PROGRAM_FIELDS = 47
|
||||
BACKEND_SEP = '[]:[]'
|
||||
|
|
|
@ -4,43 +4,67 @@
|
|||
<allowoverlay>yes</allowoverlay>
|
||||
<onload lang="python"><![CDATA[
|
||||
from mythboxee import MythBoxee
|
||||
|
||||
mb = MythBoxee()
|
||||
|
||||
mb.GetRecordings()
|
||||
mb.LoadMain()
|
||||
]]></onload>
|
||||
<controls>
|
||||
<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="group" id="1020">
|
||||
<control type="image" id="1021">
|
||||
<width>1280</width>
|
||||
<height>720</height>
|
||||
<texture>mb_bg.png</texture>
|
||||
</control>
|
||||
<control type="image" id="1022">
|
||||
<posx>10</posx>
|
||||
<posy>10</posy>
|
||||
<width>244</width>
|
||||
<height>65</height>
|
||||
<texture>logo.png</texture>
|
||||
</control>
|
||||
</control>
|
||||
<control type="grouplist" id="1040">
|
||||
<posy>28</posy>
|
||||
<posx>940</posx>
|
||||
<width>334</width>
|
||||
<itemgap>10</itemgap>
|
||||
<orientation>horizontal</orientation>
|
||||
<ondown>1030</ondown>
|
||||
<control type="button" id="1041">
|
||||
<label>Refresh</label>
|
||||
<texturefocus>bg_btn.png</texturefocus>
|
||||
<texturenofocus></texturenofocus>
|
||||
<height>30</height>
|
||||
<align>center</align>
|
||||
<onclick lang="python"><![CDATA[mb.RefreshMain()]]></onclick>
|
||||
</control>
|
||||
<control type="button" id="1042">
|
||||
<label>Settings</label>
|
||||
<texturefocus>bg_btn.png</texturefocus>
|
||||
<texturenofocus></texturenofocus>
|
||||
<height>30</height>
|
||||
<align>center</align>
|
||||
<onclick lang="python"><![CDATA[mc.ActivateWindow(14004)]]></onclick>
|
||||
</control>
|
||||
<!--
|
||||
780/500
|
||||
<control type="button" id="1043">
|
||||
<label>Send Logs</label>
|
||||
<texturefocus>bg_btn.png</texturefocus>
|
||||
<texturenofocus></texturenofocus>
|
||||
<height>29</height>
|
||||
<align>center</align>
|
||||
<onclick lang="python"><![CDATA[mb.SendLogs()]]></onclick>
|
||||
</control>
|
||||
-->
|
||||
</control>
|
||||
<control type="panel" id="1030">
|
||||
<posx>22</posx>
|
||||
<posy>82</posy>
|
||||
<width>1280</width>
|
||||
<height>592</height>
|
||||
<height>692</height>
|
||||
<onleft>-</onleft>
|
||||
<onright>-</onright>
|
||||
<onup>-</onup>
|
||||
<onup>1040</onup>
|
||||
<ondown>-</ondown>
|
||||
<itemlayout width="420" height="120">
|
||||
<control type="image">
|
||||
|
@ -154,5 +178,25 @@ mb.GetRecordings()
|
|||
<onclick lang="python"><![CDATA[mb.DisplayShow()]]></onclick>
|
||||
</content>
|
||||
</control>
|
||||
<control type="group">
|
||||
<visible>App.HasSetting(loading)</visible>
|
||||
<animation effect="fade" start="0" end="100" time="150">VisibleChange</animation>
|
||||
<control type="image">
|
||||
<width>1280</width>
|
||||
<height>720</height>
|
||||
<texture>black.png</texture>
|
||||
<animation effect="fade" start="80" end="80" time="0" condition="true">Conditional</animation>
|
||||
</control>
|
||||
<control type="label">
|
||||
<posx>530</posx>
|
||||
<width>1280</width>
|
||||
<height>720</height>
|
||||
<align>cetner</align>
|
||||
<aligny>center</aligny>
|
||||
<font>sans40b</font>
|
||||
<label>LOADING...</label>
|
||||
<textcolor>ffffffff</textcolor>
|
||||
</control>
|
||||
</control>
|
||||
</controls>
|
||||
</window>
|
||||
|
|
|
@ -0,0 +1,231 @@
|
|||
<window type="window" id="14004">
|
||||
<defaultcontrol always="true">1030</defaultcontrol>
|
||||
<allowoverlay>yes</allowoverlay>
|
||||
<onload lang="python"><![CDATA[
|
||||
import mc
|
||||
import mythboxee
|
||||
mb.LoadSettings()
|
||||
]]></onload>
|
||||
<controls>
|
||||
<control type="group" id="1010">
|
||||
<control type="image" id="1011">
|
||||
<width>1280</width>
|
||||
<height>720</height>
|
||||
<texture>mb_bg_settings.png</texture>
|
||||
</control>
|
||||
</control>
|
||||
|
||||
<!-- START: BACKEND INFORMATION -->
|
||||
|
||||
<control type="group" id="1040">
|
||||
<control type="label" id="1041">
|
||||
<posx>820</posx>
|
||||
<posy>150</posy>
|
||||
<width>250</width>
|
||||
<label>Backend Information</label>
|
||||
<font>font23</font>
|
||||
</control>
|
||||
<control type="edit" id="1042">
|
||||
<posx>820</posx>
|
||||
<posy>175</posy>
|
||||
<width>300</width>
|
||||
<label>Hostname/IP:</label>
|
||||
<align>left</align>
|
||||
<font>font18</font>
|
||||
<ondown>1043</ondown>
|
||||
</control>
|
||||
<control type="edit" id="1043">
|
||||
<posx>820</posx>
|
||||
<posy>205</posy>
|
||||
<width>300</width>
|
||||
<label>Username:</label>
|
||||
<align>left</align>
|
||||
<font>font18</font>
|
||||
<onup>1042</onup>
|
||||
<ondown>1044</ondown>
|
||||
</control>
|
||||
<control type="edit" id="1044">
|
||||
<posx>820</posx>
|
||||
<posy>235</posy>
|
||||
<width>300</width>
|
||||
<align>left</align>
|
||||
<label>Password:</label>
|
||||
<password>true</password>
|
||||
<font>font18</font>
|
||||
<onup>1043</onup>
|
||||
<ondown>1022</ondown>
|
||||
</control>
|
||||
</control>
|
||||
|
||||
<!-- END: BACKEND INFORMATION -->
|
||||
|
||||
<!-- START: STREAM METHOD -->
|
||||
|
||||
<control type="group" id="1020">
|
||||
<control type="label" id="1021">
|
||||
<posx>820</posx>
|
||||
<posy>300</posy>
|
||||
<width>250</width>
|
||||
<align>left</align>
|
||||
<label>Stream Method</label>
|
||||
<font>font23</font>
|
||||
</control>
|
||||
<control type="list" id="1022">
|
||||
<posx>830</posx>
|
||||
<posy>335</posy>
|
||||
<width>164</width>
|
||||
<height>100</height>
|
||||
<onup>1044</onup>
|
||||
<ondown>1032</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>font18</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>font18</font>
|
||||
<textcolor>green</textcolor>
|
||||
<visible>Control.HasFocus(1022)</visible>
|
||||
<selectedcolor>green</selectedcolor>
|
||||
</control>
|
||||
<control type="label">
|
||||
<visible>!Control.HasFocus(1022)</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>font18</font>
|
||||
<textcolor>FF999999</textcolor>
|
||||
<selectedcolor>FFFFFFFF</selectedcolor>
|
||||
</control>
|
||||
</focusedlayout>
|
||||
<content type="action">
|
||||
<onclick lang="python"><![CDATA[mb.SetStreamMethod()]]></onclick>
|
||||
</content>
|
||||
</control>
|
||||
</control>
|
||||
|
||||
<!-- END: STREAM METHOD -->
|
||||
|
||||
<!-- START: SMB SETTINGS -->
|
||||
|
||||
<control type="group" id="1030">
|
||||
<control type="label" id="1031">
|
||||
<posx>820</posx>
|
||||
<posy>420</posy>
|
||||
<width>250</width>
|
||||
<align>left</align>
|
||||
<label>SMB Share</label>
|
||||
<font>font23</font>
|
||||
</control>
|
||||
<control type="edit" id="1032">
|
||||
<posx>820</posx>
|
||||
<posy>445</posy>
|
||||
<width>300</width>
|
||||
<label>Share:</label>
|
||||
<align>left</align>
|
||||
<font>font18</font>
|
||||
<onup>1022</onup>
|
||||
<ondown>1033</ondown>
|
||||
<ontextchange lang="python"><![CDATA[mb.SaveSMBSettings()]]></ontextchange>
|
||||
</control>
|
||||
<control type="edit" id="1033">
|
||||
<posx>820</posx>
|
||||
<posy>475</posy>
|
||||
<width>300</width>
|
||||
<label>Username:</label>
|
||||
<align>left</align>
|
||||
<font>font18</font>
|
||||
<onup>1032</onup>
|
||||
<ondown>1034</ondown>
|
||||
<ontextchange lang="python"><![CDATA[mb.SaveSMBSettings()]]></ontextchange>
|
||||
</control>
|
||||
<control type="edit" id="1034">
|
||||
<posx>820</posx>
|
||||
<posy>505</posy>
|
||||
<width>300</width>
|
||||
<label>Password:</label>
|
||||
<align>left</align>
|
||||
<font>font18</font>
|
||||
<password>true</password>
|
||||
<onup>1033</onup>
|
||||
<ontextchange lang="python"><![CDATA[mb.SaveSMBSettings()]]></ontextchange>
|
||||
</control>
|
||||
</control>
|
||||
|
||||
<!-- END: SMB SETTINGS -->
|
||||
|
||||
<!-- START: CACHE SETTINGS -->
|
||||
<!--
|
||||
<control type="group" id="1050">
|
||||
<control type="label" id="1051">
|
||||
<posx>820</posx>
|
||||
<posy>560</posy>
|
||||
<width>250</width>
|
||||
<align>left</align>
|
||||
<label>Cache Settings</label>
|
||||
<font>font23</font>
|
||||
</control>
|
||||
<control type="togglebutton" id="1052">
|
||||
<posx>820</posx>
|
||||
<posy>565</posy>
|
||||
<width>300</width>
|
||||
<label>Share:</label>
|
||||
<align>left</align>
|
||||
<font>font18</font>
|
||||
<onup>1022</onup>
|
||||
<ondown>1033</ondown>
|
||||
<ontextchange lang="python"><![CDATA[mb.SaveCacheSettings()]]></ontextchange>
|
||||
</control>
|
||||
<control type="edit" id="1053">
|
||||
<posx>820</posx>
|
||||
<posy>590</posy>
|
||||
<width>300</width>
|
||||
<label>Username:</label>
|
||||
<align>left</align>
|
||||
<font>font18</font>
|
||||
<onup>1032</onup>
|
||||
<ondown>1034</ondown>
|
||||
<ontextchange lang="python"><![CDATA[mb.SaveCacheSettings()]]></ontextchange>
|
||||
</control>
|
||||
<control type="edit" id="1054">
|
||||
<posx>820</posx>
|
||||
<posy>615</posy>
|
||||
<width>300</width>
|
||||
<label>Password:</label>
|
||||
<align>left</align>
|
||||
<font>font18</font>
|
||||
<password>true</password>
|
||||
<onup>1033</onup>
|
||||
<ontextchange lang="python"><![CDATA[mb.SaveCacheSettings()]]></ontextchange>
|
||||
</control>
|
||||
</control>
|
||||
-->
|
||||
<!-- END: CACHE SETTINGS -->
|
||||
|
||||
|
||||
</controls>
|
||||
</window>
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0"?>
|
||||
<window type="window" id="14002">
|
||||
<window type="window" id="14003">
|
||||
<defaultcontrol always="true">6003</defaultcontrol>
|
||||
<allowoverlay>yes</allowoverlay>
|
||||
<controls>
|
||||
|
|
|
@ -4,50 +4,78 @@
|
|||
<allowoverlay>true</allowoverlay>
|
||||
<onload lang="python"><![CDATA[
|
||||
import mythboxee
|
||||
|
||||
mb.LoadShow()
|
||||
]]></onload>
|
||||
<controls>
|
||||
<!--
|
||||
<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">
|
||||
<control type="image" id="2021">
|
||||
<width>1280</width>
|
||||
<height>720</height>
|
||||
<texture>mb_bg.png</texture>
|
||||
</control>
|
||||
<control type="image" id="2022">
|
||||
<posx>10</posx>
|
||||
<posy>10</posy>
|
||||
<width>244</width>
|
||||
<height>65</height>
|
||||
<texture>logo.png</texture>
|
||||
</control>
|
||||
</control>
|
||||
|
||||
<!-- START: TOP MENU -->
|
||||
|
||||
<control type="grouplist" id="1040">
|
||||
<posy>28</posy>
|
||||
<posx>940</posx>
|
||||
<width>334</width>
|
||||
<itemgap>10</itemgap>
|
||||
<orientation>horizontal</orientation>
|
||||
<ondown>2040</ondown>
|
||||
<control type="button" id="1041">
|
||||
<label>Refresh</label>
|
||||
<texturefocus>bg_btn.png</texturefocus>
|
||||
<texturenofocus></texturenofocus>
|
||||
<height>30</height>
|
||||
<align>center</align>
|
||||
<onclick lang="python"><![CDATA[mb.RefreshMain()]]></onclick>
|
||||
</control>
|
||||
<control type="button" id="1042">
|
||||
<label>Settings</label>
|
||||
<texturefocus>bg_btn.png</texturefocus>
|
||||
<texturenofocus></texturenofocus>
|
||||
<height>30</height>
|
||||
<align>center</align>
|
||||
<onclick lang="python"><![CDATA[mc.ActivateWindow(14004)]]></onclick>
|
||||
</control>
|
||||
<!--
|
||||
780/500
|
||||
<control type="button" id="1043">
|
||||
<label>Send Logs</label>
|
||||
<texturefocus>bg_btn.png</texturefocus>
|
||||
<texturenofocus></texturenofocus>
|
||||
<height>29</height>
|
||||
<align>center</align>
|
||||
<onclick lang="python"><![CDATA[mb.SendLogs()]]></onclick>
|
||||
</control>
|
||||
-->
|
||||
</control>
|
||||
|
||||
<!-- END: TOP MENU -->
|
||||
|
||||
<control type="group" id="2030">
|
||||
<description>details box</description>
|
||||
<posx>28</posx>
|
||||
<posy>81</posy>
|
||||
<onleft>-</onleft>
|
||||
<onright>2040</onright>
|
||||
<onup>-</onup>
|
||||
<onup>1040</onup>
|
||||
<ondown>-</ondown>
|
||||
<control type="image">
|
||||
<description>details box's background</description>
|
||||
<posx>0</posx>
|
||||
<posy>0</posy>
|
||||
<width>283</width>
|
||||
<height>597</height>
|
||||
<height>630</height>
|
||||
<texture>mb_show.png</texture>
|
||||
</control>
|
||||
<control type="image">
|
||||
|
@ -70,7 +98,7 @@ mb.LoadShow()
|
|||
<aligny>top</aligny>
|
||||
<scroll>true</scroll>
|
||||
<label>$INFO[Container(2070).ListItem.Label]</label>
|
||||
<font>font16b</font>
|
||||
<font>font18</font>
|
||||
<textcolor>FFFEFEFE</textcolor>
|
||||
<wrapmultiline>true</wrapmultiline>
|
||||
</control>
|
||||
|
@ -79,7 +107,7 @@ mb.LoadShow()
|
|||
<posx>22</posx>
|
||||
<posy>395</posy>
|
||||
<width>228</width>
|
||||
<height>195</height>
|
||||
<height>215</height>
|
||||
<align>left</align>
|
||||
<aligny>top</aligny>
|
||||
<scroll>true</scroll>
|
||||
|
@ -98,46 +126,41 @@ mb.LoadShow()
|
|||
<posx>345</posx>
|
||||
<posy>82</posy>
|
||||
<width>700</width>
|
||||
<height>592</height>
|
||||
<height>630</height>
|
||||
<onleft>-</onleft>
|
||||
<onright>2051</onright>
|
||||
<onup>-</onup>
|
||||
<onup>1040</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">
|
||||
<itemlayout width="700" height="105">
|
||||
<control type="image">
|
||||
<description>background</description>
|
||||
<posx>0</posx>
|
||||
<posy>0</posy>
|
||||
<width>700</width>
|
||||
<height>82</height>
|
||||
<height>102</height>
|
||||
<texture border="5">mb_item_big.png</texture>
|
||||
</control>
|
||||
<control type="image">
|
||||
<description>thumbnail</description>
|
||||
<posx>10</posx>
|
||||
<posy>10</posy>
|
||||
<width>106</width>
|
||||
<height>62</height>
|
||||
<info>Listitem.Thumb</info>
|
||||
<width>126</width>
|
||||
<height>82</height>
|
||||
<info>ListItem.Thumb</info>
|
||||
<aspectratio>scale</aspectratio>
|
||||
<bordersize>3</bordersize>
|
||||
<bordertexture>mb_thumb_bg.png</bordertexture>
|
||||
</control>
|
||||
<control type="label">
|
||||
<description>episode title</description>
|
||||
<posx>128</posx>
|
||||
<posx>148</posx>
|
||||
<posy>6</posy>
|
||||
<width>440</width>
|
||||
<height>30</height>
|
||||
<align>left</align>
|
||||
<aligny>top</aligny>
|
||||
<info>ListItem.Label</info>
|
||||
<font>font16b</font>
|
||||
<font>font18</font>
|
||||
<textcolor>FFFEFEFE</textcolor>
|
||||
<wrapmultiline>true</wrapmultiline>
|
||||
</control>
|
||||
|
@ -150,30 +173,30 @@ mb.LoadShow()
|
|||
<align>right</align>
|
||||
<aligny>top</aligny>
|
||||
<label>Air Date: $INFO[ListItem.Date]</label>
|
||||
<font>font12</font>
|
||||
<font>font16</font>
|
||||
<textcolor>FFCCCCCC</textcolor>
|
||||
</control>
|
||||
<control type="label">
|
||||
<description>description</description>
|
||||
<posx>128</posx>
|
||||
<posx>148</posx>
|
||||
<posy>31</posy>
|
||||
<width>560</width>
|
||||
<height>60</height>
|
||||
<align>left</align>
|
||||
<aligny>top</aligny>
|
||||
<label>$INFO[ListItem.property(description)]</label>
|
||||
<font>font14</font>
|
||||
<font>font16</font>
|
||||
<textcolor>FFCCCCCC</textcolor>
|
||||
<wrapmultiline>true</wrapmultiline>
|
||||
</control>
|
||||
</itemlayout>
|
||||
<focusedlayout width="700" height="85">
|
||||
<focusedlayout width="700" height="105">
|
||||
<control type="togglebutton">
|
||||
<description>background</description>
|
||||
<posx>0</posx>
|
||||
<posy>0</posy>
|
||||
<width>700</width>
|
||||
<height>82</height>
|
||||
<height>102</height>
|
||||
<texturefocus border="5">mb_item_big_hover.png</texturefocus>
|
||||
<texturenofocus border="5">mb_item_big_hover.png</texturenofocus>
|
||||
<alttexturefocus border="5">mb_item_big.png</alttexturefocus>
|
||||
|
@ -184,19 +207,20 @@ mb.LoadShow()
|
|||
<description>thumbnail</description>
|
||||
<posx>10</posx>
|
||||
<posy>10</posy>
|
||||
<width>106</width>
|
||||
<height>62</height>
|
||||
<width>126</width>
|
||||
<height>82</height>
|
||||
<info>Listitem.Thumb</info>
|
||||
<aspectratio>scale</aspectratio>
|
||||
<bordertexture>mb_thumb_bg.png</bordertexture>
|
||||
<bordersize>3</bordersize>
|
||||
<visible>!Control.HasFocus(2040)</visible>
|
||||
</control>
|
||||
<control type="image">
|
||||
<description>thumbnail hover</description>
|
||||
<posx>10</posx>
|
||||
<posy>10</posy>
|
||||
<width>106</width>
|
||||
<height>62</height>
|
||||
<width>126</width>
|
||||
<height>82</height>
|
||||
<info>Listitem.Thumb</info>
|
||||
<aspectratio>scale</aspectratio>
|
||||
<bordertexture>mb_thumb_hover_bg.png</bordertexture>
|
||||
|
@ -205,14 +229,14 @@ mb.LoadShow()
|
|||
</control>
|
||||
<control type="label">
|
||||
<description>episode title</description>
|
||||
<posx>128</posx>
|
||||
<posx>148</posx>
|
||||
<posy>6</posy>
|
||||
<width>440</width>
|
||||
<height>30</height>
|
||||
<align>left</align>
|
||||
<aligny>top</aligny>
|
||||
<info>ListItem.Label</info>
|
||||
<font>font16b</font>
|
||||
<font>font18</font>
|
||||
<textcolor>FFFEFEFE</textcolor>
|
||||
</control>
|
||||
<control type="label">
|
||||
|
@ -224,28 +248,23 @@ mb.LoadShow()
|
|||
<align>right</align>
|
||||
<aligny>top</aligny>
|
||||
<label>Air Date: $INFO[ListItem.Date]</label>
|
||||
<font>font12</font>
|
||||
<font>font16</font>
|
||||
<textcolor>FFCCCCCC</textcolor>
|
||||
</control>
|
||||
<control type="label">
|
||||
<description>description</description>
|
||||
<posx>128</posx>
|
||||
<posx>148</posx>
|
||||
<posy>31</posy>
|
||||
<width>560</width>
|
||||
<height>60</height>
|
||||
<align>left</align>
|
||||
<aligny>top</aligny>
|
||||
<label>$INFO[ListItem.property(description)]</label>
|
||||
<font>font14</font>
|
||||
<font>font16</font>
|
||||
<textcolor>FFCCCCCC</textcolor>
|
||||
<wrapmultiline>true</wrapmultiline>
|
||||
</control>
|
||||
</focusedlayout>
|
||||
<!--
|
||||
<content type="action">
|
||||
<onclick lang="python"><![CDATA[mb.PlayRecording()]]></onclick>
|
||||
</content>
|
||||
-->
|
||||
</control>
|
||||
|
||||
<!-- end EPISODES LIST -->
|
||||
|
@ -326,7 +345,6 @@ mb.LoadShow()
|
|||
<!-- end SORT LIST -->
|
||||
|
||||
<control type="group" id="2060">
|
||||
|
||||
<control type="label">
|
||||
<posx>1079</posx>
|
||||
<posy>200</posy>
|
||||
|
@ -335,7 +353,6 @@ mb.LoadShow()
|
|||
<aligny>top</aligny>
|
||||
<textcolor>FF999999</textcolor>
|
||||
</control>
|
||||
|
||||
<control type="list" id="2061">
|
||||
<posx>1070</posx>
|
||||
<posy>225</posy>
|
||||
|
@ -344,7 +361,7 @@ mb.LoadShow()
|
|||
<onleft>2040</onleft>
|
||||
<onright>-</onright>
|
||||
<onup>2051</onup>
|
||||
<ondown>-</ondown>
|
||||
<ondown>2082</ondown>
|
||||
<itemlayout width="164" height="27">
|
||||
<control type="label">
|
||||
<description>title</description>
|
||||
|
@ -394,10 +411,79 @@ mb.LoadShow()
|
|||
<onclick lang="python"><![CDATA[mythboxee.SortDirSeriesEpisodes()]]></onclick>
|
||||
</content>
|
||||
</control>
|
||||
|
||||
</control>
|
||||
|
||||
|
||||
<control type="group" id="2080">
|
||||
<control type="label" id="2081">
|
||||
<posx>1079</posx>
|
||||
<posy>300</posy>
|
||||
<label>FILTERS:</label>
|
||||
<font>font14b</font>
|
||||
<aligny>top</aligny>
|
||||
<textcolor>FF999999</textcolor>
|
||||
</control>
|
||||
|
||||
<control type="list" id="2082">
|
||||
<posx>1070</posx>
|
||||
<posy>325</posy>
|
||||
<width>164</width>
|
||||
<height>100</height>
|
||||
<onleft>2040</onleft>
|
||||
<onright>-</onright>
|
||||
<onup>2061</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(2082)</visible>
|
||||
<selectedcolor>FFFFFFFF</selectedcolor>
|
||||
</control>
|
||||
<control type="label">
|
||||
<visible>!Control.HasFocus(2082)</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[mb.FilterEpisodes()]]></onclick>
|
||||
</content>
|
||||
</control>
|
||||
</control>
|
||||
|
||||
<!-- begin SHOW DETAILS CONTAINER -->
|
||||
|
||||
<control type="list" id="2070">
|
||||
|
@ -413,5 +499,26 @@ mb.LoadShow()
|
|||
|
||||
<!-- end SHOW DETAILS CONTAINER -->
|
||||
|
||||
<control type="group">
|
||||
<visible>App.HasSetting(loading)</visible>
|
||||
<animation effect="fade" start="0" end="100" time="150">VisibleChange</animation>
|
||||
<control type="image">
|
||||
<width>1280</width>
|
||||
<height>720</height>
|
||||
<texture>black.png</texture>
|
||||
<animation effect="fade" start="80" end="80" time="0" condition="true">Conditional</animation>
|
||||
</control>
|
||||
<control type="label">
|
||||
<posx>530</posx>
|
||||
<width>1280</width>
|
||||
<height>720</height>
|
||||
<align>cetner</align>
|
||||
<aligny>center</aligny>
|
||||
<font>sans40b</font>
|
||||
<label>LOADING...</label>
|
||||
<textcolor>ffffffff</textcolor>
|
||||
</control>
|
||||
</control>
|
||||
|
||||
</controls>
|
||||
</window>
|
||||
|
|
After Width: | Height: | Size: 859 B |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 52 KiB |