Exemplo n.º 1
0
    def getNextRefreshTS(self):
        cacheFilePrefix = os.path.basename( Globals().nsCacheFilePrefix )
        cacheFileNameRE = re.compile( r'^' + cacheFilePrefix + '\d+$' )

        fetchTimeList = []
        
        for file in os.listdir( Globals().nsCacheDir ):
            if cacheFileNameRE.match( file ):
                cacheFileName = os.path.join( Globals().nsCacheDir, file )
                # Get data fetch time
                fp = open( cacheFileName, "rb" )
                cacheData = cPickle.load( fp )
                fp.close()
                fetchTimeList.append( cacheData['fetch_time'] )

        # Keep smaller TS
        nextTS = -1
        for ts in fetchTimeList:
            if nextTS == -1:
                nextTS = ts
            else:
                if ts < nextTS:
                    nextTS = ts

        if nextTS == -1:
            return -1
        else:
            return ( nextTS + self.expiration )
Exemplo n.º 2
0
def copyThemeFilesToConfigDir(widget):
    # Copy files
    for file in Globals().nsCGuiFiles:
        source = karamba.readThemeFile(widget, file)
        dest = open(os.path.join(Globals().nsCGuiBaseDir, file), "w")
        tools.msgDebug("Copying file: %s" % file, __name__)
        print >> dest, source
        dest.close()
Exemplo n.º 3
0
 def _releaseLock(self):
     if self.writeFlag:
         tools.msgDebug("Saving config...", __name__)
         # Write back to config file
         fp = open(Globals().nsConfFile, "w")
         self.write(fp)
         fp.close()
         tools.msgDebug("Config saved to %s" % Globals().nsConfFile,
                        __name__)
     # Release LOCK
     Config.LOCK = False
     tools.msgDebug("Config LOCK released", __name__)
Exemplo n.º 4
0
    def __init__(self):
        #### User-Agent we use while doing HTTP requests
        version = Globals().versions
        kernName = os.popen('uname -s').read()[:-1]
        kernRel = os.popen('uname -r').read()[:-1]
        #return "Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.6 (like Gecko)"
        self.userAgent = u"Mozilla/5.0 (compatible; nextShows/%s; %s-%s)" % (
            version['nextShows'], kernName, kernRel)

        #### Set default timeout
        socket.setdefaulttimeout(10)  # 10s
Exemplo n.º 5
0
    def __init__(self):
        SafeConfigParser.__init__(self)

        # LOCK Config() and read configuration file
        self._acquireLock()

        # Write Flag
        # Used to prevent writing back to config file if it was just opened for reading
        self.writeFlag = False

        #### Define default config values
        ### [main]
        ## Default DEBUG Value
        self.debug = False

        ### [gui]
        ## Filter checkbox
        self.filter = True

        ### [shows]
        ## My Shows
        self.myShows = []

        ### [display]
        ## Past days to display
        self.numPastDays = 1
        ## Lines
        self.linesFixed = 10
        self.linesMin = 1
        self.linesMax = 10
        self.linesType = "Fixed"  # Values: Fixed / Auto
        ## Format
        self.format = "$show:12:...$-S$season:2$E$episode:2$-$title$"
        ## Theme
        self.theme = Globals().defaultThemeName
        ## Date
        self.dateFormat = "%%d/%%m/%%y"
        ## Date Separator
        self.dateSeparator = "/"
        ## When format
        self.whenFormat = 0

        ### [colors]
        self.myColors = {}
        self.myColors['default'] = "#111111"
        self.myColors['ranges'] = [(-99, -1, "#771111"), (0, 0, "#117711"),
                                   (1, 1, "#111177")]

        ### [misc]
        self.cacheExpiration = 1
        self.browser = "firefox -remote 'openURL($url$,new-tab)'"

        #### Create necessary dir structure
        self._initConfigStorage()
Exemplo n.º 6
0
    def getCachedEpisodeList(self, id):
        # Cache filename
        cacheFileName = Globals().nsCacheFilePrefix + str( id )
        
        # Get data
        tools.msgDebug("Getting data from cache %s..." % cacheFileName, __name__)
        fp = open( cacheFileName, "rb" )
        data = cPickle.load( fp )
        fp.close()

        # Return episode list
        return data['episode_list']
