示例#1
0
文件: epg.py 项目: jansaris/AminoPVR
    def _syncEpgIds(self):
        conn = DBConnection()

        # By not including inactive channels, we automatically delete epgIds that
        # are currently not active
        uniqueEpgIds = Channel.getUniqueEpgIdsFromDb(conn, includeRadio=True)

        conn.delayCommit(True)

        # Get epgids from database (contains channels per epg_id and strategy)
        epgIds = EpgId.getAllFromDb(conn, includeRadio=True)
        epgIdsDict = {epgId.epgId: epgId for epgId in epgIds}
        currentEpgIds = epgIdsDict.keys()

        for epgId in epgIds:
            if epgId.epgId not in uniqueEpgIds:
                epgId.deleteFromDb(conn)
                self._logger.info("_syncEpgIds: removing epgId=%s" %
                                  (epgId.epgId))

        newEpgIds = set(uniqueEpgIds).difference(set(currentEpgIds))
        self._logger.info("_syncEpgIds: newEpgIds=%r" % (newEpgIds))

        for newEpgId in newEpgIds:
            epgId = EpgId(newEpgId, "none")
            epgId.addToDb(conn)
            self._logger.info("_syncEpgIds: adding epgId=%s" % (epgId.epgId))

        conn.delayCommit(False)
示例#2
0
文件: epg.py 项目: jansaris/AminoPVR
    def _syncEpgIds( self ):
        conn = DBConnection()

        # By not including inactive channels, we automatically delete epgIds that
        # are currently not active
        uniqueEpgIds = Channel.getUniqueEpgIdsFromDb( conn, includeRadio=True )

        conn.delayCommit( True )

        # Get epgids from database (contains channels per epg_id and strategy)
        epgIds        = EpgId.getAllFromDb( conn, includeRadio=True )
        epgIdsDict    = { epgId.epgId: epgId for epgId in epgIds }
        currentEpgIds = epgIdsDict.keys()

        for epgId in epgIds:
            if epgId.epgId not in uniqueEpgIds:
                epgId.deleteFromDb( conn )
                self._logger.info( "_syncEpgIds: removing epgId=%s" % ( epgId.epgId ) )

        newEpgIds = set( uniqueEpgIds ).difference( set( currentEpgIds ) )
        self._logger.info( "_syncEpgIds: newEpgIds=%r" % ( newEpgIds ) )

        for newEpgId in newEpgIds:
            epgId = EpgId( newEpgId, "none" )
            epgId.addToDb( conn )
            self._logger.info( "_syncEpgIds: adding epgId=%s" % ( epgId.epgId ) )

        conn.delayCommit( False )
示例#3
0
    def setChannelList( self, channelList ):
        self._logger.debug( "setChannelList( %s )" % ( channelList ) )

        try:
            channels = json.loads( channelList )
            conn     = DBConnection()

            conn.delayCommit( True )

            newChannelNumbers = []

            for channel in channels:
                channelId  = -1
                channelOld = PendingChannel.getByNumberFromDb( conn, channel["id"] )
                if channelOld:
                    channelId = channelOld.id
                channelNew = self._getChannelFromJson( channel, channelId )
                newChannelNumbers.append( channelNew.number )
                self._logger.debug( "setChannelList: processing channel: %s" % ( channelNew.dump() ) )
                if not channelNew:
                    self._logger.error( "setChannelList: unable to create channel for channel=%s", ( channel ) )
                elif not channelOld:
                    self._logger.info( "setChannelList: adding channel: %i - %s" % ( channelNew.number, channelNew.name ) )
                    channelNew.addToDb( conn )
                elif channelOld != channelNew:
                    self._logger.info( "setChannelList: updating channel: %i - %s" % ( channelNew.number, channelNew.name ) )
                    channelNew.addToDb( conn )
                else:
                    self._logger.debug( "setChannelList: same channel: %i - %s" % ( channelNew.number, channelNew.name ) )

            currentChannels       = PendingChannel.getAllFromDb( conn, includeRadio=True, tv=True )
            currentChannelNumbers = [ channel.number for channel in currentChannels ]
            removedChannelNumbers = set( currentChannelNumbers ).difference( set( newChannelNumbers ) )

            for number in removedChannelNumbers:
                channel = PendingChannel.getByNumberFromDb( conn, number )
                if channel:
                    self._logger.info( "setChannelList: remove channel: %i - %s" % ( channel.number, channel.name ) )
                    channel.deleteFromDb( conn )

            return self._createResponse( API.STATUS_SUCCESS, { "numChannels": len( channels ) } )
        except:
            self._logger.exception( "setChannelList: exception: channelList=%s" % ( channelList ) )

        return self._createResponse( API.STATUS_FAIL, { "numChannels": 0 } )
