telegram-notify/telegram-notify.py

234 lines
6.9 KiB
Python

#!/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()