Exemplo n.º 7
0
    def checkCacheFile(self, id):
        # Cache filename
        cacheFileName = Globals().nsCacheFilePrefix + str( id )

        # Check if a file exists for the given id
        if os.path.isfile( cacheFileName ):
            # Check if data are still valid
            currentTS = int( datetime.utcnow().strftime("%s") )
            # Show filename
            cacheFileName = Globals().nsCacheFilePrefix + str( id )
            # Get data fetch time
            fp = open( cacheFileName, "rb" )
            cacheData = cPickle.load( fp )
            fp.close()
            cacheFileTS = cacheData['fetch_time']

            if ( cacheFileTS + self.expiration ) < currentTS:
                return self.CACHEFILEOUTDATED
        else:
            return self.CACHEFILENOTFOUND

        return self.CACHEFILEOK
Exemplo n.º 8
0
def menuOptionChanged(widget, key, value):
    global g_configGuiPid

    karamba.setMenuConfigOption(widget, "config_gui", 0)

    if key == "config_gui":
        if g_configGuiPid == None:
            # Launch config GUI
            gui = os.path.join(Globals().nsCGuiBaseDir, "launchGUI")
            cmd = ["python", gui]
            g_configGuiPid = karamba.executeInteractive(widget, cmd)
        else:
            tools.msgDebug("GUI already running", __name__)
Exemplo n.º 9
0
    def deleteOldCacheFiles(self):
        tools.msgDebug("Purging cache dir...", __name__)
        cacheDirContents = os.listdir( Globals().nsCacheDir )
        cacheFilePrefix = os.path.basename( Globals().nsCacheFilePrefix )

        for id in self.showIds:
            fileName = cacheFilePrefix + str( id )
            if fileName in cacheDirContents:
                index = cacheDirContents.index( fileName )
                cacheDirContents.pop( index )

        # Remove unwanted files
        exitFlag = True
        for file in cacheDirContents:
            fileName = os.path.join( Globals().nsCacheDir, file )
            try:
                os.remove( fileName )
                tools.msgDebug("Deleted %s..." % fileName, __name__)
            except:
                exitFlag = False
                tools.msgDebug("Error raised while trying to delete %s..." % fileName, __name__)

        return exitFlag
Exemplo n.º 10
0
 def _acquireLock(self):
     # If a LOCK already exist, wait until it is released
     while Config.LOCK:
         tools.msgDebug(
             "Config file LOCKed! Waiting for lock to be released...",
             __name__)
         randomize = float(random.randint(0, 1000)) / 1000
         time.sleep(randomize)
     # Acquire LOCK
     Config.LOCK = True
     tools.msgDebug("Config LOCK acquired", __name__)
     # Read config
     self.read(Globals().nsConfFile)
     tools.msgDebug("Config read", __name__)
Exemplo n.º 11
0
    def _initConfigStorage(self):

        # /!\ Directory tree should be created when the widget launches

        # Create necessary directories
        #        mode = Globals().nsDirMode
        #        dirs = [ Globals().superKarambaDir, Globals().nsConfDir ]

        #        for dir in dirs:
        #            try:
        #                os.mkdir( dir, mode )
        #            except OSError:
        #                pass

        # If no config file is found, create a default one
        if not os.path.isfile(Globals().nsConfFile):
            self._createDefaultConfFile()
Exemplo n.º 12
0
def createConfigDirs():
    # Create dirs
    mode = Globals().nsDirMode
    dirs = [
        Globals().superKarambaDir,
        Globals().nsConfDir,
        Globals().nsCacheDir,
        Globals().nsCGuiBaseDir
    ]
    for dir in Globals().nsCGuiDirs:
        dirs.append(os.path.join(Globals().nsCGuiBaseDir, dir))
    for dir in dirs:
        try:
            os.mkdir(dir, mode)
            tools.msgDebug("Created dir: %s" % dir, __name__)
        except OSError:
            pass
Exemplo n.º 13
0
    def cacheEpisodeList(self, id):
        # Cache filename
        cacheFileName = Globals().nsCacheFilePrefix + str( id )

        # Get the data
        parser = TvRage()
        epList = parser.getEpisodeList( id )

        if not epList:
            return False    # In case something went wrong during parsing...

        showEpList = {}
        showEpList['fetch_time']   = int( datetime.utcnow().strftime("%s") ) # Timestamp (UTC)
        showEpList['episode_list'] = epList

        # Open the file for writing
        tools.msgDebug("Writing cache file %s..." % cacheFileName, __name__)
        fp = open( cacheFileName, "wb" )
        cPickle.dump( showEpList, fp, cPickle.HIGHEST_PROTOCOL )
        fp.close()

        # At this point we suppose everything hopefully went well
        return True
