moving everything to active or retired vs incubating and graduated
All checks were successful
Reese's Arch Toolbox / build-and-push-arch-toolbox (push) Successful in 14s
All checks were successful
Reese's Arch Toolbox / build-and-push-arch-toolbox (push) Successful in 14s
This commit is contained in:
164
active/os_ios/ios.md
Normal file
164
active/os_ios/ios.md
Normal file
@@ -0,0 +1,164 @@
|
||||
# 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])"
|
||||
```
|
||||
Reference in New Issue
Block a user