|
import os |
|
import requests |
|
import smtplib |
|
import json |
|
import logging |
|
import time |
|
from email.mime.multipart import MIMEMultipart |
|
from email.mime.application import MIMEApplication |
|
from datetime import datetime, timedelta |
|
from configparser import ConfigParser |
|
|
|
# Ermittle aktuelles Verzeichnis |
|
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) |
|
|
|
# Logger Setup |
|
logging.basicConfig( |
|
filename=os.path.join(SCRIPT_DIR, 'paperless_forward.log'), |
|
level=logging.INFO, |
|
format='%(asctime)s - %(levelname)s - %(message)s' |
|
) |
|
|
|
def load_config(): |
|
config = ConfigParser() |
|
config.read(os.path.join(SCRIPT_DIR, 'config.ini')) |
|
return config |
|
|
|
def load_sent_documents(): |
|
try: |
|
with open(os.path.join(SCRIPT_DIR, 'sent_documents.json'), 'r') as f: |
|
return set(json.load(f)) |
|
except FileNotFoundError: |
|
return set() |
|
|
|
def save_sent_document(doc_id): |
|
sent_docs = load_sent_documents() |
|
sent_docs.add(doc_id) |
|
with open(os.path.join(SCRIPT_DIR, 'sent_documents.json'), 'w') as f: |
|
json.dump(list(sent_docs), f) |
|
|
|
def get_new_documents(config): |
|
try: |
|
headers = { |
|
'Authorization': f'Token {config["paperless"]["api_token"]}' |
|
} |
|
|
|
all_documents = [] |
|
tag_ids = [tag.strip() for tag in config["paperless"]["forward_tag_ids"].split(',')] |
|
|
|
for tag_id in tag_ids: |
|
next_url = f'{config["paperless"]["url"]}/api/documents/' |
|
params = { |
|
'tags__id': tag_id, |
|
'page_size': 100 # Maximale Anzahl pro Seite |
|
} |
|
|
|
while next_url: |
|
response = requests.get( |
|
next_url, |
|
headers=headers, |
|
params=params, |
|
timeout=30 |
|
) |
|
response.raise_for_status() |
|
data = response.json() |
|
|
|
all_documents.extend(data['results']) |
|
next_url = data.get('next') |
|
# Bei weiteren Seiten keine Parameter mehr senden |
|
params = None |
|
|
|
logging.info(f'Gefundene Dokumente für Tag {tag_id} bisher: {len(all_documents)}') |
|
|
|
return all_documents |
|
except requests.RequestException as e: |
|
logging.error(f'API Fehler: {str(e)}') |
|
return [] |
|
|
|
def send_document(doc, config): |
|
smtp = None |
|
try: |
|
smtp = smtplib.SMTP(config['email']['smtp_server'], int(config['email']['smtp_port'])) |
|
smtp.starttls() |
|
smtp.login(config['email']['username'], config['email']['password']) |
|
|
|
to_addrs = [addr.strip() for addr in config['email']['to_addrs'].split(',')] |
|
for to_addr in to_addrs: |
|
msg = MIMEMultipart() |
|
msg['From'] = config['email']['from_addr'] |
|
msg['To'] = to_addr |
|
msg['Subject'] = f'Paperless Dokument: {doc["title"]}' |
|
|
|
# Dokument herunterladen |
|
doc_response = requests.get( |
|
f'{config["paperless"]["url"]}/api/documents/{doc["id"]}/download/', |
|
headers={'Authorization': f'Token {config["paperless"]["api_token"]}'}, |
|
timeout=30 |
|
) |
|
doc_response.raise_for_status() |
|
|
|
attachment = MIMEApplication(doc_response.content, _subtype="pdf") |
|
attachment.add_header('Content-Disposition', 'attachment', filename=f'{doc["title"]}.pdf') |
|
msg.attach(attachment) |
|
|
|
try: |
|
smtp.send_message(msg) |
|
logging.info(f'Dokument {doc["id"]} - {doc["title"]} an {to_addr} weitergeleitet') |
|
time.sleep(2) # Kurze Pause zwischen einzelnen Empfängern |
|
except Exception as e: |
|
logging.error(f'Fehler beim Senden von Dokument {doc["id"]} an {to_addr}: {str(e)}') |
|
|
|
except requests.RequestException as e: |
|
logging.error(f'Fehler beim Herunterladen von Dokument {doc["id"]}: {str(e)}') |
|
except smtplib.SMTPException as e: |
|
logging.error(f'SMTP-Fehler bei Dokument {doc["id"]}: {str(e)}') |
|
except Exception as e: |
|
logging.error(f'Unerwarteter Fehler bei Dokument {doc["id"]}: {str(e)}') |
|
finally: |
|
if smtp: |
|
smtp.quit() |
|
|
|
def main(): |
|
try: |
|
config = load_config() |
|
docs = get_new_documents(config) |
|
sent_docs = load_sent_documents() |
|
|
|
for doc in docs: |
|
if str(doc["id"]) not in sent_docs: |
|
send_document(doc, config) |
|
save_sent_document(str(doc["id"])) |
|
time.sleep(5) # 5 Sekunden Pause zwischen E-Mails |
|
|
|
except Exception as e: |
|
logging.error(f'Allgemeiner Fehler: {str(e)}') |
|
|
|
if __name__ == '__main__': |
|
main() |