示例#4
0
                        if len(currChannels) > 0:
                            logger.warning(
                                "Channels found, but no Url match for chanId=%i, epgId=%s"
                                % (mythTvChannel.chanId, epgId))
                            mythTvChannelMap[
                                mythTvChannel.chanId] = currChannels[0]
                            mythTvChannelUrlTypeMap[
                                mythTvChannel.chanId] = "sd"
                            for channel in currChannels:
                                logger.info("Channel: %s" % (channel.dump()))
                        else:
                            logger.warning(
                                "No channels found for chanId=%i, epgId=%s" %
                                (mythTvChannel.chanId, epgId))

                conn.delayCommit(True)

                # Convert MythTV records (schedule entries) to AminoPVR schedules
                for record in mythTvRecords:
                    # If the channel is not in the channel map (yet), it does not exist
                    # in the AminoPVR database.
                    # If there is enough information on MythTV side, create an inactive
                    # channel.
                    if record.chanId != 0 and record.chanId not in mythTvChannelMap:
                        channel, urlType = _addChannel(record.chanId,
                                                       mythTvChannelsDict,
                                                       mythTvIptvChannelsDict,
                                                       dryRun)
                        if channel:
                            logger.warning("Adding Channel: %s" %
                                           (channel.dump()))
示例#5
0
文件: epg.py 项目: jansaris/AminoPVR
    def _grabEpgForChannel( self, channel=None, epgId=None ):
        conn = DBConnection()

        if channel:
            epgId = EpgId.getFromDb( conn, channel.epgId )
            self._logger.info( "Grabbing EPG for channel: %s (%s; method: %s)" % ( channel.name, channel.epgId, epgId.strategy ) )
        if not epgId:
            return
        else:
            self._logger.info( "Grabbing EPG for epgId: %s (method: %s)" % ( epgId.epgId, epgId.strategy ) )

        # Check if _fail_# is behind strategy
        # This is to indicate epg grabbing for this epgId failed previously
        strategy   = epgId.strategy
        strategyRe = re.compile( r'_fail_(?P<fail>\d+)' )
        failMatch  = strategyRe.search( strategy )
        failCount  = 0
        if failMatch:
            failCount = int( failMatch.group( "fail" ) )
            strategy  = epgId.strategy.split( '_' )[0]

        # We're going to attempt to grab EPG information for this channel 5 times
        # before we stop grabbing this epgId in the future.
        if failCount < 5:
            now             = time.localtime()
            nowDay          = datetime.datetime( now[0], now[1], now[2] )
            daysDetailDelta = datetime.timedelta( days = 3 )

            epgFilename = "/%s.json.gz" % ( epgId.epgId )
            epgUrl      = self._glashartConfig.epgChannelsPath + epgFilename

            currentPrograms     = EpgProgram.getAllByEpgIdFromDb( conn, epgId.epgId )
            currentProgramsDict = { currProgram.originalId: currProgram for currProgram in currentPrograms }
            newProgramsDict     = {}

            content, _, _ = getPage( epgUrl )

            if content:
                fileHandle = gzip.GzipFile( fileobj=StringIO( content ) )
                epgData    = json.loads( fileHandle.read() )

                # If strategy has changed (working after (a few) failed attempts)
                if epgId.strategy != strategy:
                    epgId.strategy = strategy
                    epgId.addToDb( conn )

                numPrograms             = 0
                numProgramsDetail       = 0
                numProgramsDetailFailed = 0
                numProgramsNew          = 0
                numProgramsUpdated      = 0

                for program in epgData:
                    if not self._running:
                        break

                    numPrograms += 1

                    programNew = self._getProgramFromJson( epgId.epgId, program )
                    if programNew.originalId in newProgramsDict:
                        self._logger.warning( "Program with originalId %d already in newProgramsDict" % ( programNew.originalId ) )
                    newProgramsDict[programNew.originalId] = programNew

                    updateDetailedData = True

                    programOld = None
                    if programNew.originalId in currentProgramsDict:
                        programOld = currentProgramsDict[programNew.originalId]

                    # If the old program has detailed info, copy those fields
                    # TODO: do this somewhere else
                    if programOld and programOld.detailed:
                        programNew.subtitle       = programOld.subtitle
                        programNew.description    = programOld.description
                        programNew.aspectRatio    = programOld.aspectRatio
                        programNew.parentalRating = programOld.parentalRating
                        programNew.genres         = programOld.genres
                        programNew.actors         = programOld.actors
                        programNew.directors      = programOld.directors
                        programNew.presenters     = programOld.presenters
                        programNew.ratings        = programOld.ratings
                        programNew.detailed       = programOld.detailed

                    # Now, compare the old program and the new program
                    # Are they the same, then we don't need to download detailed information
                    if programOld and programOld.detailed and programNew == programOld:
                        programNew         = programOld
                        updateDetailedData = False

                    if updateDetailedData:

                        if ( ( epgId.strategy == "default" and (nowDay + daysDetailDelta) > datetime.datetime.fromtimestamp( programNew.startTime ) ) or
                             ( epgId.strategy == "full" ) ):

                            time.sleep( random.uniform( 0.5, 1.0 ) )

                            programNew, grabbed = self._grabDetailedEpgForProgram( programNew )
                            if grabbed:
                                numProgramsDetail += 1
                            else:
                                # if more than 10 detailed program information grabs failed, set strategy to none.
                                numProgramsDetailFailed += 1
                                if numProgramsDetailFailed == 10:
                                    self._logger.error( "Couldn't download at least 10 detailed program information files, so setting strategy to 'none', but do not store" )
                                    epgId.strategy = "none"

                conn.delayCommit( True )

                for programId in newProgramsDict:
                    programNew = newProgramsDict[programId]
                    programOld = None
                    if programNew.originalId in currentProgramsDict:
                        programOld = currentProgramsDict[programNew.originalId]

                    if not programOld or programNew != programOld:
                        if programOld:
                            self._logger.debug( "Updated program: id = %s" % ( programNew.originalId ) )
                            self._logger.debug( "Start time: %s > %s" % ( str( programOld.startTime ), str( programNew.startTime ) ) )
                            self._logger.debug( "End time:   %s > %s" % ( str( programOld.endTime ),   str( programNew.endTime ) ) )
                            self._logger.debug( "Name:       %s > %s" % ( repr( programOld.title ),    repr( programNew.title ) ) )
                            programNew.id = programOld.id
                            numProgramsUpdated += 1
                        else:
                            numProgramsNew += 1

                        try:
                            programNew.addToDb( conn )
                        except:
                            self._logger.exception( programNew.dump() )

                conn.delayCommit( False )

                if self._running:
                    self._logger.debug( "Num programs:         %i" % ( numPrograms ) )
                    self._logger.debug( "Num program details:  %i" % ( numProgramsDetail ) )
                    self._logger.info( "Num new programs:     %i" % ( numProgramsNew ) )
                    self._logger.info( "Num updated programs: %i" % ( numProgramsUpdated ) )
                    if numProgramsNew == 0:
                        self._logger.warning( "No new programs were added for epgId: %s" % ( epgId.epgId ) )
            else:
                self._logger.warning( "Unable to download EPG information for epgId: %s" % ( epgId.epgId ) )
                failCount     += 1
                epgId.strategy = "%s_fail_%d" % ( strategy, failCount )
                epgId.addToDb( conn )
        else:
            self._logger.info( "Downloading of EPG information for epgId: %s skipped becaused it failed too many times" % ( epgId.epgId ) )