Exemplo n.º 14
0
    def _createDefaultConfFile(self):
        self.writeFlag = True  # Must save the config

        tools.msgDebug(
            "Creating default config file %s" % Globals().nsConfFile, __name__)

        #----------------------------------------------------------------------
        # Create necessary sections
        #sections = ( 'main', 'gui', 'display', 'colors', 'shows', 'misc' )
        sections = ('main', 'display', 'colors', 'shows', 'misc')
        for section in sections:
            self.add_section(section)
        # Main
        self.set("main", "version", "0")
        self.set("main", "debug", str(self.debug))
        # Gui
        #self.set( "gui",     "filter",      str(self.filter)      )
        # Display
        self.set("display", "past_days", str(self.numPastDays))
        self.set("display", "lines_fixed", str(self.linesFixed))
        self.set("display", "lines_min", str(self.linesMin))
        self.set("display", "lines_max", str(self.linesMax))
        self.set("display", "type", str(self.linesType))
        self.set("display", "format", str(self.format))
        self.set("display", "date_format", str(self.dateFormat))
        self.set("display", "date_separator", str(self.dateSeparator))
        # Misc
        self.set("misc", "cache_expiration", str(self.cacheExpiration))
        self.set("misc", "browser", str(self.browser))
        self.set("misc", "when_format", str(self.whenFormat))
        self.set("misc", "theme", str(self.theme))
        #----------------------------------------------------------------------

        # Set shows
        self.setShows(self.myShows)
        # Set color
        self.setColors(self.myColors)
Exemplo n.º 15
0
 def refreshFormatPreview(self, text):
     testFormat = tools.formatEpisode(Globals().sampleEpisode, text)
     self.ui.lblFormatPreview.setText(u"<u><b>Preview:</b></u> %s" %
                                      testFormat)
Exemplo n.º 16
0
    def initForm(self):
        # 1st tab labels
        self.ui.lblResultsDisplayed.setText(u"Displayed results: 0/0")
        self.ui.lblTrackedShows.setText(u"Tracked shows: 0")

        # Format Sample
        fmtSample = u"<u><b>Sample:</b></u> <b>show:</b> %s, <b>title:</b> %s, <b>season</b>: %d, <b>episode</b>: %d" % (
            Globals().sampleEpisode['show'], Globals().sampleEpisode['title'],
            Globals().sampleEpisode['season'],
            Globals().sampleEpisode['episode'])
        self.ui.lblFormatSample.setText(fmtSample)

        #### Versions
        version = Globals().versions
        # nextShows Footer Release
        labelContent = str(self.ui.lblFooterRelease.text())
        self.ui.lblFooterRelease.setText(labelContent % version['nextShows'])
        # nextShows Release (About tab)
        labelContent = str(self.ui.lblNextShowsVersion.text())
        self.ui.lblNextShowsVersion.setText(labelContent %
                                            version['nextShows'])
        # Libs releases (About tab)
        # Python version
        a, b, c, d, e = sys.version_info
        pythonVersion = "%d.%d.%d" % (a, b, c)
        #
        labelContent = str(self.ui.lblLibsVersion.text())
        self.ui.lblLibsVersion.setText(
            labelContent %
            (pythonVersion, QT_VERSION_STR, PYQT_VERSION_STR, version["KDE"]))

        #### Default values
        self.ui.spinNumPastDays.setMinimum(0)
        self.ui.spinNumPastDays.setMaximum(99)
        #self.ui.spinNumPastDays.setValue(1)
        self.ui.spinFixedDispLines.setMinimum(1)
        self.ui.spinFixedDispLines.setMaximum(50)
        #self.ui.spinFixedDispLines.setValue(10)
        self.ui.spinMinDispLines.setMinimum(1)
        self.ui.spinMinDispLines.setMaximum(49)
        #self.ui.spinMinDispLines.setValue(1)
        self.ui.spinMaxDispLines.setMinimum(2)
        self.ui.spinMaxDispLines.setMaximum(50)
        #self.ui.spinMaxDispLines.setValue(10)
        #
        self.ui.spinColorsSingleDay.setMinimum(-99)
        self.ui.spinColorsSingleDay.setMaximum(99)
        self.ui.spinColorsSingleDay.setValue(0)
        self.ui.spinColorsFrom.setMinimum(-99)
        self.ui.spinColorsFrom.setMaximum(98)
        self.ui.spinColorsFrom.setValue(0)
        self.ui.spinColorsTo.setMinimum(-98)
        self.ui.spinColorsTo.setMaximum(99)
        self.ui.spinColorsTo.setValue(10)

        # default color for "Select color"
        self.ui.lblSelectColor.setPixmap(
            self.drawPreviewColor(self.lastColorUsed, 36, 36))

        # Theme combo
        self.ui.comboTheme.addItems(Globals().availableThemes)

        ####
        #### Read config
        ####
        tools.msgDebug(u"Reading config...", __name__)
        config = Config()

        # Enable/Disable DEBUG
        if config.getboolean("main", "debug") == False:
            tools.msgDebug("Disabling debug messages !", __name__)
            Globals.DEBUG = False

        # Get Data
        self.myShows = config.getShows()
        self.displayMyShows()
        self.myColors = config.getColors()
        self.ui.lblDefaultColor.setPixmap(
            self.drawPreviewColor(self.myColors['default'], 36, 36))
        self.displayMyColors()

        if config.get("display", "type") == "Fixed":
            self.ui.radioDispFixedLines.setChecked(True)
        else:
            self.ui.radioDispAutoResize.setChecked(True)

        self.ui.spinNumPastDays.setValue(
            int(config.get("display", "past_days")))
        self.ui.spinFixedDispLines.setValue(
            int(config.get("display", "lines_fixed")))
        self.ui.spinMinDispLines.setValue(
            int(config.get("display", "lines_min")))
        self.ui.spinMaxDispLines.setValue(
            int(config.get("display", "lines_max")))
        self.ui.leditFormat.setText(config.get("display", "format"))
        self.refreshFormatPreview(str(self.ui.leditFormat.text()))

        self.ui.spinCacheExpiration.setValue(
            int(config.get("misc", "cache_expiration")))
        self.ui.leditBrowser.setText(config.get("misc", "browser"))

        # Fallback code since the "theme" key was located in the [display] section
        # in versions < 2.1.0
        try:
            idx = int(Globals().availableThemes.index(
                config.get("misc", "theme")))
        except:
            idx = 0
        self.ui.comboTheme.setCurrentIndex(idx)

        # Date Separator
        # Fallback code since the "date_separator" key doesn't exist in version < 2.1.0
        try:
            sep = config.get("display", "date_separator")
        except:
            sep = "/"
        self.ui.leditDateSeparator.setText(sep)

        # Date Format
        dateFormat = config.get("display", "date_format")
        data = ["%" + a for a in dateFormat.split(sep)]
        idx = self.ui.comboDateFormat.findData(QVariant(data))
        if idx == -1: idx = 0
        self.ui.comboDateFormat.setCurrentIndex(idx)

        config.close()

        # Reset "Save" button state
        self.saveRequired(False)

        tools.msgDebug(u"Done!", __name__)
