#!/usr/bin/python3 # -*- coding: utf-8 -*- # file: ./plugins/status.py # date: 23.07.2020 # desc: status plugin ... grabs the krautspaces door status from # https://status.kraut.space/api and returns the result. import urllib3 import codecs import json import time import threading import logging logging = logging.getLogger() from manager import Plugin lock = threading.Lock() class Plugin(Plugin): __module = 'status' __command = 'status' __description = 'Deliver krautspace door status' @staticmethod def get_module(): return Plugin.__module @staticmethod def get_command(): return Plugin.__command @staticmethod def get_description(): return Plugin.__description def __init__(self, callback=None): self.callback = callback def help(self): return ('!status grabs the doorstatus from https://status.kraut.space ' 'and delivers him to MUC.\nSyntax: !status') def run(self, stanza): ''' Starts a thread to grab krautspaces door status und returns immediately. ''' logging.debug('Start thread for status') api_thread = ApiThread(self.callback) api_thread.run() logging.debug('Status thread started') class ApiThread(threading.Thread): ''' The thread who fetched, parsed and returns the door status. ''' def __init__(self, callback): threading.Thread.__init__(self) self.callback = callback def run(self): ''' Runs the thread. ''' api_page = self.get_file() if api_page == None: self.go_back('Error while connecting API') else: status = api_page.status logging.debug("Page returns {}".format(status)) if status == 200: message = self.parse_api(api_page.data) self.go_back(message) else: self.go_back('Error while fetching API') def get_file(self): ''' Grabs the API file, parse it and returns a json ... otherwise none. returns: json or none ''' url = 'https://status.kraut.space/api' logging.debug('Try to fetch {}'.format(url)) http = urllib3.PoolManager() try: api_page = http.request('Get', url) logging.debug('{}: successfull fetched'.format(url)) except: logging.debug('{}: failed to fetch'.format(url)) return None return api_page def parse_api(self, page_data): ''' Extracts needed data from given json and create the message. param 1: json returns: string ''' timestamp = None status = None message = None json_string = page_data.decode('utf-8') json_dict = json.loads(json_string) status = json_dict['state']['open'] unixtime = json_dict['state']['lastchange'] timestamp = time.strftime('%d.%m.%Y %H:%M', time.localtime(unixtime)) logging.debug('Open: {}; Time: {}; Last Change: {}'.format( status, timestamp, unixtime)) if status is True: message = 'Space is open since {}.'.format(timestamp) elif status is False: message = 'Space is closed since {}.'.format(timestamp) else: message = 'Invalid status: "{}"'.format(status) return message def go_back(self, message): ''' param 1: string ''' lock.acquire() try: self.callback(message) finally: lock.release()