#!/usr/bin/python import time import random import datetime import re import ConfigParser import telepot import json import sys import os import argparse from telepot.loop import MessageLoop from watchdog.observers import Observer from watchdog.events import PatternMatchingEventHandler version = 0.1 def writeconfig(): global configParser with open('telegram-notify.conf', 'wb') as configfile: configParser.write(configfile) def handle(msg): global configParser global chat_ids pair_pin = configParser.get('general', 'pair_pin') chat_id = msg['chat']['id'] username = msg['chat']['username'] firstname = msg['chat']['first_name'] lastname = msg['chat']['last_name'] command = msg['text'] param = '' paired_user = [x for x in chat_ids if x['id'] == chat_id] is_paired = len(paired_user) > 0 # if text starts with '/' then it's a command if re.match(r'^/',msg['text']): command = re.sub(r"\s.*",'',msg['text']) param = re.sub(r"^([^\s]+)\s","",msg['text']) print '\n\nUser %s sent command: %s (%s)' % (username, command, param) if command == '/pair': if is_paired: bot.sendMessage(chat_id, 'You\'re already paired.') elif param == pair_pin: chat={ 'username': username, 'firstname': firstname, 'lastname': lastname, 'id': chat_id } chat_ids.append(chat) section = 'id-' + str(chat_id) if not configParser.has_section(section): configParser.add_section(section) configParser.set(section, 'username', username) configParser.set(section, 'firstname', firstname) configParser.set(section, 'lastname', lastname) writeconfig() bot.sendMessage(chat_id, 'Pairing ok.') else: bot.sendMessage(chat_id, 'Pairing failed: wrong pin.') elif command == '/newpin': if not is_paired: bot.sendMessage(chat_id, 'You\'re not allowed to do that. You have to pair first.') elif param != '': pair_pin = param configParser.set('general', 'pair_pin', pair_pin) writeconfig() bot.sendMessage(chat_id, 'The new pin is: %s' % pair_pin) else: bot.sendMessage(chat_id, 'Please specify the new pin.') elif command == '/unpair': if not is_paired: bot.sendMessage(chat_id, 'You\'re not allowed to do that. You have to pair first.') else: chat_ids[:] = [x for x in chat_ids if x['id'] != chat_id] section = 'id-' + str(chat_id) configParser.remove_section(section) writeconfig() bot.sendMessage(chat_id, 'Bye.') elif command == '/users': if not is_paired: bot.sendMessage(chat_id, 'You\'re not allowed to do that. You have to pair first.') else: users = [x['username'] + ' (' + x['firstname'] + ' ' + x['lastname'] + ')\n' for x in chat_ids] bot.sendMessage(chat_id, 'Paired users:\n' + "".join([str(i) for i in users]) ) elif command == '/start': bot.sendMessage(chat_id, 'Started:\n' ) elif command == '/help': bot.sendMessage(chat_id, 'Help:\n' ) elif command == '/settings': bot.sendMessage(chat_id, 'Settings:\n' ) def processFile(filename): global chat_ids if re.match(r'.*jpg$',filename): for c in chat_ids: try: r=bot.sendPhoto(c['id'], open(filename, 'rb')) os.remove(filename) except: time.sleep(10) if re.match(r'.*txt$',filename): for c in chat_ids: try: with open(filename,'r') as f: r=bot.sendMessage(c['id'], f.read()) os.remove(filename) except: time.sleep(10) class FilesChangedHandler(PatternMatchingEventHandler): patterns = ["*.jpg", "*.txt"] def process(self, event): """ event.event_type 'modified' | 'created' | 'moved' | 'deleted' event.is_directory True | False event.src_path path/to/observed/file """ global bot if event.event_type=='created': processFile(event.src_path) def on_modified(self, event): self.process(event) def on_created(self, event): self.process(event) def checkFiles(): l=os.listdir(spool_dir) for f in l: processFile("%s/%s" % (spool_dir,f) ) configFile = '/etc/telegram-notify/telegram-notify.conf' if not os.path.isfile(configFile) or not os.access(configFile, os.R_OK): configFile = './telegram-notify.conf' if not os.path.isfile(configFile) or not os.access(configFile, os.R_OK): configFile = '' parser = argparse.ArgumentParser(description='Daemon for Telegram notification management') parser.add_argument('-c', '--config', nargs='?', help='start with specified config file') parser.add_argument('-V', '--version', action='store_true', help='show program version and quit') args = parser.parse_args() if args.version: print 'telegram-notify version %s - Copyright (C) 2018 by Paolo Asperti.' % version sys.exit(0) if args.config: if not os.path.isfile(args.config): print 'specified config file doesn\'t exists or is not a file' sys.exit(1) if not os.access(args.config, os.R_OK): print 'specified config file is not readable' sys.exit(1) if not os.access(args.config, os.W_OK): # TODO: logging print 'WARNING: specified config file is not wriable' configFile = args.config if configFile == '': print 'no config file available' sys.exit(1) # TODO: logging print 'INFO: using config file: %s' % configFile configParser = ConfigParser.RawConfigParser() configParser.read(configFile) spool_dir = configParser.get('general', 'spool_dir') if not os.path.isdir(spool_dir): print "spool directory (%s) doesn't exists or is not a directory!" % spool_dir sys.exit(1) if not os.access(spool_dir, os.W_OK): print "spool directory (%s) is not writable!" % spool_dir sys.exit(1) chat_ids=[] print "Allowed users: " for p in configParser.sections(): if re.match('^id-.*',p): chat_id={ 'username': configParser.get(p,'username'), 'firstname': configParser.get(p,'firstname'), 'lastname': configParser.get(p,'lastname'), 'id': int(re.sub(r'^id-','',p)) } chat_ids.append(chat_id) print(" - (%s) %s %s" % (chat_id['username'],chat_id['firstname'],chat_id['lastname']) ) token = configParser.get('general', 'token') bot = telepot.Bot(token) MessageLoop(bot, handle).run_as_thread() print 'I am listening ...' checkFiles() observer = Observer() observer.schedule(FilesChangedHandler(), path=spool_dir) observer.start() while 1: time.sleep(10) checkFiles()