Exemplo n.º 17
0
    def _readThemeInfos(self, theme):
        self.themeName = theme
        self.themePath = os.path.join("themes", self.themeName)
        themeInfo = os.path.join(self.themePath, "theme.info")
        themeInfoContent = karamba.readThemeFile(Applet.widget, themeInfo)

        if themeInfoContent == "":
            tools.msgDebug("Error finding/reading %s..." % themeInfo, __name__)
            # Try to fallback to the default theme
            self.themeName = Globals().defaultThemeName
            self.themePath = os.path.join("themes", self.themeName)
            themeInfo = os.path.join(self.themePath, "theme.info")
            themeInfoContent = karamba.readThemeFile(Applet.widget, themeInfo)
            if themeInfoContent == "":
                tools.msgDebug("Error finding/reading %s..." % themeInfo,
                               __name__)
                return False

        #######################################################################
        # FIXME: Unfortunately, it is not possible to directly feed ConfigParser
        # with a str()....
        # Yep! That's another ugly hack!
        #######################################################################
        tempName = os.tempnam()
        fp = open(tempName, "w")
        fp.write(themeInfoContent)
        fp.close()
        fp = open(tempName, "r")
        scp = SafeConfigParser()
        scp.readfp(fp)
        fp.close()
        os.unlink(tempName)
        #######################################################################

        self.themeHeaderImg = os.path.join(self.themePath,
                                           scp.get("images", "header"))
        self.themeHeaderTxtTitle = scp.get("header", "title_text")
        X = scp.getint("header", "title_pos_x")
        Y = scp.getint("header", "title_pos_y")
        self.themeHeaderTxtTitleXY = (X, Y)
        W = scp.getint("header", "title_width")
        H = 0
        self.themeHeaderTxtTitleWH = (W, H)
        self.themeHeaderTxtWhen = scp.get("header", "when_text")
        X = scp.getint("header", "when_pos_x")
        Y = scp.getint("header", "when_pos_y")
        self.themeHeaderTxtWhenXY = (X, Y)
        W = scp.getint("header", "when_width")
        H = 0
        self.themeHeaderTxtWhenWH = (W, H)
        self.themeBodyImg = os.path.join(self.themePath,
                                         scp.get("images", "body"))
        X = scp.getint("body", "title_pos_x")
        Y = scp.getint("body", "title_pos_y")
        self.themeBodyTitleXY = (X, Y)
        W = scp.getint("body", "title_width")
        H = scp.getint("body", "title_height")
        self.themeBodyTitleWH = (W, H)
        X = scp.getint("body", "when_pos_x")
        Y = scp.getint("body", "when_pos_y")
        self.themeBodyWhenXY = (X, Y)
        W = scp.getint("body", "when_width")
        H = scp.getint("body", "when_height")
        self.themeBodyWhenWH = (W, H)
        self.themeFooterImg = os.path.join(self.themePath,
                                           scp.get("images", "footer"))
