tanabata/bot/tfm-tb.py

179 lines
5.4 KiB
Python

#!../venv/bin/python3
import telebot
import sys
import os
import atexit
import signal
from time import sleep
from socket import getaddrinfo
from requests import get
from subprocess import check_output
import logging as log
from json import loads as ljson
from datetime import datetime
import pytz
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import api.tfm_api as tfm_api
# set logger
log.basicConfig(
level=log.INFO,
filename="/var/log/tfm/tfm-tb.log",
filemode="a",
format="%(asctime)s | %(threadName)s | %(levelname)s | %(message)s"
)
# actions to do on exit
exit_actions = []
defer = exit_actions.append
def finalize(*args):
exec('\n'.join(exit_actions))
os._exit(0)
atexit.register(finalize)
signal.signal(signal.SIGTERM, finalize)
signal.signal(signal.SIGINT, finalize)
# initialize TFM API
try:
tfm_api.Initialize()
tfm = tfm_api.TSession("af6dde9b-7be1-46f2-872e-9a06ce3d3358")
except Exception as e:
log.critical(f"failed to initialize TFM API: {str(e)}")
exit(1)
# initialize bot
tfm_tb = telebot.TeleBot(tfm_api.conf["Telebot"]["Token"])
TZ = pytz.timezone("Europe/Moscow")
# check if user is authorized and if chat exists in db
def check_chat(message):
return message.from_user.id == 924090228
# file handler
@tfm_tb.message_handler(content_types=['document', 'photo', 'audio', 'video', 'voice', 'animation'])
def file_handler(message):
if not check_chat(message):
return
notes = None
orig_name = None
if message.forward_from_chat:
notes = f"Telegram origin: \"{message.forward_from_chat.title}\" ({message.forward_from_chat.username})"
if message.photo:
fname = f"{message.photo[-1].file_unique_id}"
log.info(f"got photo '{fname}'")
file_info = tfm_tb.get_file(message.photo[-1].file_id)
file_path = os.path.join(tfm_api.conf["Telebot"]["SaveFolder"], fname)
with open(file_path, 'wb') as f:
f.write(tfm_tb.download_file(file_info.file_path))
elif message.video:
fname = f"{message.video.file_unique_id}"
log.info(f"got video '{fname}'")
file_info = tfm_tb.get_file(message.video.file_id)
file_path = os.path.join(tfm_api.conf["Telebot"]["SaveFolder"], fname)
with open(file_path, 'wb') as f:
f.write(tfm_tb.download_file(file_info.file_path))
else:
file = None
if message.document:
file = message.document
elif message.animation:
file = message.animation
else:
tfm_tb.reply_to(message, "Unsupported file type.")
return
log.info(f"got file '{file.file_name}'")
orig_name = file.file_name
file_info = tfm_tb.get_file(file.file_id)
file_path = os.path.join(tfm_api.conf["Telebot"]["SaveFolder"], f"{file.file_unique_id}")
try:
with open(file_path, 'wb') as f:
f.write(tfm_tb.download_file(file_info.file_path))
log.info(f"downloaded file '{file_path}'")
exif = ljson(os.popen(f"exiftool -json \"{file_path}\"").read())[0]
dt = exif["FileModifyDate"]
if "SubSecCreateDate" in exif.keys():
dt = exif["SubSecCreateDate"]
if '.' in dt:
dt = datetime.strptime(dt, "%Y:%m:%d %H:%M:%S.%f%z")
else:
dt = datetime.strptime(dt, "%Y:%m:%d %H:%M:%S%z")
file_id, ext = tfm.add_file(file_path, dt, notes, orig_name=orig_name)
tfm.add_file_to_tag(file_id, "d6d8129a-984d-4451-8c83-d04523ced8a8")
except Exception as e:
tfm_tb.reply_to(message, "Error: %s" % str(e).split('\n')[0])
log.info(f"Error: %s" % str(e).split('\n')[0])
os.remove(file_path)
log.info(f"removed file '{file_path}'")
else:
tfm_tb.reply_to(message, "File saved.")
log.info(f"imported file '{file_path}'")
# folder scanner
@tfm_tb.message_handler(commands=['scan'])
def scan(message):
tfm_tb.reply_to(message, "Scanning...")
log.info("Scanning...")
scan_dir = "/srv/share/hfs/misc/tfm_temp/scan"
files = []
for file in os.listdir(scan_dir):
new_file = {"name": file}
file = os.path.join(scan_dir, file)
if not os.path.isfile(file):
continue
new_file["path"] = file
try:
exif = ljson(os.popen(f"exiftool -json \"{file}\"").read())[0]
except Exception as e:
log.error("Error while parsing EXIF for file '%s': %s" % (file, e))
continue
dt = exif["FileModifyDate"]
if "SubSecDateTimeOriginal" in exif.keys():
dt = exif["SubSecDateTimeOriginal"]
elif "DateTimeOriginal" in exif.keys():
dt = exif["DateTimeOriginal"]
if '.' in dt:
try:
dt = datetime.strptime(dt, "%Y:%m:%d %H:%M:%S.%f%z")
except:
dt = TZ.localize(datetime.strptime(dt, "%Y:%m:%d %H:%M:%S.%f"))
else:
try:
try:
dt = datetime.strptime(dt, "%Y:%m:%d %H:%M:%S%z")
except:
dt = TZ.localize(datetime.strptime(dt[:19], "%Y:%m:%d %H:%M:%S"))
except:
log.error("Broken date: %s\t%s" % (new_file, dt))
continue
new_file["datetime"] = dt
files.append(new_file)
tfm_tb.reply_to(message, f"{len(files)} files found.")
log.info(f"{len(files)} files found.")
files.sort(key=lambda f: f["datetime"])
for file in files:
try:
file_id, ext = tfm.add_file(file["path"], file["datetime"])
tfm.add_file_to_tag(file_id, "d6d8129a-984d-4451-8c83-d04523ced8a8")
except Exception as e:
tfm_tb.reply_to(message, f"Error adding file '{file['name']}': {str(e)}")
log.error(f"Error adding file '{file['name']}': {str(e)}")
tfm_tb.reply_to(message, "Files added.")
log.info("Files added.")
if __name__ == '__main__':
log.info("tfm-tb started")
defer("log.info(\"tfm-tb stopped\")")
while True:
try:
tfm_tb.polling(none_stop=True)
except Exception as e:
log.exception("exception on polling")
sleep(1)