def add(self, bot, **kwargs): """ add a nickserv entry. """ options = { 'nickserv': 'NickServ', 'identify': 'IDENTIFY', } options.update(kwargs) assert options.has_key('password'), 'A password must be set' for key in options.keys(): Pdod.set(self, bot.name, key, options[key]) self.save()
class Cloud(ThreadLoop): def __init__(self): ThreadLoop.__init__(self, 'cloud') self.datadir = datadir + os.sep + 'plugs' + os.sep + 'cloud' self.nodes = {} self.state = Pdod(self.datadir + os.sep + 'state') self.startup = Pdod(self.datadir + os.sep + 'startup') if not self.state.has_key('ignore'): self.state['ignore'] = [] if not self.state.has_key('names'): self.state['names'] = {} if not self.startup.has_key('start'): self.startup['start'] = {} self.enabled = False self.running = False def addifping(self, name, url): if not url.endswith('/'): url += '/' node = Node(name, url) def cb(client, result): if result.error: rlog(0, url, 'failed to receive pong .. not adding: %s' % \ result.error) return if 'pong' in result.data: self.add(name, url) else: rlog(0, url, 'invalid ping data') client = Client(url + 'gozernet/ping').addcb(cb) client.get() def add(self, name, url, persist=True): if not url.endswith('/'): url += '/' node = Node(name, url) self.nodes[url] = node self.state.set('names', name, url) if persist: self.persist(name, url) rlog(0, url, 'added %s node <%s>' % (name, url)) return self.nodes[url] def start(self, regname, regport, booturl=None): ThreadLoop.start(self) self.enabled = True for name, url in self.startup['start'].iteritems(): self.add(name, url) def cb(client, result): if result.error: rlog(10, booturl, 'boot error: %s' % result.error) else: rlog(10, booturl, 'boot result: %s' % result.data) self.boot(regname, regport, booturl, cbin=cb) def handle(self, *args): asyncore.loop() def persist(self, name, url): try: if self.startup['start'][name] == url: return except KeyError: pass self.startup.set('start', name, url) self.startup.save() def get(self, url): return self.nodes[url] def byname(self, name): try: url = self.state['names'][name] if url: return self.get(url) except KeyError: return None def remove(self, id): target = self.get(id) if not target: return del self.state['names'][target.name] del self.nodes[id] def unpersist(self, url): try: del self.startup['start'][url] self.startup.save() except KeyError: pass def ignore(self, url): self.state['ignore'].append(url) def unignore(self, url): self.state.data['ignore'].remove(url) self.state.save() def doget(self, mount, *args, **kwargs): self.put('go') for url, node in self.nodes.iteritems(): node.doget(mount, *args, **kwargs) def dopost(self, mount, *args, **kwargs): self.put('go') for url, node in self.nodes.iteritems(): node.dopost(mount, *args, **kwargs) def getnodes(self): result = [] for url, node in self.nodes.iteritems(): result.append((node.name, url)) return result def getname(self, url): return self.get(url).name def addrecord(self, regname, url, cbin=None): rlog(0, regname, 'sending addrecord request') def cb(client, result): if result.error: rlog(10, url, 'addrecord error: %s' % result.error) else: rlog(10, url, 'record added') client = Client(url + '/gozernet/+addrecord').addcb(cb) if cbin: client.addcb(cbin) client.post(name=regname) return client def join(self, regname, regport, url, cbin=None): rlog(0, regname, 'joining on port %s' % regport) def cb(client, result): if result.error: rlog(0, url, 'join error: %s' % result.error) else: rlog(0, url, 'joined') client = Client(url + '/gozernet/+join').addcb(cb) if cbin: client.addcb(cbin) client.post(name=regname, port=regport) self.addrecord(regname, url, cbin) return client def joinall(self, regname, regport, cbin=None): for url, node in self.nodes.iteritems(): self.join(regname, regport, url, cbin) def boot(self, regname, regport, url=None, cbin=None): rlog(10, 'cloud', 'booting') if url: self.sync(url, cbin) else: self.sync('http://gozerbot.org:10101', cbin) def fullboot(self, cbin=None): teller = 0 threads = [] for node in self.nodes.values(): self.sync(node.url, False, cbin) teller += 1 return teller def sync(self, url, throw=True, cbin=None): """ sync cache with node """ def cb(client, result): if result.error: rlog(10, url, "can't sync: %s" % result.error) return for node in result.data: gnode = self.add(node[0], node[1]) gnode.synced = time.time() client = Client('%s/gozernet/nodes/' % url).addcb(cb) if cbin: client.addcb(cbin) client.get() def size(self): return len(self.nodes) def list(self): res = [] for node in self.nodes.values(): res.append(str(node)) return res def names(self): return self.state['names'].keys()