Exemplo n.º 18
0
def initWidget(widget):
    global g_nextCacheRefresh, g_showList, g_showIds, g_cacheExpiration, g_pastDays, g_linesMin, g_linesMax

    # Pass the widget reference
    Applet.widget = widget

    # Init splash
    splash = Applet().Splash()
    splash.show()

    # Create dir structure
    splash.setText("Checking config dirs...")
    createConfigDirs()

    # Read config
    splash.setText("Reading config...")
    config = Config()

    # Check whether we want DEBUG messages enabled or not
    if config.getboolean("main", "debug") == False:
        tools.msgDebug("Disabling debug messages !", __name__)
        Globals.DEBUG = False

    # Copy GUI files (if necessary)
    if Globals().versions['nextShows'] != config.get("main", "version") \
    or not "launchGUI" in os.listdir( Globals().nsCGuiBaseDir ):
        # Init dir structures and copy files
        splash.setText("Setup GUI...")
        copyThemeFilesToConfigDir(widget)
        config.set("main", "version", Globals().versions['nextShows'])

    # Get other useful infos from config
    splash.setText("Reading config...")
    displayType = config.get("display", "type")
    if displayType == "Fixed":
        g_linesMax = config.getint("display", "lines_fixed")
        g_linesMin = g_linesMax
    else:
        g_linesMin = config.getint("display", "lines_min")
        g_linesMax = config.getint("display", "lines_max")
    g_cacheExpiration = config.getint("misc", "cache_expiration")
    g_pastDays = config.getint("display", "past_days")
    applet.colorList = config.getColors()
    applet.episodeFormatString = config.get("display", "format")
    applet.browser = config.get("misc", "browser")
    applet.dateFormat = config.get("display", "date_format")
    applet.whenFormat = config.getint("misc", "when_format")

    # Getting the show list
    splash.setText("Getting show list....")
    g_showList = config.getShows()

    # Extract IDs
    g_showIds = [show['id'] for show in g_showList]

    # Init cache
    cache.setExpiration(g_cacheExpiration)
    cache.showIds = g_showIds

    # Refresh cache if necessary
    staledList = cache.getStaledCacheFiles()
    for id in staledList:
        for show in g_showList:
            if show['id'] == id:
                showName = show['name']
        splash.setText("Updating cache: '%s'..." % showName)
        cache.cacheEpisodeList(id)

    # Fetch data to display
    splash.setText("Filtering episodes...")
    data = Data()
    episodeList = data.getEpisodeList(g_showIds, g_pastDays, g_linesMax)
    applet.episodeList = episodeList

    # Close the splash
    splash.setText("Done!")
    splash.hide()

    # Init widget
    # Fallback (for compatibility reasons)
    # "[display] theme=" was moved to "[misc] theme="
    try:
        applet.themeName = config.get("misc", "theme")
    except:
        applet.themeName = Globals().defaultThemeName
    numReturnedEpisode = len(episodeList)
    if numReturnedEpisode < g_linesMin:
        themeLines = g_linesMin
    elif numReturnedEpisode > g_linesMax:
        themeLines = g_linesMax
    else:
        themeLines = numReturnedEpisode
    applet.themeLines = themeLines
    applet.drawBackground()
    applet.printEpisodeList()

    # Store next cache refresh
    g_nextCacheRefresh = cache.getNextRefreshTS()

    # Setup menu entry for config GUI
    karamba.addMenuConfigOption(widget, "config_gui", "Configure...")
    karamba.setMenuConfigOption(widget, "config_gui", 0)