async def check_state_change(): ts_state, _ = get_space() state = store.get('open') if str(ts_state) != str(state, 'utf-8'): store.set('open', ts_state) await update_spaceapi(ts_state) say_state(ts_state)
async def check_wiki(): wiki_key = 'shack.wikichange' while True: await asyncio.sleep(60) try: async with aiohttp.ClientSession() as session: with async_timeout.timeout(30): async with session.get( 'http://wiki.shackspace.de/feed.php') as resp: feed = feedparser.parse(await resp.text()) latest_change = feed.entries[0] last_change = store.get(wiki_key) last_change = last_change.decode( ) if last_change else '' store.set(wiki_key, latest_change['id']) if last_change != latest_change['id']: response = 'Page changed: ' + latest_change['title'] response += ' by ' + latest_change['authors'][0][ 'name'] if latest_change.get('authors') else '' response += ' – ' + latest_change['links'][0][ 'href'] bot.say('#shackspace', response) except (asyncio.CancelledError, asyncio.TimeoutError): print('timeout')
def set_space(state): """ use when setting the space manually """ # seconds ince epoch if state == _OPEN: store.set('door_irc_open_timestamp', datetime.now().timestamp()) else: store.set('door_irc_closed_timestamp', datetime.now().timestamp())
def get_image_hash(self, resource_id, hasher=sha256, blocksize=4096): start_t = time() image_detail = self.inspect_image(resource_id) image_id = image_detail['Id'] size = image_detail['Size'] image = self.get_image(resource_id) f_handler, filename = tempfile.mkstemp(suffix='.tar', text=False) with open(filename, 'wb') as f: f.write(image.data) tar_file = tarfile.open(fileobj=open(filename)) members = tar_file.getmembers() hashes = [] for m in members: f = tar_file.extractfile(m) if f is None: continue h = md5() while True: buf = f.readline(blocksize) if not buf: break h.update(buf) hashes.append(h.hexdigest()) os.remove(filename) h = hasher() h.update("$".join(sorted(hashes))) rt = h.hexdigest() end_t = time() b = Bucket(_S.get('RECENT_HASH_TIME', []), RECENT_HASH_TIME_BUCKET_SIZE) b.push((size, (end_t - start_t))) _S.set('RECENT_HASH_TIME', b) if _S.get(image_id) != rt: _S.set(image_id, rt) return rt
async def check_blog(): blog_key = 'shack.blogpost' while True: await asyncio.sleep(60) try: async with aiohttp.ClientSession() as session: with async_timeout.timeout(30): async with session.get( 'http://blog.shackspace.de/?feed=rss2') as resp: soup = bs4.BeautifulSoup(await resp.text(), 'lxml-xml') latest_post = soup.rss.find('item') last_post = store.get(blog_key) last_post = last_post.decode() if last_post else '' store.set(blog_key, latest_post.link.text) if last_post != latest_post.link.text: bot.say( '#shackspace', 'New blog post! »{title}« by {author}: {url}'. format( title=latest_post.title.text, author=latest_post.find('creator').text, url=latest_post.link.text, )) except (asyncio.CancelledError, asyncio.TimeoutError): print('timeout')
def post(self): args = reqparse.RequestParser() \ .add_argument('address') \ .parse_args() default_address = args['address'] _S.set('default_address', default_address) return dict(default_address=default_address)
def get_image_hash_with_cache(self, resource_id, *args): image_id = self.image_id(resource_id) h = _S.get(image_id) if not h: h = self.get_image_hash(resource_id, *args) _S.set(image_id, h) return h
def decrement_karma(target, karma): target = target.lower() current = get_karma(target, karma) if not current: store.set('karma.{}§{}'.format(target, karma), -1) else: store.decr('karma.{}§{}'.format(target, karma), 1) update_scores(target, karma, current - 1) return current - 1
def show_karma(parsed, user, target, text): text = text[len('.karma'):].strip().lower() if not text: try: top = json.loads( store.get('karma.top.{}'.format(target)).decode()) or dict() bottom = json.loads( store.get( 'karma.bottom.{}'.format(target)).decode()) or dict() except AttributeError: store.set('karma.top.{}'.format(target), dict()) store.set('karma.bottom.{}'.format(target), dict()) else: user_karma = get_karma(target, user.nick) response = 'Top karma: {}. Flop karma: {}. Karma for {}: {}'.format( ', '.join('{}: {}'.format(key, value) for key, value in top.items()), ', '.join('{}: {}'.format(key, value) for key, value in bottom.items()), user.nick, user_karma, ) bot.say(target, response) else: to_print = [] in_literal = [] for word in text.split(): if in_literal: if word.endswith('"'): in_literal.append(word[:-1]) to_print.append(' '.join(in_literal)) in_literal = [] else: in_literal.append(word) elif word.startswith('"'): if word.endswith('"'): to_print.append(word[1:-1]) else: in_literal.append(word[1:]) else: to_print.append(word) response = ', '.join( '{}: {}'.format(word, get_karma(target, word.lower())) for word in to_print) bot.say(target, response)
async def wait_kick_space(): """ The external device will publish a mqtt event. This function handles this event. """ while True: mqcli = MQTTClient() await mqcli.connect('mqtt://localhost/') await mqcli.subscribe([ ('afra/door', QOS_2), ]) await mqcli.deliver_message() # TODO: ignoring the payload for now store.set('door_kicked_timestamp', datetime.now().timestamp()) await check_state_change()
def _handle_repeat(url, bot, target): bare_url = '{0.netloc}{0.path}?{0.query}'.format(urlsplit(url)) redis_string = 'urls.{}§{}'.format(target, bare_url) count = int(store.get(redis_string) or 0) if count: if count == 1: message = 'This url has been posted already, lame!' elif count == 2: message = 'This url has been posted twice before, must be important.' else: message = 'This url has been posted {} times before.'.format(count) bot.say(target, message) store.incr(redis_string, 1) else: store.set(redis_string, 1)
def get_bound_orgs_with_local_eth_accounts(self): eth_accounts = web3_client().eth.accounts bound_org = _S.get('BOUND_ORG') if bound_org and _S.get('LAST_ETH_ACCOUNTS') == eth_accounts: return bound_org bound_org = {} for o, addrs in self.get_all_bound_addresses().items(): bound_addrs = [] for a in addrs: if a in eth_accounts: bound_addrs.append(a) if bound_addrs: bound_org[o] = bound_addrs if bound_org: _S.set('BOUND_ORG', bound_org) _S.set('LAST_ETH_ACCOUNTS', eth_accounts) return bound_org
def update_scores(target, karma, value): try: top = json.loads(store.get( 'karma.top.{}'.format(target)).decode()) or dict() bottom = json.loads( store.get('karma.bottom.{}'.format(target)).decode()) or dict() except: top = dict() bottom = dict() top.update({karma: value}) bottom.update({karma: value}) top = dict( sorted(top.items(), key=operator.itemgetter(1), reverse=True)[:3]) bottom = dict( sorted(bottom.items(), key=operator.itemgetter(1), reverse=False)[:3]) store.set('karma.top.{}'.format(target), json.dumps(top)) store.set('karma.bottom.{}'.format(target), json.dumps(bottom))
async def check_site(): while True: await asyncio.sleep(60) status = await _is_open() if status is True: new = 'open' elif status is False: new = 'closed' else: new = 'no data' old = store.get('shack.state') old = old.decode() if old else '' if status is not None: store.set('shack.state', new) if 'open' in new and 'closed' in old: bot.say('#shackspace', 'The shack has been opened.') elif 'open' in old and 'closed' in new: bot.say('#shackspace', 'The shack has been closed.')
def default_namespace(self, value): _S.set('DEFAULT_USER_NAME_SPACE', value)