eaf-base-api 1.5__tar.gz → 1.6.1__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.
- {eaf_base_api-1.5 → eaf_base_api-1.6.1}/PKG-INFO +1 -1
- {eaf_base_api-1.5 → eaf_base_api-1.6.1}/base_api/base.py +43 -13
- eaf_base_api-1.6.1/base_api/modules/consts.py +3 -0
- {eaf_base_api-1.5 → eaf_base_api-1.6.1}/eaf_base_api.egg-info/PKG-INFO +1 -1
- {eaf_base_api-1.5 → eaf_base_api-1.6.1}/setup.py +1 -1
- eaf_base_api-1.5/base_api/modules/consts.py +0 -2
- {eaf_base_api-1.5 → eaf_base_api-1.6.1}/README.md +0 -0
- {eaf_base_api-1.5 → eaf_base_api-1.6.1}/base_api/__init__.py +0 -0
- {eaf_base_api-1.5 → eaf_base_api-1.6.1}/base_api/modules/__init__.py +0 -0
- {eaf_base_api-1.5 → eaf_base_api-1.6.1}/base_api/modules/download.py +0 -0
- {eaf_base_api-1.5 → eaf_base_api-1.6.1}/base_api/modules/progress_bars.py +0 -0
- {eaf_base_api-1.5 → eaf_base_api-1.6.1}/base_api/modules/quality.py +0 -0
- {eaf_base_api-1.5 → eaf_base_api-1.6.1}/eaf_base_api.egg-info/SOURCES.txt +0 -0
- {eaf_base_api-1.5 → eaf_base_api-1.6.1}/eaf_base_api.egg-info/dependency_links.txt +0 -0
- {eaf_base_api-1.5 → eaf_base_api-1.6.1}/eaf_base_api.egg-info/requires.txt +0 -0
- {eaf_base_api-1.5 → eaf_base_api-1.6.1}/eaf_base_api.egg-info/top_level.txt +0 -0
- {eaf_base_api-1.5 → eaf_base_api-1.6.1}/setup.cfg +0 -0
|
@@ -2,11 +2,12 @@ import requests
|
|
|
2
2
|
import logging
|
|
3
3
|
import time
|
|
4
4
|
import string
|
|
5
|
+
import os
|
|
5
6
|
|
|
6
7
|
from base_api.modules.quality import Quality
|
|
7
8
|
from base_api.modules.progress_bars import Callback
|
|
8
9
|
from base_api.modules.download import default, threaded, FFMPEG
|
|
9
|
-
from base_api.modules.consts import MAX_RETRIES
|
|
10
|
+
from base_api.modules.consts import MAX_RETRIES, REQUEST_DELAY
|
|
10
11
|
from pathlib import Path
|
|
11
12
|
|
|
12
13
|
|
|
@@ -19,14 +20,24 @@ def setup_api(do_logging=False):
|
|
|
19
20
|
logging.disable(logging.CRITICAL)
|
|
20
21
|
|
|
21
22
|
|
|
22
|
-
base_qualities = ["250p", "360p", "480p", "720p", "1080p", "1440p", "2160p"]
|
|
23
|
-
|
|
24
|
-
|
|
25
23
|
class Core:
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
def __init__(self, delay=REQUEST_DELAY):
|
|
25
|
+
self.delay = delay
|
|
26
|
+
self.start_delay = False
|
|
27
|
+
self.last_request_time = None
|
|
28
|
+
|
|
29
|
+
def get_content(self, url, headers=None, cookies=None, stream=False):
|
|
28
30
|
for i in range(MAX_RETRIES):
|
|
29
31
|
try:
|
|
32
|
+
|
|
33
|
+
# Delay mechanism
|
|
34
|
+
if self.last_request_time:
|
|
35
|
+
elapsed_time = time.time() - self.last_request_time
|
|
36
|
+
if elapsed_time < self.delay:
|
|
37
|
+
time.sleep(self.delay - elapsed_time)
|
|
38
|
+
|
|
39
|
+
self.last_request_time = time.time() # Update the time of the last request
|
|
40
|
+
|
|
30
41
|
logging.debug(f"Trying to fetch {url} / Attempt: [{i+1}]")
|
|
31
42
|
response = requests.get(url, headers=headers, cookies=cookies, stream=stream)
|
|
32
43
|
if response.status_code == 200:
|
|
@@ -57,7 +68,7 @@ class Core:
|
|
|
57
68
|
elif str(quality) == "worst":
|
|
58
69
|
return Quality.WORST
|
|
59
70
|
|
|
60
|
-
def get_available_qualities(self, m3u8_base_url):
|
|
71
|
+
def get_available_qualities(self, m3u8_base_url, base_qualities, seperator):
|
|
61
72
|
"""Returns the available qualities from the M3U8 base url"""
|
|
62
73
|
content = self.get_content(m3u8_base_url).decode("utf-8")
|
|
63
74
|
lines = content.splitlines()
|
|
@@ -66,18 +77,18 @@ class Core:
|
|
|
66
77
|
|
|
67
78
|
for line in lines:
|
|
68
79
|
for quality in base_qualities:
|
|
69
|
-
if f"
|
|
80
|
+
if f"{seperator}{quality}" in line and not str(line).startswith("#"):
|
|
70
81
|
quality_url_map[quality] = line
|
|
71
82
|
|
|
72
83
|
self.quality_url_map = quality_url_map
|
|
73
84
|
self.available_qualities = list(quality_url_map.keys())
|
|
74
85
|
return self.available_qualities
|
|
75
86
|
|
|
76
|
-
def get_m3u8_by_quality(self, quality, m3u8_base_url):
|
|
87
|
+
def get_m3u8_by_quality(self, quality, m3u8_base_url, base_qualities, seperator):
|
|
77
88
|
"""Returns the m3u8 url for the given quality"""
|
|
78
89
|
quality = self.fix_quality(quality)
|
|
79
90
|
|
|
80
|
-
self.get_available_qualities(m3u8_base_url)
|
|
91
|
+
self.get_available_qualities(m3u8_base_url, base_qualities, seperator=seperator)
|
|
81
92
|
if quality == Quality.BEST:
|
|
82
93
|
selected_quality = max(self.available_qualities, key=lambda q: base_qualities.index(q))
|
|
83
94
|
elif quality == Quality.WORST:
|
|
@@ -117,10 +128,11 @@ class Core:
|
|
|
117
128
|
return Path(path)
|
|
118
129
|
|
|
119
130
|
@classmethod
|
|
120
|
-
def get_segments(cls, quality, m3u8_base_url):
|
|
131
|
+
def get_segments(cls, quality, m3u8_base_url, base_qualities, seperator, source=1):
|
|
121
132
|
quality = Core().fix_quality(quality)
|
|
122
133
|
base_url = m3u8_base_url
|
|
123
|
-
new_segment = Core().get_m3u8_by_quality(quality, m3u8_base_url=base_url
|
|
134
|
+
new_segment = Core().get_m3u8_by_quality(quality, m3u8_base_url=base_url, base_qualities=base_qualities,
|
|
135
|
+
seperator=seperator)
|
|
124
136
|
# Split the base URL into components
|
|
125
137
|
url_components = base_url.split('/')
|
|
126
138
|
|
|
@@ -129,6 +141,10 @@ class Core:
|
|
|
129
141
|
|
|
130
142
|
# Rejoin the components into the new full URL
|
|
131
143
|
new_url = '/'.join(url_components)
|
|
144
|
+
|
|
145
|
+
if source == "spankbang":
|
|
146
|
+
new_url = new_url.split(".mp4.urlset/")[1] # Please just don't ask, I'm a terrible programmer fr
|
|
147
|
+
|
|
132
148
|
master_src = Core().get_content(url=new_url).decode("utf-8")
|
|
133
149
|
|
|
134
150
|
urls = [l for l in master_src.splitlines()
|
|
@@ -151,4 +167,18 @@ class Core:
|
|
|
151
167
|
"""
|
|
152
168
|
illegal_chars = '<>:"/\\|?*'
|
|
153
169
|
cleaned_title = ''.join([char for char in title if char in string.printable and char not in illegal_chars])
|
|
154
|
-
return cleaned_title
|
|
170
|
+
return cleaned_title
|
|
171
|
+
|
|
172
|
+
@classmethod
|
|
173
|
+
def return_path(cls, video, args):
|
|
174
|
+
path = args.output
|
|
175
|
+
if args.use_title:
|
|
176
|
+
if not str(path).endswith(os.sep):
|
|
177
|
+
path += os.sep
|
|
178
|
+
|
|
179
|
+
path += video.title + ".mp4"
|
|
180
|
+
|
|
181
|
+
else:
|
|
182
|
+
path = args.output
|
|
183
|
+
|
|
184
|
+
return path
|
|
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
|