script it
BIN
resources/preview logos/soundtrack.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
resources/store icons/glide_preview_clean.webp
Normal file
|
After Width: | Height: | Size: 985 KiB |
BIN
resources/store icons/tumble_preview_clean.png
Normal file
|
After Width: | Height: | Size: 574 KiB |
140
scripts/regenerate_soundtrack_previews.py
Normal file
@@ -0,0 +1,140 @@
|
||||
import argparse
|
||||
import hashlib
|
||||
import io
|
||||
import re
|
||||
from pathlib import Path
|
||||
from zipfile import ZIP_DEFLATED, ZipFile
|
||||
|
||||
from PIL import Image
|
||||
|
||||
|
||||
CANVAS_SIZE = (1024, 1024)
|
||||
HEADER_WIDTH = 900
|
||||
HEADER_TOP = 40
|
||||
STAMP_WIDTH = 465
|
||||
STAMP_LEFT = 520
|
||||
STAMP_TOP = 165
|
||||
MINIGAME_STAMP_TOP = 225
|
||||
SOURCES = {
|
||||
"adventure_time": "resources/lce skinpack icons/adventure_time.png",
|
||||
"chinese_mythology": "resources/store icons/chinesemytho_preview.png",
|
||||
"city": "resources/store icons/city_preview.png",
|
||||
"egyptian_mythology": "resources/store icons/egyptianmytho_preview.png",
|
||||
"fallout": "resources/store icons/fallout_preview.png",
|
||||
"fantasy": "resources/store icons/fantasy_preview.png",
|
||||
"festive": "resources/store icons/festive_preview.png",
|
||||
"glide": "resources/store icons/glide_preview_clean.webp",
|
||||
"greek_mythology": "resources/store icons/greekmytho_preview.png",
|
||||
"halloween_2015": "resources/store icons/halloween_preview.png",
|
||||
"halo": "resources/lce skinpack icons/mashuphalo.png",
|
||||
"littlebigplanet": "resources/store icons/lbp_preview.png",
|
||||
"mass_effect": "resources/store icons/masseffect_preview.png",
|
||||
"norse_mythology": "resources/store icons/norsemytho_preview.png",
|
||||
"pirates_of_the_caribbean": "resources/store icons/potc_preview.png",
|
||||
"skyrim": "resources/lce skinpack icons/skyrim.png",
|
||||
"steampunk": "resources/store icons/steampunk_preview.png",
|
||||
"steven_universe": "resources/lce skinpack icons/stevenuniverse.png",
|
||||
"the_nightmare_before_christmas": "resources/lce skinpack icons/thenightmarebeforechristmas.png",
|
||||
"toy_story": "resources/lce skinpack icons/toystorymash-up.png",
|
||||
"tumble": "resources/store icons/tumble_preview_clean.png",
|
||||
}
|
||||
NO_HEADER = {"glide", "littlebigplanet", "toy_story", "tumble"}
|
||||
|
||||
|
||||
def repo_root() -> Path:
|
||||
return Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
def cover(image: Image.Image) -> Image.Image:
|
||||
image = image.convert("RGBA")
|
||||
scale = max(CANVAS_SIZE[0] / image.width, CANVAS_SIZE[1] / image.height)
|
||||
resized = image.resize((round(image.width * scale), round(image.height * scale)), Image.Resampling.LANCZOS)
|
||||
left = (resized.width - CANVAS_SIZE[0]) // 2
|
||||
top = (resized.height - CANVAS_SIZE[1]) // 2
|
||||
return resized.crop((left, top, left + CANVAS_SIZE[0], top + CANVAS_SIZE[1]))
|
||||
|
||||
|
||||
def resize_width(image: Image.Image, width: int) -> Image.Image:
|
||||
height = round(image.height * width / image.width)
|
||||
return image.resize((width, height), Image.Resampling.LANCZOS)
|
||||
|
||||
|
||||
def make_preview(source: Path, output: Path, header: Image.Image, stamp: Image.Image, skip_header: bool) -> None:
|
||||
canvas = cover(Image.open(source))
|
||||
stamp_image = resize_width(stamp, STAMP_WIDTH)
|
||||
if not skip_header:
|
||||
header_image = resize_width(header, HEADER_WIDTH)
|
||||
canvas.alpha_composite(header_image, ((CANVAS_SIZE[0] - HEADER_WIDTH) // 2, HEADER_TOP))
|
||||
canvas.alpha_composite(stamp_image, (STAMP_LEFT, MINIGAME_STAMP_TOP if skip_header else STAMP_TOP))
|
||||
output.parent.mkdir(parents=True, exist_ok=True)
|
||||
canvas.save(output)
|
||||
|
||||
|
||||
def replace_pack_icon(zip_path: Path, preview: Path) -> None:
|
||||
buffer = io.BytesIO()
|
||||
Image.open(preview).save(buffer, format="PNG")
|
||||
replacement = buffer.getvalue()
|
||||
temp_path = zip_path.with_suffix(".zip.tmp")
|
||||
with ZipFile(zip_path, "r") as source, ZipFile(temp_path, "w", ZIP_DEFLATED) as target:
|
||||
replaced = False
|
||||
for item in source.infolist():
|
||||
if item.filename == "pack.png":
|
||||
target.writestr(item, replacement)
|
||||
replaced = True
|
||||
else:
|
||||
target.writestr(item, source.read(item.filename))
|
||||
if not replaced:
|
||||
target.writestr("pack.png", replacement)
|
||||
temp_path.replace(zip_path)
|
||||
|
||||
|
||||
def md5(path: Path) -> str:
|
||||
digest = hashlib.md5()
|
||||
with path.open("rb") as file:
|
||||
for chunk in iter(lambda: file.read(1024 * 1024), b""):
|
||||
digest.update(chunk)
|
||||
return digest.hexdigest()
|
||||
|
||||
|
||||
def update_index(index_path: Path, results: dict[str, tuple[str, str]]) -> None:
|
||||
text = index_path.read_text(encoding="utf-8")
|
||||
for soundtrack_id, (zip_hash, image_hash) in results.items():
|
||||
zip_pattern = rf"(soundtracks/packs/{re.escape(soundtrack_id)}\.zip\?checksum=)[0-9a-f]+"
|
||||
image_pattern = rf"(soundtracks/preview_images/{re.escape(soundtrack_id)}_preview\.png\?checksum=)[0-9a-f]+"
|
||||
text = re.sub(zip_pattern, rf"\g<1>{zip_hash}", text)
|
||||
text = re.sub(image_pattern, rf"\g<1>{image_hash}", text)
|
||||
index_path.write_text(text, encoding="utf-8")
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description="Regenerate soundtrack preview images and pack icons.")
|
||||
parser.add_argument("--id", action="append", choices=sorted(SOURCES), help="Generate only the selected soundtrack. May be repeated.")
|
||||
parser.add_argument("--force", action="store_true", help="Regenerate previews that already exist.")
|
||||
args = parser.parse_args()
|
||||
|
||||
root = repo_root()
|
||||
header = Image.open(root / "resources" / "preview logos" / "header.png").convert("RGBA")
|
||||
stamp = Image.open(root / "resources" / "preview logos" / "soundtrack.png").convert("RGBA")
|
||||
selected = args.id or list(SOURCES)
|
||||
results = {}
|
||||
for soundtrack_id in selected:
|
||||
source = root / SOURCES[soundtrack_id]
|
||||
preview = root / "soundtracks" / "preview_images" / f"{soundtrack_id}_preview.png"
|
||||
zip_path = root / "soundtracks" / "packs" / f"{soundtrack_id}.zip"
|
||||
if preview.exists() and not args.force:
|
||||
continue
|
||||
if not source.exists():
|
||||
raise FileNotFoundError(source)
|
||||
if not zip_path.exists():
|
||||
raise FileNotFoundError(zip_path)
|
||||
make_preview(source, preview, header, stamp, soundtrack_id in NO_HEADER)
|
||||
replace_pack_icon(zip_path, preview)
|
||||
results[soundtrack_id] = (md5(zip_path), md5(preview))
|
||||
print(f"{soundtrack_id}: zip={results[soundtrack_id][0]} image={results[soundtrack_id][1]}")
|
||||
update_index(root / "soundtracks" / "index.json", results)
|
||||
print(f"Regenerated {len(results)} soundtrack previews")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -12,72 +12,72 @@
|
||||
"id": "glide",
|
||||
"name": "Glide Mini Game Soundtrack",
|
||||
"description": "Relive the fast-paced scuffles of Legacy Console Edition's Glide Mini Game with its energising soundtrack, featuring music composed by Gareth Coker.",
|
||||
"downloadURI": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/packs/glide.zip?checksum=d00a2d063a810eee9a12e7c87db2b240",
|
||||
"imageUrl": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/preview_images/glide_preview.png?checksum=8252e0ee21c0bd609d5edd308877357f",
|
||||
"downloadURI": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/packs/glide.zip?checksum=3fd203daafc4df58a1057ee584ccadad",
|
||||
"imageUrl": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/preview_images/glide_preview.png?checksum=e49231dadd98d07322e999976b18b057",
|
||||
"tags": ["auto_apply_resource_pack"]
|
||||
},
|
||||
{
|
||||
"id": "tumble",
|
||||
"name": "Tumble Mini Game Soundtrack",
|
||||
"description": "Relive the fast-paced scuffles of Legacy Console Edition's Tumble Mini Game with its energising soundtrack, featuring music composed by Gareth Coker.",
|
||||
"downloadURI": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/packs/tumble.zip?checksum=92b73f0b4619317248a98068448dffbc",
|
||||
"imageUrl": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/preview_images/tumble_preview.png?checksum=d4a4f81632b4f242e57dc3cfe3c41c33",
|
||||
"downloadURI": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/packs/tumble.zip?checksum=9096707d93e485c69aa13b4638443889",
|
||||
"imageUrl": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/preview_images/tumble_preview.png?checksum=af3aff178658515b52a9caaee0626f81",
|
||||
"tags": ["auto_apply_resource_pack"]
|
||||
},
|
||||
{
|
||||
"id": "fallout",
|
||||
"name": "Fallout Soundtrack",
|
||||
"description": "Keep dancing until the end of the world with Legacy Console Edition's Fallout Mash-Up soundtrack, featuring familiar music from across the Fallout series.",
|
||||
"downloadURI": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/packs/fallout.zip?checksum=1fea18d7ed6c8e873c27d221b565d52b",
|
||||
"imageUrl": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/preview_images/fallout_preview.png?checksum=46d7ebbc3a9e0f5edba483945671ba1f",
|
||||
"downloadURI": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/packs/fallout.zip?checksum=a9e3efaa82bb8539add1b57fcd81774f",
|
||||
"imageUrl": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/preview_images/fallout_preview.png?checksum=e5b7e873e9c926f7790e37ef680db050",
|
||||
"tags": ["auto_apply_resource_pack"]
|
||||
},
|
||||
{
|
||||
"id": "pirates_of_the_caribbean",
|
||||
"name": "Pirates of the Caribbean Soundtrack",
|
||||
"description": "Set sail with Legacy Console Edition's Pirates of the Caribbean Mash-Up soundtrack and relive adventures inspired by all five films.",
|
||||
"downloadURI": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/packs/pirates_of_the_caribbean.zip?checksum=d218011bae3f21e7029fc4d7e0b99d7b",
|
||||
"imageUrl": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/preview_images/pirates_of_the_caribbean_preview.png?checksum=4487c235895745a560a10ed7c0d02d4d",
|
||||
"downloadURI": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/packs/pirates_of_the_caribbean.zip?checksum=0b9a823cc5872dfa643a833661675a63",
|
||||
"imageUrl": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/preview_images/pirates_of_the_caribbean_preview.png?checksum=2e71f282e9b52dcbc3fd90556a235733",
|
||||
"tags": ["auto_apply_resource_pack"]
|
||||
},
|
||||
{
|
||||
"id": "halo",
|
||||
"name": "Halo Soundtrack",
|
||||
"description": "Suit up as the Master Chief with Legacy Console Edition's Halo Mash-Up soundtrack, featuring music from across the Halo franchise.",
|
||||
"downloadURI": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/packs/halo.zip?checksum=b24a09cf27b4c04ea29598ff65dda25d",
|
||||
"imageUrl": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/preview_images/halo_preview.png?checksum=b02742e762783ee1b1c00f789c804db9",
|
||||
"downloadURI": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/packs/halo.zip?checksum=b2553a14cd0059dfa94e03c9f83f87c3",
|
||||
"imageUrl": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/preview_images/halo_preview.png?checksum=6f1de4b78d2909e165f4636a0e65a660",
|
||||
"tags": ["auto_apply_resource_pack"]
|
||||
},
|
||||
{
|
||||
"id": "littlebigplanet",
|
||||
"name": "LittleBigPlanet Soundtrack",
|
||||
"description": "Join Sackboy with Legacy Console Edition's LittleBigPlanet Mash-Up soundtrack and relive the imaginative world of LittleBigPlanet.",
|
||||
"downloadURI": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/packs/littlebigplanet.zip?checksum=e0a160bdb114c7eaccf277aac08f7f4b",
|
||||
"imageUrl": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/preview_images/littlebigplanet_preview.png?checksum=92051dacb30ffaf41dfbdd212d7b0917",
|
||||
"downloadURI": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/packs/littlebigplanet.zip?checksum=b340cc19c6779af6962bcbcd57ff8e79",
|
||||
"imageUrl": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/preview_images/littlebigplanet_preview.png?checksum=17864c80cb58a2e9c69659abc2e4c90f",
|
||||
"tags": ["auto_apply_resource_pack"]
|
||||
},
|
||||
{
|
||||
"id": "the_nightmare_before_christmas",
|
||||
"name": "The Nightmare Before Christmas Soundtrack",
|
||||
"description": "Step into Halloween Town with Legacy Console Edition's The Nightmare Before Christmas Mash-Up soundtrack and relive the stop-motion classic.",
|
||||
"downloadURI": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/packs/the_nightmare_before_christmas.zip?checksum=f9f157b1c1daad9a20ca075e3e05a253",
|
||||
"imageUrl": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/preview_images/the_nightmare_before_christmas_preview.png?checksum=14da8df20f6f6110129270d706eece9d",
|
||||
"downloadURI": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/packs/the_nightmare_before_christmas.zip?checksum=45efb466a769c737166fa2d52d39c5a9",
|
||||
"imageUrl": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/preview_images/the_nightmare_before_christmas_preview.png?checksum=de7a3e2311c1f83446213d2e824c55b2",
|
||||
"tags": ["auto_apply_resource_pack"]
|
||||
},
|
||||
{
|
||||
"id": "halloween_2015",
|
||||
"name": "Halloween 2015 Soundtrack",
|
||||
"description": "Bring a frightful atmosphere to your game with Legacy Console Edition's Halloween 2015 Mash-Up soundtrack.",
|
||||
"downloadURI": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/packs/halloween_2015.zip?checksum=b70a67624c5f5e4a2df8c33609cba20c",
|
||||
"imageUrl": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/preview_images/halloween_2015_preview.png?checksum=e04cb498df53d9c5e04f7cf526f029fd",
|
||||
"downloadURI": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/packs/halloween_2015.zip?checksum=8e4757c8c531fbce6caa102f65fcf9d5",
|
||||
"imageUrl": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/preview_images/halloween_2015_preview.png?checksum=930fb58a83c20be6eaad4a0fd16dc47c",
|
||||
"tags": ["auto_apply_resource_pack"]
|
||||
},
|
||||
{
|
||||
"id": "chinese_mythology",
|
||||
"name": "Chinese Mythology Soundtrack",
|
||||
"description": "Journey through a land inspired by ancient China with Legacy Console Edition's Chinese Mythology Mash-Up soundtrack.",
|
||||
"downloadURI": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/packs/chinese_mythology.zip?checksum=f32828984ae9f452c07f1c0d1714bf07",
|
||||
"imageUrl": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/preview_images/chinese_mythology_preview.png?checksum=132c485ea6d6e809607f55717f19d433",
|
||||
"downloadURI": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/packs/chinese_mythology.zip?checksum=2397aa3339d0c49057364f4053990498",
|
||||
"imageUrl": "https://raw.githubusercontent.com/creeper2eletricboogaloo/L4JDownloadableContent/main/soundtracks/preview_images/chinese_mythology_preview.png?checksum=7bfc44847be73a4e6e3d20018fbf96f8",
|
||||
"tags": ["auto_apply_resource_pack"]
|
||||
}
|
||||
]
|
||||
|
||||
BIN
soundtracks/packs/adventure_time.zip
Normal file
BIN
soundtracks/packs/city.zip
Normal file
BIN
soundtracks/packs/egyptian_mythology.zip
Normal file
BIN
soundtracks/packs/fantasy.zip
Normal file
BIN
soundtracks/packs/festive.zip
Normal file
BIN
soundtracks/packs/greek_mythology.zip
Normal file
BIN
soundtracks/packs/mass_effect.zip
Normal file
BIN
soundtracks/packs/norse_mythology.zip
Normal file
BIN
soundtracks/packs/skyrim.zip
Normal file
BIN
soundtracks/packs/steampunk.zip
Normal file
BIN
soundtracks/packs/steven_universe.zip
Normal file
BIN
soundtracks/packs/toy_story.zip
Normal file
BIN
soundtracks/preview_images/adventure_time_preview.png
Normal file
|
After Width: | Height: | Size: 908 KiB |
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 1.2 MiB |
BIN
soundtracks/preview_images/city_preview.png
Normal file
|
After Width: | Height: | Size: 887 KiB |
BIN
soundtracks/preview_images/egyptian_mythology_preview.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 628 KiB After Width: | Height: | Size: 638 KiB |
BIN
soundtracks/preview_images/fantasy_preview.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
soundtracks/preview_images/festive_preview.png
Normal file
|
After Width: | Height: | Size: 908 KiB |
|
Before Width: | Height: | Size: 1.6 MiB After Width: | Height: | Size: 1.5 MiB |
BIN
soundtracks/preview_images/greek_mythology_preview.png
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 990 KiB After Width: | Height: | Size: 912 KiB |
|
Before Width: | Height: | Size: 796 KiB After Width: | Height: | Size: 1.1 MiB |
BIN
soundtracks/preview_images/mass_effect_preview.png
Normal file
|
After Width: | Height: | Size: 793 KiB |
BIN
soundtracks/preview_images/norse_mythology_preview.png
Normal file
|
After Width: | Height: | Size: 992 KiB |
|
Before Width: | Height: | Size: 746 KiB After Width: | Height: | Size: 716 KiB |
BIN
soundtracks/preview_images/skyrim_preview.png
Normal file
|
After Width: | Height: | Size: 703 KiB |
BIN
soundtracks/preview_images/steampunk_preview.png
Normal file
|
After Width: | Height: | Size: 855 KiB |
BIN
soundtracks/preview_images/steven_universe_preview.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 748 KiB After Width: | Height: | Size: 728 KiB |
BIN
soundtracks/preview_images/toy_story_preview.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 1.6 MiB After Width: | Height: | Size: 1.5 MiB |