warp-beacon 2.6.47__tar.gz → 2.6.49__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. {warp_beacon-2.6.47/warp_beacon.egg-info → warp_beacon-2.6.49}/PKG-INFO +1 -1
  2. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/setup.py +2 -0
  3. warp_beacon-2.6.49/warp_beacon/__version__.py +2 -0
  4. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/telegram/bot.py +15 -11
  5. warp_beacon-2.6.49/warp_beacon/telegram/edit_message.py +141 -0
  6. warp_beacon-2.6.49/warp_beacon/telegram/progress_bar.py +66 -0
  7. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/telegram/progress_file_reader.py +8 -12
  8. {warp_beacon-2.6.47 → warp_beacon-2.6.49/warp_beacon.egg-info}/PKG-INFO +1 -1
  9. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon.egg-info/SOURCES.txt +2 -0
  10. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon.egg-info/top_level.txt +2 -0
  11. warp_beacon-2.6.47/warp_beacon/__version__.py +0 -2
  12. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/LICENSE +0 -0
  13. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/MANIFEST.in +0 -0
  14. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/README.md +0 -0
  15. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/assets/placeholder.gif +0 -0
  16. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/etc/.gitignore +0 -0
  17. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/etc/accounts.json +0 -0
  18. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/etc/proxies.json +0 -0
  19. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/etc/warp_beacon.conf +0 -0
  20. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/etc/warp_beacon.service +0 -0
  21. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/pyproject.toml +0 -0
  22. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/setup.cfg +0 -0
  23. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/__init__.py +0 -0
  24. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/compress/__init__.py +0 -0
  25. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/compress/video.py +0 -0
  26. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/jobs/__init__.py +0 -0
  27. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/jobs/abstract.py +0 -0
  28. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/jobs/download_job.py +0 -0
  29. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/jobs/types.py +0 -0
  30. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/jobs/upload_job.py +0 -0
  31. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/mediainfo/__init__.py +0 -0
  32. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/mediainfo/abstract.py +0 -0
  33. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/mediainfo/audio.py +0 -0
  34. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/mediainfo/silencer.py +0 -0
  35. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/mediainfo/video.py +0 -0
  36. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/scheduler/__init__.py +0 -0
  37. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/scheduler/instagram_human.py +0 -0
  38. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/scheduler/scheduler.py +0 -0
  39. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/scraper/__init__.py +0 -0
  40. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/scraper/abstract.py +0 -0
  41. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/scraper/account_selector.py +0 -0
  42. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/scraper/exceptions.py +0 -0
  43. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/scraper/fail_handler.py +0 -0
  44. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/scraper/instagram/__init__.py +0 -0
  45. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/scraper/instagram/captcha.py +0 -0
  46. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/scraper/instagram/instagram.py +0 -0
  47. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/scraper/link_resolver.py +0 -0
  48. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/scraper/utils.py +0 -0
  49. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/scraper/youtube/__init__.py +0 -0
  50. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/scraper/youtube/abstract.py +0 -0
  51. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/scraper/youtube/music.py +0 -0
  52. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/scraper/youtube/shorts.py +0 -0
  53. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/scraper/youtube/youtube.py +0 -0
  54. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/storage/__init__.py +0 -0
  55. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/storage/mongo.py +0 -0
  56. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/telegram/__init__.py +0 -0
  57. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/telegram/caption_shortener.py +0 -0
  58. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/telegram/handlers.py +0 -0
  59. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/telegram/placeholder_message.py +0 -0
  60. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/telegram/utils.py +0 -0
  61. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/uploader/__init__.py +0 -0
  62. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/warp_beacon.py +0 -0
  63. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon/yt_auth.py +0 -0
  64. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon.egg-info/dependency_links.txt +0 -0
  65. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon.egg-info/entry_points.txt +0 -0
  66. {warp_beacon-2.6.47 → warp_beacon-2.6.49}/warp_beacon.egg-info/requires.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: warp_beacon
3
- Version: 2.6.47
3
+ Version: 2.6.49
4
4
  Summary: Telegram bot for expanding external media links
5
5
  Home-page: https://github.com/sb0y/warp_beacon
6
6
  Author: Andrey Bagrintsev
