warp-beacon 2.7.11__py3-none-any.whl → 2.7.13__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.
@@ -1,2 +1,2 @@
1
- __version__ = "2.7.11"
1
+ __version__ = "2.7.13"
2
2
 
@@ -475,7 +475,7 @@ class InstagramScraper(ScraperAbstract):
475
475
  "report_type": ReportType.PROGRESS
476
476
  }
477
477
  self.status_pipe.send(msg)
478
- self._download_progress_threshold += 10
478
+ self._download_progress_threshold += 20
479
479
 
480
480
  def report_seen(self, items: dict) -> None:
481
481
  try:
@@ -13,6 +13,7 @@ from typing import Callable, Optional, Union
13
13
  from urllib.parse import parse_qs, urlparse
14
14
 
15
15
  import numpy as np
16
+ import av
16
17
  import pytubefix
17
18
  import pytubefix.exceptions
18
19
  import requests
@@ -245,7 +246,7 @@ class YoutubeAbstract(ScraperAbstract):
245
246
  self.status_pipe.send(msg)
246
247
  logging.debug("[Download worker] Downloaded %d%%", percentage_of_completion)
247
248
  if total_size > 0:
248
- self._download_progress_threshold += 10
249
+ self._download_progress_threshold += 20
249
250
 
250
251
  def build_proxies(self, proxy_dsn: str) -> dict:
251
252
  if not proxy_dsn:
@@ -310,7 +311,7 @@ class YoutubeAbstract(ScraperAbstract):
310
311
  self.status_pipe.send(msg)
311
312
  logging.debug("[Download worker][yt_dlp] Downloaded %d%%", percentage_of_completion)
312
313
  if total_size > 0:
313
- self._download_progress_threshold += 10
314
+ self._download_progress_threshold += 20
314
315
 
315
316
  def build_yt_dlp(self, timeout: int = 60) -> yt_dlp.YoutubeDL:
316
317
  auth_data = {}
@@ -387,3 +388,30 @@ class YoutubeAbstract(ScraperAbstract):
387
388
  raise Unavailable("Сontent unvailable")
388
389
 
389
390
  return ret
391
+
392
+ def mux_raw_copy(self, video_path: str, audio_path: str, output_path: str) -> str:
393
+ try:
394
+ with av.open(video_path) as input_video, av.open(audio_path) as input_audio, av.open(output_path, mode='w') as output:
395
+ in_video_stream = input_video.streams.video[0]
396
+ in_audio_stream = input_audio.streams.audio[0]
397
+
398
+ video_stream_map = output.add_stream(template=in_video_stream)
399
+ audio_stream_map = output.add_stream(template=in_audio_stream)
400
+
401
+ for packet in input_video.demux(in_video_stream):
402
+ if packet.dts is None:
403
+ continue
404
+ packet.stream = video_stream_map
405
+ output.mux(packet)
406
+
407
+ for packet in input_audio.demux(in_audio_stream):
408
+ if packet.dts is None:
409
+ continue
410
+ packet.stream = audio_stream_map
411
+ output.mux(packet)
412
+ except Exception as e:
413
+ logging.error("Failed to mux audio and video!")
414
+ logging.exception(e)
415
+ return ''
416
+
417
+ return output_path
@@ -1,13 +1,16 @@
1
+ import os
1
2
  import io
2
3
  from typing import Optional
4
+ import time
3
5
 
4
6
  import logging
5
7
 
8
+ from pytubefix.exceptions import AgeRestrictedError
9
+
6
10
  from warp_beacon.jobs.types import JobType
7
11
  from warp_beacon.scraper.youtube.abstract import YoutubeAbstract
8
- from warp_beacon.scraper.exceptions import NotFound
9
12
 
10
- from warp_beacon.mediainfo.video import VideoInfo
13
+ from warp_beacon.scraper.exceptions import NotFound, YotubeAgeRestrictedError
11
14
 
12
15
  class YoutubeShortsScraper(YoutubeAbstract):
13
16
  YT_MAX_RETRIES_DEFAULT = 8
@@ -15,7 +18,14 @@ class YoutubeShortsScraper(YoutubeAbstract):
15
18
  YT_TIMEOUT_DEFAULT = 2
