Skip to content

Commit

Permalink
Version 0.1.5
Browse files Browse the repository at this point in the history
- Support for mails without body/message added, part 2 (fix for #2)
- Optionally read mails received before application was started, via configuration file or command line parameter
- Decode file names of attachments having national/special characters
  • Loading branch information
awalon committed Apr 22, 2022
1 parent 661f174 commit f163a2a
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 5 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ now.
```
sudo vi /etc/mail-to-telegram-forwarder/mailToTelegramForwarder.conf
```
### Command line options
`-c`, `--config`: Configuration file.

`-o`, `--read-old-mails` (optional): Read mails received before application was started.
Can be used to overwrite `read_old_mails` as defined by configuration file.

### Configuration
#### Mail
Expand Down Expand Up @@ -156,6 +161,9 @@ or last loop).
#search: (UID ${lastUID}:* UNSEEN HEADER Subject "<Subject or Part of Subject>")
```

`read_old_mails` [**Default** False]: Read mails received before application was started.
See command line option `-o` or `--read-old-mails` for one-time use.

`max_length` [**Default** 2000]: Email content will be trimmed, if longer than this
value. HTML messages will be trimmed to this number of characters after unsupported
HTML Elements was removed.
Expand Down
4 changes: 4 additions & 0 deletions conf/mailToTelegramForwarder.conf
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ server: <IMAP mail server>
# Default:
#search: (UID ${lastUID}:* UNSEEN)

# Read mails received before application was started (default: False)
# see command line option "-o" or "--read-old-mails" for one-time use
#read_old_mails: False

# max length (characters) of forwarded mail content
#max_length: 2000

Expand Down
31 changes: 26 additions & 5 deletions mailToTelegramForwarder.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"""

__appname__ = "Mail to Telegram Forwarder"
__version__ = "0.1.4"
__version__ = "0.1.5"
__author__ = "Awalon (https://github.com/awalon)"

with warnings.catch_warnings(record=True) as w:
Expand Down Expand Up @@ -95,6 +95,7 @@ class Config:
imap_search = '(UID ${lastUID}:* UNSEEN)'
imap_mark_as_read = False
imap_max_length = 2000
imap_read_old_mails = False

tg_bot_token = None
tg_forward_to_chat_id = None
Expand Down Expand Up @@ -124,6 +125,7 @@ def __init__(self, cmd_args):
self.imap_push_mode = self.get_config('Mail', 'push_mode', self.imap_push_mode, bool)
self.imap_disconnect = self.get_config('Mail', 'disconnect', self.imap_disconnect, bool)
self.imap_folder = self.get_config('Mail', 'folder', self.imap_folder)
self.imap_read_old_mails = self.get_config('Mail', 'read_old_mails', self.imap_read_old_mails)
self.imap_search = self.get_config('Mail', 'search', self.imap_search)
self.imap_mark_as_read = self.get_config('Mail', 'mark_as_read', self.imap_mark_as_read, bool)
self.imap_max_length = self.get_config('Mail', 'max_length', self.imap_max_length, int)
Expand All @@ -137,6 +139,8 @@ def __init__(self, cmd_args):
self.tg_markdown_version = self.get_config('Telegram', 'markdown_version', self.tg_markdown_version, int)
self.tg_forward_attachment = self.get_config('Telegram', 'forward_attachment',
self.tg_forward_attachment, bool)
if cmd_args.read_old_mails:
self.imap_read_old_mails = True

except configparser.ParsingError as parse_error:
logging.critical("Error parsing config file: Impossible to parse file %s. Message: %s"
Expand Down Expand Up @@ -323,7 +327,7 @@ def send_message(self, mails):
tg_chat_title, str(self.config.tg_forward_to_chat_id)))

except telegram.TelegramError as tg_mail_error:
msg = "Failed to send Telegram message (UID: %s) to '%s': %s" \
msg = "Failed to send Telegram message (UID: %s) to '%s': %s" \
% (mail.uid, tg_mail_error.message, str(self.config.tg_forward_to_chat_id))
logging.critical(msg)
try:
Expand Down Expand Up @@ -368,6 +372,13 @@ class MailAttachment:
name = ''
file = None

def set_name(self, file_name):
name = ''
for file_name_part in email.header.decode_header(file_name):
part, encoding = file_name_part
name += Tool.binary_to_string(part, encoding=encoding)
self.name = name


class MailBody:
text = ''
Expand Down Expand Up @@ -521,7 +532,7 @@ def decode_body(msg) -> MailBody:
elif part.get_content_charset() is None and part.get_content_disposition() == 'attachment':
attachment = MailAttachment()
attachment.idx = index
attachment.name = str(part.get_filename())
attachment.set_name(str(part.get_filename()))
attachment.file = part.get_payload(decode=True)
attachments.append(attachment)
index += 1
Expand Down Expand Up @@ -593,7 +604,7 @@ def parse_mail(self, uid, mail):

max_len = self.config.imap_max_length
content_len = len(content)
if message_type == MailData.HTML:
if message_type == MailData.HTML and content_len > 0:
# get length from parsed HTML (all tags removed)
content_plain = re.sub(r'<[^>]*>', '', content, flags=re.MULTILINE)
# get new max length based on plain text factor
Expand Down Expand Up @@ -713,7 +724,15 @@ def search_mails(self):
return self.MailError(msg)

mails = []
max_num = int(self.last_uid)
if self.config.imap_read_old_mails:
# ignore current/max UID during first loop
max_num = 0
self.config.imap_read_old_mails = False
logging.info('Ignore max UID %s, as old mails have to be processed first.' % self.last_uid)
else:
max_num = int(self.last_uid)
logging.info('Reading mails having UID greater than %s to ignore mails '
'received before application was started.' % self.last_uid)
for num in sorted(data[0].split()):
current_uid = int(Tool.binary_to_string(num))

Expand Down Expand Up @@ -784,6 +803,8 @@ def main():

args_parser = argparse.ArgumentParser(description='Mail to Telegram Forwarder')
args_parser.add_argument('-c', '--config', type=str, help='Path to config file', required=True)
args_parser.add_argument('-o', '--read-old-mails', action='store_true', required=False,
help='Read mails received, before application was started')
cmd_args = args_parser.parse_args()

if cmd_args.config is None:
Expand Down

0 comments on commit f163a2a

Please sign in to comment.