"""
$Id: mythtvlivetv.py,v 1.51 2007/05/12 23:43:24 frooby Exp $
"""
from mythtvgui import Dialog
from singleton import getInstance,delInstance
import datetime, threading
import mythtv
import mythtvgui
import mythtvutil
import mythtvstruct
import os
import sre
import string
import time
import traceback
import xbmcgui
import xbmc
def debug( str ):
mythtvutil.debug( mythtvutil.DEBUG_GUI, str )
def compareChannelAsc( x, y ):
if x.callsign() == y.callsign():
return cmp( x.chanid(), y.chanid() )
else:
return x.callsign() < y.callsign()
def compareChannelDesc( y, x ):
if x.callsign() == y.callsign():
return cmp( x.chanid(), y.chanid() )
else:
return x.callsign() < y.callsign()
def compareTitleAsc( x, y ):
if x.title() == y.title():
return cmp( x.starttime(), y.starttime() )
else:
return cmp( x.title(), y.title() )
def compareTitleDesc( y, x ):
if x.title() == y.title():
return cmp( x.starttime(), y.starttime() )
else:
return cmp( x.title(), y.title() )
def showWindow(winDialog):
"""
Function to create the livetv window.
"""
debug( "> mythtvlivetv.showWindow()" )
# global win
# mythtvgui.checkSettings()
win = Window()
win.loadskin( "livetv.xml" )
win.checkConnections()
win.loadPrograms()
winDialog.close()
win.doModal()
del win
debug( "< mythtvlivetv.showWindow()" )
class Window( mythtvgui.BaseWindow ):
def __init__( self ):
mythtvgui.BaseWindow.__init__( self )
debug("> LIVETV Window.init")
self.player = None
self.channels = None
self.programs=[]
self.focusControl = None
self.curChannel = 0
self.ringBufferName = ""
self.conn = None
self.stopping = False
self.playing = False
self.recLoaded = False
self.filePrefix = ""
debug(" LIVETV Window.init [A]")
self.lastFile = ""
self.lastChainPos = -1
self.db = None
self.fullpath = ""
self.loopPause = 0.5 # (seconds) how long to wait between loops while playing
self.chainCheck = 3 # (seconds) how long to wait between check for new tvchains
self.chainCheckCount = self.chainCheck * ( 1 / self.loopPause )
self.programReload = 360 # (seconds) How long to wait before reloading program information (so the info is upto date)
self.programReloadCount = self.programReload * ( 1 / self.loopPause )
self.conflictCheck = 30 # (seconds) How long to wait between checks for conflicts
self.conflictCheckCount = self.conflictCheck * ( 1 / self.loopPause )
debug(" LIVETV Window.init [B]")
self.lastMin = int(time.strftime("%M", time.localtime() ))
self.curEncoder = -1
self.nextRec = False
self.recordedFormat = getInstance( mythtv.Settings ).getSetting( "mythtv_recordlive" )
debug(" LIVETV Window.init [C] - Creating Playlist")
# create a new playlist to add tvchains to
try:
self.tvplaylist = xbmc.PlayList(1)
except:
self.tvplaylist = xbmc.PlayList(3)
debug(" LIVETV Window.init [D] - Done")
self.osd = None
self.recosd = None
debug( '< LIVETV Window.init' )
def cleanupPlayer( self ):
self.loadingShow(False)
if self.conn:
self.conn.close()
delInstance ( mythtv.Connection )
self.conn = None
if self.db and self.recordedFormat != "1":
self.db.setMythSetting("XBMCClientChainID", mythtv.ourHost, "")
self.db.setMythSetting("XBMCClientStatus", mythtv.ourHost, "0")
self.db.setMythSetting("XBMCClientEncoder", mythtv.ourHost, "-1")
delInstance ( mythtv.Database )
self.db = None
del self.player
self.player = None
self.playing = False
self.loadingRemove()
self.loadPrograms()
def checkConnections( self ):
debug("> Checking Connections")
if not self.db:
self.db = getInstance( mythtv.Database )
if self.db.isConnected == 0:
self.db.initialise()
if self.db.isConnected == 0:
Dialog().ok( mythtvutil.getLocalizedString( 27 ), "Database Connection Failed.","XBMCMythTV is Unable to Continue" )
self.close()
if not self.conn:
self.conn = getInstance( mythtv.Connection )
if self.conn.isConnected == 0:
self.conn.initialise()
if self.conn.isConnected == 0:
Dialog().ok( mythtvutil.getLocalizedString( 27 ), "MythTV Server Connection Failed.","XBMCMythTV is Unable to Continue" )
self.close()
debug("< Checking Connections")
def loadPrograms( self ):
debug( '> mythtvlivetv.Window.loadPrograms()' )
self.schedules = []
self.checkConnections()
if self.channels == None:
self.channels = self.db.getChannelList()
self.channels.sort( compareChannelAsc )
now = datetime.datetime.now()
end = now
xbmcgui.lock()
try:
self.programs = self.db.getProgramListings( now, end )
self.programs = self.fixProgramList()
cnt = 0
# don't need to actually UPDATE the list when we are playing TV
if not self.playing:
channelListControl = self.controls["show_list"].control
channelListControl.reset()
for p in self.programs:
if p != None:
channelListControl.addItem(
p.callsign() + " - " + p.fullTitle() )
else:
channelListControl.addItem(
self.channels[cnt].callsign() + " - No Programs Found" )
cnt += 1
channelListControl.selectItem( self.curChannel )
self.updateShowDetails( self.curChannel )
xbmcgui.unlock()
except:
xbmcgui.unlock()
raise
debug( '< mythtvlivetv.Window.loadPrograms()' )
def containsChannel( self, progs, chan ):
for p in progs:
if p != None:
if p.chanid() == chan.chanid():
return True
return False
def fixProgramList( self ):
# return an array holding real program information including missing channels
debug ( '>mythtvlivetv.Windows.fixProgramList()' )
newProgs = []
for chan in self.channels:
foundProg = False
for p in self.programs:
if self.containsChannel( newProgs, chan):
foundProg = True
else:
if p.chanid() == chan.chanid():
newProgs.append(p)
foundProg = True
if not foundProg:
newProgs.append(None)
debug ( '<mythtvlivetv.Windows.fixProgramList()' )
return newProgs
def updateShowDetails( self, pos ):
if pos < len( self.programs ):
show = self.programs[pos]
self.populateShowDetails(show)
def loadingRemove(self):
self.isLoading = False
self.hidegroup("popup")
def showIconImg( self, img, path="" ):
c = self.controls['popup_icon'].control
self.removeControl( c )
del c
x = int(self.getvalue( self.getoption( "popup_channel_x" ) ) )
y = int(self.getvalue( self.getoption( "popup_channel_y" ) ) )
w = int(self.getvalue( self.getoption( "popup_channel_w" ) ) )
h = int(self.getvalue( self.getoption( "popup_channel_h" ) ) )
texture = img
tx = mythtvutil.findMediaFile( texture )
if tx == None:
tx = path + texture
c = xbmcgui.ControlImage( x, y, w, h, tx )
self.addControl( c )
self.controls['popup_icon'].control = c
def loadingShow(self, isTuning):
# self.loadingRemove()
self.group = "main"
self.showgroup("popup", False)
# populate title
self.isLoading = True
prog = self.programs[int(self.curChannel)]
if prog != None:
theShowName = self.programs[int(self.curChannel)].fullTitle()
theChanID = self.programs[int(self.curChannel)].chanstr()
theChanName = self.programs[int(self.curChannel)].callsign()
else:
theShowName = "No Program Details Available"
theChanID = self.channels[int(self.curChannel)].channum()
theChanName = self.channels[int(self.curChannel)].callsign()
if isTuning:
if self.recordedFormat == "1":
chanTxt = "Recording " + str(theChanName) + " Please Wait..."
else:
chanTxt = "Tuning " + str(theChanName) + " Please Wait..."
else:
if self.recordedFormat == "1":
chanTxt = "Stopping " + str(theChanName) + " Please Wait..."
else:
chanTxt = "Closing " + str(theChanName) + " Please Wait..."
theShowName = ""
self.controls['popup_title'].control.setLabel( str(theChanName) )
self.controls['popup_line_a'].control.reset()
self.controls['popup_line_a'].control.addLabel( chanTxt )
self.controls['popup_line_b'].control.reset()
self.controls['popup_line_b'].control.addLabel( theShowName )
self.showIconImg( 'channels\\' + str(theChanID) + mythtvgui.picType, mythtvgui.picBase )
def updateLoadLine( self, txt ):
self.controls['popup_line_c'].control.reset()
self.controls['popup_line_c'].control.addLabel( txt )
def populateShowDetails(self, show):
# Remove the loading image just incase it hasn't already been removed
# self.loadingRemove()
fullTitle = ""
airDate = ""
channel = ""
origAir = ""
desc = ""
if show != None:
fullTitle = show.fullTitle()
airDate = show.formattedAirDate()
channel = show.formattedChannel()
origAir = show.formattedOrigAirDate()
desc = show.formattedDescription()
else:
fullTitle = "Unavailable"
airDate = ""
channel = "%s %s" % (self.channels[int(self.curChannel)].channum(), self.channels[int(self.curChannel)].callsign())
origAir = ""
desc = "Program Information is Unavailable for this Channel"
# populate title
self.controls['show_title'].control.reset()
self.controls['show_title'].control.addLabel( fullTitle )
debug( "show_title=[%s]"%fullTitle )
# populate air datea
self.controls['show_air_date'].control.setLabel( airDate )
debug( "show_air_date=[%s]"%airDate)
# populate channel
self.controls['show_channel'].control.setLabel( channel )
debug( "show_channel=[%s]"%channel )
# populate orig air
self.controls['show_orig_air'].control.setLabel( origAir )
debug( "show_orig_air=[%s]"%origAir )
# populate description
self.controls['show_descr'].control.reset()
self.controls['show_descr'].control.addLabel( desc )
debug( "show_descr=[%s]"%desc )
def onActionHook( self, action ):
debug( "> mythtvlivetv.Window.onActionHook( action=[%s] )"%action )
self.focusControl = self.getFocus()
if action == mythtvgui.ACTION_PREVIOUS_MENU:
try:
getInstance( mythtv.Settings ).saveSettings()
except:
pass
debug( "< mythtvlivetv.Window.onActionHook()" )
return 0
def onActionPostHook( self, action ):
debug( "> mythtvlivetv.Window.onActionPostHook( action=[%s] )"%action )
# check if the action was to move up or down
if action == mythtvgui.ACTION_MOVE_UP or \
action == mythtvgui.ACTION_MOVE_DOWN or \
action == mythtvgui.ACTION_SCROLL_UP or \
action == mythtvgui.ACTION_SCROLL_DOWN:
# check if the control in focus is the show list
id = self.getcontrolid( self.focusControl )
if id == "show_list":
self.curChannel = self.focusControl.getSelectedPosition()
# give gui time to update
time.sleep( 0.10 )
# get selected show and populate details
self.updateShowDetails( self.focusControl.getSelectedPosition() )
debug( "< mythtvlivetv.Window.onActionPostHook()" )
def playTV(self, chanid):
debug( '> LiveTVPlayer.play, ChanID [%s]' % chanid )
try:
useDVDPlayer = getInstance( mythtv.Settings ).getSetting( "mythtv_liveplayer" )
if useDVDPlayer == "1":
self.updateLoadLine("Trying to use DVDPlayer for Playback...")
try:
debug("Trying to use DVDPlayer for LiveTV Playback")
self.player = xbmc.Player(xbmc.PLAYER_CORE_DVDPLAYER)
self.updateLoadLine("Trying to use DVDPlayer for Playback...Success")
except:
self.player = xbmc.Player()
self.updateLoadLine("Trying to use DVDPlayer for Playback...Failed")
else:
self.updateLoadLine("Using MPlayer for Playback")
self.player = xbmc.Player()
if not self.conn:
self.conn = getInstance( mythtv.Connection )
if not self.db:
self.db = getInstance( mythtv.Database )
if self.player.isPlaying() and len( self.ringBufferName ) > 0:
# flag to indicate script is stopping playback
self.stopping = True
self.player.stop()
else:
self.stopping = False
s = getInstance( mythtv.Settings )
if int(mythtv.mythProtocolVersion) >= 26:
self.filePrefix = s.getSetting("paths_recordedprefix")
else:
self.filePrefix = s.getSetting("paths_livetvprefix")
#--------------------------------------------------------------------------
# this would assume each backend shares the same directories!
# Do people normally setup multiple backends using NFS for record dir?
# host = self.db.getCaptureCardHost( self.curEncoder )
#--------------------------------------------------------------------------
host = s.getSetting( "mythtv_host" )
#--------------------------------------------------------------------------
# would like to replace 'recordedprefix' with just 'recorded share name'
# ie 'myth' instead of 'smb:\\%h\myth' then have to deal with substitution!
# but that would mean ALL settings files will be wrong. Maybe add NEW setting
# and remove old?
#--------------------------------------------------------------------------
if self.recordedFormat == "1":
self.doLiveRecord( chanid )
else:
self.doLiveRingBuffer( chanid )
self.cleanupPlayer()
except Exception, ex:
xbmcgui.unlock()
traceback.print_exc()
self.cleanupPlayer()
debug ( str( ex ) )
return 0
debug( '< LiveTV.play' )
return 1
def doLiveRingBuffer( self, chanid ):
isOn = False
changeChannel = True
lastChainPos = -1
# replace occurances of %h in filePrefix with host
self.filePrefix = sre.sub( '\%h', host, self.filePrefix )
self.filePrefix = string.replace( self.filePrefix, '\\', '/' )
## SET 'STATUS' TO 1 - STARTING LIVE TV
## This will change to 11 if we find this channel with an encoder already watching it!
self.db.setMythSetting("XBMCClientStatus", mythtv.ourHost, "1")
if not self.conn.liveEnabled:
self.updateLoadLine("Initializing Request for LiveTV")
buffDetails = self.conn.liveRequest( chanid )
self.ringBufferName = buffDetails[0]
isOn = buffDetails[1]
changeChannel = buffDetails[2]
self.curEncoder = buffDetails[3]
if buffDetails[0] == None and buffDetails[1] == None:
self.updateLoadLine("*** ERROR: No Encoder Available for Playback ***")
self.cleanupPlayer()
return 0
if changeChannel and int(mythtv.mythProtocolVersion) < 26:
self.updateLoadLine("Changing Channel...")
self.ringBufferName = self.conn.changeLiveTV(chanid)
self.updateLoadLine("Changing Channel...Success...")
self.tvplaylist.clear()
if int(mythtv.mythProtocolVersion) >= 26:
# create playlist with all valid tvchains
for fp in self.ringBufferName:
fullpath = self.filePrefix + "/" + fp["recorded.basename"]
self.tvplaylist.add(fullpath)
self.updateLoadLine("Added %s to Playlist" % fp["recorded.basename"])
debug ( "ADDED FILE: %s" % str(fullpath) )
self.lastFile = fullpath
self.lastChainPos = fp["tvchain.chainpos"]
lastChannel = fp["tvchain.channame"]
debug ("Current Channel %s Wanted %s" % ( str(lastChannel), str(chanid) ) )
if ( str(lastChannel) != str(chanid) ):
debug ( "Cleared Playlist - Wrong Channel" )
self.tvplaylist.clear()
self.lastFile = ""
self.updateLoadLine( "Changing Channel" )
debug ( "Changing Channel" )
self.ringBufferName = self.conn.changeLiveTV(chanid)
for fp in self.ringBufferName:
fullpath = self.filePrefix + "/" + fp["recorded.basename"]
self.tvplaylist.add(fullpath)
self.updateLoadLine("Added %s to Playlist" % fp["recorded.basename"])
debug ( "ADDED FILE: %s" % str(fullpath) )
self.lastFile = fullpath
self.lastChainPos = fp["tvchain.chainpos"]
else:
fullpath = self.filePrefix + "/" + self.ringBufferName
self.tvplaylist.add( fullpath )
self.lastFile = fullpath
debug( 'fullpath=[%s]' % fullpath )
## CHANGE STATUS TO 2 - WATCHING LIVE TV
self.db.setMythSetting("XBMCClientStatus", mythtv.ourHost, "2")
try:
playSize = len(self.tvplaylist)
except:
playSize = self.tvplaylist.size()
if self.lastFile != "":
debug("*** TRYING TO PLAY %s***" % str(self.lastFile))
self.player.play( self.tvplaylist )
else:
Dialog().ok( "Error", "No Valid files found to playback!" )
self.cleanupPlayer()
return 0
if int(mythtv.mythProtocolVersion) >= 26:
pass
self.hidegroup("popup")
self.playing = True
debug("--- Starting wait for new tvchains ---")
while self.player.isPlaying():
self.checkPlayInfo()
def doLiveRecord( self, chanid ):
# when using recordedFormat it will create a new 'recording' in the 'LiveTV' group which will be a
# manual recording for the period of 'recordedLength'
# when livetv is 'stopped' will get option to continue recording, which will store the current
# position to database, or to cancel recording which will delete the show
# ------------------------
# need to be able to set start a new manual recording, starting now on this channel
recordedLength = int(getInstance( mythtv.Settings ).getSetting( "mythtv_recordlength" ))
realChanId = self.db.getChanID(chanid)
# get all current schedules for this channel, covering the current time
endTimeDate = ( datetime.datetime.now() + (datetime.timedelta(minutes=2))).strftime("%Y-%m-%d %H:%M:00")
self.schedules = self.db.getCurrentSchedule( chanid, endTimeDate )
schedule = None
curRecording = False
recid = None
curTime = None
allowDelete = True
self.tvplaylist.clear()
# Check if there is already a schedule for this channel covering the time
# If there is then just load that schedule
if len(self.schedules) >= 1:
curRecording = True
schedule = self.schedules[0]
if schedule != None:
debug("schedule [%s]"%schedule)
recid = schedule.recordid()
debug("recid = %s"%recid)
s = self.db.getSchedule("",int(recid))
if len(s) == 0:
s = self.db.getSchedule(realChanId)
if len(s) >= 1:
sched = s[0]
if ( sched.category() == "Manual recording" ) and ( sched.recgroup() == "LiveTV"):
self.updateLoadLine("Playing Existing Recording")
debug ("MANUAL RECORDING")
allowDelete = True
else:
self.updateLoadLine("Playing Scheduled Recording")
debug ("SCHEDULED RECORDING")
allowDelete = False
endDate = sched.enddate()
endTime = sched.endtime()
else:
allowDelete = False
return
curTime = float(self.db.getMythSetting("XBMCSeek%s"%schedule.basename()))
debug("GOING TO PLAY EXISTING SCHEDULE %s on %s. STARTING FROM %s ENDS %s %s"%(schedule.basename(),schedule.hostname(), str(curTime), endDate,endTime))
# replace occurances of %h in filePrefix with host
self.tvplaylist.add(schedule.remotePath())
# Else create a new schedule if one doesn't already exist for this channel
else:
chanName = self.db.getChanCallsign(chanid)
endTime = ( datetime.datetime.now() + (datetime.timedelta(minutes=recordedLength))).strftime("%Y-%m-%d %H:%M:00")
# get any schedules
debug("Checking other recordings")
othSchedules = self.db.getCurrentSchedule(chanid, endTime)
if len(othSchedules) >= 1:
endTime = othSchedules[0].endtime()
endDate = othSchedules[0].enddate()
if othScedules[0].category() != "Manual recording":
debug ("SCHEDULED RECORDING ENDS %s %s"%(endDate,endTime))
allowDelete = False
else:
debug ("MANUAL RECORDING ENDS %s %s"%(endDate,endTime))
allowDelete = True
curTime = int(self.db.getMythSetting("XBMCSeek%s"%othSchedule[0].basename()))
else:
endTime = ( datetime.datetime.now() + (datetime.timedelta(minutes=recordedLength))).strftime("%H:%M:00")
endDate = ( datetime.datetime.now() + (datetime.timedelta(minutes=recordedLength))).strftime("%Y-%m-%d")
debug("No other schedules for this channel - Current one ends %s %s"%(endDate,endTime))
# endTime = ( datetime.datetime.now() + (datetime.timedelta(hours=recordedLength))).strftime("%H:%M:%S")
# endDate = ( datetime.datetime.now() + (datetime.timedelta(hours=recordedLength))).strftime("%Y-%m-%d")
# Create the schedule
startTime = time.strftime("%H:%M:00", time.localtime())
startDate = time.strftime("%Y-%m-%d", time.localtime())
self.updateLoadLine("Creating new Schedule")
s = mythtvstruct.ScheduleFromQuery( dict(
{ 'recordid' : None, 'type' : 1,
'chanid' : realChanId, 'starttime' : startTime,
'startdate' : startDate, 'endtime' : endTime,
'enddate' : endDate , 'title' : 'LiveTV ' + str(chanName),
'subtitle' : time.strftime("%m-%d %H:%M", time.localtime()),
'description' : 'XBMCMythTV LiveTV Recording',
'category' : 'Manual recording', 'profile' : 'Default',
'recpriority' : 0, 'autoexpire' : 1,
'maxepisodes' : 0, 'maxnewest' : 0,
'startoffset' : 2, 'endoffset' : 0,
'recgroup' : 'LiveTV', 'dupmethod' : 6,
'dupin' : 15, 'station' : chanName,
'seriesid' : '', 'programid' : '',
'search' : 5, 'autotranscode' : 0,
'autocommflag' : 0, 'autouserjob1' : 0,
'autouserjob2' : 0, 'autouserjob3' : 0,
'autouserjob4' : 0, 'findday' : time.strftime("%w", time.localtime()),
'findtime' : time.strftime("%H:%M:%S", time.localtime()),
'findid' : (time.time()/60/60/24) + 719528,
'inactive' : 0, 'parentid' : 0
} ) )
# save it
recid = self.db.saveSchedule( s )
# tell the backend about it
self.conn.rescheduleNotify( s )
sched = s
# give myth a chance to start the recording
sleepTime = int(getInstance( mythtv.Settings ).getSetting( "mythtv_tunewait" ))
time.sleep(sleepTime)
# get the schedule created ( so we can get the file & hostname for it )
self.schedules = self.db.getCurrentSchedule(chanid, endDate + " " + endTime)
if len(self.schedules) <= 0:
schedule = None
else:
schedule = self.schedules[0]
if schedule != None:
schedule.data()['recordid'] = recid
s = self.db.getSchedule("",int(recid))
debug("GOING TO PLAY NEW SCHEDULE %s on %s"%(schedule.basename(),schedule.hostname()))
# wait for the file to get big enough to play ( bigger than XBMC Cache )
self.db.waitForBigFile(schedule.basename())
self.tvplaylist.add(schedule.remotePath())
else:
# we should probably die at this point!
debug("Our Schedule Wasn't found...")
return
# encID = self.conn.getEncoder(schedule.title())
self.player.play( self.tvplaylist )
self.hidegroup("popup")
if curTime == None or curTime < 0 or curTime >= self.player.getTotalTime():
curTime = self.player.getTotalTime() - 1
debug("Seeking %s" %str(curTime))
self.player.seekTime(curTime)
saveCnt = 0
while self.player.isPlaying():
# can't use player.getTime as seems to give me crap info
# curTime = self.player.getTime()
curTime = curTime + 0.5
saveCnt = saveCnt + 1
if saveCnt == 6:
self.db.setMythSetting("XBMCSeek%s"%schedule.basename(),mythtv.ourHost, str(curTime))
saveCnt = 0
time.sleep( 0.5 )
# Step 3: When player is stopped prompt use to either Continue Recording?
# If Going to continue recording then save the current player position so we can continue from there later
# Or just cancel the recording. Don't delete though as the LiveTV files will be cleared
if allowDelete:
remStr = ""
realEnd = datetime.datetime(*time.strptime(string.replace(endDate,"-","") + string.replace(endTime,":",""),"%Y%m%d%H%M%S")[0:6])
if realEnd < datetime.datetime.now():
remStr = ""
else:
diff = realEnd - datetime.datetime.now()
minDiff = round(diff.seconds / 60,0)
if minDiff < 1:
remStr = "There are %s seconds remaining."%str(minDiff * 100)
else:
if minDiff < 2:
remStr = "There is 1 minute remaining."
else:
remStr = "There are %s minutes remaining."%string.replace(str(minDiff),".0","")
if not self.stopping:
self.stopping = True
if remStr == "":
result = Dialog().yesno("Remove Recording?","Do you want to Remove this LiveTV Recording?",remStr)
else:
result = Dialog().yesno("Stop Recording?","Do you want to Stop this LiveTV Recording?",remStr)
else:
result = True
if result or remStr == "":
self.db.deleteSchedule( sched )
self.conn.rescheduleNotify( sched )
debug("Schedule StartDate: %s StartTime: %s EndDate: %s EndTime: %s"%(sched.startdate(),sched.starttime(),sched.enddate(),sched.endtime()))
# Don't delete the recording just finish the recording
# if encID != -1:
# self.conn.finishRecording( encID )
if result:
program = self.conn.getSingleProgram( sched.chanid(), sched.startdate() + sched.starttime(), sched.enddate() + sched.endtime() )
if program != None:
debug( "Deleting Program [%s][%s]" %(program.title(),sched.title()) )
if program.title() == sched.title():
# self.conn.deleteRecording( program )
self.conn.deleteRecording( program )
# else:
# self.db.setMythSetting("XBMCSeek%s"%schedule.basename(),mythtv.ourHost, str(curTime))
self.db.delMythSetting("XBMCSeek%s"%schedule.basename(),mythtv.ourHost )
def checkPlayInfo( self ):
#debug( '> LiveTV.checkPlayInfo' )
time.sleep( self.loopPause )
# After 'self.programReload' minutes reload the program listings
if self.programReloadCount == 0:
# this is really only used for the future OSD
#self.loadPrograms()
self.programReloadCount = self.programReload * ( 1 / self.loopPause )
else:
self.programReloadCount -= 1
self.checkConflict()
if int(mythtv.mythProtocolVersion) >= 26:
self.checkChains()
#debug( '< LiveTV.checkPlayInfo' )
def checkConflict ( self ):
if self.conflictCheckCount == 0:
debug( '> LiveTV.checkConflict' )
if self.recosd == None:
## Check if there is a pending recording in the next 1 minute
isPending = getInstance( mythtv.Connection ).isPendingRecording( self.curEncoder, 1 )
if isPending != None:
debug ("There is a pending recording...")
self.player.stop()
self.conflictCheckCount = self.conflictCheck * ( 1 / self.loopPause )
debug( '< LiveTV.checkConflict' )
else:
self.conflictCheckCount -= 1
def checkChains( self ):
if self.chainCheckCount == 0:
## Need to check for our tvchains and stick them at the end of the playlist?
newChains = self.db.getChainFiles( mythtv.chainid, None, self.lastChainPos, 1, True )
for fp in newChains:
fullpath = self.filePrefix + "/" + fp["recorded.basename"]
self.tvplaylist.add( fullpath )
## self.player.playnext()
## time.sleep( 1 )
debug ( "ADDED FILE: %s" % str(fullpath) )
self.lastFile = fullpath
self.lastChainPos = fp["tvchain.chainpos"]
self.chainCheckCount = self.chainCheck * ( 1 / self.loopPause )
else:
self.chainCheckCount -= 1
def playSelected(self, control):
debug( "> mythtvlivetv.Window.playSelected()" )
pos = control.getSelectedPosition()
self.curChannel = pos
if pos < len( self.channels ):
self.loadingShow(True)
self.playTV( self.channels[pos].channum() )
debug( "< mythtvlivetv.Window.playSelected()" )
def onControlHook( self, control ):
debug( "> mythtvlivetv.Window.onControlHook()" )
id = self.getcontrolid( control )
debug( "ID: %s" % id )
# if id == "view_by":
# self.viewBySelected()
if id == "show_list":
self.playSelected( control )
elif id == "refresh":
self.loadPrograms()
debug( "< mythtvlivetv.Window.onControlHook()" )
return 1
if __name__ == "__main__":
try:
loadingWin = xbmcgui.DialogProgress()
loadingWin.create("LiveTV","Loading LiveTV","Please Wait...")
mythtvutil.debugSetLevel( mythtvutil.DEBUG_GUI | mythtvutil.DEBUG_MYTH )
# mythtvutil.debugOff()
mythtvutil.initialize()
showWindow(loadingWin)
except Exception, ex:
traceback.print_exc()
Dialog().ok( mythtvutil.getLocalizedString( 27 ), str( ex ) )
|