mythtvlivetv.py :  » Game-2D-3D » XBMC-MythTV » xbmcmythtv » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Game 2D 3D » XBMC MythTV 
XBMC MythTV » xbmcmythtv » mythtvlivetv.py
"""
$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 ) )

www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.