示例#6
0
文件: epg.py 项目: jansaris/AminoPVR
    def _grabEpgForChannel(self, channel=None, epgId=None):
        conn = DBConnection()

        if channel:
            epgId = EpgId.getFromDb(conn, channel.epgId)
            self._logger.info("Grabbing EPG for channel: %s (%s; method: %s)" %
                              (channel.name, channel.epgId, epgId.strategy))
        if not epgId:
            return
        else:
            self._logger.info("Grabbing EPG for epgId: %s (method: %s)" %
                              (epgId.epgId, epgId.strategy))

        # Check if _fail_# is behind strategy
        # This is to indicate epg grabbing for this epgId failed previously
        strategy = epgId.strategy
        strategyRe = re.compile(r'_fail_(?P<fail>\d+)')
        failMatch = strategyRe.search(strategy)
        failCount = 0
        if failMatch:
            failCount = int(failMatch.group("fail"))
            strategy = epgId.strategy.split('_')[0]

        # We're going to attempt to grab EPG information for this channel 5 times
        # before we stop grabbing this epgId in the future.
        if failCount < 5:
            now = time.localtime()
            nowDay = datetime.datetime(now[0], now[1], now[2])
            daysDetailDelta = datetime.timedelta(days=3)

            epgFilename = "/%s.json.gz" % (epgId.epgId)
            epgUrl = self._glashartConfig.epgChannelsPath + epgFilename

            currentPrograms = EpgProgram.getAllByEpgIdFromDb(conn, epgId.epgId)
            currentProgramsDict = {
                currProgram.originalId: currProgram
                for currProgram in currentPrograms
            }
            newProgramsDict = {}

            content, _, _ = getPage(epgUrl)

            if content:
                fileHandle = gzip.GzipFile(fileobj=StringIO(content))
                epgData = json.loads(fileHandle.read())

                # If strategy has changed (working after (a few) failed attempts)
                if epgId.strategy != strategy:
                    epgId.strategy = strategy
                    epgId.addToDb(conn)

                numPrograms = 0
                numProgramsDetail = 0
                numProgramsDetailFailed = 0
                numProgramsNew = 0
                numProgramsUpdated = 0

                for program in epgData:
                    if not self._running:
                        break

                    numPrograms += 1

                    programNew = self._getProgramFromJson(epgId.epgId, program)
                    if programNew.originalId in newProgramsDict:
                        self._logger.warning(
                            "Program with originalId %d already in newProgramsDict"
                            % (programNew.originalId))
                    newProgramsDict[programNew.originalId] = programNew

                    updateDetailedData = True

                    programOld = None
                    if programNew.originalId in currentProgramsDict:
                        programOld = currentProgramsDict[programNew.originalId]

                    # If the old program has detailed info, copy those fields
                    # TODO: do this somewhere else
                    if programOld and programOld.detailed:
                        programNew.subtitle = programOld.subtitle
                        programNew.description = programOld.description
                        programNew.aspectRatio = programOld.aspectRatio
                        programNew.parentalRating = programOld.parentalRating
                        programNew.genres = programOld.genres
                        programNew.actors = programOld.actors
                        programNew.directors = programOld.directors
                        programNew.presenters = programOld.presenters
                        programNew.ratings = programOld.ratings
                        programNew.detailed = programOld.detailed

                    # Now, compare the old program and the new program
                    # Are they the same, then we don't need to download detailed information
                    if programOld and programOld.detailed and programNew == programOld:
                        programNew = programOld
                        updateDetailedData = False

                    if updateDetailedData:

                        if ((epgId.strategy == "default" and
                             (nowDay + daysDetailDelta) >
                             datetime.datetime.fromtimestamp(
                                 programNew.startTime))
                                or (epgId.strategy == "full")):

                            time.sleep(random.uniform(0.5, 1.0))

                            programNew, grabbed = self._grabDetailedEpgForProgram(
                                programNew)
                            if grabbed:
                                numProgramsDetail += 1
                            else:
                                # if more than 10 detailed program information grabs failed, set strategy to none.
                                numProgramsDetailFailed += 1
                                if numProgramsDetailFailed == 10:
                                    self._logger.error(
                                        "Couldn't download at least 10 detailed program information files, so setting strategy to 'none', but do not store"
                                    )
                                    epgId.strategy = "none"

                conn.delayCommit(True)

                for programId in newProgramsDict:
                    programNew = newProgramsDict[programId]
                    programOld = None
                    if programNew.originalId in currentProgramsDict:
                        programOld = currentProgramsDict[programNew.originalId]

                    if not programOld or programNew != programOld:
                        if programOld:
                            self._logger.debug("Updated program: id = %s" %
                                               (programNew.originalId))
                            self._logger.debug("Start time: %s > %s" %
                                               (str(programOld.startTime),
                                                str(programNew.startTime)))
                            self._logger.debug("End time:   %s > %s" % (str(
                                programOld.endTime), str(programNew.endTime)))
                            self._logger.debug("Name:       %s > %s" % (repr(
                                programOld.title), repr(programNew.title)))
                            programNew.id = programOld.id
                            numProgramsUpdated += 1
                        else:
                            numProgramsNew += 1

                        try:
                            programNew.addToDb(conn)
                        except:
                            self._logger.exception(programNew.dump())

                conn.delayCommit(False)

                if self._running:
                    self._logger.debug("Num programs:         %i" %
                                       (numPrograms))
                    self._logger.debug("Num program details:  %i" %
                                       (numProgramsDetail))
                    self._logger.info("Num new programs:     %i" %
                                      (numProgramsNew))
                    self._logger.info("Num updated programs: %i" %
                                      (numProgramsUpdated))
                    if numProgramsNew == 0:
                        self._logger.warning(
                            "No new programs were added for epgId: %s" %
                            (epgId.epgId))
            else:
                self._logger.warning(
                    "Unable to download EPG information for epgId: %s" %
                    (epgId.epgId))
                failCount += 1
                epgId.strategy = "%s_fail_%d" % (strategy, failCount)
                epgId.addToDb(conn)
        else:
            self._logger.info(
                "Downloading of EPG information for epgId: %s skipped becaused it failed too many times"
                % (epgId.epgId))
