warp-beacon 1.2.3__tar.gz → 1.2.5__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-1.2.3/warp_beacon.egg-info → warp_beacon-1.2.5}/PKG-INFO +1 -1
- warp_beacon-1.2.5/warp_beacon/__version__.py +2 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/warp_beacon/mediainfo/abstract.py +12 -1
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/warp_beacon/mediainfo/video.py +1 -9
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/warp_beacon/scraper/__init__.py +11 -1
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/warp_beacon/scraper/exceptions.py +3 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/warp_beacon/scraper/youtube/music.py +36 -3
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/warp_beacon/warp_beacon.py +6 -2
- {warp_beacon-1.2.3 → warp_beacon-1.2.5/warp_beacon.egg-info}/PKG-INFO +1 -1
- warp_beacon-1.2.3/warp_beacon/__version__.py +0 -2
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/LICENSE +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/MANIFEST.in +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/README.md +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/assets/placeholder.gif +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/etc/.gitignore +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/etc/warp_beacon.conf +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/etc/warp_beacon.service +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/pyproject.toml +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/setup.cfg +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/setup.py +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/warp_beacon/__init__.py +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/warp_beacon/compress/__init__.py +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/warp_beacon/compress/video.py +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/warp_beacon/jobs/__init__.py +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/warp_beacon/jobs/abstract.py +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/warp_beacon/jobs/download_job.py +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/warp_beacon/jobs/upload_job.py +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/warp_beacon/mediainfo/__init__.py +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/warp_beacon/mediainfo/audio.py +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/warp_beacon/scraper/abstract.py +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/warp_beacon/scraper/instagram.py +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/warp_beacon/scraper/youtube/__init__.py +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/warp_beacon/scraper/youtube/shorts.py +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/warp_beacon/storage/__init__.py +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/warp_beacon/uploader/__init__.py +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/warp_beacon.egg-info/SOURCES.txt +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/warp_beacon.egg-info/dependency_links.txt +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/warp_beacon.egg-info/entry_points.txt +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/warp_beacon.egg-info/requires.txt +0 -0
- {warp_beacon-1.2.3 → warp_beacon-1.2.5}/warp_beacon.egg-info/top_level.txt +0 -0
@@ -1,6 +1,8 @@
|
|
1
1
|
import os
|
2
2
|
from abc import ABC, abstractmethod
|
3
3
|
|
4
|
+
from PIL import Image
|
5
|
+
|
4
6
|
import av
|
5
7
|
|
6
8
|
class MediaInfoAbstract(ABC):
|
@@ -25,4 +27,13 @@ class MediaInfoAbstract(ABC):
|
|
25
27
|
|
26
28
|
@abstractmethod
|
27
29
|
def get_finfo(cls, except_info: tuple=()) -> dict:
|
28
|
-
raise NotImplementedError
|
30
|
+
raise NotImplementedError
|
31
|
+
|
32
|
+
@staticmethod
|
33
|
+
def shrink_image_to_fit(image: Image, size: tuple = (320, 320)) -> Image:
|
34
|
+
image.thumbnail(size, Image.Resampling.LANCZOS)
|
35
|
+
#image.save(
|
36
|
+
# "/tmp/test.th.jpg",
|
37
|
+
# quality=80,
|
38
|
+
#)
|
39
|
+
return image
|
@@ -41,14 +41,6 @@ class VideoInfo(MediaInfoAbstract):
|
|
41
41
|
res["filesize"] = VideoInfo.get_filesize(self.filename)
|
42
42
|
return res
|
43
43
|
|
44
|
-
def shrink_image_to_fit(self, image: Image, size: tuple = (320, 320)) -> Image:
|
45
|
-
image.thumbnail(size, Image.Resampling.LANCZOS)
|
46
|
-
#image.save(
|
47
|
-
# "/tmp/test.th.jpg",
|
48
|
-
# quality=80,
|
49
|
-
#)
|
50
|
-
return image
|
51
|
-
|
52
44
|
def generate_thumbnail(self) -> Union[io.BytesIO, None]:
|
53
45
|
try:
|
54
46
|
image = None
|
@@ -71,7 +63,7 @@ class VideoInfo(MediaInfoAbstract):
|
|
71
63
|
#)
|
72
64
|
#break
|
73
65
|
if image:
|
74
|
-
image =
|
66
|
+
image = VideoInfo.shrink_image_to_fit(image)
|
75
67
|
io_buf = io.BytesIO()
|
76
68
|
image.save(io_buf, format='JPEG')
|
77
69
|
io_buf.seek(0)
|
@@ -5,7 +5,7 @@ from typing import Optional
|
|
5
5
|
import multiprocessing
|
6
6
|
from queue import Empty
|
7
7
|
|
8
|
-
from warp_beacon.scraper.exceptions import NotFound, UnknownError, TimeOut, Unavailable
|
8
|
+
from warp_beacon.scraper.exceptions import NotFound, UnknownError, TimeOut, Unavailable, FileTooBig
|
9
9
|
from warp_beacon.mediainfo.video import VideoInfo
|
10
10
|
from warp_beacon.mediainfo.audio import AudioInfo
|
11
11
|
from warp_beacon.compress.video import VideoCompress
|
@@ -102,6 +102,14 @@ class AsyncDownloader(object):
|
|
102
102
|
job_failed_msg="Failed to download content. Please check you Internet connection or retry amount bot configuration settings.")
|
103
103
|
)
|
104
104
|
break
|
105
|
+
except FileTooBig as e:
|
106
|
+
logging.warning("Telegram limits exceeded :(")
|
107
|
+
logging.exception(e)
|
108
|
+
self.uploader.queue_task(job.to_upload_job(
|
109
|
+
job_failed=True,
|
110
|
+
job_failed_msg="Unfortunately, this file exceeds the telegram limit of 50 megabytes.")
|
111
|
+
)
|
112
|
+
break
|
105
113
|
except (UnknownError, Exception) as e:
|
106
114
|
logging.warning("UnknownError occurred!")
|
107
115
|
logging.exception(e)
|
@@ -146,6 +154,8 @@ class AsyncDownloader(object):
|
|
146
154
|
logging.info("New file size of compressed file is '%.3f'", media_info["filesize"])
|
147
155
|
elif item["media_type"] == "audio":
|
148
156
|
media_info = self.get_media_info(item["local_media_path"], item.get("media_info", {}), "audio")
|
157
|
+
media_info["performer"] = item.get("performer", None)
|
158
|
+
media_info["thumb"] = item.get("thumb", None)
|
149
159
|
logging.info("Final media info: %s", media_info)
|
150
160
|
elif item["media_type"] == "collection":
|
151
161
|
for v in item["items"]:
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import os
|
2
|
+
import io
|
2
3
|
import pathlib
|
3
4
|
import time
|
4
5
|
|
@@ -11,10 +12,13 @@ import requests
|
|
11
12
|
import urllib
|
12
13
|
import http.client
|
13
14
|
|
15
|
+
from PIL import Image
|
16
|
+
|
14
17
|
from pytubefix import YouTube
|
15
18
|
from pytubefix.exceptions import VideoUnavailable, VideoPrivate, MaxRetriesExceeded
|
16
19
|
|
17
|
-
from warp_beacon.
|
20
|
+
from warp_beacon.mediainfo.abstract import MediaInfoAbstract
|
21
|
+
from warp_beacon.scraper.exceptions import NotFound, UnknownError, TimeOut, Unavailable, FileTooBig, extract_exception_message
|
18
22
|
from warp_beacon.scraper.abstract import ScraperAbstract
|
19
23
|
|
20
24
|
import logging
|
@@ -87,11 +91,34 @@ class YoutubeMusicScraper(ScraperAbstract):
|
|
87
91
|
|
88
92
|
return new_filepath
|
89
93
|
|
94
|
+
def download_thumbnail(self, url: str) -> Union[io.BytesIO, None]:
|
95
|
+
try:
|
96
|
+
reply = requests.get(url, stream=True)
|
97
|
+
if reply.ok and reply.status_code == 200:
|
98
|
+
image = Image.open(io.BytesIO(reply.content))
|
99
|
+
image = MediaInfoAbstract.shrink_image_to_fit(image)
|
100
|
+
io_buf = io.BytesIO()
|
101
|
+
image.save(io_buf, format='JPEG')
|
102
|
+
io_buf.seek(0)
|
103
|
+
return io_buf
|
104
|
+
except Exception as e:
|
105
|
+
logging.error("Failed to download download thumbnail!")
|
106
|
+
logging.exception(e)
|
107
|
+
|
108
|
+
return None
|
109
|
+
|
90
110
|
def _download(self, url: str, timeout: int = 0) -> list:
|
91
111
|
res = []
|
112
|
+
thumbnail = None
|
92
113
|
yt = YouTube(url)
|
114
|
+
if yt and yt.thumbnail_url:
|
115
|
+
thumbnail = self.download_thumbnail(yt.thumbnail_url)
|
93
116
|
stream = yt.streams.get_audio_only()
|
94
117
|
if stream:
|
118
|
+
logging.info("Announced audio file size: '%d'", stream.filesize)
|
119
|
+
if stream.filesize > 5e+7:
|
120
|
+
logging.warning("Downloading size reported by YouTube is over than 50 mb!")
|
121
|
+
raise FileTooBig("YouTube file is larger than 50 mb")
|
95
122
|
logging.info("Operation timeout is '%d'", timeout)
|
96
123
|
local_file = stream.download(
|
97
124
|
output_path=DOWNLOAD_DIR,
|
@@ -101,8 +128,14 @@ class YoutubeMusicScraper(ScraperAbstract):
|
|
101
128
|
filename_prefix='yt_download_',
|
102
129
|
mp3=True
|
103
130
|
)
|
104
|
-
logging.
|
105
|
-
res.append({
|
131
|
+
logging.debug("Temp filename: '%s'", local_file)
|
132
|
+
res.append({
|
133
|
+
"local_media_path": self.rename_local_file(local_file),
|
134
|
+
"performer": yt.author,
|
135
|
+
"thumb": thumbnail,
|
136
|
+
"canonical_name": stream.title,
|
137
|
+
"media_type": "audio"
|
138
|
+
})
|
106
139
|
|
107
140
|
return res
|
108
141
|
|
@@ -237,13 +237,17 @@ def build_tg_args(update: Update, context: ContextTypes.DEFAULT_TYPE, job: Uploa
|
|
237
237
|
elif job.media_type == "audio":
|
238
238
|
if job.tg_file_id:
|
239
239
|
if job.placeholder_message_id:
|
240
|
-
args["media"] = InputMediaAudio(
|
240
|
+
args["media"] = InputMediaAudio(
|
241
|
+
media=job.tg_file_id.replace(":audio", '')
|
242
|
+
)
|
241
243
|
else:
|
242
244
|
args["audio"] = job.tg_file_id.replace(":audio", '')
|
243
245
|
else:
|
244
246
|
args["media"] = InputMediaAudio(
|
245
247
|
media=open(job.local_media_path, 'rb'),
|
246
|
-
filename="%s%s" % (job.canonical_name, os.path.splitext(job.local_media_path)[-1])
|
248
|
+
filename="%s%s" % (job.canonical_name, os.path.splitext(job.local_media_path)[-1]),
|
249
|
+
performer=job.media_info["performer"],
|
250
|
+
thumbnail=job.media_info["thumb"]
|
247
251
|
)
|
248
252
|
elif job.media_type == "collection":
|
249
253
|
if job.tg_file_id:
|
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
|
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
|