# iOS

## iPhoto Export

1. Download all your photos in batches of 1000
2. Extract all zip files
3. Use `find` to copy all files to photo-archive

    find ./icloud -type f -not -name '*.zip' -print0 | xargs -0 -I % /bin/bash -c 'cp -v --backup=numbered "%" photo-archive/'

4. Verify all photos were copied successfully

    find ./icloud -type f -not -name '*.zip' | wc -l
    find ./photo-archive -type f | wc -l

5. Rename duplicates so they have the correct extension

    ```bash
    # Collect duplicates
    find photo-archive -name '*.~*' > duplicates.txt
    cat duplicates.txt | wc -l

    # dry run convert duplicates named *.~n~ to something else
    for item in $(cat duplicates.txt); do echo mv $item photo-archive/$(python -c "from pathlib import Path; number=Path(\"$item\").suffix ;name = Path(Path(\"$item\").stem); print(name.stem + '_' + number.replace('~','').replace('.','') + name.suffix)"); done    
    # actual rename
    for item in $(cat duplicates.txt); do mv $item photo-archive/$(python -c "from pathlib import Path; number=Path(\"$item\").suffix ;name = Path(Path(\"$item\").stem); print(name.stem + '_' + number.replace('~','').replace('.','') + name.suffix)"); done

    # verify
    find photo-archive -name '*.~*'
    find ./photo-archive -type f | wc -l
    ```

6. Remove live photos

    Live photos show up as a .MOV files. They should be the only .MOV files in the folder. Remove
    them with:

    ```bash
    find photo-archive -name '*.MOV' -delete

    # verify
    find ./photo-archive -type f | wc -l
    ```

7. Organize by year

    To keep your photos folder from getting too bloated you should organize your photos into
    subfolders by (at least) year.

    [Phockup](https://github.com/ivandokov/phockup) seems to be able to do this:

    ```bash
    podman run -v ~/Pictures:/mnt ivandokov/phockup:latest /mnt/iphone /mnt/iOS -d YYYY
    ```

## Photos Export

<https://github.com/icloud-photos-downloader/icloud_photos_downloader>

```bash
podman run -it --rm --name icloudpd \
    -v $(pwd)/iPhotos:/data \
    -e TZ=America/New_York \
    icloudpd/icloudpd:latest \
    icloudpd \
        --directory /data \
        --username apple@ducoterra.net \
        --watch-with-interval 3600
```

You can browse all downloaded photos with `feh`:

```bash
pacman -S feh

feh --recursive --scale-down -d -S filename $(pwd)/iPhotos
```

## Extensions

- PNG
- HEIC: iOS HDR photo
- MOV
- DNG: iOS raw photo
- JPG
- 3gp: quicktime video file
- MP4
- GIF
- WEBP: Google photo container
- CR2: Canon raw photo

## Conversion

You will need `imagemagick` and `libraw`:

```bash
pacman -S imagemagick libraw
```

Then you can convert any image with magick:

```bash
magick input.HEIC output.png
magick input.HEIC output.jpeg
```

You get a list of all unique file extensions with:

```bash
find . -type f | awk -F. '!a[$NF]++{print $NF}'
```

Then use those file extensions to create a find command:

```bash
# -o means "or" in this case
# Parentheses are required
find . -type f -printf '%p\n' \( \
    -iname '*.jpg' \
    -o -iname '*.heic' \
    -o -iname '*.dng' \
    -o -iname '*.png' \
    -o -iname '*.WEBP' \
    -o -iname '*.cr2' \
\)
```

And then use xargs with magick to convert the images:

```bash
find . -type f \( \
    -iname '*.jpg' \
    -o -iname '*.heic' \
    -o -iname '*.dng' \
    -o -iname '*.png' \
    -o -iname '*.WEBP' \
    -o -iname '*.cr2' \
\) -print0 | xargs -0 -P $(nproc) -I % python -c "\
import subprocess; \
from pathlib import Path; \
to_folder = '/run/media/ducoterra/photos/'; \
p = Path(\"%\"); \
realpath = (str(p.parent) + '/' if str(p.parent) != '.' else '') + p.stem + '.jpg'; \
subprocess.run(['mkdir', '-p', to_folder + str(Path(realpath).parent)]); \
subprocess.run(['magick', \"%\", to_folder + realpath])"
```

And then videos:

```bash
find . -type f \( \
    -iname '*.MOV' \
    -o -iname '*.3gp' \
    -o -iname '*.MP4' \
    -o -iname '*.GIF' \
\) -print0 | xargs -0 -I % python -c "\
import subprocess; \
from pathlib import Path; \
to_folder = '/run/media/ducoterra/photos/'; \
p = Path(\"%\"); \
realpath = (str(p.parent) + '/' if str(p.parent) != '.' else '') + p.stem + '.mp4'; \
subprocess.run(['mkdir', '-p', to_folder + str(Path(realpath).parent)]); \
subprocess.run(['ffmpeg', '-i', '%', '-c', 'copy', to_folder + realpath])"
```