warp-beacon 2.6.51__py3-none-any.whl → 2.6.53__py3-none-any.whl
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.
- warp_beacon/__version__.py +1 -1
- warp_beacon/scraper/__init__.py +20 -14
- warp_beacon/scraper/abstract.py +2 -0
- warp_beacon/scraper/youtube/abstract.py +43 -21
- warp_beacon/telegram/bot.py +6 -10
- warp_beacon/telegram/download_status.py +43 -0
- warp_beacon/telegram/edit_message.py +5 -4
- warp_beacon/telegram/progress_bar.py +13 -6
- {warp_beacon-2.6.51.dist-info → warp_beacon-2.6.53.dist-info}/METADATA +1 -1
- {warp_beacon-2.6.51.dist-info → warp_beacon-2.6.53.dist-info}/RECORD +14 -13
- {warp_beacon-2.6.51.dist-info → warp_beacon-2.6.53.dist-info}/top_level.txt +1 -0
- {warp_beacon-2.6.51.dist-info → warp_beacon-2.6.53.dist-info}/WHEEL +0 -0
- {warp_beacon-2.6.51.dist-info → warp_beacon-2.6.53.dist-info}/entry_points.txt +0 -0
- {warp_beacon-2.6.51.dist-info → warp_beacon-2.6.53.dist-info}/licenses/LICENSE +0 -0
warp_beacon/__version__.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
__version__ = "2.6.
|
1
|
+
__version__ = "2.6.53"
|
2
2
|
|
warp_beacon/scraper/__init__.py
CHANGED
@@ -1,28 +1,31 @@
|
|
1
|
+
import logging
|
2
|
+
import multiprocessing
|
3
|
+
import multiprocessing.connection
|
1
4
|
import os
|
2
|
-
|
3
5
|
import time
|
4
|
-
from typing import Optional
|
5
|
-
import multiprocessing
|
6
6
|
from multiprocessing.managers import Namespace
|
7
7
|
from queue import Empty
|
8
|
+
from typing import Optional
|
8
9
|
|
9
|
-
import logging
|
10
|
-
|
11
|
-
from warp_beacon.scraper.exceptions import NotFound, UnknownError, TimeOut, Unavailable, FileTooBig, YoutubeLiveError, \
|
12
|
-
YotubeAgeRestrictedError, IGRateLimitOccurred, CaptchaIssue, AllAccountsFailed, BadProxy
|
13
|
-
from warp_beacon.mediainfo.video import VideoInfo
|
14
|
-
from warp_beacon.mediainfo.audio import AudioInfo
|
15
|
-
from warp_beacon.mediainfo.silencer import Silencer
|
16
10
|
from warp_beacon.compress.video import VideoCompress
|
17
|
-
from warp_beacon.uploader import AsyncUploader
|
18
11
|
from warp_beacon.jobs import Origin
|
19
12
|
from warp_beacon.jobs.download_job import DownloadJob
|
20
|
-
from warp_beacon.jobs.upload_job import UploadJob
|
21
13
|
from warp_beacon.jobs.types import JobType
|
14
|
+
from warp_beacon.jobs.upload_job import UploadJob
|
15
|
+
from warp_beacon.mediainfo.audio import AudioInfo
|
16
|
+
from warp_beacon.mediainfo.silencer import Silencer
|
17
|
+
from warp_beacon.mediainfo.video import VideoInfo
|
22
18
|
from warp_beacon.scraper.account_selector import AccountSelector
|
23
|
-
from warp_beacon.
|
19
|
+
from warp_beacon.scraper.exceptions import (AllAccountsFailed, BadProxy,
|
20
|
+
CaptchaIssue, FileTooBig,
|
21
|
+
IGRateLimitOccurred, NotFound,
|
22
|
+
TimeOut, Unavailable, UnknownError,
|
23
|
+
YotubeAgeRestrictedError,
|
24
|
+
YoutubeLiveError)
|
24
25
|
from warp_beacon.scraper.fail_handler import FailHandler
|
25
26
|
from warp_beacon.scraper.link_resolver import LinkResolver
|
27
|
+
from warp_beacon.storage.mongo import DBClient
|
28
|
+
from warp_beacon.uploader import AsyncUploader
|
26
29
|
|
27
30
|
ACC_FILE = os.environ.get("SERVICE_ACCOUNTS_FILE", default="/var/warp_beacon/accounts.json")
|
28
31
|
PROXY_FILE = os.environ.get("PROXY_FILE", default="/var/warp_beacon/proxies.json")
|
@@ -41,8 +44,9 @@ class AsyncDownloader(object):
|
|
41
44
|
scheduler = None
|
42
45
|
scrolling_now = None
|
43
46
|
process_context = None
|
47
|
+
status_pipe = None
|
44
48
|
|
45
|
-
def __init__(self, uploader: AsyncUploader, workers_count: int) -> None:
|
49
|
+
def __init__(self, uploader: AsyncUploader, pipe_connection: multiprocessing.connection.Connection, workers_count: int) -> None:
|
46
50
|
self.workers = []
|
47
51
|
self.job_queue = multiprocessing.Queue()
|
48
52
|
self.auth_event = multiprocessing.Event()
|
@@ -53,6 +57,7 @@ class AsyncDownloader(object):
|
|
53
57
|
self.acc_selector = AccountSelector(self.manager, ACC_FILE, PROXY_FILE)
|
54
58
|
self.uploader = uploader
|
55
59
|
self.workers_count = workers_count
|
60
|
+
self.status_pipe = pipe_connection
|
56
61
|
if os.environ.get("TG_PREMIUM", default="false") == "true":
|
57
62
|
self.TG_FILE_LIMIT = 4294967296 # 4 GiB
|
58
63
|
|
@@ -154,6 +159,7 @@ class AsyncDownloader(object):
|
|
154
159
|
actor.send_message_to_admin_func = self.send_message_to_admin
|
155
160
|
actor.request_yt_auth = self.request_yt_auth
|
156
161
|
actor.auth_event = self.auth_event
|
162
|
+
actor.status_pipe = self.status_pipe
|
157
163
|
# job retry loop
|
158
164
|
while self.allow_loop.value == 1:
|
159
165
|
try:
|
warp_beacon/scraper/abstract.py
CHANGED
@@ -4,6 +4,7 @@ from abc import ABC, abstractmethod
|
|
4
4
|
from typing import Callable, Union
|
5
5
|
import logging
|
6
6
|
import multiprocessing
|
7
|
+
import multiprocessing.connection
|
7
8
|
import socket
|
8
9
|
import requests.packages.urllib3.util.connection as urllib3_cn
|
9
10
|
|
@@ -14,6 +15,7 @@ class ScraperAbstract(ABC):
|
|
14
15
|
original_gai_family = None
|
15
16
|
send_message_to_admin_func: Callable = lambda: None
|
16
17
|
request_yt_auth: Callable = lambda: None
|
18
|
+
status_pipe: multiprocessing.connection.Connection = None
|
17
19
|
auth_event = None
|
18
20
|
account = None
|
19
21
|
account_index = 0
|
@@ -1,39 +1,46 @@
|
|
1
|
-
import
|
1
|
+
import http.client
|
2
2
|
import io
|
3
|
-
import
|
4
|
-
import
|
3
|
+
import json
|
4
|
+
import logging
|
5
5
|
import math
|
6
|
+
import os
|
7
|
+
import pathlib
|
6
8
|
import socket
|
7
9
|
import ssl
|
10
|
+
import time
|
11
|
+
import urllib
|
8
12
|
#from abc import abstractmethod
|
9
|
-
from typing import Callable,
|
10
|
-
import
|
11
|
-
|
12
|
-
import
|
13
|
+
from typing import Callable, Optional, Union
|
14
|
+
from urllib.parse import parse_qs, urlparse
|
15
|
+
|
16
|
+
import numpy as np
|
17
|
+
import pytubefix
|
13
18
|
import pytubefix.exceptions
|
14
19
|
import requests
|
15
|
-
from PIL import Image
|
16
|
-
import numpy as np
|
17
|
-
import urllib
|
18
20
|
import urllib3
|
19
|
-
from
|
20
|
-
|
21
|
-
import
|
21
|
+
#from pytubefix.exceptions import VideoUnavailable, VideoPrivate, MaxRetriesExceeded
|
22
|
+
import yt_dlp
|
23
|
+
from PIL import Image
|
22
24
|
from pytubefix import YouTube
|
23
25
|
from pytubefix.innertube import _default_clients
|
24
26
|
from pytubefix.streams import Stream
|
25
|
-
#from pytubefix.exceptions import VideoUnavailable, VideoPrivate, MaxRetriesExceeded
|
26
|
-
import yt_dlp
|
27
27
|
|
28
28
|
from warp_beacon.jobs.download_job import DownloadJob
|
29
29
|
from warp_beacon.scraper.abstract import ScraperAbstract
|
30
|
+
from warp_beacon.scraper.exceptions import (BadProxy, TimeOut, Unavailable,
|
31
|
+
extract_exception_message)
|
30
32
|
from warp_beacon.yt_auth import YtAuth
|
31
|
-
from warp_beacon.scraper.exceptions import TimeOut, Unavailable, BadProxy, extract_exception_message
|
32
33
|
|
33
34
|
class YoutubeAbstract(ScraperAbstract):
|
34
35
|
DOWNLOAD_DIR = "/tmp"
|
35
36
|
YT_SESSION_FILE = '/var/warp_beacon/yt_session_%d.json'
|
36
37
|
|
38
|
+
job = None
|
39
|
+
|
40
|
+
def __init__(self, account: tuple, proxy: dict=None) -> None:
|
41
|
+
super().__init__(account, proxy)
|
42
|
+
self._download_progress_threshold = 20
|
43
|
+
|
37
44
|
def validate_session(self) -> int:
|
38
45
|
try:
|
39
46
|
logging.info("Validating YT session(s) ...")
|
@@ -68,8 +75,8 @@ class YoutubeAbstract(ScraperAbstract):
|
|
68
75
|
ext = path_info.suffix
|
69
76
|
#old_filename = path_info.stem
|
70
77
|
time_name = str(time.time()).replace('.', '_')
|
71
|
-
new_filename = "
|
72
|
-
new_filepath = "
|
78
|
+
new_filename = f"{time_name}{ext}"
|
79
|
+
new_filepath = f"{os.path.dirname(filename)}/{new_filename}"
|
73
80
|
|
74
81
|
os.rename(filename, new_filepath)
|
75
82
|
|
@@ -83,7 +90,7 @@ class YoutubeAbstract(ScraperAbstract):
|
|
83
90
|
def remove_tmp_files(self) -> None:
|
84
91
|
for i in os.listdir(self.DOWNLOAD_DIR):
|
85
92
|
if "yt_download_" in i:
|
86
|
-
os.unlink("
|
93
|
+
os.unlink(f"{self.DOWNLOAD_DIR}/{i}")
|
87
94
|
|
88
95
|
def calculate_size_with_padding(self,
|
89
96
|
image: Image,
|
@@ -234,8 +241,20 @@ class YoutubeAbstract(ScraperAbstract):
|
|
234
241
|
def yt_on_progress(self, stream: Stream, chunk: bytes, bytes_remaining: int) -> None:
|
235
242
|
total_size = stream.filesize or stream.filesize_approx
|
236
243
|
bytes_downloaded = total_size - bytes_remaining
|
237
|
-
percentage_of_completion = bytes_downloaded / total_size * 100
|
238
|
-
|
244
|
+
percentage_of_completion = bytes_downloaded / (total_size or 1) * 100
|
245
|
+
if total_size == 0 or percentage_of_completion >= self._download_progress_threshold:
|
246
|
+
msg = {
|
247
|
+
"action": "report_download_status",
|
248
|
+
"current": bytes_downloaded,
|
249
|
+
"total": total_size,
|
250
|
+
"message_id": self.job.placeholder_message_id,
|
251
|
+
"chat_id": self.job.chat_id,
|
252
|
+
"completed": percentage_of_completion >= 100
|
253
|
+
}
|
254
|
+
self.status_pipe.send(msg)
|
255
|
+
logging.debug("[Download worker] Downloaded %d%%", percentage_of_completion)
|
256
|
+
if total_size > 0:
|
257
|
+
self._download_progress_threshold += 20
|
239
258
|
|
240
259
|
def build_proxies(self, proxy_dsn: str) -> dict:
|
241
260
|
if not proxy_dsn:
|
@@ -309,6 +328,7 @@ class YoutubeAbstract(ScraperAbstract):
|
|
309
328
|
raise NotImplementedError("You should to implement _download_yt_dlp method")
|
310
329
|
|
311
330
|
def download(self, job: DownloadJob) -> list:
|
331
|
+
self.job = job
|
312
332
|
ret = []
|
313
333
|
thumbnail = None
|
314
334
|
try:
|
@@ -323,6 +343,8 @@ class YoutubeAbstract(ScraperAbstract):
|
|
323
343
|
logging.exception(e)
|
324
344
|
|
325
345
|
try:
|
346
|
+
self.status_pipe.send({"action": "report_download_status", "current": 0, "total": 0,
|
347
|
+
"message_id": self.job.placeholder_message_id, "chat_id": self.job.chat_id})
|
326
348
|
ret = self.download_hndlr(self._download, job.url, session=True, thumbnail=thumbnail)
|
327
349
|
return ret
|
328
350
|
except (Unavailable, TimeOut, KeyError) as e:
|
warp_beacon/telegram/bot.py
CHANGED
@@ -4,9 +4,7 @@ import asyncio
|
|
4
4
|
from typing import Optional, Union
|
5
5
|
|
6
6
|
import logging
|
7
|
-
|
8
7
|
import html
|
9
|
-
|
10
8
|
import uvloop
|
11
9
|
|
12
10
|
from pyrogram import Client, filters
|
@@ -29,6 +27,7 @@ from warp_beacon.telegram.utils import Utils
|
|
29
27
|
from warp_beacon.telegram.caption_shortener import CaptionShortner
|
30
28
|
from warp_beacon.scheduler.scheduler import IGScheduler
|
31
29
|
from warp_beacon.telegram.edit_message import EditMessage
|
30
|
+
from warp_beacon.telegram.download_status import DownloadStatus
|
32
31
|
|
33
32
|
class Bot(object):
|
34
33
|
should_exit = None
|
@@ -42,6 +41,7 @@ class Bot(object):
|
|
42
41
|
scheduler = None
|
43
42
|
me = None
|
44
43
|
edit_message = None
|
44
|
+
download_status = 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
|
@@ -76,9 +76,11 @@ class Bot(object):
|
|
76
76
|
pool_size=int(os.environ.get("UPLOAD_POOL_SIZE", default=workers_amount)),
|
77
77
|
loop=self.client.loop
|
78
78
|
)
|
79
|
+
self.download_status = DownloadStatus(self.client)
|
79
80
|
self.downloader = warp_beacon.scraper.AsyncDownloader(
|
80
81
|
workers_count=int(os.environ.get("WORKERS_POOL_SIZE", default=workers_amount)),
|
81
|
-
uploader=self.uploader
|
82
|
+
uploader=self.uploader,
|
83
|
+
pipe_connection=self.download_status.child_conn
|
82
84
|
)
|
83
85
|
|
84
86
|
self.scheduler = IGScheduler(self.downloader)
|
@@ -111,6 +113,7 @@ class Bot(object):
|
|
111
113
|
os.environ["TG_PREMIUM"] = "true"
|
112
114
|
self.downloader.start()
|
113
115
|
self.uploader.start()
|
116
|
+
loop.add_reader(self.download_status.status_pipe.fileno(), self.download_status.on_status)
|
114
117
|
self.scheduler.start()
|
115
118
|
logging.info("Warp Beacon version '%s' started", __version__)
|
116
119
|
await self.should_exit.wait()
|
@@ -402,13 +405,6 @@ class Bot(object):
|
|
402
405
|
|
403
406
|
return args
|
404
407
|
|
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
|
-
|
412
408
|
async def upload_job(self, job: UploadJob) -> list[str]:
|
413
409
|
tg_file_ids = []
|
414
410
|
try:
|
@@ -0,0 +1,43 @@
|
|
1
|
+
import logging
|
2
|
+
from multiprocessing import Pipe
|
3
|
+
from pyrogram import Client
|
4
|
+
from warp_beacon.telegram.progress_bar import ProgressBar
|
5
|
+
|
6
|
+
class DownloadStatus(object):
|
7
|
+
status_pipe = None
|
8
|
+
child_conn = None
|
9
|
+
client = None
|
10
|
+
progress_bars = None
|
11
|
+
|
12
|
+
def __init__(self, client: Client) -> None:
|
13
|
+
self.progress_bars = {}
|
14
|
+
self.client = client
|
15
|
+
self.status_pipe, self.child_conn = Pipe()
|
16
|
+
|
17
|
+
async def handle_message(self, msg: dict, progress_bar: ProgressBar) -> None:
|
18
|
+
await progress_bar.progress_callback(
|
19
|
+
current=msg.get("current", 0),
|
20
|
+
total=msg.get("total", 0),
|
21
|
+
message_id=msg.get("message_id", 0),
|
22
|
+
chat_id=msg.get("chat_id", 0),
|
23
|
+
operation="Downloaded"
|
24
|
+
)
|
25
|
+
|
26
|
+
def on_status(self) -> None:
|
27
|
+
msg = self.status_pipe.recv()
|
28
|
+
if not msg:
|
29
|
+
logging.warning("Empty status message!")
|
30
|
+
return
|
31
|
+
logging.info("Received pipe message: %s", msg)
|
32
|
+
message_id = msg.get("message_id", 0)
|
33
|
+
chat_id = msg.get("chat_id", 0)
|
34
|
+
a_key = f"{message_id}:{chat_id}"
|
35
|
+
progress_bar = None
|
36
|
+
if a_key not in self.progress_bars:
|
37
|
+
progress_bar = ProgressBar(self.client)
|
38
|
+
self.progress_bars[a_key] = progress_bar
|
39
|
+
else:
|
40
|
+
progress_bar = self.progress_bars[a_key]
|
41
|
+
task = self.client.loop.create_task(self.handle_message(msg, progress_bar))
|
42
|
+
if msg.get("completed", False):
|
43
|
+
task.add_done_callback(lambda _: self.progress_bars.pop(a_key, None))
|
@@ -93,7 +93,8 @@ class EditMessage(object):
|
|
93
93
|
file_name: str = None
|
94
94
|
) -> None:
|
95
95
|
progress_bar = ProgressBar(self.client)
|
96
|
-
|
96
|
+
await progress_bar.progress_callback(current=0, total=0, chat_id=chat_id, message_id=message_id, operation="Uploaded", label=file_name)
|
97
|
+
raw_file = await self.client.save_file(path=media.media, progress=progress_bar.progress_callback, progress_args=(chat_id, message_id, "Uploaded", file_name,))
|
97
98
|
|
98
99
|
caption = media.caption
|
99
100
|
parse_mode = media.parse_mode
|
@@ -106,17 +107,17 @@ class EditMessage(object):
|
|
106
107
|
raw_media = None
|
107
108
|
if isinstance(media, types.InputMediaVideo):
|
108
109
|
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_file_thumb = await self.client.save_file(path=media.thumb, progress=progress_bar_thumb.progress_callback, progress_args=(chat_id, message_id, "Uploaded", "thumbnail",))
|
110
111
|
raw_media = self.get_wrapped_video(raw_file=raw_file, raw_thumb=raw_file_thumb, media=media, file_name=file_name)
|
111
112
|
elif isinstance(media, types.InputMediaPhoto):
|
112
113
|
raw_media = self.get_wrapped_photo(raw_file=raw_file, media=media)
|
113
114
|
elif isinstance(media, types.InputMediaAudio):
|
114
115
|
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_file_thumb = await self.client.save_file(path=media.thumb, progress=progress_bar_thumb.progress_callback, progress_args=(chat_id, message_id, "Uploaded", "thumbnail",))
|
116
117
|
raw_media = self.get_wrapped_audio(raw_file=raw_file, raw_thumb=raw_file_thumb, media=media, file_name=file_name)
|
117
118
|
elif isinstance(media, types.InputMediaAnimation):
|
118
119
|
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_file_thumb = await self.client.save_file(path=media.thumb, progress=progress_bar_thumb.progress_callback, progress_args=(chat_id, message_id, "Uploaded", "thumbnail",))
|
120
121
|
raw_media = self.get_wrapped_animation(raw_file=raw_file, raw_thumb=raw_file_thumb, media=media, file_name=file_name)
|
121
122
|
|
122
123
|
peer = await self.client.resolve_peer(chat_id)
|
@@ -10,6 +10,10 @@ class ProgressBar(object):
|
|
10
10
|
def __init__(self, client: Client) -> None:
|
11
11
|
self._next_threshold = 20
|
12
12
|
self.client = client
|
13
|
+
self.complete = False
|
14
|
+
|
15
|
+
def is_complete(self) -> bool:
|
16
|
+
return self.complete
|
13
17
|
|
14
18
|
def make_progress_bar(self, current: int, total: int, length: int = 10) -> str:
|
15
19
|
"""
|
@@ -43,20 +47,23 @@ class ProgressBar(object):
|
|
43
47
|
percent = frac * 100
|
44
48
|
return f"[{pbar}] {round(percent)}%"
|
45
49
|
|
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:
|
50
|
+
async def progress_callback(self, current: int, total: int, chat_id: int | str, message_id: int, operation: str, label: str = "") -> None:
|
51
|
+
percent = current * 100 / (total or 1)
|
52
|
+
if total == 0 or percent >= self._next_threshold:
|
49
53
|
#pbar = self.make_progress_bar(percent, 100, 25)
|
50
54
|
pbar = self.make_emoji_progress_bar(percent, 100, 14)
|
51
|
-
logging.info("[%s] Uploaded to Telegram %d%%", label, percent)
|
55
|
+
logging.info("[%s] Uploaded to Telegram %d%%", label or operation, percent)
|
52
56
|
try:
|
53
|
-
await self.client.edit_message_caption(chat_id, message_id, f"{pbar} <b>
|
57
|
+
await self.client.edit_message_caption(chat_id, message_id, f"{pbar} <b>{operation}</b> {label}", ParseMode.HTML)
|
54
58
|
except MessageNotModified:
|
55
59
|
logging.warning("bad_request_400.MessageNotModified")
|
56
60
|
except Exception as e:
|
57
61
|
logging.warning("An error occurred while updating progress bar")
|
58
62
|
logging.exception(e)
|
59
|
-
|
63
|
+
if total > 0:
|
64
|
+
self._next_threshold += 20
|
65
|
+
if percent >= 100:
|
66
|
+
self.complete = True
|
60
67
|
|
61
68
|
@staticmethod
|
62
69
|
def make_hash(chat_id: str | int, message_id: int, algorithm: str = 'sha256') -> str:
|
@@ -4,7 +4,7 @@ var/warp_beacon/accounts.json,sha256=OsXdncs6h88xrF_AP6_WDCK1waGBn9SR-uYdIeK37GM
|
|
4
4
|
var/warp_beacon/placeholder.gif,sha256=cE5CGJVaop4Sx21zx6j4AyoHU0ncmvQuS2o6hJfEH88,6064
|
5
5
|
var/warp_beacon/proxies.json,sha256=VnjlQDXumOEq72ZFjbh6IqHS1TEHqn8HPYAZqWCeSIA,95
|
6
6
|
warp_beacon/__init__.py,sha256=_rThNODmz0nDp_n4mWo_HKaNFE5jk1_7cRhHyYaencI,163
|
7
|
-
warp_beacon/__version__.py,sha256=
|
7
|
+
warp_beacon/__version__.py,sha256=hcmauQ1R3h1hRfSDodv85yWUciNm6uQit0GyDrOnLDg,24
|
8
8
|
warp_beacon/warp_beacon.py,sha256=ED43vNzdjDUJ_9qLCbri0bjWLWEJ69BENGj9i7G6AvM,342
|
9
9
|
warp_beacon/yt_auth.py,sha256=GUTKqYr_tzDC-07Lx_ahWXSag8EyLxXBUnQbDBIkEmk,6022
|
10
10
|
warp_beacon/compress/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -22,8 +22,8 @@ warp_beacon/mediainfo/video.py,sha256=UBZrhTN5IDI-aYu6tsJEILo9nFkjHhkldGVFmvV7tE
|
|
22
22
|
warp_beacon/scheduler/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
23
23
|
warp_beacon/scheduler/instagram_human.py,sha256=0LaRUu0MBBuEOQeFzuq22HIYfJL9pTK_7udsXfef0Fk,8204
|
24
24
|
warp_beacon/scheduler/scheduler.py,sha256=9OCh7Ta4wY_aTHGAOOZmaKXg56Ftx1N_aV1g6E3ZLKA,4941
|
25
|
-
warp_beacon/scraper/__init__.py,sha256=
|
26
|
-
warp_beacon/scraper/abstract.py,sha256=
|
25
|
+
warp_beacon/scraper/__init__.py,sha256=buXmGcJnwCi0qGZAh3srcSbww0XvKyTACp_DW11e86Q,20225
|
26
|
+
warp_beacon/scraper/abstract.py,sha256=wwmk2L1S4H9la8x74eN4svdG-BgOdE1tKrOv7jjFhXE,3043
|
27
27
|
warp_beacon/scraper/account_selector.py,sha256=-tAbOIbM7sC9QafsgSe64RCWXewRO-RehEYsYSB3HGo,9727
|
28
28
|
warp_beacon/scraper/exceptions.py,sha256=EKwoF0oH2xZWbNU-v8DOaWK5skKwa3s1yTIBdlcfMpc,1452
|
29
29
|
warp_beacon/scraper/fail_handler.py,sha256=zcPK3ZVEsu6JmHYcWP7L3naTRK3gWFVRkpP84VBOtJs,964
|
@@ -33,25 +33,26 @@ warp_beacon/scraper/instagram/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5N
|
|
33
33
|
warp_beacon/scraper/instagram/captcha.py,sha256=9UYziuqB3Tsat_ET6ex-cnZDbi6yCnsXHSpmE8MuUHk,4651
|
34
34
|
warp_beacon/scraper/instagram/instagram.py,sha256=zbkF-1lU5lxJ_2m8i8mGRX0EQMLVSflsOafBM1FEC6s,15588
|
35
35
|
warp_beacon/scraper/youtube/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
36
|
-
warp_beacon/scraper/youtube/abstract.py,sha256
|
36
|
+
warp_beacon/scraper/youtube/abstract.py,sha256=KjtMb_5RJrAyLGz_BIBv-RdBRey6PnJX6jnOaJKsbTk,13485
|
37
37
|
warp_beacon/scraper/youtube/music.py,sha256=5AeSBQyUgVCJT2hoBCV2WvlyuV9US09SYJhmBG_P9F8,2755
|
38
38
|
warp_beacon/scraper/youtube/shorts.py,sha256=1GtoYUlxAwcgSQcn80u5ehNJytH5AN5dPOicmX-XD8E,1705
|
39
39
|
warp_beacon/scraper/youtube/youtube.py,sha256=x9v9p1coA9TvBhxjNAofGu4UBkAEdYPE2ePRnU-5tK0,7233
|
40
40
|
warp_beacon/storage/__init__.py,sha256=0Vajd0oITKJfu2vmNx5uQSt3-L6vwIvUYWJo8HZCjco,3398
|
41
41
|
warp_beacon/storage/mongo.py,sha256=qC4ZiO8XXvPnP0rJwz4CJx42pqFsyAjCiW10W5QdT6E,527
|
42
42
|
warp_beacon/telegram/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
43
|
-
warp_beacon/telegram/bot.py,sha256=
|
43
|
+
warp_beacon/telegram/bot.py,sha256=W13hyJD89ozZallLq0NIb9c3uh1Hov8Axi7ab7LkE3A,19128
|
44
44
|
warp_beacon/telegram/caption_shortener.py,sha256=EnguNCF52ne7y4P-iJAbI6K3sqoJqJbND_dX5Fhwkv0,1549
|
45
|
-
warp_beacon/telegram/
|
45
|
+
warp_beacon/telegram/download_status.py,sha256=dV0mRIOkA8dU0ECsmC_rZ33XQhVnkW2nZBNTxQ0Y6x4,1342
|
46
|
+
warp_beacon/telegram/edit_message.py,sha256=_452kXWn65qj9iPSvSmORbKXXTjJ0z6kBCxPcmKDrlM,5742
|
46
47
|
warp_beacon/telegram/handlers.py,sha256=uvR6TPHSqdSxigp3wR-ewiE6t3TvVcbVLVcYGwkgD2s,9559
|
47
48
|
warp_beacon/telegram/placeholder_message.py,sha256=wN9-BRiyrtHG-EvXtZkGJHt2CX71munQ57ITttjt0mw,6400
|
48
|
-
warp_beacon/telegram/progress_bar.py,sha256=
|
49
|
+
warp_beacon/telegram/progress_bar.py,sha256=TYvoGTmr44aqAYbZ6byU5sekdVoz7x_0YMDkLO6plYo,2575
|
49
50
|
warp_beacon/telegram/progress_file_reader.py,sha256=e3equyNKlKs764AD-iE9QRsh3YDHTzP78Mx5tdvPPWs,969
|
50
51
|
warp_beacon/telegram/utils.py,sha256=1Lq67aRylVJzbwSyvAgjPAGjJZFATkICvAj3TJGuJiM,4635
|
51
52
|
warp_beacon/uploader/__init__.py,sha256=j3qcuKhpchseZLGzSsSiogqe6WdMbkK8d3I-ConhNRs,5687
|
52
|
-
warp_beacon-2.6.
|
53
|
-
warp_beacon-2.6.
|
54
|
-
warp_beacon-2.6.
|
55
|
-
warp_beacon-2.6.
|
56
|
-
warp_beacon-2.6.
|
57
|
-
warp_beacon-2.6.
|
53
|
+
warp_beacon-2.6.53.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
54
|
+
warp_beacon-2.6.53.dist-info/METADATA,sha256=Jg3gJ15i-ifchkeXPPek-KLoCByZrT0fqAyllygNDIk,22706
|
55
|
+
warp_beacon-2.6.53.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
|
56
|
+
warp_beacon-2.6.53.dist-info/entry_points.txt,sha256=eSB61Rb89d56WY0O-vEIQwkn18J-4CMrJcLA_R_8h3g,119
|
57
|
+
warp_beacon-2.6.53.dist-info/top_level.txt,sha256=2x4wBJ_HeeBt6Bsdu9C4tItXWqH8spX8jGSHpoL0IMw,1334
|
58
|
+
warp_beacon-2.6.53.dist-info/RECORD,,
|
@@ -34,6 +34,7 @@ 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/download_status
|
37
38
|
warp_beacon/telegram/edit_message
|
38
39
|
warp_beacon/telegram/handlers
|
39
40
|
warp_beacon/telegram/placeholder_message
|
File without changes
|
File without changes
|
File without changes
|