def __runtask__(self, t): lockname = "Framework.Parallel." + self.tasksetname taskset = parallel.tasksets[self.tasksetname] Thread.Lock(lockname, addToLog=False) self.threadcount += 1 Thread.Unlock(lockname, addToLog=False) try: t() finally: Thread.Lock(lockname, addToLog=False) self.threadcount -= 1 Thread.Unlock(lockname, addToLog=False)
def Log(msg, debugOnly=True, encoding=None): if not debugOnly or Plugin.Debug: global __logSaveScheduled global __logSaveBuffer # Try to decode the message if the encoding is specified try: if encoding is not None: msg = str(msg.decode(encoding).encode("utf8")) except: pass msg = "%s: %-40s: %s" % (str( Datetime.Now().time()), Plugin.Identifier, msg) # Don't write to stderr on Windows, it causes issues. if __sys.platform != "win32": __sys.stderr.write("%s\n" % msg) Thread.Lock("Framework.Log", addToLog=False) if __logSaveBuffer == None: __logSaveBuffer = msg + "\n" else: __logSaveBuffer += msg + "\n" if not __logSaveScheduled: Thread.CreateTimer(5, __saveLog) __logSaveScheduled = True Thread.Unlock("Framework.Log", addToLog=False)
def pms_fwk_modifydict_wrapper(f): lockname = "Framework.ModDict:" + key Thread.Lock(lockname, addToLog=False) dictitem = Dict.Get(key) f(dictitem) Dict.Set(key, dictitem, addToLog=False) Thread.Unlock(lockname, addToLog=False)
def lock(f): lockname = "Framework.Lock:" + f.__name__ try: Thread.Lock(lockname, addToLog=False) f() finally: Thread.Unlock(lockname, addToLog=False) return f
def Set(key, value, addToLog=True): global __dict global __saveScheduled Thread.Lock("Framework.Dict", addToLog=False) __dict[key] = value if not __saveScheduled: Thread.CreateTimer(5, __save, addToLog=addToLog) __saveScheduled = True Thread.Unlock("Framework.Dict", addToLog=False)
def __saveLog(): global __logSaveBuffer global __logSaveScheduled Thread.Lock("Framework.Log", False) f = open(Plugin.__logFilePath, 'a') f.write("%s\n" % __logSaveBuffer) f.close() __logSaveBuffer = None __logSaveScheduled = False Thread.Unlock("Framework.Log", addToLog=False)
def __call__(self): PMS.Log("(Framework) Starting a parallel task set named '%s'" % self.tasksetname) # Try & fetch the task set try: taskset = parallel.tasksets[self.tasksetname] except: PMS.Log( "(Framework) ERROR: Unable to start the task set named '%s'" % self.tasksetname) return if len(taskset) == 0: PMS.Log( "(Framework) ERROR: The task set named '%s' contains no tasks" % self.tasksetname) return # Start tasks, making sure we don't go over the maximum limit lockname = "Framework.Parallel." + self.tasksetname taskindex = 0 while taskindex < len(taskset): Thread.Lock(lockname, addToLog=False) if self.threadcount < parallel.maxThreads: Thread.Create(self.__runtask__, taskset[taskindex]) taskindex += 1 Thread.Unlock(lockname, addToLog=False) Thread.Sleep(0.05) # Wait for all threads to terminate while True: Thread.Lock(lockname, addToLog=False) if self.threadcount > 0: Thread.Unlock(lockname, addToLog=False) Thread.Sleep(0.05) else: Thread.Unlock(lockname, addToLog=False) break # Remove the task set PMS.Log("(Framework) Parallel task set named '%s' has finished." % self.tasksetname)
def __save(addToLog=True): Thread.Lock("Framework.Dict", addToLog=False) dictToSave = copy.deepcopy(__dict) global __saveScheduled __saveScheduled = False try: Data.__pickle("%s/Dict" % Data.__dataPath, dictToSave) if addToLog: PMS.Log("(Framework) Saved the dictionary file") finally: Thread.Unlock("Framework.Dict", addToLog=False)
def __save(): global __prefs global __prefsPath Thread.Lock("Framework.Prefs", addToLog=False) try: userPrefs = XML.Element("PluginPreferences") for pref in __prefs: if pref.has_key("value"): userPrefs.append(XML.Element(pref["id"], pref["value"])) f = open(__prefsPath, "w") f.write(XML.StringFromElement(userPrefs)) f.close() PMS.Log("(Framework) Saved the user preferences file") finally: Thread.Unlock("Framework.Prefs", addToLog=False)
def __save(): global __saveScheduled Thread.Lock("Framework.HTTPCache", addToLog=False) try: # Save the cache Data.__pickle("%s/HTTPCache" % Data.__dataPath, __cache) # Save the cookie jar if __cookieJar is not None: __cookieJar.save("%s/HTTPCookies" % Data.__dataPath) finally: __saveScheduled = False Thread.Unlock("Framework.HTTPCache", addToLog=False) PMS.Log("(Framework) Saved shared HTTP data")
def Request(url, values=None, headers={}, cacheTime=None, autoUpdate=False, encoding=None, errors=None, addToLog=True): global __cache global __saveScheduled now = Datetime.Now() # If no cache time is given, use the default if cacheTime is None: cacheTime = __cacheTime # Attempt to return a cached copy, fetching again if an exception occurs try: # Make sure we don't cache POST requests if values == None and cacheTime > 0: if __cache.has_key(url): cachedAt = __cache[url]["CheckTime"] expiresAt = cachedAt + Datetime.Delta(seconds=cacheTime) if Datetime.Now() < expiresAt: if addToLog: PMS.Log( "(Framework) Loaded %s from the cache (expires at %s)" % (url, expiresAt)) return __cache[url]["Content"] except: if addToLog: PMS.Log( "(Framework) Couldn't load %s from the cache, attempting to fetch again." ) # Try to fetch the page from the server try: # Encode the values data = None if values is not None: data = urllib.urlencode(values) h = __headers.copy() for header in headers: h[header] = headers[header] request = urllib2.Request(url, data, h) f = urllib2.urlopen(request) response = f.read() # If the response is gzipped, unzip it if f.headers.get('Content-Encoding') == "gzip": if addToLog: PMS.Log("(Framework) Received gzipped response from %s" % url) stream = StringIO.StringIO(response) gzipper = gzip.GzipFile(fileobj=stream) response = gzipper.read() else: if addToLog: PMS.Log("(Framework) Received response from %s" % url) # Try to decode the response if manually specified try: if not (encoding is None and errors is None): if encoding is None: encoding = "utf8" if errors is None: errors = "strict" response = str( response.decode(encoding, errors).encode("utf8", errors)) except: if addToLog: PMS.Log( "(Framework) Unable to decode response from '%s' with codec %s" % (url, encoding)) # Handle common errors except urllib2.HTTPError: PMS.Log("(Framework) HTTPError when requesting '%s'" % url) return None except urllib2.URLError: PMS.Log("(Framework) URLError when requesting '%s'" % url) return None Thread.Lock("Framework.HTTPCache", addToLog=False) try: # Cache the data if required if response is not None and cacheTime > 0: item = {} item["Content"] = response item["CheckTime"] = Datetime.Now() if autoUpdate: item["UpdateTime"] = Datetime.Now() + Datetime.Delta( seconds=cacheTime) item["CacheTime"] = cacheTime item["Headers"] = headers item["Encoding"] = encoding item["Errors"] = errors __cache[url] = item if addToLog: PMS.Log("(Framework) Cached response from %s" % url) if not __saveScheduled: Thread.CreateTimer(5, __save) __saveScheduled = True finally: Thread.Unlock("Framework.HTTPCache", addToLog=False) # Return the data return response