warp-beacon 2.1.6__tar.gz → 2.1.7__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.
- {warp_beacon-2.1.6/warp_beacon.egg-info → warp_beacon-2.1.7}/PKG-INFO +1 -1
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/setup.py +3 -1
- warp_beacon-2.1.7/warp_beacon/__init__.py +7 -0
- warp_beacon-2.1.7/warp_beacon/__version__.py +2 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/jobs/abstract.py +2 -0
- warp_beacon-2.1.7/warp_beacon/scheduler/scheduler.py +62 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/scraper/__init__.py +22 -8
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/scraper/exceptions.py +1 -1
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/scraper/instagram/instagram.py +8 -4
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/telegram/bot.py +1 -4
- {warp_beacon-2.1.6 → warp_beacon-2.1.7/warp_beacon.egg-info}/PKG-INFO +1 -1
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon.egg-info/SOURCES.txt +2 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon.egg-info/top_level.txt +2 -0
- warp_beacon-2.1.6/warp_beacon/__version__.py +0 -2
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/LICENSE +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/MANIFEST.in +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/README.md +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/assets/placeholder.gif +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/etc/.gitignore +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/etc/accounts.json +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/etc/warp_beacon.conf +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/etc/warp_beacon.service +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/pyproject.toml +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/setup.cfg +0 -0
- {warp_beacon-2.1.6/warp_beacon → warp_beacon-2.1.7/warp_beacon/compress}/__init__.py +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/compress/video.py +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/jobs/__init__.py +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/jobs/download_job.py +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/jobs/types.py +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/jobs/upload_job.py +0 -0
- {warp_beacon-2.1.6/warp_beacon/compress → warp_beacon-2.1.7/warp_beacon/mediainfo}/__init__.py +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/mediainfo/abstract.py +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/mediainfo/audio.py +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/mediainfo/silencer.py +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/mediainfo/video.py +0 -0
- {warp_beacon-2.1.6/warp_beacon/mediainfo → warp_beacon-2.1.7/warp_beacon/scheduler}/__init__.py +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/scraper/abstract.py +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/scraper/account_selector.py +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/scraper/instagram/__init__.py +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/scraper/youtube/__init__.py +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/scraper/youtube/abstract.py +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/scraper/youtube/music.py +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/scraper/youtube/shorts.py +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/scraper/youtube/youtube.py +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/storage/__init__.py +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/telegram/__init__.py +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/telegram/handlers.py +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/telegram/placeholder_message.py +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/telegram/utils.py +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/uploader/__init__.py +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon/warp_beacon.py +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon.egg-info/dependency_links.txt +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon.egg-info/entry_points.txt +0 -0
- {warp_beacon-2.1.6 → warp_beacon-2.1.7}/warp_beacon.egg-info/requires.txt +0 -0
@@ -54,7 +54,8 @@ setup(
|
|
54
54
|
'warp_beacon/scraper/youtube',
|
55
55
|
'warp_beacon/mediainfo',
|
56
56
|
'warp_beacon/jobs',
|
57
|
-
'warp_beacon/compress'
|
57
|
+
'warp_beacon/compress',
|
58
|
+
'warp_beacon/scheduler'
|
58
59
|
],
|
59
60
|
py_modules=[
|
60
61
|
"warp_beacon/__version__",
|
@@ -71,6 +72,7 @@ setup(
|
|
71
72
|
"warp_beacon/mediainfo/audio",
|
72
73
|
"warp_beacon/mediainfo/silencer",
|
73
74
|
"warp_beacon/compress/video",
|
75
|
+
"warp_beacon/scheduler/scheduler",
|
74
76
|
"warp_beacon/scraper/abstract",
|
75
77
|
"warp_beacon/scraper/exceptions",
|
76
78
|
"warp_beacon/scraper/types",
|
@@ -36,6 +36,7 @@ class JobSettings(TypedDict):
|
|
36
36
|
geoblock_error_count: int
|
37
37
|
account_switches: int
|
38
38
|
yt_auth: bool
|
39
|
+
session_validation: bool
|
39
40
|
|
40
41
|
class AbstractJob(ABC):
|
41
42
|
job_id: uuid.UUID = None
|
@@ -66,6 +67,7 @@ class AbstractJob(ABC):
|
|
66
67
|
geoblock_error_count: int = 0
|
67
68
|
account_switches: int = 0
|
68
69
|
yt_auth: bool = False
|
70
|
+
session_validation: bool = False
|
69
71
|
|
70
72
|
def __init__(self, **kwargs: Unpack[JobSettings]) -> None:
|
71
73
|
if kwargs:
|
@@ -0,0 +1,62 @@
|
|
1
|
+
import threading
|
2
|
+
|
3
|
+
import warp_beacon
|
4
|
+
|
5
|
+
import logging
|
6
|
+
|
7
|
+
class IGScheduler(object):
|
8
|
+
downloader = None
|
9
|
+
running = True
|
10
|
+
thread = None
|
11
|
+
event = None
|
12
|
+
|
13
|
+
def __init__(self, downloader: "warp_beacon.scraper.AsyncDownloader") -> None:
|
14
|
+
self.downloader = downloader
|
15
|
+
self.event = threading.Event()
|
16
|
+
|
17
|
+
def __del__(self) -> None:
|
18
|
+
self.stop()
|
19
|
+
|
20
|
+
def start(self) -> None:
|
21
|
+
self.thread = threading.Thread(target=self.do_work)
|
22
|
+
self.thread.start()
|
23
|
+
|
24
|
+
def stop(self) -> None:
|
25
|
+
self.running = False
|
26
|
+
if self.thread:
|
27
|
+
t_id = self.thread.native_id
|
28
|
+
logging.info("Stopping scheduler thread #'%s'", t_id)
|
29
|
+
self.thread.join()
|
30
|
+
logging.info("Scheduler thread #'%s' stopped", t_id)
|
31
|
+
self.thread = None
|
32
|
+
|
33
|
+
def post_image(self, image) -> None:
|
34
|
+
pass
|
35
|
+
|
36
|
+
def post_story(self) -> None:
|
37
|
+
pass
|
38
|
+
|
39
|
+
def download_random_image(self) -> None:
|
40
|
+
pass
|
41
|
+
|
42
|
+
def validate_ig_session(self) -> bool:
|
43
|
+
try:
|
44
|
+
self.downloader.queue_task(warp_beacon.jobs.download_job.DownloadJob.build(
|
45
|
+
session_validation=True
|
46
|
+
))
|
47
|
+
except Exception as e:
|
48
|
+
logging.warning("An error occurred while validating instagram session!")
|
49
|
+
logging.exception(e)
|
50
|
+
|
51
|
+
return False
|
52
|
+
|
53
|
+
def do_work(self) -> None:
|
54
|
+
logging.info("Scheduler thread started ...")
|
55
|
+
while self.running:
|
56
|
+
try:
|
57
|
+
logging.info("Scheduler waking up")
|
58
|
+
self.validate_ig_session()
|
59
|
+
self.event.wait(timeout=3600)
|
60
|
+
except Exception as e:
|
61
|
+
logging.error("An error occurred in scheduler thread!")
|
62
|
+
logging.exception(e)
|
@@ -4,7 +4,7 @@ from typing import Optional
|
|
4
4
|
import multiprocessing
|
5
5
|
from queue import Empty
|
6
6
|
|
7
|
-
from warp_beacon.scraper.exceptions import NotFound, UnknownError, TimeOut, Unavailable, FileTooBig, YotubeLiveError, YotubeAgeRestrictedError,
|
7
|
+
from warp_beacon.scraper.exceptions import NotFound, UnknownError, TimeOut, Unavailable, FileTooBig, YotubeLiveError, YotubeAgeRestrictedError, IGRateLimitOccurred, CaptchaIssue, AllAccountsFailed
|
8
8
|
from warp_beacon.mediainfo.video import VideoInfo
|
9
9
|
from warp_beacon.mediainfo.audio import AudioInfo
|
10
10
|
from warp_beacon.mediainfo.silencer import Silencer
|
@@ -15,10 +15,11 @@ from warp_beacon.jobs.download_job import DownloadJob
|
|
15
15
|
from warp_beacon.jobs.upload_job import UploadJob
|
16
16
|
from warp_beacon.jobs.types import JobType
|
17
17
|
from warp_beacon.scraper.account_selector import AccountSelector
|
18
|
+
from warp_beacon.scheduler.scheduler import IGScheduler
|
18
19
|
|
19
20
|
import logging
|
20
21
|
|
21
|
-
ACC_FILE = os.environ.get("SERVICE_ACCOUNTS_FILE", default="/var/warp_beacon/
|
22
|
+
ACC_FILE = os.environ.get("SERVICE_ACCOUNTS_FILE", default="/var/warp_beacon/accounts.json")
|
22
23
|
|
23
24
|
class AsyncDownloader(object):
|
24
25
|
__JOE_BIDEN_WAKEUP = None
|
@@ -29,12 +30,14 @@ class AsyncDownloader(object):
|
|
29
30
|
workers_count = 0
|
30
31
|
auth_event = multiprocessing.Event()
|
31
32
|
acc_selector = None
|
33
|
+
scheduler = None
|
32
34
|
|
33
35
|
def __init__(self, uploader: AsyncUploader, workers_count: int) -> None:
|
34
36
|
self.allow_loop = multiprocessing.Value('i', 1)
|
35
37
|
self.uploader = uploader
|
36
38
|
self.workers_count = workers_count
|
37
39
|
self.acc_selector = AccountSelector(ACC_FILE)
|
40
|
+
self.scheduler = IGScheduler(self)
|
38
41
|
|
39
42
|
def __del__(self) -> None:
|
40
43
|
self.stop_all()
|
@@ -104,13 +107,17 @@ class AsyncDownloader(object):
|
|
104
107
|
elif job.job_origin is Origin.YOUTUBE:
|
105
108
|
from warp_beacon.scraper.youtube.youtube import YoutubeScraper
|
106
109
|
actor = YoutubeScraper(self.acc_selector.get_current())
|
107
|
-
#self.auth_event = multiprocessing.Event()
|
108
110
|
actor.send_message_to_admin_func = self.send_message_to_admin
|
109
111
|
actor.auth_event = self.auth_event
|
110
112
|
while True:
|
111
113
|
try:
|
112
|
-
|
113
|
-
|
114
|
+
if job.session_validation:
|
115
|
+
logging.info("Validating '%s' session ...", job.origin.value)
|
116
|
+
actor.validate_session()
|
117
|
+
logging.info("done")
|
118
|
+
else:
|
119
|
+
logging.info("Downloading URL '%s'", job.url)
|
120
|
+
items = actor.download(job.url)
|
114
121
|
break
|
115
122
|
except NotFound as e:
|
116
123
|
logging.warning("Not found error occurred!")
|
@@ -159,14 +166,14 @@ class AsyncDownloader(object):
|
|
159
166
|
f"Task {job.job_id} failed. URL: '{job.url}'. Reason: 'FileTooBig'."
|
160
167
|
)
|
161
168
|
break
|
162
|
-
except
|
163
|
-
logging.warning("IG ratelimit
|
169
|
+
except IGRateLimitOccurred as e:
|
170
|
+
logging.warning("IG ratelimit occurred :(")
|
164
171
|
logging.exception(e)
|
165
172
|
self.try_next_account(job, report_error="rate_limits")
|
166
173
|
self.job_queue.put(job)
|
167
174
|
break
|
168
175
|
except CaptchaIssue as e:
|
169
|
-
logging.warning("Challange
|
176
|
+
logging.warning("Challange occurred!")
|
170
177
|
logging.exception(e)
|
171
178
|
self.try_next_account(job)
|
172
179
|
self.job_queue.put(job)
|
@@ -215,6 +222,9 @@ class AsyncDownloader(object):
|
|
215
222
|
job_failed=True,
|
216
223
|
job_failed_msg="This content does not accessible for all yout bot accounts. Seems like author blocked certain regions.")
|
217
224
|
)
|
225
|
+
self.send_message_to_admin(
|
226
|
+
f"Task {job.job_id} failed. URL: '{job.url}'. Reason: 'geoblock_required'."
|
227
|
+
)
|
218
228
|
break
|
219
229
|
job.geoblock_error_count += 1
|
220
230
|
logging.info("Trying to switch account")
|
@@ -225,6 +235,10 @@ class AsyncDownloader(object):
|
|
225
235
|
job_failed=True,
|
226
236
|
job_failed_msg="WOW, unknown error occured! Please [create issue](https://github.com/sb0y/warp_beacon/issues) with service logs.")
|
227
237
|
)
|
238
|
+
self.send_message_to_admin(
|
239
|
+
f"Task {job.job_id} failed. URL: '{job.url}'. Reason: 'UnknownError'."
|
240
|
+
f"Exception:\n```\n{exception_msg}\n```"
|
241
|
+
)
|
228
242
|
break
|
229
243
|
|
230
244
|
if items:
|
@@ -19,7 +19,7 @@ from instagrapi import Client
|
|
19
19
|
from instagrapi.mixins.challenge import ChallengeChoice
|
20
20
|
from instagrapi.exceptions import LoginRequired, PleaseWaitFewMinutes, MediaNotFound, ClientNotFoundError, UserNotFound, ChallengeRequired, ChallengeSelfieCaptcha, UnknownError as IGUnknownError
|
21
21
|
|
22
|
-
from warp_beacon.scraper.exceptions import NotFound, UnknownError, TimeOut,
|
22
|
+
from warp_beacon.scraper.exceptions import NotFound, UnknownError, TimeOut, IGRateLimitOccurred, CaptchaIssue, extract_exception_message
|
23
23
|
from warp_beacon.scraper.abstract import ScraperAbstract
|
24
24
|
from warp_beacon.jobs.types import JobType
|
25
25
|
from warp_beacon.telegram.utils import Utils
|
@@ -85,9 +85,13 @@ class InstagramScraper(ScraperAbstract):
|
|
85
85
|
self.cl.login(username=username, password=password, verification_code="")
|
86
86
|
self.safe_write_session()
|
87
87
|
|
88
|
-
def
|
88
|
+
def validate_session(self) -> None:
|
89
89
|
self.load_session()
|
90
90
|
self._download_hndlr(self.cl.get_timeline_feed)
|
91
|
+
self._download_hndlr(self.cl.get_reels_tray_feed)
|
92
|
+
|
93
|
+
def scrap(self, url: str) -> tuple[str]:
|
94
|
+
self.load_session()
|
91
95
|
def _scrap() -> tuple[str]:
|
92
96
|
if "stories" in url:
|
93
97
|
# remove URL options
|
@@ -258,8 +262,8 @@ class InstagramScraper(ScraperAbstract):
|
|
258
262
|
logging.warning("Please wait a few minutes error. Trying to relogin ...")
|
259
263
|
logging.exception(e)
|
260
264
|
if please_wait_few_minutes_count >= ratelimit_threshold:
|
261
|
-
logging.warning("IG ratelimit
|
262
|
-
raise
|
265
|
+
logging.warning("IG ratelimit occurred")
|
266
|
+
raise IGRateLimitOccurred()
|
263
267
|
wait_timeout += timeout_increment
|
264
268
|
logging.info("Waiting %d seconds according configuration option `IG_WAIT_TIMEOUT` with `IG_TIMEOUT_INCREMENT`", wait_timeout)
|
265
269
|
if res:
|
@@ -2,7 +2,6 @@ import os, io
|
|
2
2
|
import signal
|
3
3
|
|
4
4
|
import uvloop
|
5
|
-
import asyncio
|
6
5
|
|
7
6
|
from pyrogram import Client, filters
|
8
7
|
from pyrogram.enums import ParseMode
|
@@ -10,15 +9,13 @@ from pyrogram.handlers import MessageHandler, CallbackQueryHandler
|
|
10
9
|
from pyrogram.types import Message, InputMedia, InputMediaAudio, InputMediaPhoto, InputMediaVideo, InputMediaAnimation, InputMediaDocument, InlineKeyboardButton, InlineKeyboardMarkup
|
11
10
|
from pyrogram.errors import RPCError, FloodWait, NetworkMigrate, BadRequest, MultiMediaTooLong, MessageIdInvalid
|
12
11
|
|
12
|
+
import warp_beacon
|
13
13
|
from warp_beacon.__version__ import __version__
|
14
14
|
from warp_beacon.telegram.handlers import Handlers
|
15
|
-
import warp_beacon.scraper
|
16
15
|
from warp_beacon.telegram.placeholder_message import PlaceholderMessage
|
17
16
|
from warp_beacon.storage import Storage
|
18
17
|
from warp_beacon.uploader import AsyncUploader
|
19
|
-
from warp_beacon.jobs.download_job import DownloadJob
|
20
18
|
from warp_beacon.jobs.upload_job import UploadJob
|
21
|
-
from warp_beacon.jobs import Origin
|
22
19
|
from warp_beacon.jobs.types import JobType
|
23
20
|
from warp_beacon.telegram.utils import Utils
|
24
21
|
|
@@ -30,6 +30,8 @@ warp_beacon/mediainfo/abstract.py
|
|
30
30
|
warp_beacon/mediainfo/audio.py
|
31
31
|
warp_beacon/mediainfo/silencer.py
|
32
32
|
warp_beacon/mediainfo/video.py
|
33
|
+
warp_beacon/scheduler/__init__.py
|
34
|
+
warp_beacon/scheduler/scheduler.py
|
33
35
|
warp_beacon/scraper/__init__.py
|
34
36
|
warp_beacon/scraper/abstract.py
|
35
37
|
warp_beacon/scraper/account_selector.py
|
@@ -11,6 +11,8 @@ warp_beacon/mediainfo/abstract
|
|
11
11
|
warp_beacon/mediainfo/audio
|
12
12
|
warp_beacon/mediainfo/silencer
|
13
13
|
warp_beacon/mediainfo/video
|
14
|
+
warp_beacon/scheduler
|
15
|
+
warp_beacon/scheduler/scheduler
|
14
16
|
warp_beacon/scraper
|
15
17
|
warp_beacon/scraper/abstract
|
16
18
|
warp_beacon/scraper/account_selector
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{warp_beacon-2.1.6/warp_beacon/compress → warp_beacon-2.1.7/warp_beacon/mediainfo}/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{warp_beacon-2.1.6/warp_beacon/mediainfo → warp_beacon-2.1.7/warp_beacon/scheduler}/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|