示例#7
0
    def setChannelList(self, channelList):
        self._logger.debug("setChannelList( %s )" % (channelList))

        try:
            channels = json.loads(channelList)
            conn = DBConnection()

            conn.delayCommit(True)

            newChannelNumbers = []

            for channel in channels:
                channelId = -1
                channelOld = PendingChannel.getByNumberFromDb(
                    conn, channel["id"])
                if channelOld:
                    channelId = channelOld.id
                channelNew = self._getChannelFromJson(channel, channelId)
                newChannelNumbers.append(channelNew.number)
                self._logger.debug("setChannelList: processing channel: %s" %
                                   (channelNew.dump()))
                if not channelNew:
                    self._logger.error(
                        "setChannelList: unable to create channel for channel=%s",
                        (channel))
                elif not channelOld:
                    self._logger.info(
                        "setChannelList: adding channel: %i - %s" %
                        (channelNew.number, channelNew.name))
                    channelNew.addToDb(conn)
                elif channelOld != channelNew:
                    self._logger.info(
                        "setChannelList: updating channel: %i - %s" %
                        (channelNew.number, channelNew.name))
                    channelNew.addToDb(conn)
                else:
                    self._logger.debug(
                        "setChannelList: same channel: %i - %s" %
                        (channelNew.number, channelNew.name))

            currentChannels = PendingChannel.getAllFromDb(conn,
                                                          includeRadio=True,
                                                          tv=True)
            currentChannelNumbers = [
                channel.number for channel in currentChannels
            ]
            removedChannelNumbers = set(currentChannelNumbers).difference(
                set(newChannelNumbers))

            for number in removedChannelNumbers:
                channel = PendingChannel.getByNumberFromDb(conn, number)
                if channel:
                    self._logger.info(
                        "setChannelList: remove channel: %i - %s" %
                        (channel.number, channel.name))
                    channel.deleteFromDb(conn)

            return self._createResponse(API.STATUS_SUCCESS,
                                        {"numChannels": len(channels)})
        except:
            self._logger.exception(
                "setChannelList: exception: channelList=%s" % (channelList))

        return self._createResponse(API.STATUS_FAIL, {"numChannels": 0})
