######################################################
######################################################
# XBMC Script for SageTV #
# by Brian Pattison aka Coolwave #
# coolwave6@yahoo.com #
# #
# This is my first experience with Python. #
# Thanks to all the great scripts out there #
# for me to get code from. This script wouldn't #
# exist without nielm's webserver for SageTV. #
# The guys at Frey of course rock for creating #
# such an extensible piece of software in SageTV. #
# Same goes to the XMBC developers! Rock on! #
# Thanks also to the crazy graphic designers #
# creating all the skins for MediaPortal. Your #
# Graphics are used in every PVR program out there #
# and we love them. Please switch to SageTV so we #
# can have you all creating new STVs. :) #
# #
######################################################
######################################################
import os, threading, xbmc, xbmcgui, time
import urllib, urllib2, re, copy, xml.dom.minidom
from string import split, replace, find
try: Emulating = xbmcgui.Emulating
except: Emulating = False
######################################################
######################################################
#User Adjustable Variables#
# x and y can help to move the entire interface
# on the screen if it is not displayed properly
x = 30
y = -15
######################################################
######################################################
# PLEASE EDIT settings.xml TO CHANGE ANY OTHER SETTINGS #
if Emulating:
dirHome = 'Q:\\scripts\\SageTV\\'
dirSkin = 'skins\\BlueTwo\\'
else:
dirHome = os.getcwd()
dirHome = dirHome[:-1]+'\\'
#Settings Class
class Setting:
def __init__(self, tagname, attribname):
XMLFile = open(dirHome + 'settings.xml', "r")
XMLData = XMLFile.read()
dom = xml.dom.minidom.parseString(XMLData)
XMLFile.close()
Item = dom.getElementsByTagName(tagname)[0]
self.tagname = tagname
self.attribname = attribname
self.value = Item.getAttribute(attribname)
def update(self, newvalue):
try:
XMLFile = open(dirHome + 'settings.xml', "r")
XMLData = XMLFile.read()
dom = xml.dom.minidom.parseString(XMLData)
XMLFile.close()
Item = dom.getElementsByTagName(self.tagname)[0]
Item.setAttribute(self.attribname, newvalue)
xmlstring = dom.toxml()
f = file(dirHome + 'settings.xml', 'wb')
try:
f.write(xmlstring)
finally:
f.close()
except:
dialog = xbmcgui.Dialog()
dialog.ok("SageTV", "Cannot write to " + dirHome + "settings.xml")
#End Settings Class
s = Setting("Connection", "Ipaddress")
ipaddress = s.value
s = Setting("Connection", "Port")
port = s.value
s = Setting("Connection", "UserId")
userid = s.value
s = Setting("Connection", "Password")
password = s.value
s = Setting("Appearance", "ShowEpisodeNames")
if s.value.lower() == "true":
ShowEpisodeNames = True
else:
ShowEpisodeNames = False
s = Setting("Appearance", "ShowDontLike")
if s.value.lower() == "true":
ShowDontLike = True
else:
ShowDontLike = False
s = Setting("Appearance", "ShowArchive")
if s.value.lower() == "true":
ShowArchive = True
else:
ShowArchive = False
s = Setting("Appearance", "Skin")
dirSkin = "skins\\" + s.value + "\\"
s = Setting("System", "RecordingPath")
RecordingPath = s.value.split(',')
s = Setting("System", "XBMCPath")
XBMCPath = s.value.split(',')
if ipaddress == "0.0.0.0":
firstlaunch = True
dialog = xbmcgui.Dialog()
dialog.ok("SageTV", "Please enter the IP Adress of the SageTV webserver.")
keyboard = xbmc.Keyboard(ipaddress)
keyboard.doModal()
if (keyboard.isConfirmed()):
ipaddress = keyboard.getText()
s = Setting("Connection", "Ipaddress")
s.update(ipaddress)
dialog.ok("SageTV", "Please enter the port used on the SageTV webserver.")
keyboard = xbmc.Keyboard(port)
keyboard.doModal()
if (keyboard.isConfirmed()):
port = keyboard.getText()
s = Setting("Connection", "Port")
s.update(port)
dialog.ok("SageTV", "Please enter the username for the SageTV webserver.")
keyboard = xbmc.Keyboard(userid)
keyboard.doModal()
if (keyboard.isConfirmed()):
userid = keyboard.getText()
s = Setting("Connection", "UserId")
s.update(userid)
dialog.ok("SageTV", "Please enter the password for the SageTV webserver.")
keyboard = xbmc.Keyboard(password)
keyboard.doModal()
if (keyboard.isConfirmed()):
password = keyboard.getText()
s = Setting("Connection", "Password")
s.update(password)
else:
firstlaunch = False
webaddress = userid + ":" + password + "@" + ipaddress + ":" + port
#Get Current Date/Connect to webserver
try:
Base_URL = "http://" + webaddress + "/sage/Home"
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close() # Closes connection to url
CURRENT_DATE = re.compile('Last updated: (....[0-9]*),', re.I).findall(WebHTML)[0]
Connect = True
except:
dialog = xbmcgui.Dialog()
dialog.ok("SageTV", "Unable to connect to http://" + webaddress + ".")
Connect = False
if firstlaunch:
s = Setting("Connection", "Ipaddress")
s.update("0.0.0.0")
#Declare global static variables
ACTION_MOVE_LEFT = 1
ACTION_MOVE_RIGHT = 2
ACTION_MOVE_UP = 3
ACTION_MOVE_DOWN = 4
ACTION_PAGE_UP = 5
ACTION_PAGE_DOWN = 6
ACTION_SELECT_ITEM = 7
ACTION_HIGHLIGHT_ITEM = 8
ACTION_PARENT_DIR = 9
ACTION_PREVIOUS_MENU = 10
ACTION_SHOW_INFO = 11
ACTION_PAUSE = 12
ACTION_STOP = 13
ACTION_NEXT_ITEM = 14
ACTION_PREV_ITEM = 15
ACTION_SCROLL_UP = 111
ACTION_SCROLL_DOWN = 112
ACTION_REMOTE_PLAY = 79
ACTION_REMOTE_BACK = 9
class Program:
def __init__(self, mediafileid, airingid):
#Get info from webpage
if mediafileid != 0:
Base_URL = "http://" + webaddress + "/sage/DetailedInfo?MediaFileId=" + str(mediafileid)
pmfid = mediafileid
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close() # Closes connection to url
precorded = True
elif airingid != 0:
Base_URL = "http://" + webaddress + "/sage/DetailedInfo?AiringId=" + str(airingid)
pmfid = airingid
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close() # Closes connection to url
precorded = False
if WebHTML.find('Internal details: MediaFileID=') > 0:
pmfid = re.compile('Internal details: MediaFileID=([0-9]*)', re.I).findall(WebHTML)[0]
precorded = True
else:
WebHTML = ""
if WebHTML != "":
#Title
ptitle = re.compile('\n(.*)', re.I).findall(WebHTML)[0]
ptitle = ptitle.replace("&", "&")
ptitle = ptitle.replace("%60", "'")
ptitle = ptitle.replace("%27", "'")
#SubTitle
if WebHTML.find('
Episode:') > 0:
psubtitle = re.compile('
Episode: (.*)
', re.I).findall(WebHTML)[0]
psubtitle = psubtitle.replace("amp;", "")
psubtitle = psubtitle.replace("%60", "'")
psubtitle = psubtitle.replace("%27", "'")
psubtitle2 = psubtitle + " - "
else:
psubtitle = ""
psubtitle2 = ""
#First Run/Rerun
if WebHTML.find(' ') > 0:
pfirstrun = True
else:
pfirstrun = False
#Currently Recording
if WebHTML.find('Record Options', re.I) > 0:
if WebHTML.find('Watch (Streamed)', re.I) > 0:
pcur_rec = True
else:
pcur_rec = False
else:
pcur_rec = False
#Date and Time
if WebHTML.find('Aired: \r\n', re.I) > 0:
pdatetime = re.compile('
Aired: \r\n(.*)\r\n', re.I).findall(WebHTML)[0]
pdate = re.compile('
Aired: \r\n(.*),.*\r\n', re.I).findall(WebHTML)[0]
if pdate == CURRENT_DATE:
pdate = 'Today'
ptime = re.compile('.*,.[0-9][0-9][0-9][0-9].([0-9]*:[0-9][0-9]...).-', re.I).findall(pdatetime)[0]
elif WebHTML.find('
Airing: \r\n', re.I) > 0:
pdatetime = re.compile('
Airing: \r\n(.*)\r\n', re.I).findall(WebHTML)[0]
pdate = re.compile('
Airing: \r\n(.*),.*\r\n', re.I).findall(WebHTML)[0]
ptime = re.compile('.*,.[0-9][0-9][0-9][0-9].([0-9]*:[0-9][0-9]...).-', re.I).findall(pdatetime)[0]
if pdate == CURRENT_DATE:
pdate = ptime
if pcur_rec: pdate = 'Now'
else:
pdatetime = ''
pdate = ''
ptime = ''
#Channel
if WebHTML.find('
Rating:', re.I) > 0:
pchannel = re.compile('
Channel: (.*)
Rating: .*
', re.I).findall(WebHTML)[0]
else:
try: pchannel = re.compile('Channel: (.*)
', re.I).findall(WebHTML)[0]
except: pchannel = "Err"
#Description
try: pshortdesc = re.compile('Description: (.*)
', re.I).findall(WebHTML)[0]
except: pshortdesc = "N/A"
pdesc = pshortdesc + '\n\n'
starring = re.compile('q=(.*);nm=on', re.I).findall(WebHTML)
for i in range(len(starring)):
starring[i] = starring[i].replace("+", " ")
starring[i] = starring[i].replace("%3A", ":")
starring[i] = starring[i].replace("%60", "'")
starring[i] = starring[i].replace("%27", "'")
if i > 0: pdesc = pdesc + ", " + starring[i]
else: pdesc = pdesc + starring[i]
category = re.compile('Category: (.*)
', re.I).findall(WebHTML)[0]
pdesc = pdesc + '\n\n' + category
showid = re.compile('Show ID: (.*)
', re.I).findall(WebHTML)[0]
pdesc = pdesc + '\n\n' + 'ShowID: ' + showid
#Record/Cancel Record
if WebHTML.find('command=Record', re.I) > 0:
pman_rec = False
else:
pman_rec = True
#Record Series/Cancel Record Series
if WebHTML.find('FavoriteId', re.I) > 0:
pfav = re.compile('FavoriteId=([0-9]*)">', re.I).findall(WebHTML)[0]
else:
pfav = "No"
#Watched/Unwatched
if WebHTML.find('command=ClearWatched', re.I) > 0:
pwatched = True
else:
pwatched = False
#Set/Clear Don't Like
if WebHTML.find(' ', re.I) > 0:
pdontlike = True
else:
pdontlike = False
#Archived
if mediafileid != 0:
if WebHTML.find(' ', re.I) > 0:
parch = True
else:
parch = False
else:
parch = False
#Start/End Padding
pstartpadding = 0
pendpadding = 0
if pman_rec:
if WebHTML.find('name="startpad"', re.I) > 0:
pstartpadding = int(re.compile('name="startpad" value="([0-9]*)"', re.I).findall(WebHTML)[0])
pendpadding = int(re.compile('name="endpad" value="([0-9]*)"', re.I).findall(WebHTML)[0])
earlypadding = (re.compile('', re.I).findall(WebHTML))
if earlypadding[0] == ' selected="selected">Earlier':
pstartpadding = -pstartpadding
if earlypadding[1] == ' selected="selected">Earlier':
pendpadding = -pendpadding
#Quality
pquality = "Default"
pallqualities = ["Default"]
if pman_rec:
if WebHTML.find('', re.I) > 0:
startsearch = WebHTML.find('', re.I)
pallqualities = re.compile('', re.I).findall(WebHTML)[0]
autodelsecstart = WebHTML.find('')
autodelsecend = WebHTML[autodelsecstart:].find(' ') + autodelsecstart
autodelete = re.compile('option value="(.*)" selected="selected"', re.I).findall(WebHTML[autodelsecstart:autodelsecend])[0]
startpadding = 0
endpadding = 0
startpadding = int(re.compile('name="startpad" value="([0-9]*)"', re.I).findall(WebHTML)[0])
endpadding = int(re.compile('name="endpad" value="([0-9]*)"', re.I).findall(WebHTML)[0])
earlypadding = (re.compile(' ', re.I).findall(WebHTML))
if earlypadding[0] == ' selected="selected">Earlier':
startpadding = -startpadding
if earlypadding[1] == ' selected="selected">Earlier':
endpadding = -endpadding
qualitystart = WebHTML.find('', re.I)
qualityend = WebHTML[qualitystart:].find(' ', re.I) + qualitystart
allqualities = re.compile(' ', re.I)
keepend = WebHTML[keepstart:].find(' ', re.I) + keepstart
keepatmost = int(re.compile('value="([0-9]*)" selected="selected"', re.I).findall(WebHTML[keepstart:keepend])[0])
if WebHTML.find('value="Above" selected="selected"') > 0:
priorityrelation = "Above"
else:
priorityrelation = "Below"
relfavstart = WebHTML.find('', re.I)
relfavend = WebHTML[relfavstart:].find(' ', re.I) + relfavstart
relativefid = re.compile('value="([0-9]*)" selected="selected"', re.I).findall(WebHTML[relfavstart:relfavend])[0]
self.priorityrelation = priorityrelation
self.relativefavoriteid = relativefid
self.title = title
self.firstruns = firstruns
self.autodelete = autodelete
self.startpadding = startpadding
self.endpadding = endpadding
self.quality = quality
self.allqualities = allqualities
self.keepatmost = keepatmost
#End Series Class
SearchVar = ""
SearchVarString = ""
#STARTUP WINDOW
SelectedProgram = Program(0,0)
class SageMain(xbmcgui.Window):
def __init__(self):
self.setCoordinateResolution(4)
if Emulating: xbmcgui.Window.__init__(self)
self.LeftButtonTitles = ['Recorded TV','Guide','Movies','Schedule','Search : Title','Search : Keyword']
s = Setting("Appearance", "AutoRefresh")
if s.value.lower() == "false":
self.LeftButtonTitles.append('Refresh')
self.LeftButtonTitles.append('Quit')
self.drawBackground()
self.getRecentRecordings()
self.getUpcomingRecordings()
self.drawRecentRecordings()
self.drawUpcomingRecordings()
self.fillRecentRecordings()
self.fillUpcomingRecordings()
self.drawLeftButtons()
self.setButtonControls()
self.setFocus(self.buttonLeft[0])
def drawBackground(self):
#Draw background
self.addControl(xbmcgui.ControlImage(0, 0, 720, 480, dirHome + dirSkin + 'background.png'))
self.addControl(xbmcgui.ControlImage(5 + x, 30 + y, 397, 70, dirHome + dirSkin + 'television_logo.png'))
self.strActionInfo = xbmcgui.ControlLabel(126 + x, 62 + y, 400, 20, '', 'font14', '0xFFCCCCFF')
self.addControl(self.strActionInfo)
self.strActionInfo.setLabel('My TV' )
def getRecentRecordings(self):
self.RecentPrograms = []
#Read Webpage
Base_URL = "http://" + webaddress + "/sage/Search?SearchString=&searchType=TVFiles&search_fields=title&TimeRange=0&Categories=**Any**&Channels=**Any**&watched=any&dontlike=any&favorite=any&autodelete=any&partials=both&sort1=airdate_desc&sort2=title_asc&pagelen=5"
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close() # Closes connection to url
#Find MediaFileIds
rmediafileids = re.compile('MediaFileId=([0-9]*)">', re.I).findall(WebHTML)
for i in range(len(rmediafileids)):
self.RecentPrograms.append(Program(rmediafileids[i], 0))
def getUpcomingRecordings(self):
self.UpcomingPrograms = []
#Read Webpage
Base_URL = "http://" + webaddress + "/sage/RecordingSchedule"
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close() # Closes connection to url
#Find AiringIds
uairingids = re.compile('AiringId=([0-9]*)"', re.I).findall(WebHTML)
if len(uairingids) > 5:
for i in range(0,4):
self.UpcomingPrograms.append(Program(0, uairingids[i]))
else:
for i in range(len(uairingids)):
self.UpcomingPrograms.append(Program(0, uairingids[i]))
def drawRecentRecordings(self):
#Draw Recent Recordings
self.strActionInfo = xbmcgui.ControlLabel(178 + x, 94 + y, 400, 20, '', 'font14', '0xFFCCCCFF')
self.addControl(self.strActionInfo)
self.strActionInfo.setLabel('Recent Recordings')
self.lstRecentRecordings = xbmcgui.ControlList(178 + x, 120 + y, 450, 170, 'font13', '0xFFCCCCFF', dirHome + dirSkin + 'list_sub_nofocus.png', dirHome + dirSkin + 'list_sub_focus.png', '0xFFFFFFFF')
self.addControl(self.lstRecentRecordings)
self.imgRecentCurRec = []
self.imgRecentWatched = []
self.imgRecentArchived = []
for i in range(len(self.RecentPrograms)):
self.imgRecentCurRec.append(xbmcgui.ControlImage(500 + x, 124 + 30*i + y, 15, 15, dirHome + dirSkin + 'curr_rec.png'))
self.addControl(self.imgRecentCurRec[i])
self.imgRecentWatched.append(xbmcgui.ControlImage(522 + x, 124 + 30*i + y, 15, 15, dirHome + dirSkin + 'watched.png'))
self.addControl(self.imgRecentWatched[i])
self.imgRecentArchived.append(xbmcgui.ControlImage(544 + x, 124 + 30*i + y, 15, 15, dirHome + dirSkin + 'lock.png'))
self.addControl(self.imgRecentArchived[i])
self.imgRecentWatched[i].setVisible(False)
self.imgRecentArchived[i].setVisible(False)
self.imgRecentCurRec[i].setVisible(False)
def fillRecentRecordings(self):
self.lstRecentRecordings.reset()
if not Emulating:
for i in range(len(self.RecentPrograms)):
listitem = xbmcgui.ListItem()
if (self.RecentPrograms[i].subtitle != "" and ShowEpisodeNames):
listitem.setLabel(self.RecentPrograms[i].title + ' - "' + self.RecentPrograms[i].subtitle + '"')
else:
listitem.setLabel(self.RecentPrograms[i].title)
listitem.setLabel2(self.RecentPrograms[i].date)
self.lstRecentRecordings.addItem(listitem)
if self.RecentPrograms[i].archived: (True)
else: self.imgRecentArchived[i].setVisible(False)
if self.RecentPrograms[i].watched: self.imgRecentWatched[i].setVisible(True)
else: self.imgRecentWatched[i].setVisible(False)
if self.RecentPrograms[i].cur_rec: self.imgRecentCurRec[i].setVisible(True)
else: self.imgRecentCurRec[i].setVisible(False)
def drawUpcomingRecordings(self):
#Draw Upcoming Recordings
self.strActionInfo = xbmcgui.ControlLabel(178 + x, 286 + y, 400, 20, '', 'font14', '0xFFCCCCFF')
self.addControl(self.strActionInfo)
self.strActionInfo.setLabel('Upcoming Recordings')
self.lstUpcomingRecordings = xbmcgui.ControlList(178 + x, 312 + y, 450, 170, 'font13', '0xFFCCCCFF', dirHome + dirSkin + 'list_sub_nofocus.png', dirHome + dirSkin + 'list_sub_focus.png', '0xFFFFFFFF')
self.addControl(self.lstUpcomingRecordings)
self.imgUpcomingWatched = []
for i in range(len(self.UpcomingPrograms)):
self.imgUpcomingWatched.append(xbmcgui.ControlImage(522 + x, 314 + 30*i + y, 15, 15, dirHome + dirSkin + 'watched.png'))
self.addControl(self.imgUpcomingWatched[i])
self.imgUpcomingWatched[i].setVisible(False)
def fillUpcomingRecordings(self):
self.lstUpcomingRecordings.reset()
if not Emulating:
for i in range(len(self.UpcomingPrograms)):
listitem = xbmcgui.ListItem()
if (self.UpcomingPrograms[i].subtitle != "" and ShowEpisodeNames):
listitem.setLabel(self.UpcomingPrograms[i].title + ' - "' + self.UpcomingPrograms[i].subtitle + '"')
else:
listitem.setLabel(self.UpcomingPrograms[i].title)
listitem.setLabel2(self.UpcomingPrograms[i].date)
self.lstUpcomingRecordings.addItem(listitem)
if self.UpcomingPrograms[i].watched: self.imgUpcomingWatched[i].setVisible(True)
else: self.imgUpcomingWatched[i].setVisible(False)
def drawLeftButtons(self):
#Draw Left Buttons
self.buttonLeft = []
for i in range(len(self.LeftButtonTitles)):
button = xbmcgui.ControlButton(6 + x, 94 + 36*i + y, 164, 30, self.LeftButtonTitles[i], dirHome + dirSkin + 'menu_list_focus.png', dirHome + dirSkin + 'menu_list_nofocus.png')
self.addControl(button)
self.buttonLeft.append(button)
for i in range(len(self.LeftButtonTitles)):
self.buttonLeft[i].controlUp(self.buttonLeft[i - 1])
self.buttonLeft[i].controlDown(self.buttonLeft[(i + 1) % len(self.LeftButtonTitles)])
self.buttonLeft[i].controlRight(self.lstRecentRecordings)
def Refresh(self):
#Refresh Recent and Upcoming Recordings
self.getRecentRecordings()
self.getUpcomingRecordings()
self.fillRecentRecordings()
self.fillUpcomingRecordings()
def setButtonControls(self):
#Set Button Controls
self.lstRecentRecordings.controlLeft(self.buttonLeft[0])
self.lstRecentRecordings.controlRight(self.lstUpcomingRecordings)
self.lstUpcomingRecordings.controlLeft(self.buttonLeft[0])
def downloadURL(self, source, destination):
try:
loc = urllib.URLopener()
loc.retrieve(source, destination)
except:
self.message('Stream Failed')
def onAction(self, action):
if (action == 10 or action == ACTION_REMOTE_BACK):
self.close()
elif (action == ACTION_REMOTE_PLAY):
if self.getFocus() == self.lstRecentRecordings:
#Watch
# Get video playlist from XBMC
plist = xbmc.PlayList(2)
plist.clear()
comskiparray = []
selected = self.lstRecentRecordings.getSelectedPosition()
if XBMCPath[self.RecentPrograms[selected].filelocation] != "":
for i in range(len(self.RecentPrograms[selected].files)):
plist.add(XBMCPath[self.RecentPrograms[selected].filelocation] + self.RecentPrograms[selected].files[i] + '.mpg')
pathschanged = True
else:
webfile = 'http://' + webaddress + '/sagepublic/PlaylistGenerator?Command=Generate&pltype=m3u&fntype=url&MediaFileId=' + str(self.RecentPrograms[selected].mediafileid)
localfile = dirHome + 'streamplaylist.m3u'
self.downloadURL(webfile,localfile)
# Change this to your playlist(s).
# Written like this: ['path\\to\\plist1', 'to\\plist2', 'plist\\3']
playlist_file = localfile
# Load playlist
plist.load(playlist_file)
pathschanged = False
p = xbmc.Player()
p.play(plist)
if (self.RecentPrograms[selected].watched == False and pathschanged == True and self.RecentPrograms[selected].cur_rec == False):
s = Setting("Appearance", "AutoRefresh")
while(p.isPlayingVideo()):
if (p.getTime() / p.getTotalTime()) > .8:
Base_URL = "http://" + webaddress + "/sage/AiringCommand?command=SetWatched&MediaFileId=" + str(self.RecentPrograms[selected].mediafileid)
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close() # Closes connection to url
if WebHTML.find('Applied command: SetWatched') > 0:
self.RecentPrograms[selected].watched = True
if s.value.lower() == "true":
self.Refresh()
try: self.lstRecentRecordings.selectItem(selected)
except: self.lstRecentRecordings.selectItem(0)
break
else:
time.sleep(3)
def onControl(self, control):
global SelectedProgram
s = Setting("Appearance", "AutoRefresh")
#One of the Recent Recordings was selected
if control == self.lstRecentRecordings:
selected = self.lstRecentRecordings.getSelectedPosition()
SelectedProgram = Program(self.RecentPrograms[selected].mediafileid, 0)
popup = SageProgramInfo()
popup .doModal()
del popup
if s.value.lower() == "true":
self.Refresh()
try: self.lstRecentRecordings.selectItem(selected)
except: self.lstRecentRecordings.selectItem(0)
#One of the Upcoming Recordings was selected
if control == self.lstUpcomingRecordings:
selected = self.lstUpcomingRecordings.getSelectedPosition()
SelectedProgram = Program(0, self.UpcomingPrograms[selected].mediafileid)
popup = SageProgramInfo()
popup .doModal()
del popup
if s.value.lower() == "true":
self.Refresh()
try: self.lstUpcomingRecordings.selectItem(selected)
except: self.lstUpcomingRecordings.selectItem(0)
#Left Buttons
for i in range(len(self.LeftButtonTitles)):
if control == self.buttonLeft[i]:
if self.LeftButtonTitles[i] == "Recorded TV":
#RecordedTV
self.displayResults("getRecordedTV", "")
if s.value.lower() == "true":
self.Refresh()
if self.LeftButtonTitles[i] == "Guide":
#Guide
popup = SageGuide()
popup .doModal()
del popup
if s.value.lower() == "true":
self.Refresh()
if self.LeftButtonTitles[i] == "Movies":
#Movies
self.displayResults("getMovies", "")
if s.value.lower() == "true":
self.Refresh()
if self.LeftButtonTitles[i] == "Schedule":
#Schedule
self.displayResults("getSchedule", "")
if s.value.lower() == "true":
self.Refresh()
if self.LeftButtonTitles[i] == "Search : Title":
#Search : Title
keyboard = xbmc.Keyboard('')
keyboard.doModal()
if (keyboard.isConfirmed()):
self.displayResults("getSearchTitle", keyboard.getText())
if s.value.lower() == "true":
self.Refresh()
if self.LeftButtonTitles[i] == "Search : Keyword":
#Search : Keyword
keyboard = xbmc.Keyboard('')
keyboard.doModal()
if (keyboard.isConfirmed()):
self.displayResults("getSearchKeyword", keyboard.getText())
if s.value.lower() == "true":
self.Refresh()
if self.LeftButtonTitles[i] == "Refresh":
#Refresh
self.Refresh()
if self.LeftButtonTitles[i] == "Quit":
#Quit
self.close()
def message(self, message):
dialog = xbmcgui.Dialog()
dialog.ok("SageTV", message)
def displayResults(self, searchvar, searchvarstring):
global SearchVar
global SearchVarString
SearchVar = searchvar
SearchVarString = searchvarstring
popup = SageSearchResults()
popup .doModal()
del popup
#End Startup Window
#SEARCH RESULTS WINDOW
class SageSearchResults(xbmcgui.Window):
def __init__(self):
self.setCoordinateResolution(4)
global SearchVar
global SearchVarString
if Emulating: xbmcgui.Window.__init__(self)
self.SortBy = "Date"
self.isRefreshed = False
self.BasePrograms = []
self.LeftButtonTitles = []
self.Filter = "No Filter"
if (SearchVar == "getRecordedTV" and SearchVarString == ""):
self.LeftButtonTitles.append(self.Filter)
s = Setting("RecordedTV", "SortBy")
self.SortBy = s.value
elif SearchVar == "getMovies":
s = Setting("Movies", "SortBy")
self.SortBy = s.value
elif SearchVar == "getSchedule":
s = Setting("Schedule", "SortBy")
self.SortBy = s.value
if self.SortBy.lower() == "title":
self.LeftButtonTitles.append('Sort By Title')
else:
self.LeftButtonTitles.append('Sort By Date')
if (SearchVar == "getRecordedTV" and SearchVarString == ""):
self.LeftButtonTitles.append('Schedule')
s = Setting("Appearance", "AutoRefresh")
if s.value.lower() == "false":
self.LeftButtonTitles.append('Refresh')
self.drawBackground()
self.getSearchResults()
self.drawLabels()
self.drawSearchResults()
self.fillSearchResults()
self.drawIcons()
self.drawLeftButtons()
self.setFocus(self.buttonLeft[0])
def drawBackground(self):
#Draw background
self.addControl(xbmcgui.ControlImage(0, 0, 720, 480, dirHome + dirSkin + 'background.png'))
self.addControl(xbmcgui.ControlImage(5 + x, 30 + y, 397, 70, dirHome + dirSkin + 'television_logo.png'))
def getSearchResults(self):
global SearchVar
global SearchVarString
if not self.isRefreshed:
self.SearchPrograms = []
sVar = SearchVarString.replace(" ", "+")
sVar = sVar.replace(":", "%3A")
sVar = sVar.replace("&", "&")
sVar = sVar.replace("'", "%27")
sVar = sVar.replace("`", "%60")
#Read the corresponding webpage for selected search
if SearchVar == "getRecordedTV":
if SearchVarString != "":
self.ScreenTitle = "Recorded TV (" + SearchVarString + ")"
self.SortBy = "Date"
else:
self.ScreenTitle = "Recorded TV"
if self.Filter.lower() == "unwatched":
watched = "cleared"
else:
watched = "any"
if self.Filter.lower() == "movies":
categories = "&Categories=film&Categories=movie&Categories=Movie"
else:
categories = "&Categories=**Any**"
Base_URL = "http://" + webaddress + "/sage/Search?SearchString=" + sVar + "&searchType=TVFiles&search_fields=title&TimeRange=0" + categories + "&Channels=**Any**&watched=" + watched + "&dontlike=any&favorite=any&autodelete=any&partials=both&sort1=airdate_desc&sort2=title_asc&pagelen=100"
elif SearchVar == "getMovies":
self.ScreenTitle = "Movies"
Base_URL = "http://" + webaddress + "/sage/Search?TimeRange=48&Categories=film&Categories=movie&Categories=Movie&SearchString="
elif SearchVar == "getSchedule":
self.ScreenTitle = "Schedule"
Base_URL = "http://" + webaddress + "/sage/RecordingSchedule"
elif SearchVar == "getSearchTitle":
self.ScreenTitle = "Title Search Results: " + SearchVarString
Base_URL = "http://" + webaddress + "/sage/Search?SearchString=" + sVar + "&searchType=Airings&search_fields=title&sort1=airdate_asc&pagelen=100"
elif SearchVar == "getOtherShowings":
self.ScreenTitle = "Other Showings of " + SearchVarString
Base_URL = "http://" + webaddress + "/sage/Search?SearchString=" + sVar + "&ExactTitle=true"
elif SearchVar == "getOtherScheduled":
self.ScreenTitle = "Other Scheduled Showings of " + SearchVarString
Base_URL = "http://" + webaddress + "/sage/Search?SearchString=" + sVar + "&ExactTitle=true"
elif SearchVar == "getSearchKeyword":
self.ScreenTitle = "Keyword Search Results: " + SearchVarString
Base_URL = "http://" + webaddress + "/sage/Search?SearchString=" + sVar + "&searchType=Airings&search_fields=**ALL**&sort1=airdate_asc&pagelen=100"
else:
self.ScreenTitle = "Search Results"
Base_URL = "http://" + webaddress + "/sage/Search?SearchString=" + sVar + "&pagelen=100"
#Reac webpage and add to list
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close() # Closes connection to url
self.TempPrograms = []
if SearchVar == "getRecordedTV":
mediafileids = re.compile('MediaFileId=([0-9]*)"', re.I).findall(WebHTML)
for i in range(len(mediafileids)):
self.SearchPrograms.append(Program(mediafileids[i], 0))
else:
airingids = re.compile('AiringId=([0-9]*)"', re.I).findall(WebHTML)
for i in range(len(airingids)):
self.SearchPrograms.append(Program(0, airingids[i]))
if SearchVar == "getOtherScheduled":
for i in range(len(self.SearchPrograms)):
if self.SearchPrograms[i].record:
self.TempPrograms.append(self.SearchPrograms[i])
elif self.SearchPrograms[i].favorite != "No":
self.TempPrograms.append(self.SearchPrograms[i])
self.SearchPrograms = self.TempPrograms
self.BasePrograms = copy.copy(self.SearchPrograms)
if self.SortBy.lower() == "title":
self.SearchPrograms.sort()
self.TempPrograms = []
self.DateLabels = []
for i in range(len(self.SearchPrograms)):
if i < len(self.SearchPrograms) - 1:
if self.SearchPrograms[i].title == self.SearchPrograms[i+1].title:
if i > 0:
if self.SearchPrograms[i].title != self.SearchPrograms[i-1].title:
self.TempPrograms.append(self.SearchPrograms[i])
self.DateLabels.append("More")
else:
self.TempPrograms.append(self.SearchPrograms[i])
self.DateLabels.append("More")
else:
if i > 0:
if self.SearchPrograms[i].title != self.SearchPrograms[i-1].title:
self.TempPrograms.append(self.SearchPrograms[i])
self.DateLabels.append(self.SearchPrograms[i].date)
else:
self.TempPrograms.append(self.SearchPrograms[i])
self.DateLabels.append(self.SearchPrograms[i].date)
else:
if self.SearchPrograms[i].title != self.SearchPrograms[i-1].title:
self.TempPrograms.append(self.SearchPrograms[i])
self.DateLabels.append(self.SearchPrograms[i].date)
self.SearchPrograms = self.TempPrograms
def drawLabels(self):
#Draw Screen Title Label
self.strActionInfo = xbmcgui.ControlLabel(126 + x, 62 + y, 400, 20, '', 'font14', '0xFFCCCCFF')
self.addControl(self.strActionInfo)
self.strActionInfo.setLabel(self.ScreenTitle)
#Draw Description Text
self.lblTitle = xbmcgui.ControlFadeLabel(178 + x, 360 + y, 450, 20,'font14','0xFFFFFFFF')
self.lblDescription = xbmcgui.ControlFadeLabel(178 + x, 380 + y, 450, 20,'font14','0xFFFFFFFF')
self.lblChannelTime = xbmcgui.ControlFadeLabel(178 + x, 400 + y, 450, 20,'font14','0xFFFFFFFF')
self.addControl(self.lblTitle)
self.addControl(self.lblDescription)
self.addControl(self.lblChannelTime)
def drawSearchResults(self):
#Draw Search Results
self.lstSearchResults = xbmcgui.ControlList(178 + x, 94 + y, 450, 260, 'font13', '0xFFCCCCFF', dirHome + dirSkin + 'list_sub_nofocus.png', dirHome + dirSkin + 'list_sub_focus.png', '0xFFFFFFFF')
self.addControl(self.lstSearchResults)
def fillSearchResults(self):
#Fill Search Results
self.lstSearchResults.reset()
if not Emulating:
for i in range(len(self.SearchPrograms)):
listitem = xbmcgui.ListItem()
if self.SortBy.lower() == "title":
if self.DateLabels[i] != "More":
if (self.SearchPrograms[i].subtitle != "" and ShowEpisodeNames):
listitem.setLabel(str(i+1) + '. ' + self.SearchPrograms[i].title + ' - "' + self.SearchPrograms[i].subtitle + '"')
else:
listitem.setLabel(str(i+1) + '. ' + self.SearchPrograms[i].title)
else:
listitem.setLabel(str(i+1) + '. ' + self.SearchPrograms[i].title)
listitem.setLabel2(self.DateLabels[i])
else:
if (self.SearchPrograms[i].subtitle != "" and ShowEpisodeNames):
listitem.setLabel(str(i+1) + '. ' + self.SearchPrograms[i].title + ' - "' + self.SearchPrograms[i].subtitle + '"')
else:
listitem.setLabel(str(i+1) + '. ' + self.SearchPrograms[i].title)
listitem.setLabel2(self.SearchPrograms[i].date)
self.lstSearchResults.addItem(listitem)
def drawIcons(self):
#Draw Watched and Archived images
self.imgWatched = xbmcgui.ControlImage(178 + x, 420 + y, 20, 20, dirHome + dirSkin + 'watched.png')
self.addControl(self.imgWatched)
self.imgArchived = xbmcgui.ControlImage(201 + x, 420 + y, 20, 20, dirHome + dirSkin + 'lock.png')
self.addControl(self.imgArchived)
self.imgDontLike = xbmcgui.ControlImage(224 + x, 420 + y, 20, 20, dirHome + dirSkin + 'dontlike.png')
self.addControl(self.imgDontLike)
self.imgWatched.setVisible(False)
self.imgArchived.setVisible(False)
self.imgDontLike.setVisible(False)
def drawLeftButtons(self):
global SearchVar
global SearchVarString
#Draw Left Buttons
self.buttonLeft = []
for i in range(len(self.LeftButtonTitles)):
arrowspace = ""
if self.LeftButtonTitles[i][:4] == "Sort": arrowspace = " "
spacedbuttons = ["No Filter", "Unwatched", "Archived", "Movies"]
for j in range(len(spacedbuttons)):
if self.LeftButtonTitles[i] == spacedbuttons[j]: arrowspace = " "
button = xbmcgui.ControlButton(6 + x, 94 + 36*i + y, 164, 30, arrowspace + self.LeftButtonTitles[i], dirHome + dirSkin + 'menu_list_focus.png', dirHome + dirSkin + 'menu_list_nofocus.png')
self.addControl(button)
self.buttonLeft.append(button)
self.imgSortArrow = xbmcgui.ControlImage(16 + x, 103 + y, 12, 12, dirHome + dirSkin + 'arrow_round_right_nofocus.png')
self.addControl(self.imgSortArrow)
if (SearchVar == "getRecordedTV" and SearchVarString == ""):
self.imgFilterArrow = xbmcgui.ControlImage(16 + x, 139 + y, 12, 12, dirHome + dirSkin + 'arrow_round_right_nofocus.png')
self.addControl(self.imgFilterArrow)
for i in range(len(self.LeftButtonTitles)):
self.buttonLeft[i].controlUp(self.buttonLeft[i - 1])
self.buttonLeft[i].controlDown(self.buttonLeft[(i + 1) % len(self.LeftButtonTitles)])
self.buttonLeft[i].controlRight(self.lstSearchResults)
self.lstSearchResults.controlLeft(self.buttonLeft[0])
def Refresh(self):
global SearchVar
global SearchVarString
if (SearchVar == "getRecordedTV" and SearchVarString == ""):
s = Setting("RecordedTV", "SortBy")
if self.SortBy.lower() == "title":
s.update("Title")
else:
s.update("Date")
elif SearchVar == "getMovies":
s = Setting("Movies", "SortBy")
if self.SortBy.lower() == "title":
s.update("Title")
else:
s.update("Date")
elif SearchVar == "getSchedule":
s = Setting("Schedule", "SortBy")
if self.SortBy.lower() == "title":
s.update("Title")
else:
s.update("Date")
for i in range(len(self.buttonLeft)):
self.removeControl(self.buttonLeft[i])
self.removeControl(self.imgSortArrow)
self.drawLeftButtons()
self.getSearchResults()
self.fillSearchResults()
def downloadURL(self, source, destination):
try:
loc = urllib.URLopener()
loc.retrieve(source, destination)
except:
self.message('Stream Failed')
def onAction(self, action):
if (action == 10 or action == ACTION_REMOTE_BACK):
self.close()
elif (action == ACTION_REMOTE_PLAY):
if SearchVar == "getRecordedTV":
#Watch
# Get video playlist from XBMC
plist = xbmc.PlayList(2)
plist.clear()
selected = self.lstSearchResults.getSelectedPosition()
if XBMCPath[self.SearchPrograms[selected].filelocation] != "":
for i in range(len(self.SearchPrograms[selected].files)):
plist.add(XBMCPath[self.SearchPrograms[selected].filelocation] + self.SearchPrograms[selected].files[i] + '.mpg')
pathschanged = True
else:
webfile = 'http://' + webaddress + '/sagepublic/PlaylistGenerator?Command=Generate&pltype=m3u&fntype=url&MediaFileId=' + str(self.SearchPrograms[selected].mediafileid)
localfile = dirHome + 'streamplaylist.m3u'
self.downloadURL(webfile,localfile)
# Change this to your playlist(s).
# Written like this: ['path\\to\\plist1', 'to\\plist2', 'plist\\3']
playlist_file = localfile
# Load playlist
plist.load(playlist_file)
pathschanged = False
p = xbmc.Player()
p.play(plist)
if (self.SearchPrograms[selected].watched == False and pathschanged == True and self.SearchPrograms[selected].cur_rec == False):
s = Setting("Appearance", "AutoRefresh")
while(p.isPlayingVideo()):
if (p.getTime() / p.getTotalTime()) > .8:
Base_URL = "http://" + webaddress + "/sage/AiringCommand?command=SetWatched&MediaFileId=" + str(self.SearchPrograms[selected].mediafileid)
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close() # Closes connection to url
if WebHTML.find('Applied command: SetWatched') > 0:
self.SearchPrograms[selected].watched = True
if s.value.lower() == "true":
self.isRefreshed = False
self.Refresh()
try: self.lstSearchResults.selectItem(selected)
except: self.lstSearchResults.selectItem(0)
self.lblTitle.reset()
self.lblDescription.reset()
self.lblChannelTime.reset()
if self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].subtitle != "":
self.lblDescription.addLabel('"' + self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].subtitle + '" ' + self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].shortdescription)
else:
self.lblDescription.addLabel(self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].shortdescription)
self.lblTitle.addLabel(self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].title)
self.lblChannelTime.addLabel(self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].channel + " " + self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].datetime)
if self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].archived: self.imgArchived.setVisible(True)
else: self.imgArchived.setVisible(False)
if self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].watched: self.imgWatched.setVisible(True)
else: self.imgWatched.setVisible(False)
if self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].dontlike: self.imgDontLike.setVisible(True)
else: self.imgDontLike.setVisible(False)
break
else:
time.sleep(3)
elif (action == ACTION_MOVE_LEFT or action == ACTION_MOVE_RIGHT
or action == ACTION_MOVE_UP or action == ACTION_MOVE_DOWN
or action == ACTION_PAGE_UP or action == ACTION_PAGE_DOWN
or action == ACTION_SCROLL_UP or action == ACTION_SCROLL_DOWN):
def SubthreadUpdate(self):
self.lblTitle.reset()
self.lblDescription.reset()
self.lblChannelTime.reset()
if self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].subtitle != "":
self.lblDescription.addLabel('"' + self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].subtitle + '" ' + self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].shortdescription)
else:
self.lblDescription.addLabel(self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].shortdescription)
self.lblTitle.addLabel(self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].title)
self.lblChannelTime.addLabel(self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].channel + " " + self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].datetime)
if self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].archived: self.imgArchived.setVisible(True)
else: self.imgArchived.setVisible(False)
if self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].watched: self.imgWatched.setVisible(True)
else: self.imgWatched.setVisible(False)
if self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].dontlike: self.imgDontLike.setVisible(True)
else: self.imgDontLike.setVisible(False)
subThread = threading.Thread(target=SubthreadUpdate, args=[self])
subThread.setDaemon(True)
xbmcgui.lock()
subThread.start()
subThread.join(0.05)
xbmcgui.unlock()
def onControl(self, control):
global SelectedProgram
global SearchVar
global SearchVarString
for i in range(len(self.LeftButtonTitles)):
global SearchVar
if control == self.buttonLeft[i]:
if self.LeftButtonTitles[i] == "No Filter":
self.isRefreshed = False
self.Filter = "Unwatched"
self.LeftButtonTitles[i] = self.Filter
self.Refresh()
self.setFocus(self.buttonLeft[i])
break
elif self.LeftButtonTitles[i] == "Unwatched":
self.isRefreshed = False
self.Filter = "Movies"
self.LeftButtonTitles[i] = self.Filter
self.Refresh()
self.setFocus(self.buttonLeft[i])
break
elif self.LeftButtonTitles[i] == "Movies":
self.isRefreshed = False
self.Filter = "No Filter"
self.LeftButtonTitles[i] = self.Filter
self.Refresh()
self.setFocus(self.buttonLeft[i])
break
elif self.LeftButtonTitles[i] == "Sort By Date":
self.isRefreshed = True
self.LeftButtonTitles[i] = "Sort By Title"
self.SortBy = "Title"
self.Refresh()
self.setFocus(self.buttonLeft[i])
break
elif self.LeftButtonTitles[i] == "Sort By Title":
self.isRefreshed = True
self.SearchPrograms = copy.copy(self.BasePrograms)
self.LeftButtonTitles[i] = "Sort By Date"
self.SortBy = "Date"
self.Refresh()
self.setFocus(self.buttonLeft[i])
break
elif self.LeftButtonTitles[i] == "Schedule":
s = Setting("Appearance", "AutoRefresh")
SearchVar = "getSchedule"
popup = SageSearchResults()
popup .doModal()
del popup
SearchVar = "getRecordedTV"
if s.value.lower() == "true":
self.isRefreshed = False
self.Refresh()
self.setFocus(self.buttonLeft[i])
break
elif self.LeftButtonTitles[i] == "Refresh":
self.isRefreshed = False
self.Refresh()
self.setFocus(self.buttonLeft[i])
break
if control == self.lstSearchResults:
s = Setting("Appearance", "AutoRefresh")
selected = self.lstSearchResults.getSelectedPosition()
if self.SortBy.lower() == "title":
if self.DateLabels[selected] == "More":
if self.SearchPrograms[selected].recorded:
SearchVar = "getRecordedTV"
else:
if self.SearchPrograms[selected].record:
SearchVar = "getOtherScheduled"
else:
SearchVar = "getOtherShowings"
SearchVarString = self.SearchPrograms[selected].title
popup = SageSearchResults()
popup .doModal()
del popup
else:
if self.SearchPrograms[selected].recorded:
SelectedProgram = Program(self.SearchPrograms[selected].mediafileid, 0)
else:
SelectedProgram = Program(0, self.SearchPrograms[selected].mediafileid)
popup = SageProgramInfo()
popup .doModal()
del popup
else:
if self.SearchPrograms[selected].recorded:
SelectedProgram = Program(self.SearchPrograms[selected].mediafileid, 0)
else:
SelectedProgram = Program(0, self.SearchPrograms[selected].mediafileid)
popup = SageProgramInfo()
popup .doModal()
del popup
if s.value.lower() == "true":
self.isRefreshed = False
self.Refresh()
try: self.lstSearchResults.selectItem(selected)
except: self.lstSearchResults.selectItem(0)
self.lblTitle.reset()
self.lblDescription.reset()
self.lblChannelTime.reset()
if self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].subtitle != "":
self.lblDescription.addLabel('"' + self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].subtitle + '" ' + self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].shortdescription)
else:
self.lblDescription.addLabel(self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].shortdescription)
self.lblTitle.addLabel(self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].title)
self.lblChannelTime.addLabel(self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].channel + " " + self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].datetime)
if self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].archived: self.imgArchived.setVisible(True)
else: self.imgArchived.setVisible(False)
if self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].watched: self.imgWatched.setVisible(True)
else: self.imgWatched.setVisible(False)
if self.SearchPrograms[self.lstSearchResults.getSelectedPosition()].dontlike: self.imgDontLike.setVisible(True)
else: self.imgDontLike.setVisible(False)
def message(self, message):
dialog = xbmcgui.Dialog()
dialog.ok("SageTV", message)
#End Search Reults Window
FavoriteId = 0
#PROGRAM INFO WINDOW
class SageProgramInfo(xbmcgui.Window):
def __init__(self):
self.setCoordinateResolution(4)
if Emulating: xbmcgui.Window.__init__(self)
global SelectedProgram
self.program = SelectedProgram
self.drawBackground()
self.drawLabels()
self.drawIcons()
self.drawLeftButtons()
self.setFocus(self.buttonLeft[0])
def drawBackground(self):
#Background and Labels Draw
self.addControl(xbmcgui.ControlImage(0,0,720,480, dirHome + dirSkin + 'background.png'))
self.addControl(xbmcgui.ControlImage(5 + x, 30 + y, 397, 70, dirHome + dirSkin + 'television_logo.png'))
self.strActionInfo = xbmcgui.ControlLabel(126 + x, 62 + y, 400, 20, '', 'font14', '0xFFCCCCFF')
self.addControl(self.strActionInfo)
self.strActionInfo.setLabel('Program Info' )
def drawLabels(self):
#First Run and subtitle
self.lblFirstRun = xbmcgui.ControlFadeLabel(178 + x, 120 + y, 430, 20, 'font14', '0xFFCCCCFF')
self.addControl(self.lblFirstRun)
if self.program.subtitle == "":
if self.program.firstrun: self.lblFirstRun.addLabel("First Run")
else: self.lblFirstRun.addLabel("Rerun")
else:
if self.program.firstrun: self.lblFirstRun.addLabel(self.program.subtitle + " - First Run")
else: self.lblFirstRun.addLabel(self.program.subtitle + " - Rerun")
#Date and Time
self.lblDateTime = xbmcgui.ControlFadeLabel(178 + x, 142 + y, 430, 20, 'font14', '0xFFCCCCFF')
self.addControl(self.lblDateTime)
self.lblDateTime.addLabel(self.program.datetime)
#Channel
self.lblChannel = xbmcgui.ControlFadeLabel(178 + x, 162 + y, 430, 20, 'font14', '0xFFCCCCFF')
self.addControl(self.lblChannel)
self.lblChannel.addLabel(self.program.channel)
#Description
self.DescriptionBox = xbmcgui.ControlTextBox(178 + x, 186 + y, 430, 300, 'font14', '0xFFFFFFFF')
self.addControl(self.DescriptionBox)
self.DescriptionBox.setText(self.program.description)
def drawLeftButtons(self):
self.LeftButtonTitles = []
if not self.program.recorded:
if self.program.record:
self.LeftButtonTitles.append('Recording Settings')
self.LeftButtonTitles.append('Cancel Recording')
else:
self.LeftButtonTitles.append('Record')
self.LeftButtonTitles.append('Advanced Record')
else:
self.LeftButtonTitles.append('Watch')
if self.program.cur_rec:
self.LeftButtonTitles.append('Recording Settings')
self.LeftButtonTitles.append('Cancel Recording')
if self.program.favorite != "No":
self.LeftButtonTitles.append('Series Settings')
else:
self.LeftButtonTitles.append('Record Series')
self.LeftButtonTitles.append('Other Showings')
if self.program.watched: self.LeftButtonTitles.append('Clear Watched')
else: self.LeftButtonTitles.append('Set Watched')
if ShowDontLike:
if self.program.dontlike: self.LeftButtonTitles.append("Clear Don't Like")
else: self.LeftButtonTitles.append("Set Don't Like")
if self.program.recorded:
if not self.program.archived:
if ShowArchive: self.LeftButtonTitles.append('Archive')
self.LeftButtonTitles.append('Delete')
self.buttonLeft = []
for i in range(len(self.LeftButtonTitles)):
button = xbmcgui.ControlButton(6 + x, 94 + 36*i + y, 164, 30, self.LeftButtonTitles[i], dirHome + dirSkin + 'menu_list_focus.png', dirHome + dirSkin + 'menu_list_nofocus.png')
self.addControl(button)
self.buttonLeft.append(button)
for i in range(len(self.LeftButtonTitles)):
self.buttonLeft[i].controlUp(self.buttonLeft[i - 1])
self.buttonLeft[i].controlDown(self.buttonLeft[(i + 1) % len(self.LeftButtonTitles)])
self.buttonLeft[i].controlRight(self.DescriptionBox)
self.DescriptionBox.controlLeft(self.buttonLeft[0])
def drawIcons(self):
ProgramTitleXadjust = 0
self.imgRec = []
if self.program.archived:
self.imgRec.append(xbmcgui.ControlImage(178 + x, 90 + y, 30, 30, dirHome + dirSkin + 'lock.png'))
ProgramTitleXadjust = 34
if self.program.cur_rec:
self.imgRec.append(xbmcgui.ControlImage(178 + x + ProgramTitleXadjust, 90 + y, 30, 30, dirHome + dirSkin + 'curr_rec.png'))
ProgramTitleXadjust = ProgramTitleXadjust + 34
if self.program.record:
self.imgRec.append(xbmcgui.ControlImage(178 + x + ProgramTitleXadjust, 90 + y, 30, 30, dirHome + dirSkin + 'man_rec.png'))
ProgramTitleXadjust = ProgramTitleXadjust + 34
if self.program.favorite != "No":
self.imgRec.append(xbmcgui.ControlImage(178 + x + ProgramTitleXadjust, 90 + y, 60, 30, dirHome + dirSkin + 'series_rec.png'))
ProgramTitleXadjust = ProgramTitleXadjust + 64
if self.program.watched:
self.imgRec.append(xbmcgui.ControlImage(178 + x + ProgramTitleXadjust, 90 + y, 30, 30, dirHome + dirSkin + 'watched.png'))
ProgramTitleXadjust = ProgramTitleXadjust + 34
if self.program.dontlike:
self.imgRec.append(xbmcgui.ControlImage(178 + x + ProgramTitleXadjust, 90 + y, 30, 30, dirHome + dirSkin + 'dontlike.png'))
ProgramTitleXadjust = ProgramTitleXadjust + 34
for i in range(len(self.imgRec)):
self.addControl(self.imgRec[i])
self.lblTitle = xbmcgui.ControlFadeLabel(178 + x + ProgramTitleXadjust, 94 + y, 300, 20, 'font14', '0xFFCCCCFF')
self.addControl(self.lblTitle)
self.lblTitle.addLabel(self.program.title)
def Refresh(self):
for i in range(len(self.buttonLeft)):
self.removeControl(self.buttonLeft[i])
for i in range(len(self.imgRec)):
self.removeControl(self.imgRec[i])
if self.program.recorded: self.program = Program(self.program.mediafileid, 0)
else: self.program = Program(0, self.program.mediafileid)
self.lblTitle.reset()
self.lblFirstRun.reset()
self.lblDateTime.reset()
self.lblChannel.reset()
self.DescriptionBox.reset()
self.LeftButtonTitles = []
self.drawLabels()
self.drawIcons()
self.drawLeftButtons()
def onAction(self, action):
if (action == 10 or action == ACTION_REMOTE_BACK):
self.close()
def onControl(self, control):
global SelectedProgram
global SearchVar
global SearchVarString
pt = self.program.title.replace(" ", "+")
pt = pt.replace(":", "%3A")
for i in range(len(self.LeftButtonTitles)):
if control == self.buttonLeft[i]:
if self.LeftButtonTitles[i] == "Watch":
#Watch
# Get video playlist from XBMC
plist = xbmc.PlayList(2)
plist.clear()
if XBMCPath[self.program.filelocation] != "":
for i in range(len(self.program.files)):
plist.add(XBMCPath[self.program.filelocation] + self.program.files[i] + '.mpg')
pathschanged = True
else:
webfile = 'http://' + webaddress + '/sagepublic/PlaylistGenerator?Command=Generate&pltype=m3u&fntype=url&MediaFileId=' + str(self.program.mediafileid)
localfile = dirHome + 'streamplaylist.m3u'
self.downloadURL(webfile,localfile)
# Change this to your playlist(s).
# Written like this: ['path\\to\\plist1', 'to\\plist2', 'plist\\3']
playlist_file = localfile
# Load playlist
plist.load(playlist_file)
pathschanged = False
p = xbmc.Player()
p.play(plist)
if (self.program.watched == False and pathschanged == True and self.program.cur_rec == False):
s = Setting("Appearance", "AutoRefresh")
while(p.isPlayingVideo()):
if (p.getTime() / p.getTotalTime()) > .8:
Base_URL = "http://" + webaddress + "/sage/AiringCommand?command=SetWatched&MediaFileId=" + str(self.program.mediafileid)
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close() # Closes connection to url
if WebHTML.find('Applied command: SetWatched') > 0:
self.program.watched = True
if s.value.lower() == "true":
self.Refresh()
self.setFocus(self.buttonLeft[0])
break
else:
time.sleep(3)
elif self.LeftButtonTitles[i] == "Record":
#Record
#Load recording page for particular MediaFileId or AiringId
Base_URL = "http://" + webaddress + "/sage/ManualRecord?command=Record&AiringId=" + str(self.program.mediafileid)
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close() # Closes connection to url
#Set and display proper label for Recording or Cancel Recording
if WebHTML.find('Applied command: Record') > 0:
self.program.record = True
self.Refresh()
self.setFocus(self.buttonLeft[i])
break
elif self.LeftButtonTitles[i] == "Recording Settings":
if self.program.cur_rec:
SelectedProgram = Program(self.program.mediafileid, 0)
else:
SelectedProgram = Program(0, self.program.mediafileid)
popup = SageRecSettings()
popup .doModal()
del popup
elif self.LeftButtonTitles[i] == "Advanced Record":
SelectedProgram = Program(0, self.program.mediafileid)
popup = SageRecSettings()
popup .doModal()
del popup
self.Refresh()
self.setFocus(self.buttonLeft[i])
elif self.LeftButtonTitles[i] == "Cancel Recording":
#Cancel Recording
if self.program.cur_rec: Base_URL = "http://" + webaddress + "/sage/ManualRecord?command=CancelRecord&MediaFileId=" + str(self.program.mediafileid)
else: Base_URL = "http://" + webaddress + "/sage/ManualRecord?command=CancelRecord&AiringId=" + str(self.program.mediafileid)
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close() # Closes connection to url
#Set and display proper label for Recording or Cancel Recording
if WebHTML.find('Applied command: CancelRecord') > 0:
self.program.record = False
self.Refresh()
self.setFocus(self.buttonLeft[i])
break
elif self.LeftButtonTitles[i] == "Record Series":
#Record Series
Base_URL = "http://" + webaddress + "/sage/FavoriteCommand?command=Add&title=" + pt + "&FavoriteId=-1"
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close() # Closes connection to url
self.program.favorite = True
self.Refresh()
self.setFocus(self.buttonLeft[i])
break
elif self.LeftButtonTitles[i] == "Series Settings":
#Series Settings
global FavoriteId
FavoriteId = self.program.favorite
popup = SageSeriesSettings()
popup .doModal()
del popup
self.Refresh()
self.setFocus(self.buttonLeft[i])
break
elif self.LeftButtonTitles[i] == "Other Showings":
#Other Showings
SearchVar = "getOtherShowings"
SearchVarString = self.program.title
#self.close()
popup = SageSearchResults()
popup .doModal()
del popup
elif self.LeftButtonTitles[i] == "Set Watched":
#Set Watched
if self.program.recorded: Base_URL = "http://" + webaddress + "/sage/AiringCommand?command=SetWatched&MediaFileId=" + str(self.program.mediafileid)
else: Base_URL = "http://" + webaddress + "/sage/AiringCommand?command=SetWatched&AiringId=" + str(self.program.mediafileid)
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close() # Closes connection to url
if WebHTML.find('Applied command: SetWatched') > 0:
self.program.watched = True
self.Refresh()
self.setFocus(self.buttonLeft[i])
break
elif self.LeftButtonTitles[i] == "Clear Watched":
#Clear Watched
if self.program.recorded: Base_URL = "http://" + webaddress + "/sage/AiringCommand?command=ClearWatched&MediaFileId=" + str(self.program.mediafileid)
else: Base_URL = "http://" + webaddress + "/sage/AiringCommand?command=ClearWatched&AiringId=" + str(self.program.mediafileid)
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close() # Closes connection to url
if WebHTML.find('Applied command: ClearWatched') > 0:
self.program.watched = False
self.Refresh()
self.setFocus(self.buttonLeft[i])
break
elif self.LeftButtonTitles[i] == "Set Don't Like":
#Set Don't Like
if self.program.recorded: Base_URL = "http://" + webaddress + "/sage/AiringCommand?command=SetDontLike&MediaFileId=" + str(self.program.mediafileid)
else: Base_URL = "http://" + webaddress + "/sage/AiringCommand?command=SetDontLike&AiringId="+ str(self.program.mediafileid)
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close() # Closes connection to url
if WebHTML.find('Applied command: SetDontLike') > 0:
self.program.dontlike = True
self.Refresh()
self.setFocus(self.buttonLeft[i])
break
elif self.LeftButtonTitles[i] == "Clear Don't Like":
#Clear Don't Like
if self.program.recorded: Base_URL = "http://" + webaddress + "/sage/AiringCommand?command=ClearDontLike&MediaFileId=" + str(self.program.mediafileid)
else: Base_URL = "http://" + webaddress + "/sage/AiringCommand?command=ClearDontLike&AiringId=" + str(self.program.mediafileid)
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close() # Closes connection to url
if WebHTML.find('Applied command: ClearDontLike') > 0:
self.program.dontlike = False
self.Refresh()
self.setFocus(self.buttonLeft[i])
break
elif self.LeftButtonTitles[i] == "Archive":
#Archive
self.message("Haven't found a way to archive through webserver...")
elif self.LeftButtonTitles[i] == "Delete":
#Delete
deleteDialog = xbmcgui.Dialog()
if deleteDialog.yesno("SageTV", "Are you sure you want to delete \n" + self.program.title + "?"):
Base_URL = "http://" + webaddress + "/sage/MediaFileCommand?command=DeleteFile&MediaFileId=" + str(self.program.mediafileid)
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close() # Closes connection to url
if WebHTML.find('Applied command: DeleteFile') > 0:
self.close()
def downloadURL(self, source, destination):
try:
loc = urllib.URLopener()
loc.retrieve(source, destination)
except:
self.message('Stream Failed')
def message(self, message):
dialog = xbmcgui.Dialog()
dialog.ok("SageTV", message)
#RECORDING SETTINGS
class SageRecSettings(xbmcgui.Window):
def __init__(self):
self.setCoordinateResolution(4)
if Emulating: xbmcgui.Window.__init__(self)
global SelectedProgram
self.program = SelectedProgram
if self.program.cur_rec:
dialog = xbmcgui.Dialog()
dialog.ok("SageTV", "Sorry, programs currently recording are not yet supported.")
self.close()
if not self.program.record:
self.setRecord()
self.NotScheduled = True
self.program = Program(0, self.program.mediafileid)
else:
self.NotScheduled = False
self.LeftButtonTitles = ['Save','Cancel']
self.drawBackground()
self.drawLabels()
self.drawPlusMinusButtons()
self.drawLeftButtons()
self.setFocus(self.buttonLeft[0])
def drawBackground(self):
#Background and Labels Draw
self.addControl(xbmcgui.ControlImage(0,0,720,480, dirHome + dirSkin + 'background.png'))
self.addControl(xbmcgui.ControlImage(5 + x, 30 + y, 397, 70, dirHome + dirSkin + 'television_logo.png'))
self.strActionInfo = xbmcgui.ControlLabel(126 + x, 62 + y, 400, 20, '', 'font14', '0xFFCCCCFF')
self.addControl(self.strActionInfo)
self.strActionInfo.setLabel('Advanced Recording (' + self.program.title + ')')
#Data Labels
self.lblQuality = xbmcgui.ControlFadeLabel(219 + x, 126 + y, 400, 20,'font13','0xFFFFFFFF')
self.addControl(self.lblQuality)
self.lblStop = xbmcgui.ControlFadeLabel(219 + x, 192 + y, 400, 20,'font13','0xFFFFFFFF')
self.addControl(self.lblStop)
self.lblStart = xbmcgui.ControlFadeLabel(219 + x, 258 + y, 400, 20,'font13','0xFFFFFFFF')
self.addControl(self.lblStart)
#Static Labels
self.strActionInfo = xbmcgui.ControlLabel(213 + x, 94 + y, 400, 20, '', 'font14', '0xFFFFFFFF')
self.addControl(self.strActionInfo)
self.strActionInfo.setLabel('Quality:')
self.strActionInfo = xbmcgui.ControlLabel(213 + x, 160 + y, 400, 20, '', 'font14', '0xFFFFFFFF')
self.addControl(self.strActionInfo)
self.strActionInfo.setLabel('Stop:')
self.strActionInfo = xbmcgui.ControlLabel(213 + x, 226 + y, 400, 20, '', 'font14', '0xFFFFFFFF')
self.addControl(self.strActionInfo)
self.strActionInfo.setLabel('Start:')
def drawLeftButtons(self):
#Draw Left Buttons
if self.program.record: self.buttonLeftTitles = ['Save', 'Cancel']
else: self.buttonLeftTitles = ['Record', 'Cancel']
self.buttonLeft = []
for i in range(len(self.LeftButtonTitles)):
button = xbmcgui.ControlButton(6 + x, 94 + 36*i + y, 164, 30, self.LeftButtonTitles[i], dirHome + dirSkin + 'menu_list_focus.png', dirHome + dirSkin + 'menu_list_nofocus.png')
self.addControl(button)
self.buttonLeft.append(button)
for i in range(len(self.LeftButtonTitles)):
self.buttonLeft[i].controlUp(self.buttonLeft[i - 1])
self.buttonLeft[i].controlDown(self.buttonLeft[(i + 1) % len(self.LeftButtonTitles)])
self.buttonLeft[i].controlRight(self.buttonMinus[0])
for i in range(3):
self.buttonMinus[i].controlLeft(self.buttonLeft[0])
self.buttonPlus[i].controlRight(self.buttonLeft[0])
def drawLabels(self):
#Quality
self.lblQuality.reset()
self.lblQuality.addLabel(self.program.quality)
#Stop
self.lblStop.reset()
if self.program.endpadding == -1:
stoplabel = "1 minute before"
elif self.program.endpadding < -1:
stoplabel = str(-self.program.endpadding) + " minutes before"
elif self.program.endpadding == 0:
stoplabel = "On Time"
elif self.program.endpadding == 1:
stoplabel = "1 minute after"
else:
stoplabel = str(self.program.endpadding) + " minutes after"
self.lblStop.addLabel(stoplabel)
#Start
self.lblStart.reset()
if self.program.startpadding == -1:
startlabel = "1 minute before"
elif self.program.startpadding < -1:
startlabel = str(-self.program.startpadding) + " minutes before"
elif self.program.startpadding == 0:
startlabel = "On Time"
elif self.program.startpadding == 1:
startlabel = "1 minute after"
else:
startlabel = str(self.program.startpadding) + " minutes after"
self.lblStart.addLabel(startlabel)
def drawPlusMinusButtons(self):
self.buttonPlus = []
self.buttonMinus = []
for i in range(3):
#Minus Buttons
button = xbmcgui.ControlButton(530 + x, 124 + 66*i + y, 30, 30, "-", dirHome + dirSkin + 'menu_list_focus.png', dirHome + dirSkin + 'menu_list_nofocus.png')
self.addControl(button)
self.buttonMinus.append(button)
#Plus Buttons
button = xbmcgui.ControlButton(564 + x, 124 + 66*i + y, 30, 30, "+", dirHome + dirSkin + 'menu_list_focus.png', dirHome + dirSkin + 'menu_list_nofocus.png')
self.addControl(button)
self.buttonPlus.append(button)
for i in range(3):
self.buttonPlus[i].controlUp(self.buttonPlus[i - 1])
self.buttonPlus[i].controlDown(self.buttonPlus[(i + 1) % 3])
self.buttonPlus[i].controlLeft(self.buttonMinus[i])
self.buttonMinus[i].controlUp(self.buttonMinus[i - 1])
self.buttonMinus[i].controlDown(self.buttonMinus[(i + 1) % 3])
self.buttonMinus[i].controlRight(self.buttonPlus[i])
def setRecord(self):
#Set to Record
Base_URL = "http://" + webaddress + "/sage/ManualRecord?command=Record&AiringId=" + str(self.program.mediafileid)
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close() # Closes connection to url
#Set and display proper label for Recording or Cancel Recording
if WebHTML.find('Applied command: Record') > 0:
self.program.record = True
def setCancelRecord(self):
Base_URL = "http://" + webaddress + "/sage/ManualRecord?command=CancelRecord&AiringId=" + str(self.program.mediafileid)
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close() # Closes connection to url
#Set and display proper label for Recording or Cancel Recording
if WebHTML.find('Applied command: CancelRecord') > 0:
self.program.record = False
def setQualityPadding(self):
#Set Quality
Base_URL = "http://" + webaddress + "/sage/ManualRecord?command=SetRecQual&AiringId=" + str(self.program.mediafileid) + "&quality=" + self.program.quality.replace(" ", "+")
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close() # Closes connection to url
#Set and display proper label for Recording or Cancel Recording
if not WebHTML.find('Applied command: SetRecQual') > 0:
self.message("Error Setting Quality")
#Set Padding
if self.program.startpadding < 0:
startpadtype = "earlier"
startpad = -self.program.startpadding
else:
startpadtype = "later"
startpad = self.program.startpadding
if self.program.endpadding < 0:
endpadtype = "earlier"
endpad = -self.program.endpadding
else:
endpadtype = "later"
endpad = self.program.endpadding
Base_URL = "http://" + webaddress + "/sage/ManualRecord?command=SetRecPad&AiringId=" + str(self.program.mediafileid) + "&startpad=" + str(startpad) + "&StartPadOffsetType=" + startpadtype + "&endpad=" + str(endpad) + "&EndPadOffsetType=" + endpadtype
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close() # Closes connection to url
#Set and display proper label for Recording or Cancel Recording
if not WebHTML.find('Applied command: SetRecPad') > 0:
self.message("Error Setting Start/Stop Time")
def onAction(self, action):
if (action == 10 or action == ACTION_REMOTE_BACK):
if self.NotScheduled:
self.setCancelRecord()
self.close()
def onControl(self, control):
for i in range(len(self.LeftButtonTitles)):
if control == self.buttonLeft[i]:
if self.LeftButtonTitles[i] == "Record":
self.setQualityPadding()
self.close()
elif self.LeftButtonTitles[i] == "Save":
#Save
self.setQualityPadding()
self.close()
elif self.LeftButtonTitles[i] == "Cancel":
#Cancel
if self.NotScheduled:
self.setCancelRecord()
self.close()
for i in range(3):
if control == self.buttonPlus[i]:
#Quality +
if i == 0:
for j in range(len(self.program.allqualities)):
if self.program.allqualities[j] == self.program.quality:
if j > 0:
self.program.quality = self.program.allqualities[j - 1]
break
self.drawLabels()
#Stop +
elif i == 1:
self.program.endpadding = self.program.endpadding + 1
self.drawLabels()
#Start +
elif i == 2:
self.program.startpadding = self.program.startpadding + 1
self.drawLabels()
if control == self.buttonMinus[i]:
#Quality -
if i == 0:
for j in range(len(self.program.allqualities)):
if self.program.allqualities[j] == self.program.quality:
if j < len(self.program.allqualities) - 1:
self.program.quality = self.program.allqualities[j + 1]
break
else:
break
self.drawLabels()
#Stop -
elif i == 1:
self.program.endpadding = self.program.endpadding - 1
self.drawLabels()
#Start -
elif i == 2:
self.program.startpadding = self.program.startpadding - 1
self.drawLabels()
def message(self, message):
dialog = xbmcgui.Dialog()
dialog.ok("SageTV", message)
#End SageRecSettings
#RECORD SERIES SETTINGS
class SageSeriesSettings(xbmcgui.Window):
def __init__(self):
self.setCoordinateResolution(4)
global FavoriteId
if Emulating: xbmcgui.Window.__init__(self)
if FavoriteId != 0:
self.series = Series(FavoriteId)
self.LeftButtonTitles = ['Save','Cancel','Cancel Series','Other Showings']
self.drawBackground()
self.drawLabels()
self.drawPlusMinusButtons()
self.drawLeftButtons()
self.setFocus(self.buttonLeft[0])
def drawBackground(self):
#Background and Labels Draw
self.addControl(xbmcgui.ControlImage(0,0,720,480, dirHome + dirSkin + 'background.png'))
self.addControl(xbmcgui.ControlImage(5 + x, 30 + y, 397, 70, dirHome + dirSkin + 'television_logo.png'))
self.strActionInfo = xbmcgui.ControlLabel(126 + x, 62 + y, 400, 20, '', 'font14', '0xFFCCCCFF')
self.addControl(self.strActionInfo)
self.strActionInfo.setLabel('Series Settings (' + self.series.title + ')')
#Data Labels
self.lblFirstRuns = xbmcgui.ControlFadeLabel(219 + x, 120 + y, 400, 20,'font13','0xFFFFFFFF')
self.addControl(self.lblFirstRuns)
self.lblQuality = xbmcgui.ControlFadeLabel(219 + x, 180 + y, 400, 20,'font13','0xFFFFFFFF')
self.addControl(self.lblQuality)
self.lblStop = xbmcgui.ControlFadeLabel(219 + x, 240 + y, 400, 20,'font13','0xFFFFFFFF')
self.addControl(self.lblStop)
self.lblStart = xbmcgui.ControlFadeLabel(219 + x, 300 + y, 400, 20,'font13','0xFFFFFFFF')
self.addControl(self.lblStart)
self.lblKeep = xbmcgui.ControlFadeLabel(219 + x, 360 + y, 400, 20,'font13','0xFFFFFFFF')
self.addControl(self.lblKeep)
self.lblKeepupto = xbmcgui.ControlFadeLabel(219 + x, 420 + y, 400, 20,'font13','0xFFFFFFFF')
self.addControl(self.lblKeepupto)
#Static Labels
self.strActionInfo = xbmcgui.ControlLabel(213 + x, 94 + y, 400, 20, '', 'font14', '0xFFFFFFFF')
self.addControl(self.strActionInfo)
self.strActionInfo.setLabel('Show Type:')
self.strActionInfo = xbmcgui.ControlLabel(213 + x, 154 + y, 400, 20, '', 'font14', '0xFFFFFFFF')
self.addControl(self.strActionInfo)
self.strActionInfo.setLabel('Quality:')
self.strActionInfo = xbmcgui.ControlLabel(213 + x, 214 + y, 400, 20, '', 'font14', '0xFFFFFFFF')
self.addControl(self.strActionInfo)
self.strActionInfo.setLabel('Stop:')
self.strActionInfo = xbmcgui.ControlLabel(213 + x, 274 + y, 400, 20, '', 'font14', '0xFFFFFFFF')
self.addControl(self.strActionInfo)
self.strActionInfo.setLabel('Start:')
self.strActionInfo = xbmcgui.ControlLabel(213 + x, 334 + y, 400, 20, '', 'font14', '0xFFFFFFFF')
self.addControl(self.strActionInfo)
self.strActionInfo.setLabel('Keep:')
self.strActionInfo = xbmcgui.ControlLabel(213 + x, 394 + y, 400, 20, '', 'font14', '0xFFFFFFFF')
self.addControl(self.strActionInfo)
self.strActionInfo.setLabel('Keep up to:')
def drawLeftButtons(self):
#Draw Left Buttons
self.buttonLeft = []
for i in range(len(self.LeftButtonTitles)):
button = xbmcgui.ControlButton(6 + x, 94 + 36*i + y, 164, 30, self.LeftButtonTitles[i], dirHome + dirSkin + 'menu_list_focus.png', dirHome + dirSkin + 'menu_list_nofocus.png')
self.addControl(button)
self.buttonLeft.append(button)
for i in range(len(self.LeftButtonTitles)):
self.buttonLeft[i].controlUp(self.buttonLeft[i - 1])
self.buttonLeft[i].controlDown(self.buttonLeft[(i + 1) % len(self.LeftButtonTitles)])
self.buttonLeft[i].controlRight(self.buttonMinus[0])
for i in range(6):
self.buttonMinus[i].controlLeft(self.buttonLeft[0])
self.buttonPlus[i].controlRight(self.buttonLeft[0])
def drawLabels(self):
#Show Type
self.lblFirstRuns.reset()
self.lblFirstRuns.addLabel(self.series.firstruns)
#Quality
self.lblQuality.reset()
self.lblQuality.addLabel(self.series.quality)
#Stop
self.lblStop.reset()
if self.series.endpadding == -1:
stoplabel = "1 minute before"
elif self.series.endpadding < -1:
stoplabel = str(-self.series.endpadding) + " minutes before"
elif self.series.endpadding == 0:
stoplabel = "On Time"
elif self.series.endpadding == 1:
stoplabel = "1 minute after"
else:
stoplabel = str(self.series.endpadding) + " minutes after"
self.lblStop.addLabel(stoplabel)
#Start
self.lblStart.reset()
if self.series.startpadding == -1:
startlabel = "1 minute before"
elif self.series.startpadding < -1:
startlabel = str(-self.series.startpadding) + " minutes before"
elif self.series.startpadding == 0:
startlabel = "On Time"
elif self.series.startpadding == 1:
startlabel = "1 minute after"
else:
startlabel = str(self.series.startpadding) + " minutes after"
self.lblStart.addLabel(startlabel)
#Keep
self.lblKeep.reset()
if self.series.autodelete == "true":
self.lblKeep.addLabel("Until space is needed")
else:
self.lblKeep.addLabel("Until I delete")
#Keep up to
self.lblKeepupto.reset()
if self.series.keepatmost == 0:
self.lblKeepupto.addLabel("As many as possible")
else:
self.lblKeepupto.addLabel(str(self.series.keepatmost))
def drawPlusMinusButtons(self):
self.buttonPlus = []
self.buttonMinus = []
for i in range(6):
#Minus Buttons
button = xbmcgui.ControlButton(530 + x, 124 + 60*i + y, 30, 30, "-", dirHome + dirSkin + 'menu_list_focus.png', dirHome + dirSkin + 'menu_list_nofocus.png')
self.addControl(button)
self.buttonMinus.append(button)
#Plus Buttons
button = xbmcgui.ControlButton(564 + x, 124 + 60*i + y, 30, 30, "+", dirHome + dirSkin + 'menu_list_focus.png', dirHome + dirSkin + 'menu_list_nofocus.png')
self.addControl(button)
self.buttonPlus.append(button)
for i in range(6):
self.buttonPlus[i].controlUp(self.buttonPlus[i - 1])
self.buttonPlus[i].controlDown(self.buttonPlus[(i + 1) % 6])
self.buttonPlus[i].controlLeft(self.buttonMinus[i])
self.buttonMinus[i].controlUp(self.buttonMinus[i - 1])
self.buttonMinus[i].controlDown(self.buttonMinus[(i + 1) % 6])
self.buttonMinus[i].controlRight(self.buttonPlus[i])
def onAction(self, action):
if (action == 10 or action == ACTION_REMOTE_BACK):
self.close()
def onControl(self, control):
global SearchVar
global SearchVarString
temptitle = self.series.title.replace(" ", "+")
temptitle = temptitle.replace("&", "%26")
temptitle = temptitle.replace("`", "%60")
temptitle = temptitle.replace("'", "%27")
for i in range(len(self.LeftButtonTitles)):
if control == self.buttonLeft[i]:
if self.LeftButtonTitles[i] == "Save":
#Save
if self.series.startpadding < 0:
startpadtype = "earlier"
startpad = -self.series.startpadding
else:
startpadtype = "later"
startpad = self.series.startpadding
if self.series.endpadding < 0:
endpadtype = "earlier"
endpad = -self.series.endpadding
else:
endpadtype = "later"
endpad = self.series.endpadding
quality = self.series.quality.replace(" ", "+")
Base_URL = "http://" + webaddress + "/sage/FavoriteCommand?command=Update&FavoriteId=" + str(self.series.favoriteid) + "&title=" + temptitle + "&run=" + self.series.firstruns.replace(" ", "+") + "&autodelete=" + self.series.autodelete + "&keepatmost=" + str(self.series.keepatmost) + "&startpad=" + str(startpad) + "&StartPadOffsetType=" + startpadtype + "&endpad=" + str(endpad) + "&EndPadOffsetType=" + endpadtype + "&quality=" + quality + "&favoritepriorityrelation=" + self.series.priorityrelation + "&relativefavoriteid=" + self.series.relativefavoriteid
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close() # Closes connection to url
if not WebHTML.find('Applied command: Update on favorite') > 0:
self.message("Error Updating Series Settings")
self.close()
elif self.LeftButtonTitles[i] == "Cancel":
#Cancel
self.close()
elif self.LeftButtonTitles[i] == "Cancel Series":
#Cancel Series
deleteDialog = xbmcgui.Dialog()
if deleteDialog.yesno("SageTV", "Are you sure you want to cancel series for \n" + self.series.title + "?"):
Base_URL = "http://" + webaddress + "/sage/FavoriteCommand?command=Remove&FavoriteId=" + str(self.series.favoriteid)
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close() # Closes connection to url
self.close()
elif self.LeftButtonTitles[i] == "Other Showings":
#Other Showings
SearchVar = "getOtherShowings"
SearchVarString = self.series.title
#self.close()
popup = SageSearchResults()
popup .doModal()
del popup
for i in range(6):
if control == self.buttonPlus[i]:
#FirstRuns +
if i == 0:
fruns = ['First Runs and ReRuns', 'First Runs', 'ReRuns']
for j in range(len(fruns)):
if fruns[j] == self.series.firstruns:
if j < len(fruns) - 1:
self.series.firstruns = fruns[j + 1]
break
else:
self.series.firstruns = fruns[0]
break
self.drawLabels()
#Quality +
if i == 1:
for j in range(len(self.series.allqualities)):
if self.series.allqualities[j] == self.series.quality:
if j > 0:
self.series.quality = self.series.allqualities[j - 1]
break
self.drawLabels()
#Stop +
elif i == 2:
self.series.endpadding = self.series.endpadding + 1
self.drawLabels()
#Start +
elif i == 3:
self.series.startpadding = self.series.startpadding + 1
self.drawLabels()
#Keep +
elif i == 4:
if self.series.autodelete == "true": self.series.autodelete = "false"
else: self.series.autodelete = "true"
self.drawLabels()
#Keep up to +
elif i == 5:
if self.series.keepatmost < 15:
self.series.keepatmost = self.series.keepatmost + 1
else:
self.series.keepatmost = 0
self.drawLabels()
if control == self.buttonMinus[i]:
#FirstRuns -
if i == 0:
fruns = ['First Runs and ReRuns', 'First Runs', 'ReRuns']
for j in range(len(fruns)):
if fruns[j] == self.series.firstruns:
if j > 0:
self.series.firstruns = fruns[j - 1]
break
else:
self.series.firstruns = fruns[len(fruns) - 1]
break
self.drawLabels()
#Quality -
if i == 1:
for j in range(len(self.series.allqualities)):
if self.series.allqualities[j] == self.series.quality:
if j < len(self.series.allqualities) - 1:
self.series.quality = self.series.allqualities[j + 1]
break
else:
break
self.drawLabels()
#Stop -
elif i == 2:
self.series.endpadding = self.series.endpadding - 1
self.drawLabels()
#Start -
elif i == 3:
self.series.startpadding = self.series.startpadding - 1
self.drawLabels()
#Keep -
elif i == 4:
if self.series.autodelete == "true": self.series.autodelete = "false"
else: self.series.autodelete = "true"
self.drawLabels()
#Keep up to -
elif i == 5:
if self.series.keepatmost > 0:
self.series.keepatmost = self.series.keepatmost - 1
else:
self.series.keepatmost = 15
self.drawLabels()
def message(self, message):
dialog = xbmcgui.Dialog()
dialog.ok("SageTV", message)
#End SageSeriesSettings
#THE GUIDE
class SageGuide(xbmcgui.Window):
def __init__(self):
self.setCoordinateResolution(4)
if Emulating: xbmcgui.Window.__init__(self)
self.drawBackground()
self.drawChannelsPrograms()
self.drawIcons()
self.fillChannels()
self.setFocus(self.lstChannels)
def drawBackground(self):
#Background and Labels Draw
self.addControl(xbmcgui.ControlImage(0,0,720,480, dirHome + dirSkin + 'background.png'))
self.addControl(xbmcgui.ControlImage(5 + x, 30 + y, 397, 70, dirHome + dirSkin + 'television_logo.png'))
self.strActionInfo = xbmcgui.ControlLabel(126 + x, 62 + y, 400, 20, '', 'font14', '0xFFCCCCFF')
self.addControl(self.strActionInfo)
self.strActionInfo.setLabel('Guide')
def drawChannelsPrograms(self):
#Draw Channels List
self.lstChannels = xbmcgui.ControlList(2 + x, 94 + y, 164, 260, 'font13', '0xFFCCCCFF', dirHome + dirSkin + 'list_sub_nofocus.png', dirHome + dirSkin + 'list_sub_focus.png', '0xFFFFFFFF')
self.addControl(self.lstChannels)
#Draw Listings List
self.lstPrograms = xbmcgui.ControlList(178 + x, 94 + y, 450, 260, 'font13', '0xFFCCCCFF', dirHome + dirSkin + 'list_sub_nofocus.png', dirHome + dirSkin + 'list_sub_focus.png', '0xFFFFFFFF')
self.addControl(self.lstPrograms)
self.lstChannels.controlRight(self.lstPrograms)
self.lstPrograms.controlLeft(self.lstChannels)
#Draw Description Text
self.lblTitle = xbmcgui.ControlFadeLabel(178 + x, 360 + y, 450, 20,'font14','0xFFFFFFFF')
self.lblDescription = xbmcgui.ControlFadeLabel(178 + x, 380 + y, 450, 20,'font14','0xFFFFFFFF')
self.lblChannelTime = xbmcgui.ControlFadeLabel(178 + x, 400 + y, 450, 20,'font14','0xFFFFFFFF')
self.addControl(self.lblTitle)
self.addControl(self.lblDescription)
self.addControl(self.lblChannelTime)
def drawIcons(self):
#Draw Watched and Archived images
self.imgWatched = xbmcgui.ControlImage(178 + x, 420 + y, 20, 20, dirHome + dirSkin + 'watched.png')
self.addControl(self.imgWatched)
self.imgArchived = xbmcgui.ControlImage(201 + x, 420 + y, 20, 20, dirHome + dirSkin + 'lock.png')
self.addControl(self.imgArchived)
self.imgDontLike = xbmcgui.ControlImage(224 + x, 420 + y, 20, 20, dirHome + dirSkin + 'dontlike.png')
self.addControl(self.imgDontLike)
self.imgWatched.setVisible(False)
self.imgArchived.setVisible(False)
self.imgDontLike.setVisible(False)
def fillChannels(self):
Base_URL = "http://" + webaddress + "/sage/Search"
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close() # Closes connection to url
channelsstart = WebHTML.find('', re.I) + channelsstart
self.ChannelsValue = re.compile('(.*) ', re.I).findall(WebHTML[channelsstart:channelsend])
self.Channels = self.Channels[1:len(self.Channels)]
#Fill Channels
self.lstChannels.reset()
if not Emulating:
for i in range(len(self.Channels)):
self.lstChannels.addItem(xbmcgui.ListItem(label=self.Channels[i]))
def fillPrograms(self, channelid):
#Get Shows for channel
Base_URL = "http://" + webaddress + "/sage/Search?SearchString=&searchType=Airings&Channels=" + str(channelid) + "&sort1=airdate_asc&sort2=none&pagelen=20"
WebSock = urllib.urlopen(Base_URL) # Opens a 'Socket' to URL
WebHTML = WebSock.read() # Reads Contents of URL and saves to Variable
WebSock.close() # Closes connection to url
self.ChannelPrograms = []
airingids = re.compile('AiringId=([0-9]*)"', re.I).findall(WebHTML)
for i in range(len(airingids)):
self.ChannelPrograms.append(Program(0, airingids[i]))
#Fill Programs
self.lstPrograms.reset()
if not Emulating:
for i in range(len(self.ChannelPrograms)):
listitem = xbmcgui.ListItem()
if (self.ChannelPrograms[i].subtitle != "" and ShowEpisodeNames):
listitem.setLabel(str(i+1) + '. ' + self.ChannelPrograms[i].title + ' - "' + self.ChannelPrograms[i].subtitle + '"')
else:
listitem.setLabel(str(i+1) + '. ' + self.ChannelPrograms[i].title)
listitem.setLabel2(self.ChannelPrograms[i].date)
self.lstPrograms.addItem(listitem)
def onAction(self, action):
if (action == 10 or action == ACTION_REMOTE_BACK):
self.close()
elif (action == ACTION_MOVE_LEFT or action == ACTION_MOVE_RIGHT
or action == ACTION_MOVE_UP or action == ACTION_MOVE_DOWN
or action == ACTION_PAGE_UP or action == ACTION_PAGE_DOWN
or action == ACTION_SCROLL_UP or action == ACTION_SCROLL_DOWN):
def SubthreadUpdate(self):
if action == ACTION_MOVE_LEFT:
self.setFocus(self.lstChannels)
elif action == ACTION_MOVE_RIGHT:
self.setFocus(self.lstPrograms)
self.lblTitle.reset()
self.lblDescription.reset()
self.lblChannelTime.reset()
if self.ChannelPrograms[self.lstPrograms.getSelectedPosition()].subtitle != "":
self.lblDescription.addLabel('"' + self.ChannelPrograms[self.lstPrograms.getSelectedPosition()].subtitle + '" ' + self.ChannelPrograms[self.lstPrograms.getSelectedPosition()].shortdescription)
else:
self.lblDescription.addLabel(self.ChannelPrograms[self.lstPrograms.getSelectedPosition()].shortdescription)
self.lblTitle.addLabel(self.ChannelPrograms[self.lstPrograms.getSelectedPosition()].title)
self.lblChannelTime.addLabel(self.ChannelPrograms[self.lstPrograms.getSelectedPosition()].channel + " " + self.ChannelPrograms[self.lstPrograms.getSelectedPosition()].datetime)
if self.ChannelPrograms[self.lstPrograms.getSelectedPosition()].archived: self.imgArchived.setVisible(True)
else: self.imgArchived.setVisible(False)
if self.ChannelPrograms[self.lstPrograms.getSelectedPosition()].watched: self.imgWatched.setVisible(True)
else: self.imgWatched.setVisible(False)
if self.ChannelPrograms[self.lstPrograms.getSelectedPosition()].dontlike: self.imgDontLike.setVisible(True)
else: self.imgDontLike.setVisible(False)
subThread = threading.Thread(target=SubthreadUpdate, args=[self])
subThread.setDaemon(True)
xbmcgui.lock()
subThread.start()
subThread.join(0.05)
xbmcgui.unlock()
def onControl(self, control):
global SelectedProgram
if control == self.lstChannels:
self.fillPrograms(self.ChannelsValue[self.lstChannels.getSelectedPosition()])
elif control == self.lstPrograms:
SelectedProgram = Program(0, self.ChannelPrograms[self.lstPrograms.getSelectedPosition()].mediafileid)
popup = SageProgramInfo()
popup .doModal()
del popup
if Connect:
mydisplay = SageMain()
mydisplay .doModal()
del mydisplay