@@ -66,7 +66,9 @@ setup(
66
66
  "warp_beacon/telegram/handlers",
67
67
  "warp_beacon/telegram/utils",
68
68
  "warp_beacon/telegram/caption_shortener",
69
+ "warp_beacon/telegram/progress_bar",
69
70
  "warp_beacon/telegram/progress_file_reader",
71
+ "warp_beacon/telegram/edit_message",
70
72
  "warp_beacon/jobs/abstract",
71
73
  "warp_beacon/jobs/download_job",
72
74
  "warp_beacon/jobs/upload_job",
@@ -0,0 +1,2 @@
1
+ __version__ = "2.6.49"
2
+
@@ -8,7 +8,6 @@ import logging
8
8
  import html
9
9
 
10
10
  import uvloop
11
- #from contextlib import ExitStack
12
11
 
13
12
  from pyrogram import Client, filters
14
13
  from pyrogram.enums import ParseMode, ChatType
@@ -29,7 +28,7 @@ from warp_beacon.jobs import Origin
29
28
  from warp_beacon.telegram.utils import Utils
30
29
  from warp_beacon.telegram.caption_shortener import CaptionShortner
31
30
  from warp_beacon.scheduler.scheduler import IGScheduler
32
- from warp_beacon.telegram.progress_file_reader import ProgressFileReader
31
+ from warp_beacon.telegram.edit_message import EditMessage
33
32
 
34
33
  class Bot(object):
35
34
  should_exit = None
@@ -42,22 +41,19 @@ class Bot(object):
42
41
  placeholder = None
43
42
  scheduler = None
44
43
  me = None
44
+ edit_message = None
45
45
 
46
46
  def __init__(self, tg_bot_name: str, tg_token: str, tg_api_id: str, tg_api_hash: str) -> None:
47
47
  # Enable logging
48
48
  logging.basicConfig(
49
- format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO
49
+ format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
50
+ level=logging.INFO
50
51
  )
51
52
 
52
53
  logging.getLogger("pyrogram").setLevel(logging.ERROR)
53
-
54
54
  logging.info("Starting Warp Beacon version '%s' ...", __version__)
55
-
56
- db_connect = DBClient()
57
- self.storage = Storage(db_connect)
58
-
55
+ self.storage = Storage(DBClient())
59
56
  self.should_exit = asyncio.Event()
60
-
61
57
  workers_amount = min(32, os.cpu_count() + 4)
62
58
 
63
59
  uvloop.install()
@@ -71,6 +67,8 @@ class Bot(object):
71
67
  workers=int(os.environ.get("TG_WORKERS_POOL_SIZE", default=workers_amount))
72
68
  )
73
69
 
70
+ self.editor = EditMessage(self.client)
71
+
74
72
  self.uploader = AsyncUploader(
75
73
  storage=self.storage,
76
74
  admin_message_callback=self.send_text_to_admin,
@@ -84,7 +82,6 @@ class Bot(object):
84
82
  )
85
83
 
86
84
  self.scheduler = IGScheduler(self.downloader)
87
-
88
85
  self.handlers = Handlers(self)
89
86
 
90
87
  self.client.add_handler(MessageHandler(self.handlers.start, filters.command("start")))
@@ -405,6 +402,13 @@ class Bot(object):
405
402
 
406
403
  return args
407
404
 
405
+ async def progress_callback(self, current: int, total: int, chat_id: int | str, message_id: int, label: str) -> None:
406
+ percents = int(current * 100 / total)
407
+ if (percents % 40) > 0 or percents == 100:
408
+ p = round(percents)
409
+ await self.client.edit_message_caption(chat_id, message_id, f"<b>{p}% <code>{label}</code> uploaded</b>", ParseMode.HTML)
410
+ logging.info("[%s] Uploaded to Telegram %d%%", label, p)
411
+
408
412
  async def upload_job(self, job: UploadJob) -> list[str]:
409
413
  tg_file_ids = []
410
414
  try:
@@ -418,7 +422,7 @@ class Bot(object):
418
422
  await Utils.ensure_me_loaded(self.client)
419
423
  if job.placeholder_message_id:
420
424
  try:
421
- reply_message = await self.client.edit_message_media(**self.build_tg_args(job))
425
+ reply_message = await self.editor.edit(**self.build_tg_args(job))
422
426
  except MessageIdInvalid:
423
427
  logging.warning("Placeholder message not found. Looks like placeholder message was deleted by administrator.")
424
428
  job.placeholder_message_id = None
