feat(pixi): some repl around, cannot match heic with mov
parent
8ba20cbc56
commit
7b5a6cfa94
|
@ -0,0 +1 @@
|
|||
__pycache__
|
|
@ -0,0 +1,20 @@
|
|||
[tool.poetry]
|
||||
name = "pixi"
|
||||
version = "0.0.1"
|
||||
description = "Toy project to investigate about apple photos synced iphone -> mac"
|
||||
authors = ["Pegasust <pegasucksgg@gmail.com>"]
|
||||
readme = "README.md"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.10"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
pytest = "^7.3.1"
|
||||
|
||||
[[tool.poetry.packages]]
|
||||
include = "repl"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
#!/usr/bin/env python
|
||||
"""
|
||||
REPL-friendly python mono-module for importing and execution singleton
|
||||
"""
|
||||
|
||||
import os
|
||||
from dataclasses import dataclass
|
||||
from itertools import groupby
|
||||
from typing import Iterable
|
||||
|
||||
mac_photos = os.getenv("MAC_PHOTOS_PATH", default="mac_photos")
|
||||
|
||||
|
||||
@dataclass(slots=True, frozen=True)
|
||||
class PhotosKExt:
|
||||
name: str
|
||||
parent: tuple[str, ...]
|
||||
exts_lowered: tuple[str, ...]
|
||||
|
||||
@classmethod
|
||||
def from_root_file(cls, root: str, filename: str):
|
||||
ext_elems = filename.split('.')
|
||||
return cls(
|
||||
name=ext_elems[0],
|
||||
parent=os.path.split(root),
|
||||
exts_lowered=tuple(
|
||||
ext.lower() for ext in ext_elems[1:]
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@dataclass(slots=True, frozen=True)
|
||||
class PhotosKey:
|
||||
filename: str
|
||||
parent: tuple[str, ...]
|
||||
|
||||
@classmethod
|
||||
def from_key_ext(cls, ext: PhotosKExt):
|
||||
return cls(filename=ext.name, parent=ext.parent)
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
class PhotosValue:
|
||||
exts: dict[str, list[str]]
|
||||
|
||||
def heic_paths(self) -> list[str]:
|
||||
return self.exts.get("heic", list())
|
||||
|
||||
def mov_paths(self) -> list[str]:
|
||||
return self.exts.get("mov", list())
|
||||
|
||||
|
||||
def candidate_exts(file_exts: Iterable[PhotosKExt]):
|
||||
"""
|
||||
>>> {ext: len(files)for ext, files in cexts.items()}
|
||||
stdout> {... 'mov': 2769, 'heic': 2354 ...}
|
||||
|
||||
We could make a bold guess that iPhone 11 stores both `heic` and `mov`
|
||||
for materialized best capture and live movie for live capture.
|
||||
"""
|
||||
exts_rv: dict[str, list[PhotosKExt]] = dict()
|
||||
|
||||
for file in file_exts:
|
||||
for ext in file.exts_lowered:
|
||||
exts_rv.setdefault(ext, list()).append(file)
|
||||
|
||||
return exts_rv
|
||||
|
||||
|
||||
def file_exts(photos_dir: str = mac_photos):
|
||||
return {
|
||||
PhotosKExt.from_root_file(filename=file, root=root)
|
||||
for root, _, files in os.walk(photos_dir, followlinks=True)
|
||||
for file in files
|
||||
}
|
||||
|
||||
|
||||
def photos_exts(files_with_ext: Iterable[PhotosKExt]):
|
||||
return {
|
||||
k: list(v)
|
||||
for k, v in groupby(files_with_ext, key=lambda x: (x.name, x.parent))
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
fexts = file_exts()
|
||||
cexts = candidate_exts(fexts)
|
||||
print(f"{photos_exts(fexts)=}")
|
||||
print(f"{cexts=}")
|
||||
movs = cexts['mov']
|
||||
heics = cexts['heic']
|
||||
heic_name_set = {heic.name.lower() for heic in heics}
|
||||
mov_name_set = {mov.name.lower() for mov in movs}
|
||||
print(len(heic_name_set - mov_name_set) - len(heic_name_set))
|
||||
# stdout> (not 0)
|
||||
# Hence, we are not able to match `.heic` with its `.mov` with just names
|
||||
# Could it be that the `.heic` also contains the high-quality live?
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -0,0 +1 @@
|
|||
/Users/hungtran/Pictures/Photos Library.photoslibrary
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
inputs,
|
||||
cell,
|
||||
}: let
|
||||
inherit (inputs.nixpkgs) system;
|
||||
inherit (cell.packages) pixi-deps pixi-edit;
|
||||
in {
|
||||
pixi = inputs.nixpkgs.mkShell {
|
||||
buildInputs = [
|
||||
pixi-deps
|
||||
pixi-edit
|
||||
inputs.std.packages.${system}.default
|
||||
];
|
||||
};
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
inputs,
|
||||
cell,
|
||||
}: let
|
||||
inherit (inputs.nixpkgs) system;
|
||||
poetry2nix = inputs.nix-boost.inputs.poetry2nix.legacyPackages.${system};
|
||||
|
||||
pixi-src = "${inputs.self}/dev/pixi";
|
||||
in {
|
||||
pixi-deps = poetry2nix.mkPoetryEnv {
|
||||
projectDir = pixi-src;
|
||||
};
|
||||
pixi-edit = poetry2nix.mkPoetryEditablePackage {
|
||||
projectDir = pixi-src;
|
||||
editablePackageSources = {
|
||||
pixi = pixi-src;
|
||||
};
|
||||
};
|
||||
}
|
|
@ -34,4 +34,6 @@ in {
|
|||
description = "Wrapper for keepassxc and keepassxc-cli with additional Darwin-specific fixes";
|
||||
};
|
||||
};
|
||||
|
||||
pixi-edit = inputs.cells.dev.packages.pixi-edit;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue