appleFonts.base: Let's try using an IPSW
This commit is contained in:
parent
0fa9c60778
commit
7e34876a71
File diff suppressed because one or more lines are too long
|
@ -1,4 +1,4 @@
|
|||
{ lib, fetchurl, stdenvNoCC, unzip }:
|
||||
{ lib, fetchurl, stdenvNoCC, unzip, ipsw, _7zz }:
|
||||
let
|
||||
root = lib.importJSON ./assets.json;
|
||||
|
||||
|
@ -23,9 +23,11 @@ let
|
|||
done
|
||||
'';
|
||||
|
||||
passthru.font = true;
|
||||
meta = with lib; {
|
||||
license = licenses.unfree;
|
||||
platforms = platforms.all;
|
||||
maintainer = with maintainers; [ artemist ];
|
||||
description = "${family} fonts as downloadable from macOS";
|
||||
};
|
||||
};
|
||||
|
@ -33,4 +35,27 @@ let
|
|||
in {
|
||||
extra = lib.mapAttrs' mkExtraFont root.extra;
|
||||
allExtra = (mkExtraFont "All Extra" root.all_extra).value;
|
||||
|
||||
base = let data = root.base;
|
||||
in stdenvNoCC.mkDerivation {
|
||||
pname = "macos-fonts-base";
|
||||
version = with data; "${version}-${build}";
|
||||
|
||||
src = fetchurl { inherit (data) url hash; };
|
||||
|
||||
installPhase = ''
|
||||
${ipsw}/bin/ipsw extract $src --dmg fs
|
||||
${_7zz}/bin/7zz e -i'!4.apfs' ${data.build}*/*.dmg
|
||||
|
||||
mkdir -p $out/share/fonts/apple
|
||||
|
||||
# This gives us some erros, ignore that
|
||||
# Skipping overwrite because Apple has duplicate fonts for some reason
|
||||
${_7zz}/bin/7zz e -i'!System/Library/Fonts' \
|
||||
-i'!System/Library/PrivateFrameworks/FontServices.framework/Versions/A/Resources/Fonts/ApplicationSupport' \
|
||||
4.apfs -aos -o$out/share/fonts/apple
|
||||
'';
|
||||
|
||||
dontUnpack = true;
|
||||
};
|
||||
}
|
||||
|
|
129
apple/update.py
129
apple/update.py
|
@ -5,54 +5,97 @@ import base64
|
|||
import json
|
||||
import plistlib
|
||||
import requests
|
||||
import re
|
||||
from typing import Dict, Any, List
|
||||
|
||||
assets = plistlib.loads(
|
||||
requests.get(
|
||||
"https://mesu.apple.com/assets/com_apple_MobileAsset_Font7/com_apple_MobileAsset_Font7.xml"
|
||||
).content
|
||||
)["Assets"]
|
||||
|
||||
families: Dict[str, Any] = dict()
|
||||
all_assets: List[Dict[str, str]] = []
|
||||
for asset in assets:
|
||||
# Period used for extra PUA font
|
||||
names = set(
|
||||
[
|
||||
info["FontFamilyName"]
|
||||
for info in asset["FontInfo4"]
|
||||
if not info["FontFamilyName"].startswith(".")
|
||||
]
|
||||
)
|
||||
name = names.pop()
|
||||
def update_macos_extra():
|
||||
assets = plistlib.loads(
|
||||
requests.get(
|
||||
"https://mesu.apple.com/assets/com_apple_MobileAsset_Font7/com_apple_MobileAsset_Font7.xml"
|
||||
).content
|
||||
)["Assets"]
|
||||
|
||||
# There seems to be some support for things other than SHA-1 but I haven't seen it
|
||||
hsh = "sha1-" + base64.b64encode(asset["_Measurement"]).decode("utf-8")
|
||||
url = asset["__BaseURL"] + asset["__RelativePath"]
|
||||
asset_obj = {
|
||||
"url": url,
|
||||
"hash": hsh,
|
||||
families: Dict[str, Any] = dict()
|
||||
all_assets: List[Dict[str, str]] = []
|
||||
for asset in assets:
|
||||
# Period used for extra PUA font
|
||||
names = set(
|
||||
[
|
||||
info["FontFamilyName"]
|
||||
for info in asset["FontInfo4"]
|
||||
if not info["FontFamilyName"].startswith(".")
|
||||
]
|
||||
)
|
||||
name = names.pop()
|
||||
|
||||
# There seems to be some support for things other than SHA-1 but I haven't seen it
|
||||
hsh = "sha1-" + base64.b64encode(asset["_Measurement"]).decode("utf-8")
|
||||
url = asset["__BaseURL"] + asset["__RelativePath"]
|
||||
asset_obj = {
|
||||
"url": url,
|
||||
"hash": hsh,
|
||||
}
|
||||
all_assets.append(asset_obj)
|
||||
version = asset["_CompatibilityVersion"]
|
||||
|
||||
if len(names) > 1:
|
||||
print("Multiple family names found in asset:", ", ".join(names))
|
||||
if name in families:
|
||||
other_version = families[name]["version"]
|
||||
if version == other_version:
|
||||
families[name]["assets"].append(asset_obj)
|
||||
continue
|
||||
elif int(version) < int(other_version):
|
||||
print(f"Duplicate asset found for family {name}, skipping")
|
||||
continue
|
||||
|
||||
families[name] = {
|
||||
"assets": [asset_obj],
|
||||
"version": version,
|
||||
}
|
||||
|
||||
return {"extra": families, "all_extra": {"assets": all_assets, "version": "mixed"}}
|
||||
|
||||
|
||||
def update_macos_ipsw():
|
||||
ipsws = plistlib.loads(
|
||||
requests.get(
|
||||
"https://mesu.apple.com/assets/macos/com_apple_macOSIPSW/com_apple_macOSIPSW.xml"
|
||||
).content
|
||||
)["MobileDeviceSoftwareVersionsByVersion"]["1"]["MobileDeviceSoftwareVersions"]
|
||||
|
||||
# Apple seems to be naming everything Mac now, use the newest one
|
||||
# As of writing everything is UniversalMac but do this anyway
|
||||
pattern = re.compile(r"Mac(\d+),(\d+)")
|
||||
max_ident = (0, 0)
|
||||
for ident in ipsws.keys():
|
||||
if match := pattern.fullmatch(ident):
|
||||
major, minor = match.groups()
|
||||
major, minor = int(major), int(minor)
|
||||
if major > max_ident[0] or major == max_ident[0] and minor > max_ident[1]:
|
||||
max_ident = major, minor
|
||||
|
||||
ident = f"Mac{max_ident[0]},{max_ident[1]}"
|
||||
|
||||
# Unknown has an extra level we don't want, ignore it
|
||||
build = max(ipsws[ident].keys(), key=lambda item: "" if item == "Unknown" else item)
|
||||
ipsw = ipsws[ident][build]["Restore"]
|
||||
version = ipsw["ProductVersion"]
|
||||
|
||||
print(f"Using ipsw from macOS {version} (build {build})")
|
||||
return {
|
||||
"base": {
|
||||
"url": ipsw["FirmwareURL"],
|
||||
"hash": "sha1-"
|
||||
+ base64.b64encode(
|
||||
base64.b16decode(ipsw["FirmwareSHA1"], casefold=True)
|
||||
).decode("utf-8"),
|
||||
"version": version,
|
||||
"build": build,
|
||||
}
|
||||
}
|
||||
all_assets.append(asset_obj)
|
||||
version = asset["_CompatibilityVersion"]
|
||||
|
||||
if len(names) > 1:
|
||||
print("Multiple family names found in asset:", ", ".join(names))
|
||||
if name in families:
|
||||
other_version = families[name]["version"]
|
||||
if version == other_version:
|
||||
families[name]["assets"].append(asset_obj)
|
||||
continue
|
||||
elif int(version) < int(other_version):
|
||||
print(f"Duplicate asset found for family {name}, skipping")
|
||||
continue
|
||||
|
||||
families[name] = {
|
||||
"assets": [asset_obj],
|
||||
"version": version,
|
||||
}
|
||||
|
||||
with open("assets.json", "w") as f:
|
||||
json.dump(
|
||||
{"extra": families, "all_extra": {"assets": all_assets, "version": "mixed"}}, f
|
||||
)
|
||||
json.dump(update_macos_ipsw() | update_macos_extra(), f)
|
||||
|
|
24
flake.lock
24
flake.lock
|
@ -1,5 +1,28 @@
|
|||
{
|
||||
"nodes": {
|
||||
"artemist": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"utils": [
|
||||
"flake-utils"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1702966889,
|
||||
"narHash": "sha256-+vRUp3CoGyEya2JhhjxxM7JuVynsET7cbloYOlpZDOo=",
|
||||
"ref": "refs/heads/canon",
|
||||
"rev": "195c2e4d1c70f6e9b36f134097beddeedd2dd8d0",
|
||||
"revCount": 18,
|
||||
"type": "git",
|
||||
"url": "https://git.mildlyfunctional.gay/artemist/packages.git"
|
||||
},
|
||||
"original": {
|
||||
"type": "git",
|
||||
"url": "https://git.mildlyfunctional.gay/artemist/packages.git"
|
||||
}
|
||||
},
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
|
@ -35,6 +58,7 @@
|
|||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"artemist": "artemist",
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
|
|
15
flake.nix
15
flake.nix
|
@ -3,9 +3,14 @@
|
|||
inputs = {
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
nixpkgs.url = "github:nixos/nixpkgs";
|
||||
artemist = {
|
||||
url = "git+https://git.mildlyfunctional.gay/artemist/packages.git";
|
||||
inputs.utils.follows = "flake-utils";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, flake-utils, }:
|
||||
outputs = { self, nixpkgs, flake-utils, artemist }:
|
||||
with nixpkgs.lib;
|
||||
{
|
||||
overlays.default = (final: prev:
|
||||
|
@ -118,7 +123,7 @@
|
|||
meta = {
|
||||
inherit license;
|
||||
platforms = platforms.all;
|
||||
maintainers = with maintainers; [ artemist ];
|
||||
maintainers = [ maintainers.artemist ];
|
||||
description = "${name} font by ${author}";
|
||||
};
|
||||
};
|
||||
|
@ -127,13 +132,15 @@
|
|||
name = replaceStrings [ " " ] [ "-" ] (toLower font.name);
|
||||
value = buildLocalFont font;
|
||||
}) localFonts);
|
||||
appleFonts = final.callPackage ./apple { };
|
||||
appleFonts = final.callPackage ./apple {
|
||||
ipsw = if final ? ipsw then final.ipsw else artemist.packages.${final.stdenv.system}.ipsw;
|
||||
};
|
||||
});
|
||||
} // flake-utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [ self.overlays.default ];
|
||||
overlays = [ self.overlays.default artemist.overlays.default ];
|
||||
config.allowUnfree = true;
|
||||
};
|
||||
in {
|
||||
|
|
Loading…
Reference in a new issue