patch 3f2611ef2ec2a73f0327df45855e40f04ebb5955
Author: E. Bosch <presidev@AT@gmail.com>
Date: Tue Jul 7 23:15:14 CEST 2026
* Merge pull request #11 on github from Mirochill/fix-9-invalid-escape-warnings
Fix invalid escape warnings
patch 7827ddfc286acd03ba80f6dfef6efed92fc0457a
Author: E. Bosch <presidev@AT@gmail.com>
Date: Sun Jun 21 23:41:03 CEST 2026
* Update year in copyright notices
patch 6493c04f9d8bdb7b1d2c037fdd66c337a7a91af5
Author: E. Bosch <presidev@AT@gmail.com>
Date: Sun May 31 00:26:34 CEST 2026
* utils: Modify sanitize_filename(): convert invalid chars to hex representation,
this makes the filenames deterministic for the same session,
and helps to not download a file more than once
patch dd18dbebc3877faa7fe1c7f1257fb3a4048aab32
Author: E. Bosch <presidev@AT@gmail.com>
Date: Sat May 30 22:25:32 CEST 2026
* utils: In add_filename() don't put a final dot if there is no extension in the filename
patch feebc9eac596c484be6e5f67934196e64d52beeb
Author: E. Bosch <presidev@AT@gmail.com>
Date: Sat May 30 21:33:57 CEST 2026
* telegram: Refactor download media routine
optimized to download files only once
utils: Add session tokens for unnamed files
patch 4009bc07c6261c0ea2cb1a4112f8aaf266cbd65d
Author: E. Bosch <presidev@AT@gmail.com>
Date: Sat Jul 26 01:56:12 CEST 2025
* emoji2emoticon: Add emoji "rolling on the floor laughing" to convert to ASCII
diff -rN -u old-irgramd/LICENSE new-irgramd/LICENSE
--- old-irgramd/LICENSE 2026-07-08 06:41:05.698264992 +0200
+++ new-irgramd/LICENSE 2026-07-08 06:41:05.750264936 +0200
@@ -1,7 +1,7 @@
MIT License
Copyright (c) 2019 Peter Bui <pbui@bx612.space>
-Copyright (c) 2020-2024 E. Bosch <presidev@AT@gmail.com>
+Copyright (c) 2020-2026 E. Bosch <presidev@AT@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff -rN -u old-irgramd/README.md new-irgramd/README.md
--- old-irgramd/README.md 2026-07-08 06:41:05.698264992 +0200
+++ new-irgramd/README.md 2026-07-08 06:41:05.750264936 +0200
@@ -125,7 +125,7 @@
## License
Copyright (c) 2019 Peter Bui <pbui@bx612.space>
-Copyright (c) 2020-2024 E. Bosch <presidev@AT@gmail.com>
+Copyright (c) 2020-2026 E. Bosch <presidev@AT@gmail.com>
Use of this source code is governed by a MIT style license that
can be found in the LICENSE file included in this project.
diff -rN -u old-irgramd/emoji2emoticon.py new-irgramd/emoji2emoticon.py
--- old-irgramd/emoji2emoticon.py 2026-07-08 06:41:05.706264983 +0200
+++ new-irgramd/emoji2emoticon.py 2026-07-08 06:41:05.750264936 +0200
@@ -1,7 +1,7 @@
# irgramd: IRC-Telegram gateway
# emoji2emoticon.py: UTF-8 Emoji to ASCII emoticon replacement
#
-# (C) Copyright 2019,2023 E. Bosch <presidev@AT@gmail.com>
+# (C) Copyright 2019,2023,2025 E. Bosch <presidev@AT@gmail.com>
#
# Use of this source code is governed by a MIT style license that
# can be found in the LICENSE file included in this project.
@@ -14,7 +14,7 @@
'\U0001f44d': '"+1"',
'\U0001f44e': '"-1"',
'\U0001f44f': '"m_m"',
- '\U0001f525': '"\^^^/"',
+ '\U0001f525': r'"\^^^/"',
'\U0001f600': '":D"',
'\U0001f601': '"xD"',
'\U0001f602': '"x_D"',
@@ -85,6 +85,7 @@
'\U0001f643': '"(:"',
'\U0001f644': '"o o,"',
'\U0001f914': '":-L"',
+ '\U0001f923': '"X__D"',
'\U0001f92b': '":-o-m"',
'\U0001f970': '":)e>"',
}
diff -rN -u old-irgramd/exclam.py new-irgramd/exclam.py
--- old-irgramd/exclam.py 2026-07-08 06:41:05.706264983 +0200
+++ new-irgramd/exclam.py 2026-07-08 06:41:05.758264927 +0200
@@ -1,7 +1,7 @@
# irgramd: IRC-Telegram gateway
# exclam.py: IRC exclamation command handlers
#
-# Copyright (c) 2023, 2024 E. Bosch <presidev@AT@gmail.com>
+# Copyright (c) 2023-2025 E. Bosch <presidev@AT@gmail.com>
#
# Use of this source code is governed by a MIT style license that
# can be found in the LICENSE file included in this project.
diff -rN -u old-irgramd/include.py new-irgramd/include.py
--- old-irgramd/include.py 2026-07-08 06:41:05.710264979 +0200
+++ new-irgramd/include.py 2026-07-08 06:41:05.758264927 +0200
@@ -1,7 +1,7 @@
# irgramd: IRC-Telegram gateway
# include.py: Constants and other definitions to be included in other files
#
-# Copyright (c) 2020-2022 E. Bosch <presidev@AT@gmail.com>
+# Copyright (c) 2020-2024 E. Bosch <presidev@AT@gmail.com>
#
# Use of this source code is governed by a MIT style license that
# can be found in the LICENSE file included in this project.
diff -rN -u old-irgramd/irc.py new-irgramd/irc.py
--- old-irgramd/irc.py 2026-07-08 06:41:05.714264974 +0200
+++ new-irgramd/irc.py 2026-07-08 06:41:05.766264919 +0200
@@ -2,7 +2,7 @@
# irc.py: IRC server side implementation
#
# Copyright (c) 2019 Peter Bui <pbui@bx612.space>
-# Copyright (c) 2020-2023 E. Bosch <presidev@AT@gmail.com>
+# Copyright (c) 2020-2024 E. Bosch <presidev@AT@gmail.com>
#
# Use of this source code is governed by a MIT style license that
# can be found in the LICENSE file included in this project.
@@ -28,7 +28,7 @@
SRV = None
ALL_PARAMS = 16
-VALID_IRC_NICK_FIRST_CHARS = string.ascii_letters + '[]\`_^{|}'
+VALID_IRC_NICK_FIRST_CHARS = string.ascii_letters + r'[]\`_^{|}'
VALID_IRC_NICK_CHARS = VALID_IRC_NICK_FIRST_CHARS + string.digits + '-'
# IRC Regular Expressions
diff -rN -u old-irgramd/service.py new-irgramd/service.py
--- old-irgramd/service.py 2026-07-08 06:41:05.714264974 +0200
+++ new-irgramd/service.py 2026-07-08 06:41:05.766264919 +0200
@@ -1,7 +1,7 @@
# irgramd: IRC-Telegram gateway
# service.py: IRC service/control command handlers
#
-# Copyright (c) 2022,2023 E. Bosch <presidev@AT@gmail.com>
+# Copyright (c) 2022-2024 E. Bosch <presidev@AT@gmail.com>
#
# Use of this source code is governed by a MIT style license that
# can be found in the LICENSE file included in this project.
diff -rN -u old-irgramd/telegram.py new-irgramd/telegram.py
--- old-irgramd/telegram.py 2026-07-08 06:41:05.738264949 +0200
+++ new-irgramd/telegram.py 2026-07-08 06:41:05.770264915 +0200
@@ -2,7 +2,7 @@
# telegram.py: Interface to Telethon Telegram library
#
# Copyright (c) 2019 Peter Bui <pbui@bx612.space>
-# Copyright (c) 2020-2024 E. Bosch <presidev@AT@gmail.com>
+# Copyright (c) 2020-2026 E. Bosch <presidev@AT@gmail.com>
#
# Use of this source code is governed by a MIT style license that
# can be found in the LICENSE file included in this project.
@@ -23,7 +23,7 @@
from include import CHAN_MAX_LENGTH, NICK_MAX_LENGTH
from irc import IRCUser
from utils import sanitize_filename, add_filename, is_url_equiv, extract_url, get_human_size, get_human_duration
-from utils import get_highlighted, fix_braces, format_timestamp, pretty, current_date
+from utils import get_highlighted, fix_braces, format_timestamp, pretty, current_date, token
import emoji2emoticon as e
# Test IP table
@@ -44,6 +44,8 @@
self.notice_size = settings['download_notice'] * 1048576
self.media_dir = settings['media_dir']
self.media_url = settings['media_url']
+ if self.media_url[-1:] != '/':
+ self.media_url += '/'
self.upload_dir = settings['upload_dir']
self.api_id = settings['api_id']
self.api_hash = settings['api_hash']
@@ -59,7 +61,8 @@
self.geo_url = settings['geo_url']
if not settings['emoji_ascii']:
e.emo = {}
- self.media_cn = 0
+ self.token = token('+0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz')
+ self.filename_token = self.token.gen_token(5)
self.irc = irc
self.authorized = False
self.id = None
@@ -1028,30 +1031,25 @@
if not self.download:
return ''
if filename:
- idd_file = add_filename(filename, mid)
- new_file = sanitize_filename(idd_file)
- new_path = os.path.join(self.telegram_media_dir, new_file)
- if os.path.exists(new_path):
- local_path = new_path
+ aux_file = filename
+ else:
+ if hasattr(message, 'file') and message.file is not None:
+ aux_file = self.filename_token + message.file.ext
else:
- await self.notice_downloading(size, relay_attr)
- local_path = await message.download_media(new_path)
- if not local_path: return ''
+ aux_file = self.filename_token
+
+ idd_file = add_filename(aux_file, mid)
+ new_file = sanitize_filename(idd_file)
+ new_path = os.path.join(self.telegram_media_dir, new_file)
+ if os.path.exists(new_path) and (size == 0 or size == os.path.getsize(new_path)):
+ local_path = new_path
else:
await self.notice_downloading(size, relay_attr)
- local_path = await message.download_media(self.telegram_media_dir)
+ local_path = await message.download_media(new_path)
if not local_path: return ''
- filetype = os.path.splitext(local_path)[1]
- gen_file = str(self.media_cn) + filetype
- idd_file = add_filename(gen_file, mid)
- new_file = sanitize_filename(idd_file)
- self.media_cn += 1
- new_path = os.path.join(self.telegram_media_dir, new_file)
if local_path != new_path:
os.replace(local_path, new_path)
- if self.media_url[-1:] != '/':
- self.media_url += '/'
return self.media_url + new_file
async def notice_downloading(self, size, relay_attr):
diff -rN -u old-irgramd/utils.py new-irgramd/utils.py
--- old-irgramd/utils.py 2026-07-08 06:41:05.738264949 +0200
+++ new-irgramd/utils.py 2026-07-08 06:41:05.770264915 +0200
@@ -2,7 +2,7 @@
# utils.py: Helper functions
#
# Copyright (c) 2019 Peter Bui <pbui@bx612.space>
-# Copyright (c) 2020-2024 E. Bosch <presidev@AT@gmail.com>
+# Copyright (c) 2020-2026 E. Bosch <presidev@AT@gmail.com>
#
# Use of this source code is governed by a MIT style license that
# can be found in the LICENSE file included in this project.
@@ -14,10 +14,11 @@
import zoneinfo
import difflib
import logging
+import random
# Constants
-FILENAME_INVALID_CHARS = re.compile('[/{}<>()"\'\\|&#%?]')
+FILENAME_INVALID_CHARS = re.compile('[\0-\x1F/{}<>"\'\\|*&#%?\x7F]')
SIMPLE_URL = re.compile('http(|s)://[^ ]+')
from include import MAX_LINE
@@ -86,22 +87,23 @@
return messages_limited
def sanitize_filename(fn):
- cn = str(sanitize_filename.cn)
- new_fn, ns = FILENAME_INVALID_CHARS.subn(cn, fn)
- if ns:
- sanitize_filename.cn += 1
- return new_fn.strip('-').replace(' ','_')
-sanitize_filename.cn = 0
+ def hexize(m):
+ return '-{:x}-'.format(ord(m.group(0)))
+
+ new_fn = FILENAME_INVALID_CHARS.sub(hexize, fn)
+ return new_fn.lstrip('-').replace(' ','_')
def add_filename(filename, add):
if add:
aux = filename.rsplit('.', 1)
name = aux[0]
+ last_dot = '.'
try:
ext = aux[1]
except:
ext = ''
- return '{}-{}.{}'.format(name, add, ext)
+ last_dot = ''
+ return '{}-{}{}{}'.format(name, add, last_dot, ext)
else:
return filename
@@ -240,3 +242,15 @@
def pretty(object):
return object.stringify() if LOGL.debug and object else object
+
+class token:
+ def __init__(self, alpha):
+ self.alpha = alpha
+ self.long_alpha = len(alpha)
+
+ def gen_token(self, long_token):
+ if long_token == 1:
+ return self.alpha[random.randrange(self.long_alpha)]
+ else:
+ aux = self.gen_token(long_token - 1)
+ return aux + self.alpha[random.randrange(self.long_alpha)]