16
19
  YT_TIMEOUT_INCREMENT_DEFAULT = 60
17
20
 
18
- def _download(self, url: str, session: bool = True, thumbnail: Optional[io.BytesIO] = None, timeout: int = 0) -> list:
21
+ def _download(self, url: str, session: bool = True, thumbnail: Optional[io.BytesIO] = None, timeout: int = 60) -> list:
22
+ res = self._download_pytubefix_max_res(url=url, session=session, thumbnail=thumbnail, timeout=timeout)
23
+ if not res:
24
+ res = self._download_pytube_dash(url=url, session=session, thumbnail=thumbnail, timeout=timeout)
25
+
26
+ return res
27
+
28
+ def _download_pytube_dash(self, url: str, session: bool = True, thumbnail: Optional[io.BytesIO] = None, timeout: int = 0) -> list:
19
29
  res = []
20
30
  yt = self.build_yt(url, session=session)
21
31
  stream = yt.streams.get_highest_resolution()
@@ -58,4 +68,57 @@ class YoutubeShortsScraper(YoutubeAbstract):
58
68
  "media_type": JobType.VIDEO
59
69
  })
60
70
 
71
+ return res
72
+
73
+ def _download_pytubefix_max_res(self, url: str, session: bool = True, thumbnail: Optional[io.BytesIO] = None, timeout: int = 60) -> list:
74
+ res = []
75
+ local_video_file, local_audio_file = '', ''
76
+ try:
77
+ yt = self.build_yt(url, session=session)
78
+
79
+ video_stream = yt.streams.filter(adaptive=True, file_extension='mp4', only_video=True).order_by('resolution').desc().first()
80
+ audio_stream = yt.streams.filter(adaptive=True, file_extension='mp4', only_audio=True).order_by('abr').desc().first()
81
+
82
+ local_video_file = video_stream.download(
83
+ output_path=self.DOWNLOAD_DIR,
84
+ max_retries=3,
85
+ timeout=timeout,
86
+ skip_existing=False,
87
+ filename_prefix="yt_download_video_"
88
+ )
89
+ local_video_file = self.rename_local_file(local_video_file)
90
+ logging.debug("Temp video filename: '%s'", local_video_file)
91
+ local_audio_file = audio_stream.download(
92
+ output_path=self.DOWNLOAD_DIR,
93
+ max_retries=3,
94
+ timeout=timeout,
95
+ skip_existing=False,
96
+ filename_prefix="yt_download_audio_"
97
+ )
98
+ local_audio_file = self.rename_local_file(local_audio_file)
99
+ logging.debug("Temp audio filename: '%s'", local_audio_file)
100
+
101
+ muxed_video = self.mux_raw_copy(
102
+ video_path=local_video_file,
103
+ audio_path=local_audio_file,
104
+ output_path=f"{self.DOWNLOAD_DIR}/yt_muxed_video_{int(time.time())}.mp4")
105
+ if muxed_video:
106
+ muxed_video = self.rename_local_file(muxed_video)
107
+ logging.debug("Temp muxed filename: '%s'", muxed_video)
108
+
109
+ res.append({
110
+ "local_media_path": muxed_video,
111
+ "performer": yt.author,
112
+ "thumb": thumbnail,
113
+ "canonical_name": yt.title,
114
+ "media_type": JobType.VIDEO
115
+ })
116
+ except AgeRestrictedError as e:
117
+ raise YotubeAgeRestrictedError("Youtube Age Restricted error")
118
+ finally:
119
+ if os.path.exists(local_video_file):
120
+ os.unlink(local_video_file)
121
+ if os.path.exists(local_audio_file):
122
+ os.unlink(local_audio_file)
123
+
61
124
  return res
@@ -4,7 +4,6 @@ import io
4
4
  from typing import Optional
5
5
  import logging
6
6
 
7
- import av
8
7
  from pytubefix.exceptions import AgeRestrictedError
9
8
 
10
9
  from warp_beacon.jobs.types import JobType
@@ -39,33 +38,6 @@ class YoutubeScraper(YoutubeAbstract):
39
38
  res = self._download_pytube_dash(url=url, session=session, thumbnail=thumbnail, timeout=timeout)
40
39
 
41
40
  return res
