Add ability to download game covers, misc. improvements
This commit is contained in:
@@ -4,13 +4,14 @@ import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
import random
|
||||
import requests
|
||||
from selenium import webdriver
|
||||
from selenium.webdriver.common.action_chains import ActionChains
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.common.exceptions import NoSuchElementException
|
||||
from selenium.webdriver.chrome.service import Service
|
||||
from selenium.webdriver.chrome.options import Options
|
||||
from selenium.webdriver.support.ui import WebDriverWait, Select
|
||||
#from selenium.webdriver.support.ui import Select
|
||||
from selenium.webdriver.support import expected_conditions as EC
|
||||
import sys
|
||||
import time
|
||||
@@ -59,7 +60,7 @@ def main():
|
||||
parser.add_argument("-r", type=float, help="How often to refresh statistics on screen", default=2)
|
||||
parser.add_argument("-tw", type=float, help="Number of seconds to pause between downloads", default=4)
|
||||
parser.add_argument("-nm", type=bool, help="Do not monitor download statistics", default=False)
|
||||
parser.add_argument("-gc", type=bool, help="Download cover image", default=False)
|
||||
parser.add_argument("-gc", type=int, help="Download cover image (0: don't download, 1: small, 2: large, 3: both)", default=0, choices=[0, 1, 2, 3])
|
||||
parser.add_argument("-v", action='store_true', help="Display version information")
|
||||
args = parser.parse_args()
|
||||
|
||||
@@ -82,13 +83,15 @@ def main():
|
||||
logging.info(f"Reading URLs from: {url_file}")
|
||||
logging.info(f"Using ChromeD Port: {chrome_port}")
|
||||
|
||||
emessage = f""
|
||||
# URLs to process
|
||||
try:
|
||||
with open(url_file) as f:
|
||||
urls = [line.strip() for line in f]
|
||||
except:
|
||||
logging.error(f"Could not find url file: {url_file}!")
|
||||
raise FileNotFoundError(f"Could not find url file: {url_file}!")
|
||||
except Exception as e:
|
||||
emessage = f"Could not find url file: {e}!"
|
||||
logging.error(emessage)
|
||||
sys.exit(emessage)
|
||||
urls = list(dict.fromkeys(urls))
|
||||
url_length = len(urls)
|
||||
cur_url = 1
|
||||
@@ -186,20 +189,62 @@ def main():
|
||||
total_time = 0
|
||||
failed_urls = []
|
||||
for url in urls:
|
||||
def download_it(monitor, wait_time, download_dir, total_size, total_time, cur_url, dtitle, durl, ddisc=0):
|
||||
# Click Download button
|
||||
try:
|
||||
download_button = wait.until(
|
||||
EC.element_to_be_clickable((By.XPATH, "//button[text()='Download']"))
|
||||
)
|
||||
download_button.click()
|
||||
except:
|
||||
logging.warning(f"Download button not found for {title}!")
|
||||
failed_urls.append(url)
|
||||
def download_it(monitor, wait_time, download_dir, total_size, total_time, cur_url, dtitle, durl, cover, ddisc=0):
|
||||
def download_img(download_dir, title, itype, baseurl):
|
||||
def save_img(download_dir, title, itype, iurl, baseurl, iform):
|
||||
headers: dict[str, str] = {
|
||||
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
||||
'Accept-Encoding': 'gzip, deflate, br, zstd',
|
||||
'Connection': 'keep-alive',
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:149.0) Gecko/20100101 Firefox/149.0',
|
||||
'Referer': f'{url}'
|
||||
}
|
||||
response = requests.get(iurl, headers=headers, allow_redirects=True, stream=True)
|
||||
response.raise_for_status()
|
||||
if response.status_code == 200:
|
||||
fext = 'avif'
|
||||
if iform == 2:
|
||||
fext = 'webp'
|
||||
save_path = os.path.join(download_dir, f"{title}.{fext}")
|
||||
with open(save_path, 'wb') as file:
|
||||
for chunk in response.iter_content(1024):
|
||||
file.write(chunk)
|
||||
else:
|
||||
logging.warning(f"Could not download box image: {response.status_code} - {response.reason}")
|
||||
pass
|
||||
try:
|
||||
img_element = WebDriverWait(driver, 5).until(
|
||||
EC.presence_of_element_located((By.XPATH, '//img[@alt="Box"]'))
|
||||
)
|
||||
if itype in [1,3]:
|
||||
img_url = img_element.get_attribute('src')
|
||||
if img_url:
|
||||
save_img(download_dir, title, itype, img_url, baseurl, 1)
|
||||
else:
|
||||
logging.warning("No box image url found.")
|
||||
if itype in [2,3]:
|
||||
body_element = driver.find_element(By.TAG_NAME, "body")
|
||||
img_element.click()
|
||||
try:
|
||||
dialog_element = WebDriverWait(driver, 5).until(
|
||||
EC.presence_of_element_located((By.ID, "imageDialog"))
|
||||
)
|
||||
img_element2 = dialog_element.find_element(By.TAG_NAME, "img")
|
||||
img_url2 = img_element2.get_attribute('src')
|
||||
if img_url2:
|
||||
save_img(download_dir, title, itype, img_url2, baseurl, 2)
|
||||
else:
|
||||
logging.warning("No large box image found.")
|
||||
actions = ActionChains(driver)
|
||||
actions.move_to_element_with_offset(body_element, random.randint(1, 100), random.randint(1, 100)).click().perform()
|
||||
except Exception as e:
|
||||
logging.warning(f"No large box image found! {e}")
|
||||
except:
|
||||
logging.warning("No box image exists. Skipping...")
|
||||
# Get Vimm file size
|
||||
size = 0
|
||||
try:
|
||||
size_element = WebDriverWait(driver, 10).until(
|
||||
size_element = WebDriverWait(driver, 5).until(
|
||||
EC.presence_of_element_located((By.ID, "dl_size"))
|
||||
)
|
||||
size_raw = size_element.text
|
||||
@@ -208,6 +253,20 @@ def main():
|
||||
size_raw = '1 GB'
|
||||
pass
|
||||
logging.info(f"{title} {size_raw}")
|
||||
# Download box cover
|
||||
if cover > 0:
|
||||
raw_title = driver.title.replace("The Vault: ", "")
|
||||
download_img(download_dir, raw_title, cover, url)
|
||||
# Click Download button
|
||||
try:
|
||||
download_button = WebDriverWait(driver, 5).until(
|
||||
EC.element_to_be_clickable((By.XPATH, "//button[text()='Download']"))
|
||||
)
|
||||
download_button.click()
|
||||
except:
|
||||
logging.warning(f"Download button not found for {title}!")
|
||||
failed_urls.append(url)
|
||||
pass
|
||||
if " KB" in size_raw:
|
||||
size = float(size_raw.replace(" KB", "")) * 1024
|
||||
elif " MB" in size_raw:
|
||||
@@ -220,7 +279,7 @@ def main():
|
||||
size = 500 * 1024 * 1024
|
||||
# Try to click Continue if it appears
|
||||
try:
|
||||
continue_button = WebDriverWait(driver, 4).until(
|
||||
continue_button = WebDriverWait(driver, 5).until(
|
||||
EC.element_to_be_clickable((By.XPATH, "//input[@value='Continue']"))
|
||||
)
|
||||
continue_button.click()
|
||||
@@ -233,8 +292,9 @@ def main():
|
||||
csize = 0
|
||||
if size < 33554432:
|
||||
monitor = True
|
||||
wait_time = 17
|
||||
logging.warning("File size was too small to monitor! (Less than 32MB)")
|
||||
wait_time = 15
|
||||
if total_size > 0 and total_time > 0:
|
||||
wait_time = min((size / total_size / total_time) * 1.25, wait_time)
|
||||
if monitor == False:
|
||||
tempTime = time.time()
|
||||
file_pattern = download_dir + '/*.crdownload'
|
||||
@@ -246,11 +306,17 @@ def main():
|
||||
logging.warning(f"{time.time() - tempTime}")
|
||||
time.sleep(refresh_rate)
|
||||
if monitor == False:
|
||||
csize, ctime = monitor_download(download_dir, size+1024)
|
||||
csize, ctime = monitor_download(download_dir, size*1.01)
|
||||
total_size += csize
|
||||
total_time += ctime
|
||||
# Wait to call next URL
|
||||
time.sleep(wait_time)
|
||||
if cur_url < url_length:
|
||||
if size < 33554432:
|
||||
logging.warning(f"File size was too small to monitor! (Less than 32MB). Waiting {round(wait_time, 1)} seconds...")
|
||||
time.sleep(wait_time)
|
||||
else:
|
||||
if size < 33554432:
|
||||
logging.warning(f"File size was too small to monitor! (Less than 32MB).")
|
||||
cur_url += 1
|
||||
monitor = argmonitor
|
||||
wait_time = argwait
|
||||
@@ -261,22 +327,24 @@ def main():
|
||||
wait = WebDriverWait(driver, page_load_time)
|
||||
# Multiple discs?
|
||||
try:
|
||||
#disc_elements = driver.find_elements(By.CSS_SELECTOR, "select[id^='disc_number']")
|
||||
disc_element = driver.find_element(By.ID, "disc_number")
|
||||
disc_select = Select(disc_element)
|
||||
url_length += len(disc_select.options) - 1
|
||||
for option in disc_select.options:
|
||||
disc_value = option.get_attribute("value")
|
||||
disc_text = option.get_attribute("text")
|
||||
disc_replace = f"{cur_url}/{url_length}: ({disc_text}) "
|
||||
if len(disc_select.options) == 1:
|
||||
disc_replace = f"{cur_url}/{url_length}: "
|
||||
disc_select.select_by_value(disc_value)
|
||||
title = driver.title.replace("The Vault: ", f"{cur_url}/{url_length}: ({disc_text}) ")
|
||||
osize, otime = download_it(monitor, wait_time, download_dir, total_size, total_time, cur_url, title, url, disc_value)
|
||||
title = driver.title.replace("The Vault: ", disc_replace)
|
||||
osize, otime = download_it(monitor, wait_time, download_dir, total_size, total_time, cur_url, title, url, cover, disc_value)
|
||||
total_size += osize
|
||||
total_time += otime
|
||||
cur_url += 1
|
||||
except NoSuchElementException:
|
||||
except:
|
||||
title = driver.title.replace("The Vault: ", f"{cur_url}/{url_length}: ")
|
||||
osize, otime = download_it(monitor, wait_time, download_dir, total_size, total_time, cur_url, title, url)
|
||||
osize, otime = download_it(monitor, wait_time, download_dir, total_size, total_time, cur_url, title, url, cover)
|
||||
total_size += osize
|
||||
total_time += otime
|
||||
cur_url += 1
|
||||
|
||||
Reference in New Issue
Block a user