Skip to content

Instantly share code, notes, and snippets.

@khelwood
Created August 18, 2025 20:14
Show Gist options
  • Select an option

  • Save khelwood/fc43d52458edaf8ce3cd27e4e304d348 to your computer and use it in GitHub Desktop.

Select an option

Save khelwood/fc43d52458edaf8ce3cd27e4e304d348 to your computer and use it in GitHub Desktop.
Fix the mac icons of a renpy app
#!/usr/bin/env python3
import sys
import os
import subprocess as sp
from tempfile import TemporaryDirectory
RPA = os.path.expanduser('~/bin/rpatool')
TOICNS = os.path.expanduser('~/Code/python/toicns.py')
def find_files(dir):
dirs = [dir]
while dirs:
dir = dirs.pop()
for fn in os.listdir(dir):
path = os.path.join(dir, fn)
if os.path.isdir(path):
dirs.append(path)
elif os.path.isfile(path):
yield path
def select(options, displayfn=str):
if not options:
return None
print("Select:")
for i,o in enumerate(options, 1):
print(i, ':', displayfn(o))
num = len(options)
while True:
try:
i = int(input('>> '))
except ValueError:
continue
if i==0:
return None
if 1 <= i <= num:
return options[i-1]
def fix_icon(maindir, file):
target = os.path.join(maindir, 'Contents/Resources/icon.icns')
sp.run([TOICNS, '--opac', '--clobber', file, target], check=True)
return target
def scan_for_icon(rpa):
result = sp.check_output([RPA, rpa, '-l'], text=True).splitlines()
for r in result:
if os.path.basename(r).lower()=='window_icon.png':
yield r
def extract(rpa, path, dir):
sp.run([RPA, rpa, '-x', path, '-o', dir], check=True)
return os.path.join(dir, path)
def main():
maindir = sys.argv[1]
if not os.path.isdir(maindir):
exit('Not a directory: %r'%maindir)
gamedir = os.path.join(maindir, 'Contents/Resources/autorun/game')
if not gamedir.endswith('/'):
gamedir += '/'
if not os.path.isdir(gamedir):
exit('Not a directory: %r'%gamedir)
file = select([p for p in find_files(gamedir) if os.path.basename(p).lower()=='window_icon.png'])
if file:
fix_icon(maindir, file)
return
rpas = [p for p in find_files(gamedir) if os.path.splitext(p)[1].lower()=='.rpa']
files = []
for rpa in rpas:
for fn in scan_for_icon(rpa):
files.append((rpa, fn))
file = select(files, lambda o: o[0].removeprefix(gamedir)+': '+o[1])
if not file:
print('No file found')
return
rpa, fn = file
with TemporaryDirectory(dir=gamedir) as tempdir:
path = extract(rpa, fn, tempdir)
fix_icon(maindir, path)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment