Spaces:
Paused
Paused
Commit ·
e07bd3d
1
Parent(s): 64a6f97
Update Iwara and Rule34
Browse files
app.py
CHANGED
|
@@ -27,7 +27,11 @@ if selected:
|
|
| 27 |
if selected == 'Youtube' or selected == 'Pornhub':
|
| 28 |
video_link = st.text_input("Link Video", value='https://www.youtube.com/watch?v=tFSfPmqbfKU')
|
| 29 |
resolution = st.selectbox("Pilih Resolusi", (360, 480, 720), 2)
|
| 30 |
-
elif selected == 'Iwara'
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
name = st.text_input("Nama File")
|
| 32 |
video_link = st.text_input("Link Video")
|
| 33 |
elif selected == 'Cek Video':
|
|
@@ -84,7 +88,9 @@ if selected:
|
|
| 84 |
if st.button(f"Download and Cut {selected}"):
|
| 85 |
if selected == 'Youtube' or selected == 'Pornhub':
|
| 86 |
video_file, judul_video, video_info, thumbnail_file = fungsi(video_link, resolution)
|
| 87 |
-
elif selected == 'Iwara'
|
|
|
|
|
|
|
| 88 |
video_file, judul_video, video_info, thumbnail_file = fungsi(video_link, name)
|
| 89 |
else:
|
| 90 |
video_file, judul_video, video_info, thumbnail_file = fungsi(video_link)
|
|
@@ -99,7 +105,9 @@ if selected:
|
|
| 99 |
if st.button(f"Download and Compress {selected}"):
|
| 100 |
if selected == 'Youtube' or selected == 'Pornhub':
|
| 101 |
video_file, judul_video, video_info, thumbnail_file = fungsi(video_link, resolution)
|
| 102 |
-
elif selected == 'Iwara'
|
|
|
|
|
|
|
| 103 |
video_file, judul_video, video_info, thumbnail_file = fungsi(video_link, name)
|
| 104 |
else:
|
| 105 |
video_file, judul_video, video_info, thumbnail_file = fungsi(video_link)
|
|
@@ -112,10 +120,12 @@ if selected:
|
|
| 112 |
if st.button(f"Download {selected}"):
|
| 113 |
if selected == 'Youtube' or selected == 'Pornhub':
|
| 114 |
video_file, judul_video, video_info, thumbnail_file = fungsi(video_link, resolution)
|
| 115 |
-
elif selected == 'Iwara'
|
|
|
|
|
|
|
| 116 |
video_file, judul_video, video_info, thumbnail_file = fungsi(video_link, name)
|
| 117 |
else:
|
| 118 |
video_file, judul_video, video_info, thumbnail_file = fungsi(video_link)
|
| 119 |
file_size = os.path.getsize(video_file)
|
| 120 |
session(video_info, video_file, thumbnail_file, choice)
|
| 121 |
-
st.text_input(f"Video '{judul_video}' setelah diproses:", convert_size(file_size))
|
|
|
|
| 27 |
if selected == 'Youtube' or selected == 'Pornhub':
|
| 28 |
video_link = st.text_input("Link Video", value='https://www.youtube.com/watch?v=tFSfPmqbfKU')
|
| 29 |
resolution = st.selectbox("Pilih Resolusi", (360, 480, 720), 2)
|
| 30 |
+
elif selected == 'Iwara':
|
| 31 |
+
username = st.text_input("Username")
|
| 32 |
+
password = st.text_input("Password")
|
| 33 |
+
video_link = st.text_input("Link Video")
|
| 34 |
+
elif selected == 'Mega':
|
| 35 |
name = st.text_input("Nama File")
|
| 36 |
video_link = st.text_input("Link Video")
|
| 37 |
elif selected == 'Cek Video':
|
|
|
|
| 88 |
if st.button(f"Download and Cut {selected}"):
|
| 89 |
if selected == 'Youtube' or selected == 'Pornhub':
|
| 90 |
video_file, judul_video, video_info, thumbnail_file = fungsi(video_link, resolution)
|
| 91 |
+
elif selected == 'Iwara':
|
| 92 |
+
video_file, judul_video, video_info, thumbnail_file = fungsi(video_link, username, password)
|
| 93 |
+
elif selected == 'Mega':
|
| 94 |
video_file, judul_video, video_info, thumbnail_file = fungsi(video_link, name)
|
| 95 |
else:
|
| 96 |
video_file, judul_video, video_info, thumbnail_file = fungsi(video_link)
|
|
|
|
| 105 |
if st.button(f"Download and Compress {selected}"):
|
| 106 |
if selected == 'Youtube' or selected == 'Pornhub':
|
| 107 |
video_file, judul_video, video_info, thumbnail_file = fungsi(video_link, resolution)
|
| 108 |
+
elif selected == 'Iwara':
|
| 109 |
+
video_file, judul_video, video_info, thumbnail_file = fungsi(video_link, username, password)
|
| 110 |
+
elif selected == 'Mega':
|
| 111 |
video_file, judul_video, video_info, thumbnail_file = fungsi(video_link, name)
|
| 112 |
else:
|
| 113 |
video_file, judul_video, video_info, thumbnail_file = fungsi(video_link)
|
|
|
|
| 120 |
if st.button(f"Download {selected}"):
|
| 121 |
if selected == 'Youtube' or selected == 'Pornhub':
|
| 122 |
video_file, judul_video, video_info, thumbnail_file = fungsi(video_link, resolution)
|
| 123 |
+
elif selected == 'Iwara':
|
| 124 |
+
video_file, judul_video, video_info, thumbnail_file = fungsi(video_link, username, password)
|
| 125 |
+
elif selected == 'Mega':
|
| 126 |
video_file, judul_video, video_info, thumbnail_file = fungsi(video_link, name)
|
| 127 |
else:
|
| 128 |
video_file, judul_video, video_info, thumbnail_file = fungsi(video_link)
|
| 129 |
file_size = os.path.getsize(video_file)
|
| 130 |
session(video_info, video_file, thumbnail_file, choice)
|
| 131 |
+
st.text_input(f"Video '{judul_video}' setelah diproses:", convert_size(file_size))
|
iwara.py
CHANGED
|
@@ -5,7 +5,6 @@ api_url = 'https://api.iwara.tv'
|
|
| 5 |
file_url = 'https://files.iwara.tv'
|
| 6 |
|
| 7 |
class BearerAuth(requests.auth.AuthBase):
|
| 8 |
-
"""Bearer Authentication"""
|
| 9 |
def __init__(self, token):
|
| 10 |
self.token = token
|
| 11 |
|
|
@@ -17,30 +16,12 @@ class ApiClient:
|
|
| 17 |
def __init__(self, email, password):
|
| 18 |
self.email = email
|
| 19 |
self.password = password
|
| 20 |
-
|
| 21 |
-
# self.headers = {
|
| 22 |
-
# 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36',
|
| 23 |
-
# 'X-Version': 's'
|
| 24 |
-
# }
|
| 25 |
-
|
| 26 |
-
# API
|
| 27 |
self.api_url = api_url
|
| 28 |
self.file_url = file_url
|
| 29 |
self.timeout = 30
|
| 30 |
-
# self.max_retries = 5
|
| 31 |
self.download_timeout = 300
|
| 32 |
self.token = None
|
| 33 |
|
| 34 |
-
# HTML
|
| 35 |
-
# self.html_url = html_url
|
| 36 |
-
|
| 37 |
-
# Cloudscraper
|
| 38 |
-
# self.scraper = cloudscraper.create_scraper(browser={'browser': 'firefox','platform': 'windows','mobile': False},
|
| 39 |
-
# # interpreter = 'nodejs'
|
| 40 |
-
# )
|
| 41 |
-
# Requests-html
|
| 42 |
-
# self.session = HTMLSession()
|
| 43 |
-
|
| 44 |
def login(self) -> requests.Response:
|
| 45 |
url = self.api_url + '/user/login'
|
| 46 |
json = {'email': self.email, 'password': self.password}
|
|
@@ -50,312 +31,141 @@ class ApiClient:
|
|
| 50 |
print('API Login success')
|
| 51 |
except:
|
| 52 |
print('API Login failed')
|
| 53 |
-
|
| 54 |
-
# try:
|
| 55 |
-
# # Cloudscraper
|
| 56 |
-
# # r = self.scraper.post(url, json=json, headers=self.headers, timeout=self.timeout)
|
| 57 |
-
|
| 58 |
-
# # Requests-html
|
| 59 |
-
# r = self.session.post(url, json=json, headers=self.headers, timeout=self.timeout)
|
| 60 |
-
# except:
|
| 61 |
-
# print('BS4 Login failed')
|
| 62 |
-
|
| 63 |
return r
|
| 64 |
|
| 65 |
-
|
| 66 |
-
def get_videos(self, sort = 'date', rating = 'all', page = 0, limit = 32, subscribed = False) -> requests.Response:
|
| 67 |
-
"""# Get new videos from iwara.tv
|
| 68 |
-
- sort: date, trending, popularity, views, likes
|
| 69 |
-
- rating: all, general, ecchi
|
| 70 |
-
"""
|
| 71 |
url = self.api_url + '/videos'
|
| 72 |
-
params = {'sort': sort,
|
| 73 |
-
'rating': rating,
|
| 74 |
-
'page': page,
|
| 75 |
-
'limit': limit,
|
| 76 |
-
'subscribed': 'true' if subscribed else 'false',
|
| 77 |
-
}
|
| 78 |
if self.token is None:
|
| 79 |
r = requests.get(url, params=params, timeout=self.timeout)
|
| 80 |
else:
|
| 81 |
-
|
| 82 |
-
# Verbose Debug
|
| 83 |
-
# request = requests.Request('GET', url, params=params, auth=BearerAuth(self.token))
|
| 84 |
-
# print(request.prepare().method, request.prepare().url, request.prepare().headers, request.prepare().body, sep='\n')
|
| 85 |
-
# r = requests.Session().send(request.prepare())
|
| 86 |
-
|
| 87 |
r = requests.get(url, params=params, auth=BearerAuth(self.token), timeout=self.timeout)
|
| 88 |
-
|
| 89 |
-
#Debug
|
| 90 |
-
print("[DEBUG] get_videos response:", r)
|
| 91 |
-
|
| 92 |
return r
|
| 93 |
-
|
| 94 |
def get_video(self, video_id) -> requests.Response:
|
| 95 |
-
"""# Get video info from iwara.tv
|
| 96 |
-
"""
|
| 97 |
url = self.api_url + '/video/' + video_id
|
| 98 |
-
|
| 99 |
if self.token is None:
|
| 100 |
r = requests.get(url, timeout=self.timeout)
|
| 101 |
else:
|
| 102 |
r = requests.get(url, auth=BearerAuth(self.token), timeout=self.timeout)
|
| 103 |
-
|
| 104 |
-
#Debug
|
| 105 |
-
print("[DEBUG] get_video response:", r)
|
| 106 |
-
|
| 107 |
return r
|
| 108 |
-
|
| 109 |
def download_video_thumbnail(self, video_id) -> str:
|
| 110 |
-
"""# Download video thumbnail from iwara.tv
|
| 111 |
-
"""
|
| 112 |
video = self.get_video(video_id).json()
|
| 113 |
-
|
| 114 |
file_id = video['file']['id']
|
| 115 |
thumbnail_id = video['thumbnail']
|
| 116 |
-
|
| 117 |
url = self.file_url + '/image/original/' + file_id + '/thumbnail-{:02d}.jpg'.format(thumbnail_id)
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 123 |
return thumbnail_file_name
|
| 124 |
-
|
| 125 |
print(f"Downloading thumbnail for video ID: {video_id} ...")
|
| 126 |
-
with open(thumbnail_file_name,
|
| 127 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 128 |
if chunk:
|
| 129 |
f.write(chunk)
|
| 130 |
-
|
| 131 |
|
|
|
|
| 132 |
return thumbnail_file_name
|
| 133 |
|
| 134 |
def download_video(self, video_id) -> str:
|
| 135 |
-
"""# Download video from iwara.tv
|
| 136 |
-
"""
|
| 137 |
-
|
| 138 |
-
# html
|
| 139 |
-
# url = self.html_url + '/video/' + video_id
|
| 140 |
-
|
| 141 |
-
# Cloudscraer
|
| 142 |
-
# html = self.scraper.get(url, auth=BearerAuth(self.token), timeout=self.timeout).text
|
| 143 |
-
|
| 144 |
-
# Requests-html
|
| 145 |
-
# html = self.session.get(url, auth=BearerAuth(self.token), timeout=self.timeout).text
|
| 146 |
-
|
| 147 |
-
# print(html)
|
| 148 |
-
# html = BeautifulSoup(, 'html.parser')
|
| 149 |
-
# downloadLink = html.find('div', class_='dropdown_content')
|
| 150 |
-
# print(downloadLink)
|
| 151 |
-
|
| 152 |
-
# API
|
| 153 |
try:
|
| 154 |
video = self.get_video(video_id).json()
|
| 155 |
except Exception as e:
|
| 156 |
raise Exception(f"Failed to get video info for video ID: {video_id}, error: {e}")
|
| 157 |
-
|
| 158 |
-
#Debug
|
| 159 |
-
print(video)
|
| 160 |
-
|
| 161 |
url = video['fileUrl']
|
| 162 |
file_id = video['file']['id']
|
| 163 |
expires = url.split('/')[4].split('?')[1].split('&')[0].split('=')[1]
|
| 164 |
-
|
| 165 |
-
# IMPORTANT: This might change in the future.
|
| 166 |
SHA_postfix = "_5nFp9kmbNnHdAFhaqMvt"
|
| 167 |
-
|
| 168 |
SHA_key = file_id + "_" + expires + SHA_postfix
|
| 169 |
hash = hashlib.sha1(SHA_key.encode('utf-8')).hexdigest()
|
| 170 |
-
|
| 171 |
headers = {"X-Version": hash}
|
| 172 |
-
|
| 173 |
resources = requests.get(url, headers=headers, auth=BearerAuth(self.token), timeout=self.timeout).json()
|
| 174 |
-
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 180 |
for resource in resources:
|
| 181 |
-
if resource['name']
|
| 182 |
-
resources_by_quality[
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
print(resource)
|
| 198 |
-
|
| 199 |
-
download_link = "https:" + resource['src']['download']
|
| 200 |
-
file_type = resource['type'].split('/')[1]
|
| 201 |
-
|
| 202 |
-
video_file_name = video_id + '.' + file_type
|
| 203 |
-
|
| 204 |
-
if (os.path.exists(video_file_name)):
|
| 205 |
-
print(f"Video ID {video_id} Already downloaded, skipped downloading. ")
|
| 206 |
-
return video_file_name
|
| 207 |
-
|
| 208 |
-
print(f"Downloading video ID: {video_id} ...")
|
| 209 |
-
try:
|
| 210 |
-
with open(video_file_name, "wb") as f:
|
| 211 |
-
for chunk in requests.get(download_link).iter_content(chunk_size=1024):
|
| 212 |
-
if chunk:
|
| 213 |
-
f.write(chunk)
|
| 214 |
-
f.flush()
|
| 215 |
-
return video_file_name
|
| 216 |
-
except Exception as e:
|
| 217 |
-
os.remove(video_file_name)
|
| 218 |
-
raise Exception(f"Failed to download video ID: {video_id}, error: {e}")
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
raise Exception("No video with Source quality found")
|
| 222 |
-
|
| 223 |
-
# -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
|
| 227 |
-
# -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 228 |
-
|
| 229 |
-
### download video from iwara.tv
|
| 230 |
-
### usage: python iwara [url]
|
| 231 |
-
### by AngelBottomless @ github
|
| 232 |
-
# download from iwara page
|
| 233 |
-
import requests
|
| 234 |
-
# use selenium to get video url
|
| 235 |
-
from selenium import webdriver
|
| 236 |
-
import argparse
|
| 237 |
-
|
| 238 |
-
def download_video(url):
|
| 239 |
-
# save video to local
|
| 240 |
-
filename = url.split('/')[-1] + '.mp4'
|
| 241 |
-
# get video
|
| 242 |
-
driver = run_webdriver(url)
|
| 243 |
-
click_accept(driver)
|
| 244 |
-
driver.implicitly_wait(2)
|
| 245 |
-
click_play(driver)
|
| 246 |
-
url = find_video_url(driver)
|
| 247 |
-
# download video
|
| 248 |
-
r = requests.get(url)
|
| 249 |
-
with open(filename, 'wb') as f:
|
| 250 |
-
f.write(r.content)
|
| 251 |
-
# close driver
|
| 252 |
-
driver.close()
|
| 253 |
-
|
| 254 |
-
def download_with_retry(url, retry=3):
|
| 255 |
-
# retry download
|
| 256 |
-
for _ in range(retry):
|
| 257 |
try:
|
| 258 |
-
|
| 259 |
-
|
| 260 |
-
|
| 261 |
-
|
| 262 |
-
|
| 263 |
-
|
| 264 |
-
|
| 265 |
-
|
| 266 |
-
|
| 267 |
-
|
| 268 |
-
|
| 269 |
-
|
| 270 |
-
|
| 271 |
-
|
| 272 |
-
|
| 273 |
-
|
| 274 |
-
|
| 275 |
-
|
| 276 |
-
def click_accept(driver):
|
| 277 |
-
# xpath = /html/body/div[3]/div/div[2]/button[1]
|
| 278 |
-
button = driver.find_element('xpath', '/html/body/div[3]/div/div[2]/button[1]')
|
| 279 |
-
button.click()
|
| 280 |
-
def click_play(driver):
|
| 281 |
-
# xpath = //*[@id="vjs_video_3"]/button
|
| 282 |
-
button = driver.find_element('xpath', '//*[@id="vjs_video_3"]/button')
|
| 283 |
-
button.click()
|
| 284 |
-
|
| 285 |
-
def find_video_url(driver):
|
| 286 |
-
# xpath //*[@id="vjs_video_3_html5_api"]
|
| 287 |
-
#access 'src'
|
| 288 |
-
video = driver.find_element('xpath', '//*[@id="vjs_video_3_html5_api"]')
|
| 289 |
-
video_url = video.get_attribute('src')
|
| 290 |
-
return video_url
|
| 291 |
-
|
| 292 |
-
def track_clipboard():
|
| 293 |
-
import pyperclip
|
| 294 |
-
import time
|
| 295 |
-
import subprocess
|
| 296 |
-
failed_urls = []
|
| 297 |
-
success_urls = set()
|
| 298 |
-
print('tracking clipboard...')
|
| 299 |
-
# loop to track clipboard
|
| 300 |
-
# if clipboard contains url, download video
|
| 301 |
-
# track every 1 second
|
| 302 |
-
previous = ''
|
| 303 |
-
# expect KeyboardInterrupt and return 0
|
| 304 |
-
try:
|
| 305 |
-
while True:
|
| 306 |
-
# get clipboard
|
| 307 |
-
clipboard = pyperclip.paste()
|
| 308 |
-
if clipboard != previous:
|
| 309 |
-
# if clipboard contains url
|
| 310 |
-
if 'iwara.tv' in clipboard:
|
| 311 |
-
print('url detected, downloading...')
|
| 312 |
-
# use subprocess to download video in background
|
| 313 |
-
# ['python', '-m', 'iwara', clipboard]
|
| 314 |
-
subprocess.Popen(['python', '-m', 'iwara', clipboard])
|
| 315 |
-
print('download complete')
|
| 316 |
-
previous = clipboard
|
| 317 |
-
time.sleep(1)
|
| 318 |
-
except KeyboardInterrupt:
|
| 319 |
-
print('exiting...')
|
| 320 |
-
return 0
|
| 321 |
|
| 322 |
-
|
| 323 |
-
|
| 324 |
-
|
| 325 |
-
|
| 326 |
-
|
| 327 |
-
|
| 328 |
-
|
| 329 |
-
|
| 330 |
-
|
| 331 |
-
|
| 332 |
-
|
| 333 |
-
|
| 334 |
-
|
| 335 |
-
track_clipboard()
|
| 336 |
-
elif 'iwara.tv' in args.url:
|
| 337 |
-
result = download_with_retry(args.url)
|
| 338 |
-
if not result:
|
| 339 |
-
print('download failed')
|
| 340 |
-
failed_urls.append(args.url)
|
| 341 |
-
else:
|
| 342 |
-
print('download complete')
|
| 343 |
-
success_urls.add(args.url)
|
| 344 |
-
if len(failed_urls) > 0:
|
| 345 |
-
print('failed urls:')
|
| 346 |
-
for url in failed_urls:
|
| 347 |
-
print(url)
|
| 348 |
-
# write in ./failed.txt
|
| 349 |
-
with open('failed.txt', 'a') as f:
|
| 350 |
-
f.write(url + '\n')
|
| 351 |
-
sys.exit(1)
|
| 352 |
-
else:
|
| 353 |
-
print('invalid url')
|
| 354 |
-
sys.exit(1)
|
| 355 |
|
| 356 |
# -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 357 |
|
| 358 |
-
def iwara(video_url,
|
|
|
|
|
|
|
|
|
|
| 359 |
# Set the path to the thumbnail directory
|
| 360 |
directory = "/home/user/app/Iwara"
|
| 361 |
if not os.path.exists(directory):
|
|
|
|
| 5 |
file_url = 'https://files.iwara.tv'
|
| 6 |
|
| 7 |
class BearerAuth(requests.auth.AuthBase):
|
|
|
|
| 8 |
def __init__(self, token):
|
| 9 |
self.token = token
|
| 10 |
|
|
|
|
| 16 |
def __init__(self, email, password):
|
| 17 |
self.email = email
|
| 18 |
self.password = password
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
self.api_url = api_url
|
| 20 |
self.file_url = file_url
|
| 21 |
self.timeout = 30
|
|
|
|
| 22 |
self.download_timeout = 300
|
| 23 |
self.token = None
|
| 24 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
def login(self) -> requests.Response:
|
| 26 |
url = self.api_url + '/user/login'
|
| 27 |
json = {'email': self.email, 'password': self.password}
|
|
|
|
| 31 |
print('API Login success')
|
| 32 |
except:
|
| 33 |
print('API Login failed')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
return r
|
| 35 |
|
| 36 |
+
def get_videos(self, sort='date', rating='all', page=0, limit=32, subscribed=False) -> requests.Response:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
url = self.api_url + '/videos'
|
| 38 |
+
params = {'sort': sort, 'rating': rating, 'page': page, 'limit': limit, 'subscribed': 'true' if subscribed else 'false'}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
if self.token is None:
|
| 40 |
r = requests.get(url, params=params, timeout=self.timeout)
|
| 41 |
else:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
r = requests.get(url, params=params, auth=BearerAuth(self.token), timeout=self.timeout)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
return r
|
| 44 |
+
|
| 45 |
def get_video(self, video_id) -> requests.Response:
|
|
|
|
|
|
|
| 46 |
url = self.api_url + '/video/' + video_id
|
|
|
|
| 47 |
if self.token is None:
|
| 48 |
r = requests.get(url, timeout=self.timeout)
|
| 49 |
else:
|
| 50 |
r = requests.get(url, auth=BearerAuth(self.token), timeout=self.timeout)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
return r
|
| 52 |
+
|
| 53 |
def download_video_thumbnail(self, video_id) -> str:
|
|
|
|
|
|
|
| 54 |
video = self.get_video(video_id).json()
|
|
|
|
| 55 |
file_id = video['file']['id']
|
| 56 |
thumbnail_id = video['thumbnail']
|
|
|
|
| 57 |
url = self.file_url + '/image/original/' + file_id + '/thumbnail-{:02d}.jpg'.format(thumbnail_id)
|
| 58 |
+
title = video['title']
|
| 59 |
+
user = video['user']
|
| 60 |
+
name = user['name']
|
| 61 |
+
username = user['username']
|
| 62 |
+
print("Name:", name)
|
| 63 |
+
print("Username:", username)
|
| 64 |
+
print("Title:", title)
|
| 65 |
+
judul = f"{name} - {title.replace('’S', '’s').replace(' / ', ' ').replace('/', ' ').replace('_', ' ')}"
|
| 66 |
+
folder_download = f"/content/Download Iwara/Thumbnail/{name}"
|
| 67 |
+
if not os.path.exists(folder_download):
|
| 68 |
+
os.makedirs(folder_download)
|
| 69 |
+
thumbnail_file_name = os.path.join(folder_download, judul + '.jpg')
|
| 70 |
+
if os.path.exists(thumbnail_file_name):
|
| 71 |
+
print(f"Video ID {video_id} thumbnail already downloaded, skipped downloading.")
|
| 72 |
return thumbnail_file_name
|
|
|
|
| 73 |
print(f"Downloading thumbnail for video ID: {video_id} ...")
|
| 74 |
+
with open(thumbnail_file_name, 'wb') as f:
|
| 75 |
+
response = requests.get(url, stream=True)
|
| 76 |
+
total_size = int(response.headers.get('Content-Length', 0))
|
| 77 |
+
progress_bar = tqdm(total=total_size, unit='B', unit_scale=True, ncols=80)
|
| 78 |
+
|
| 79 |
+
for chunk in response.iter_content(chunk_size=1024):
|
| 80 |
if chunk:
|
| 81 |
f.write(chunk)
|
| 82 |
+
progress_bar.update(len(chunk))
|
| 83 |
|
| 84 |
+
progress_bar.close()
|
| 85 |
return thumbnail_file_name
|
| 86 |
|
| 87 |
def download_video(self, video_id) -> str:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 88 |
try:
|
| 89 |
video = self.get_video(video_id).json()
|
| 90 |
except Exception as e:
|
| 91 |
raise Exception(f"Failed to get video info for video ID: {video_id}, error: {e}")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
url = video['fileUrl']
|
| 93 |
file_id = video['file']['id']
|
| 94 |
expires = url.split('/')[4].split('?')[1].split('&')[0].split('=')[1]
|
|
|
|
|
|
|
| 95 |
SHA_postfix = "_5nFp9kmbNnHdAFhaqMvt"
|
|
|
|
| 96 |
SHA_key = file_id + "_" + expires + SHA_postfix
|
| 97 |
hash = hashlib.sha1(SHA_key.encode('utf-8')).hexdigest()
|
|
|
|
| 98 |
headers = {"X-Version": hash}
|
|
|
|
| 99 |
resources = requests.get(url, headers=headers, auth=BearerAuth(self.token), timeout=self.timeout).json()
|
| 100 |
+
title = video['title']
|
| 101 |
+
user = video['user']
|
| 102 |
+
name = user['name']
|
| 103 |
+
username = user['username']
|
| 104 |
+
print("Name:", name)
|
| 105 |
+
print("Username:", username)
|
| 106 |
+
print("Title:", title)
|
| 107 |
+
judul = f"{name} - {title.replace('’S', '’s').replace(' / ', ' ').replace('/', ' ').replace('_', ' ')}"
|
| 108 |
+
folder_download = f"/content/Download/{name}"
|
| 109 |
+
if not os.path.exists(folder_download):
|
| 110 |
+
os.makedirs(folder_download)
|
| 111 |
+
quality_priority = ['Source', '1080', '720', '540', '480', '360']
|
| 112 |
+
resources_by_quality = {quality: None for quality in quality_priority}
|
| 113 |
for resource in resources:
|
| 114 |
+
if resource['name'] in resources_by_quality:
|
| 115 |
+
resources_by_quality[resource['name']] = resource
|
| 116 |
+
download_resource = None
|
| 117 |
+
for quality in quality_priority:
|
| 118 |
+
if resources_by_quality[quality] is not None:
|
| 119 |
+
download_resource = resources_by_quality[quality]
|
| 120 |
+
break
|
| 121 |
+
if download_resource is None:
|
| 122 |
+
raise Exception("No video with acceptable quality found")
|
| 123 |
+
download_link = "https:" + download_resource['src']['download']
|
| 124 |
+
file_type = download_resource['type'].split('/')[1]
|
| 125 |
+
video_file_name = os.path.join(folder_download, judul + '.' + file_type)
|
| 126 |
+
if os.path.exists(video_file_name):
|
| 127 |
+
print(f"Video ID {video_id} already downloaded, skipped downloading.")
|
| 128 |
+
return video_file_name
|
| 129 |
+
print(f"Downloading video ID: {video_id} ...")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
try:
|
| 131 |
+
with open(video_file_name, 'wb') as file:
|
| 132 |
+
response = requests.get(download_link, stream=True)
|
| 133 |
+
total_size = int(response.headers.get("Content-Length", 0))
|
| 134 |
+
progress_bar = tqdm(total=total_size, unit="B", unit_scale=True, ncols=80)
|
| 135 |
+
|
| 136 |
+
for chunk in response.iter_content(chunk_size=1024):
|
| 137 |
+
if chunk:
|
| 138 |
+
file.write(chunk)
|
| 139 |
+
progress_bar.update(len(chunk))
|
| 140 |
+
|
| 141 |
+
progress_bar.close()
|
| 142 |
+
return video_file_name
|
| 143 |
+
except Exception as e:
|
| 144 |
+
if os.path.exists(video_file_name):
|
| 145 |
+
os.remove(video_file_name)
|
| 146 |
+
raise Exception(f"Failed to download video ID: {video_id}, error: {e}")
|
| 147 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 148 |
|
| 149 |
+
# def process_txt(txt_files, baris = 1):
|
| 150 |
+
# for txt_file in txt_files:
|
| 151 |
+
# file_path = os.path.join('/content', txt_file)
|
| 152 |
+
# with open(file_path, 'r') as f:
|
| 153 |
+
# links = f.read().splitlines()
|
| 154 |
+
# for link in links:
|
| 155 |
+
# if link.strip():
|
| 156 |
+
# print(f"Baris: {baris}")
|
| 157 |
+
# video_id = link.split("/")[4]
|
| 158 |
+
# client.download_video(video_id)
|
| 159 |
+
# baris += 1
|
| 160 |
+
# print()
|
| 161 |
+
# os.remove(file_path)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 162 |
|
| 163 |
# -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
| 164 |
|
| 165 |
+
def iwara(video_url, x, y):
|
| 166 |
+
if 'client' not in globals():
|
| 167 |
+
client = ApiClient(email=x, password=y)
|
| 168 |
+
client.login()
|
| 169 |
# Set the path to the thumbnail directory
|
| 170 |
directory = "/home/user/app/Iwara"
|
| 171 |
if not os.path.exists(directory):
|
rule34.py
CHANGED
|
@@ -23,23 +23,31 @@ def get_info_rule34(link):
|
|
| 23 |
print("Judul Video tidak ditemukan")
|
| 24 |
|
| 25 |
# Mencari nama artist di elemen dengan class col
|
| 26 |
-
cols = soup.find_all(class_="col")
|
|
|
|
|
|
|
| 27 |
if cols:
|
| 28 |
-
for col in cols:
|
| 29 |
-
# Mencari elemen dengan class label yang memiliki teks yang cocok dengan
|
| 30 |
-
label = col.find(class_="label", string="Artist
|
| 31 |
if label:
|
| 32 |
-
# Mencari elemen dengan class item yang merupakan saudara dari label
|
| 33 |
-
|
| 34 |
-
|
| 35 |
# Mencari elemen dengan class name yang merupakan anak dari item
|
| 36 |
name = item.find(class_="name")
|
| 37 |
if name:
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
else:
|
| 44 |
print("Elemen col tidak ditemukan")
|
| 45 |
|
|
@@ -85,7 +93,7 @@ def get_info_rule34(link):
|
|
| 85 |
print("Tidak ditemukan video kualitas 720p atau 480p")
|
| 86 |
video_url = None
|
| 87 |
|
| 88 |
-
return video_title,
|
| 89 |
|
| 90 |
def rule34(link):
|
| 91 |
video_info = ""
|
|
|
|
| 23 |
print("Judul Video tidak ditemukan")
|
| 24 |
|
| 25 |
# Mencari nama artist di elemen dengan class col
|
| 26 |
+
cols = soup.find_all(class_="col") # Menggunakan find_all untuk mendapatkan semua elemen dengan class col
|
| 27 |
+
artists = []
|
| 28 |
+
|
| 29 |
if cols:
|
| 30 |
+
for col in cols: # Melakukan iterasi untuk setiap elemen col
|
| 31 |
+
# Mencari elemen dengan class label yang memiliki teks yang cocok dengan "Artist"
|
| 32 |
+
label = col.find(class_="label", string="Artist")
|
| 33 |
if label:
|
| 34 |
+
# Mencari semua elemen dengan class item btn_link yang merupakan saudara dari label
|
| 35 |
+
items = label.find_next_siblings(class_="item btn_link")
|
| 36 |
+
for item in items:
|
| 37 |
# Mencari elemen dengan class name yang merupakan anak dari item
|
| 38 |
name = item.find(class_="name")
|
| 39 |
if name:
|
| 40 |
+
if "VA" not in name.text.strip():
|
| 41 |
+
artists.append(name.text.strip())
|
| 42 |
+
break # Keluar dari loop jika sudah menemukan label artist
|
| 43 |
+
|
| 44 |
+
if artists:
|
| 45 |
+
artists.sort() # Mengurutkan nama-nama artist
|
| 46 |
+
artist_string = ", ".join(artists) # Menggabungkan nama-nama artist dengan koma
|
| 47 |
+
print(f"Nama Artist: {artist_string}")
|
| 48 |
+
else:
|
| 49 |
+
artist_string = "Unknown Artist"
|
| 50 |
+
print("Nama Artist tidak ditemukan")
|
| 51 |
else:
|
| 52 |
print("Elemen col tidak ditemukan")
|
| 53 |
|
|
|
|
| 93 |
print("Tidak ditemukan video kualitas 720p atau 480p")
|
| 94 |
video_url = None
|
| 95 |
|
| 96 |
+
return video_title, artist_string, video_url, thumbnail_url
|
| 97 |
|
| 98 |
def rule34(link):
|
| 99 |
video_info = ""
|