~ubuntu-branches/ubuntu/utopic/gozerbot/utopic

« back to all changes in this revision

Viewing changes to build/lib/gozerbot/plugins.py

  • Committer: Package Import Robot
  • Author(s): Jeremy Malcolm
  • Date: 2012-04-03 21:58:28 UTC
  • mfrom: (3.1.11 sid)
  • Revision ID: package-import@ubuntu.com-20120403215828-6mik0tzug5na93la
Tags: 0.99.1-2
* Removes logfiles on purge (Closes: #668767)
* Reverted location of installed files back to /usr/lib/gozerbot.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# gozerbot/plugins.py
 
2
#
 
3
#
 
4
 
 
5
""" provide plugin infrastructure """
 
6
 
 
7
__copyright__ = 'this file is in the public domain'
 
8
 
 
9
## gozerbot imports
 
10
 
 
11
from gozerbot.stats import stats
 
12
from gozerbot.tests import tests
 
13
from gozerbot.datadir import datadir
 
14
from users import users
 
15
from irc.monitor import outmonitor, saymonitor
 
16
from xmpp.monitor import xmppmonitor
 
17
from utils.log import rlog
 
18
from utils.exception import handle_exception
 
19
from utils.generic import checkchan
 
20
from utils.locking import lockdec, funclocked, Locked
 
21
from utils.generic import plugnames, waitforqueue, uniqlist, makeoptions, makeargrest, cleanpycfile
 
22
from gozerimport import gozer_import, force_import
 
23
from persist.persist import Persist
 
24
from persist.persistconfig import PersistConfig
 
25
from config import config
 
26
from commands import cmnds
 
27
from callbacks import callbacks, jcallbacks, gn_callbacks
 
28
from redispatcher import rebefore, reafter
 
29
from aliases import aliascheck, aliasget
 
30
from ignore import shouldignore
 
31
from threads.thr import start_new_thread, getname
 
32
from persist.persiststate import PersistState
 
33
from simplejson import loads
 
34
from morphs import inputmorphs, outputmorphs
 
35
from eventbase import EventBase
 
36
from admin import cmndtable, pluginlist
 
37
 
 
38
# basic imports
 
39
import os, os.path, thread, time, Queue, re, copy
 
40
 
 
41
## END IMPORT
 
42
 
 
43
## LOCK SECTION
 
44
 
 
45
loadlock = thread.allocate_lock()
 
46
loadlocked = lockdec(loadlock)
 
47
 
 
48
## END LOCK
 
49
 
 
50
class Plugins(object):
 
51
 
 
52
    """
 
53
        hold all the plugins.
 
54
 
 
55
    """
 
56
 
 
57
    def __init__(self):
 
58
        self.plugs = {} # dict with the plugins
 
59
        self.reloadlock = thread.allocate_lock()
 
60
        # persisted data for deny of plugins (blacklist)
 
61
        self.plugdeny = Persist(datadir + os.sep + 'plugdeny', init=False)
 
62
        if not self.plugdeny.data:
 
63
            self.plugdeny.data = []
 
64
        # persisted data for allowing of plugins (whitelist)
 
65
        self.plugallow = Persist(datadir + os.sep + 'plugallow', init=False)
 
66
        if not self.plugallow.data:
 
67
            self.plugallow.data = []
 
68
        self.avail = [] # available plugins
 
69
        self.ondisk = [] # plugisn available for reload
 
70
        self.initcalled = [] # plugins which init functions are called
 
71
        self.overloads = {} # plugins to overload
 
72
        self.activated = {}
 
73
        for plug in config['plugdeny']:
 
74
            self.disable(plug)
 
75
 
 
76
    def __getitem__(self, item):
 
77
 
 
78
        """
 
79
            return plugin.
 
80
 
 
81
        """
 
82
 
 
83
        if self.plugs.has_key(item):
 
84
            return self.plugs[item]
 
85
        else:
 
86
            return None
 
87
 
 
88
    def get(self, item, attr):
 
89
 
 
90
        """
 
91
            get attribute of plugin.
 
92
 
 
93
            :param item: plugin to get attribute of
 
94
            :type item: string
 
95
            :param attr: attribute to fetch
 
96
            :type attr: string
 
97
 
 
98
            .. literalinclude:: ../../gozerbot/plugins.py
 
99
                :pyobject: Plugins.get
 
100
 
 
101
        """
 
102
 
 
103
        if self.plugs.has_key(item):
 
104
            return getattr(self.plugs[item], attr)
 
105
 
 
106
    def whatperms(self):
 
107
 
 
108
        """
 
109
            return what permissions are possible.
 
110
 
 
111
            :rtype: list
 
112
 
 
113
            .. literalinclude:: ../../gozerbot/plugins.py
 
114
                :pyobject: Plugins.whatperms
 
115
 
 
116
        """
 
117
 
 
118
        result = []
 
119
 
 
120
        # search RE callbacks before the commands
 
121
        for i in rebefore.whatperms():
 
122
            if not i in result:
 
123
                result.append(i)
 
124
 
 
125
        # search the commands
 
126
        for i in cmnds.whatperms():
 
127
            if not i in result:
 
128
                result.append(i)
 
129
 
 
130
        # search RE callbacks after commands
 
131
        for i in reafter.whatperms():
 
132
            if not i in result:
 
133
                result.append(i)
 
134
 
 
135
        result.sort()
 
136
        return result
 
137
 
 
138
    def exist(self, name):
 
139
 
 
140
        """
 
141
            see if plugin exists.
 
142
 
 
143
            :param name: name of plugin to check for
 
144
            :type name: string
 
145
            :rtype: boolean
 
146
 
 
147
            .. literalinclude:: ../../gozerbot/plugins.py
 
148
                :pyobject: Plugins.exist
 
149
 
 
150
        """
 
151
 
 
152
        if self.plugs.has_key(name):
 
153
            return True
 
154
        return False
 
155
 
 
156
    def disable(self, name):
 
157
 
 
158
        """
 
159
            prevent plugin to be loaded. plugins does get imported but 
 
160
            commands, callbacks, monitors etc are not enabled.
 
161
 
 
162
            :param name: name of the plugin to disable
 
163
            :type name: string
 
164
 
 
165
            .. literalinclude:: ../../gozerbot/plugins.py
 
166
                :pyobject: Plugins.disable
 
167
 
 
168
        """
 
169
 
 
170
        try:
 
171
            config['loadlist'].remove(name)
 
172
            config.save()
 
173
            self.plugdeny.data.append(name)
 
174
            self.plugdeny.save()
 
175
            
 
176
        except:
 
177
            pass
 
178
 
 
179
    def enable(self, name):
 
180
 
 
181
        """
 
182
            enable plugin.
 
183
 
 
184
            :param name: name of plugin to enable
 
185
            :type name: string
 
186
 
 
187
            .. literalinclude:: ../../gozerbot/plugins.py
 
188
                :pyobject: Plugins.enable
 
189
 
 
190
        """
 
191
 
 
192
        try:
 
193
 
 
194
            if name not in config['loadlist']:
 
195
                config['loadlist'].append(name)
 
196
                config.save()
 
197
 
 
198
        except KeyError:
 
199
            pass
 
200
 
 
201
        try:
 
202
            self.plugdeny.data.remove(name)
 
203
            self.plugdeny.save()
 
204
 
 
205
        except ValueError:
 
206
            pass
 
207
 
 
208
    def plugsizes(self):
 
209
 
 
210
        """
 
211
            call the size() function in all plugins.
 
212
 
 
213
            :rtype: list .. list of plugin sizes
 
214
 
 
215
            .. literalinclude:: ../../gozerbot/plugins.py
 
216
                :pyobject: Plugins.plugsizes
 
217
        """
 
218
 
 
219
        reslist = []
 
220
        cp = dict(self.plugs)
 
221
        for i, j in cp.iteritems():
 
222
            try:
 
223
                reslist.append("%s: %s" % (i, j.size()))
 
224
            except AttributeError:
 
225
                pass
 
226
        return reslist
 
227
 
 
228
    def list(self):
 
229
 
 
230
        """
 
231
            list of registered plugins.
 
232
 
 
233
            :rtype: list .. list of enabled plugins
 
234
 
 
235
            .. literalinclude:: ../../gozerbot/plugins.py
 
236
                :pyobject: Plugins.list
 
237
 
 
238
        """
 
239
 
 
240
        self.avail.sort()
 
241
        return self.avail
 
242
 
 
243
    def plugimport(self, mod, name):
 
244
 
 
245
        """
 
246
            import a plugin.
 
247
 
 
248
            :param mod: module to import plugin from
 
249
            :type mod: string
 
250
            :param name: name of the plugin to import
 
251
            :type name: string
 
252
            :rtype: module .. the plugin
 
253
 
 
254
            .. literalinclude:: ../../gozerbot/plugins.py
 
255
                :pyobject: Plugins.plugimport
 
256
 
 
257
        """
 
258
        
 
259
        if name in config['loadlist']:
 
260
            return self.load(mod, name)
 
261
 
 
262
    def regplugin(self, mod, name):
 
263
 
 
264
        """
 
265
            register plugin.
 
266
 
 
267
            :param mod: module to import plugin from
 
268
            :type mod: string
 
269
            :param name: name of the plugin to import
 
270
            :type name: string
 
271
            :rtype: module .. the plugin
 
272
 
 
273
            .. literalinclude:: ../../gozerbot/plugins.py
 
274
                :pyobject: Plugins.regplugin
 
275
 
 
276
        """
 
277
 
 
278
        name = name.lower()
 
279
        mod = mod.lower()
 
280
        modname = mod + '.' + name
 
281
 
 
282
        # see if plugin is in deny
 
283
        if name in self.avail:
 
284
            rlog(0, 'plugins', '%s already registered' % name)
 
285
            return
 
286
 
 
287
        if name in config['plugdeny']:
 
288
            rlog(0, 'plugins', '%s is in config.plugdeny .. not loading' % name)
 
289
            return
 
290
 
 
291
        if name in self.plugdeny.data:
 
292
            rlog(0, 'plugins', '%s.%s in deny .. not loading' % (mod, name))
 
293
            return 0
 
294
 
 
295
        if config.has_key('loadlist') and name not in config['loadlist'] and 'gplugs' in modname and name not in self.plugallow.data:
 
296
                rlog(9, 'plugins', 'not loading %s.%s' % (mod, name))
 
297
                return 0
 
298
 
 
299
        # if plugin is already registered unload it
 
300
        if self.plugs.has_key(name):
 
301
            rlog(10, 'plugins', 'overloading %s plugin with %s version' % (name, mod))
 
302
            self.unloadnosave(name)
 
303
 
 
304
        # create the plugin data dir
 
305
        if hasattr(os, 'mkdir'):
 
306
            if not os.path.isdir(datadir + os.sep + 'plugs'):
 
307
                os.mkdir(datadir + os.sep + 'plugs')
 
308
 
 
309
            if not os.path.isdir(datadir + os.sep + 'plugs' + os.sep + name):
 
310
                os.mkdir(datadir + os.sep + 'plugs' + os.sep + name)
 
311
 
 
312
        # import the plugin
 
313
        plug = self.plugimport(mod, name)
 
314
 
 
315
        if plug:
 
316
            rlog(0, 'plugins', "%s.%s registered" % (mod, name))
 
317
 
 
318
            if name not in self.avail:
 
319
                self.avail.append(name)
 
320
 
 
321
            return plug
 
322
 
 
323
        else:
 
324
            rlog(10, 'plugins', "can't import %s.%s .. try plug-enable" % (mod, name))
 
325
         
 
326
    def showregistered(self):
 
327
 
 
328
        """
 
329
            show registered plugins.
 
330
 
 
331
            .. literalinclude:: ../../gozerbot/plugins.py
 
332
                :pyobject: Plugins.showregistered
 
333
 
 
334
        """
 
335
 
 
336
        self.avail.sort()
 
337
        rlog(10, 'plugins', 'registered %s' % ' .. '.join(self.avail))
 
338
        self.overload()
 
339
 
 
340
    def regdir(self, dirname, exclude=[]):
 
341
 
 
342
        """
 
343
            register a directory.
 
344
 
 
345
            :param dirname: directory to import plugins from
 
346
            :type dirname: string
 
347
            :param exclude: plugins to exclude from importing
 
348
            :type exclude: list .. list of plugin names
 
349
            :rtype: list .. list of plugin names that are registered
 
350
 
 
351
            .. literalinclude:: ../../gozerbot/plugins.py
 
352
                :pyobject: Plugins.regdir
 
353
 
 
354
        """
 
355
 
 
356
        threads = []
 
357
        plugs = []
 
358
        for plug in plugnames(dirname):
 
359
            if plug in exclude or plug.startswith('.'):
 
360
                continue
 
361
            try:
 
362
                self.regplugin(dirname, plug)
 
363
                plugs.append(plug)
 
364
            except:
 
365
                handle_exception()
 
366
        self.ondisk.extend(plugs)
 
367
        return plugs
 
368
 
 
369
    def regcore(self): 
 
370
 
 
371
        """
 
372
            register core plugins.
 
373
 
 
374
            .. literalinclude:: ../../gozerbot/plugins.py
 
375
                :pyobject: Plugins.regcore
 
376
 
 
377
        """
 
378
 
 
379
        self.plugdeny.init([])
 
380
        self.plugallow.init([])
 
381
        avail = [] 
 
382
        plugs = force_import('gozerbot.plugs')
 
383
 
 
384
        for i in plugs.__plugs__:
 
385
 
 
386
            if i not in avail:
 
387
 
 
388
                try:
 
389
                    self.regplugin('gozerbot.plugs', i)
 
390
                except Exception, ex:
 
391
                    handle_exception()
 
392
                else:
 
393
                    avail.append(i)
 
394
 
 
395
        self.ondisk.extend(avail)
 
396
 
 
397
    def enableall(self):
 
398
 
 
399
        """
 
400
            enable all plugins
 
401
 
 
402
            .. literalinclude:: ../../gozerbot/plugins.py
 
403
                :pyobject: Plugins.enableall
 
404
 
 
405
        """
 
406
 
 
407
        for name in self.available():
 
408
            self.enable(name)
 
409
 
 
410
    def regplugins(self):
 
411
 
 
412
        """
 
413
            register all plugins.
 
414
 
 
415
            .. literalinclude:: ../../gozerbot/plugins.py
 
416
                :pyobject: Plugins.regplugins
 
417
 
 
418
        """
 
419
 
 
420
        self.regcore()
 
421
        avail = []
 
422
 
 
423
        # check for myplugs directory
 
424
        if os.path.isdir('myplugs'):
 
425
            avail.extend(self.regdir('myplugs'))  
 
426
 
 
427
            for i in os.listdir('myplugs'):
 
428
 
 
429
                if i.startswith('.'):
 
430
                    continue
 
431
 
 
432
                if os.path.isdir('myplugs' + os.sep + i):
 
433
                    avail.extend(self.regdir('myplugs' + os.sep + i))  
 
434
        else:
 
435
            rlog(10, 'plugins', 'no myplugs directory found')
 
436
 
 
437
        # check for gplugs package
 
438
        try:
 
439
            gplugs = gozer_import('gplugs')
 
440
        except ImportError:
 
441
            rlog(20, 'plugins', "no gplugs package found")
 
442
            gplugs = None
 
443
 
 
444
        if gplugs:
 
445
 
 
446
            for i in gplugs.__plugs__:
 
447
 
 
448
                try:
 
449
                    self.regplugin('gplugs', i)
 
450
                    avail.append(i)
 
451
                except Exception, ex:
 
452
                    handle_exception()
 
453
 
 
454
        if config.get('db_driver') == "olddb":
 
455
            # check for gplugs package
 
456
            try:
 
457
                gplugs = gozer_import('gplugs.olddb')
 
458
            except ImportError:
 
459
                rlog(20, 'plugins', "no gplugs.old package found")
 
460
                gplugs = None
 
461
 
 
462
            if gplugs:
 
463
 
 
464
                for i in gplugs.__plugs__:
 
465
 
 
466
                    try:
 
467
                        self.regplugin('gplugs.olddb', i)
 
468
                        avail.append(i)
 
469
                    except Exception, ex:
 
470
                        handle_exception()
 
471
        else:
 
472
            # check for gplugs package
 
473
            try:
 
474
                gplugs = gozer_import('gplugs.alchemy')
 
475
            except ImportError:
 
476
                rlog(20, 'plugins', "no gplugs.alchemy package found")
 
477
                gplugs = None
 
478
 
 
479
            if gplugs:
 
480
 
 
481
                for i in gplugs.__plugs__:
 
482
 
 
483
                    try:
 
484
                        self.regplugin('gplugs.alchemy', i)
 
485
                        avail.append(i)
 
486
                    except Exception, ex:
 
487
                        handle_exception()
 
488
 
 
489
        self.ondisk.extend(avail)
 
490
        self.readoverload()
 
491
        start_new_thread(self.showregistered, ())
 
492
 
 
493
    def readoverload(self):
 
494
 
 
495
        """ 
 
496
            see if there is a permoverload file and if so use it to overload
 
497
            permissions based on function name.
 
498
 
 
499
            .. literalinclude:: ../../gozerbot/plugins.py
 
500
                :pyobject: Plugins.readoverload
 
501
 
 
502
        """
 
503
 
 
504
        try:
 
505
            overloadfile = open(datadir + os.sep + 'permoverload', 'r')
 
506
        except IOError:
 
507
            return
 
508
 
 
509
        try:
 
510
 
 
511
            for i in overloadfile:
 
512
                i = i.strip()
 
513
                splitted = i.split(',')
 
514
 
 
515
                try:
 
516
                    funcname = splitted[0].strip()
 
517
                    perms = []
 
518
                    for j in splitted[1:]:
 
519
                        perms.append(j.strip())
 
520
                except IndexError:
 
521
                    rlog(10, 'plugins', "permoverload: can't set perms of %s" \
 
522
% i)
 
523
                    continue
 
524
 
 
525
                if not funcname:
 
526
                    rlog(10, 'plugins', "permoverload: no function provided")
 
527
                    continue
 
528
 
 
529
                if not perms:
 
530
                    rlog(10, 'plugins', "permoverload: no permissions \
 
531
provided for %s" % funcname)
 
532
                    continue
 
533
 
 
534
                self.overloads[funcname] = perms
 
535
 
 
536
        except Exception, ex:
 
537
             handle_exception()
 
538
 
 
539
    def overload(self):
 
540
 
 
541
        """
 
542
            overload functions in self.overloads. 
 
543
 
 
544
            .. literalinclude:: ../../gozerbot/plugins.py
 
545
                :pyobject: Plugins.overload
 
546
 
 
547
        """
 
548
        for funcname, perms in self.overloads.iteritems():
 
549
 
 
550
            if self.permoverload(funcname, perms):
 
551
                rlog(0, 'plugins', '%s permission set to %s' % (funcname, \
 
552
perms))
 
553
 
 
554
    def available(self):
 
555
 
 
556
        """
 
557
            available plugins not yet registered.
 
558
 
 
559
            .. literalinclude:: ../../gozerbot/plugins.py
 
560
                :pyobject: Plugins.available
 
561
 
 
562
        """
 
563
 
 
564
        self.ondisk.sort()
 
565
        return self.ondisk
 
566
 
 
567
    def saveplug(self, plugname):
 
568
 
 
569
        """
 
570
            call save() function of plugin.
 
571
 
 
572
            :param plugname: name of the plugin to call save() on
 
573
            :type plugname: string
 
574
 
 
575
            .. literalinclude:: ../../gozerbot/plugins.py
 
576
                :pyobject: Plugins.saveplug
 
577
        """
 
578
 
 
579
        try:
 
580
            self.plugs[plugname].save()
 
581
 
 
582
        except AttributeError:
 
583
            pass
 
584
 
 
585
        except KeyError:
 
586
            pass
 
587
 
 
588
    def save(self):
 
589
 
 
590
        """
 
591
            call registered plugins save.
 
592
 
 
593
            .. literalinclude:: ../../gozerbot/plugins.py
 
594
                :pyobject: Plugins.save
 
595
 
 
596
        """
 
597
 
 
598
        for plug in self.plugs.values():
 
599
 
 
600
            try:
 
601
                plug.save()
 
602
 
 
603
            except AttributeError:
 
604
                pass
 
605
 
 
606
            except Exception, ex:
 
607
                handle_exception()
 
608
 
 
609
    def save_cfg(self):
 
610
 
 
611
        """
 
612
            call registered plugins configuration save.
 
613
 
 
614
            .. literalinclude:: ../../gozerbot/plugins.py
 
615
                :pyobject: Plugins.save_cfg
 
616
 
 
617
        """
 
618
 
 
619
        for plug in self.plugs.values():
 
620
            try:
 
621
                cfg = getattr(plug, 'cfg')
 
622
                if isinstance(cfg, PersistConfig):
 
623
                    try:
 
624
                        cfg.save()
 
625
                    except:
 
626
                        handle_exception()
 
627
            except AttributeError:
 
628
                continue
 
629
 
 
630
    def save_cfgname(self, name):
 
631
 
 
632
        """
 
633
            save plugin persisted config data.
 
634
 
 
635
            :param name: name of the plugin to call cfg.save for
 
636
            :type name: string
 
637
 
 
638
            .. literalinclude:: ../../gozerbot/plugins.py
 
639
                :pyobject: Plugins.save_cfgname
 
640
        """
 
641
 
 
642
        try:
 
643
            plug = self.plugs[name]
 
644
            cfg = getattr(plug, 'cfg')
 
645
 
 
646
            if isinstance(cfg, PersistConfig):
 
647
 
 
648
                try:
 
649
                    cfg.save()
 
650
                except:
 
651
                    handle_exception()
 
652
 
 
653
        except (AttributeError, KeyError):
 
654
            pass
 
655
        
 
656
    def exit(self):
 
657
 
 
658
        """
 
659
            call shutdown on all registered plugins. 
 
660
 
 
661
            .. literalinclude:: ../../gozerbot/plugins.py
 
662
                :pyobject: Plugins.exit
 
663
 
 
664
        """
 
665
 
 
666
        self.save()
 
667
        threadlist = []
 
668
 
 
669
        # call shutdown on all plugins
 
670
        for name, plug in self.plugs.iteritems():
 
671
 
 
672
            try:
 
673
                shutdown = getattr(plug, 'shutdown')
 
674
                thread = start_new_thread(shutdown, ())
 
675
                threadlist.append((name, thread))
 
676
 
 
677
                try:
 
678
                    self.initcalled.remove(name)
 
679
                except ValueError:
 
680
                    pass
 
681
 
 
682
            except AttributeError:
 
683
                continue
 
684
 
 
685
            except Exception, ex:
 
686
                rlog(10, 'plugins', 'error shutting down %s: %s' % (name, str(ex)))
 
687
 
 
688
        # join shutdown threads
 
689
        try:
 
690
 
 
691
            for name, thread in threadlist:
 
692
                thread.join()
 
693
                rlog(10, 'plugins', '%s shutdown finished' % name)
 
694
        except:
 
695
            handle_exception()
 
696
 
 
697
    def getoptions(self, command):
 
698
 
 
699
        """
 
700
            return options entry of a command.
 
701
 
 
702
            :param command: command name to get options of
 
703
            :type command: string
 
704
            :rtype: dict
 
705
 
 
706
            .. literalinclude:: ../../gozerbot/plugins.py
 
707
                :pyobject: Plugins.getoptions
 
708
 
 
709
        """
 
710
 
 
711
        return cmnds.getoptions(command)
 
712
 
 
713
    def getdepend(self, plugname):
 
714
 
 
715
        """
 
716
            get plugins the plugin depends on.  NOT USED ANYMORE ..
 
717
 
 
718
            we use the __depending__ attribute now which checks for the 
 
719
            reverse case ala what plugins depends on this plugin. code is 
 
720
            in reload().
 
721
 
 
722
        """
 
723
 
 
724
        # try to import the plugin
 
725
        if plugname in self.plugs:
 
726
            plug = self.plugs[plugname]
 
727
        else:
 
728
            for mod in ['gozerbot.plugs', 'gplugs', 'myplugs']:
 
729
                try:
 
730
                    plug = gozer_import('%s.%s' % (mod, plugname))
 
731
                except ImportError:
 
732
                    continue
 
733
 
 
734
        # check for the __depend__ attribute           
 
735
        try: 
 
736
            depends = plug.__depend__
 
737
        except:
 
738
            depends = []
 
739
 
 
740
        return depends
 
741
 
 
742
    def load(self, mod , name, enable=True):
 
743
        #if name in config['plugdeny']:
 
744
        #     return
 
745
        # force an import of the plugin
 
746
        modname = mod + '.' + name
 
747
        self.down(name)
 
748
        self.unload(name)
 
749
        if enable:
 
750
            self.enable(name)
 
751
        plug = self.plugs[name] = gozer_import(modname)
 
752
        plug.loadtime = time.time()
 
753
        if enable:
 
754
            self.enable(name)
 
755
            self.overload()
 
756
            # call plugins init() function
 
757
            try:
 
758
                rlog(0, 'plugins', 'calling %s init()' % modname)
 
759
                plug.init()
 
760
                self.initcalled.append(modname)
 
761
 
 
762
            except (AttributeError, KeyError):
 
763
                pass
 
764
 
 
765
            except Exception, ex:
 
766
                rlog(10, 'plugins', '%s module init failed' % name)
 
767
                raise
 
768
 
 
769
            rlog(0, 'plugins', 'enabled %s' % name)
 
770
 
 
771
        self.activate(name)
 
772
        return plug
 
773
 
 
774
    #@loadlocked
 
775
    def reload(self, mod, name, enable=True):
 
776
 
 
777
        """
 
778
            reload plugin.
 
779
 
 
780
            :param mod: module to import plugin from
 
781
            :type mod: string
 
782
            :param name: name of the plugin to reload
 
783
            :type name: string
 
784
            :param enable: whether plugin should be enabled on reload
 
785
            :type enable: boolean  
 
786
            :rtype: list .. list of names of reloaded plugins
 
787
 
 
788
            .. literalinclude:: ../../gozerbot/plugins.py
 
789
                :pyobject: Plugins.reload
 
790
 
 
791
        """
 
792
 
 
793
        # create the plugin data dir
 
794
        if not os.path.isdir(datadir + os.sep + 'plugs'):
 
795
            os.mkdir(datadir + os.sep + 'plugs')
 
796
 
 
797
        if not os.path.isdir(datadir + os.sep + 'plugs' + os.sep + name):
 
798
            os.mkdir(datadir + os.sep + 'plugs' + os.sep + name)
 
799
 
 
800
        reloaded = []
 
801
        modname = mod + '.' + name
 
802
 
 
803
        # force an import of the plugin
 
804
        plug = self.load(mod, name)
 
805
 
 
806
        # recurse the reload function if plugin is a dir
 
807
        try:
 
808
            for p in plug.__plugs__:
 
809
                self.load(modname, p)
 
810
                reloaded.append(p)
 
811
 
 
812
        except (KeyError, AttributeError):
 
813
            pass
 
814
 
 
815
        rlog(0, 'plugins', 'reloaded plugin %s' % modname)
 
816
        reloaded.append(name)
 
817
        self.plugallow.data.append(name)
 
818
 
 
819
        try:
 
820
            self.plugdeny.data.remove(name)
 
821
        except ValueError:
 
822
            pass
 
823
 
 
824
        if name not in self.avail:
 
825
            self.avail.append(name)
 
826
 
 
827
        # recurse on plugins the depend on this plugin
 
828
        try:
 
829
            depends = plug.__depending__
 
830
 
 
831
            for plug in depends:
 
832
                rlog(10, 'plugins', 'loading depending plugin %s (%s)' % (plug, name))
 
833
                self.load(mod, plug, False)
 
834
                reloaded.append(plug)
 
835
 
 
836
        except AttributeError:
 
837
            pass
 
838
 
 
839
        return reloaded
 
840
 
 
841
    def activate(self, plugname):
 
842
        self.activated[plugname] = True
 
843
        try:
 
844
            cmnds.activate(plugname)
 
845
            callbacks.activate(plugname)
 
846
            gn_callbacks.activate(plugname)
 
847
            jcallbacks.activate(plugname)
 
848
            rebefore.activate(plugname)
 
849
            reafter.activate(plugname)
 
850
            saymonitor.activate(plugname)
 
851
            outmonitor.activate(plugname)
 
852
            xmppmonitor.activate(plugname)
 
853
            tests.activate(plugname)
 
854
            outputmorphs.activate(plugname)
 
855
            inputmorphs.activate(plugname)
 
856
        except Exception, ex:
 
857
            handle_exception()
 
858
            return 0
 
859
 
 
860
    def down(self, plugname):
 
861
        self.activated[plugname] = False
 
862
        try:
 
863
            cmnds.disable(plugname)
 
864
            callbacks.disable(plugname)
 
865
            gn_callbacks.disable(plugname)
 
866
            jcallbacks.disable(plugname)
 
867
            rebefore.disable(plugname)
 
868
            reafter.disable(plugname)
 
869
            saymonitor.disable(plugname)
 
870
            outmonitor.disable(plugname)
 
871
            xmppmonitor.disable(plugname)
 
872
            tests.disable(plugname)
 
873
            outputmorphs.disable(plugname)
 
874
            inputmorphs.disable(plugname)
 
875
        except Exception, ex:
 
876
            handle_exception()
 
877
            return 0
 
878
 
 
879
    def unload(self, plugname):
 
880
 
 
881
        """
 
882
            unload plugin.
 
883
 
 
884
            :param plugname: name of the plugin to unload
 
885
            :type plugname: string
 
886
            :rtype: list .. list of unloaded plugins
 
887
 
 
888
            .. literalinclude:: ../../gozerbot/plugins.py
 
889
                :pyobject: Plugins.unload
 
890
 
 
891
        """
 
892
 
 
893
        # call plugins shutdown function if available
 
894
        unloaded = [plugname, ]
 
895
 
 
896
        # recurse if plugin is dir
 
897
        try:
 
898
            plug = self.plugs[plugname]
 
899
 
 
900
            for p in plug.__plugs__:
 
901
                if p == plug:
 
902
                    raise Exception("same plugin name as dir name (%s)" % plugname)
 
903
                unloaded.extend(self.unload(p))
 
904
 
 
905
        except (KeyError, AttributeError):
 
906
            pass
 
907
 
 
908
        # save and unload
 
909
        for plugname in unloaded:
 
910
            self.saveplug(plugname)
 
911
            self.unloadnosave(plugname)
 
912
 
 
913
            try:
 
914
                self.avail.remove(plugname)
 
915
 
 
916
            except ValueError:
 
917
                pass
 
918
 
 
919
        return unloaded
 
920
 
 
921
    def unloadnosave(self, plugname):
 
922
 
 
923
        """
 
924
            unload plugin without saving.
 
925
 
 
926
            :param plugname: name of the plugin to unload
 
927
            :type plugname: string
 
928
            :rtype: list .. list of unloaded plugins
 
929
 
 
930
            .. literalinclude:: ../../gozerbot/plugins.py
 
931
                :pyobject: Plugins.unloadnosave
 
932
 
 
933
        """
 
934
 
 
935
        # call shutdown function
 
936
        try:
 
937
            self.plugs[plugname].shutdown()
 
938
            rlog(10, 'plugins', '%s shutdown called' % plugname)
 
939
 
 
940
        except (AttributeError, KeyError):
 
941
            pass
 
942
 
 
943
        except Exception, ex:
 
944
            handle_exception()
 
945
 
 
946
        # remove from plugallow
 
947
        try:
 
948
            self.plugallow.data.remove(plugname)
 
949
        except (KeyError, ValueError):
 
950
            pass
 
951
 
 
952
        # remove from avail list
 
953
        try:
 
954
            self.avail.remove(plugname)
 
955
        except ValueError:
 
956
            pass
 
957
 
 
958
        # remove from initcalled list
 
959
        try:
 
960
            self.initcalled.remove(plugname)
 
961
        except ValueError:
 
962
            pass
 
963
 
 
964
        # unload commands, RE callbacks, callbacks, monitorsetc.
 
965
        try:
 
966
            cmnds.unload(plugname)
 
967
            callbacks.unload(plugname)
 
968
            gn_callbacks.unload(plugname)
 
969
            jcallbacks.unload(plugname)
 
970
            rebefore.unload(plugname)
 
971
            reafter.unload(plugname)
 
972
            saymonitor.unload(plugname)
 
973
            outmonitor.unload(plugname)
 
974
            xmppmonitor.unload(plugname)
 
975
            tests.unload(plugname)
 
976
            outputmorphs.unload(plugname)
 
977
            inputmorphs.unload(plugname)
 
978
 
 
979
            if self.plugs.has_key(plugname):
 
980
                del self.plugs[plugname]
 
981
 
 
982
        except Exception, ex:
 
983
            handle_exception()
 
984
            return 0
 
985
 
 
986
        rlog(0, 'plugins', '%s unloaded' % plugname)
 
987
        return 1
 
988
 
 
989
    def whereis(self, what):
 
990
 
 
991
        """
 
992
            locate command.
 
993
 
 
994
            :param what: name of command to search
 
995
            :type what: string
 
996
            :rtype: string .. plugin the command is in
 
997
 
 
998
            .. literalinclude:: ../../gozerbot/plugins.py
 
999
                :pyobject: Plugins.whereis
 
1000
 
 
1001
        """
 
1002
 
 
1003
        return cmnds.whereis(what)
 
1004
 
 
1005
    def permoverload(self, funcname, perms):
 
1006
 
 
1007
        """
 
1008
            overload permission of a function.
 
1009
 
 
1010
            :param funcname: name of function to overload permissions of
 
1011
            :type funcname: string
 
1012
            :param perms: permissions to overload
 
1013
            :type perms: list .. list of permissions
 
1014
            :rtype: boolean: whether overload worked or not
 
1015
 
 
1016
            .. literalinclude:: ../../gozerbot/plugins.py
 
1017
                :pyobject: Plugins.permoverload
 
1018
 
 
1019
        """
 
1020
 
 
1021
        if not rebefore.permoverload(funcname, perms):
 
1022
 
 
1023
            if not cmnds.permoverload(funcname, perms):
 
1024
 
 
1025
                if not reafter.permoverload(funcname, perms):
 
1026
                    return False
 
1027
 
 
1028
        return True
 
1029
 
 
1030
    def woulddispatch(self, bot, ievent):
 
1031
 
 
1032
        """
 
1033
            function to determine whether a event would dispatch.
 
1034
 
 
1035
            :param bot: bot on which command is given
 
1036
            :type bot: gozerbot.botbase.BotBase
 
1037
            :param ievent: the event triggering the command
 
1038
            :type ievent: gozerbot.eventbase.EventBase
 
1039
            :rtype: boolean .. whether the dispatch should fire
 
1040
 
 
1041
            .. literalinclude:: ../../gozerbot/plugins.py
 
1042
                :pyobject: Plugins.woulddispatch
 
1043
 
 
1044
        """
 
1045
        #self.needreloadcheck(bot, ievent)
 
1046
        (what, command) = self.dispatchtest(bot, ievent)
 
1047
 
 
1048
        #if what and not what.activate:
 
1049
        #    return False
 
1050
 
 
1051
        if what and command:
 
1052
            return True
 
1053
 
 
1054
        return False
 
1055
 
 
1056
    #@funclocked
 
1057
    def dispatchtest(self, bot, ievent, direct=False):
 
1058
 
 
1059
        """
 
1060
            return (dispatcher, command) on which command should fire.
 
1061
 
 
1062
            :param bot: bot on which command is given
 
1063
            :type bot: gozerbot.botbase.BotBase
 
1064
            :param ievent: the event triggering the command
 
1065
            :type ievent: gozerbot.eventbase.EventBase
 
1066
            :param direct: whether user permission should be checked
 
1067
            :type direct: boolean .. when set user permission is NOT checked
 
1068
            :rtype: tuple .. (dispatcher, command) tuples
 
1069
 
 
1070
            .. literalinclude:: ../../gozerbot/plugins.py
 
1071
                :pyobject: Plugins.dispatchtest
 
1072
        """
 
1073
 
 
1074
        # check for ignore
 
1075
        if shouldignore(ievent.userhost):
 
1076
            return (None, None)
 
1077
 
 
1078
        # check for throttle
 
1079
        if ievent.userhost in bot.throttle:
 
1080
            return (None, None)
 
1081
 
 
1082
        # set target properly
 
1083
        if ievent.txt.find(' | ') != -1:
 
1084
            target = ievent.txt.split(' | ')[0]
 
1085
        elif ievent.txt.find(' && ') != -1:
 
1086
            target = ievent.txt.split(' && ')[0]
 
1087
        else:
 
1088
            target = ievent.txt
 
1089
 
 
1090
        result = []
 
1091
 
 
1092
        # first check for RE before commands dispatcher
 
1093
        com = rebefore.getcallback(target)
 
1094
 
 
1095
        if com and not target.startswith('!'):
 
1096
            com.re = True
 
1097
            result = [rebefore, com]
 
1098
        else:
 
1099
 
 
1100
            # try commands 
 
1101
            if ievent.txt.startswith('!'):
 
1102
                ievent.txt = ievent.txt[1:]
 
1103
 
 
1104
            aliascheck(ievent)
 
1105
            com = cmnds.getcommand(ievent.txt)
 
1106
 
 
1107
            if com:
 
1108
                com.re = False
 
1109
                result = [cmnds, com]
 
1110
                ievent.txt = ievent.txt.strip()
 
1111
 
 
1112
            else:
 
1113
 
 
1114
                # try RE after commands
 
1115
                com = reafter.getcallback(target)
 
1116
                if com:
 
1117
                    com.re = True
 
1118
                    result = [reafter, com]
 
1119
        if result:
 
1120
 
 
1121
            # check for auto registration
 
1122
            if config['auto_register'] and not users.getname(ievent.userhost):
 
1123
                if bot.google:
 
1124
                    users.add(ievent.userhost , [ievent.userhost, ], ['USER', ])
 
1125
                elif not bot.jabber:
 
1126
                    users.add("%s!%s" % (ievent.nick, ievent.userhost) , [ievent.userhost, ], ['USER', ])
 
1127
                    bot.ratelimit(ievent.userhost, 20)
 
1128
                else:
 
1129
                    if ievent.groupchat:
 
1130
                        users.add(ievent.userhost , [ievent.userhost, ], ['USER', ])
 
1131
                        bot.ratelimit(ievent.userhost)
 
1132
                    else:
 
1133
                        users.add(ievent.stripped , [ievent.stripped, ], ['USER', ])
 
1134
                        bot.ratelimit(ievent.stripped, 20)
 
1135
 
 
1136
            # check for anon access
 
1137
            if config['anon_enable'] and not 'OPER' in result[1].perms:
 
1138
                return result
 
1139
 
 
1140
            # check if command is allowed (all-add command)
 
1141
            if com.name in bot.state['allowed'] or getname(com.func) in bot.state['allowed']:
 
1142
                return result
 
1143
 
 
1144
            # check for channel permissions
 
1145
            try:
 
1146
                chanperms = bot.channels[ievent.channel.lower()]['perms']
 
1147
 
 
1148
                for i in result[1].perms:
 
1149
                    if i in chanperms and not ievent.msg:
 
1150
                        ievent.speed = 1
 
1151
                        return result
 
1152
 
 
1153
            except (KeyError, TypeError):
 
1154
                pass
 
1155
 
 
1156
            # if direct is set dont check the user database
 
1157
            if direct:
 
1158
                return result
 
1159
 
 
1160
            # use event.stripped in case of jabber 
 
1161
            if bot.jabber and ievent.jabber:
 
1162
                if not ievent.groupchat or ievent.jidchange:
 
1163
                    if users.allowed(ievent.stripped, result[1].perms):
 
1164
                        return result
 
1165
 
 
1166
            # irc users check
 
1167
            if users.allowed(ievent.userhost, result[1].perms):
 
1168
                return result
 
1169
 
 
1170
        return (None, None)
 
1171
 
 
1172
    def cmnd(self, bot, ievent, timeout=15, response=False, onlyqueues=True):
 
1173
 
 
1174
        """
 
1175
            launch command and wait for result.
 
1176
 
 
1177
            :param bot: bot on which command is given
 
1178
            :type bot: gozerbot.botbase.BotBase
 
1179
            :param ievent: the event triggering the command
 
1180
            :type ievent: gozerbot.eventbase.EventBase
 
1181
            :param timeout: number of seconds to wait for a result
 
1182
            :type timeout: integer
 
1183
            :param response: whether to notify user we are running the command
 
1184
            :type response: string
 
1185
            :rtype: list .. list of results
 
1186
 
 
1187
            .. literalinclude:: ../../gozerbot/plugins.py
 
1188
                :pyobject: Plugins.cmnd
 
1189
 
 
1190
        """
 
1191
        if response:
 
1192
            ievent.reply('launching %s on %s bot' % (ievent.txt, bot.name))
 
1193
        #ii = self.clonedevent(bot, ievent)
 
1194
        #q = Queue.Queue()
 
1195
        #ii.queues.append(q)
 
1196
        #ii.onlyqueues = onlyqueues
 
1197
        q = Queue.Queue()
 
1198
        ievent.queues.append(q)
 
1199
        self.trydispatch(bot, ievent)
 
1200
        return waitforqueue(q, timeout)
 
1201
 
 
1202
    def waitdispatch(self, bot, ievent, direct=False):
 
1203
        
 
1204
        """
 
1205
            dispatch command and wait for results.
 
1206
 
 
1207
            :param bot: bot on which command is given
 
1208
            :type bot: gozerbot.botbase.BotBase
 
1209
            :param ievent: the event triggering the command
 
1210
            :type ievent: gozerbot.eventbase.EventBase
 
1211
            :param direct: whether user permission should be checked
 
1212
            :type direct: boolean .. when set user permission is NOT checked
 
1213
            :rtype: boolean .. whether dispatch succeeded or not
 
1214
 
 
1215
            .. literalinclude:: ../../gozerbot/plugins.py
 
1216
                :pyobject: Plugins.waitdispatch
 
1217
 
 
1218
        """
 
1219
        ievent.threaded = True
 
1220
        return self.trydispatch(bot, ievent, direct, wait=True)
 
1221
 
 
1222
    def trydispatch(self, bot, ievent, direct=False, wait=False):
 
1223
 
 
1224
        """
 
1225
            try to dispatch ievent.
 
1226
 
 
1227
            :param bot: bot on which command is given
 
1228
            :type bot: gozerbot.botbase.BotBase
 
1229
            :param ievent: the event triggering the command
 
1230
            :type ievent: gozerbot.eventbase.EventBase
 
1231
            :param direct: whether user permission should be checked
 
1232
            :type direct: boolean .. when set user permission is NOT checked
 
1233
            :param wait: whether function should wait for results
 
1234
            :type wait: boolean
 
1235
            :rtype: boolean .. whether dispatch succeeded or not
 
1236
 
 
1237
            .. literalinclude:: ../../gozerbot/plugins.py
 
1238
                :pyobject: Plugins.trydispatch
 
1239
 
 
1240
        """
 
1241
 
 
1242
        # test for ignore
 
1243
        if shouldignore(ievent.userhost):
 
1244
            return 0
 
1245
 
 
1246
        # set printto
 
1247
        if ievent.msg:
 
1248
            ievent.printto = ievent.nick
 
1249
        else:
 
1250
            ievent.printto = ievent.channel
 
1251
 
 
1252
        # see if ievent would dispatch
 
1253
        # what is rebefore, cmnds of reafter, com is the command object
 
1254
        # check if redispatcher or commands object needs to be used
 
1255
        #self.needreloadcheck(bot, ievent)
 
1256
 
 
1257
        (what, com) = self.dispatchtest(bot, ievent, direct)
 
1258
 
 
1259
        if what:
 
1260
 
 
1261
            if com.allowqueue:
 
1262
                ievent.txt = ievent.txt.replace(' || ', ' | ')
 
1263
 
 
1264
                if ievent.txt.find(' | ') != -1:
 
1265
 
 
1266
                    if ievent.txt[0] == '!':
 
1267
                        ievent.txt = ievent.txt[1:]
 
1268
                    else:
 
1269
                        self.splitpipe(bot, ievent)
 
1270
                        return
 
1271
 
 
1272
                elif ievent.txt.find(' && ') != -1:
 
1273
                    self.multiple(bot, ievent)
 
1274
                    return
 
1275
 
 
1276
            return self.dispatch(what, com, bot, ievent, wait)
 
1277
 
 
1278
    def dispatch(self, what, com, bot, ievent, wait=False):
 
1279
 
 
1280
        """
 
1281
            do the actual dispatch of event.
 
1282
 
 
1283
            :param what: the dispatcher to dispatch the command on
 
1284
            :type what: gozerbot.redispatcher.REdispatcher or gozerbot.commands.Commands
 
1285
            :param com: the command to dispatch
 
1286
            :type com: gozerbot.redispatcher.REcallback or gozerbot.commands.Command
 
1287
            :param bot: bot on which command is given
 
1288
            :type bot: gozerbot.botbase.BotBase
 
1289
            :param ievent: the event triggering the command
 
1290
            :type ievent: gozerbot.eventbase.EventBase
 
1291
            :param wait: whether function should wait for results
 
1292
            :type wait: boolean
 
1293
            :rtype: boolean .. whether dispatch succeeded or not
 
1294
 
 
1295
            .. literalinclude:: ../../gozerbot/plugins.py
 
1296
                :pyobject: Plugins.dispatch
 
1297
 
 
1298
        """
 
1299
        if bot.stopped:
 
1300
            return False
 
1301
 
 
1302
        # make command options
 
1303
        if com.options:
 
1304
            makeoptions(ievent, com.options)
 
1305
        else:
 
1306
            makeoptions(ievent)
 
1307
 
 
1308
        # make arguments and rest
 
1309
        makeargrest(ievent)
 
1310
        ievent.usercmnd = True
 
1311
        rlog(10, 'plugins', 'dispatching %s for %s' % (ievent.command, ievent.userhost))
 
1312
 
 
1313
        # call dispatch
 
1314
        what.dispatch(com, bot, ievent, wait)
 
1315
        return True
 
1316
 
 
1317
    def clonedevent(self, bot, event):
 
1318
 
 
1319
        """
 
1320
            clone a event.
 
1321
 
 
1322
            
 
1323
            :param bot: bot on which command is given
 
1324
            :type bot: gozerbot.botbase.BotBase
 
1325
            :param ievent: the event triggering the command
 
1326
            :type ievent: gozerbot.eventbase.EventBase
 
1327
            :rtype: gozerbot.eventbase.EventBase
 
1328
 
 
1329
            .. literalinclude:: ../../gozerbot/plugins.py
 
1330
                :pyobject: Plugins.clonedevent
 
1331
 
 
1332
        """
 
1333
 
 
1334
        ie = copy.deepcopy(event)
 
1335
        return ie
 
1336
 
 
1337
 
 
1338
    def multiple(self, bot, ievent):
 
1339
 
 
1340
        """
 
1341
            execute multiple commands.
 
1342
 
 
1343
 
 
1344
            :param bot: bot on which command is given
 
1345
            :type bot: gozerbot.botbase.BotBase
 
1346
            :param ievent: the event triggering the command
 
1347
            :type ievent: gozerbot.eventbase.EventBase
 
1348
 
 
1349
            .. literalinclude:: ../../gozerbot/plugins.py
 
1350
                :pyobject: Plugins.multiple
 
1351
 
 
1352
        """
 
1353
 
 
1354
        for i in ievent.txt.split(' && '):
 
1355
            ie = self.clonedevent(bot, ievent)
 
1356
            ie.txt = i
 
1357
            #self.needreloadcheck(bot, ievent)
 
1358
            self.trydispatch(bot, ie)
 
1359
 
 
1360
    def splitpipe(self, bot, ievent):
 
1361
 
 
1362
        """
 
1363
            execute commands in a pipeline.
 
1364
 
 
1365
            :param bot: bot on which command is given
 
1366
            :type bot: gozerbot.botbase.BotBase
 
1367
            :param ievent: the event triggering the command
 
1368
            :type ievent: gozerbot.eventbase.EventBase
 
1369
 
 
1370
            .. literalinclude:: ../../gozerbot/plugins.py
 
1371
                :pyobject: Plugins.splitpipe
 
1372
 
 
1373
        """
 
1374
 
 
1375
        origqueues = ievent.queues
 
1376
        ievent.queues = []
 
1377
        events = []
 
1378
        txt = ievent.txt.replace(' || ', ' ##')
 
1379
 
 
1380
        # split commands
 
1381
        for i in txt.split(' | '):
 
1382
            item = i.replace(' ##', ' | ')
 
1383
            ie = self.clonedevent(bot, ievent)
 
1384
            ie.userhost = ievent.userhost
 
1385
            ie.onlyqueues = True
 
1386
            ie.txt = item.strip()
 
1387
            #self.needreloadcheck(bot, ie)
 
1388
            events.append(ie)
 
1389
 
 
1390
        # loop over events .. chain queues
 
1391
        prevq = None
 
1392
 
 
1393
        for i in events[:-1]:
 
1394
            q = Queue.Queue()
 
1395
            i.queues.append(q)
 
1396
            if prevq:
 
1397
                i.inqueue = prevq
 
1398
            prevq = q
 
1399
 
 
1400
        events[-1].inqueue = prevq
 
1401
        events[-1].onlyqueues = False
 
1402
 
 
1403
        if origqueues:
 
1404
            events[-1].queues = origqueues
 
1405
 
 
1406
        # check if all commands would dispatch
 
1407
        for i in events:
 
1408
            if not self.woulddispatch(bot, i):
 
1409
                ievent.reply("can't execute %s" % str(i.txt))
 
1410
                return
 
1411
 
 
1412
        # do the dispatch
 
1413
        for i in events:
 
1414
            (what, com) = self.dispatchtest(bot, i)
 
1415
            if what:
 
1416
                self.dispatch(what, com, bot, i)
 
1417
 
 
1418
    def needreloadcheck(self, bot, event, target=None):
 
1419
 
 
1420
        if cmndtable:
 
1421
 
 
1422
            try: 
 
1423
                if target:
 
1424
                    rlog(10, 'plugins', 'target set: %s' % target)
 
1425
                    cmnd = 'target-set'
 
1426
                    plugin = target
 
1427
                else:
 
1428
                    t = event.txt.split()[0]
 
1429
                    cmnd = aliasget(t) or t
 
1430
                    plugin = cmndtable[cmnd]
 
1431
 
 
1432
                rlog(10, 'plugins', 'cmnd: %s plugin: %s' % (cmnd, plugin))
 
1433
 
 
1434
                if self.exist(plugin):
 
1435
                    return
 
1436
 
 
1437
                try:
 
1438
                    self.reload('gozerbot.plugs', plugin)
 
1439
                except ImportError, ex:
 
1440
 
 
1441
                    try:
 
1442
                        self.reload('gplugs', plugin)
 
1443
                    except ImportError, ex:
 
1444
                        if config.get('db_driver') == 'olddb':
 
1445
                            try:
 
1446
                                self.reload('gplugs.olddb', plugin)
 
1447
                            except ImportError, ex: pass
 
1448
                        else:
 
1449
                            try:
 
1450
                                self.reload('gplugs.alchemy', plugin)
 
1451
                            except ImportError, ex: pass
 
1452
                        try:
 
1453
                            self.reload('myplugs', plugin)
 
1454
                        except ImportError, ex:
 
1455
                            return
 
1456
 
 
1457
                rlog(100, 'plugins', 'reloaded %s' % plugin)
 
1458
 
 
1459
            except KeyError, ex:
 
1460
                rlog(10, 'plugins', "can't find plugin to reload for %s" % event.txt.split()[0])
 
1461
 
 
1462
 
 
1463
    def listreload(self, pluglist):
 
1464
 
 
1465
        """
 
1466
            reload list of plugins.
 
1467
 
 
1468
            :param pluglist: list of plugin names
 
1469
            :type pluglist: list
 
1470
            :rtype: list .. list of plugins where reload failed
 
1471
 
 
1472
            .. literalinclude:: ../../gozerbot/plugins.py
 
1473
                :pyobject: Plugins.listreload
 
1474
 
 
1475
        """
 
1476
 
 
1477
        failed = []
 
1478
 
 
1479
        # loop over the plugin list and reload them
 
1480
        for what in pluglist:
 
1481
            splitted = what[:-3].split(os.sep)
 
1482
            mod = '.'.join(splitted[:-1])
 
1483
 
 
1484
            if not mod:
 
1485
                if config.get('db_driver') == "olddb":
 
1486
                    mod = "gplugs.olddb"
 
1487
                elif config.get("db_driver") == "alchemy":
 
1488
                    mod = "gplugs.alchemy"
 
1489
                else:
 
1490
                    mod = 'gplugs'
 
1491
 
 
1492
            plug  = splitted[-1]
 
1493
 
 
1494
            # reload the plugin
 
1495
            try:
 
1496
                self.reload(mod, plug)
 
1497
 
 
1498
            except Exception, ex:
 
1499
                failed.append(what)
 
1500
 
 
1501
        return failed
 
1502
 
 
1503
## INIT SECTION
 
1504
 
 
1505
# THE plugins object
 
1506
plugins = Plugins()
 
1507
 
 
1508
## END INIT
 
1509