warp-beacon 1.2.4__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.4/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.4 → warp_beacon-1.2.5}/warp_beacon/mediainfo/abstract.py +12 -1
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/warp_beacon/mediainfo/video.py +1 -9
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/warp_beacon/scraper/__init__.py +2 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/warp_beacon/scraper/youtube/music.py +31 -2
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/warp_beacon/warp_beacon.py +6 -2
- {warp_beacon-1.2.4 → warp_beacon-1.2.5/warp_beacon.egg-info}/PKG-INFO +1 -1
- warp_beacon-1.2.4/warp_beacon/__version__.py +0 -2
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/LICENSE +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/MANIFEST.in +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/README.md +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/assets/placeholder.gif +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/etc/.gitignore +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/etc/warp_beacon.conf +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/etc/warp_beacon.service +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/pyproject.toml +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/setup.cfg +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/setup.py +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/warp_beacon/__init__.py +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/warp_beacon/compress/__init__.py +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/warp_beacon/compress/video.py +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/warp_beacon/jobs/__init__.py +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/warp_beacon/jobs/abstract.py +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/warp_beacon/jobs/download_job.py +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/warp_beacon/jobs/upload_job.py +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/warp_beacon/mediainfo/__init__.py +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/warp_beacon/mediainfo/audio.py +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/warp_beacon/scraper/abstract.py +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/warp_beacon/scraper/exceptions.py +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/warp_beacon/scraper/instagram.py +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/warp_beacon/scraper/youtube/__init__.py +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/warp_beacon/scraper/youtube/shorts.py +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/warp_beacon/storage/__init__.py +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/warp_beacon/uploader/__init__.py +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/warp_beacon.egg-info/SOURCES.txt +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/warp_beacon.egg-info/dependency_links.txt +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/warp_beacon.egg-info/entry_points.txt +0 -0
- {warp_beacon-1.2.4 → warp_beacon-1.2.5}/warp_beacon.egg-info/requires.txt +0 -0
- {warp_beacon-1.2.4 → 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)
|
@@ -154,6 +154,8 @@ class AsyncDownloader(object):
|
|
154
154
|
logging.info("New file size of compressed file is '%.3f'", media_info["filesize"])
|
155
155
|
elif item["media_type"] == "audio":
|
156
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)
|
157
159
|
logging.info("Final media info: %s", media_info)
|
158
160
|
elif item["media_type"] == "collection":
|
159
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,9 +12,12 @@ 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
|
|
20
|
+
from warp_beacon.mediainfo.abstract import MediaInfoAbstract
|
17
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
|
|
@@ -87,9 +91,28 @@ 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:
|
95
118
|
logging.info("Announced audio file size: '%d'", stream.filesize)
|
@@ -105,8 +128,14 @@ class YoutubeMusicScraper(ScraperAbstract):
|
|
105
128
|
filename_prefix='yt_download_',
|
106
129
|
mp3=True
|
107
130
|
)
|
108
|
-
logging.
|
109
|
-
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
|
+
})
|
110
139
|
|
111
140
|
return res
|
112
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
|
File without changes
|