Files
KKAFIO/test.py
2024-10-06 23:43:33 +01:00

211 lines
6.5 KiB
Python

import concurrent.futures
import requests
import json
import patoolib
import logging
import shutil
from bs4 import BeautifulSoup
from pathlib import Path
from util.config import Config
from util.file_manager import FileManager
from modules.create_backup import CreateBackup
from modules.fc_kks import FilterConvertKKS
from modules.install_chara import InstallChara
from modules.remove_chara import RemoveChara
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
CWD = Path.cwd()
TEST_PATH = CWD / "test"
GAMEPATH = TEST_PATH / "Koikatsu Party"
BACKUP_PATH = TEST_PATH / "Backup"
DOWNLOAD_PATH = TEST_PATH / "Downloads"
if TEST_PATH.exists() and TEST_PATH.is_dir():
shutil.rmtree(TEST_PATH)
paths_to_check = [
TEST_PATH,
BACKUP_PATH,
DOWNLOAD_PATH,
GAMEPATH / "UserData",
GAMEPATH / "BepInEx",
GAMEPATH / "mods",
GAMEPATH / "UserData" / "chara" / "male",
GAMEPATH / "UserData" / "chara" / "female",
GAMEPATH / "UserData" / "coordinate",
GAMEPATH / "UserData" / "Overlays"
]
for path in paths_to_check:
path.mkdir(parents=True, exist_ok=True)
def create_config():
"""Creates and saves the configuration file."""
data = {
"Core": {"GamePath": str(GAMEPATH)},
"CreateBackup": {
"Enable": True,
"OutputPath": str(BACKUP_PATH),
"BepInEx": False,
"Filename": "koikatsu_backup",
"mods": False,
"UserData": False,
},
"FilterConvertKKS": {
"Convert": True,
"InputPath": str(DOWNLOAD_PATH),
"Enable": True,
},
"InstallChara": {
"Password": "Skip",
"FileConflicts": "Skip",
"Enable": True,
"InputPath": str(DOWNLOAD_PATH),
},
"RemoveChara": {
"Enable": True,
"InputPath": str(DOWNLOAD_PATH),
},
}
config_path = TEST_PATH / 'config/config.json'
config_path.parent.mkdir(parents=True, exist_ok=True)
with open(config_path, "w") as f:
json.dump(data, f, indent=4)
return Config(config_path)
CONFIG = create_config()
FILE_MANAGER = FileManager(CONFIG)
def valid_link(link_button):
"""Check if a link is a valid download button."""
return link_button.text == 'Download' and link_button.get('href')
def get_card_urls(bepis_url: str) -> list[str]:
"""Extract card download URLs from a bepis page."""
try:
response = requests.get(bepis_url)
response.raise_for_status()
except requests.RequestException as e:
logger.error(f"Error fetching {bepis_url}: {e}")
return []
soup = BeautifulSoup(response.text, 'html.parser')
link_buttons = soup.find_all('a', class_='btn btn-primary btn-sm')
return ['https://db.bepis.moe' + link_button.get('href') for link_button in link_buttons if valid_link(link_button)]
def download_card(card_url: str) -> Path:
"""Download a card from a given URL."""
card_name = Path(card_url).name
card_path = DOWNLOAD_PATH / card_name
try:
with requests.get(card_url, stream=True) as response:
response.raise_for_status()
with open(card_path, "wb") as out_file:
out_file.write(response.content)
logger.info(f"Downloaded {card_name}")
return card_path
except requests.RequestException as e:
logger.error(f"Error downloading {card_url}: {e}")
return None
def download(bepis_url: str):
"""Download all cards from a given bepis URL using a thread pool."""
download_urls = get_card_urls(bepis_url)
with concurrent.futures.ThreadPoolExecutor() as executor:
results = list(executor.map(download_card, download_urls))
return set(filter(None, results))
def test_fckss(kk_cards, kks_cards):
"""Test FilterConvertKKS functionality."""
fckss = FilterConvertKKS(CONFIG, FILE_MANAGER)
fckss.run()
filter_path = DOWNLOAD_PATH / '_KKS_card_'
conversion_path = DOWNLOAD_PATH / '_KKS_to_KK_'
assert filter_path.exists(), "Filter path does not exist."
assert conversion_path.exists(), "Conversion path does not exist."
for kk_path in kk_cards:
card_name = kk_path.name
filtered_kks_path = filter_path / card_name
converted_kks_path = conversion_path / f"KKS2KK_{card_name}"
assert not filtered_kks_path.exists(), f"{filtered_kks_path} exists but should not."
assert not converted_kks_path.exists(), f"{converted_kks_path} exists but should not."
for kks_path in kks_cards:
card_name = kks_path.name
filtered_kks_path = filter_path / card_name
converted_kks_path = conversion_path / f"KKS2KK_{card_name}"
assert filtered_kks_path.exists(), f"{filtered_kks_path} does not exist."
assert converted_kks_path.exists(), f"{converted_kks_path} does not exist."
kk_cards.add(converted_kks_path)
def test_install(kk_cards):
"""Test character installation."""
install_chara = InstallChara(CONFIG, FILE_MANAGER)
install_chara.run()
chara_path = GAMEPATH / 'UserData' / 'chara' / 'female'
for card in kk_cards:
assert (chara_path / card.name).exists(), f"{card.name} not found in installed cards."
def test_backup(kk_cards):
"""Test backup functionality."""
create_backup = CreateBackup(CONFIG, FILE_MANAGER)
create_backup.run()
koikatsu_backup = BACKUP_PATH / 'koikatsu_backup.7z'
assert koikatsu_backup.exists(), "Backup file does not exist."
outdir = BACKUP_PATH / 'outdir'
patoolib.extract_archive(str(koikatsu_backup), outdir=str(outdir))
for card in kk_cards:
assert (outdir / "UserData" / "chara" / "female" / card.name).exists(), f"{card.name} missing in backup."
def test_remove():
"""Test character removal."""
remove_chara = RemoveChara(CONFIG, FILE_MANAGER)
remove_chara.run()
chara_path = GAMEPATH / 'UserData' / 'chara' / 'female'
assert not list(chara_path.iterdir()), "Character directory not empty after removal."
def main():
"""Main function to run all tests."""
kk_cards = download('https://db.bepis.moe/koikatsu?type=steam&orderby=popularity')
kks_cards = download('https://db.bepis.moe/koikatsu?type=sunshine&orderby=popularity')
if kk_cards and kks_cards:
test_fckss(kk_cards, kks_cards)
test_install(kk_cards)
test_backup(kk_cards)
test_remove()
shutil.rmtree(TEST_PATH)
else:
logger.error("No cards downloaded. Exiting.")
if __name__ == '__main__':
main()