@@ -0,0 +1,141 @@
1
+ from pyrogram.client import Client
2
+ from pyrogram.types import InputMedia, InputMediaAudio, InputMediaPhoto, InputMediaVideo, InputMediaAnimation, InlineKeyboardMarkup
3
+ from pyrogram import raw
4
+ from pyrogram import types
5
+
6
+ #from warp_beacon.telegram.bot import Bot
7
+ from warp_beacon.telegram.progress_bar import ProgressBar
8
+
9
+ class EditMessage(object):
10
+ def __init__(self, client: Client) -> None:
11
+ self.client = client
12
+
13
+ def get_wrapped_video(self, raw_file: raw.base.InputFile, raw_thumb: raw.base.InputFile, media: InputMediaVideo, file_name: str = None) -> raw.types.InputMediaUploadedDocument:
14
+ return raw.types.InputMediaUploadedDocument(
15
+ file=raw_file,
16
+ mime_type=self.client.guess_mime_type(media.media) or "video/mp4",
17
+ thumb=raw_thumb,
18
+ spoiler=media.has_spoiler,
19
+ attributes=[
20
+ raw.types.DocumentAttributeVideo(
21
+ duration=media.duration,
22
+ w=media.width,
23
+ h=media.height,
24
+ supports_streaming=media.supports_streaming
25
+ ),
26
+ raw.types.DocumentAttributeFilename(
27
+ file_name=file_name
28
+ )
29
+ ]
30
+ )
31
+
32
+ def get_wrapped_photo(self, raw_file: raw.base.InputFile, media: InputMediaPhoto) -> raw.types.InputMediaUploadedPhoto:
33
+ return raw.types.InputMediaUploadedPhoto(
34
+ file=raw_file,
35
+ spoiler=media.has_spoiler
36
+ )
37
+
38
+ def get_wrapped_audio(self, raw_file: raw.base.InputFile, raw_thumb: raw.base.InputFile, media: InputMediaAudio, file_name: str = None) -> raw.types.InputMediaUploadedDocument:
39
+ return raw.types.InputMediaUploadedDocument(
40
+ mime_type=self.client.guess_mime_type(media.media) or "audio/mpeg",
41
+ thumb=raw_thumb,
42
+ file=raw_file,
43
+ attributes=[
44
+ raw.types.DocumentAttributeAudio(
45
+ duration=media.duration,
46
+ performer=media.performer,
47
+ title=media.title
48
+ ),
49
+ raw.types.DocumentAttributeFilename(
50
+ file_name=file_name
51
+ )
52
+ ]
53
+ )
54
+
55
+ def get_wrapped_animation(self, raw_file: raw.base.InputFile, raw_thumb: raw.base.InputFile, media: InputMediaVideo, file_name: str = None) -> raw.types.InputMediaUploadedDocument:
56
+ return raw.types.InputMediaUploadedDocument(
57
+ mime_type=self.client.guess_mime_type(media.media) or "video/mp4",
58
+ thumb=raw_thumb,
59
+ spoiler=media.has_spoiler,
60
+ file=raw_file,
61
+ attributes=[
62
+ raw.types.DocumentAttributeVideo(
63
+ supports_streaming=True,
64
+ duration=media.duration,
65
+ w=media.width,
66
+ h=media.height
67
+ ),
68
+ raw.types.DocumentAttributeFilename(
69
+ file_name=file_name
70
+ ),
71
+ raw.types.DocumentAttributeAnimated()
72
+ ]
73
+ )
74
+
75
+ #async def upload_with_progress(self,
76
+ # media: InputMedia | InputMediaAudio | InputMediaPhoto | InputMediaVideo | InputMediaAnimation,
77
+ # chat_id: int | str,
78
+ # message_id: int,
79
+ # file_name: str
80
+ #) -> raw.base.InputFile:
81
+ # progress_bar = ProgressBar(self.client)
82
+ # progress_id = f"{chat_id}:{message_id}:{file_name}"
83
+ # self.progress_bars[progress_id] = progress_bar
84
+ # raw_file = await self.client.save_file(path=media.media, progress=progress_bar.progress_callback, progress_args=(chat_id, message_id, file_name,))
85
+ # del self.progress_bars[progress_id]
86
+ # return raw_file
87
+
88
+ async def edit(self,
89
+ chat_id: int | str,
90
+ message_id: int,
91
+ media: InputMedia | InputMediaAudio | InputMediaPhoto | InputMediaVideo | InputMediaAnimation,
92
+ reply_markup: InlineKeyboardMarkup = None,
93
+ file_name: str = None
94
+ ) -> None:
95
+ progress_bar = ProgressBar(self.client)
96
+ raw_file = await self.client.save_file(path=media.media, progress=progress_bar.progress_callback, progress_args=(chat_id, message_id, file_name,))
97
+
98
+ caption = media.caption
99
+ parse_mode = media.parse_mode
100
+
101
+ message, entities = None, None
102
+
103
+ if caption is not None:
104
+ message, entities = (await self.client.parser.parse(caption, parse_mode)).values()
105
+
106
+ raw_media = None
107
+ if isinstance(media, types.InputMediaVideo):
108
+ progress_bar_thumb = ProgressBar(self.client)
109
+ raw_file_thumb = await self.client.save_file(path=media.thumb, progress=progress_bar_thumb.progress_callback, progress_args=(chat_id, message_id, "thumbnail",))
110
+ raw_media = self.get_wrapped_video(raw_file=raw_file, raw_thumb=raw_file_thumb, media=media, file_name=file_name)
111
+ elif isinstance(media, types.InputMediaPhoto):
112
+ raw_media = self.get_wrapped_photo(raw_file=raw_file, media=media)
113
+ elif isinstance(media, types.InputMediaAudio):
114
+ progress_bar_thumb = ProgressBar(self.client)
115
+ raw_file_thumb = await self.client.save_file(path=media.thumb, progress=progress_bar_thumb.progress_callback, progress_args=(chat_id, message_id, "thumbnail",))
116
+ raw_media = self.get_wrapped_audio(raw_file=raw_file, raw_thumb=raw_file_thumb, media=media, file_name=file_name)
117
+ elif isinstance(media, types.InputMediaAnimation):
118
+ progress_bar_thumb = ProgressBar(self.client)
119
+ raw_file_thumb = await self.client.save_file(path=media.thumb, progress=progress_bar_thumb.progress_callback, progress_args=(chat_id, message_id, "thumbnail",))
120
+ raw_media = self.get_wrapped_animation(raw_file=raw_file, raw_thumb=raw_file_thumb, media=media, file_name=file_name)
121
+
122
+ peer = await self.client.resolve_peer(chat_id)
123
+
124
+ r = await self.client.invoke(
125
+ raw.functions.messages.EditMessage(
126
+ peer=peer,
127
+ id=message_id,
128
+ media=raw_media,
129
+ reply_markup=await reply_markup.write(self.client) if reply_markup else None,
130
+ message=message,
131
+ entities=entities
132
+ )
133
+ )
134
+
135
+ for i in r.updates:
136
+ if isinstance(i, (raw.types.UpdateEditMessage, raw.types.UpdateEditChannelMessage)):
137
+ return await types.Message._parse(
138
+ self.client, i.message,
139
+ {i.id: i for i in r.users},
140
+ {i.id: i for i in r.chats}
141
+ )
@@ -0,0 +1,66 @@
1
+ import logging
2
+
3
+ import hashlib
4
+
5
+ from pyrogram.enums import ParseMode
6
+ from pyrogram.errors.exceptions.bad_request_400 import MessageNotModified
7
+ from pyrogram import Client
8
+
9
+ class ProgressBar(object):
10
+ def __init__(self, client: Client) -> None:
11
+ self._next_threshold = 20
12
+ self.client = client
13
+
14
+ def make_progress_bar(self, current: int, total: int, length: int = 10) -> str:
15
+ """
16
+ Returns string
17
+ [████▌────] 55%
18
+ length — amount of characters in bar
19
+ """
20
+ # fraction of completed job from 0.0 to 1.0
21
+ frac = current / total if total else 0
22
+ # how much "filled" cells
23
+ filled = int(frac * length)
24
+ # part between whole cells, optional may withdraw half
25
+ half_block = ''
26
+ if (frac * length) - filled >= 0.5:
27
+ half_block = '▌' # or '▏', '▍' and etc.
28
+ # building bar
29
+ pbar = '█' * filled + half_block + '─' * (length - filled - len(half_block))
30
+ percent = frac * 100
31
+ return f"<b>[{pbar}] {round(percent)}</b>%"
32
+
33
+ def make_emoji_progress_bar(self, current: int, total: int, length: int = 10) -> str:
34
+ """
35
+ Returns string:
36
+ [🟩🟩🟩⬜️⬜️⬜️⬜️⬜️⬜️⬜️] 30%
37
+ length — common number of emoji cells
38
+ """
39
+ frac = (current / total) if total else 0
40
+ filled_count = int(frac * length)
41
+ empty_count = length - filled_count
42
+ pbar = "🟩" * filled_count + "⬜️" * empty_count
43
+ percent = frac * 100
44
+ return f"[{pbar}] {round(percent)}%"
45
+
46
+ async def progress_callback(self, current: int, total: int, chat_id: int | str, message_id: int, label: str) -> None:
47
+ percent = current * 100 / total
48
+ if percent >= self._next_threshold:
49
+ #pbar = self.make_progress_bar(percent, 100, 25)
50
+ pbar = self.make_emoji_progress_bar(percent, 100, 14)
51
+ logging.info("[%s] Uploaded to Telegram %d%%", label, percent)
52
+ try:
53
+ await self.client.edit_message_caption(chat_id, message_id, f"{pbar} <b>Uploading <code>{label}</code></b>", ParseMode.HTML)
54
+ except MessageNotModified:
55
+ logging.warning("bad_request_400.MessageNotModified")
56
+ except Exception as e:
57
+ logging.warning("An error occurred while updating progress bar")
58
+ logging.exception(e)
59
+ self._next_threshold += 20
60
+
61
+ @staticmethod
62
+ def make_hash(chat_id: str | int, message_id: int, algorithm: str = 'sha256') -> str:
63
+ s = f"{chat_id}:{message_id}"
64
+ # md5, sha1, sha256
65
+ h = hashlib.new(algorithm, s.encode('utf-8'))
66
+ return h.hexdigest()
@@ -3,27 +3,27 @@ import os
3
3
  from types import TracebackType