示例#8
0
    def activatePendingChannels(self):
        self._logger.debug("activatePendingChannels()")
        conn = DBConnection()
        pendingChannels = PendingChannel.getAllFromDb(conn,
                                                      includeInactive=True,
                                                      includeRadio=True,
                                                      tv=True)

        pendingChannelNumbers = [channel.number for channel in pendingChannels]

        conn.delayCommit(True)

        for channel in pendingChannels:
            currChannel = Channel.getByNumberFromDb(conn, channel.number)
            if currChannel and currChannel.epgId != channel.epgId:
                # Found a channel on the same channel number, but epgId is different
                # Find another match.
                self._logger.info(
                    "activatePendingChannels: epgId mismatch for channel %i - %s: %s != %s"
                    % (channel.number, channel.name, channel.epgId,
                       currChannel.epgId))
                # If channel name is the same (or partially the same), then they must have changed epgId
                # Else, try to find a channel that would match
                if (channel.name != currChannel.name)         and \
                   (not channel.name     in currChannel.name) and \
                   (not currChannel.name in channel.name):
                    currChannel = None
                    epgIdChannels = Channel.getAllByEpgIdFromDb(
                        conn,
                        channel.epgId,
                        includeInactive=True,
                        includeRadio=True)
                    for epgIdChannel in epgIdChannels:
                        if (epgIdChannel.name == channel.name)      or \
                           (channel.name      in epgIdChannel.name) or \
                           (epgIdChannel.name in channel.name):
                            currChannel = epgIdChannel
                            break
                # TODO: if still no match is found (based on epgId), then look for similar names
                # and maybe equal urls

            if currChannel:
                # Convert PendingChannel to Channel but keep channel id
                newCurrChannel = Channel.copy(channel, currChannel.id)

                # Keep the scrambled setting from ChannelUrl's currently in the Db.
                # This setting cannot be retrieved from the source
                for key in currChannel.urls.keys():
                    if newCurrChannel.urls.has_key(key):
                        newCurrChannel.urls[key].scrambled = currChannel.urls[
                            key].scrambled

                # Has the channel really changed?
                if newCurrChannel != currChannel:
                    self._logger.info(
                        "activatePendingChannels: existing channel: %i - %s" %
                        (channel.number, channel.name))

                    # Hmm, channel number and name are the same, but epgId is different
                    if newCurrChannel.epgId != currChannel.epgId:
                        self._logger.info(
                            "activatePendingChannels: epgId has changed: %s > %s"
                            % (currChannel.epgId, newCurrChannel.epgId))

                    # Make sure the changed channel is activated (again)
                    newCurrChannel.inactive = False

                    if currChannel.logo != "" and os.path.basename(
                            newCurrChannel.logo) != os.path.basename(
                                currChannel.logo):
                        currChannel.removeLogo(conn)
                    if currChannel.thumbnail != "" and os.path.basename(
                            newCurrChannel.thumbnail) != os.path.basename(
                                currChannel.thumbnail):
                        currChannel.removeThumbnail(conn)

                    # Download the logo and thumbnail for this channel
                    newCurrChannel.downloadLogoAndThumbnail()
                    newCurrChannel.addToDb(conn)
            else:
                self._logger.info(
                    "activatePendingChannels: new channel: %i - %s" %
                    (channel.number, channel.name))
                newChannel = Channel.copy(channel)
                newChannel.downloadLogoAndThumbnail()
                newChannel.addToDb(conn)

        currentChannels = Channel.getAllFromDb(conn,
                                               includeInactive=True,
                                               includeRadio=True,
                                               tv=True)
        currentChannelNumbers = [channel.number for channel in currentChannels]
        removedChannelNumbers = set(currentChannelNumbers).difference(
            set(pendingChannelNumbers))

        self._logger.info(
            "activatePendingChannels: %i, %i, %i" %
            (len(set(currentChannelNumbers)), len(
                set(pendingChannelNumbers)), len(removedChannelNumbers)))
        for number in removedChannelNumbers:
            currChannel = Channel.getByNumberFromDb(conn, number)
            if not currChannel.inactive:
                self._logger.info(
                    "activatePendingChannels: inactive channel: %i - %s" %
                    (currChannel.number, currChannel.name))
                currChannel.inactive = True
                currChannel.addToDb(conn)

        conn.delayCommit(False)

        channels = Channel.getAllFromDb(conn, includeRadio=True, tv=True)
        channelsArray = []

        for channel in channels:
            channelJson = channel.toDict(InputStreamProtocol.HTTP,
                                         includeScrambled=False,
                                         includeHd=True)
            if channelJson:
                channelsArray.append(channelJson)
        return self._createResponse(API.STATUS_SUCCESS, channelsArray)
