Event fixes

This commit is contained in:
Ruud committed 2012-02-11 02:49:35 +01:00
1 parent e4588a5e7e
commit cfadd851bf
14 files changed
+66 -49

No files matched your search

+1 -1
View File
@@ -15,7 +15,7 @@ import os
log = CPLog(__name__) log = CPLog(__name__)
app = Flask(__name__) app = Flask(__name__, static_folder = 'nope')
web = Blueprint('web', __name__) web = Blueprint('web', __name__)
+4 -5
View File
@@ -70,7 +70,7 @@ class Core(Plugin):
def crappyShutdown(self): def crappyShutdown(self):
try: try:
self.urlopen('%sapp.shutdown' % self.createApiUrl(), show_error = False) self.urlopen('%s/app.shutdown' % self.createApiUrl(), show_error = False)
return True return True
except: except:
self.initShutdown() self.initShutdown()
@@ -78,7 +78,7 @@ class Core(Plugin):
def crappyRestart(self): def crappyRestart(self):
try: try:
self.urlopen('%sapp.restart' % self.createApiUrl(), show_error = False) self.urlopen('%s/app.restart' % self.createApiUrl(), show_error = False)
return True return True
except: except:
self.initShutdown(restart = True) self.initShutdown(restart = True)
@@ -163,8 +163,7 @@ class Core(Plugin):
host = 'localhost' host = 'localhost'
port = Env.setting('port') port = Env.setting('port')
return '%s:%d' % (cleanHost(host).rstrip('/'), int(port)) return '%s:%d%s' % (cleanHost(host).rstrip('/'), int(port), '/' + Env.setting('url_base').lstrip('/') if Env.setting('url_base') else '')
def createApiUrl(self): def createApiUrl(self):
return '%s/%s' % (self.createBaseUrl(), Env.setting('api_key'))
return '%s/%s/' % (self.createBaseUrl(), Env.setting('api_key'))
+1 -1
View File
@@ -17,7 +17,7 @@ def requires_auth(f):
@wraps(f) @wraps(f)
def decorated(*args, **kwargs): def decorated(*args, **kwargs):
auth = getattr(request, 'authorization') auth = getattr(request, 'authorization')
if Env.setting('username') and (not auth or not check_auth(auth.username, md5(auth.password))): if Env.setting('username') and Env.setting('password') and (not auth or not check_auth(auth.username, md5(auth.password))):
return authenticate() return authenticate()
return f(*args, **kwargs) return f(*args, **kwargs)
+10 -4
View File
@@ -2,6 +2,7 @@ from axl.axel import Event
from couchpotato.core.helpers.variable import mergeDicts from couchpotato.core.helpers.variable import mergeDicts
from couchpotato.core.logger import CPLog from couchpotato.core.logger import CPLog
import threading import threading
import time
import traceback import traceback
log = CPLog(__name__) log = CPLog(__name__)
@@ -25,15 +26,17 @@ def addEvent(name, handler, priority = 100):
try: try:
parent = handler.im_self parent = handler.im_self
parent.beforeCall(handler) bc = hasattr(parent, 'beforeCall')
if bc: parent.beforeCall(handler)
h = runHandler(name, handler, *args, **kwargs) h = runHandler(name, handler, *args, **kwargs)
parent.afterCall(handler) ac = hasattr(parent, 'afterCall')
if ac: parent.afterCall(handler)
except: except:
h = runHandler(name, handler, *args, **kwargs) h = runHandler(name, handler, *args, **kwargs)
return h return h
e.handle(createHandle, priority = priority) e.handle(handler, priority = priority)
def removeEvent(name, handler): def removeEvent(name, handler):
e = events[name] e = events[name]
@@ -64,8 +67,10 @@ def fireEvent(name, *args, **kwargs):
except: pass except: pass
e = events[name] e = events[name]
e.lock.acquire()
e.asynchronous = False e.asynchronous = False
result = e(*args, **kwargs) result = e(*args, **kwargs)
e.lock.release()
if single and not merge: if single and not merge:
results = None results = None
@@ -123,10 +128,11 @@ def fireEventAsync(name, *args, **kwargs):
#log.debug('Async "%s": %s, %s' % (name, args, kwargs)) #log.debug('Async "%s": %s, %s' % (name, args, kwargs))
try: try:
e = events[name] e = events[name]
e.lock.acquire()
e.asynchronous = True e.asynchronous = True
e.error_handler = errorHandler e.error_handler = errorHandler
e(*args, **kwargs) e(*args, **kwargs)
e.lock.release()
return True return True
except Exception, e: except Exception, e:
log.error('%s: %s' % (name, e)) log.error('%s: %s' % (name, e))
+17 -7
View File
@@ -1,7 +1,11 @@
from couchpotato.core.event import fireEvent
from couchpotato.core.logger import CPLog from couchpotato.core.logger import CPLog
from couchpotato.core.notifications.base import Notification from couchpotato.core.notifications.base import Notification
from gntp import notifier from gntp import notifier
import logging import logging
import thread
import time
import traceback
log = CPLog(__name__) log = CPLog(__name__)
@@ -15,13 +19,19 @@ class Growl(Notification):
logger.disabled = True logger.disabled = True
try: try:
self.growl = notifier.GrowlNotifier( def startGrowl():
applicationName = 'CouchPotato', time.sleep(2)
notifications = ["Updates"], try:
defaultNotifications = ["Updates"], self.growl = notifier.GrowlNotifier(
applicationIcon = 'http://couchpota.to/media/images/couch.png', applicationName = 'CouchPotato',
) notifications = ["Updates"],
self.growl.register() defaultNotifications = ["Updates"],
applicationIcon = '%s/static/images/couch.png' % fireEvent('app.api_url', single = True),
)
self.growl.register()
except:
log.error('Failed register of growl: %s' % traceback.format_exc())
thread.start_new_thread(startGrowl, ())
except: except:
pass pass
+3 -5
View File
@@ -54,7 +54,7 @@ class Plugin(object):
s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', self.__class__.__name__) s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', self.__class__.__name__)
class_name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower() class_name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()
path = 'static/' + class_name + '/' path = '%s/static/%s/' % (Env.setting('api_key'), class_name)
addView(path + '<path:filename>', self.showStatic, static = True) addView(path + '<path:filename>', self.showStatic, static = True)
if add_to_head: if add_to_head:
@@ -94,8 +94,6 @@ class Plugin(object):
# http request # http request
def urlopen(self, url, timeout = 10, params = {}, headers = {}, multipart = False, show_error = True): def urlopen(self, url, timeout = 10, params = {}, headers = {}, multipart = False, show_error = True):
socket.setdefaulttimeout(timeout)
# Fill in some headers # Fill in some headers
if not headers.get('Referer'): if not headers.get('Referer'):
headers['Referer'] = urlparse(url).hostname headers['Referer'] = urlparse(url).hostname
@@ -114,13 +112,13 @@ class Plugin(object):
cookies = cookielib.CookieJar() cookies = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookies), MultipartPostHandler) opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookies), MultipartPostHandler)
data = opener.open(request).read() data = opener.open(request, timeout = timeout).read()
else: else:
log.info('Opening url: %s, params: %s' % (url, [x for x in params.iterkeys()])) log.info('Opening url: %s, params: %s' % (url, [x for x in params.iterkeys()]))
data = urllib.urlencode(params) if len(params) > 0 else None data = urllib.urlencode(params) if len(params) > 0 else None
request = urllib2.Request(url, data, headers) request = urllib2.Request(url, data, headers)
data = urllib2.urlopen(request).read() data = urllib2.urlopen(request, timeout = timeout).read()
except IOError: except IOError:
if show_error: if show_error:
log.error('Failed opening url in %s: %s %s' % (self.getName(), url, traceback.format_exc(1))) log.error('Failed opening url in %s: %s %s' % (self.getName(), url, traceback.format_exc(1)))
+2 -2
View File
@@ -290,11 +290,11 @@ class Renamer(Plugin):
# Remove files # Remove files
for src in remove_files: for src in remove_files:
log.info('Removing "%s"' % src) log.info('(fake) Removing "%s"' % src)
# Remove matching releases # Remove matching releases
for release in remove_releases: for release in remove_releases:
log.info('Removing release %s' % release) log.info('(fake) Removing release %s' % release)
# Search for trailers etc # Search for trailers etc
fireEventAsync('renamer.after', group) fireEventAsync('renamer.after', group)
+3 -1
View File
@@ -528,7 +528,9 @@ class Scanner(Plugin):
return True return True
def isSampleFile(self, filename): def isSampleFile(self, filename):
return re.search('(^|[\W_])sample\d*[\W_]', filename.lower()) is_sample = re.search('(^|[\W_])sample\d*[\W_]', filename.lower())
if is_sample: log.debug('Is sample file: %s' % filename)
return is_sample
def filesizeBetween(self, file, min = 0, max = 100000): def filesizeBetween(self, file, min = 0, max = 100000):
try: try:
+4 -4
View File
@@ -16,18 +16,18 @@ log = CPLog(__name__)
class Searcher(Plugin): class Searcher(Plugin):
def __init__(self): def __init__(self):
addEvent('searcher.all', self.all) addEvent('searcher.all', self.all_movies)
addEvent('searcher.single', self.single) addEvent('searcher.single', self.single)
addEvent('searcher.correct_movie', self.correctMovie) addEvent('searcher.correct_movie', self.correctMovie)
addEvent('searcher.download', self.download) addEvent('searcher.download', self.download)
# Schedule cronjob # Schedule cronjob
fireEvent('schedule.cron', 'searcher.all', self.all, day = self.conf('cron_day'), hour = self.conf('cron_hour'), minute = self.conf('cron_minute')) fireEvent('schedule.cron', 'searcher.all', self.all_movies, day = self.conf('cron_day'), hour = self.conf('cron_hour'), minute = self.conf('cron_minute'))
if not Env.setting('development'): if not Env.setting('development'):
addEvent('app.load', self.all) addEvent('app.load', self.all_movies)
def all(self): def all_movies(self):
db = get_session() db = get_session()
+1 -1
View File
@@ -9,7 +9,7 @@ import os.path
import time import time
class Settings(): class Settings(object):
options = {} options = {}
types = {} types = {}
+3 -2
View File
@@ -10,8 +10,8 @@ import locale
import logging import logging
import os.path import os.path
import sys import sys
import traceback
import time import time
import traceback
def getOptions(base_path, args): def getOptions(base_path, args):
@@ -180,7 +180,8 @@ def runCouchPotato(options, base_path, args, desktop = None):
} }
# Static path # Static path
web.add_url_rule('static/<path:filename>', app.static_folder = os.path.join(base_path, 'couchpotato', 'static')
web.add_url_rule('%s/static/<path:filename>' % api_key,
endpoint = 'static', endpoint = 'static',
view_func = app.send_static_file) view_func = app.send_static_file)
Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