42
-
43
- def mux_raw_copy(self, video_path: str, audio_path: str, output_path: str) -> str:
44
- try:
45
- with av.open(video_path) as input_video, av.open(audio_path) as input_audio, av.open(output_path, mode='w') as output:
46
- in_video_stream = input_video.streams.video[0]
47
- in_audio_stream = input_audio.streams.audio[0]
48
-
49
- video_stream_map = output.add_stream(template=in_video_stream)
50
- audio_stream_map = output.add_stream(template=in_audio_stream)
51
-
52
- for packet in input_video.demux(in_video_stream):
53
- if packet.dts is None:
54
- continue
55
- packet.stream = video_stream_map
56
- output.mux(packet)
57
-
58
- for packet in input_audio.demux(in_audio_stream):
59
- if packet.dts is None:
60
- continue
61
- packet.stream = audio_stream_map
62
- output.mux(packet)
63
- except Exception as e:
64
- logging.error("Failed to mux audio and video!")
65
- logging.exception(e)
66
- return ''
67
-
68
- return output_path
69
41
 
70
42
  def _download_pytubefix_max_res(self, url: str, session: bool = True, thumbnail: Optional[io.BytesIO] = None, timeout: int = 60) -> list:
71
43
  res = []
@@ -125,7 +125,7 @@ class ProgressBar(object):
125
125
  logging.warning("An error occurred while setup task to update progress bar")
126
126
  logging.exception(e)
127
127
  if total > 0 and percent != 0:
128
- self._next_threshold += 15
128
+ self._next_threshold += 20
129
129
 
130
130
  @staticmethod
131
131
  def make_hash(chat_id: str | int, message_id: int, algorithm: str = 'sha256') -> str:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: warp_beacon
3
- Version: 2.7.11
3
+ Version: 2.7.13
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
@@ -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=lqKHRYdVpzdXmWoJV13ehvNCGpYmFAl2Y41YmvWzQXo,24
7
+ warp_beacon/__version__.py,sha256=x219y8Xqh6qOh4lcwrZPGXW00waIfTBdHsot4GpeNiI,24
8
8
  warp_beacon/warp_beacon.py,sha256=ADCR30uGXIsDrt9WoiI9Ghu2QtWs0qZIK6x3pQKM_B4,1109
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
@@ -31,13 +31,13 @@ warp_beacon/scraper/link_resolver.py,sha256=Rc9ZuMyOo3iPywDHwjngy-WRQ2SXhJwxcg-5
31
31
  warp_beacon/scraper/utils.py,sha256=yL-nrdCOAXNZgmIFPurIYFHfPsxHDl8pqif6BYKrzJI,1218
32
32
  warp_beacon/scraper/instagram/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
33
  warp_beacon/scraper/instagram/captcha.py,sha256=9UYziuqB3Tsat_ET6ex-cnZDbi6yCnsXHSpmE8MuUHk,4651
34
- warp_beacon/scraper/instagram/instagram.py,sha256=qypIbRLPiOn98n9DOFlkU7X2Ux-cOSu7skJAO2JudIQ,18629
34
+ warp_beacon/scraper/instagram/instagram.py,sha256=oVXP6VweJCeffhyDU-GZLa66ESW06GvfuGcW2V6YdQ4,18629
35
35
  warp_beacon/scraper/instagram/wb_instagrapi.py,sha256=M5NCtLwdUvByjmDBZMWljgB275R0LSBFblsGpapluD0,5968
36
36
  warp_beacon/scraper/youtube/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
- warp_beacon/scraper/youtube/abstract.py,sha256=yQCJzi5YCEJFr365uPnMzKB8Rmi_zKVIlxw9-DI3sKE,15278
37
+ warp_beacon/scraper/youtube/abstract.py,sha256=H53RjCGB5W-uvKEgFrPn0kSBxc8EQgpme-9DJF9I7rU,16193
38
38
  warp_beacon/scraper/youtube/music.py,sha256=5AeSBQyUgVCJT2hoBCV2WvlyuV9US09SYJhmBG_P9F8,2755