4
4
  from typing import Optional, Callable, Type
5
5
 
6
- class ProgressFileReader(io.BufferedReader):
6
+ class ProgressFileReader(io.FileIO):
7
7
  def __init__(self, file_path: str, callback: Optional[Callable[[str, int, int], None]]) -> None:
8
- raw = open(file_path, "rb")
9
- super().__init__(raw)
10
- self._raw = raw
8
+ super().__init__(file_path, "rb")
11
9
  self.callback = callback
12
10
  self._total = os.path.getsize(file_path)
13
11
  self._read_bytes = 0
14
- self._name = os.path.basename(file_path)
12
+ self._display_name = os.path.basename(file_path)
13
+
14
+ def __fspath__(self) -> str:
15
+ return self._display_name
15
16
 
16
17
  def read(self, size: int = -1) -> bytes:
17
18
  chunk = super().read(size)
18
19
  self._read_bytes += len(chunk)
19
20
  if self.callback:
20
- self.callback(self.name, self._read_bytes, self._total)
21
+ self.callback(self._display_name, self._read_bytes, self._total)
21
22
  return chunk
22
23
 
23
24
  def close(self) -> None:
24
25
  if not self.closed:
25
26
  super().close()
26
- self._raw.close()
27
27
 
28
28
  def __enter__(self) -> "ProgressFileReader":