示例#9
0
                                    mythTvChannelMap[mythTvChannel.chanId]        = channel
                                    mythTvChannelUrlTypeMap[mythTvChannel.chanId] = urlType
                                    break

                    # We didn't find a match
                    if mythTvChannel.chanId not in mythTvChannelMap:
                        if len( currChannels ) > 0:
                            logger.warning( "Channels found, but no Url match for chanId=%i, epgId=%s" % ( mythTvChannel.chanId, epgId ) )
                            mythTvChannelMap[mythTvChannel.chanId]        = currChannels[0]
                            mythTvChannelUrlTypeMap[mythTvChannel.chanId] = "sd"
                            for channel in currChannels:
                                logger.info( "Channel: %s" % ( channel.dump() ) )
                        else:
                            logger.warning( "No channels found for chanId=%i, epgId=%s" % ( mythTvChannel.chanId, epgId ) )

                conn.delayCommit( True )

                # Convert MythTV records (schedule entries) to AminoPVR schedules
                for record in mythTvRecords:
                    # If the channel is not in the channel map (yet), it does not exist
                    # in the AminoPVR database.
                    # If there is enough information on MythTV side, create an inactive
                    # channel.
                    if record.chanId != 0 and record.chanId not in mythTvChannelMap:
                        channel, urlType =_addChannel( record.chanId, mythTvChannelsDict, mythTvIptvChannelsDict, dryRun )
                        if channel:
                            logger.warning( "Adding Channel: %s" % ( channel.dump() ) )
                            if not dryRun:
                                channel.addToDb( conn )
                            mythTvChannelMap[record.chanId]        = channel
                            mythTvChannelUrlTypeMap[record.chanId] = urlType