39
- warp_beacon/scraper/youtube/shorts.py,sha256=1GtoYUlxAwcgSQcn80u5ehNJytH5AN5dPOicmX-XD8E,1705
40
- warp_beacon/scraper/youtube/youtube.py,sha256=x9v9p1coA9TvBhxjNAofGu4UBkAEdYPE2ePRnU-5tK0,7233
39
+ warp_beacon/scraper/youtube/shorts.py,sha256=y0591kpWU35rt5OoWamkcHIstNZ98SXUlUKvYmUsyEY,4030
40
+ warp_beacon/scraper/youtube/youtube.py,sha256=i-3Z5l3S-EltIFbxkbvDjXMgH8fGOrB5-ua1p6iH_Bc,6316
41
41
  warp_beacon/storage/__init__.py,sha256=0Vajd0oITKJfu2vmNx5uQSt3-L6vwIvUYWJo8HZCjco,3398
42
42
  warp_beacon/storage/mongo.py,sha256=qC4ZiO8XXvPnP0rJwz4CJx42pqFsyAjCiW10W5QdT6E,527
43
43
  warp_beacon/telegram/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -47,14 +47,14 @@ warp_beacon/telegram/download_status.py,sha256=N-Qg13LVcPskyQNKG1lw50K1lhFtXu003
47
47
  warp_beacon/telegram/edit_message.py,sha256=6DX8eJV70MG_b79WbuJG55qLBs66boElzYdCr8zpMeI,5380
48
48
  warp_beacon/telegram/handlers.py,sha256=PaO90370v-S90nwr4PYMzrlHRFBU0VBO6YkqDqTbnjw,9634
49
49
  warp_beacon/telegram/placeholder_message.py,sha256=wN9-BRiyrtHG-EvXtZkGJHt2CX71munQ57ITttjt0mw,6400
50
- warp_beacon/telegram/progress_bar.py,sha256=T0YR-I159mB-X1IwSN3Kppz3rKDDUZLPz9pe_voSFR4,5014
50
+ warp_beacon/telegram/progress_bar.py,sha256=IP4xtvLtdJtqdr2C-0YaU428iQGrKurbP4Npr31iW74,5014
51
51
  warp_beacon/telegram/progress_file_reader.py,sha256=e3equyNKlKs764AD-iE9QRsh3YDHTzP78Mx5tdvPPWs,969
52
52
  warp_beacon/telegram/types.py,sha256=Kvdng6uCF1HRoqQgGW1ZYYPJoVuYkFb-LDvMBbW5Hjk,89
53
53
  warp_beacon/telegram/utils.py,sha256=S1N_JbHM_ExiM5tS0CeYKWIlvaJMlyq85TQNbK_GVds,5029
54
54
  warp_beacon/uploader/__init__.py,sha256=ewvR60k9osJxw_kb5U-TlZkCGR_574biq3w_aR1tjIU,5689
55
- warp_beacon-2.7.11.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
56
- warp_beacon-2.7.11.dist-info/METADATA,sha256=C8Y4rTMfgyxlL2A13F6qEFy4UZr_KNLeTOYNZhAfkGg,23215
57
- warp_beacon-2.7.11.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
58
- warp_beacon-2.7.11.dist-info/entry_points.txt,sha256=eSB61Rb89d56WY0O-vEIQwkn18J-4CMrJcLA_R_8h3g,119
59
- warp_beacon-2.7.11.dist-info/top_level.txt,sha256=5YQRN46STNg81V_3jdzZ6bftkMxhe1hTPSFvJugDu84,1405
60
- warp_beacon-2.7.11.dist-info/RECORD,,
55
+ warp_beacon-2.7.13.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
56
+ warp_beacon-2.7.13.dist-info/METADATA,sha256=wRZPk7SRIYDZ9xSsAVfRdW_TK206mInTQIiZYLRD_sY,23215
57
+ warp_beacon-2.7.13.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
58
+ warp_beacon-2.7.13.dist-info/entry_points.txt,sha256=eSB61Rb89d56WY0O-vEIQwkn18J-4CMrJcLA_R_8h3g,119
59
+ warp_beacon-2.7.13.dist-info/top_level.txt,sha256=5YQRN46STNg81V_3jdzZ6bftkMxhe1hTPSFvJugDu84,1405
60
+ warp_beacon-2.7.13.dist-info/RECORD,,