29
29
  return self
@@ -33,8 +33,4 @@ class ProgressFileReader(io.BufferedReader):
33
33
  exc_val: Optional[BaseException],
34
34
  exc_tb: Optional[TracebackType]
35
35
  ) -> None:
36
- self.close()
37
-
38
- @property
39
- def name(self) -> str:
40
- return self._name
36
+ self.close()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: warp_beacon
3
- Version: 2.6.47
3
+ Version: 2.6.49
4
4
  Summary: Telegram bot for expanding external media links
5
5
  Home-page: https://github.com/sb0y/warp_beacon
6
6
  Author: Andrey Bagrintsev
@@ -55,8 +55,10 @@ warp_beacon/storage/mongo.py
55
55
  warp_beacon/telegram/__init__.py
56
56
  warp_beacon/telegram/bot.py
57
57
  warp_beacon/telegram/caption_shortener.py
58
+ warp_beacon/telegram/edit_message.py
58
59
  warp_beacon/telegram/handlers.py
59
60
  warp_beacon/telegram/placeholder_message.py
61
+ warp_beacon/telegram/progress_bar.py
60
62
  warp_beacon/telegram/progress_file_reader.py
61
63
  warp_beacon/telegram/utils.py
62
64
  warp_beacon/uploader/__init__.py
@@ -34,8 +34,10 @@ warp_beacon/storage/mongo
34
34
  warp_beacon/telegram
35
35
  warp_beacon/telegram/bot
36
36
  warp_beacon/telegram/caption_shortener
37
+ warp_beacon/telegram/edit_message
37
38
  warp_beacon/telegram/handlers
38
39
  warp_beacon/telegram/placeholder_message
40
+ warp_beacon/telegram/progress_bar
39
41
  warp_beacon/telegram/progress_file_reader
40
42
  warp_beacon/telegram/utils
41
43
  warp_beacon/uploader
@@ -1,2 +0,0 @@
1
- __version__ = "2.6.47"
2
-
File without changes
File without changes
File without changes
File without changes