示例#10
0
    def activatePendingChannels( self ):
        self._logger.debug( "activatePendingChannels()" )
        conn = DBConnection()
        pendingChannels = PendingChannel.getAllFromDb( conn, includeInactive=True, includeRadio=True, tv=True )

        pendingChannelNumbers = [ channel.number for channel in pendingChannels ]

        conn.delayCommit( True )

        for channel in pendingChannels:
            currChannel = Channel.getByNumberFromDb( conn, channel.number )
            if currChannel and currChannel.epgId != channel.epgId:
                # Found a channel on the same channel number, but epgId is different
                # Find another match.
                self._logger.info( "activatePendingChannels: epgId mismatch for channel %i - %s: %s != %s" % ( channel.number, channel.name, channel.epgId, currChannel.epgId ) )
                # If channel name is the same (or partially the same), then they must have changed epgId
                # Else, try to find a channel that would match
                if (channel.name != currChannel.name)         and \
                   (not channel.name     in currChannel.name) and \
                   (not currChannel.name in channel.name):
                    currChannel   = None
                    epgIdChannels = Channel.getAllByEpgIdFromDb( conn, channel.epgId, includeInactive=True, includeRadio=True )
                    for epgIdChannel in epgIdChannels:
                        if (epgIdChannel.name == channel.name)      or \
                           (channel.name      in epgIdChannel.name) or \
                           (epgIdChannel.name in channel.name):
                            currChannel = epgIdChannel
                            break
                # TODO: if still no match is found (based on epgId), then look for similar names
                # and maybe equal urls 

            if currChannel:
                # Convert PendingChannel to Channel but keep channel id
                newCurrChannel = Channel.copy( channel, currChannel.id )

                # Keep the scrambled setting from ChannelUrl's currently in the Db.
                # This setting cannot be retrieved from the source 
                for key in currChannel.urls.keys():
                    if newCurrChannel.urls.has_key( key ):
                        newCurrChannel.urls[key].scrambled = currChannel.urls[key].scrambled

                # Has the channel really changed?
                if newCurrChannel != currChannel:
                    self._logger.info( "activatePendingChannels: existing channel: %i - %s" % ( channel.number, channel.name ) )

                    # Hmm, channel number and name are the same, but epgId is different
                    if newCurrChannel.epgId != currChannel.epgId:
                        self._logger.info( "activatePendingChannels: epgId has changed: %s > %s" % ( currChannel.epgId, newCurrChannel.epgId ) )

                    # Make sure the changed channel is activated (again)
                    newCurrChannel.inactive = False

                    if currChannel.logo != "" and os.path.basename( newCurrChannel.logo ) != os.path.basename( currChannel.logo ):
                        currChannel.removeLogo( conn )
                    if currChannel.thumbnail != "" and os.path.basename( newCurrChannel.thumbnail ) != os.path.basename( currChannel.thumbnail ):
                        currChannel.removeThumbnail( conn )

                    # Download the logo and thumbnail for this channel
                    newCurrChannel.downloadLogoAndThumbnail()
                    newCurrChannel.addToDb( conn )
            else:
                self._logger.info( "activatePendingChannels: new channel: %i - %s" % ( channel.number, channel.name ) )
                newChannel = Channel.copy( channel )
                newChannel.downloadLogoAndThumbnail()
                newChannel.addToDb( conn )

        currentChannels       = Channel.getAllFromDb( conn, includeInactive=True, includeRadio=True, tv=True )
        currentChannelNumbers = [ channel.number for channel in currentChannels ]
        removedChannelNumbers = set( currentChannelNumbers ).difference( set( pendingChannelNumbers ) )

        self._logger.info( "activatePendingChannels: %i, %i, %i" % ( len( set( currentChannelNumbers ) ), len( set( pendingChannelNumbers ) ), len( removedChannelNumbers ) ) )
        for number in removedChannelNumbers:
            currChannel = Channel.getByNumberFromDb( conn, number )
            if not currChannel.inactive:
                self._logger.info( "activatePendingChannels: inactive channel: %i - %s" % ( currChannel.number, currChannel.name ) )
                currChannel.inactive = True
                currChannel.addToDb( conn )

        conn.delayCommit( False )

        channels      = Channel.getAllFromDb( conn, includeRadio=True, tv=True )
        channelsArray = []

        for channel in channels:
            channelJson = channel.toDict( InputStreamProtocol.HTTP, includeScrambled=False, includeHd=True )
            if channelJson:
                channelsArray.append( channelJson )
        return self._createResponse( API.STATUS_SUCCESS, channelsArray )