@@ -13,6 +13,7 @@ Page.Wanted = new Class({
// Wanted movies // Wanted movies
self.wanted = new MovieList({ self.wanted = new MovieList({
'status': 'active', 'status': 'active',
'navigation': true,
'actions': MovieActions 'actions': MovieActions
}); });
$(self.wanted).inject(self.el); $(self.wanted).inject(self.el);
+16 -16
View File
@@ -13,8 +13,10 @@
from couchpotato.core.helpers.variable import natcmp from couchpotato.core.helpers.variable import natcmp
import Queue import Queue
import hashlib
import sys import sys
import threading import threading
import time
class Event(object): class Event(object):
""" """
@@ -75,7 +77,7 @@ class Event(object):
if True, the execution result will contain sys.exc_info() if True, the execution result will contain sys.exc_info()
on error. exc_info must be also True to get the traceback on error. exc_info must be also True to get the traceback
hash = hash(handler) hash = self.hash(handler)
Handlers are stored in a dictionary that has as keys the handler's hash Handlers are stored in a dictionary that has as keys the handler's hash
handlers = { handlers = {
@@ -103,6 +105,9 @@ class Event(object):
self.handlers = {} self.handlers = {}
self.memoize = {} self.memoize = {}
def hash(self, handler):
return hashlib.md5(str(handler)).hexdigest()
def handle(self, handler, priority = 0): def handle(self, handler, priority = 0):
""" Registers a handler. The handler can be transmitted together """ Registers a handler. The handler can be transmitted together
with two arguments as a list or dictionary. The arguments are: with two arguments as a list or dictionary. The arguments are:
@@ -121,13 +126,13 @@ class Event(object):
event += {'handler':handler, 'memoize':True, 'timeout':1.5} event += {'handler':handler, 'memoize':True, 'timeout':1.5}
""" """
handler_, memoize, timeout = self._extract(handler) handler_, memoize, timeout = self._extract(handler)
self.handlers['%s.%s' % (priority, hash(handler_))] = (handler_, memoize, timeout) self.handlers['%s.%s' % (priority, self.hash(handler_))] = (handler_, memoize, timeout)
return self return self
def unhandle(self, handler): def unhandle(self, handler):
""" Unregisters a handler """ """ Unregisters a handler """
handler_, memoize, timeout = self._extract(handler) handler_, memoize, timeout = self._extract(handler)
key = hash(handler_) key = self.hash(handler_)
if not key in self.handlers: if not key in self.handlers:
raise ValueError('Handler "%s" was not found' % str(handler_)) raise ValueError('Handler "%s" was not found' % str(handler_))
del self.handlers[key] del self.handlers[key]
@@ -139,6 +144,7 @@ class Event(object):
self.result = [] self.result = []
if self.handlers: if self.handlers:
max_threads = self._threads() max_threads = self._threads()
for i in range(max_threads): for i in range(max_threads):
@@ -172,10 +178,8 @@ class Event(object):
""" Executes all handlers stored in the queue """ """ Executes all handlers stored in the queue """
while True: while True:
try: try:
handler, memoize, timeout = self.handlers[self.queue.get()] h_ = self.queue.get()
handler, memoize, timeout = self.handlers[h_]
if isinstance(self.lock, threading._RLock):
self.lock.acquire() #synchronization
try: try:
r = self._memoize(memoize, timeout, handler, *args, **kwargs) r = self._memoize(memoize, timeout, handler, *args, **kwargs)
@@ -189,14 +193,9 @@ class Event(object):
else: else:
self.error_handler(sys.exc_info()) self.error_handler(sys.exc_info())
finally: finally:
if isinstance(self.lock, threading._RLock):
self.lock.release()
if not self.asynchronous: if not self.asynchronous:
try: self.queue.task_done()
self.queue.task_done()
except ValueError:
pass
if self.queue.empty(): if self.queue.empty():
raise Queue.Empty raise Queue.Empty
@@ -235,7 +234,7 @@ class Event(object):
def _memoize(self, memoize, timeout, handler, *args, **kwargs): def _memoize(self, memoize, timeout, handler, *args, **kwargs):
""" Caches the execution result of successful executions """ Caches the execution result of successful executions
hash = hash(handler) hash = self.hash(handler)
memoize = { memoize = {
hash : ((args, kwargs, result), (args, kwargs, result), ...), hash : ((args, kwargs, result), (args, kwargs, result), ...),
hash : ((args, kwargs, result), ...), ... hash : ((args, kwargs, result), ...), ...
@@ -247,7 +246,8 @@ class Event(object):
if not memoize: if not memoize:
if timeout <= 0: #no time restriction if timeout <= 0: #no time restriction
return [True, handler(*args, **kwargs), handler] result = [True, handler(*args, **kwargs), handler]
return result
result = self._timeout(timeout, handler, *args, **kwargs) result = self._timeout(timeout, handler, *args, **kwargs)
if isinstance(result, tuple) and len(result) == 3: if isinstance(result, tuple) and len(result) == 3:
@@ -255,7 +255,7 @@ class Event(object):
return [False, self._error(result), handler] return [False, self._error(result), handler]
return [True, result, handler] return [True, result, handler]
else: else:
hash_ = hash(handler) hash_ = self.hash(handler)
if hash_ in self.memoize: if hash_ in self.memoize:
for args_, kwargs_, result in self.memoize[hash_]: for args_, kwargs_, result in self.memoize[hash_]:
if args_ == args and kwargs_ == kwargs: if args_ == args and kwargs_ == kwargs: