#!/usr/bin/env python3 # Adapted from custom_dsstore.py by the Jalview team 2024 # Copyright (c) 2013-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. import ds_store import pprint import mac_alias import argparse import json parser = argparse.ArgumentParser( prog = "jalview_custom_dsstore.py", description = "Take an existing DS_Store file and change the volume name and add path to background image" ) parser.add_argument("-i", "--input", help="The existing styled DS_Store file", dest="input") parser.add_argument("-o", "--output", help="The output DS_Store file", dest="output") parser.add_argument("-v", "--volumename", help="The name of the output DS_Store volume", dest="volumename") parser.add_argument("-b", "--backgroundfile", help="The background image filename to use", dest="backgroundfile", default="background.png") parser.add_argument("-d", "--backgrounddir", help="The background image hidden dirname to use", dest="backgrounddir", default=".background") parser.add_argument("-c", "--config", help="YAML configuration for window and icon sizes and positions", dest="config") parser.add_argument("-m", "--dmg", help="The filename of the DMG file", dest="dmg", default="Jalview_macos.dmg") parser.add_argument("--dump", help="Display contents of the input DS_Store to stdout", action="store_true", dest="dump") parser.add_argument("-q", "--quiet", help="Don't print messages to stdout", action="store_true", dest="quiet") parser.add_argument("-f", "--filenames", help="List of comma-separated filenames to show information for --dump", dest="filenames", default="") args = parser.parse_args() def myprint(string): if (not args.quiet): print(string) def mypprint(string): if (not args.quiet): pprint.pprint(string) if (args.dump and not args.input): exit("When --dump used, an --input must be given") if (args.dump): with ds_store.DSStore.open(args.input, 'r+') as d: print(f"d=") print(pprint.pformat(d['.']['bwsp'], width=1)) for key in ["bwsp", "icvp","Iloc"]: try: print(f"d['.']['{key}']=") pprint.pprint(str(d['.'][key]), width=1) except: print(f"No info for d['.']['{key}']") a = mac_alias.Alias.from_bytes( d['.']['icvp']['backgroundImageAlias'] ) print("backgroundImageAlias:") print("alias.volume="+pprint.pformat(a.volume)) print("alias.target="+pprint.pformat(a.target)) for data in d: try: data = str(data) pprint.pprint(f"d['{data}']="+d[data], width=1) except: print(f"No info for d['{data}']") # for filename in args.filenames.split(","): # if (filename): # for f in d.find(filename): # myprint(f"d['{f}']=", d[f]) # else: # myprint(f"# No filename '{filename}' found in DS_Store '{args.input}'") exit(0) if (args.output and not (args.input or args.config)): exit("Need --input FILENAME or --config FILENAME to produce an --output") if (not args.output): exit("Provide --output FILENAME to output DS_Store") if (not args.volumename): exit("Provide a volume name with --volumename NAME") if (not args.backgroundfile): exit("Provide a background image filename (just the file, no path) with --backgroundfile FILENAME") package_name_ns = args.volumename configfilename = args.config config = None if (configfilename): configfile = open(configfilename, 'r') config = json.load(configfile) inputds = ds_store.DSStore.open(args.input) outputds = ds_store.DSStore.open(args.output, 'w+') bwsp = {} for key in "ShowStatusBar SidebarWidthTenElevenOrLater ShowToolbar ShowTabView ContainerShowSidebar WindowBounds ShowSidebar ShowPathbar".split(): bwsp[key] = inputds['.']['bwsp'][key] myprint(f"Setting bwsp['{key}'] to '"+str(inputds['.']['bwsp'][key])+"'") outputds['.']['bwsp'] = bwsp icvp = {} alias = mac_alias.Alias.from_bytes(inputds['.']['icvp']['backgroundImageAlias']) alias.volume.name = args.volumename alias.volume.posix_path = "/Volumes/" + args.volumename alias.volume.disk_image_alias.volume.name = "Macintosh HD" alias.volume.disk_image_alias.volume.posix_path = "/" alias.volume.disk_image_alias.target.filename = args.dmg alias.volume.disk_image_alias.target.folder_name = "Downloads" alias.volume.disk_image_alias.target.carbon_path = f'Macintosh HD:Users:Jalview:Downloads:{args.dmg}' alias.volume.disk_image_alias.target.posix_path = f'/Users/jalview/Downloads/{args.dmg}' alias.target.filename = args.backgroundfile alias.target.folder_name = args.backgrounddir alias.target.carbon_path = f'{args.volumename}:{args.backgrounddir}:{args.backgroundfile}' alias.target.posix_path = f'/{args.backgrounddir}/{args.backgroundfile}' icvp['backgroundImageAlias'] = alias.to_bytes() for key in "backgroundColorRed backgroundColorBlue backgroundColorGreen gridSpacing gridOffsetX gridOffsetY showItemInfo viewOptionsVersion arrangeBy textSize labelOnBottom backgroundType showIconPreview iconSize".split(): icvp[key] = inputds['.']['icvp'][key] myprint(f"Setting icvp['{key}'] to '"+str(inputds['.']['icvp'][key])+"'") outputds['.']['icvp'] = icvp # copy filenames properties? not working, using JSON config file #for filename in args.filenames.split(","): # outputds[filename]['Iloc'] = inputds[filename]['Iloc'] outputds['.']['vSrn'] = ('long', 1) if config: for fileinfo in config['files']: outputds[fileinfo['name']]['Iloc'] = (fileinfo['xpos'], fileinfo['ypos']) outputds.flush() outputds.close() inputds.close()