commit 5da1c15ba0c175a6b2cba3219a1407369996d79d
parent 326d293707557609967ddc616fac1e1d7c0a8a72
Author: Marcel <mtrnord1@gmail.com>
Date: Fri, 27 Jan 2017 16:18:46 +0100
try to fix CTRL+C problem (not fixed) and some other changes
Diffstat:
| M | __init__.py | | | 287 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------- |
1 file changed, 197 insertions(+), 90 deletions(-)
diff --git a/__init__.py b/__init__.py
@@ -2,138 +2,245 @@
import telegram.ext
from telegram.ext import Updater, Filters
from slackclient import SlackClient
-import json, os.path, sys, traceback, functools, time, shutil
+import json, os.path, sys, traceback, functools, time, shutil, logging, logging.config, argparse, signal
from multiprocessing import Pool
+logger = logging.getLogger(__name__)
+
#Import internal Modules that are needed
import config
class Core:
def __init__(self):
try:
- self.config = config.Config("config/config.json")
+ self.config = config.Config(os.path.join('config', 'config.json'))
except ValueError:
logging.exception("failed to load config, malformed json")
sys.exit()
try:
- self.memory = config.Memory("config/memory.json")
+ self.memory = config.Memory(os.path.join('config', 'memory.json'))
except ValueError:
logging.exception("failed to load config, malformed json")
sys.exit()
+
+ try:
+ api_key = self.config.get_by_path(['SLACK_API_KEY'])
+ self.sc = SlackClient(api_key)
+ except Exception as e:
+ traceback.print_exc()
+
+ try:
+ api_key = self.config.get_by_path(['TELEGRAM_API_KEY'])
+ if not self.memory.exists(['tg_sl-sync']):
+ logger.warn('tg_sl-sync missing...')
+ self.memory.set_by_path(['tg_sl-sync'], {'sl2tg':{}, 'tg2sl': {}})
+ self.memory.save()
+ self.updater = Updater(api_key)
+ except Exception as e:
+ traceback.print_exc()
+
+ def run(self):
+ pool = Pool(2)
+ try:
+ telegram = pool.apply_async(self.telegram_init(), [])
+ slack = pool.apply_async(self.slack_init(), [])
+ pool.close()
+ telegram.join()
+ slack.join()
+ except KeyboardInterrupt:
+ logger.info("Caught KeyboardInterrupt, terminating workers")
+ pool.terminate()
+
def slack_init(self):
- api_key = self.config.get_by_path(['SLACK_API_KEY'])
- sc = SlackClient(api_key)
-
- print("slack starting...")
- if sc.rtm_connect():
- last_ping = int(time.time())
- while True:
- rtm_flow = sc.rtm_read()
- if rtm_flow:
- type = rtm_flow[0]['type']
- if type == "message":
- if "subtype" in rtm_flow[0]:
- subtype = rtm_flow[0]['subtype']
- if subtype == "message_deleted":
- print("something deleted")
+ try:
+ logger.info("Slack Bot starting...")
+ if self.sc.rtm_connect():
+ last_ping = int(time.time())
+ while True:
+ rtm_flow = self.sc.rtm_read()
+ if rtm_flow:
+ type = rtm_flow[0]['type']
+ if type == "message":
+ if "subtype" in rtm_flow[0]:
+ subtype = rtm_flow[0]['subtype']
+ if subtype == "message_deleted":
+ logger.debug("something deleted")
+ else:
+ logger.debug(rtm_flow)
else:
- print(rtm_flow)
- else:
- print(rtm_flow)
- now = int(time.time())
- if now > last_ping + 30:
- sc.server.ping()
- last_ping = now
- time.sleep(.1)
- else:
- print("Connection Failed, invalid token?")
+ logger.debug(rtm_flow)
+ now = int(time.time())
+ if now > last_ping + 30:
+ self.sc.server.ping()
+ last_ping = now
+ time.sleep(.1)
+ else:
+ logger.critical("Connection Failed, invalid token?")
+ except KeyboardInterrupt:
+ sys.exit()
- def telegram_init(self):
- def sync_handler(bot, update):
- print(update.message.text)
+ def Hsyc(self, bot, update):
+ try:
+ tg2sl = self.memory.get_by_path(['tg_sl-sync'])['tg2sl']
+ sl2tg = self.memory.get_by_path(['tg_sl-sync'])['sl2tg']
+ except Exception as e:
+ traceback.print_exc()
+ update.message.reply_text('Failed to get memory. Please contact Admin!')
+ if update.message.chat_id in tg2sl:
+ update.message.reply_text('This channel is already synced!')
+ logger.debug(update.message.text)
+
+ def Cslacksync(self, bot, update):
+ params = update.message.text.split()
+ logger.debug(params[1])
- def slacksync(bot, update):
- params = update.message.text.split()
- print(params[1])
+ try:
+ tg2sl = self.memory.get_by_path(['tg_sl-sync'])['tg2sl']
+ sl2tg = self.memory.get_by_path(['tg_sl-sync'])['sl2tg']
+ except Exception as e:
+ traceback.print_exc()
+ update.message.reply_text('Failed to get memory. Please contact Admin!')
+
+ update.message.reply_text(tg2sl)
+ if update.message.chat_id in tg2sl:
+ print("in it")
+ update.message.reply_text('This channel is already synced!')
+ else:
+ logger.debug("got sync request...")
try:
- tg2sl = self.memory.get_by_path(['tg_sl-sync'])['tg2sl']
- sl2tg = self.memory.get_by_path(['tg_sl-sync'])['sl2tg']
+ tg2sl[str(update.message.chat_id)] = params[1]
+ sl2tg[str(params[1])] = str(update.message.chat_id)
+ new_memory = {'tg2sl': tg2sl, 'sl2tg': sl2tg}
+ self.memory.set_by_path(['tg_sl-sync'], new_memory)
+ self.memory.save()
+ update.message.reply_text('Saved sync!')
+ logger.debug("sync saved")
except Exception as e:
- #print(e)
- exc_type, exc_obj, exc_tb = sys.exc_info()
- fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
- print(exc_type, fname, exc_tb.tb_lineno)
traceback.print_exc()
- update.message.reply_text('Failed to get memory. Please contact Admin!')
+ update.message.reply_text('Failed to save sync!')
- if tg2sl:
- print("works")
+ def telegram_init(self):
+ try:
+ logger.info("Telegram starting...")
+ self.updater.dispatcher.add_handler(telegram.ext.MessageHandler(Filters.text, self.Hsyc))
+ self.updater.dispatcher.add_handler(telegram.ext.CommandHandler('slacksync', self.Cslacksync))
+ self.updater.start_polling()
+ except KeyboardInterrupt:
+ sys.exit()
- if update.message.chat_id in tg2sl:
- print("tretre")
- else:
- print("got sync request...")
+def configure_logging(args):
+ """Configure Logging
+ If the user specified a logging config file, open it, and
+ fail if unable to open. If not, attempt to open the default
+ logging config file. If that fails, move on to basic
+ log configuration.
+ """
+
+ log_level = 'DEBUG' if args.debug else 'INFO'
+
+ default_config = {
+ 'version': 1,
+ 'disable_existing_loggers': False,
+ 'formatters': {
+ 'console': {
+ 'format': '%(asctime)s %(levelname)s %(name)s: %(message)s',
+ 'datefmt': '%H:%M:%S'
+ },
+ 'default': {
+ 'format': '%(asctime)s %(levelname)s %(name)s: %(message)s',
+ 'datefmt': '%Y-%m-%d %H:%M:%S'
+ }
+ },
+ 'handlers': {
+ 'console': {
+ 'class': 'logging.StreamHandler',
+ 'stream': 'ext://sys.stdout',
+ 'level': 'INFO',
+ 'formatter': 'console'
+ },
+ 'file': {
+ 'class': 'logging.FileHandler',
+ 'filename': args.log,
+ 'level': log_level,
+ 'formatter': 'default',
+ }
+ },
+ 'loggers': {
+ # root logger
+ '': {
+ 'handlers': ['file', 'console'],
+ 'level': log_level
+ },
+
+ # asyncio's debugging logs are VERY noisy, so adjust the log level
+ 'asyncio': {'level': 'WARNING'},
+ 'irde_bot': {'level': 'ERROR'}
+ }
+ }
+
+ logging_config = default_config
+
+ # Temporarily bring in the configuration file, just so we can configure
+ # logging before bringing anything else up. There is no race internally,
+ # if logging() is called before configured, it outputs to stderr, and
+ # we will configure it soon enough
+ bootcfg = config.Config(os.path.join('config', 'config.json'))
+ if bootcfg.exists(["logging.system"]):
+ logging_config = bootcfg["logging.system"]
+
+ if "extras.setattr" in logging_config:
+ for class_attr, value in logging_config["extras.setattr"].items():
+ try:
+ [modulepath, classname, attribute] = class_attr.rsplit(".", maxsplit=2)
try:
- tg2sl[str(update.message.chat_id)] = params[1]
- sl2tg[str(params[1])] = str(update.message.chat_id)
- new_memory = {'tg2sl': tg2sl, 'sl2tg': sl2tg}
- self.memory.set_by_path(['tg_sl-sync'], new_memory)
- self.memory.save()
- update.message.reply_text('Saved sync!')
- except Exception as e:
- #print(e)
- exc_type, exc_obj, exc_tb = sys.exc_info()
- fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
- print(exc_type, fname, exc_tb.tb_lineno)
- traceback.print_exc()
- update.message.reply_text('Failed to save sync!')
- print("sync saved")
-
- print("Telegram starting...")
- api_key = self.config.get_by_path(['TELEGRAM_API_KEY'])
- if not self.memory.exists(['tg_sl-sync']):
- print('tg_sl-sync missing...')
- self.memory.set_by_path(['tg_sl-sync'], {'sl2tg':{}, 'tg2sl': {}})
- self.memory.save()
- updater = Updater(api_key)
- updater.dispatcher.add_handler(telegram.ext.MessageHandler(Filters.text, sync_handler))
- updater.dispatcher.add_handler(telegram.ext.CommandHandler('slacksync', slacksync))
-
-
- updater.start_polling()
- # updater.idle()
-
- def stop(self):
- print("Caught keyboard interrupt. Canceling tasks...")
-
- def init(self):
- pool = Pool()
- telegram = pool.apply_async(self.telegram_init(), []) # evaluate "solve1(A)" asynchronously
- slack = pool.apply_async(self.slack_init(), []) # evaluate "solve2(B)" asynchronously
+ setattr(class_from_name(modulepath, classname), attribute, value)
+ except ImportError:
+ logging.error("module {} not found".format(modulepath))
+ except AttributeError:
+ logging.error("{} in {} not found".format(classname, modulepath))
+ except ValueError:
+ logging.error("format should be <module>.<class>.<attribute>")
+
+ logging.config.dictConfig(logging_config)
+
+ logger = logging.getLogger()
+ if args.debug:
+ logger.setLevel(logging.DEBUG)
if __name__ == "__main__":
+ default_log_path = os.path.join('config', 'irde_bot.log')
+
+ parser = argparse.ArgumentParser(prog='irde_bot',
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+ parser.add_argument('--log', default=default_log_path,
+ help='log file path')
+ parser.add_argument('-d', '--debug', action='store_true',
+ help='log detailed debugging messages')
+ args = parser.parse_args()
+
if os.path.isdir("config"):
- if not os.path.isfile('config/config.json'):
+ if not os.path.isfile(os.path.join('config', 'config.json')):
try:
- shutil.copy('defaults/config.json', "config/config.json")
+ shutil.copy(os.path.join('config', 'config.json'), os.path.join('config', 'config.json'))
sys.exit('Please set Api Keys')
except (OSError, IOError) as e:
sys.exit('Failed to copy default config file: {}'.format(e))
- if not os.path.isfile('config/memory.json'):
+ if not os.path.isfile(os.path.join('config', 'config.json')):
try:
- shutil.copy('defaults/memory.json', "config/memory.json")
+ shutil.copy(os.path.join('defaults', 'memory.json'), os.path.join('config', 'memory.json'))
except (OSError, IOError) as e:
sys.exit('Failed to copy default memory file: {}'.format(e))
else:
os.mkdir("config")
- if not os.path.isfile('config/config.json'):
+ if not os.path.isfile(os.path.join('config', 'config.json')):
try:
- shutil.copy('defaults/config.json', "config/config.json")
+ shutil.copy(os.path.join('defaults', 'config.json'), os.path.join('config', 'config.json'))
sys.exit('Please set Api Keys')
except (OSError, IOError) as e:
sys.exit('Failed to copy default config file: {}'.format(e))
+ configure_logging(args)
core = Core()
- core.init()
+ core.run()