# -*- coding: utf-8 -*-

import traceback

from module.plugins.internal.Plugin import Base


class Expose(object):
    """Used for decoration to declare rpc services"""

    def __new__(cls, f, *args, **kwargs):
        hookManager.addRPC(f.__module__, f.func_name, f.func_doc)
        return f


def threaded(fn):

    def run(*args, **kwargs):
        hookManager.startThread(fn, *args, **kwargs)

    return run


class Hook(Base):
    __name__    = "Hook"
    __type__    = "hook"
    __version__ = "0.04"

    __config__   = []  #: [("name", "type", "desc", "default")]
    __threaded__ = []  #@TODO: Remove in 0.4.10

    __description__ = """Base hook plugin"""
    __license__     = "GPLv3"
    __authors__     = [("mkaay"         , "mkaay@mkaay.de"   ),
                       ("RaNaN"         , "RaNaN@pyload.org" ),
                       ("Walter Purcaro", "vuolter@gmail.com")]


    def __init__(self, core, manager):
        super(Hook, self).__init__(core)

        #: Provide information in dict here, usable by API `getInfo`
        self.info = {}

        #: Callback of periodical job task, used by HookManager
        self.cb       = None
        self.interval = 60

        #: `HookManager`
        self.manager = manager

        self.setup()

        #: automatically register event listeners for functions, attribute will be deleted dont use it yourself
        self.event_map = {}

        # Deprecated alternative to event_map
        #: List of events the plugin can handle, name the functions exactly like eventname.
        self.event_list = []  #@NOTE: dont make duplicate entries in event_map

        self.initEvents()
        # self.initPeriodical(10)


    def initEvents(self):
         # register events
        if self.event_map:
            for event, funcs in self.event_map.iteritems():
                if type(funcs) in (list, tuple):
                    for f in funcs:
                        self.manager.addEvent(event, getattr(self, f))
                else:
                    self.manager.addEvent(event, getattr(self, funcs))

            # delete for various reasons
            self.event_map = None

        if self.event_list:
            self.logWarning(_("Deprecated method `event_list`, use `event_map` instead"))

            for f in self.event_list:
                self.manager.addEvent(f, getattr(self, f))

            self.event_list = None


    def initPeriodical(self, delay=0, threaded=False):
        self.cb = self.core.scheduler.addJob(max(0, delay), self._periodical, [threaded], threaded=threaded)


    def _periodical(self, threaded):
        if self.interval < 0:
            self.cb = None
            return

        try:
            self.periodical()

        except Exception, e:
            self.logError(_("Error executing hook: %s") % e)
            if self.core.debug:
                traceback.print_exc()

        self.cb = self.core.scheduler.addJob(self.interval, self._periodical, [threaded], threaded=threaded)


    def __repr__(self):
        return "<Hook %s>" % self.__name__


    def setup(self):
        """More init stuff if needed"""
        pass


    def isActivated(self):
        """Checks if hook is activated"""
        return self.getConfig("activated")


    def deactivate(self):
        """Called when hook was deactivated"""
        pass


    #: Deprecated, use method `deactivate` instead
    def unload(self):
        return self.deactivate()


    def activate(self):
        """Called when hook was activated"""
        pass


    #: Deprecated, use method `activate` instead
    def coreReady(self):
        return self.activate()


    def exit(self):
        """Called by core.shutdown just before pyLoad exit"""
        pass


    #: Deprecated, use method `exit` instead
    def coreExiting(self):
        return self.exit()


    def downloadPreparing(self, pyfile):
        pass


    def downloadFinished(self, pyfile):
        pass


    def downloadFailed(self, pyfile):
        pass


    def packageFinished(self, pypack):
        pass


    def beforeReconnecting(self, ip):
        pass


    def afterReconnecting(self, ip):
        pass


    def periodical(self):
        pass


    def captchaTask(self, task):
        """New captcha task for the plugin, it MUST set the handler and timeout or will be ignored"""
        pass


    #: Deprecated, use method `captchaTask` instead
    def newCaptchaTask(self, task):
        return self.captchaTask(task)


    def captchaCorrect(self, task):
        pass


    def captchaInvalid(self, task):
        pass

@@ -500,17 +500,17 @@
 _ = %220.0
-4
+5
 %22%0A%0A    _
@@ -1652,18 +1652,16 @@
 %0A       
- #
  self.in
@@ -1709,35 +1709,8 @@
 f):%0A
-         # register events%0A
     
@@ -3332,28 +3332,28 @@
 precated
-, use
  method
+, use
  %60deacti
@@ -3524,28 +3524,28 @@
 precated
-, use
  method
+, use
  %60activa
@@ -3728,28 +3728,28 @@
 precated
-, use
  method
+, use
  %60exit%60 
@@ -4187,25 +4187,26 @@
  def captcha
-T
+_t
 ask(self, ta
@@ -4348,20 +4348,20 @@
 ated
-, use
  method
+, use
  %60ca
@@ -4365,17 +4365,18 @@
 %60captcha
-T
+_t
 ask%60 ins
@@ -4439,25 +4439,26 @@
 self.captcha
-T
+_t
 ask(task)%0A%0A%0A

Update Hook (2)