Compare commits

...

61 Commits

Author SHA1 Message Date
Rhet Turnbull
eee8ff85ac Added example [skip ci] 2023-08-14 21:15:59 -07:00
Rhet Turnbull
d3a6fed119 Added example [skip ci] 2023-08-14 20:58:54 -07:00
Rhet Turnbull
1b8a254bd8 Updated CHANGELOG.md [skip ci] 2023-08-13 09:53:16 -07:00
Rhet Turnbull
f1cee7959d Updated CHANGELOG.md [skip ci] 2023-08-13 09:52:17 -07:00
Rhet Turnbull
a9843ac60e
Release v0 62 1 (#1158)
* Updated ExportResults docstrings so Sphinx picks them up

* Updated API_README so link works in docs

* Removed sweep templates
2023-08-13 09:47:53 -07:00
Rhet Turnbull
51b1abccf8 Updated CHANGELOG.md [skip ci] 2023-08-13 07:59:00 -07:00
Rhet Turnbull
d7cf66b11f Updated docs 2023-08-13 07:57:55 -07:00
Rhet Turnbull
bc0123ccdb Updated CHANGELOG.md [skip ci] 2023-08-13 07:47:51 -07:00
Rhet Turnbull
d6ca010fa5 Updated CHANGELOG.md [skip ci] 2023-08-12 19:46:51 -07:00
Rhet Turnbull
bb1f93a964
Release v0.62.0 (#1156) 2023-08-12 19:33:04 -07:00
Rhet Turnbull
8be71243d5
Refactor ruff (#1155)
* Refactored to make ruff happy

* Refactored tests, fixed bug in Mojave path_raw
2023-08-12 19:24:46 -07:00
Rhet Turnbull
e53d223f2d
Added shared_library to asdict() (#1154) 2023-08-12 11:21:49 -07:00
sweep-ai[bot]
009e17b75c
Configure Sweep (#1152)
* Create sweep.yaml config file

* Create bugfix template

* Create feature template

* Create refactor template

---------

Co-authored-by: sweep-ai[bot] <128439645+sweep-ai[bot]@users.noreply.github.com>
2023-08-12 11:07:56 -07:00
Rhet Turnbull
7cf28fe0d2
Added shared moment, syndicated, shared library to inspect (#1150) 2023-08-12 10:09:11 -07:00
Rhet Turnbull
0e0b4b1b09
Feature shared icloud library 860 (#1149)
* Initial support for iCloud Shared Library, #860

* Initial implementation of ShareInfo, ShareParticipant
2023-08-12 07:06:49 -07:00
Rhet Turnbull
b833cde599
Feature post function return 1136 (#1147)
* Changed return signature for post_function

* Updated post_function.py example

* Added tests for post_function returns ExportResults
2023-08-06 08:47:42 -07:00
Rhet Turnbull
0ff2d50004
Added API_README to docs (#1146) 2023-08-05 08:41:03 -07:00
Rhet Turnbull
2875b45d6e
Feature post command options 1142 (#1145)
* Added --post-command-break/catch

* Added --post-command-break/catch

* Added --post-command-error and tests

* Fixed help text for --post-command-error
2023-08-05 08:11:47 -07:00
Rhet Turnbull
8fb47d9c40 Fixed typo in template help 2023-08-05 07:35:38 -07:00
Rhet Turnbull
d1d6938581 Fixed typo in template help 2023-08-05 07:31:33 -07:00
Rhet Turnbull
3f74eeff44 Fixed typo in template help, #1143 2023-08-05 07:04:37 -07:00
Rhet Turnbull
93e1966607
Feature catch template error (#1141)
* Starting to implement catch_errors for sidecar_template

* Fixed error printing

* Fixed error printing

* Added tests for catch_errors
2023-08-03 06:33:17 -07:00
Rhet Turnbull
e937285a72
Feature keep file 1135 (#1139)
* Added gitignorefile

* Fixed gitignorefile for os.PathLike paths

* --keep now follows .gitignore rules

* Fixed ruff QA error

* Added support for .osxphotos_keep file

* Added reference to .osxphotos_keep

* Added tests for .osxphotos_keep

* Updated help text for --cleanup, --keep
2023-08-02 06:37:29 -07:00
Rhet Turnbull
284c272183 Updated .gitignore 2023-07-29 12:13:52 -07:00
Rhet Turnbull
db6caa5fa4
Feature custom sidecar zero length (#1138)
* Added skip_zero option to --sidecar-template

* Added missing test file
2023-07-29 10:29:16 -07:00
Rhet Turnbull
ed1486fd4b
Refactored --sidecar-template options (#1137) 2023-07-29 08:54:07 -07:00
Rhet Turnbull
8c49916253 Updated CHANGELOG.md [skip ci] 2023-07-25 07:22:37 -07:00
Rhet Turnbull
201bdacddd
Release v0.61.0 (#1132) 2023-07-25 06:55:23 -07:00
Rhet Turnbull
3999e54f6c
Feature custom sidecar 1123 cache (#1131)
* Added caching to Template, fixed typos

* Added additional sidecar tests
2023-07-25 06:44:39 -07:00
Rhet Turnbull
02b6698c80
Feature custom sidecar 1123 (#1129)
* Working on custom sidecar, #1123

* Working on custom sidecar, #1123

* Added custom sidecar example

* Added WRITE_SKIPPED argument for --sidecar-template

* Updated report writer for user sidecars

* Added noqa to long lines in report writer

* Initial tests for --sidecar-template

* Initial tests for --sidecar-template

* Initial tests for --sidecar-template

* Completed tests for --sidecar-template

* Added json example for --sidecar-template

* Added json example for --sidecar-template
2023-07-24 06:38:44 -07:00
Rhet Turnbull
3bae875a63 Added custom sidecar example 2023-07-22 12:39:18 -07:00
Rhet Turnbull
ea6ecc9767 Updated CHANGELOG.md [skip ci] 2023-07-20 06:30:36 -07:00
Rhet Turnbull
2b1ad4ed7f
Release v0.60.10 (#1128) 2023-07-20 06:22:09 -07:00
Rhet Turnbull
4efc0c9f56
Fixed syndicated photos to work on Photos 7, #1116 (#1127) 2023-07-20 06:20:07 -07:00
Rhet Turnbull
25d4015b65
Added scopes to orphans check (#1126) 2023-07-19 06:14:41 -07:00
Rhet Turnbull
1d46c9ce8b
Feature update photoinfo asdict (#1125)
* Added missing properties to PhotoInfo.asdict()

* Moved new properties to shallow=False
2023-07-19 05:30:57 -07:00
Rhet Turnbull
34fda8bcbc
Added more info to debug-dump --dump photos (#1124) 2023-07-19 05:30:25 -07:00
Rhet Turnbull
45468dd1a9 Updated CHANGELOG.md [skip ci] 2023-07-16 19:08:21 -07:00
allcontributors[bot]
903079a819
add neilpa as a contributor for bug (#1121)
* update README.md [skip ci]

* update .all-contributorsrc [skip ci]

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2023-07-16 19:02:34 -07:00
Rhet Turnbull
ff70981fbb
Release v0.60.9 (#1120) 2023-07-16 19:01:52 -07:00
Rhet Turnbull
052f2791ac
Bug shared moments 1116 (#1119)
* Partial for #1116, shared moment photos

* Added --shared-moment, --not-shared-moment query args
2023-07-16 18:14:25 -07:00
Rhet Turnbull
4f0e2a101d Updated CHANGELOG.md [skip ci] 2023-07-16 16:31:25 -07:00
Rhet Turnbull
185c6934b8
Release v0.60.8 (#1118) 2023-07-16 16:26:11 -07:00
Rhet Turnbull
c0fa8ef262
alpha support for macOS Sonoma (Photos 9) (#1117) 2023-07-16 15:09:06 -07:00
Rhet Turnbull
e87a42a3ac Updated CHANGELOG.md [skip ci] 2023-07-15 08:19:48 -07:00
Rhet Turnbull
bf9961e203
Release v0.60.7 (#1114) 2023-07-15 08:11:06 -07:00
dvdkon
c63b08694e
Add .AAE adjustment export (fix #97) (#1113)
Implements #97, export of adjustments data
2023-07-15 07:16:56 -07:00
Rhet Turnbull
30b0c13b33 Added docs for PlaceInfo.asdict() 2023-07-03 00:45:37 -07:00
Rhet Turnbull
1977578cfd Updated CHANGELOG.md [skip ci] 2023-07-02 13:27:51 -07:00
Rhet Turnbull
44a46cb652
Release v0.60.6, for real this time (#1112) 2023-07-02 09:42:57 -07:00
Rhet Turnbull
7ed8c7e583
Release v0.60.6 (#1110) 2023-07-02 09:34:29 -07:00
Rhet Turnbull
0064304574
Updated PlaceInfo to work with docs, #1100 (#1109) 2023-07-02 09:32:26 -07:00
Rhet Turnbull
179997aa96
Removed --library/--db from import command, #1105 (#1107) 2023-07-02 09:03:00 -07:00
allcontributors[bot]
889c878138
add msolo as a contributor for bug (#1106)
* update README.md [skip ci]

* update .all-contributorsrc [skip ci]

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2023-06-30 20:51:08 -05:00
Rhet Turnbull
2bac3a9c3e Updated CHANGELOG.md [skip ci] 2023-06-24 11:19:53 -07:00
Rhet Turnbull
3a1a4ad991
Release v0.60.5 (#1103) 2023-06-24 10:53:28 -07:00
Rhet Turnbull
2190628e82
Implemented --count, #1098 (#1102) 2023-06-24 10:50:34 -07:00
Rhet Turnbull
bb8e164f21
Unicode refactor (#1101)
* Began refactoring for improving unicode handling

* Added platform and unicode modules

* Added tests for unicode utilities

* Added tests for unicode utilities

* Added tests for unicode utilities

* Added tests for unicode utilities

* Fixed unicode tests for linux

* Fixed unicode tests for linux

* Fixed duplicate alubm name with --add-to-album

* Fixed test for linux

* Fix for duplicate unicode kewyords, see #907, #1085
2023-06-24 10:50:10 -07:00
Rhet Turnbull
7ccfe26e37 Added note on pipx reinstall: 2023-06-18 16:26:39 -07:00
Rhet Turnbull
2c80226ec8
fixed formatting (#1096) 2023-06-18 16:22:46 -07:00
Rhet Turnbull
492e1edb7f Updated CHANGELOG.md [skip ci] 2023-06-18 16:18:37 -07:00
416 changed files with 16543 additions and 2205 deletions

View File

@ -184,7 +184,8 @@
"avatar_url": "https://avatars.githubusercontent.com/u/42419?v=4",
"profile": "https://neilpa.me",
"contributions": [
"code"
"code",
"bug"
]
},
{
@ -588,6 +589,15 @@
"contributions": [
"bug"
]
},
{
"login": "msolo",
"name": "msolo",
"avatar_url": "https://avatars.githubusercontent.com/u/5078276?v=4",
"profile": "https://github.com/msolo",
"contributions": [
"bug"
]
}
],
"contributorsPerLine": 7,

View File

@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.60.4
current_version = 0.62.1
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)
serialize = {major}.{minor}.{patch}

4
.gitignore vendored
View File

@ -1,6 +1,6 @@
.metrics
.DS_store
__pycache__
__pycache__/
.coverage
.condaauto
t.out
@ -17,4 +17,4 @@ cli.spec
docsrc/_build/
venv/
.python-version
cov.xml
cov.xml

View File

@ -57,11 +57,12 @@ osxphotos provides several useful helper functions to make it easy to build simp
Here's a simple example showing how to use the `query_command` decorator to implement a simple command line tool. The `query_command` decorator turns your function into a full-fledged [Click](https://palletsprojects.com/p/click/) command line app that can be run via `osxphotos run example.py` or `python example.py` if you have pip installed osxphotos. Your command will include all the query options available in `osxphotos query` as command line options as well as `--verbose` and other convenient options.
<!--[[[cog
cog.out("```python\n")
cog.out("\n```python\n")
with open("examples/cli_example_1.py", "r") as f:
cog.out(f.read())
cog.out("```\n")
]]]-->
```python
"""Sample query command for osxphotos
@ -136,11 +137,12 @@ if __name__ == "__main__":
Here is a more advanced example that shows how to implement a script with a "dry run" and "resume" capability that preserves state between runs. Using the built-in helpers allows you to implement complex behavior in just a few lines of code.
<!--[[[cog
cog.out("```python\n")
cog.out("\n```python\n")
with open("examples/cli_example_2.py", "r") as f:
cog.out(f.read())
cog.out("```\n")
]]]-->
```python
"""Sample query command for osxphotos
@ -308,11 +310,12 @@ if __name__ == "__main__":
In addition to the `query_command` decorator, you can also use the `selection_command` decorator to implement a command that operates on the current selection in Photos.
<!--[[[cog
cog.out("```python\n")
cog.out("\n```python\n")
with open("examples/cli_example_3.py", "r") as f:
cog.out(f.read())
cog.out("```\n")
]]]-->
```python
"""Sample query command for osxphotos
@ -339,10 +342,7 @@ to your function. You can then do whatever you want with the photos.
from __future__ import annotations
import osxphotos
from osxphotos.cli import (
selection_command,
verbose,
)
from osxphotos.cli import selection_command, verbose
@selection_command
@ -445,7 +445,7 @@ if __name__ == "__main__":
## Package Interface
### PhotosDB
### <a name="photosdb">PhotosDB</a>
#### Read a Photos library database
@ -636,11 +636,11 @@ For example, in my library, Photos says I have 19,386 photos and 474 movies. Ho
Returns a single PhotoInfo instance for photo with UUID matching `uuid` or None if no photo is found matching `uuid`. If you know the UUID of a photo, `get_photo()` is much faster than `photos`. See also [photos()](#photos).
#### <A name="photosdbquery">`query(options: QueryOptions) -> List[PhotoInfo]:`</a>
#### <A name="photosdb_query">`query(options: QueryOptions) -> List[PhotoInfo]:`</a>
Returns a list of [PhotoInfo](#photoinfo) objects matching the query options. This is preferred method of querying the photos database. See [QueryOptions](#queryoptions) for details on the options available.
#### `keywords`
#### <a name="photosdb_keywords">`keywords`</a>
```python
# assumes photosdb is a PhotosDB object (see above)
@ -649,16 +649,16 @@ keywords = photosdb.keywords
Returns a list of the keywords found in the Photos library
#### <a name="photosdbalbuminfo">`album_info`</a>
#### <a name="photosdb_albuminfo">`album_info`</a>
```python
# assumes photosdb is a PhotosDB object (see above)
albums = photosdb.album_info
```
Returns a list of [AlbumInfo](#albuminfo) objects representing albums in the database or empty list if there are no albums. See also [albums](#albums) and [burst_album_info](#burst_album_info).
Returns a list of [AlbumInfo](#albuminfo) objects representing albums in the database or empty list if there are no albums. See also [albums](#photosdb_albums) and [burst_album_info](#burst_album_info).
#### `albums`
#### <a name="photosdb_albums">`albums`</a>
```python
# assumes photosdb is a PhotosDB object (see above)
@ -669,7 +669,7 @@ Returns a list of the album names found in the Photos library. See also [burst_a
**Note**: In Photos 5.0 (MacOS 10.15/Catalina), It is possible to have more than one album with the same name in Photos. Albums with duplicate names are treated as a single album and the photos in each are combined. For example, if you have two albums named "Wedding" and each has 2 photos, osxphotos will treat this as a single album named "Wedding" with 4 photos in it.
See also [album_info](#album_info.)
See also [album_info](#photosdb_album_info.)
#### `albums_shared`
@ -677,30 +677,30 @@ Returns list of shared album names found in photos database (e.g. albums shared
**Note**: *Only valid for Photos 5 / MacOS 10.15*; on Photos <= 4, prints warning and returns empty list.
#### `import_info`
#### <a name = "photosdb_import_info">`import_info`</a>
Returns a list of [ImportInfo](#importinfo) objects representing the import sessions for the database.
#### `project_info`
#### <a name="photosdb_project_info">`project_info`</a>
Returns a list of [ProjectInfo](#projectinfo) objects representing the projects/creations (cards, calendars, etc.) in the database.
#### `moment_info`
#### <a name="photosdb_moment_info">`moment_info`</a>
Returns the [MomentInfo](#momentinfo) object for the photo or `None` if the photo does not have an associated moment.
#### `folder_info`
#### <a name="photosdb_folder_info">`folder_info`</a>
```python
# assumes photosdb is a PhotosDB object (see above)
folders = photosdb.folder_info
```
Returns a list of [FolderInfo](#folderinfo) objects representing top level folders in the database or empty list if there are no folders. See also [folders](#folders).
Returns a list of [FolderInfo](#folderinfo) objects representing top level folders in the database or empty list if there are no folders. See also [folders](#photosdb_folders).
**Note**: Currently folder_info is only implemented for Photos 5 (Catalina); will return empty list and output warning if called on earlier database versions.
#### `folders`
#### <a name="photosdb_folders">`folders`</a>
```python
# assumes photosdb is a PhotosDB object (see above)
@ -711,16 +711,16 @@ Returns a list names of top level folder names in the database.
**Note**: Currently folders is only implemented for Photos 5 (Catalina); will return empty list and output warning if called on earlier database versions.
#### `persons`
#### <a name="photosdb_persons">`persons`</a>
```python
# assumes photosdb is a PhotosDB object (see above)
persons = photosdb.persons
```
Returns a list of the person names (faces) found in the Photos library. **Note**: It is of course possible to have more than one person with the same name, e.g. "Maria Smith", in the database. `persons` assumes these are the same person and will list only one person named "Maria Smith". If you need more information about persons in the database, see [person_info](#dbpersoninfo).
Returns a list of the person names (faces) found in the Photos library. **Note**: It is of course possible to have more than one person with the same name, e.g. "Maria Smith", in the database. `persons` assumes these are the same person and will list only one person named "Maria Smith". If you need more information about persons in the database, see [person_info](#photosdb_personinfo).
#### <a name="dbpersoninfo">`person_info`</a>
#### <a name="photosdb_person_info">`person_info`</a>
```python
# assumes photosdb is a PhotosDB object (see above)
@ -769,17 +769,17 @@ Returns a dictionary of shared albums (e.g. shared via iCloud photo sharing) fou
**Note**: *Photos 5 / MacOS 10.15 only*. On earlier versions of Photos, prints warning and returns empty dictionary.
#### `labels`
#### <a name="photosdb_labels">`labels`</a>
Returns image categorization labels associated with photos in the library as list of str.
**Note**: Only valid on Photos 5; on earlier versions, returns empty list. In Photos 5, Photos runs machine learning image categorization against photos in the library and automatically assigns labels to photos such as "People", "Dog", "Water", etc. A photo may have zero or more labels associated with it. See also [labels_normalized](#labels_normalized).
**Note**: Only valid on Photos 5; on earlier versions, returns empty list. In Photos 5, Photos runs machine learning image categorization against photos in the library and automatically assigns labels to photos such as "People", "Dog", "Water", etc. A photo may have zero or more labels associated with it. See also [labels_normalized](#photosdb_labels_normalized).
#### `labels_normalized`
#### <a name="photosdb_labels_normalized">`labels_normalized`</a>
Returns image categorization labels associated with photos in the library as list of str. Labels are normalized (e.g. converted to lower case). Use of normalized strings makes it easier to search if you don't how Apple capitalizes a label.
**Note**: Only valid on Photos 5; on earlier versions, returns empty list. In Photos 5, Photos runs machine learning image categorization against photos in the library and automatically assigns labels to photos such as "People", "Dog", "Water", etc. A photo may have zero or more labels associated with it. See also [labels](#labels).
**Note**: Only valid on Photos 5; on earlier versions, returns empty list. In Photos 5, Photos runs machine learning image categorization against photos in the library and automatically assigns labels to photos such as "People", "Dog", "Water", etc. A photo may have zero or more labels associated with it. See also [labels](#photosdb_labels).
#### `labels_as_dict`
@ -952,7 +952,7 @@ if __name__ == "__main__":
print(photo.original_filename, photo.date)
```
### PhotoInfo
### <a name="photoinfo">PhotoInfo</a>
PhotosDB.photos() returns a list of PhotoInfo objects. Each PhotoInfo object represents a single photo in the Photos library.
@ -1012,11 +1012,11 @@ Returns a list of [ProjectInfo](#projectinfo) objects representing projects/crea
Returns a list of the names of the persons in the photo
#### <a name="photopersoninfo">`person_info`</a>
#### <a name="photoinfo_personinfo">`person_info`</a>
Returns a list of [PersonInfo](#personinfo) objects representing persons in the photo. Each PersonInfo object is associated with one or more FaceInfo objects.
#### <a name="photofaceinfo">`face_info`</a>
#### <a name="photooinfo_faceinfo">`face_info`</a>
Returns a list of [FaceInfo](#faceinfo) objects representing faces in the photo. Each face is associated with the a PersonInfo object.
@ -1184,12 +1184,20 @@ Returns True if photo is a [cloud asset](#iscloudasset) and is synched to iCloud
#### `syndicated`
Return true if photo was shared via syndication (e.g. via Messages, etc.); these are photos that appear in "Shared with you" album. Photos 8+ only; returns None if not Photos 8+.
Return true if photo was shared via syndication (e.g. via Messages, etc.); these are photos that appear in "Shared with you" album. Photos 7+ only; returns None if not Photos 7+.
#### `saved_to_library`
Return True if syndicated photo has been saved to library; returns False if photo is not syndicated or has not been saved to the library.
Syndicated photos are photos that appear in "Shared with you" album. Photos 8+ only; returns None if not Photos 8+.
Syndicated photos are photos that appear in "Shared with you" album. Photos 7+ only; returns None if not Photos 7+.
#### `shared_moment`
Return True if photo is part of a shared moment, otherwise False. Shared moments are created when multiple photos are shared via iCloud. (e.g. in Messages)
#### `shared_library`
Return True if photo is included in shared iCloud library, otherwise False. Photos 8+ only; returns False if not Photos 8+.
#### `uti`
@ -1321,19 +1329,19 @@ for photo in photosdb.photos():
**Note**: Only valid on Photos 5+; on earlier versions, returns empty list. In Photos 5+, Photos runs machine learning image categorization against photos in the library and automatically assigns labels to photos such as "People", "Dog", "Water", etc. A photo may have zero or more labels associated with it. See also [labels](#labels).
#### <a name="photosearchinfo">`search_info`</a>
#### <a name="photoinfo_searchinfo">`search_info`</a>
Returns [SearchInfo](#searchinfo) object that represents search metadata for the photo.
**Note**: Only valid on Photos 5+; on ealier versions, returns None.
#### <a name="photosearchinfo-normalized">`search_info_normalized`</a>
#### <a name="photoinfo_search_info_normalized">`search_info_normalized`</a>
Returns [SearchInfo](#searchinfo) object that represents normalized search metadata for the photo. This returns a SearchInfo object just as `search_info` but all the properties of the object return normalized text (converted to lowercase).
**Note**: Only valid on Photos 5+; on ealier versions, returns None.
#### `exif_info`
#### <a name="photoinfo_exif_info">`exif_info`</a>
Returns an [ExifInfo](#exifinfo) object with EXIF details from the Photos database. See [ExifInfo](#exifinfo) for additional details.
@ -1341,7 +1349,7 @@ Returns an [ExifInfo](#exifinfo) object with EXIF details from the Photos databa
See also `exiftool`.
#### `exiftool`
#### <a name="photoinfo_exiftool">`exiftool`</a>
Returns an [ExifToolCaching](#exiftoolExifTool) object for the photo which provides an interface to [exiftool](https://exiftool.org/) allowing you to read the actual EXIF data in the image file inside the Photos library. If [exif_info](#exif-info) doesn't give you all the data you need, you can use `exiftool` to read the entire EXIF contents of the image.
@ -1491,7 +1499,7 @@ Some substitutions, notably `album`, `keyword`, and `person` could return multip
See [Template System](#template-system) for additional details.
#### <a name="detected_text_method">`detected_text(confidence_threshold=TEXT_DETECTION_CONFIDENCE_THRESHOLD)`</a>
#### <a name="photoinfo_detected_text">`detected_text(confidence_threshold=TEXT_DETECTION_CONFIDENCE_THRESHOLD)`</a>
Detects text in photo and returns lists of results as (detected text, confidence)
@ -1507,7 +1515,7 @@ See also [Text Detection](#textdetection).
### ExifInfo
[PhotosInfo.exif_info](#exif-info) returns an `ExifInfo` object with some EXIF data about the photo (Photos 5 only). `ExifInfo` contains the following properties:
[PhotosInfo.exif_info](#photoinfo_exif_info) returns an `ExifInfo` object with some EXIF data about the photo (Photos 5 only). `ExifInfo` contains the following properties:
```python
flash_fired: bool
@ -1545,7 +1553,7 @@ nikon_photos = [
### AlbumInfo
PhotosDB.album_info and PhotoInfo.album_info return a list of AlbumInfo objects. Each AlbumInfo object represents a single album in the Photos library.
[PhotosDB.album_info](#photosdb_album_info) and [PhotoInfo.album_info](photoinfo_album_info) return a list of AlbumInfo objects. Each AlbumInfo object represents a single album in the Photos library.
#### `uuid`
@ -1721,11 +1729,11 @@ Returns the universally unique identifier (uuid) of the folder. This is how Pho
Returns the title or name of the folder.
#### `album_info`
#### <a name="folderinfo_album_info">`album_info`</a>
Returns a list of [AlbumInfo](#albuminfo) objects representing each album contained in the folder.
#### `album_info_shared`
#### <a name="folderinfo_album_info_shared">`album_info_shared`</a>
Returns a list of [AlbumInfo](#albuminfo) objects for each shared album in the photos database.
@ -2036,11 +2044,11 @@ Returns a dictionary representation of the PersonInfo instance.
[PhotoInfo.face_info](#photofaceinfo) return a list of FaceInfo objects representing detected faces in a photo. The FaceInfo class has the following properties and methods.
#### `uuid`
#### <a name="faceinfo_uuid">`uuid`</a>
UUID of the face.
#### `name`
#### <a name="faceinfo_name">`name`</a>
Full name of the person represented by the face or None if person hasn't been given a name in Photos. This is a shortcut for `FaceInfo.person_info.name`.
@ -2048,11 +2056,11 @@ Full name of the person represented by the face or None if person hasn't been gi
UUID of the photo this face is associated with.
#### `person_info`
#### <a name="faceinfo_person_info">`person_info`</a>
[PersonInfo](#personinfo) object associated with this face.
#### `photo`
#### <a name="faceinfo_photo">`photo`</a>
[PhotoInfo](#photoinfo) object representing the photo that contains this face.
@ -2129,11 +2137,11 @@ The following additional properties are also available but are not yet fully doc
* `lip_makeup_type`:
* `smile_type`:
#### `asdict()`
#### <a name="faceinfo_asdict">`asdict()`</a>
Returns a dictionary representation of the FaceInfo instance.
#### `json()`
#### <a name="faceinfo_json">`json()`</a>
Returns a JSON representation of the FaceInfo instance.
@ -2241,8 +2249,9 @@ To get the path of every raw photo, whether it's a single raw photo or a raw+JPE
<!--[[[cog
from osxphotos.phototemplate import get_template_help
cog.out(get_template_help())
cog.out("\n"+get_template_help())
]]]-->
<!-- Generated by cog: see phototemplate.cog.md -->
The templating system converts one or template statements, written in osxphotos metadata templating language, to one or more rendered values using information from the photo being processed.
@ -2394,9 +2403,9 @@ e.g. `"{created.year}/{openbrace}{title}{closebrace}"` would result in `"2020/{P
**Variables**
You can define variables for later use in the template string using the format `{var:NAME,VALUE}`. Variables may then be referenced using the format `%NAME`. For example: `{var:foo,bar}` defines the variable `%foo` to have value `bar`. This can be useful if you want to re-use a complex template value in multiple places within your template string or for allowing the use of characters that would otherwise be prohibited in a template string. For example, the "pipe" (`|`) character is not allowed in a find/replace pair but you can get around this limitation like so: `{var:pipe,{pipe}}{title[-,%pipe]}` which replaces the `-` character with `|` (the value of `%pipe`).
You can define variables for later use in the template string using the format `{var:NAME,VALUE}` where `VALUE` is a template statement. Variables may then be referenced using the format `%NAME`. For example: `{var:foo,bar}` defines the variable `%foo` to have value `bar`. This can be useful if you want to re-use a complex template value in multiple places within your template string or for allowing the use of characters that would otherwise be prohibited in a template string. For example, the "pipe" (`|`) character is not allowed in a find/replace pair but you can get around this limitation like so: `{var:pipe,{pipe}}{title[-,%pipe]}` which replaces the `-` character with `|` (the value of `%pipe`).
Variables can also be referenced as fields in the template string, for example: `{var:year,created.year}{original_name}-{%year}`. In some cases, use of variables can make your template string more readable. Variables can be used as template fields, as values for filters, as values for conditional operations, or as default values. When used as a conditional value or default value, variables should be treated like any other field and enclosed in braces as conditional and default values are evaluated as template strings. For example: `{var:name,Katie}{person contains {%name}?{%name},Not-{%name}}`.
Variables can also be referenced as fields in the template string, for example: `{var:year,{created.year}}{original_name}-{%year}`. In some cases, use of variables can make your template string more readable. Variables can be used as template fields, as values for filters, as values for conditional operations, or as default values. When used as a conditional value or default value, variables should be treated like any other field and enclosed in braces as conditional and default values are evaluated as template strings. For example: `{var:name,Katie}{person contains {%name}?{%name},Not-{%name}}`.
If you need to use a `%` (percent sign character), you can escape the percent sign by using `%%`. You can also use the `{percent}` template field where a template field is required. For example:
@ -2407,8 +2416,9 @@ The following template field substitutions are availabe for use the templating s
<!--[[[cog
from osxphotos.phototemplate import get_template_field_table
cog.out(get_template_field_table())
cog.out("\n"+get_template_field_table()+"\n")
]]]-->
| Field | Description |
|--------------|-------------|
|{name}|Current filename of the photo|
@ -2502,7 +2512,7 @@ cog.out(get_template_field_table())
|{cr}|A carriage return: '\r'|
|{crlf}|A carriage return + line feed: '\r\n'|
|{tab}|:A tab: '\t'|
|{osxphotos_version}|The osxphotos version, e.g. '0.60.4'|
|{osxphotos_version}|The osxphotos version, e.g. '0.62.1'|
|{osxphotos_cmd_line}|The full command line used to run osxphotos|
|{album}|Album(s) photo is contained in|
|{folder_album}|Folder path + album photo is contained in. e.g. 'Folder/Subfolder/Album' or just 'Album' if no enclosing folder|
@ -2694,7 +2704,7 @@ Attributes:
### <a name="textdetection">Text Detection</a>
The [PhotoInfo.detected_text()](#detected_text_method) and the `{detected_text}` template will perform text detection on the photos in your library. Text detection is a slow process so to avoid unnecessary re-processing of photos, osxphotos will cache the results of the text detection process as an extended attribute on the photo image file. Extended attributes do not modify the actual file. The extended attribute is named `osxphotos.metadata:detected_text` and can be viewed using the built-in [xattr](https://ss64.com/osx/xattr.html) command or my [osxmetadata](https://github.com/RhetTbull/osxmetadata) tool. If you want to remove the cached attribute, you can do so with `xattr` as follows:
The [PhotoInfo.detected_text()](#photoinfo_detected_text) and the `{detected_text}` template will perform text detection on the photos in your library. Text detection is a slow process so to avoid unnecessary re-processing of photos, osxphotos will cache the results of the text detection process as an extended attribute on the photo image file. Extended attributes do not modify the actual file. The extended attribute is named `osxphotos.metadata:detected_text` and can be viewed using the built-in [xattr](https://ss64.com/osx/xattr.html) command or my [osxmetadata](https://github.com/RhetTbull/osxmetadata) tool. If you want to remove the cached attribute, you can do so with `xattr` as follows:
`find ~/Pictures/Photos\ Library.photoslibrary | xargs -I{} xattr -c osxphotos.metadata:detected_text '{}'`

View File

@ -2,6 +2,228 @@
All notable changes to this project will be documented in this file.
## [v0.62.1](https://github.com/RhetTbull/osxphotos/compare/v0.62.0...v0.62.1)
Documentation Fixes
### [v0.62.1] - 2023-08-13
#### Changed
#### Added
#### Removed
#### Fixed
- Minor fixes to the documentation.
#### Contributors
- [@RhetTbull](https://github.com/RhetTbull)
## [v0.62.0](https://github.com/RhetTbull/osxphotos/compare/v0.61.0...v0.62.0)
Initial support for iCloud Shared Libraries.
This release contains a lot of changes some of which may be breaking depending on your workflow. If you use `--sidecar-template`, you should look at the help for this option as the options have changed from boolean flags to named flags.
If you use `--report` with `--append` and you use CSV reports, you should archive the existing report and start a new one as the report now contains additional fields for user files.
If you use `--post-function`, the called function may now return an [ExportResults](https://rhettbull.github.io/osxphotos/reference.html#osxphotos.ExportResults) object with information about the files written, the files skipped, and any errors generated. If returned, these files will be included in `--report` and will be protected from cleanup with `--cleanup`.
Initial support for photos in Shared iCloud Libraries has been implemented. These photos can be queried via the `--shared-library` option. Still working on decoding the participant information (who is sharing the photos).
### [v0.62.0] - 20230812
#### Added
- Support for iCloud shared libraries, PhotoInfo.shared_library, PhotoInfo.share_participants, PhotoInfo.share_info (#860)
- Shared moment, syndicated, shared library support to `osxphotos inspect`(#860)
- `--post-command-error` option to configure error handling of `--post-command` (#1142)
- `.osxphotos_keep` file can now be used to specify keep patterns for `--cleanup` (#1135)
- Option to `--sidecar-template` to skip zero length files
#### Removed
#### Changed
- Changed `--sidecar-template` options to use named options instead of boolean
- Changed signature of --post-function function to enable it to work with --report, --cleanup (#1136)
- Now can catch template errors with `catch_errors` option to `--sidecar-template`
#### Fixed
- Fixed bug with PhotoInfo.path_raw on Photos <= 4.0
#### Contributors
- [@RhetTbull](https://github.com/RhetTbull) - Code and testing
- [@neilpa](https://github.com/neilpa) - The idea for custom sidecars and suggestions to improve the feature
- [@kvisle](https://github.com/kvisle) - For user testing with iCloud shared libraries
## [v0.61.0](https://github.com/RhetTbull/osxphotos/compare/v0.60.10...v0.61.0)
Custom sidecars for osxphotos export
### [v0.61.0] - 20230725
#### Added
- `--sidecar-template` option to export to allow user to specify one or more Mako templates for creating custom sidecars. See [example](https://github.com/RhetTbull/osxphotos/blob/main/examples/custom_sidecar.mako for an example)
#### Removed
#### Changed
- Added `user_sidecar` field to all report formats. This means that if you are using a CSV report with `--append`, you should archive your current report and create a new one which will include the correct headers. For JSON reports, the JSON outpput will simply include a new key for new records. For SQLite reports, the `report` table will be altered to add the new column.
#### Contributors
- [@RhetTbull](https://github.com/RhetTbull) - Code and testing
- [@neilpa](https://github.com/neilpa) - The idea for custom sidecars
## [v0.60.10](https://github.com/RhetTbull/osxphotos/compare/v0.60.9...v0.60.10)
Support for syndicated photos on Monterey (Photos 7)
### [v0.60.10] - 2023-07-20
#### Added
#### Removed
#### Changed
- Added additional photo details to `osxphotos debug-dump`
#### Fixed
- Syndicated photos now work on Monterey (#1116)
- `osxphotos orphans` now also scans the scopes directory
#### Contributors
- [@RhetTbull](https://github.com/RhetTbull) - code
- [@neilpa](https://github.com/neilpa) - for testing and finding the bug with syndicated photos on Monterey
## [v0.60.9](https://github.com/RhetTbull/osxphotos/compare/v0.60.8...v0.60.9)
Fixed missing path for photos that are part of a shared moment (Ventura+)
### [v0.60.9] - 2023-07-16
#### Added
- `PhotoInfo.shared_moment` property (True if photo is part of a shared moment, otherwise False)
- `--shared-moment`, `--not-shared-moment` query options
#### Removed
#### Changed
#### Contributors
- [@RhetTbull](https://github.com/RhetTbull) for code
- [@neilpa](https://github.com/neilpa) for identifying the bug with shared moments
## [v0.60.8](https://github.com/RhetTbull/osxphotos/compare/v0.60.7...v0.60.8)
Adds support for working with Photos libraries on macOS Sonoma (14.0 preview)
### [v0.60.8] - 2023-07-16
#### Added
- Supports Photos libraries created by Photos 9.0 (macOS Sonoma)
#### Removed
#### Changed
#### Contributors
- [@RhetTbull](https://github.com/RhetTbull) - code changes and testing
## [v0.60.7](https://github.com/RhetTbull/osxphotos/compare/v0.60.6...v0.60.7)
AAE Export Support
### [v0.60.7] - 2023-07-15
#### Addeded
- `--export-aae` option for `osxphotos export` to export the raw adjustments plist files
- `PhotoInfo.adjustments_path` property for retrieving the path to the AAE file
#### Removed
#### Changed
#### Contributors
- [@dvdkon](https://github.com/dvdkon) - code changes to add support for AAE files.
## [v0.60.6](https://github.com/RhetTbull/osxphotos/compare/v0.60.5...v0.60.6)
Remove --library/--db from import command
### [v0.60.6] - 2023-07-02
#### Added
#### Removed
- Removed `--library/--db` options from `osxphotos import` as import does not allow user to specify a library; the last used library is always used for import
#### Changed
#### Contributors
- [@RhetTbull](https://github.com/RhetTbull) - Code and documentation
- [@msolo](https://github.com/msolo) - Bug report for `osxphotos import`
## [v0.60.5](https://github.com/RhetTbull/osxphotos/compare/v0.60.4...v0.60.5)
Unicode Fixes
### [v0.60.5] - 2023-06-24
#### Added
- Added `--count`to query to print count of query results and exit (#1098)
#### Removed
#### Changed
#### Fixed
- Normalize unicode for `osxphotos import` to avoid duplicate keywords and albums (#1087)
#### Contributors
- [@RhetTbull](https://github.com/RhetTbull/osxphotos) - code & testing
- [@oPromessa](https://github.com/oPromessa) - for finding and documenting the unicode bugs
## [v0.60.4](https://github.com/RhetTbull/osxphotos/compare/v0.60.3...v0.60.4)
Updated testing / compatibility matrix to include macOS 13.4.
### [v0.60.4] - 2023-06-18
#### Fixed
#### Added
#### Removed
#### Changed
#### Contributors
- [@RhetTbull](https://github.com/RhetTbull/osxphotos) - code & testing
## [v0.60.3](https://github.com/RhetTbull/osxphotos/compare/v0.60.2...v0.60.3)
Ventura introduced a "shared with you" album which shows photos shared via Messages (and possible other apps). These show up in the Photos library in the

218
README.md
View File

@ -7,7 +7,7 @@
[![Downloads](https://static.pepy.tech/personalized-badge/osxphotos?period=month&units=international_system&left_color=black&right_color=brightgreen&left_text=downloads/month)](https://pepy.tech/project/osxphotos)
[![subreddit](https://img.shields.io/reddit/subreddit-subscribers/osxphotos?style=social)](https://www.reddit.com/r/osxphotos/)
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-61-orange.svg?style=flat)](#contributors)
[![All Contributors](https://img.shields.io/badge/all_contributors-62-orange.svg?style=flat)](#contributors)
<!-- ALL-CONTRIBUTORS-BADGE:END -->
OSXPhotos provides the ability to interact with and query Apple's Photos.app library on macOS and Linux. You can query the Photos library database — for example, file name, file path, and metadata such as keywords/tags, persons/faces, albums, etc. You can also easily export both the original and edited photos.
@ -39,10 +39,12 @@ On Linux, macOS-specific features of the CLI will not be available (these will n
The export and query CLI commands as well as the Python API will work on Linux which enables you to export photos
from a Photos library on a Linux machine.
Tested on macOS Sierra (10.12.6) through macOS Ventura (13.3). Tested on both x86 and Apple silicon (M1).
Tested on macOS Sierra (10.12.6) through macOS Ventura (13.4). Tested on both x86 and Apple silicon (M1).
macOS Sonoma (14.0) is currently supported but is still in alpha testing.
| macOS Version | macOS name | Photos.app version |
| ----------------- |------------|:-------------------|
| 14.0 | Sonoma | 9.0 ✅ (alpha support) |
| 13.0 - 13.4 | Ventura | 8.0 ✅ |
| 12.0 - 12.6 | Monterey | 7.0 ✅ |
| 10.16, 11.0-11.4 | Big Sur | 6.0 ✅ |
@ -74,6 +76,14 @@ Once you've installed osxphotos with pipx, to upgrade to the latest version:
pipx upgrade osxphotos
**Note**: When installing other packages with homebrew, homebrew may update the version of Python installed which would then cause any app (including osxphotos) installed with `pipx` to fail. If this happens, the easiest fix is to reinstall osxphotos with:
pipx reinstall osxphotos
Alternatively, you can reinstall all apps installed with `pipx` with:
pipx reinstall-all
### Installation using pip
You can also install directly from [pypi](https://pypi.org/project/osxphotos/):
@ -132,15 +142,8 @@ Usage: osxphotos [OPTIONS] COMMAND [ARGS]...
osxphotos: the multi-tool for your Photos library
Options:
-v, --version Show the version and exit.
--library, --db PHOTOS_LIBRARY_PATH
Specify path to Photos library. If not
provided, will attempt to find the library to
use in the following order: 1. last opened
library, 2. system library, 3.
~/Pictures/Photos Library.photoslibrary
--json Print output in JSON format.
-h, --help Show this message and exit.
-v, --version Show the version and exit.
-h, --help Show this message and exit.
Commands:
about Print information about osxphotos including license.
@ -879,6 +882,14 @@ Options:
to the library
--not-saved-to-library Search for syndicated photos that have not
saved to the library
--shared-moment Search for photos that are part of a shared
moment
--not-shared-moment Search for photos that are not part of a
shared moment
--shared-library Search for photos that are part of a shared
library
--not-shared-library Search for photos that are not part of a
shared library
--regex REGEX TEMPLATE Search for photos where TEMPLATE matches
regular expression REGEX. For example, to find
photos in an album that begins with 'Beach': '
@ -1065,6 +1076,14 @@ Options:
export all burst images; only the primary
photo will be exported--associated burst
images will be skipped.
--export-aae Also export an adjustments file detailing
edits made to the original. The resulting file
is named photoname.AAE. Note that to import
these files back to Photos succesfully, you
also need to export the edited photo and match
the filename format Photos.app expects:
--filename 'IMG_{edited_version?E,}{id:04d}'
--edited-suffix ''
--sidecar FORMAT Create sidecar for each photo exported; valid
FORMAT values: xmp, json, exiftool; --sidecar
xmp: create XMP sidecar used by Digikam, Adobe
@ -1102,6 +1121,61 @@ Options:
of different types but the same name in the
output directory, e.g. 'IMG_1234.JPG' and
'IMG_1234.MOV'.
--sidecar-template MAKO_TEMPLATE_FILE SIDECAR_FILENAME_TEMPLATE OPTIONS
Create a custom sidecar file for each photo
exported with user provided Mako template
(MAKO_TEMPLATE_FILE). MAKO_TEMPLATE_FILE must
be a valid Mako template (see
https://www.makotemplates.org/). The template
will passed the following variables: photo
(PhotoInfo object for the photo being
exported), sidecar_path (pathlib.Path object
for the path to the sidecar being written),
and photo_path (pathlib.Path object for the
path to the exported photo.
SIDECAR_FILENAME_TEMPLATE must be a valid
template string (see Templating System in
help) which will be rendered to generate the
filename of the sidecar file. The `{filepath}`
template variable may be used in the
SIDECAR_FILENAME_TEMPLATE to refer to the
filename of the photo being exported. OPTIONS
is a comma-separated list of strings providing
additional options to the template. Valid
options are: write_skipped, strip_whitespace,
strip_lines, skip_zero, catch_errors, none.
write_skipped will cause the sidecar file to
be written even if the photo is skipped during
export. If write_skipped is not passed as an
option, the sidecar file will not be written
if the photo is skipped during export.
strip_whitespace and strip_lines indicate
whether or not to strip whitespace and blank
lines, respectively, from the resulting
sidecar file. skip_zero causes the sidecar
file to be skipped if the rendered template is
zero-length. catch_errors causes errors in the
template to be caught and logged but not
raised. Without catch_errors, osxphotos will
abort the export if an error occurs in the
template. For example, to create a sidecar
file with extension .xmp using a template file
named 'sidecar.mako' and write a sidecar for
skipped photos and strip blank lines but not
whitespace: `--sidecar-template sidecar.mako
'{filepath}.xmp' write_skipped,strip_lines`.
To do the same but to drop the photo extension
from the sidecar filename: `--sidecar-template
sidecar.mako
'{filepath.parent}/{filepath.stem}.xmp'
write_skipped,strip_lines`. If you are not
passing any options, you must pass 'none' as
the last argument to --sidecar-template:
`--sidecar-template sidecar.mako
'{filepath}.xmp' none`. For an example Mako
file see https://raw.githubusercontent.com/Rhe
tTbull/osxphotos/main/examples/custom_sidecar.
mako
--exiftool Use exiftool to write metadata directly to
exported photos. To use this option, exiftool
must be installed and in the path. exiftool
@ -1282,30 +1356,59 @@ Options:
scripts or other files. Be sure this is what
you intend before using --cleanup. Use --dry-
run with --cleanup first if you're not
certain.
--keep KEEP_PATH When used with --cleanup, prevents file or
directory KEEP_PATH from being deleted when
cleanup is run. Use this if there are files in
the export directory that you don't want to be
deleted when --cleanup is run. KEEP_PATH may
be a file path, e.g.
'/Volumes/Photos/keep.jpg', or a file path and
wild card, e.g. '/Volumes/Photos/*.txt', or a
directory, e.g. '/Volumes/Photos/KeepMe'.
KEEP_PATH may be an absolute path or a
relative path. If it is relative, it must be
relative to the export destination. For
certain. To prevent files not generated by
osxphotos from being deleted, you may specify
one or more rulesin a file named
`.osxphotos_keep` in the export directory.
This file uses the same format as a .gitignore
file and should contain one rule per line;
lines starting with a `#` will be ignored.
Reference https://git-
scm.com/docs/gitignore#_pattern_format for
details. In addition to the standard
.gitignore rules, the rules may also be the
absolute path to a file or directory. For
example if export destination is
`/Volumes/Photos` and you want to keep all
`.txt` files, you can specify `--keep
"/Volumes/Photos/*.txt"` or `--keep "*.txt"`.
If wild card is used, KEEP_PATH must be
enclosed in quotes to prevent the shell from
expanding the wildcard, e.g. `--keep
"/Volumes/Photos/*.txt"`. If KEEP_PATH is a
directory, all files and directories contained
in KEEP_PATH will be kept. --keep may be
repeated to keep additional files/directories.
`.txt` files, in the top level of the export
directory, you can specify `/*.txt"` in the
.osxphotos_keep file. If you want to keep all
`.txt` files in the export directory and all
subdirectories, you can specify `**/*.txt`. If
present, the .osxphotos_keep file will be read
after the export is completed and any rules
found in the file will be added to the list of
rules to keep. See also --keep.
--keep KEEP_RULE When used with --cleanup, prevents file or
directory matching KEEP_RULE from being
deleted when cleanup is run. Use this if there
are files in the export directory that you
don't want to be deleted when --cleanup is
run. KEEP_RULE follows the same format rules a
.gitignore file. Reference https://git-
scm.com/docs/gitignore#_pattern_format for
details. In addition to the standard
.gitignore rules, KEEP_RULE may also be the
absolute path to a file or directory. For
example if export destination is
`/Volumes/Photos` and you want to keep all
`.txt` files, in the top level of the export
directory, you can specify `--keep "/*.txt"`.
If you want to keep all `.txt` files in the
export directory and all subdirectories, you
can specify `--keep "**/*.txt"`. If wild card
is used, KEEP_RULE must be enclosed in quotes
to prevent the shell from expanding the
wildcard. --keep may be repeated to keep
additional files/directories. Rules may also
be included in a file named `.osxphotos_keep`
in the export directory. If present, this file
will be read after the export is completed and
any rules found in the file will be added to
the list of rules to keep. This file uses the
same format as a .gitignore file and should
contain one rule per line; lines starting with
a `#` will be ignored.
--add-exported-to-album ALBUM Add all exported photos to album ALBUM in
Photos. Album ALBUM will be created if it
doesn't exist. All exported photos will be
@ -1349,8 +1452,18 @@ Options:
full path of all exported files to the file
'exported.txt'. You can run more than one
command by repeating the '--post-command'
option with different arguments. See Post
Command below.
option with different arguments. See also
--post-command-error and --post-function.See
Post Command below.
--post-command-error ACTION Specify either `continue` or `break` for
ACTION to control behavior when a post-command
fails. If `continue`, osxphotos will log the
error and continue processing. If `break`,
osxphotos will stop processing any additional
--post-command commands for the current photo
but will continue with the export. Without
--post-command-error, osxphotos will abort the
export if a post-command encounters an error.
--post-function filename.py::function
Run function on exported files. Use this in
format: --post-function filename.py::function
@ -1772,19 +1885,20 @@ e.g. "{created.year}/{openbrace}{title}{closebrace}" would result in
Variables
You can define variables for later use in the template string using the format
{var:NAME,VALUE}. Variables may then be referenced using the format %NAME.
For example: {var:foo,bar} defines the variable %foo to have value bar. This
can be useful if you want to re-use a complex template value in multiple
places within your template string or for allowing the use of characters that
would otherwise be prohibited in a template string. For example, the "pipe"
(|) character is not allowed in a find/replace pair but you can get around
this limitation like so: {var:pipe,{pipe}}{title[-,%pipe]} which replaces the
- character with | (the value of %pipe).
{var:NAME,VALUE} where VALUE is a template statement. Variables may then be
referenced using the format %NAME. For example: {var:foo,bar} defines the
variable %foo to have value bar. This can be useful if you want to re-use a
complex template value in multiple places within your template string or for
allowing the use of characters that would otherwise be prohibited in a
template string. For example, the "pipe" (|) character is not allowed in a
find/replace pair but you can get around this limitation like so:
{var:pipe,{pipe}}{title[-,%pipe]} which replaces the - character with | (the
value of %pipe).
Variables can also be referenced as fields in the template string, for
example: {var:year,created.year}{original_name}-{%year}. In some cases, use of
variables can make your template string more readable. Variables can be used
as template fields, as values for filters, as values for conditional
example: {var:year,{created.year}}{original_name}-{%year}. In some cases, use
of variables can make your template string more readable. Variables can be
used as template fields, as values for filters, as values for conditional
operations, or as default values. When used as a conditional value or default
value, variables should be treated like any other field and enclosed in braces
as conditional and default values are evaluated as template strings. For
@ -2109,7 +2223,7 @@ Substitution Description
{cr} A carriage return: '\r'
{crlf} A carriage return + line feed: '\r\n'
{tab} :A tab: '\t'
{osxphotos_version} The osxphotos version, e.g. '0.60.4'
{osxphotos_version} The osxphotos version, e.g. '0.62.1'
{osxphotos_cmd_line} The full command line used to run osxphotos
The following substitutions may result in multiple values. Thus if specified
@ -2332,6 +2446,7 @@ OSXPhotos adheres to the [XDG](https://specifications.freedesktop.org/basedir-sp
* `$XDG_DATA_HOME` or `$HOME/.local/share`: `osxphotos` directory containing local data files, for example, the help files displayed with `osxphotos docs`.
* Current working dir: `osxphotos_crash.log` file containing the stack trace of the last crash if OSXPhotos encounters a fatal error during execution.
* export directory (when running `osxphotos export` command): `.osxphotos_export.db` [SQLite](https://www.sqlite.org/index.html) database containing information needed to update an export and track metadata changes in exported photos. *Note*: This file may contain sensitive information such as locations and the names of persons in photos so if you are using `osxphotos export` to share with others, you may want to delete this file. You can also specify an alternate location for the export database using the `--exportdb` flag during export. See also `osxphotos help exportdb` for more information about built in utilities for working with the export database.
* While osxphotos does not create the file, if present in the root of the export directory, osxphotos will read the file `.osxphotos_keep` to load a list of file/directory patterns which should be excluded from `--cleanup` during export. This file uses the same rule format as [.gitignore](https://git-scm.com/docs/gitignore). See `osxphotos help export cleanup` for more information.
## Python API
@ -2491,9 +2606,9 @@ e.g. `"{created.year}/{openbrace}{title}{closebrace}"` would result in `"2020/{P
**Variables**
You can define variables for later use in the template string using the format `{var:NAME,VALUE}`. Variables may then be referenced using the format `%NAME`. For example: `{var:foo,bar}` defines the variable `%foo` to have value `bar`. This can be useful if you want to re-use a complex template value in multiple places within your template string or for allowing the use of characters that would otherwise be prohibited in a template string. For example, the "pipe" (`|`) character is not allowed in a find/replace pair but you can get around this limitation like so: `{var:pipe,{pipe}}{title[-,%pipe]}` which replaces the `-` character with `|` (the value of `%pipe`).
You can define variables for later use in the template string using the format `{var:NAME,VALUE}` where `VALUE` is a template statement. Variables may then be referenced using the format `%NAME`. For example: `{var:foo,bar}` defines the variable `%foo` to have value `bar`. This can be useful if you want to re-use a complex template value in multiple places within your template string or for allowing the use of characters that would otherwise be prohibited in a template string. For example, the "pipe" (`|`) character is not allowed in a find/replace pair but you can get around this limitation like so: `{var:pipe,{pipe}}{title[-,%pipe]}` which replaces the `-` character with `|` (the value of `%pipe`).
Variables can also be referenced as fields in the template string, for example: `{var:year,created.year}{original_name}-{%year}`. In some cases, use of variables can make your template string more readable. Variables can be used as template fields, as values for filters, as values for conditional operations, or as default values. When used as a conditional value or default value, variables should be treated like any other field and enclosed in braces as conditional and default values are evaluated as template strings. For example: `{var:name,Katie}{person contains {%name}?{%name},Not-{%name}}`.
Variables can also be referenced as fields in the template string, for example: `{var:year,{created.year}}{original_name}-{%year}`. In some cases, use of variables can make your template string more readable. Variables can be used as template fields, as values for filters, as values for conditional operations, or as default values. When used as a conditional value or default value, variables should be treated like any other field and enclosed in braces as conditional and default values are evaluated as template strings. For example: `{var:name,Katie}{person contains {%name}?{%name},Not-{%name}}`.
If you need to use a `%` (percent sign character), you can escape the percent sign by using `%%`. You can also use the `{percent}` template field where a template field is required. For example:
@ -2596,7 +2711,7 @@ The following template field substitutions are availabe for use the templating s
|{cr}|A carriage return: '\r'|
|{crlf}|A carriage return + line feed: '\r\n'|
|{tab}|:A tab: '\t'|
|{osxphotos_version}|The osxphotos version, e.g. '0.60.4'|
|{osxphotos_version}|The osxphotos version, e.g. '0.62.1'|
|{osxphotos_cmd_line}|The full command line used to run osxphotos|
|{album}|Album(s) photo is contained in|
|{folder_album}|Folder path + album photo is contained in. e.g. 'Folder/Subfolder/Album' or just 'Album' if no enclosing folder|
@ -2670,7 +2785,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<td align="center" valign="top" width="14.28%"><a href="https://github.com/narensankar0529"><img src="https://avatars3.githubusercontent.com/u/74054766?v=4?s=75" width="75px;" alt="narensankar0529"/><br /><sub><b>narensankar0529</b></sub></a><br /><a href="https://github.com/RhetTbull/osxphotos/issues?q=author%3Anarensankar0529" title="Bug reports">🐛</a> <a href="#userTesting-narensankar0529" title="User Testing">📓</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/martinhrpi"><img src="https://avatars2.githubusercontent.com/u/19407684?v=4?s=75" width="75px;" alt="Martin"/><br /><sub><b>Martin</b></sub></a><br /><a href="#research-martinhrpi" title="Research">🔬</a> <a href="#userTesting-martinhrpi" title="User Testing">📓</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/davidjroos"><img src="https://avatars.githubusercontent.com/u/15630844?v=4?s=75" width="75px;" alt="davidjroos "/><br /><sub><b>davidjroos </b></sub></a><br /><a href="https://github.com/RhetTbull/osxphotos/commits?author=davidjroos" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://neilpa.me"><img src="https://avatars.githubusercontent.com/u/42419?v=4?s=75" width="75px;" alt="Neil Pankey"/><br /><sub><b>Neil Pankey</b></sub></a><br /><a href="https://github.com/RhetTbull/osxphotos/commits?author=neilpa" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://neilpa.me"><img src="https://avatars.githubusercontent.com/u/42419?v=4?s=75" width="75px;" alt="Neil Pankey"/><br /><sub><b>Neil Pankey</b></sub></a><br /><a href="https://github.com/RhetTbull/osxphotos/commits?author=neilpa" title="Code">💻</a> <a href="https://github.com/RhetTbull/osxphotos/issues?q=author%3Aneilpa" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://aaronweb.net/"><img src="https://avatars.githubusercontent.com/u/604665?v=4?s=75" width="75px;" alt="Aaron van Geffen"/><br /><sub><b>Aaron van Geffen</b></sub></a><br /><a href="https://github.com/RhetTbull/osxphotos/commits?author=AaronVanGeffen" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ubrandes"><img src="https://avatars.githubusercontent.com/u/59647284?v=4?s=75" width="75px;" alt="ubrandes "/><br /><sub><b>ubrandes </b></sub></a><br /><a href="#ideas-ubrandes" title="Ideas, Planning, & Feedback">🤔</a></td>
</tr>
@ -2725,6 +2840,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<td align="center" valign="top" width="14.28%"><a href="https://github.com/rajscode"><img src="https://avatars.githubusercontent.com/u/99123253?v=4?s=75" width="75px;" alt="rajscode"/><br /><sub><b>rajscode</b></sub></a><br /><a href="https://github.com/RhetTbull/osxphotos/issues?q=author%3Arajscode" title="Bug reports">🐛</a> <a href="https://github.com/RhetTbull/osxphotos/commits?author=rajscode" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MaxLyt"><img src="https://avatars.githubusercontent.com/u/136200430?v=4?s=75" width="75px;" alt="MaxLyt"/><br /><sub><b>MaxLyt</b></sub></a><br /><a href="https://github.com/RhetTbull/osxphotos/issues?q=author%3AMaxLyt" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ces3001"><img src="https://avatars.githubusercontent.com/u/23762610?v=4?s=75" width="75px;" alt="ces3001"/><br /><sub><b>ces3001</b></sub></a><br /><a href="https://github.com/RhetTbull/osxphotos/issues?q=author%3Aces3001" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/msolo"><img src="https://avatars.githubusercontent.com/u/5078276?v=4?s=75" width="75px;" alt="msolo"/><br /><sub><b>msolo</b></sub></a><br /><a href="https://github.com/RhetTbull/osxphotos/issues?q=author%3Amsolo" title="Bug reports">🐛</a></td>
</tr>
</tbody>
</table>

View File

@ -30,6 +30,12 @@ python3 utils/generate_template_docs.py
m2r2 docsrc/source/template_help.md
rm docsrc/source/template_help.md
echo "Copying API_README.md to docsrc/source/API_README.md"
rm docsrc/source/API_README.rst
cp API_README.md docsrc/source/API_README.md
m2r2 docsrc/source/API_README.md
rm docsrc/source/API_README.md
# build docs
echo "Building docs"
(cd docsrc && make github && make pdf)

View File

@ -1,4 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: 224170f9893912f89ea2dcbac8e6ccff
config: 2fc476010affcee784f205bf294f4e73
tags: 645f666f9bcd5a90fca523b33c5a78b7

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../genindex.html" /><link rel="search" title="Search" href="../search.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
<title>Overview: module code - osxphotos 0.60.4 documentation</title>
<title>Overview: module code - osxphotos 0.62.1 documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="../_static/copybutton.css" />
@ -123,7 +123,7 @@
</label>
</div>
<div class="header-center">
<a href="../index.html"><div class="brand">osxphotos 0.60.4 documentation</div></a>
<a href="../index.html"><div class="brand">osxphotos 0.62.1 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -146,7 +146,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="../index.html">
<span class="sidebar-brand-text">osxphotos 0.60.4 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.62.1 documentation</span>
</a><form class="sidebar-search-container" method="get" action="../search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@ -160,6 +160,7 @@
<li class="toctree-l1"><a class="reference internal" href="../cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
<li class="toctree-l1"><a class="reference internal" href="../template_help.html">OSXPhotos Template System</a></li>
<li class="toctree-l1"><a class="reference internal" href="../package_overview.html">OSXPhotos Python Package Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="../API_README.html">OSXPhotos Python API</a></li>
<li class="toctree-l1"><a class="reference internal" href="../reference.html">OSXPhotos Python Reference</a></li>
</ul>

View File

@ -5,7 +5,7 @@
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../genindex.html" /><link rel="search" title="Search" href="../../search.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
<title>osxphotos._constants - osxphotos 0.60.4 documentation</title>
<title>osxphotos._constants - osxphotos 0.62.0 documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
@ -123,7 +123,7 @@
</label>
</div>
<div class="header-center">
<a href="../../index.html"><div class="brand">osxphotos 0.60.4 documentation</div></a>
<a href="../../index.html"><div class="brand">osxphotos 0.62.0 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -146,7 +146,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../index.html">
<span class="sidebar-brand-text">osxphotos 0.60.4 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.62.0 documentation</span>
</a><form class="sidebar-search-container" method="get" action="../../search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@ -160,6 +160,7 @@
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../template_help.html">OSXPhotos Template System</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../package_overview.html">OSXPhotos Python Package Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../api_readme.html">OSXPhotos Python API</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">OSXPhotos Python Reference</a></li>
</ul>
@ -215,23 +216,23 @@
<span class="c1"># Apple Epoch is Jan 1, 2001</span>
<span class="n">TIME_DELTA</span> <span class="o">=</span> <span class="p">(</span><span class="n">datetime</span><span class="p">(</span><span class="mi">2001</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-</span> <span class="n">datetime</span><span class="p">(</span><span class="mi">1970</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span><span class="o">.</span><span class="n">total_seconds</span><span class="p">()</span>
<span class="c1"># Unicode format to use for comparing strings</span>
<span class="n">UNICODE_FORMAT</span> <span class="o">=</span> <span class="s2">&quot;NFC&quot;</span>
<span class="c1"># which Photos library database versions have been tested</span>
<span class="c1"># Photos 2.0 (10.12.6) == 2622</span>
<span class="c1"># Photos 3.0 (10.13.6) == 3301</span>
<span class="c1"># Photos 4.0 (10.14.5) == 4016</span>
<span class="c1"># Photos 4.0 (10.14.6) == 4025</span>
<span class="c1"># Photos 5.0 (10.15.0) == 6000 or 5001</span>
<span class="c1"># Photos 5.0+ (10.15.0) == 6000 or 5001</span>
<span class="n">_TESTED_DB_VERSIONS</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;6000&quot;</span><span class="p">,</span> <span class="s2">&quot;5001&quot;</span><span class="p">,</span> <span class="s2">&quot;4025&quot;</span><span class="p">,</span> <span class="s2">&quot;4016&quot;</span><span class="p">,</span> <span class="s2">&quot;3301&quot;</span><span class="p">,</span> <span class="s2">&quot;2622&quot;</span><span class="p">]</span>
<span class="c1"># database model versions (applies to Photos 5, Photos 6)</span>
<span class="c1"># database model versions (applies to Photos 5+)</span>
<span class="c1"># these come from PLModelVersion key in binary plist in Z_METADATA.Z_PLIST</span>
<span class="c1"># Photos 5 (10.15.1) == 13537</span>
<span class="c1"># Photos 5 (10.15.4, 10.15.5, 10.15.6) == 13703</span>
<span class="c1"># Photos 6 (10.16.0 Beta) == 14104</span>
<span class="n">_TEST_MODEL_VERSIONS</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;13537&quot;</span><span class="p">,</span> <span class="s2">&quot;13703&quot;</span><span class="p">,</span> <span class="s2">&quot;14104&quot;</span><span class="p">]</span>
<span class="c1"># Photos 7 (12.0.1) == 15323</span>
<span class="c1"># Photos 8 (13.0.0) == 16320</span>
<span class="c1"># Photos 9 (14.0.0 dev preview) = 17120</span>
<span class="n">_TEST_MODEL_VERSIONS</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;13537&quot;</span><span class="p">,</span> <span class="s2">&quot;13703&quot;</span><span class="p">,</span> <span class="s2">&quot;14104&quot;</span><span class="p">,</span> <span class="s2">&quot;15323&quot;</span><span class="p">,</span> <span class="s2">&quot;16320&quot;</span><span class="p">,</span> <span class="s2">&quot;17120&quot;</span><span class="p">]</span>
<span class="n">_PHOTOS_2_VERSION</span> <span class="o">=</span> <span class="s2">&quot;2622&quot;</span>
@ -239,7 +240,7 @@
<span class="n">_PHOTOS_3_VERSION</span> <span class="o">=</span> <span class="s2">&quot;3301&quot;</span>
<span class="c1"># versions 5.0 and later have a different database structure</span>
<span class="n">_PHOTOS_4_VERSION</span> <span class="o">=</span> <span class="s2">&quot;4025&quot;</span> <span class="c1"># latest Mojove version on 10.14.6</span>
<span class="n">_PHOTOS_4_VERSION</span> <span class="o">=</span> <span class="s2">&quot;4025&quot;</span> <span class="c1"># latest Mojave version on 10.14.6</span>
<span class="n">_PHOTOS_5_VERSION</span> <span class="o">=</span> <span class="s2">&quot;5000&quot;</span> <span class="c1"># I&#39;ve seen both 5001 and 6000. 6000 is most common on Catalina and up but there are some version 5001 database in the wild</span>
<span class="c1"># Ranges for model version by Photos version</span>
@ -247,8 +248,15 @@
<span class="n">_PHOTOS_6_MODEL_VERSION</span> <span class="o">=</span> <span class="p">[</span><span class="mi">14000</span><span class="p">,</span> <span class="mi">14999</span><span class="p">]</span>
<span class="n">_PHOTOS_7_MODEL_VERSION</span> <span class="o">=</span> <span class="p">[</span><span class="mi">15000</span><span class="p">,</span> <span class="mi">15999</span><span class="p">]</span> <span class="c1"># Dev preview: 15134, 12.1: 15331</span>
<span class="n">_PHOTOS_8_MODEL_VERSION</span> <span class="o">=</span> <span class="p">[</span><span class="mi">16000</span><span class="p">,</span> <span class="mi">16999</span><span class="p">]</span> <span class="c1"># Ventura dev preview: 16119</span>
<span class="n">_PHOTOS_9_MODEL_VERSION</span> <span class="o">=</span> <span class="p">[</span><span class="mi">17000</span><span class="p">,</span> <span class="mi">17999</span><span class="p">]</span> <span class="c1"># Sonoma dev preview: 17120</span>
<span class="c1"># some table names differ between Photos 5 and Photos 6</span>
<span class="c1"># the preview versions of 12.0.0 had a difference schema for syndication info so need to check model version before processing</span>
<span class="n">_PHOTOS_SYNDICATION_MODEL_VERSION</span> <span class="o">=</span> <span class="mi">15323</span> <span class="c1"># 12.0.1</span>
<span class="c1"># shared iCloud library versions; dev preview doesn&#39;t contain same columns as release version</span>
<span class="n">_PHOTOS_SHARED_LIBRARY_VERSION</span> <span class="o">=</span> <span class="mi">16320</span> <span class="c1"># 13.0</span>
<span class="c1"># some table names differ between Photos 5 and later versions</span>
<span class="n">_DB_TABLE_NAMES</span> <span class="o">=</span> <span class="p">{</span>
<span class="mi">5</span><span class="p">:</span> <span class="p">{</span>
<span class="s2">&quot;ASSET&quot;</span><span class="p">:</span> <span class="s2">&quot;ZGENERICASSET&quot;</span><span class="p">,</span>
@ -261,6 +269,8 @@
<span class="s2">&quot;ASSET_ALBUM_JOIN&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_26ASSETS.Z_26ALBUMS&quot;</span><span class="p">,</span>
<span class="s2">&quot;ASSET_ALBUM_TABLE&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_26ASSETS&quot;</span><span class="p">,</span>
<span class="s2">&quot;HDR_TYPE&quot;</span><span class="p">:</span> <span class="s2">&quot;ZCUSTOMRENDEREDVALUE&quot;</span><span class="p">,</span>
<span class="s2">&quot;DETECTED_FACE_PERSON_FK&quot;</span><span class="p">:</span> <span class="s2">&quot;ZDETECTEDFACE.ZPERSON&quot;</span><span class="p">,</span>
<span class="s2">&quot;DETECTED_FACE_ASSET_FK&quot;</span><span class="p">:</span> <span class="s2">&quot;ZDETECTEDFACE.ZASSET&quot;</span><span class="p">,</span>
<span class="p">},</span>
<span class="mi">6</span><span class="p">:</span> <span class="p">{</span>
<span class="s2">&quot;ASSET&quot;</span><span class="p">:</span> <span class="s2">&quot;ZASSET&quot;</span><span class="p">,</span>
@ -273,6 +283,8 @@
<span class="s2">&quot;ASSET_ALBUM_JOIN&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_26ASSETS.Z_26ALBUMS&quot;</span><span class="p">,</span>
<span class="s2">&quot;ASSET_ALBUM_TABLE&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_26ASSETS&quot;</span><span class="p">,</span>
<span class="s2">&quot;HDR_TYPE&quot;</span><span class="p">:</span> <span class="s2">&quot;ZCUSTOMRENDEREDVALUE&quot;</span><span class="p">,</span>
<span class="s2">&quot;DETECTED_FACE_PERSON_FK&quot;</span><span class="p">:</span> <span class="s2">&quot;ZDETECTEDFACE.ZPERSON&quot;</span><span class="p">,</span>
<span class="s2">&quot;DETECTED_FACE_ASSET_FK&quot;</span><span class="p">:</span> <span class="s2">&quot;ZDETECTEDFACE.ZASSET&quot;</span><span class="p">,</span>
<span class="p">},</span>
<span class="mi">7</span><span class="p">:</span> <span class="p">{</span>
<span class="s2">&quot;ASSET&quot;</span><span class="p">:</span> <span class="s2">&quot;ZASSET&quot;</span><span class="p">,</span>
@ -285,6 +297,8 @@
<span class="s2">&quot;ASSET_ALBUM_JOIN&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_27ASSETS.Z_27ALBUMS&quot;</span><span class="p">,</span>
<span class="s2">&quot;ASSET_ALBUM_TABLE&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_27ASSETS&quot;</span><span class="p">,</span>
<span class="s2">&quot;HDR_TYPE&quot;</span><span class="p">:</span> <span class="s2">&quot;ZHDRTYPE&quot;</span><span class="p">,</span>
<span class="s2">&quot;DETECTED_FACE_PERSON_FK&quot;</span><span class="p">:</span> <span class="s2">&quot;ZDETECTEDFACE.ZPERSON&quot;</span><span class="p">,</span>
<span class="s2">&quot;DETECTED_FACE_ASSET_FK&quot;</span><span class="p">:</span> <span class="s2">&quot;ZDETECTEDFACE.ZASSET&quot;</span><span class="p">,</span>
<span class="p">},</span>
<span class="mi">8</span><span class="p">:</span> <span class="p">{</span>
<span class="s2">&quot;ASSET&quot;</span><span class="p">:</span> <span class="s2">&quot;ZASSET&quot;</span><span class="p">,</span>
@ -297,6 +311,22 @@
<span class="s2">&quot;ASSET_ALBUM_JOIN&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_28ASSETS.Z_28ALBUMS&quot;</span><span class="p">,</span>
<span class="s2">&quot;ASSET_ALBUM_TABLE&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_28ASSETS&quot;</span><span class="p">,</span>
<span class="s2">&quot;HDR_TYPE&quot;</span><span class="p">:</span> <span class="s2">&quot;ZHDRTYPE&quot;</span><span class="p">,</span>
<span class="s2">&quot;DETECTED_FACE_PERSON_FK&quot;</span><span class="p">:</span> <span class="s2">&quot;ZDETECTEDFACE.ZPERSON&quot;</span><span class="p">,</span>
<span class="s2">&quot;DETECTED_FACE_ASSET_FK&quot;</span><span class="p">:</span> <span class="s2">&quot;ZDETECTEDFACE.ZASSET&quot;</span><span class="p">,</span>
<span class="p">},</span>
<span class="mi">9</span><span class="p">:</span> <span class="p">{</span>
<span class="s2">&quot;ASSET&quot;</span><span class="p">:</span> <span class="s2">&quot;ZASSET&quot;</span><span class="p">,</span>
<span class="s2">&quot;KEYWORD_JOIN&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_1KEYWORDS.Z_40KEYWORDS&quot;</span><span class="p">,</span>
<span class="s2">&quot;ALBUM_JOIN&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_28ASSETS.Z_3ASSETS&quot;</span><span class="p">,</span>
<span class="s2">&quot;ALBUM_SORT_ORDER&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_28ASSETS.Z_FOK_3ASSETS&quot;</span><span class="p">,</span>
<span class="s2">&quot;IMPORT_FOK&quot;</span><span class="p">:</span> <span class="s2">&quot;null&quot;</span><span class="p">,</span>
<span class="s2">&quot;DEPTH_STATE&quot;</span><span class="p">:</span> <span class="s2">&quot;ZASSET.ZDEPTHTYPE&quot;</span><span class="p">,</span>
<span class="s2">&quot;UTI_ORIGINAL&quot;</span><span class="p">:</span> <span class="s2">&quot;ZINTERNALRESOURCE.ZCOMPACTUTI&quot;</span><span class="p">,</span>
<span class="s2">&quot;ASSET_ALBUM_JOIN&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_28ASSETS.Z_28ALBUMS&quot;</span><span class="p">,</span>
<span class="s2">&quot;ASSET_ALBUM_TABLE&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_28ASSETS&quot;</span><span class="p">,</span>
<span class="s2">&quot;HDR_TYPE&quot;</span><span class="p">:</span> <span class="s2">&quot;ZHDRTYPE&quot;</span><span class="p">,</span>
<span class="s2">&quot;DETECTED_FACE_PERSON_FK&quot;</span><span class="p">:</span> <span class="s2">&quot;ZDETECTEDFACE.ZPERSONFORFACE&quot;</span><span class="p">,</span>
<span class="s2">&quot;DETECTED_FACE_ASSET_FK&quot;</span><span class="p">:</span> <span class="s2">&quot;ZDETECTEDFACE.ZASSETFORFACE&quot;</span><span class="p">,</span>
<span class="p">},</span>
<span class="p">}</span>
@ -327,6 +357,7 @@
<span class="p">(</span><span class="s2">&quot;13&quot;</span><span class="p">,</span> <span class="s2">&quot;2&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;13&quot;</span><span class="p">,</span> <span class="s2">&quot;3&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;13&quot;</span><span class="p">,</span> <span class="s2">&quot;4&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;14&quot;</span><span class="p">,</span> <span class="s2">&quot;0&quot;</span><span class="p">),</span>
<span class="p">]</span>
<span class="c1"># Photos 5 has persons who are empty string if unidentified face</span>

View File

@ -5,7 +5,7 @@
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../genindex.html" /><link rel="search" title="Search" href="../../search.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
<title>osxphotos.albuminfo - osxphotos 0.59.2 documentation</title>
<title>osxphotos.albuminfo - osxphotos 0.61.0 documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
@ -123,7 +123,7 @@
</label>
</div>
<div class="header-center">
<a href="../../index.html"><div class="brand">osxphotos 0.59.2 documentation</div></a>
<a href="../../index.html"><div class="brand">osxphotos 0.61.0 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -146,7 +146,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../index.html">
<span class="sidebar-brand-text">osxphotos 0.59.2 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.61.0 documentation</span>
</a><form class="sidebar-search-container" method="get" action="../../search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">

View File

@ -5,7 +5,7 @@
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../genindex.html" /><link rel="search" title="Search" href="../../search.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
<title>osxphotos.debug - osxphotos 0.58.1 documentation</title>
<title>osxphotos.debug - osxphotos 0.61.0 documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
@ -123,7 +123,7 @@
</label>
</div>
<div class="header-center">
<a href="../../index.html"><div class="brand">osxphotos 0.58.1 documentation</div></a>
<a href="../../index.html"><div class="brand">osxphotos 0.61.0 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -146,7 +146,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../index.html">
<span class="sidebar-brand-text">osxphotos 0.58.1 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.61.0 documentation</span>
</a><form class="sidebar-search-container" method="get" action="../../search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">

View File

@ -1,36 +1,200 @@
<!doctype html>
<html class="no-js" lang="en">
<head><meta charset="utf-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../genindex.html" /><link rel="search" title="Search" href="../../search.html" />
<!DOCTYPE html>
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
<title>osxphotos.exifinfo - osxphotos 0.61.0 documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo-extensions.css?digest=30d1aed668e5c3a91c3e3bf6a60b675221979f0e" />
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>osxphotos.exifinfo &#8212; osxphotos 0.47.9 documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/alabaster.css" />
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
<script src="../../_static/jquery.js"></script>
<script src="../../_static/underscore.js"></script>
<script src="../../_static/doctools.js"></script>
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
<style>
body {
--color-code-background: #f8f8f8;
--color-code-foreground: black;
}
@media not print {
body[data-theme="dark"] {
--color-code-background: #202020;
--color-code-foreground: #d0d0d0;
}
@media (prefers-color-scheme: dark) {
body:not([data-theme="light"]) {
--color-code-background: #202020;
--color-code-foreground: #d0d0d0;
}
}
}
</style></head>
<body>
<script>
document.body.dataset.theme = localStorage.getItem("theme") || "auto";
</script>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="svg-toc" viewBox="0 0 24 24">
<title>Contents</title>
<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024">
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 0 0 0 13.8z"/>
</svg>
</symbol>
<symbol id="svg-menu" viewBox="0 0 24 24">
<title>Menu</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-menu">
<line x1="3" y1="12" x2="21" y2="12"></line>
<line x1="3" y1="6" x2="21" y2="6"></line>
<line x1="3" y1="18" x2="21" y2="18"></line>
</svg>
</symbol>
<symbol id="svg-arrow-right" viewBox="0 0 24 24">
<title>Expand</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-chevron-right">
<polyline points="9 18 15 12 9 6"></polyline>
</svg>
</symbol>
<symbol id="svg-sun" viewBox="0 0 24 24">
<title>Light mode</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather-sun">
<circle cx="12" cy="12" r="5"></circle>
<line x1="12" y1="1" x2="12" y2="3"></line>
<line x1="12" y1="21" x2="12" y2="23"></line>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
<line x1="1" y1="12" x2="3" y2="12"></line>
<line x1="21" y1="12" x2="23" y2="12"></line>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
</svg>
</symbol>
<symbol id="svg-moon" viewBox="0 0 24 24">
<title>Dark mode</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-moon">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z" />
</svg>
</symbol>
<symbol id="svg-sun-half" viewBox="0 0 24 24">
<title>Auto light/dark mode</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-shadow">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
<circle cx="12" cy="12" r="9" />
<path d="M13 12h5" />
<path d="M13 15h4" />
<path d="M13 18h1" />
<path d="M13 9h4" />
<path d="M13 6h1" />
</svg>
</symbol>
</svg>
<input type="checkbox" class="sidebar-toggle" name="__navigation" id="__navigation">
<input type="checkbox" class="sidebar-toggle" name="__toc" id="__toc">
<label class="overlay sidebar-overlay" for="__navigation">
<div class="visually-hidden">Hide navigation sidebar</div>
</label>
<label class="overlay toc-overlay" for="__toc">
<div class="visually-hidden">Hide table of contents sidebar</div>
</label>
<div class="page">
<header class="mobile-header">
<div class="header-left">
<label class="nav-overlay-icon" for="__navigation">
<div class="visually-hidden">Toggle site navigation sidebar</div>
<i class="icon"><svg><use href="#svg-menu"></use></svg></i>
</label>
</div>
<div class="header-center">
<a href="../../index.html"><div class="brand">osxphotos 0.61.0 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
<button class="theme-toggle">
<div class="visually-hidden">Toggle Light / Dark / Auto color theme</div>
<svg class="theme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
<svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
<svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
</button>
</div>
<label class="toc-overlay-icon toc-header-icon no-toc" for="__toc">
<div class="visually-hidden">Toggle table of contents sidebar</div>
<i class="icon"><svg><use href="#svg-toc"></use></svg></i>
</label>
</div>
</header>
<aside class="sidebar-drawer">
<div class="sidebar-container">
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../index.html">
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<span class="sidebar-brand-text">osxphotos 0.61.0 documentation</span>
</a><form class="sidebar-search-container" method="get" action="../../search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
<input type="hidden" name="check_keywords" value="yes">
<input type="hidden" name="area" value="default">
</form>
<div id="searchbox"></div><div class="sidebar-scroll"><div class="sidebar-tree">
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../overview.html">OSXPhotos</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../tutorial.html">OSXPhotos Tutorial</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../template_help.html">OSXPhotos Template System</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../package_overview.html">OSXPhotos Python Package Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">OSXPhotos Python Reference</a></li>
</ul>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
</div>
</div>
<div class="body" role="main">
<h1>Source code for osxphotos.exifinfo</h1><div class="highlight"><pre>
</div>
</div>
</aside>
<div class="main">
<div class="content">
<div class="article-container">
<a href="#" class="back-to-top muted-link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12z"></path>
</svg>
<span>Back to top</span>
</a>
<div class="content-icon-container">
<div class="theme-toggle-container theme-toggle-content">
<button class="theme-toggle">
<div class="visually-hidden">Toggle Light / Dark / Auto color theme</div>
<svg class="theme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
<svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
<svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
</button>
</div>
<label class="toc-overlay-icon toc-content-icon no-toc" for="__toc">
<div class="visually-hidden">Toggle table of contents sidebar</div>
<i class="icon"><svg><use href="#svg-toc"></use></svg></i>
</label>
</div>
<article role="main">
<h1>Source code for osxphotos.exifinfo</h1><div class="highlight"><pre>
<span></span><span class="sd">&quot;&quot;&quot; ExifInfo class to expose EXIF info from the library &quot;&quot;&quot;</span>
<span class="kn">from</span> <span class="nn">dataclasses</span> <span class="kn">import</span> <span class="n">dataclass</span>
@ -62,72 +226,47 @@
<span class="n">codec</span><span class="p">:</span> <span class="nb">str</span>
<span class="n">lens_model</span><span class="p">:</span> <span class="nb">str</span></div>
</pre></div>
</div>
</article>
</div>
<footer>
<div class="related-pages">
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../../index.html">osxphotos</a></h1>
<h3>Navigation</h3>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../overview.html">osxphotos</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../tutorial.html">Tutorial</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">osxphotos command line interface (CLI)</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">osxphotos package</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../../index.html">Documentation overview</a><ul>
<li><a href="../index.html">Module code</a><ul>
</ul></li>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script>
<div class="bottom-of-page">
<div class="left-details">
<div class="copyright">
Copyright &#169; 2021, Rhet Turnbull
</div>
Made with <a href="https://www.sphinx-doc.org/">Sphinx</a> and <a class="muted-link" href="https://pradyunsg.me">@pradyunsg</a>'s
<a href="https://github.com/pradyunsg/furo">Furo</a>
</div>
<div class="right-details">
<div class="icons">
</div>
</div>
</div>
</div>
<div class="clearer"></div>
</footer>
</div>
<div class="footer">
&copy;2021, Rhet Turnbull.
<aside class="toc-drawer no-toc">
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 4.4.0</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
</div>
</body>
</aside>
</div>
</div><script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
<script src="../../_static/jquery.js"></script>
<script src="../../_static/underscore.js"></script>
<script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script>
<script src="../../_static/doctools.js"></script>
<script src="../../_static/sphinx_highlight.js"></script>
<script src="../../_static/scripts/furo.js"></script>
<script src="../../_static/clipboard.min.js"></script>
<script src="../../_static/copybutton.js"></script>
</body>
</html>

View File

@ -5,7 +5,7 @@
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../genindex.html" /><link rel="search" title="Search" href="../../search.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
<title>osxphotos.exiftool - osxphotos 0.59.1 documentation</title>
<title>osxphotos.exiftool - osxphotos 0.62.0 documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
@ -123,7 +123,7 @@
</label>
</div>
<div class="header-center">
<a href="../../index.html"><div class="brand">osxphotos 0.59.1 documentation</div></a>
<a href="../../index.html"><div class="brand">osxphotos 0.62.0 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -146,7 +146,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../index.html">
<span class="sidebar-brand-text">osxphotos 0.59.1 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.62.0 documentation</span>
</a><form class="sidebar-search-container" method="get" action="../../search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@ -160,6 +160,7 @@
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../template_help.html">OSXPhotos Template System</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../package_overview.html">OSXPhotos Python Package Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../api_readme.html">OSXPhotos Python API</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">OSXPhotos Python Reference</a></li>
</ul>
@ -255,7 +256,7 @@
<span class="k">def</span> <span class="nf">escape_str</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;escape string for use with exiftool -E&quot;&quot;&quot;</span>
<span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">str</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<span class="k">return</span> <span class="n">s</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">html</span><span class="o">.</span><span class="n">escape</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="s2">&quot;&amp;#xa;&quot;</span><span class="p">)</span>
@ -266,7 +267,7 @@
<span class="k">def</span> <span class="nf">unescape_str</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;unescape an HTML string returned by exiftool -E&quot;&quot;&quot;</span>
<span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">str</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<span class="k">return</span> <span class="n">s</span>
<span class="c1"># avoid &quot; in values which result in json.loads() throwing an exception, #636</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">&quot;&amp;quot;&quot;</span><span class="p">,</span> <span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&quot;&#39;</span><span class="p">)</span>

View File

@ -5,7 +5,7 @@
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../genindex.html" /><link rel="search" title="Search" href="../../search.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
<title>osxphotos.export_db - osxphotos 0.60.2 documentation</title>
<title>osxphotos.export_db - osxphotos 0.61.0 documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
@ -123,7 +123,7 @@
</label>
</div>
<div class="header-center">
<a href="../../index.html"><div class="brand">osxphotos 0.60.2 documentation</div></a>
<a href="../../index.html"><div class="brand">osxphotos 0.61.0 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -146,7 +146,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../index.html">
<span class="sidebar-brand-text">osxphotos 0.60.2 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.61.0 documentation</span>
</a><form class="sidebar-search-container" method="get" action="../../search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@ -224,7 +224,7 @@
<span class="kn">from</span> <span class="nn">._constants</span> <span class="kn">import</span> <span class="n">OSXPHOTOS_EXPORT_DB</span><span class="p">,</span> <span class="n">SQLITE_CHECK_SAME_THREAD</span>
<span class="kn">from</span> <span class="nn">._version</span> <span class="kn">import</span> <span class="n">__version__</span>
<span class="kn">from</span> <span class="nn">.fileutil</span> <span class="kn">import</span> <span class="n">FileUtil</span>
<span class="kn">from</span> <span class="nn">.utils</span> <span class="kn">import</span> <span class="n">normalize_fs_path</span>
<span class="kn">from</span> <span class="nn">.unicode</span> <span class="kn">import</span> <span class="n">normalize_fs_path</span>
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">&quot;ExportDB&quot;</span><span class="p">,</span>

View File

@ -5,7 +5,7 @@
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../genindex.html" /><link rel="search" title="Search" href="../../search.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
<title>osxphotos.fileutil - osxphotos 0.60.0 documentation</title>
<title>osxphotos.fileutil - osxphotos 0.61.0 documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
@ -123,7 +123,7 @@
</label>
</div>
<div class="header-center">
<a href="../../index.html"><div class="brand">osxphotos 0.60.0 documentation</div></a>
<a href="../../index.html"><div class="brand">osxphotos 0.61.0 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -146,7 +146,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../index.html">
<span class="sidebar-brand-text">osxphotos 0.60.0 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.61.0 documentation</span>
</a><form class="sidebar-search-container" method="get" action="../../search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@ -207,7 +207,8 @@
<span class="kn">from</span> <span class="nn">tempfile</span> <span class="kn">import</span> <span class="n">TemporaryDirectory</span>
<span class="kn">from</span> <span class="nn">.imageconverter</span> <span class="kn">import</span> <span class="n">ImageConverter</span>
<span class="kn">from</span> <span class="nn">.utils</span> <span class="kn">import</span> <span class="n">is_macos</span><span class="p">,</span> <span class="n">normalize_fs_path</span>
<span class="kn">from</span> <span class="nn">.platform</span> <span class="kn">import</span> <span class="n">is_macos</span>
<span class="kn">from</span> <span class="nn">.unicode</span> <span class="kn">import</span> <span class="n">normalize_fs_path</span>
<span class="k">if</span> <span class="n">is_macos</span><span class="p">:</span>
<span class="kn">import</span> <span class="nn">Foundation</span>

View File

@ -1,13 +1,13 @@
<!doctype html>
<html class="no-js">
<html class="no-js" lang="en">
<head><meta charset="utf-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../genindex.html" /><link rel="search" title="Search" href="../../search.html" />
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/>
<title>osxphotos.momentinfo - osxphotos 0.48.3 documentation</title>
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
<title>osxphotos.momentinfo - osxphotos 0.61.0 documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo-extensions.css?digest=30d1aed668e5c3a91c3e3bf6a60b675221979f0e" />
@ -123,7 +123,7 @@
</label>
</div>
<div class="header-center">
<a href="../../index.html"><div class="brand">osxphotos 0.48.3 documentation</div></a>
<a href="../../index.html"><div class="brand">osxphotos 0.61.0 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -146,7 +146,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../index.html">
<span class="sidebar-brand-text">osxphotos 0.48.3 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.61.0 documentation</span>
</a><form class="sidebar-search-container" method="get" action="../../search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@ -160,7 +160,7 @@
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../template_help.html">OSXPhotos Template System</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../package_overview.html">OSXPhotos Python Package Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">OSXPhotos python API</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">OSXPhotos Python Reference</a></li>
</ul>
</div>
@ -179,7 +179,8 @@
</svg>
<span>Back to top</span>
</a>
<div class="content-icon-container"><div class="theme-toggle-container theme-toggle-content">
<div class="content-icon-container">
<div class="theme-toggle-container theme-toggle-content">
<button class="theme-toggle">
<div class="visually-hidden">Toggle Light / Dark / Auto color theme</div>
<svg class="theme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
@ -194,91 +195,91 @@
</div>
<article role="main">
<h1>Source code for osxphotos.momentinfo</h1><div class="highlight"><pre>
<span></span><span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"MomentInfo"</span><span class="p">]</span>
<span class="sd">"""MomentInfo class with details about photo moments."""</span>
<span></span><span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;MomentInfo&quot;</span><span class="p">]</span>
<span class="sd">&quot;&quot;&quot;MomentInfo class with details about photo moments.&quot;&quot;&quot;</span>
<div class="viewcode-block" id="MomentInfo"><a class="viewcode-back" href="../../reference.html#osxphotos.MomentInfo">[docs]</a><span class="k">class</span> <span class="nc">MomentInfo</span><span class="p">:</span>
<span class="sd">"""Info about a photo moment"""</span>
<span class="sd">&quot;&quot;&quot;Info about a photo moment&quot;&quot;&quot;</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">db</span><span class="p">,</span> <span class="n">moment_pk</span><span class="p">):</span>
<span class="sd">"""Initialize with a moment PK; returns None if PK not found."""</span>
<span class="sd">&quot;&quot;&quot;Initialize with a moment PK; returns None if PK not found.&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_db</span> <span class="o">=</span> <span class="n">db</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_pk</span> <span class="o">=</span> <span class="n">moment_pk</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_moment</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_moment_pk</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">moment_pk</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"No moment with PK </span><span class="si">{</span><span class="n">moment_pk</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;No moment with PK </span><span class="si">{</span><span class="n">moment_pk</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">pk</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""Primary key of the moment."""</span>
<span class="sd">&quot;&quot;&quot;Primary key of the moment.&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pk</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">location</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""Location of the moment."""</span>
<span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"latitude"</span><span class="p">),</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"longitude"</span><span class="p">))</span>
<span class="sd">&quot;&quot;&quot;Location of the moment.&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;latitude&quot;</span><span class="p">),</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;longitude&quot;</span><span class="p">))</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">title</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""Title of the moment."""</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"title"</span><span class="p">)</span>
<span class="sd">&quot;&quot;&quot;Title of the moment.&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;title&quot;</span><span class="p">)</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">subtitle</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""Subtitle of the moment."""</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"subtitle"</span><span class="p">)</span>
<span class="sd">&quot;&quot;&quot;Subtitle of the moment.&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;subtitle&quot;</span><span class="p">)</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">start_date</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""Start date of the moment."""</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"startDate"</span><span class="p">)</span>
<span class="sd">&quot;&quot;&quot;Start date of the moment.&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;startDate&quot;</span><span class="p">)</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">end_date</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""Stop date of the moment."""</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"endDate"</span><span class="p">)</span>
<span class="sd">&quot;&quot;&quot;Stop date of the moment.&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;endDate&quot;</span><span class="p">)</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">date</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""Date of the moment."""</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"representativeDate"</span><span class="p">)</span>
<span class="sd">&quot;&quot;&quot;Date of the moment.&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;representativeDate&quot;</span><span class="p">)</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">modification_date</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""Modification date of the moment."""</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"modificationDate"</span><span class="p">)</span>
<span class="sd">&quot;&quot;&quot;Modification date of the moment.&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;modificationDate&quot;</span><span class="p">)</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">photos</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""All photos in this moment"""</span>
<span class="sd">&quot;&quot;&quot;All photos in this moment&quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_photos</span>
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
<span class="n">photo_uuids</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">uuid</span>
<span class="k">for</span> <span class="n">uuid</span><span class="p">,</span> <span class="n">photo</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbphotos</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
<span class="k">if</span> <span class="n">photo</span><span class="p">[</span><span class="s2">"momentID"</span><span class="p">]</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pk</span>
<span class="k">if</span> <span class="n">photo</span><span class="p">[</span><span class="s2">&quot;momentID&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pk</span>
<span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_photos</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">photos_by_uuid</span><span class="p">(</span><span class="n">photo_uuids</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_photos</span>
<div class="viewcode-block" id="MomentInfo.asdict"><a class="viewcode-back" href="../../reference.html#osxphotos.MomentInfo.asdict">[docs]</a> <span class="k">def</span> <span class="nf">asdict</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""Returns all moment info as dictionary"""</span>
<span class="sd">&quot;&quot;&quot;Returns all moment info as dictionary&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="p">{</span>
<span class="s2">"pk"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">pk</span><span class="p">,</span>
<span class="s2">"location"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">location</span><span class="p">,</span>
<span class="s2">"title"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">title</span><span class="p">,</span>
<span class="s2">"subtitle"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">subtitle</span><span class="p">,</span>
<span class="s2">"start_date"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">start_date</span><span class="o">.</span><span class="n">isoformat</span><span class="p">()</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">start_date</span> <span class="k">else</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">"end_date"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">end_date</span><span class="o">.</span><span class="n">isoformat</span><span class="p">()</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">end_date</span> <span class="k">else</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">"date"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">date</span><span class="o">.</span><span class="n">isoformat</span><span class="p">()</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">date</span> <span class="k">else</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">"modification_date"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">modification_date</span><span class="o">.</span><span class="n">isoformat</span><span class="p">()</span>
<span class="s2">&quot;pk&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">pk</span><span class="p">,</span>
<span class="s2">&quot;location&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">location</span><span class="p">,</span>
<span class="s2">&quot;title&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">title</span><span class="p">,</span>
<span class="s2">&quot;subtitle&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">subtitle</span><span class="p">,</span>
<span class="s2">&quot;start_date&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">start_date</span><span class="o">.</span><span class="n">isoformat</span><span class="p">()</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">start_date</span> <span class="k">else</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">&quot;end_date&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">end_date</span><span class="o">.</span><span class="n">isoformat</span><span class="p">()</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">end_date</span> <span class="k">else</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">&quot;date&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">date</span><span class="o">.</span><span class="n">isoformat</span><span class="p">()</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">date</span> <span class="k">else</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">&quot;modification_date&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">modification_date</span><span class="o">.</span><span class="n">isoformat</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">modification_date</span>
<span class="k">else</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">"photos"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">photos</span><span class="p">,</span>
<span class="s2">&quot;photos&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">photos</span><span class="p">,</span>
<span class="p">}</span></div></div>
</pre></div>
</article>
@ -317,7 +318,9 @@
</div><script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
<script src="../../_static/jquery.js"></script>
<script src="../../_static/underscore.js"></script>
<script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script>
<script src="../../_static/doctools.js"></script>
<script src="../../_static/sphinx_highlight.js"></script>
<script src="../../_static/scripts/furo.js"></script>
<script src="../../_static/clipboard.min.js"></script>
<script src="../../_static/copybutton.js"></script>

View File

@ -5,7 +5,7 @@
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../genindex.html" /><link rel="search" title="Search" href="../../search.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
<title>osxphotos.personinfo - osxphotos 0.58.1 documentation</title>
<title>osxphotos.personinfo - osxphotos 0.61.0 documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
@ -123,7 +123,7 @@
</label>
</div>
<div class="header-center">
<a href="../../index.html"><div class="brand">osxphotos 0.58.1 documentation</div></a>
<a href="../../index.html"><div class="brand">osxphotos 0.61.0 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -146,7 +146,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../index.html">
<span class="sidebar-brand-text">osxphotos 0.58.1 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.61.0 documentation</span>
</a><form class="sidebar-search-container" method="get" action="../../search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@ -334,7 +334,7 @@
<span class="k">return</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="fm">__eq__</span><span class="p">(</span><span class="n">other</span><span class="p">)</span></div>
<span class="k">class</span> <span class="nc">FaceInfo</span><span class="p">:</span>
<div class="viewcode-block" id="FaceInfo"><a class="viewcode-back" href="../../reference.html#osxphotos.FaceInfo">[docs]</a><span class="k">class</span> <span class="nc">FaceInfo</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;Info about a face in the Photos library&quot;&quot;&quot;</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">db</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">pk</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
@ -472,7 +472,7 @@
<span class="k">return</span> <span class="n">MPRI_Reg_Rect</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">h</span><span class="p">,</span> <span class="n">w</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">face_rect</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<div class="viewcode-block" id="FaceInfo.face_rect"><a class="viewcode-back" href="../../reference.html#osxphotos.FaceInfo.face_rect">[docs]</a> <span class="k">def</span> <span class="nf">face_rect</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Get face rectangle coordinates for current version of the associated image</span>
<span class="sd"> If image has been edited, rectangle applies to edited version, otherwise original version</span>
<span class="sd"> Coordinates in format and reference frame used by PIL</span>
@ -486,16 +486,16 @@
<span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_make_point</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">center_x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">center_y</span><span class="p">))</span>
<span class="n">x0</span><span class="p">,</span> <span class="n">y0</span> <span class="o">=</span> <span class="n">x</span> <span class="o">-</span> <span class="n">radius</span><span class="p">,</span> <span class="n">y</span> <span class="o">-</span> <span class="n">radius</span>
<span class="n">x1</span><span class="p">,</span> <span class="n">y1</span> <span class="o">=</span> <span class="n">x</span> <span class="o">+</span> <span class="n">radius</span><span class="p">,</span> <span class="n">y</span> <span class="o">+</span> <span class="n">radius</span>
<span class="k">return</span> <span class="p">[(</span><span class="n">x0</span><span class="p">,</span> <span class="n">y0</span><span class="p">),</span> <span class="p">(</span><span class="n">x1</span><span class="p">,</span> <span class="n">y1</span><span class="p">)]</span>
<span class="k">return</span> <span class="p">[(</span><span class="n">x0</span><span class="p">,</span> <span class="n">y0</span><span class="p">),</span> <span class="p">(</span><span class="n">x1</span><span class="p">,</span> <span class="n">y1</span><span class="p">)]</span></div>
<span class="k">def</span> <span class="nf">roll_pitch_yaw</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<div class="viewcode-block" id="FaceInfo.roll_pitch_yaw"><a class="viewcode-back" href="../../reference.html#osxphotos.FaceInfo.roll_pitch_yaw">[docs]</a> <span class="k">def</span> <span class="nf">roll_pitch_yaw</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Roll, pitch, yaw of face in radians as tuple&quot;&quot;&quot;</span>
<span class="n">info</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_info</span>
<span class="n">roll</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">if</span> <span class="n">info</span><span class="p">[</span><span class="s2">&quot;roll&quot;</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">info</span><span class="p">[</span><span class="s2">&quot;roll&quot;</span><span class="p">]</span>
<span class="n">pitch</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">if</span> <span class="n">info</span><span class="p">[</span><span class="s2">&quot;pitch&quot;</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">info</span><span class="p">[</span><span class="s2">&quot;pitch&quot;</span><span class="p">]</span>
<span class="n">yaw</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">if</span> <span class="n">info</span><span class="p">[</span><span class="s2">&quot;yaw&quot;</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">info</span><span class="p">[</span><span class="s2">&quot;yaw&quot;</span><span class="p">]</span>
<span class="k">return</span> <span class="p">(</span><span class="n">roll</span><span class="p">,</span> <span class="n">pitch</span><span class="p">,</span> <span class="n">yaw</span><span class="p">)</span>
<span class="k">return</span> <span class="p">(</span><span class="n">roll</span><span class="p">,</span> <span class="n">pitch</span><span class="p">,</span> <span class="n">yaw</span><span class="p">)</span></div>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">roll</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
@ -598,7 +598,7 @@
<span class="k">return</span> <span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">xr</span><span class="p">),</span> <span class="nb">int</span><span class="p">(</span><span class="n">yr</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">asdict</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<div class="viewcode-block" id="FaceInfo.asdict"><a class="viewcode-back" href="../../reference.html#osxphotos.FaceInfo.asdict">[docs]</a> <span class="k">def</span> <span class="nf">asdict</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Returns dict representation of class instance&quot;&quot;&quot;</span>
<span class="n">roll</span><span class="p">,</span> <span class="n">pitch</span><span class="p">,</span> <span class="n">yaw</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">roll_pitch_yaw</span><span class="p">()</span>
<span class="k">return</span> <span class="p">{</span>
@ -633,11 +633,11 @@
<span class="s2">&quot;intrash&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">intrash</span><span class="p">,</span>
<span class="s2">&quot;lip_makeup_type&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">lip_makeup_type</span><span class="p">,</span>
<span class="s2">&quot;smile_type&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">smile_type</span><span class="p">,</span>
<span class="p">}</span>
<span class="p">}</span></div>
<span class="k">def</span> <span class="nf">json</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<div class="viewcode-block" id="FaceInfo.json"><a class="viewcode-back" href="../../reference.html#osxphotos.FaceInfo.json">[docs]</a> <span class="k">def</span> <span class="nf">json</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return JSON representation of FaceInfo instance&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">asdict</span><span class="p">())</span>
<span class="k">return</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">asdict</span><span class="p">())</span></div>
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="sa">f</span><span class="s2">&quot;FaceInfo(uuid=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">uuid</span><span class="si">}</span><span class="s2">, center_x=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">center_x</span><span class="si">}</span><span class="s2">, center_y = </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">center_y</span><span class="si">}</span><span class="s2">, size=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">size</span><span class="si">}</span><span class="s2">, person=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="si">}</span><span class="s2">, asset_uuid=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">asset_uuid</span><span class="si">}</span><span class="s2">)&quot;</span>
@ -654,7 +654,7 @@
<span class="p">)</span>
<span class="k">def</span> <span class="fm">__ne__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">return</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="fm">__eq__</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">return</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="fm">__eq__</span><span class="p">(</span><span class="n">other</span><span class="p">)</span></div>
<span class="k">def</span> <span class="nf">rotate_image_point</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">xmid</span><span class="p">,</span> <span class="n">ymid</span><span class="p">,</span> <span class="n">angle</span><span class="p">):</span>

View File

@ -5,7 +5,7 @@
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../genindex.html" /><link rel="search" title="Search" href="../../search.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
<title>osxphotos.photoexporter - osxphotos 0.60.2 documentation</title>
<title>osxphotos.photoexporter - osxphotos 0.62.1 documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
@ -123,7 +123,7 @@
</label>
</div>
<div class="header-center">
<a href="../../index.html"><div class="brand">osxphotos 0.60.2 documentation</div></a>
<a href="../../index.html"><div class="brand">osxphotos 0.62.1 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -146,7 +146,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../index.html">
<span class="sidebar-brand-text">osxphotos 0.60.2 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.62.1 documentation</span>
</a><form class="sidebar-search-container" method="get" action="../../search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@ -160,6 +160,7 @@
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../template_help.html">OSXPhotos Template System</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../package_overview.html">OSXPhotos Python Package Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../API_README.html">OSXPhotos Python API</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">OSXPhotos Python Reference</a></li>
</ul>
@ -233,17 +234,17 @@
<span class="kn">from</span> <span class="nn">.export_db</span> <span class="kn">import</span> <span class="n">ExportDB</span><span class="p">,</span> <span class="n">ExportDBTemp</span>
<span class="kn">from</span> <span class="nn">.fileutil</span> <span class="kn">import</span> <span class="n">FileUtil</span>
<span class="kn">from</span> <span class="nn">.phototemplate</span> <span class="kn">import</span> <span class="n">RenderOptions</span>
<span class="kn">from</span> <span class="nn">.platform</span> <span class="kn">import</span> <span class="n">is_macos</span>
<span class="kn">from</span> <span class="nn">.rich_utils</span> <span class="kn">import</span> <span class="n">add_rich_markup_tag</span>
<span class="kn">from</span> <span class="nn">.unicode</span> <span class="kn">import</span> <span class="n">normalize_fs_path</span>
<span class="kn">from</span> <span class="nn">.uti</span> <span class="kn">import</span> <span class="n">get_preferred_uti_extension</span>
<span class="kn">from</span> <span class="nn">.utils</span> <span class="kn">import</span> <span class="p">(</span>
<span class="n">hexdigest</span><span class="p">,</span>
<span class="n">increment_filename</span><span class="p">,</span>
<span class="n">increment_filename_with_count</span><span class="p">,</span>
<span class="n">is_macos</span><span class="p">,</span>
<span class="n">lineno</span><span class="p">,</span>
<span class="n">list_directory</span><span class="p">,</span>
<span class="n">lock_filename</span><span class="p">,</span>
<span class="n">normalize_fs_path</span><span class="p">,</span>
<span class="n">unlock_filename</span><span class="p">,</span>
<span class="p">)</span>
@ -332,6 +333,7 @@
<span class="sd"> render_options (RenderOptions): t.Optional osxphotos.phototemplate.RenderOptions instance to specify options for rendering templates</span>
<span class="sd"> replace_keywords (bool): if True, keyword_template replaces any keywords, otherwise it&#39;s additive</span>
<span class="sd"> rich (bool): if True, will use rich markup with verbose output</span>
<span class="sd"> export_aae (bool): if True, also exports adjustments as .AAE file</span>
<span class="sd"> sidecar_drop_ext (bool, default=False): if True, drops the photo&#39;s extension from sidecar filename (e.g. &#39;IMG_1234.json&#39; instead of &#39;IMG_1234.JPG.json&#39;)</span>
<span class="sd"> sidecar: bit field (int): set to one or more of `SIDECAR_XMP`, `SIDECAR_JSON`, `SIDECAR_EXIFTOOL`</span>
<span class="sd"> - SIDECAR_JSON: if set will write a json sidecar with data in format readable by exiftool sidecar filename will be dest/filename.json;</span>
@ -384,6 +386,7 @@
<span class="n">render_options</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">RenderOptions</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">replace_keywords</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">rich</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">export_aae</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">sidecar_drop_ext</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">sidecar</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">strip</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span>
@ -461,7 +464,51 @@
<div class="viewcode-block" id="ExportResults"><a class="viewcode-back" href="../../reference.html#osxphotos.ExportResults">[docs]</a><span class="k">class</span> <span class="nc">ExportResults</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;Results class which holds export results for export&quot;&quot;&quot;</span>
<span class="sd">&quot;&quot;&quot;Results class which holds export results for export</span>
<span class="sd"> </span>
<span class="sd"> Args:</span>
<span class="sd"> converted_to_jpeg: list of files converted to jpeg</span>
<span class="sd"> deleted_directories: list of directories deleted</span>
<span class="sd"> deleted_files: list of files deleted</span>
<span class="sd"> error: list of tuples of (filename, error) for any errors generated during export</span>
<span class="sd"> exif_updated: list of files where exif data was updated with exiftool</span>
<span class="sd"> exiftool_error: list of tuples of (filename, error) for any errors generated by exiftool</span>
<span class="sd"> exiftool_warning: list of tuples of (filename, warning) for any warnings generated by exiftool</span>
<span class="sd"> exported: list of files exported</span>
<span class="sd"> exported_album: list of tuples of (file, album) for any files exported to an album</span>
<span class="sd"> metadata_changed: list of filenames that had metadata changes since last export</span>
<span class="sd"> missing: list of files that were missing</span>
<span class="sd"> missing_album: list of tuples of (file, album) for any files that were missing from an album</span>
<span class="sd"> new: list of files that were new</span>
<span class="sd"> aae_written: list of files where .AAE file was written</span>
<span class="sd"> sidecar_exiftool_skipped: list of files where exiftool sidecar was skipped</span>
<span class="sd"> sidecar_exiftool_written: list of files where exiftool sidecar was written</span>
<span class="sd"> sidecar_json_skipped: list of files where json sidecar was skipped</span>
<span class="sd"> sidecar_json_written: list of files where json sidecar was written</span>
<span class="sd"> sidecar_xmp_skipped: list of files where xmp sidecar was skipped</span>
<span class="sd"> sidecar_xmp_written: list of files where xmp sidecar was written</span>
<span class="sd"> sidecar_user_written: list of files where user sidecar was written</span>
<span class="sd"> sidecar_user_skipped: list of files where user sidecar was skipped</span>
<span class="sd"> sidecar_user_error: list of tuples of (filename, error) for any errors generated by user sidecar</span>
<span class="sd"> skipped: list of files that were skipped</span>
<span class="sd"> skipped_album: list of tuples of (file, album) for any files that were skipped from an album</span>
<span class="sd"> to_touch: list of files that were touched</span>
<span class="sd"> touched: list of files that were touched</span>
<span class="sd"> updated: list of files that were updated</span>
<span class="sd"> xattr_skipped: list of files where xattr was skipped</span>
<span class="sd"> xattr_written: list of files where xattr was written</span>
<span class="sd"> user_written: list of files written by user post_function</span>
<span class="sd"> user_skipped: list of files skipped by user post_function</span>
<span class="sd"> user_error: list of tuples of (filename, error) for any errors generated by user post_function</span>
<span class="sd"> Notes:</span>
<span class="sd"> Each attribute is a list of files or None if no files for that attribute.</span>
<span class="sd"> Error and warning attributes are a list of tuples of (filename, error) where filename is the file that caused the error and error is the error message.</span>
<span class="sd"> Album attributes are a list of tuples of (file, album) where file is the file exported and album is the album it was exported to.</span>
<span class="sd"> ExportResults can be added together with the += operator to combine results as the export progresses.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># Note: __init__ docs above added in the class docstring so they are picked up by sphinx</span>
<span class="vm">__slots__</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">&quot;_datetime&quot;</span><span class="p">,</span>
@ -478,12 +525,16 @@
<span class="s2">&quot;missing&quot;</span><span class="p">,</span>
<span class="s2">&quot;missing_album&quot;</span><span class="p">,</span>
<span class="s2">&quot;new&quot;</span><span class="p">,</span>
<span class="s2">&quot;aae_written&quot;</span><span class="p">,</span>
<span class="s2">&quot;sidecar_exiftool_skipped&quot;</span><span class="p">,</span>
<span class="s2">&quot;sidecar_exiftool_written&quot;</span><span class="p">,</span>
<span class="s2">&quot;sidecar_json_skipped&quot;</span><span class="p">,</span>
<span class="s2">&quot;sidecar_json_written&quot;</span><span class="p">,</span>
<span class="s2">&quot;sidecar_xmp_skipped&quot;</span><span class="p">,</span>
<span class="s2">&quot;sidecar_xmp_written&quot;</span><span class="p">,</span>
<span class="s2">&quot;sidecar_user_written&quot;</span><span class="p">,</span>
<span class="s2">&quot;sidecar_user_skipped&quot;</span><span class="p">,</span>
<span class="s2">&quot;sidecar_user_error&quot;</span><span class="p">,</span>
<span class="s2">&quot;skipped&quot;</span><span class="p">,</span>
<span class="s2">&quot;skipped_album&quot;</span><span class="p">,</span>
<span class="s2">&quot;to_touch&quot;</span><span class="p">,</span>
@ -491,37 +542,51 @@
<span class="s2">&quot;updated&quot;</span><span class="p">,</span>
<span class="s2">&quot;xattr_skipped&quot;</span><span class="p">,</span>
<span class="s2">&quot;xattr_written&quot;</span><span class="p">,</span>
<span class="s2">&quot;user_written&quot;</span><span class="p">,</span>
<span class="s2">&quot;user_skipped&quot;</span><span class="p">,</span>
<span class="s2">&quot;user_error&quot;</span><span class="p">,</span>
<span class="p">]</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">converted_to_jpeg</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">deleted_directories</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">deleted_files</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">error</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">exif_updated</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">exiftool_error</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">exiftool_warning</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">exported</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">exported_album</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">metadata_changed</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">missing</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">missing_album</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">new</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">sidecar_exiftool_skipped</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">sidecar_exiftool_written</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">sidecar_json_skipped</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">sidecar_json_written</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">sidecar_xmp_skipped</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">sidecar_xmp_written</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">skipped</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">skipped_album</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">to_touch</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">touched</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">updated</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">xattr_skipped</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">xattr_written</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">converted_to_jpeg</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">deleted_directories</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">deleted_files</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">error</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">exif_updated</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">exiftool_error</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">tuple</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">exiftool_warning</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">tuple</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">exported</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">exported_album</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">tuple</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">metadata_changed</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">missing</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">missing_album</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">tuple</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">new</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">aae_written</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">sidecar_exiftool_skipped</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">sidecar_exiftool_written</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">sidecar_json_skipped</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">sidecar_json_written</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">sidecar_xmp_skipped</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">sidecar_xmp_written</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">sidecar_user_written</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">sidecar_user_skipped</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">sidecar_user_error</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">tuple</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">skipped</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">skipped_album</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">tuple</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">to_touch</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">touched</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">updated</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">xattr_skipped</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">xattr_written</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">user_written</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">user_skipped</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="n">user_error</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">tuple</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="p">):</span>
<span class="sd">&quot;&quot;&quot;ExportResults data class to hold results of export.</span>
<span class="sd"> See class docstring for details.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">local_vars</span> <span class="o">=</span> <span class="nb">locals</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_datetime</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span><span class="o">.</span><span class="n">isoformat</span><span class="p">()</span>
<span class="k">for</span> <span class="n">attr</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">attributes</span><span class="p">:</span>
@ -547,17 +612,24 @@
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">exif_updated</span>
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">touched</span>
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">converted_to_jpeg</span>
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">aae_written</span>
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">sidecar_json_written</span>
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">sidecar_json_skipped</span>
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">sidecar_exiftool_written</span>
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">sidecar_exiftool_skipped</span>
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">sidecar_xmp_written</span>
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">sidecar_xmp_skipped</span>
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">sidecar_user_written</span>
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">sidecar_user_skipped</span>
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">missing</span>
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">user_written</span>
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">user_skipped</span>
<span class="p">)</span>
<span class="n">files</span> <span class="o">+=</span> <span class="p">[</span><span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">exiftool_warning</span><span class="p">]</span>
<span class="n">files</span> <span class="o">+=</span> <span class="p">[</span><span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">exiftool_error</span><span class="p">]</span>
<span class="n">files</span> <span class="o">+=</span> <span class="p">[</span><span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">error</span><span class="p">]</span>
<span class="n">files</span> <span class="o">+=</span> <span class="p">[</span><span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">sidecar_user_error</span><span class="p">]</span>
<span class="n">files</span> <span class="o">+=</span> <span class="p">[</span><span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">user_error</span><span class="p">]</span>
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">files</span><span class="p">))</span></div>
@ -802,6 +874,8 @@
<span class="sa">f</span><span class="s2">&quot;Skipping missing preview photo for </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_filename</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">photo</span><span class="o">.</span><span class="n">original_filename</span><span class="p">)</span><span class="si">}</span><span class="s2"> (</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_uuid</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">photo</span><span class="o">.</span><span class="n">uuid</span><span class="p">)</span><span class="si">}</span><span class="s2">)&quot;</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">export_aae</span><span class="p">:</span>
<span class="n">all_results</span> <span class="o">+=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_write_aae_file</span><span class="p">(</span><span class="n">dest</span><span class="o">=</span><span class="n">dest</span><span class="p">,</span> <span class="n">options</span><span class="o">=</span><span class="n">options</span><span class="p">)</span>
<span class="n">all_results</span> <span class="o">+=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_write_sidecar_files</span><span class="p">(</span><span class="n">dest</span><span class="o">=</span><span class="n">dest</span><span class="p">,</span> <span class="n">options</span><span class="o">=</span><span class="n">options</span><span class="p">)</span>
<span class="k">return</span> <span class="n">all_results</span></div>
@ -1601,6 +1675,54 @@
<span class="n">exported_paths</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">dest_new</span><span class="p">))</span>
<span class="k">return</span> <span class="n">exported_paths</span>
<span class="k">def</span> <span class="nf">_write_aae_file</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">dest</span><span class="p">:</span> <span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="p">,</span>
<span class="n">options</span><span class="p">:</span> <span class="n">ExportOptions</span><span class="p">,</span>
<span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ExportResults</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;Write AAE file for the photo.&quot;&quot;&quot;</span>
<span class="c1"># AAE files describe adjustments to originals, so they don&#39;t make sense</span>
<span class="c1"># for edited files</span>
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">edited</span><span class="p">:</span>
<span class="k">return</span> <span class="n">ExportResults</span><span class="p">()</span>
<span class="n">verbose</span> <span class="o">=</span> <span class="n">options</span><span class="o">.</span><span class="n">verbose</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">_verbose</span>
<span class="n">aae_src</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">photo</span><span class="o">.</span><span class="n">adjustments_path</span>
<span class="k">if</span> <span class="n">aae_src</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">return</span> <span class="n">ExportResults</span><span class="p">()</span>
<span class="n">aae_dest</span> <span class="o">=</span> <span class="n">dest</span><span class="o">.</span><span class="n">with_suffix</span><span class="p">(</span><span class="s2">&quot;.AAE&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">export_as_hardlink</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">if</span> <span class="n">aae_dest</span><span class="o">.</span><span class="n">exists</span><span class="p">()</span> <span class="ow">and</span> <span class="nb">any</span><span class="p">(</span>
<span class="p">[</span><span class="n">options</span><span class="o">.</span><span class="n">overwrite</span><span class="p">,</span> <span class="n">options</span><span class="o">.</span><span class="n">update</span><span class="p">,</span> <span class="n">options</span><span class="o">.</span><span class="n">force_update</span><span class="p">]</span>
<span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">options</span><span class="o">.</span><span class="n">fileutil</span><span class="o">.</span><span class="n">unlink</span><span class="p">(</span><span class="n">aae_dest</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ExportError</span><span class="p">(</span>
<span class="sa">f</span><span class="s2">&quot;Error removing file </span><span class="si">{</span><span class="n">aae_dest</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2"> ((</span><span class="si">{</span><span class="n">lineno</span><span class="p">(</span><span class="vm">__file__</span><span class="p">)</span><span class="si">}</span><span class="s2">)&quot;</span>
<span class="p">)</span> <span class="kn">from</span> <span class="nn">e</span>
<span class="n">options</span><span class="o">.</span><span class="n">fileutil</span><span class="o">.</span><span class="n">hardlink</span><span class="p">(</span><span class="n">aae_src</span><span class="p">,</span> <span class="n">aae_dest</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ExportError</span><span class="p">(</span>
<span class="sa">f</span><span class="s2">&quot;Error hardlinking </span><span class="si">{</span><span class="n">aae_src</span><span class="si">}</span><span class="s2"> to </span><span class="si">{</span><span class="n">aae_dest</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2"> (</span><span class="si">{</span><span class="n">lineno</span><span class="p">(</span><span class="vm">__file__</span><span class="p">)</span><span class="si">}</span><span class="s2">)&quot;</span>
<span class="p">)</span> <span class="kn">from</span> <span class="nn">e</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">options</span><span class="o">.</span><span class="n">fileutil</span><span class="o">.</span><span class="n">copy</span><span class="p">(</span><span class="n">aae_src</span><span class="p">,</span> <span class="n">aae_dest</span><span class="p">)</span>
<span class="n">verbose</span><span class="p">(</span>
<span class="sa">f</span><span class="s2">&quot;Exported adjustments of </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_filename</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">photo</span><span class="o">.</span><span class="n">original_filename</span><span class="p">)</span><span class="si">}</span><span class="s2"> to </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_filepath</span><span class="p">(</span><span class="n">normalize_fs_path</span><span class="p">(</span><span class="n">aae_dest</span><span class="p">))</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ExportError</span><span class="p">(</span>
<span class="sa">f</span><span class="s2">&quot;Error copying file </span><span class="si">{</span><span class="n">aae_src</span><span class="si">}</span><span class="s2"> to </span><span class="si">{</span><span class="n">aae_dest</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2"> (</span><span class="si">{</span><span class="n">lineno</span><span class="p">(</span><span class="vm">__file__</span><span class="p">)</span><span class="si">}</span><span class="s2">)&quot;</span>
<span class="p">)</span> <span class="kn">from</span> <span class="nn">e</span>
<span class="k">return</span> <span class="n">ExportResults</span><span class="p">(</span><span class="n">aae_written</span><span class="o">=</span><span class="p">[</span><span class="n">aae_dest</span><span class="p">])</span>
<span class="k">def</span> <span class="nf">_write_sidecar_files</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">dest</span><span class="p">:</span> <span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="p">,</span>

View File

@ -5,7 +5,7 @@
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../genindex.html" /><link rel="search" title="Search" href="../../search.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
<title>osxphotos.photoinfo - osxphotos 0.60.3 documentation</title>
<title>osxphotos.photoinfo - osxphotos 0.62.0 documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
@ -123,7 +123,7 @@
</label>
</div>
<div class="header-center">
<a href="../../index.html"><div class="brand">osxphotos 0.60.3 documentation</div></a>
<a href="../../index.html"><div class="brand">osxphotos 0.62.0 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -146,7 +146,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../index.html">
<span class="sidebar-brand-text">osxphotos 0.60.3 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.62.0 documentation</span>
</a><form class="sidebar-search-container" method="get" action="../../search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@ -160,6 +160,7 @@
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../template_help.html">OSXPhotos Template System</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../package_overview.html">OSXPhotos Python Package Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../api_readme.html">OSXPhotos Python API</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">OSXPhotos Python Reference</a></li>
</ul>
@ -258,11 +259,14 @@
<span class="kn">from</span> <span class="nn">.phototables</span> <span class="kn">import</span> <span class="n">PhotoTables</span>
<span class="kn">from</span> <span class="nn">.phototemplate</span> <span class="kn">import</span> <span class="n">PhotoTemplate</span><span class="p">,</span> <span class="n">RenderOptions</span>
<span class="kn">from</span> <span class="nn">.placeinfo</span> <span class="kn">import</span> <span class="n">PlaceInfo4</span><span class="p">,</span> <span class="n">PlaceInfo5</span>
<span class="kn">from</span> <span class="nn">.platform</span> <span class="kn">import</span> <span class="n">assert_macos</span><span class="p">,</span> <span class="n">is_macos</span>
<span class="kn">from</span> <span class="nn">.query_builder</span> <span class="kn">import</span> <span class="n">get_query</span>
<span class="kn">from</span> <span class="nn">.scoreinfo</span> <span class="kn">import</span> <span class="n">ScoreInfo</span>
<span class="kn">from</span> <span class="nn">.searchinfo</span> <span class="kn">import</span> <span class="n">SearchInfo</span>
<span class="kn">from</span> <span class="nn">.shareinfo</span> <span class="kn">import</span> <span class="n">ShareInfo</span><span class="p">,</span> <span class="n">get_moment_share_info</span><span class="p">,</span> <span class="n">get_share_info</span>
<span class="kn">from</span> <span class="nn">.shareparticipant</span> <span class="kn">import</span> <span class="n">ShareParticipant</span><span class="p">,</span> <span class="n">get_share_participants</span>
<span class="kn">from</span> <span class="nn">.uti</span> <span class="kn">import</span> <span class="n">get_preferred_uti_extension</span><span class="p">,</span> <span class="n">get_uti_for_extension</span>
<span class="kn">from</span> <span class="nn">.utils</span> <span class="kn">import</span> <span class="n">_get_resource_loc</span><span class="p">,</span> <span class="n">assert_macos</span><span class="p">,</span> <span class="n">hexdigest</span><span class="p">,</span> <span class="n">is_macos</span><span class="p">,</span> <span class="n">list_directory</span>
<span class="kn">from</span> <span class="nn">.utils</span> <span class="kn">import</span> <span class="n">_get_resource_loc</span><span class="p">,</span> <span class="n">hexdigest</span><span class="p">,</span> <span class="n">list_directory</span>
<span class="k">if</span> <span class="n">is_macos</span><span class="p">:</span>
<span class="kn">from</span> <span class="nn">osxmetadata</span> <span class="kn">import</span> <span class="n">OSXMetaData</span>
@ -369,6 +373,16 @@
<span class="sd">&quot;&quot;&quot;Returns candidate path for original photo on Photos &gt;= version 5&quot;&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_info</span><span class="p">[</span><span class="s2">&quot;shared&quot;</span><span class="p">]:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_path_5_shared</span><span class="p">()</span>
<span class="k">if</span> <span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">shared_moment</span>
<span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">photos_version</span> <span class="o">&gt;=</span> <span class="mi">7</span>
<span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_path_shared_moment</span><span class="p">()</span>
<span class="p">):</span>
<span class="c1"># path for photos in shared moments if it&#39;s in the shared moment folder</span>
<span class="c1"># the file may also be in the originals folder which the next check will catch</span>
<span class="c1"># check shared_moment first as a photo can be both a shared moment and syndicated</span>
<span class="c1"># and if so, will be in the shared moment folder</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_path_shared_moment</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">syndicated</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">saved_to_library</span><span class="p">:</span>
<span class="c1"># path for &quot;shared with you&quot; syndicated photos that have not yet been saved to the library</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_path_syndication</span><span class="p">()</span>
@ -412,8 +426,8 @@
<span class="p">)</span>
<span class="k">def</span> <span class="nf">_path_syndication</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return path for syndicated photo on Photos &gt;= version 8&quot;&quot;&quot;</span>
<span class="c1"># Photos 8+ stores syndicated photos in a separate directory</span>
<span class="sd">&quot;&quot;&quot;Return path for syndicated photo on Photos &gt;= version 7&quot;&quot;&quot;</span>
<span class="c1"># Photos 7+ stores syndicated photos in a separate directory</span>
<span class="c1"># in ~/Photos Library.photoslibrary/scopes/syndication/originals/X/UUID.ext</span>
<span class="c1"># where X is first digit of UUID</span>
<span class="n">syndication_path</span> <span class="o">=</span> <span class="s2">&quot;scopes/syndication/originals&quot;</span>
@ -426,6 +440,21 @@
<span class="p">)</span>
<span class="k">return</span> <span class="n">path</span> <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isfile</span><span class="p">(</span><span class="n">path</span><span class="p">)</span> <span class="k">else</span> <span class="kc">None</span>
<span class="k">def</span> <span class="nf">_path_shared_moment</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return path for shared moment photo on Photos &gt;= version 7&quot;&quot;&quot;</span>
<span class="c1"># Photos 7+ stores shared moment photos in a separate directory</span>
<span class="c1"># in ~/Photos Library.photoslibrary/scopes/momentshared/originals/X/UUID.ext</span>
<span class="c1"># where X is first digit of UUID</span>
<span class="n">momentshared_path</span> <span class="o">=</span> <span class="s2">&quot;scopes/momentshared/originals&quot;</span>
<span class="n">uuid_dir</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">uuid</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_library_path</span><span class="p">,</span>
<span class="n">momentshared_path</span><span class="p">,</span>
<span class="n">uuid_dir</span><span class="p">,</span>
<span class="bp">self</span><span class="o">.</span><span class="n">filename</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">path</span> <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isfile</span><span class="p">(</span><span class="n">path</span><span class="p">)</span> <span class="k">else</span> <span class="kc">None</span>
<span class="k">def</span> <span class="nf">_path_4</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Returns candidate path for original photo on Photos &lt;= version 4&quot;&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_info</span><span class="p">[</span><span class="s2">&quot;has_raw&quot;</span><span class="p">]:</span>
@ -546,7 +575,7 @@
<span class="p">)</span>
<span class="k">def</span> <span class="nf">_path_edited_4</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;return path_edited for Photos &lt;= 4; modified version of code in PhotoInfo to debug #859&quot;&quot;&quot;</span>
<span class="sd">&quot;&quot;&quot;return path_edited for Photos &lt;= 4; #859&quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_info</span><span class="p">[</span><span class="s2">&quot;hasAdjustments&quot;</span><span class="p">]:</span>
<span class="k">return</span> <span class="kc">None</span>
@ -651,7 +680,7 @@
<span class="c1"># In Photos 5, raw is in same folder as original but with _4.ext</span>
<span class="c1"># Unless &quot;Copy Items to the Photos Library&quot; is not checked</span>
<span class="c1"># then RAW image is not renamed but has same name is jpeg buth with raw extension</span>
<span class="c1"># then RAW image is not renamed but has same name is jpeg but with raw extension</span>
<span class="c1"># Current implementation finds images with the correct raw UTI extension</span>
<span class="c1"># in same folder as the original and with same stem as original in form: original_stem*.raw_ext</span>
<span class="c1"># TODO: I don&#39;t like this -- would prefer a more deterministic approach but until I have more</span>
@ -721,6 +750,7 @@
<span class="sa">f</span><span class="s2">&quot;MISSING PATH: RAW photo for UUID </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_uuid</span><span class="si">}</span><span class="s2"> should be at </span><span class="si">{</span><span class="n">photopath</span><span class="si">}</span><span class="s2"> but does not appear to exist&quot;</span>
<span class="p">)</span>
<span class="n">photopath</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">return</span> <span class="n">photopath</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">description</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
@ -846,28 +876,38 @@
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_info</span><span class="p">[</span><span class="s2">&quot;hasAdjustments&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="mi">1</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">adjustments</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Returns AdjustmentsInfo class for adjustment data or None if no adjustments; Photos 5+ only&quot;&quot;&quot;</span>
<span class="k">def</span> <span class="nf">adjustments_path</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Returns path to adjustments file or none if file doesn&#39;t exist&quot;&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_version</span> <span class="o">&lt;=</span> <span class="n">_PHOTOS_4_VERSION</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">hasadjustments</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_adjustmentinfo</span>
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
<span class="n">library</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_library_path</span>
<span class="n">directory</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_uuid</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># first char of uuid</span>
<span class="n">plist_file</span> <span class="o">=</span> <span class="p">(</span>
<span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="p">(</span><span class="n">library</span><span class="p">)</span>
<span class="o">/</span> <span class="s2">&quot;resources&quot;</span>
<span class="o">/</span> <span class="s2">&quot;renders&quot;</span>
<span class="o">/</span> <span class="n">directory</span>
<span class="o">/</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_uuid</span><span class="si">}</span><span class="s2">.plist&quot;</span>
<span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">plist_file</span><span class="o">.</span><span class="n">is_file</span><span class="p">():</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_adjustmentinfo</span> <span class="o">=</span> <span class="n">AdjustmentsInfo</span><span class="p">(</span><span class="n">plist_file</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_adjustmentinfo</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">hasadjustments</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="n">library</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_library_path</span>
<span class="n">directory</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_uuid</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># first char of uuid</span>
<span class="n">plist_file</span> <span class="o">=</span> <span class="p">(</span>
<span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="p">(</span><span class="n">library</span><span class="p">)</span>
<span class="o">/</span> <span class="s2">&quot;resources&quot;</span>
<span class="o">/</span> <span class="s2">&quot;renders&quot;</span>
<span class="o">/</span> <span class="n">directory</span>
<span class="o">/</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_uuid</span><span class="si">}</span><span class="s2">.plist&quot;</span>
<span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">plist_file</span><span class="o">.</span><span class="n">is_file</span><span class="p">():</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="k">return</span> <span class="n">plist_file</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">adjustments</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Returns AdjustmentsInfo class for adjustment data or None if no adjustments; Photos 5+ only&quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_adjustmentinfo</span>
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
<span class="n">plist_file</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">adjustments_path</span>
<span class="k">if</span> <span class="n">plist_file</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_adjustmentinfo</span> <span class="o">=</span> <span class="n">AdjustmentsInfo</span><span class="p">(</span><span class="n">plist_file</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_adjustmentinfo</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">external_edit</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
@ -1096,6 +1136,8 @@
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">live_photo</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">path</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">ismissing</span><span class="p">:</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">shared</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_path_live_photo_shared_5</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">shared_moment</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">photos_version</span> <span class="o">&gt;=</span> <span class="mi">7</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_path_live_shared_moment</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">syndicated</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">saved_to_library</span><span class="p">:</span>
<span class="c1"># syndicated (&quot;Shared with you&quot;) photos not yet saved to library</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_path_live_syndicated</span><span class="p">()</span>
@ -1158,8 +1200,8 @@
<span class="k">return</span> <span class="n">photopath</span>
<span class="k">def</span> <span class="nf">_path_live_syndicated</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return path for live syndicated photo on Photos &gt;= version 8&quot;&quot;&quot;</span>
<span class="c1"># Photos 8+ stores live syndicated photos in a separate directory</span>
<span class="sd">&quot;&quot;&quot;Return path for live syndicated photo on Photos &gt;= version 7&quot;&quot;&quot;</span>
<span class="c1"># Photos 7+ stores live syndicated photos in a separate directory</span>
<span class="c1"># in ~/Photos Library.photoslibrary/scopes/syndication/originals/X/UUID_3.mov</span>
<span class="c1"># where X is first digit of UUID</span>
<span class="n">syndication_path</span> <span class="o">=</span> <span class="s2">&quot;scopes/syndication/originals&quot;</span>
@ -1173,6 +1215,22 @@
<span class="p">)</span>
<span class="k">return</span> <span class="n">live_photo</span> <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isfile</span><span class="p">(</span><span class="n">live_photo</span><span class="p">)</span> <span class="k">else</span> <span class="kc">None</span>
<span class="k">def</span> <span class="nf">_path_live_shared_moment</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return path for live shared moment photo on Photos &gt;= version 7&quot;&quot;&quot;</span>
<span class="c1"># Photos 7+ stores live shared moment photos in a separate directory</span>
<span class="c1"># in ~/Photos Library.photoslibrary/scopes/momentshared/originals/X/UUID_3.mov</span>
<span class="c1"># where X is first digit of UUID</span>
<span class="n">shared_moment_path</span> <span class="o">=</span> <span class="s2">&quot;scopes/momentshared/originals&quot;</span>
<span class="n">uuid_dir</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">uuid</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">filename</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">filename</span><span class="p">)</span><span class="o">.</span><span class="n">stem</span><span class="si">}</span><span class="s2">_3.mov&quot;</span>
<span class="n">live_photo</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_library_path</span><span class="p">,</span>
<span class="n">shared_moment_path</span><span class="p">,</span>
<span class="n">uuid_dir</span><span class="p">,</span>
<span class="n">filename</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">live_photo</span> <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isfile</span><span class="p">(</span><span class="n">live_photo</span><span class="p">)</span> <span class="k">else</span> <span class="kc">None</span>
<span class="nd">@cached_property</span>
<span class="k">def</span> <span class="nf">path_derivatives</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]:</span>
<span class="sd">&quot;&quot;&quot;Return any derivative (preview) images associated with the photo as a list of paths, sorted by file size (largest first)&quot;&quot;&quot;</span>
@ -1183,19 +1241,29 @@
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_path_derivatives_5_shared</span><span class="p">()</span>
<span class="n">directory</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_uuid</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># first char of uuid</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">syndicated</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">saved_to_library</span><span class="p">:</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">shared_moment</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">photos_version</span> <span class="o">&gt;=</span> <span class="mi">7</span><span class="p">:</span>
<span class="c1"># shared moments</span>
<span class="n">derivative_path</span> <span class="o">=</span> <span class="s2">&quot;scopes/momentshared/resources/derivatives&quot;</span>
<span class="n">thumb_path</span> <span class="o">=</span> <span class="p">(</span>
<span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">derivative_path</span><span class="si">}</span><span class="s2">/masters/</span><span class="si">{</span><span class="n">directory</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">uuid</span><span class="si">}</span><span class="s2">_4_5005_c.jpeg&quot;</span>
<span class="p">)</span>
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">syndicated</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">saved_to_library</span><span class="p">:</span>
<span class="c1"># syndicated (&quot;Shared with you&quot;) photos not yet saved to library</span>
<span class="n">derivative_path</span> <span class="o">=</span> <span class="s2">&quot;scopes/syndication/resources/derivatives&quot;</span>
<span class="n">thumb_path</span> <span class="o">=</span> <span class="p">(</span>
<span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">derivative_path</span><span class="si">}</span><span class="s2">/masters/</span><span class="si">{</span><span class="n">directory</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">uuid</span><span class="si">}</span><span class="s2">_4_5005_c.jpeg&quot;</span>
<span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">derivative_path</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;resources/derivatives/</span><span class="si">{</span><span class="n">directory</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="n">derivative_path</span> <span class="o">=</span> <span class="s2">&quot;resources/derivatives&quot;</span>
<span class="n">thumb_path</span> <span class="o">=</span> <span class="p">(</span>
<span class="sa">f</span><span class="s2">&quot;resources/derivatives/masters/</span><span class="si">{</span><span class="n">directory</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">uuid</span><span class="si">}</span><span class="s2">_4_5005_c.jpeg&quot;</span>
<span class="p">)</span>
<span class="n">derivative_path</span> <span class="o">=</span> <span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_library_path</span><span class="p">)</span><span class="o">.</span><span class="n">joinpath</span><span class="p">(</span><span class="n">derivative_path</span><span class="p">)</span>
<span class="n">derivative_path</span> <span class="o">=</span> <span class="p">(</span>
<span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_library_path</span><span class="p">)</span>
<span class="o">.</span><span class="n">joinpath</span><span class="p">(</span><span class="n">derivative_path</span><span class="p">)</span>
<span class="o">.</span><span class="n">joinpath</span><span class="p">(</span><span class="n">directory</span><span class="p">)</span>
<span class="p">)</span>
<span class="n">thumb_path</span> <span class="o">=</span> <span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_library_path</span><span class="p">)</span><span class="o">.</span><span class="n">joinpath</span><span class="p">(</span><span class="n">thumb_path</span><span class="p">)</span>
<span class="c1"># find all files that start with uuid in derivative path</span>
@ -1535,9 +1603,9 @@
<span class="k">def</span> <span class="nf">syndicated</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span> <span class="o">|</span> <span class="kc">None</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;Return true if photo was shared via syndication (e.g. via Messages, etc.);</span>
<span class="sd"> these are photos that appear in &quot;Shared with you&quot; album.</span>
<span class="sd"> Photos 8+ only; returns None if not Photos 8+.</span>
<span class="sd"> Photos 7+ only; returns None if not Photos 7+.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">photos_version</span> <span class="o">&lt;</span> <span class="mi">8</span><span class="p">:</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">photos_version</span> <span class="o">&lt;</span> <span class="mi">7</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="k">try</span><span class="p">:</span>
@ -1552,10 +1620,10 @@
<span class="k">def</span> <span class="nf">saved_to_library</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span> <span class="o">|</span> <span class="kc">None</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;Return True if syndicated photo has been saved to library;</span>
<span class="sd"> returns False if photo is not syndicated or has not been saved to the library.</span>
<span class="sd"> Returns None if not Photos 8+.</span>
<span class="sd"> Syndicated photos are photos that appear in &quot;Shared with you&quot; album; Photos 8+ only.</span>
<span class="sd"> Returns None if not Photos 7+.</span>
<span class="sd"> Syndicated photos are photos that appear in &quot;Shared with you&quot; album; Photos 7+ only.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">photos_version</span> <span class="o">&lt;</span> <span class="mi">8</span><span class="p">:</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">photos_version</span> <span class="o">&lt;</span> <span class="mi">7</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="k">try</span><span class="p">:</span>
@ -1563,6 +1631,46 @@
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="nd">@cached_property</span>
<span class="k">def</span> <span class="nf">shared_moment</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;Returns True if photo is part of a shared moment otherwise False (Photos 7+ only)&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_info</span><span class="p">[</span><span class="s2">&quot;moment_share&quot;</span><span class="p">])</span>
<span class="nd">@cached_property</span>
<span class="k">def</span> <span class="nf">shared_moment_info</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ShareInfo</span> <span class="o">|</span> <span class="kc">None</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;Returns ShareInfo object with information about the shared moment the photo is part of (Photos 7+ only)&quot;&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">photos_version</span> <span class="o">&lt;</span> <span class="mi">7</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">return</span> <span class="n">get_moment_share_info</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">uuid</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="nd">@cached_property</span>
<span class="k">def</span> <span class="nf">share_info</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ShareInfo</span> <span class="o">|</span> <span class="kc">None</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;Returns ShareInfo object with information about the shared photo in a shared iCloud library (Photos 8+ only) (currently experimental)&quot;&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">photos_version</span> <span class="o">&lt;</span> <span class="mi">8</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">return</span> <span class="n">get_share_info</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">uuid</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="nd">@cached_property</span>
<span class="k">def</span> <span class="nf">shared_library</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;Returns True if photo is in a shared iCloud library otherwise False (Photos 8+ only)&quot;&quot;&quot;</span>
<span class="c1"># TODO: this is just a guess right now as I don&#39;t currently use shared libraries</span>
<span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_info</span><span class="p">[</span><span class="s2">&quot;active_library_participation_state&quot;</span><span class="p">])</span>
<span class="nd">@cached_property</span>
<span class="k">def</span> <span class="nf">share_participants</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">ShareParticipant</span><span class="p">]:</span>
<span class="sd">&quot;&quot;&quot;Returns list of ShareParticpant objects with information on who the photo is shared with (Photos 8+ only)&quot;&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">photos_version</span> <span class="o">&lt;</span> <span class="mi">8</span><span class="p">:</span>
<span class="k">return</span> <span class="p">[]</span>
<span class="k">return</span> <span class="n">get_share_participants</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">uuid</span><span class="p">)</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">labels</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;returns list of labels applied to photo by Photos image categorization</span>
@ -2065,6 +2173,10 @@
<span class="n">place</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">place</span><span class="o">.</span><span class="n">asdict</span><span class="p">()</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">place</span> <span class="k">else</span> <span class="p">{}</span>
<span class="n">score</span> <span class="o">=</span> <span class="n">dataclasses</span><span class="o">.</span><span class="n">asdict</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">score</span><span class="p">)</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">score</span> <span class="k">else</span> <span class="p">{}</span>
<span class="c1"># do not add any new properties to data_dict as this is used by export to determine</span>
<span class="c1"># if a photo needs to be re-exported and adding new properties may cause all photos</span>
<span class="c1"># to be re-exported</span>
<span class="c1"># see below `if not shallow:`</span>
<span class="n">dict_data</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;albums&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">albums</span><span class="p">,</span>
<span class="s2">&quot;burst&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">burst</span><span class="p">,</span>
@ -2139,6 +2251,7 @@
<span class="p">}</span>
<span class="c1"># non-shallow keys</span>
<span class="c1"># add any new properties here</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">shallow</span><span class="p">:</span>
<span class="n">dict_data</span><span class="p">[</span><span class="s2">&quot;album_info&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">album</span><span class="o">.</span><span class="n">asdict</span><span class="p">()</span> <span class="k">for</span> <span class="n">album</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">album_info</span><span class="p">]</span>
<span class="n">dict_data</span><span class="p">[</span><span class="s2">&quot;path_derivatives&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">path_derivatives</span>
@ -2166,6 +2279,10 @@
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">search_info_normalized</span>
<span class="k">else</span> <span class="p">{}</span>
<span class="p">)</span>
<span class="n">dict_data</span><span class="p">[</span><span class="s2">&quot;syndicated&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">syndicated</span>
<span class="n">dict_data</span><span class="p">[</span><span class="s2">&quot;saved_to_library&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">saved_to_library</span>
<span class="n">dict_data</span><span class="p">[</span><span class="s2">&quot;shared_moment&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">shared_moment</span>
<span class="n">dict_data</span><span class="p">[</span><span class="s2">&quot;shared_library&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">shared_library</span>
<span class="k">return</span> <span class="n">dict_data</span></div>

View File

@ -5,7 +5,7 @@
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../genindex.html" /><link rel="search" title="Search" href="../../search.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
<title>osxphotos.photosalbum - osxphotos 0.60.3 documentation</title>
<title>osxphotos.photosalbum - osxphotos 0.61.0 documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
@ -123,7 +123,7 @@
</label>
</div>
<div class="header-center">
<a href="../../index.html"><div class="brand">osxphotos 0.60.3 documentation</div></a>
<a href="../../index.html"><div class="brand">osxphotos 0.61.0 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -146,7 +146,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../index.html">
<span class="sidebar-brand-text">osxphotos 0.60.3 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.61.0 documentation</span>
</a><form class="sidebar-search-container" method="get" action="../../search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@ -197,12 +197,16 @@
<h1>Source code for osxphotos.photosalbum</h1><div class="highlight"><pre>
<span></span><span class="sd">&quot;&quot;&quot; PhotosAlbum class to create an album in default Photos library and add photos to it &quot;&quot;&quot;</span>
<span class="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">annotations</span>
<span class="kn">import</span> <span class="nn">unicodedata</span>
<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">List</span><span class="p">,</span> <span class="n">Optional</span>
<span class="kn">from</span> <span class="nn">more_itertools</span> <span class="kn">import</span> <span class="n">chunked</span>
<span class="kn">from</span> <span class="nn">.photoinfo</span> <span class="kn">import</span> <span class="n">PhotoInfo</span>
<span class="kn">from</span> <span class="nn">.utils</span> <span class="kn">import</span> <span class="n">assert_macos</span><span class="p">,</span> <span class="n">noop</span><span class="p">,</span> <span class="n">pluralize</span>
<span class="kn">from</span> <span class="nn">.platform</span> <span class="kn">import</span> <span class="n">assert_macos</span>
<span class="kn">from</span> <span class="nn">.utils</span> <span class="kn">import</span> <span class="n">noop</span><span class="p">,</span> <span class="n">pluralize</span>
<span class="n">assert_macos</span><span class="p">()</span>
@ -212,19 +216,36 @@
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;PhotosAlbum&quot;</span><span class="p">,</span> <span class="s2">&quot;PhotosAlbumPhotoScript&quot;</span><span class="p">]</span>
<span class="k">def</span> <span class="nf">get_unicode_variants</span><span class="p">(</span><span class="n">s</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]:</span>
<span class="sd">&quot;&quot;&quot;Get all unicode variants of string&quot;&quot;&quot;</span>
<span class="n">variants</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">form</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">&quot;NFC&quot;</span><span class="p">,</span> <span class="s2">&quot;NFD&quot;</span><span class="p">,</span> <span class="s2">&quot;NFKC&quot;</span><span class="p">,</span> <span class="s2">&quot;NFKD&quot;</span><span class="p">]:</span>
<span class="n">normalized</span> <span class="o">=</span> <span class="n">unicodedata</span><span class="o">.</span><span class="n">normalize</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
<span class="n">variants</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">normalized</span><span class="p">)</span>
<span class="k">return</span> <span class="n">variants</span>
<span class="k">def</span> <span class="nf">folder_by_path</span><span class="p">(</span><span class="n">folders</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="nb">str</span><span class="p">],</span> <span class="n">verbose</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">callable</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Folder</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;Get (and create if necessary) a Photos Folder by path (passed as list of folder names)&quot;&quot;&quot;</span>
<span class="n">library</span> <span class="o">=</span> <span class="n">PhotosLibrary</span><span class="p">()</span>
<span class="n">verbose</span> <span class="o">=</span> <span class="n">verbose</span> <span class="ow">or</span> <span class="n">noop</span>
<span class="n">top_folder_name</span> <span class="o">=</span> <span class="n">folders</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">top_folder</span> <span class="o">=</span> <span class="n">library</span><span class="o">.</span><span class="n">folder</span><span class="p">(</span><span class="n">top_folder_name</span><span class="p">,</span> <span class="n">top_level</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">top_folder</span><span class="p">:</span>
<span class="k">for</span> <span class="n">folder_variant</span> <span class="ow">in</span> <span class="n">get_unicode_variants</span><span class="p">(</span><span class="n">top_folder_name</span><span class="p">):</span>
<span class="n">top_folder</span> <span class="o">=</span> <span class="n">library</span><span class="o">.</span><span class="n">folder</span><span class="p">(</span><span class="n">folder_variant</span><span class="p">,</span> <span class="n">top_level</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="k">if</span> <span class="n">top_folder</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">break</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">verbose</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Creating folder &#39;</span><span class="si">{</span><span class="n">top_folder_name</span><span class="si">}</span><span class="s2">&#39;&quot;</span><span class="p">)</span>
<span class="n">top_folder</span> <span class="o">=</span> <span class="n">library</span><span class="o">.</span><span class="n">create_folder</span><span class="p">(</span><span class="n">top_folder_name</span><span class="p">)</span>
<span class="n">current_folder</span> <span class="o">=</span> <span class="n">top_folder</span>
<span class="k">for</span> <span class="n">folder_name</span> <span class="ow">in</span> <span class="n">folders</span><span class="p">:</span>
<span class="n">folder</span> <span class="o">=</span> <span class="n">current_folder</span><span class="o">.</span><span class="n">folder</span><span class="p">(</span><span class="n">folder_name</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">folder</span><span class="p">:</span>
<span class="k">for</span> <span class="n">folder_variant</span> <span class="ow">in</span> <span class="n">get_unicode_variants</span><span class="p">(</span><span class="n">folder_name</span><span class="p">):</span>
<span class="n">folder</span> <span class="o">=</span> <span class="n">current_folder</span><span class="o">.</span><span class="n">folder</span><span class="p">(</span><span class="n">folder_variant</span><span class="p">)</span>
<span class="k">if</span> <span class="n">folder</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">break</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">verbose</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Creating folder &#39;</span><span class="si">{</span><span class="n">folder_name</span><span class="si">}</span><span class="s2">&#39;&quot;</span><span class="p">)</span>
<span class="n">folder</span> <span class="o">=</span> <span class="n">current_folder</span><span class="o">.</span><span class="n">create_folder</span><span class="p">(</span><span class="n">folder_name</span><span class="p">)</span>
<span class="n">current_folder</span> <span class="o">=</span> <span class="n">folder</span>
@ -241,15 +262,24 @@
<span class="c1"># have folders</span>
<span class="n">album_name</span> <span class="o">=</span> <span class="n">folders_album</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="n">folder</span> <span class="o">=</span> <span class="n">folder_by_path</span><span class="p">(</span><span class="n">folders_album</span><span class="p">,</span> <span class="n">verbose</span><span class="p">)</span>
<span class="n">album</span> <span class="o">=</span> <span class="n">folder</span><span class="o">.</span><span class="n">album</span><span class="p">(</span><span class="n">album_name</span><span class="p">)</span>
<span class="k">if</span> <span class="n">album</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">for</span> <span class="n">album_variant</span> <span class="ow">in</span> <span class="n">get_unicode_variants</span><span class="p">(</span><span class="n">album_name</span><span class="p">):</span>
<span class="c1"># Get album if it exists</span>
<span class="c1"># need to check every unicode variant to avoid creating duplicate albums with same visual representation (#1085)</span>
<span class="n">album</span> <span class="o">=</span> <span class="n">folder</span><span class="o">.</span><span class="n">album</span><span class="p">(</span><span class="n">album_variant</span><span class="p">)</span>
<span class="k">if</span> <span class="n">album</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">break</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">verbose</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Creating album &#39;</span><span class="si">{</span><span class="n">album_name</span><span class="si">}</span><span class="s2">&#39;&quot;</span><span class="p">)</span>
<span class="n">album</span> <span class="o">=</span> <span class="n">folder</span><span class="o">.</span><span class="n">create_album</span><span class="p">(</span><span class="n">album_name</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># only have album name</span>
<span class="n">album_name</span> <span class="o">=</span> <span class="n">folders_album</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">album</span> <span class="o">=</span> <span class="n">library</span><span class="o">.</span><span class="n">album</span><span class="p">(</span><span class="n">album_name</span><span class="p">,</span> <span class="n">top_level</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="k">if</span> <span class="n">album</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">for</span> <span class="n">album_variant</span> <span class="ow">in</span> <span class="n">get_unicode_variants</span><span class="p">(</span><span class="n">album_name</span><span class="p">):</span>
<span class="n">album</span> <span class="o">=</span> <span class="n">library</span><span class="o">.</span><span class="n">album</span><span class="p">(</span><span class="n">album_variant</span><span class="p">,</span> <span class="n">top_level</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="k">if</span> <span class="n">album</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">break</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># album doesn&#39;t exist, create it</span>
<span class="n">verbose</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Creating album &#39;</span><span class="si">{</span><span class="n">album_name</span><span class="si">}</span><span class="s2">&#39;&quot;</span><span class="p">)</span>
<span class="n">album</span> <span class="o">=</span> <span class="n">library</span><span class="o">.</span><span class="n">create_album</span><span class="p">(</span><span class="n">album_name</span><span class="p">)</span>
@ -298,13 +328,10 @@
<span class="k">try</span><span class="p">:</span>
<span class="n">photos</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">photoscript</span><span class="o">.</span><span class="n">Photo</span><span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">uuid</span><span class="p">))</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Error creating Photo object for photo </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_format_uuid</span><span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">uuid</span><span class="p">)</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">verbose</span><span class="p">(</span>
<span class="sa">f</span><span class="s2">&quot;Error creating Photo object for photo </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_format_uuid</span><span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">uuid</span><span class="p">)</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;photos: </span><span class="si">{</span><span class="n">photos</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">photolist</span> <span class="ow">in</span> <span class="n">chunked</span><span class="p">(</span><span class="n">photos</span><span class="p">,</span> <span class="mi">10</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;photolist: </span><span class="si">{</span><span class="n">photolist</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">album</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">photolist</span><span class="p">)</span>
<span class="n">photo_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">photo_list</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">verbose</span><span class="p">(</span>

View File

@ -5,7 +5,7 @@
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../../genindex.html" /><link rel="search" title="Search" href="../../../search.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
<title>osxphotos.photosdb._photosdb_process_comments - osxphotos 0.60.2 documentation</title>
<title>osxphotos.photosdb._photosdb_process_comments - osxphotos 0.61.0 documentation</title>
<link rel="stylesheet" type="text/css" href="../../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../../_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="../../../_static/copybutton.css" />
@ -123,7 +123,7 @@
</label>
</div>
<div class="header-center">
<a href="../../../index.html"><div class="brand">osxphotos 0.60.2 documentation</div></a>
<a href="../../../index.html"><div class="brand">osxphotos 0.61.0 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -146,7 +146,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../../index.html">
<span class="sidebar-brand-text">osxphotos 0.60.2 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.61.0 documentation</span>
</a><form class="sidebar-search-container" method="get" action="../../../search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@ -203,8 +203,8 @@
<span class="kn">from</span> <span class="nn">dataclasses</span> <span class="kn">import</span> <span class="n">dataclass</span>
<span class="kn">from</span> <span class="nn">.._constants</span> <span class="kn">import</span> <span class="n">_DB_TABLE_NAMES</span><span class="p">,</span> <span class="n">_PHOTOS_4_VERSION</span><span class="p">,</span> <span class="n">TIME_DELTA</span>
<span class="kn">from</span> <span class="nn">..utils</span> <span class="kn">import</span> <span class="n">normalize_unicode</span>
<span class="kn">from</span> <span class="nn">..sqlite_utils</span> <span class="kn">import</span> <span class="n">sqlite_open_ro</span>
<span class="kn">from</span> <span class="nn">..unicode</span> <span class="kn">import</span> <span class="n">normalize_unicode</span>
<span class="k">def</span> <span class="nf">_process_comments</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>

View File

@ -5,7 +5,7 @@
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../../genindex.html" /><link rel="search" title="Search" href="../../../search.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
<title>osxphotos.photosdb.photosdb - osxphotos 0.60.3 documentation</title>
<title>osxphotos.photosdb.photosdb - osxphotos 0.62.0 documentation</title>
<link rel="stylesheet" type="text/css" href="../../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../../_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="../../../_static/copybutton.css" />
@ -123,7 +123,7 @@
</label>
</div>
<div class="header-center">
<a href="../../../index.html"><div class="brand">osxphotos 0.60.3 documentation</div></a>
<a href="../../../index.html"><div class="brand">osxphotos 0.62.0 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -146,7 +146,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../../index.html">
<span class="sidebar-brand-text">osxphotos 0.60.3 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.62.0 documentation</span>
</a><form class="sidebar-search-container" method="get" action="../../../search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@ -160,6 +160,7 @@
<li class="toctree-l1"><a class="reference internal" href="../../../cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../template_help.html">OSXPhotos Template System</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../package_overview.html">OSXPhotos Python Package Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../api_readme.html">OSXPhotos Python API</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../reference.html">OSXPhotos Python Reference</a></li>
</ul>
@ -253,18 +254,17 @@
<span class="kn">from</span> <span class="nn">..personinfo</span> <span class="kn">import</span> <span class="n">PersonInfo</span>
<span class="kn">from</span> <span class="nn">..photoinfo</span> <span class="kn">import</span> <span class="n">PhotoInfo</span>
<span class="kn">from</span> <span class="nn">..phototemplate</span> <span class="kn">import</span> <span class="n">RenderOptions</span>
<span class="kn">from</span> <span class="nn">..platform</span> <span class="kn">import</span> <span class="n">get_macos_version</span><span class="p">,</span> <span class="n">is_macos</span>
<span class="kn">from</span> <span class="nn">..queryoptions</span> <span class="kn">import</span> <span class="n">QueryOptions</span>
<span class="kn">from</span> <span class="nn">..rich_utils</span> <span class="kn">import</span> <span class="n">add_rich_markup_tag</span>
<span class="kn">from</span> <span class="nn">..sqlite_utils</span> <span class="kn">import</span> <span class="n">sqlite_db_is_locked</span><span class="p">,</span> <span class="n">sqlite_open_ro</span>
<span class="kn">from</span> <span class="nn">..utils</span> <span class="kn">import</span> <span class="p">(</span>
<span class="n">_check_file_exists</span><span class="p">,</span>
<span class="n">is_macos</span><span class="p">,</span>
<span class="n">get_macos_version</span><span class="p">,</span>
<span class="n">get_last_library_path</span><span class="p">,</span>
<span class="n">noop</span><span class="p">,</span>
<span class="n">normalize_unicode</span><span class="p">,</span>
<span class="kn">from</span> <span class="nn">..unicode</span> <span class="kn">import</span> <span class="n">normalize_unicode</span>
<span class="kn">from</span> <span class="nn">..utils</span> <span class="kn">import</span> <span class="n">_check_file_exists</span><span class="p">,</span> <span class="n">get_last_library_path</span><span class="p">,</span> <span class="n">noop</span>
<span class="kn">from</span> <span class="nn">.photosdb_utils</span> <span class="kn">import</span> <span class="p">(</span>
<span class="n">get_db_version</span><span class="p">,</span>
<span class="n">get_model_version</span><span class="p">,</span>
<span class="n">get_photos_version_from_model</span><span class="p">,</span>
<span class="p">)</span>
<span class="kn">from</span> <span class="nn">.photosdb_utils</span> <span class="kn">import</span> <span class="n">get_db_model_version</span><span class="p">,</span> <span class="n">get_db_version</span>
<span class="k">if</span> <span class="n">is_macos</span><span class="p">:</span>
<span class="kn">import</span> <span class="nn">photoscript</span>
@ -293,6 +293,7 @@
<span class="n">labels_normalized</span><span class="p">,</span>
<span class="n">labels_normalized_as_dict</span><span class="p">,</span>
<span class="p">)</span>
<span class="kn">from</span> <span class="nn">._photosdb_process_shared_library</span> <span class="kn">import</span> <span class="n">_process_shared_library_info</span>
<span class="kn">from</span> <span class="nn">._photosdb_process_syndicationinfo</span> <span class="kn">import</span> <span class="n">_process_syndicationinfo</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span>
@ -488,7 +489,7 @@
<span class="c1"># Dict to hold data on imports for Photos &lt;= 4</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_db_import_group</span> <span class="o">=</span> <span class="p">{}</span>
<span class="c1"># Dict to hold syndication info for Photos &gt;= 8</span>
<span class="c1"># Dict to hold syndication info for Photos &gt;= 7</span>
<span class="c1"># key is UUID and value is dict of syndication info</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_db_syndication_uuid</span> <span class="o">=</span> <span class="p">{}</span>
@ -528,7 +529,7 @@
<span class="c1"># photoanalysisd sometimes maintains this lock even after Photos is closed</span>
<span class="c1"># In those cases, make a temp copy of the file for sqlite3 to read</span>
<span class="k">if</span> <span class="n">sqlite_db_is_locked</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfile</span><span class="p">):</span>
<span class="n">verbose</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Database locked, creating temporary copy.&quot;</span><span class="p">)</span>
<span class="n">verbose</span><span class="p">(</span><span class="s2">&quot;Database locked, creating temporary copy.&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_tmp_db</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_copy_db_file</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfile</span><span class="p">)</span>
<span class="c1"># _db_version is set from photos.db</span>
@ -543,21 +544,23 @@
<span class="bp">self</span><span class="o">.</span><span class="n">_photos_ver</span> <span class="o">=</span> <span class="mi">4</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_photos_ver</span> <span class="o">=</span> <span class="mi">5</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_model_ver</span> <span class="o">=</span> <span class="mi">0</span> <span class="c1"># only set for Photos 5+</span>
<span class="c1"># If Photos &gt;= 5, actual data isn&#39;t in photos.db but in Photos.sqlite</span>
<span class="k">if</span> <span class="nb">int</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_db_version</span><span class="p">)</span> <span class="o">&gt;</span> <span class="nb">int</span><span class="p">(</span><span class="n">_PHOTOS_4_VERSION</span><span class="p">):</span>
<span class="n">dbpath</span> <span class="o">=</span> <span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfile</span><span class="p">)</span><span class="o">.</span><span class="n">parent</span>
<span class="n">dbfile</span> <span class="o">=</span> <span class="n">dbpath</span> <span class="o">/</span> <span class="s2">&quot;Photos.sqlite&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">_check_file_exists</span><span class="p">(</span><span class="n">dbfile</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">FileNotFoundError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;dbfile </span><span class="si">{</span><span class="n">dbfile</span><span class="si">}</span><span class="s2"> does not exist&quot;</span><span class="p">,</span> <span class="n">dbfile</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_dbfile_actual</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_tmp_db</span> <span class="o">=</span> <span class="n">dbfile</span>
<span class="n">verbose</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Processing database </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_filepath</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfile_actual</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="c1"># if database is exclusively locked, make a copy of it and use the copy</span>
<span class="k">if</span> <span class="n">sqlite_db_is_locked</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfile_actual</span><span class="p">):</span>
<span class="n">verbose</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Database locked, creating temporary copy.&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_tmp_db</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_copy_db_file</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfile_actual</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_dbfile_actual</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_tmp_db</span> <span class="o">=</span> <span class="n">dbfile</span>
<span class="n">verbose</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Processing database </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_filepath</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfile_actual</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="c1"># if database is exclusively locked, make a copy of it and use the copy</span>
<span class="k">if</span> <span class="n">sqlite_db_is_locked</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfile_actual</span><span class="p">):</span>
<span class="n">verbose</span><span class="p">(</span><span class="s2">&quot;Database locked, creating temporary copy.&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_tmp_db</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_copy_db_file</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfile_actual</span><span class="p">)</span>
<span class="c1"># set the photos version to actual value based on Photos.sqlite</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_photos_ver</span> <span class="o">=</span> <span class="n">get_db_model_version</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_tmp_db</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_photos_ver</span> <span class="o">=</span> <span class="n">get_photos_version_from_model</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_tmp_db</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_model_ver</span> <span class="o">=</span> <span class="n">get_model_version</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_tmp_db</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span>
<span class="sa">f</span><span class="s2">&quot;_dbfile = </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfile</span><span class="si">}</span><span class="s2">, _dbfile_actual = </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfile_actual</span><span class="si">}</span><span class="s2">&quot;</span>
@ -1437,6 +1440,9 @@
<span class="c1"># photos 5+ only, for shared photos</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">&quot;cloudownerhashedpersonid&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="c1"># photos 7+ only, shared moments</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">&quot;moment_share&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="c1"># compute signatures for finding possible duplicates</span>
<span class="n">signature</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_duplicate_signature</span><span class="p">(</span><span class="n">uuid</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
@ -1749,6 +1755,12 @@
<span class="n">info</span><span class="p">[</span><span class="s2">&quot;UTI_raw&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">info</span><span class="p">[</span><span class="s2">&quot;raw_pair_info&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="c1"># placeholders for shared library info on Photos 8+</span>
<span class="k">for</span> <span class="n">uuid</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">&quot;active_library_participation_state&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">&quot;library_scope_share_state&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">&quot;library_scope&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="c1"># done with the database connection</span>
<span class="n">conn</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
@ -1908,6 +1920,7 @@
<span class="c1"># get info on keyface -- some photos have null keyface so can&#39;t do a single query</span>
<span class="c1"># (at least not with my SQL skills)</span>
<span class="n">asset_fk</span> <span class="o">=</span> <span class="n">_DB_TABLE_NAMES</span><span class="p">[</span><span class="n">photos_ver</span><span class="p">][</span><span class="s2">&quot;DETECTED_FACE_ASSET_FK&quot;</span><span class="p">]</span>
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
<span class="sa">f</span><span class="s2">&quot;&quot;&quot; SELECT</span>
<span class="s2"> ZPERSON.Z_PK,</span>
@ -1916,7 +1929,7 @@
<span class="s2"> ZDETECTEDFACE.ZUUID</span>
<span class="s2"> FROM ZPERSON, ZDETECTEDFACE, </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2"></span>
<span class="s2"> WHERE ZDETECTEDFACE.Z_PK = ZPERSON.ZKEYFACE AND</span>
<span class="s2"> ZDETECTEDFACE.ZASSET = </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.Z_PK</span>
<span class="s2"> </span><span class="si">{</span><span class="n">asset_fk</span><span class="si">}</span><span class="s2"> = </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.Z_PK</span>
<span class="s2"> &quot;&quot;&quot;</span>
<span class="p">)</span>
@ -1935,13 +1948,14 @@
<span class="c1"># get information on detected faces</span>
<span class="n">verbose</span><span class="p">(</span><span class="s2">&quot;Processing detected faces in photos.&quot;</span><span class="p">)</span>
<span class="n">person_fk</span> <span class="o">=</span> <span class="n">_DB_TABLE_NAMES</span><span class="p">[</span><span class="n">photos_ver</span><span class="p">][</span><span class="s2">&quot;DETECTED_FACE_PERSON_FK&quot;</span><span class="p">]</span>
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
<span class="sa">f</span><span class="s2">&quot;&quot;&quot; SELECT</span>
<span class="s2"> ZPERSON.Z_PK,</span>
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZUUID</span>
<span class="s2"> FROM ZPERSON, ZDETECTEDFACE, </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2"></span>
<span class="s2"> WHERE ZDETECTEDFACE.ZPERSON = ZPERSON.Z_PK AND</span>
<span class="s2"> ZDETECTEDFACE.ZASSET = </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.Z_PK</span>
<span class="s2"> WHERE </span><span class="si">{</span><span class="n">person_fk</span><span class="si">}</span><span class="s2"> = ZPERSON.Z_PK AND</span>
<span class="s2"> </span><span class="si">{</span><span class="n">asset_fk</span><span class="si">}</span><span class="s2"> = </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.Z_PK</span>
<span class="s2"> &quot;&quot;&quot;</span>
<span class="p">)</span>
@ -2149,7 +2163,8 @@
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZSAVEDASSETTYPE,</span>
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZADDEDDATE,</span>
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.Z_PK,</span>
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZCLOUDOWNERHASHEDPERSONID</span>
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZCLOUDOWNERHASHEDPERSONID,</span>
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZMOMENTSHARE</span>
<span class="s2"> FROM </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2"> </span>
<span class="s2"> JOIN ZADDITIONALASSETATTRIBUTES ON ZADDITIONALASSETATTRIBUTES.ZASSET = </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.Z_PK </span>
<span class="s2"> ORDER BY </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZUUID &quot;&quot;&quot;</span>
@ -2200,6 +2215,7 @@
<span class="c1"># 41 ZGENERICASSET.ZADDEDDATE -- date item added to the library</span>
<span class="c1"># 42 ZGENERICASSET.Z_PK -- primary key</span>
<span class="c1"># 43 ZGENERICASSET.ZCLOUDOWNERHASHEDPERSONID -- used to look up owner name (for shared photos)</span>
<span class="c1"># 44 ZASSET.ZMOMENTSHARE -- FK for ZSHARE (shared moments, Photos 5+; in Photos 7+ these are in the scopes/momentshared folder)</span>
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
<span class="n">uuid</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
@ -2387,6 +2403,8 @@
<span class="n">info</span><span class="p">[</span><span class="s2">&quot;pk&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">42</span><span class="p">]</span>
<span class="n">info</span><span class="p">[</span><span class="s2">&quot;cloudownerhashedpersonid&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">43</span><span class="p">]</span>
<span class="n">info</span><span class="p">[</span><span class="s2">&quot;moment_share&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">44</span><span class="p">]</span>
<span class="c1"># initialize import session info which will be filled in later</span>
<span class="c1"># not every photo has an import session so initialize all records now</span>
<span class="n">info</span><span class="p">[</span><span class="s2">&quot;import_session&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
@ -2411,6 +2429,11 @@
<span class="n">info</span><span class="p">[</span><span class="s2">&quot;UTI_edited_photo&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">info</span><span class="p">[</span><span class="s2">&quot;UTI_edited_video&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="c1"># placeholder for shared library info (Photos 8+)</span>
<span class="n">info</span><span class="p">[</span><span class="s2">&quot;active_library_participation_state&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">info</span><span class="p">[</span><span class="s2">&quot;library_scope_share_state&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">info</span><span class="p">[</span><span class="s2">&quot;library_scope&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">]</span> <span class="o">=</span> <span class="n">info</span>
<span class="c1"># compute signatures for finding possible duplicates</span>
@ -2719,10 +2742,14 @@
<span class="n">verbose</span><span class="p">(</span><span class="s2">&quot;Processing moments.&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_process_moments</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">photos_version</span> <span class="o">&gt;=</span> <span class="mi">8</span><span class="p">:</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">photos_version</span> <span class="o">&gt;=</span> <span class="mi">7</span><span class="p">:</span>
<span class="n">verbose</span><span class="p">(</span><span class="s2">&quot;Processing syndication info.&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_process_syndicationinfo</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">photos_version</span> <span class="o">&gt;=</span> <span class="mi">8</span><span class="p">:</span>
<span class="n">verbose</span><span class="p">(</span><span class="s2">&quot;Processing shared iCloud library info&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_process_shared_library_info</span><span class="p">()</span>
<span class="n">verbose</span><span class="p">(</span><span class="s2">&quot;Done processing details from Photos library.&quot;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_process_moments</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
@ -3732,6 +3759,16 @@
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">not_saved_to_library</span><span class="p">:</span>
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">syndicated</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">saved_to_library</span><span class="p">]</span>
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">shared_moment</span><span class="p">:</span>
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">shared_moment</span><span class="p">]</span>
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">not_shared_moment</span><span class="p">:</span>
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">shared_moment</span><span class="p">]</span>
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">shared_library</span><span class="p">:</span>
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">shared_library</span><span class="p">]</span>
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">not_shared_library</span><span class="p">:</span>
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">shared_library</span><span class="p">]</span>
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">function</span><span class="p">:</span>
<span class="k">for</span> <span class="n">function</span> <span class="ow">in</span> <span class="n">options</span><span class="o">.</span><span class="n">function</span><span class="p">:</span>
<span class="n">photos</span> <span class="o">=</span> <span class="n">function</span><span class="p">[</span><span class="mi">0</span><span class="p">](</span><span class="n">photos</span><span class="p">)</span>

View File

@ -5,7 +5,7 @@
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../genindex.html" /><link rel="search" title="Search" href="../../search.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
<title>osxphotos.phototemplate - osxphotos 0.60.0 documentation</title>
<title>osxphotos.phototemplate - osxphotos 0.62.0 documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
@ -123,7 +123,7 @@
</label>
</div>
<div class="header-center">
<a href="../../index.html"><div class="brand">osxphotos 0.60.0 documentation</div></a>
<a href="../../index.html"><div class="brand">osxphotos 0.62.0 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -146,7 +146,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../index.html">
<span class="sidebar-brand-text">osxphotos 0.60.0 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.62.0 documentation</span>
</a><form class="sidebar-search-container" method="get" action="../../search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@ -160,6 +160,7 @@
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../template_help.html">OSXPhotos Template System</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../package_overview.html">OSXPhotos Python Package Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../api_readme.html">OSXPhotos Python API</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">OSXPhotos Python Reference</a></li>
</ul>
@ -661,7 +662,7 @@
<span class="sd"> ([rendered_strings], [unmatched]): tuple of list of rendered strings and list of unmatched template values</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">template</span><span class="p">)</span> <span class="ow">is</span> <span class="ow">not</span> <span class="nb">str</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">template</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;template must be type str, not </span><span class="si">{</span><span class="nb">type</span><span class="p">(</span><span class="n">template</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">options</span> <span class="o">=</span> <span class="n">options</span>
@ -1592,7 +1593,7 @@
<span class="c1"># if no uuid, then template is being validated but not actually run</span>
<span class="c1"># so don&#39;t run the function</span>
<span class="n">values</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">elif</span> <span class="n">caller</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">&quot;export&quot;</span><span class="p">,</span> <span class="s2">&quot;query&quot;</span><span class="p">]:</span>
<span class="k">elif</span> <span class="n">caller</span> <span class="ow">in</span> <span class="p">{</span><span class="s2">&quot;export&quot;</span><span class="p">,</span> <span class="s2">&quot;query&quot;</span><span class="p">}:</span>
<span class="c1"># function signature is:</span>
<span class="c1"># def example(photo: PhotoInfo, options: ExportOptions, args: Optional[str] = None, **kwargs) -&gt; Union[List, str]:</span>
<span class="n">values</span> <span class="o">=</span> <span class="n">template_func</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">photo</span><span class="p">,</span> <span class="n">options</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">options</span><span class="p">,</span> <span class="n">args</span><span class="o">=</span><span class="n">field_arg</span><span class="p">)</span>
@ -1608,7 +1609,7 @@
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
<span class="sa">f</span><span class="s2">&quot;Invalid return type for function </span><span class="si">{</span><span class="n">funcname</span><span class="si">}</span><span class="s2">: expected str or list&quot;</span>
<span class="p">)</span>
<span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">values</span><span class="p">)</span> <span class="o">==</span> <span class="nb">str</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">values</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<span class="n">values</span> <span class="o">=</span> <span class="p">[</span><span class="n">values</span><span class="p">]</span>
<span class="c1"># sanitize directory names if needed</span>

View File

@ -5,7 +5,7 @@
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../genindex.html" /><link rel="search" title="Search" href="../../search.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
<title>osxphotos.placeinfo - osxphotos 0.60.0 documentation</title>
<title>osxphotos.placeinfo - osxphotos 0.61.0 documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
@ -123,7 +123,7 @@
</label>
</div>
<div class="header-center">
<a href="../../index.html"><div class="brand">osxphotos 0.60.0 documentation</div></a>
<a href="../../index.html"><div class="brand">osxphotos 0.61.0 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -146,7 +146,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../index.html">
<span class="sidebar-brand-text">osxphotos 0.60.0 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.61.0 documentation</span>
</a><form class="sidebar-search-container" method="get" action="../../search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@ -202,14 +202,16 @@
<span class="sd"> See https://developer.apple.com/documentation/corelocation/clplacemark</span>
<span class="sd"> for additional documentation on reverse geolocation data</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">annotations</span>
<span class="kn">from</span> <span class="nn">abc</span> <span class="kn">import</span> <span class="n">ABC</span><span class="p">,</span> <span class="n">abstractmethod</span>
<span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">namedtuple</span> <span class="c1"># pylint: disable=syntax-error</span>
<span class="kn">import</span> <span class="nn">yaml</span>
<span class="kn">from</span> <span class="nn">bpylist2</span> <span class="kn">import</span> <span class="n">archiver</span>
<span class="kn">from</span> <span class="nn">._constants</span> <span class="kn">import</span> <span class="n">UNICODE_FORMAT</span>
<span class="kn">from</span> <span class="nn">.utils</span> <span class="kn">import</span> <span class="n">normalize_unicode</span>
<span class="kn">from</span> <span class="nn">.unicode</span> <span class="kn">import</span> <span class="n">normalize_unicode</span>
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">&quot;PLRevGeoLocationInfo&quot;</span><span class="p">,</span>
@ -529,36 +531,101 @@
<span class="n">archiver</span><span class="o">.</span><span class="n">update_class_map</span><span class="p">({</span><span class="s2">&quot;PLRevGeoLocationInfo&quot;</span><span class="p">:</span> <span class="n">PLRevGeoLocationInfo</span><span class="p">})</span>
<div class="viewcode-block" id="PlaceInfo"><a class="viewcode-back" href="../../reference.html#osxphotos.PlaceInfo">[docs]</a><span class="k">class</span> <span class="nc">PlaceInfo</span><span class="p">(</span><span class="n">ABC</span><span class="p">):</span>
<span class="c1"># PlaceInfo is really an abstract base class but defining it as such</span>
<span class="c1"># means it doesn&#39;t get picked up by the doc generation tools</span>
<span class="c1"># so we define it as a regular class and then subclass it</span>
<span class="c1"># TODO: right fix is probably have PlaceInfo as the only class that</span>
<span class="c1"># is used and then have PlaceInfo4 and PlaceInfo5 called by PlaceInfo</span>
<span class="c1"># as needed to return the properties (and make them private classes)</span>
<div class="viewcode-block" id="PlaceInfo"><a class="viewcode-back" href="../../reference.html#osxphotos.PlaceInfo">[docs]</a><span class="k">class</span> <span class="nc">PlaceInfo</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;Reverse geolocation place info for a photo.&quot;&quot;&quot;</span>
<span class="nd">@property</span>
<span class="nd">@abstractmethod</span>
<span class="k">def</span> <span class="nf">address_str</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">address_str</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;Returns the full postal address as a string if defined, otherwise `None`.&quot;&quot;&quot;</span>
<span class="k">pass</span>
<span class="nd">@property</span>
<span class="nd">@abstractmethod</span>
<span class="k">def</span> <span class="nf">country_code</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">country_code</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;Returns the country_code of place, for example &quot;GB&quot;.</span>
<span class="sd"> Returns `None` if PhotoInfo contains no country code.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">pass</span>
<span class="nd">@property</span>
<span class="nd">@abstractmethod</span>
<span class="k">def</span> <span class="nf">ishome</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">ishome</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;Returns `True` if photo place is user&#39;s home address, otherwise `False`.&quot;&quot;&quot;</span>
<span class="k">pass</span>
<span class="nd">@property</span>
<span class="nd">@abstractmethod</span>
<span class="k">def</span> <span class="nf">name</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">name</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;Returns the name of the local place as str.</span>
<span class="sd"> This is what Photos displays in the Info window.</span>
<span class="sd"> **Note** Photos 5 uses a different algorithm to determine the name than earlier versions which means the same Photo may have a different place name in Photos 4 and Photos 5.</span>
<span class="sd"> `PhotoInfo.name` will return the name Photos would have shown depending on the version of the library being processed.</span>
<span class="sd"> Returns `None` if photo does not contain a name.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">pass</span>
<span class="nd">@property</span>
<span class="nd">@abstractmethod</span>
<span class="k">def</span> <span class="nf">names</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">names</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">PlaceNames</span> <span class="o">|</span> <span class="kc">None</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;Returns a `PlaceNames` namedtuple with the following fields.</span>
<span class="sd"> Each field is a list with zero or more values, sorted by area in ascending order.</span>
<span class="sd"> E.g. `names.area_of_interest` could be [&#39;Gulf Islands National Seashore&#39;, &#39;Santa Rosa Island&#39;], [&quot;Knott&#39;s Berry Farm&quot;], or [] if `area_of_interest` not defined.</span>
<span class="sd"> The value shown in Photos is the first value in the list. With the exception of `body_of_water` each of these field corresponds to an attribute of</span>
<span class="sd"> a [CLPlacemark](https://developer.apple.com/documentation/corelocation/clplacemark) object.</span>
<span class="sd"> * `country`; the name of the country associated with the placemark.</span>
<span class="sd"> * `state_province`; administrativeArea, The state or province associated with the placemark.</span>
<span class="sd"> * `sub_administrative_area`; additional administrative area information for the placemark.</span>
<span class="sd"> * `city`; locality; the city associated with the placemark.</span>
<span class="sd"> * `additional_city_info`; subLocality, Additional city-level information for the placemark.</span>
<span class="sd"> * `ocean`; the name of the ocean associated with the placemark.</span>
<span class="sd"> * `area_of_interest`; areasOfInterest, The relevant areas of interest associated with the placemark.</span>
<span class="sd"> * `inland_water`; the name of the inland water body associated with the placemark.</span>
<span class="sd"> * `region`; the geographic region associated with the placemark.</span>
<span class="sd"> * `sub_throughfare`; additional street-level information for the placemark.</span>
<span class="sd"> * `postal_code`; the postal code associated with the placemark.</span>
<span class="sd"> * `street_address`; throughfare, The street address associated with the placemark.</span>
<span class="sd"> * `body_of_water`; in Photos 4, any body of water; in Photos 5 contains the union of ocean and inland_water</span>
<span class="sd"> **Note**: In Photos &lt;= 4.0, only the following fields are defined; all others are set to empty list:</span>
<span class="sd"> * `country`</span>
<span class="sd"> * `state_province`</span>
<span class="sd"> * `sub_administrative_area`</span>
<span class="sd"> * `city`</span>
<span class="sd"> * `additional_city_info`</span>
<span class="sd"> * `area_of_interest`</span>
<span class="sd"> * `body_of_water`</span>
<span class="sd"> Note:</span>
<span class="sd"> The `PlaceNames` namedtuple contains reserved fields not listed below (see implementation for details),</span>
<span class="sd"> thus it should be referenced only by name (e.g. `names.city`) and not by index.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">pass</span>
<span class="nd">@property</span>
<span class="nd">@abstractmethod</span>
<span class="k">def</span> <span class="nf">address</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">pass</span></div>
<span class="sd">&quot;&quot;&quot;Returns a `PostalAddress` namedtuple with details of the postal address containing the following fields:</span>
<span class="sd"> * `city`</span>
<span class="sd"> * `country`</span>
<span class="sd"> * `postal_code`</span>
<span class="sd"> * `state`</span>
<span class="sd"> * `street`</span>
<span class="sd"> * `sub_administrative_area`</span>
<span class="sd"> * `sub_locality`</span>
<span class="sd"> * `iso_country_code`</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">pass</span>
<div class="viewcode-block" id="PlaceInfo.asdict"><a class="viewcode-back" href="../../reference.html#osxphotos.PlaceInfo.asdict">[docs]</a> <span class="k">def</span> <span class="nf">asdict</span><span class="p">():</span>
<span class="sd">&quot;&quot;&quot;Returns a dictionary representation of the PlaceInfo object.&quot;&quot;&quot;</span>
<span class="k">pass</span></div></div>
<span class="k">class</span> <span class="nc">PlaceInfo4</span><span class="p">(</span><span class="n">PlaceInfo</span><span class="p">):</span>

View File

@ -5,7 +5,7 @@
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../genindex.html" /><link rel="search" title="Search" href="../../search.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
<title>osxphotos.queryoptions - osxphotos 0.60.3 documentation</title>
<title>osxphotos.queryoptions - osxphotos 0.62.0 documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
@ -123,7 +123,7 @@
</label>
</div>
<div class="header-center">
<a href="../../index.html"><div class="brand">osxphotos 0.60.3 documentation</div></a>
<a href="../../index.html"><div class="brand">osxphotos 0.62.0 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -146,7 +146,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../index.html">
<span class="sidebar-brand-text">osxphotos 0.60.3 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.62.0 documentation</span>
</a><form class="sidebar-search-container" method="get" action="../../search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@ -160,6 +160,7 @@
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../template_help.html">OSXPhotos Template System</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../package_overview.html">OSXPhotos Python Package Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../api_readme.html">OSXPhotos Python API</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">OSXPhotos Python Reference</a></li>
</ul>
@ -309,6 +310,10 @@
<span class="sd"> not_syndicated: search for photos that have not been shared via syndication (&quot;Shared with You&quot; album via Messages, etc.)</span>
<span class="sd"> saved_to_library: search for syndicated photos that have been saved to the Photos library</span>
<span class="sd"> not_saved_to_library: search for syndicated photos that have not been saved to the Photos library</span>
<span class="sd"> shared_moment: search for photos that have been shared via a shared moment</span>
<span class="sd"> not_shared_moment: search for photos that have not been shared via a shared moment</span>
<span class="sd"> shared_library: search for photos that are part of a shared iCloud library</span>
<span class="sd"> not_shared_library: search for photos that are not part of a shared iCloud library</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">added_after</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
@ -397,6 +402,10 @@
<span class="n">not_syndicated</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">saved_to_library</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">not_saved_to_library</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">shared_moment</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">not_shared_moment</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">shared_library</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">not_shared_library</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">def</span> <span class="nf">asdict</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="n">asdict</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span></div>
@ -468,7 +477,10 @@
<span class="p">(</span><span class="s2">&quot;deleted_only&quot;</span><span class="p">,</span> <span class="s2">&quot;not_deleted&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;syndicated&quot;</span><span class="p">,</span> <span class="s2">&quot;not_syndicated&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;saved_to_library&quot;</span><span class="p">,</span> <span class="s2">&quot;not_saved_to_library&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;shared_moment&quot;</span><span class="p">,</span> <span class="s2">&quot;not_shared_moment&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;shared_library&quot;</span><span class="p">,</span> <span class="s2">&quot;not_shared_library&quot;</span><span class="p">),</span>
<span class="p">]</span>
<span class="c1"># TODO: add option to validate requiring at least one query arg</span>
<span class="k">for</span> <span class="n">arg</span><span class="p">,</span> <span class="n">not_arg</span> <span class="ow">in</span> <span class="n">exclusive</span><span class="p">:</span>
<span class="k">if</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span> <span class="ow">and</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">not_arg</span><span class="p">):</span>

View File

@ -5,7 +5,7 @@
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../genindex.html" /><link rel="search" title="Search" href="../../search.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
<title>osxphotos.scoreinfo - osxphotos 0.60.2 documentation</title>
<title>osxphotos.scoreinfo - osxphotos 0.61.0 documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
@ -123,7 +123,7 @@
</label>
</div>
<div class="header-center">
<a href="../../index.html"><div class="brand">osxphotos 0.60.2 documentation</div></a>
<a href="../../index.html"><div class="brand">osxphotos 0.61.0 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -146,7 +146,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../index.html">
<span class="sidebar-brand-text">osxphotos 0.60.2 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.61.0 documentation</span>
</a><form class="sidebar-search-container" method="get" action="../../search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@ -197,7 +197,7 @@
<h1>Source code for osxphotos.scoreinfo</h1><div class="highlight"><pre>
<span></span><span class="sd">&quot;&quot;&quot; ScoreInfo class to expose computed score info from the library &quot;&quot;&quot;</span>
<span class="kn">from</span> <span class="nn">dataclasses</span> <span class="kn">import</span> <span class="n">dataclass</span><span class="p">,</span> <span class="n">asdict</span>
<span class="kn">from</span> <span class="nn">dataclasses</span> <span class="kn">import</span> <span class="n">asdict</span><span class="p">,</span> <span class="n">dataclass</span>
<span class="kn">from</span> <span class="nn">._constants</span> <span class="kn">import</span> <span class="n">_PHOTOS_4_VERSION</span>

View File

@ -5,7 +5,7 @@
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../genindex.html" /><link rel="search" title="Search" href="../../search.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
<title>osxphotos.searchinfo - osxphotos 0.58.1 documentation</title>
<title>osxphotos.searchinfo - osxphotos 0.61.0 documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
@ -123,7 +123,7 @@
</label>
</div>
<div class="header-center">
<a href="../../index.html"><div class="brand">osxphotos 0.58.1 documentation</div></a>
<a href="../../index.html"><div class="brand">osxphotos 0.61.0 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -146,7 +146,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../index.html">
<span class="sidebar-brand-text">osxphotos 0.58.1 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.61.0 documentation</span>
</a><form class="sidebar-search-container" method="get" action="../../search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">

File diff suppressed because it is too large Load Diff

View File

@ -14,6 +14,7 @@ Welcome to OSXPhotos's documentation!
cli
template_help
package_overview
API_README
reference

View File

@ -162,9 +162,9 @@ e.g. ``"{created.year}/{openbrace}{title}{closebrace}"`` would result in ``"2020
**Variables**
You can define variables for later use in the template string using the format ``{var:NAME,VALUE}``. Variables may then be referenced using the format ``%NAME``. For example: ``{var:foo,bar}`` defines the variable ``%foo`` to have value ``bar``. This can be useful if you want to re-use a complex template value in multiple places within your template string or for allowing the use of characters that would otherwise be prohibited in a template string. For example, the "pipe" (\ ``|``\ ) character is not allowed in a find/replace pair but you can get around this limitation like so: ``{var:pipe,{pipe}}{title[-,%pipe]}`` which replaces the ``-`` character with ``|`` (the value of ``%pipe``\ ).
You can define variables for later use in the template string using the format ``{var:NAME,VALUE}`` where ``VALUE`` is a template statement. Variables may then be referenced using the format ``%NAME``. For example: ``{var:foo,bar}`` defines the variable ``%foo`` to have value ``bar``. This can be useful if you want to re-use a complex template value in multiple places within your template string or for allowing the use of characters that would otherwise be prohibited in a template string. For example, the "pipe" (\ ``|``\ ) character is not allowed in a find/replace pair but you can get around this limitation like so: ``{var:pipe,{pipe}}{title[-,%pipe]}`` which replaces the ``-`` character with ``|`` (the value of ``%pipe``\ ).
Variables can also be referenced as fields in the template string, for example: ``{var:year,created.year}{original_name}-{%year}``. In some cases, use of variables can make your template string more readable. Variables can be used as template fields, as values for filters, as values for conditional operations, or as default values. When used as a conditional value or default value, variables should be treated like any other field and enclosed in braces as conditional and default values are evaluated as template strings. For example: ``{var:name,Katie}{person contains {%name}?{%name},Not-{%name}}``.
Variables can also be referenced as fields in the template string, for example: ``{var:year,{created.year}}{original_name}-{%year}``. In some cases, use of variables can make your template string more readable. Variables can be used as template fields, as values for filters, as values for conditional operations, or as default values. When used as a conditional value or default value, variables should be treated like any other field and enclosed in braces as conditional and default values are evaluated as template strings. For example: ``{var:name,Katie}{person contains {%name}?{%name},Not-{%name}}``.
If you need to use a ``%`` (percent sign character), you can escape the percent sign by using ``%%``. You can also use the ``{percent}`` template field where a template field is required. For example:
@ -361,7 +361,7 @@ Template Substitutions
* - {tab}
- :A tab: '\t'
* - {osxphotos_version}
- The osxphotos version, e.g. '0.60.4'
- The osxphotos version, e.g. '0.62.1'
* - {osxphotos_cmd_line}
- The full command line used to run osxphotos
* - {album}

View File

@ -1,6 +1,6 @@
var DOCUMENTATION_OPTIONS = {
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
VERSION: '0.60.4',
VERSION: '0.62.1',
LANGUAGE: 'en',
COLLAPSE_INDEX: false,
BUILDER: 'html',

View File

@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="OSXPhotos Template System" href="template_help.html" /><link rel="prev" title="OSXPhotos Tutorial" href="tutorial.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
<title>OSXPhotos Command Line Interface (CLI) - osxphotos 0.60.4 documentation</title>
<title>OSXPhotos Command Line Interface (CLI) - osxphotos 0.62.1 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@ -124,7 +124,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">osxphotos 0.60.4 documentation</div></a>
<a href="index.html"><div class="brand">osxphotos 0.62.1 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -147,7 +147,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
<span class="sidebar-brand-text">osxphotos 0.60.4 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.62.1 documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@ -161,6 +161,7 @@
<li class="toctree-l1 current current-page"><a class="current reference internal" href="#">OSXPhotos Command Line Interface (CLI)</a></li>
<li class="toctree-l1"><a class="reference internal" href="template_help.html">OSXPhotos Template System</a></li>
<li class="toctree-l1"><a class="reference internal" href="package_overview.html">OSXPhotos Python Package Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="API_README.html">OSXPhotos Python API</a></li>
<li class="toctree-l1"><a class="reference internal" href="reference.html">OSXPhotos Python Reference</a></li>
</ul>
@ -211,18 +212,6 @@
<dd><p>Show the version and exit.</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-library">
<span id="cmdoption-osxphotos-db"></span><span class="sig-name descname"><span class="pre">--library</span></span><span class="sig-prename descclassname"></span><span class="sig-prename descclassname"><span class="pre">,</span> </span><span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;PHOTOS_LIBRARY_PATH&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-library" title="Permalink to this definition">#</a></dt>
<dd><p>Specify path to Photos library. If not provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-json">
<span class="sig-name descname"><span class="pre">--json</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-json" title="Permalink to this definition">#</a></dt>
<dd><p>Print output in JSON format.</p>
</dd></dl>
<section id="osxphotos-about">
<h3>about<a class="headerlink" href="#osxphotos-about" title="Permalink to this heading">#</a></h3>
<p>Print information about osxphotos including license.</p>
@ -752,6 +741,30 @@ See <cite>osxphotos help timewarp</cite> for more information.</p>
<dd><p>Search for syndicated photos that have not saved to the library</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-add-locations-shared-moment">
<span class="sig-name descname"><span class="pre">--shared-moment</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-add-locations-shared-moment" title="Permalink to this definition">#</a></dt>
<dd><p>Search for photos that are part of a shared moment</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-add-locations-not-shared-moment">
<span class="sig-name descname"><span class="pre">--not-shared-moment</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-add-locations-not-shared-moment" title="Permalink to this definition">#</a></dt>
<dd><p>Search for photos that are not part of a shared moment</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-add-locations-shared-library">
<span class="sig-name descname"><span class="pre">--shared-library</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-add-locations-shared-library" title="Permalink to this definition">#</a></dt>
<dd><p>Search for photos that are part of a shared library</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-add-locations-not-shared-library">
<span class="sig-name descname"><span class="pre">--not-shared-library</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-add-locations-not-shared-library" title="Permalink to this definition">#</a></dt>
<dd><p>Search for photos that are not part of a shared library</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-add-locations-regex">
<span class="sig-name descname"><span class="pre">--regex</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;REGEX</span> <span class="pre">TEMPLATE&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-add-locations-regex" title="Permalink to this definition">#</a></dt>
@ -1707,6 +1720,30 @@ to modify this behavior.</p>
<dd><p>Search for syndicated photos that have not saved to the library</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-shared-moment">
<span class="sig-name descname"><span class="pre">--shared-moment</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-export-shared-moment" title="Permalink to this definition">#</a></dt>
<dd><p>Search for photos that are part of a shared moment</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-not-shared-moment">
<span class="sig-name descname"><span class="pre">--not-shared-moment</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-export-not-shared-moment" title="Permalink to this definition">#</a></dt>
<dd><p>Search for photos that are not part of a shared moment</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-shared-library">
<span class="sig-name descname"><span class="pre">--shared-library</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-export-shared-library" title="Permalink to this definition">#</a></dt>
<dd><p>Search for photos that are part of a shared library</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-not-shared-library">
<span class="sig-name descname"><span class="pre">--not-shared-library</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-export-not-shared-library" title="Permalink to this definition">#</a></dt>
<dd><p>Search for photos that are not part of a shared library</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-regex">
<span class="sig-name descname"><span class="pre">--regex</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;REGEX</span> <span class="pre">TEMPLATE&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-export-regex" title="Permalink to this definition">#</a></dt>
@ -1905,6 +1942,12 @@ to modify this behavior.</p>
<dd><p>Attempt to download missing photos from iCloud. The current implementation uses Applescript to interact with Photos to export the photo which will force Photos to download from iCloud if the photo does not exist on disk. This will be slow and will require internet connection. This obviously only works if the Photos library is synched to iCloud. Note: download-missing does not currently export all burst images; only the primary photo will be exportedassociated burst images will be skipped.</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-export-aae">
<span class="sig-name descname"><span class="pre">--export-aae</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-export-export-aae" title="Permalink to this definition">#</a></dt>
<dd><p>Also export an adjustments file detailing edits made to the original. The resulting file is named photoname.AAE. Note that to import these files back to Photos succesfully, you also need to export the edited photo and match the filename format Photos.app expects: filename IMG_{edited_version?E,}{id:04d} edited-suffix </p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-sidecar">
<span class="sig-name descname"><span class="pre">--sidecar</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;FORMAT&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-export-sidecar" title="Permalink to this definition">#</a></dt>
@ -1924,6 +1967,12 @@ to modify this behavior.</p>
<dd><p>Drop the photos extension when naming sidecar files. By default, sidecar files are named in format photo_filename.photo_ext.sidecar_ext, e.g. IMG_1234.JPG.xmp. Use sidecar-drop-ext to ignore the photo extension. Resulting sidecar files will have name in format IMG_1234.xmp. Warning: this may result in sidecar filename collisions if there are files of different types but the same name in the output directory, e.g. IMG_1234.JPG and IMG_1234.MOV.</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-sidecar-template">
<span class="sig-name descname"><span class="pre">--sidecar-template</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;MAKO_TEMPLATE_FILE</span> <span class="pre">SIDECAR_FILENAME_TEMPLATE</span> <span class="pre">OPTIONS&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-export-sidecar-template" title="Permalink to this definition">#</a></dt>
<dd><p>Create a custom sidecar file for each photo exported with user provided Mako template (MAKO_TEMPLATE_FILE). MAKO_TEMPLATE_FILE must be a valid Mako template (see <a class="reference external" href="https://www.makotemplates.org/">https://www.makotemplates.org/</a>). The template will passed the following variables: photo (PhotoInfo object for the photo being exported), sidecar_path (pathlib.Path object for the path to the sidecar being written), and photo_path (pathlib.Path object for the path to the exported photo. SIDECAR_FILENAME_TEMPLATE must be a valid template string (see Templating System in help) which will be rendered to generate the filename of the sidecar file. The <cite>{filepath}</cite> template variable may be used in the SIDECAR_FILENAME_TEMPLATE to refer to the filename of the photo being exported. OPTIONS is a comma-separated list of strings providing additional options to the template. Valid options are: write_skipped, strip_whitespace, strip_lines, skip_zero, catch_errors, none. write_skipped will cause the sidecar file to be written even if the photo is skipped during export. If write_skipped is not passed as an option, the sidecar file will not be written if the photo is skipped during export. strip_whitespace and strip_lines indicate whether or not to strip whitespace and blank lines, respectively, from the resulting sidecar file. skip_zero causes the sidecar file to be skipped if the rendered template is zero-length. catch_errors causes errors in the template to be caught and logged but not raised. Without catch_errors, osxphotos will abort the export if an error occurs in the template. For example, to create a sidecar file with extension .xmp using a template file named sidecar.mako and write a sidecar for skipped photos and strip blank lines but not whitespace: <cite>sidecar-template sidecar.mako {filepath}.xmp write_skipped,strip_lines</cite>. To do the same but to drop the photo extension from the sidecar filename: <cite>sidecar-template sidecar.mako {filepath.parent}/{filepath.stem}.xmp write_skipped,strip_lines</cite>. If you are not passing any options, you must pass none as the last argument to sidecar-template: <cite>sidecar-template sidecar.mako {filepath}.xmp none</cite>. For an example Mako file see <a class="reference external" href="https://raw.githubusercontent.com/RhetTbull/osxphotos/main/examples/custom_sidecar.mako">https://raw.githubusercontent.com/RhetTbull/osxphotos/main/examples/custom_sidecar.mako</a></p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-exiftool">
<span class="sig-name descname"><span class="pre">--exiftool</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-export-exiftool" title="Permalink to this definition">#</a></dt>
@ -2082,13 +2131,13 @@ to modify this behavior.</p>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-cleanup">
<span class="sig-name descname"><span class="pre">--cleanup</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-export-cleanup" title="Permalink to this definition">#</a></dt>
<dd><p>Cleanup export directory by deleting any files which were not included in this export set. For example, photos which had previously been exported and were subsequently deleted in Photos. WARNING: cleanup will delete <em>any</em> files in the export directory that were not exported by osxphotos, for example, your own scripts or other files. Be sure this is what you intend before using cleanup. Use dry-run with cleanup first if youre not certain.</p>
<dd><p>Cleanup export directory by deleting any files which were not included in this export set. For example, photos which had previously been exported and were subsequently deleted in Photos. WARNING: cleanup will delete <em>any</em> files in the export directory that were not exported by osxphotos, for example, your own scripts or other files. Be sure this is what you intend before using cleanup. Use dry-run with cleanup first if youre not certain. To prevent files not generated by osxphotos from being deleted, you may specify one or more rulesin a file named <cite>.osxphotos_keep</cite> in the export directory. This file uses the same format as a .gitignore file and should contain one rule per line; lines starting with a <cite>#</cite> will be ignored. Reference <a class="reference external" href="https://git-scm.com/docs/gitignore#_pattern_format">https://git-scm.com/docs/gitignore#_pattern_format</a> for details. In addition to the standard .gitignore rules, the rules may also be the absolute path to a file or directory. For example if export destination is <cite>/Volumes/Photos</cite> and you want to keep all <cite>.txt</cite> files, in the top level of the export directory, you can specify <cite>/*.txt”</cite> in the .osxphotos_keep file. If you want to keep all <cite>.txt</cite> files in the export directory and all subdirectories, you can specify <cite>**/*.txt</cite>. If present, the .osxphotos_keep file will be read after the export is completed and any rules found in the file will be added to the list of rules to keep. See also keep.</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-keep">
<span class="sig-name descname"><span class="pre">--keep</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;KEEP_PATH&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-export-keep" title="Permalink to this definition">#</a></dt>
<dd><p>When used with cleanup, prevents file or directory KEEP_PATH from being deleted when cleanup is run. Use this if there are files in the export directory that you dont want to be deleted when cleanup is run. KEEP_PATH may be a file path, e.g. /Volumes/Photos/keep.jpg, or a file path and wild card, e.g. /Volumes/Photos/<em>.txt, or a directory, e.g. /Volumes/Photos/KeepMe. KEEP_PATH may be an absolute path or a relative path. If it is relative, it must be relative to the export destination. For example if export destination is `/Volumes/Photos` and you want to keep all `.txt` files, you can specify `keep “/Volumes/Photos/</em>.txt”` or <cite>keep “*.txt”</cite>. If wild card is used, KEEP_PATH must be enclosed in quotes to prevent the shell from expanding the wildcard, e.g. <cite>keep “/Volumes/Photos/*.txt”</cite>. If KEEP_PATH is a directory, all files and directories contained in KEEP_PATH will be kept. keep may be repeated to keep additional files/directories.</p>
<span class="sig-name descname"><span class="pre">--keep</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;KEEP_RULE&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-export-keep" title="Permalink to this definition">#</a></dt>
<dd><p>When used with cleanup, prevents file or directory matching KEEP_RULE from being deleted when cleanup is run. Use this if there are files in the export directory that you dont want to be deleted when cleanup is run. KEEP_RULE follows the same format rules a .gitignore file. Reference <a class="reference external" href="https://git-scm.com/docs/gitignore#_pattern_format">https://git-scm.com/docs/gitignore#_pattern_format</a> for details. In addition to the standard .gitignore rules, KEEP_RULE may also be the absolute path to a file or directory. For example if export destination is <cite>/Volumes/Photos</cite> and you want to keep all <cite>.txt</cite> files, in the top level of the export directory, you can specify <cite>keep “/*.txt”</cite>. If you want to keep all <cite>.txt</cite> files in the export directory and all subdirectories, you can specify <cite>keep “**/*.txt”</cite>. If wild card is used, KEEP_RULE must be enclosed in quotes to prevent the shell from expanding the wildcard. keep may be repeated to keep additional files/directories. Rules may also be included in a file named <cite>.osxphotos_keep</cite> in the export directory. If present, this file will be read after the export is completed and any rules found in the file will be added to the list of rules to keep. This file uses the same format as a .gitignore file and should contain one rule per line; lines starting with a <cite>#</cite> will be ignored.</p>
</dd></dl>
<dl class="std option">
@ -2112,7 +2161,18 @@ to modify this behavior.</p>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-post-command">
<span class="sig-name descname"><span class="pre">--post-command</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;CATEGORY</span> <span class="pre">COMMAND&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-export-post-command" title="Permalink to this definition">#</a></dt>
<dd><p>Run COMMAND on exported files of category CATEGORY. CATEGORY can be one of: exported, new, updated, skipped, missing, exif_updated, touched, converted_to_jpeg, sidecar_json_written, sidecar_json_skipped, sidecar_exiftool_written, sidecar_exiftool_skipped, sidecar_xmp_written, sidecar_xmp_skipped, error. COMMAND is an osxphotos template string, for example: post-command exported “echo {filepath|shell_quote} &gt;&gt; {export_dir}/exported.txt”, which appends the full path of all exported files to the file exported.txt. You can run more than one command by repeating the post-command option with different arguments. See Post Command below.</p>
<dd><p>Run COMMAND on exported files of category CATEGORY. CATEGORY can be one of: exported, new, updated, skipped, missing, exif_updated, touched, converted_to_jpeg, sidecar_json_written, sidecar_json_skipped, sidecar_exiftool_written, sidecar_exiftool_skipped, sidecar_xmp_written, sidecar_xmp_skipped, error. COMMAND is an osxphotos template string, for example: post-command exported “echo {filepath|shell_quote} &gt;&gt; {export_dir}/exported.txt”, which appends the full path of all exported files to the file exported.txt. You can run more than one command by repeating the post-command option with different arguments. See also post-command-error and post-function.See Post Command below.</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-post-command-error">
<span class="sig-name descname"><span class="pre">--post-command-error</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;ACTION&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-export-post-command-error" title="Permalink to this definition">#</a></dt>
<dd><p>Specify either <cite>continue</cite> or <cite>break</cite> for ACTION to control behavior when a post-command fails. If <cite>continue</cite>, osxphotos will log the error and continue processing. If <cite>break</cite>, osxphotos will stop processing any additional post-command commands for the current photo but will continue with the export. Without post-command-error, osxphotos will abort the export if a post-command encounters an error.</p>
<dl class="field-list simple">
<dt class="field-odd">Options<span class="colon">:</span></dt>
<dd class="field-odd"><p>continue | break</p>
</dd>
</dl>
</dd></dl>
<dl class="std option">
@ -2380,7 +2440,11 @@ to modify this behavior.</p>
</section>
<section id="osxphotos-import">
<h3>import<a class="headerlink" href="#osxphotos-import" title="Permalink to this heading">#</a></h3>
<p>Import photos and videos into Photos.</p>
<p>Import photos and videos into Photos. Photos will be imported into the
most recently opened Photos library.</p>
<p>Photos are imported one at a time thus the “Imports” album in Photos will show
a new import group for each photo imported. Batch import into a single import
group will be added in a future release.</p>
<div class="highlight-shell notranslate"><div class="highlight"><pre><span></span>osxphotos import <span class="o">[</span>OPTIONS<span class="o">]</span> <span class="o">[</span>FILES<span class="o">]</span>...
</pre></div>
</div>
@ -2829,6 +2893,12 @@ If the same query option is provided multiple times, they are treated as
<dd><p>Print output in JSON format.</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-query-count">
<span class="sig-name descname"><span class="pre">--count</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-query-count" title="Permalink to this definition">#</a></dt>
<dd><p>Print count of photos matching query and exit.</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-query-keyword">
<span class="sig-name descname"><span class="pre">--keyword</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;KEYWORD&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-query-keyword" title="Permalink to this definition">#</a></dt>
@ -3297,6 +3367,30 @@ If the same query option is provided multiple times, they are treated as
<dd><p>Search for syndicated photos that have not saved to the library</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-query-shared-moment">
<span class="sig-name descname"><span class="pre">--shared-moment</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-query-shared-moment" title="Permalink to this definition">#</a></dt>
<dd><p>Search for photos that are part of a shared moment</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-query-not-shared-moment">
<span class="sig-name descname"><span class="pre">--not-shared-moment</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-query-not-shared-moment" title="Permalink to this definition">#</a></dt>
<dd><p>Search for photos that are not part of a shared moment</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-query-shared-library">
<span class="sig-name descname"><span class="pre">--shared-library</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-query-shared-library" title="Permalink to this definition">#</a></dt>
<dd><p>Search for photos that are part of a shared library</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-query-not-shared-library">
<span class="sig-name descname"><span class="pre">--not-shared-library</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-query-not-shared-library" title="Permalink to this definition">#</a></dt>
<dd><p>Search for photos that are not part of a shared library</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-query-regex">
<span class="sig-name descname"><span class="pre">--regex</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;REGEX</span> <span class="pre">TEMPLATE&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-query-regex" title="Permalink to this definition">#</a></dt>
@ -3858,6 +3952,30 @@ If the same query option is provided multiple times, they are treated as
<dd><p>Search for syndicated photos that have not saved to the library</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-repl-shared-moment">
<span class="sig-name descname"><span class="pre">--shared-moment</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-repl-shared-moment" title="Permalink to this definition">#</a></dt>
<dd><p>Search for photos that are part of a shared moment</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-repl-not-shared-moment">
<span class="sig-name descname"><span class="pre">--not-shared-moment</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-repl-not-shared-moment" title="Permalink to this definition">#</a></dt>
<dd><p>Search for photos that are not part of a shared moment</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-repl-shared-library">
<span class="sig-name descname"><span class="pre">--shared-library</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-repl-shared-library" title="Permalink to this definition">#</a></dt>
<dd><p>Search for photos that are part of a shared library</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-repl-not-shared-library">
<span class="sig-name descname"><span class="pre">--not-shared-library</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-repl-not-shared-library" title="Permalink to this definition">#</a></dt>
<dd><p>Search for photos that are not part of a shared library</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-repl-regex">
<span class="sig-name descname"><span class="pre">--regex</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;REGEX</span> <span class="pre">TEMPLATE&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-repl-regex" title="Permalink to this definition">#</a></dt>
@ -4541,6 +4659,30 @@ two different computers, you can export the metadata to a shared folder.</p>
<dd><p>Search for syndicated photos that have not saved to the library</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-sync-shared-moment">
<span class="sig-name descname"><span class="pre">--shared-moment</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-sync-shared-moment" title="Permalink to this definition">#</a></dt>
<dd><p>Search for photos that are part of a shared moment</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-sync-not-shared-moment">
<span class="sig-name descname"><span class="pre">--not-shared-moment</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-sync-not-shared-moment" title="Permalink to this definition">#</a></dt>
<dd><p>Search for photos that are not part of a shared moment</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-sync-shared-library">
<span class="sig-name descname"><span class="pre">--shared-library</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-sync-shared-library" title="Permalink to this definition">#</a></dt>
<dd><p>Search for photos that are part of a shared library</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-sync-not-shared-library">
<span class="sig-name descname"><span class="pre">--not-shared-library</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-sync-not-shared-library" title="Permalink to this definition">#</a></dt>
<dd><p>Search for photos that are not part of a shared library</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-sync-regex">
<span class="sig-name descname"><span class="pre">--regex</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;REGEX</span> <span class="pre">TEMPLATE&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-sync-regex" title="Permalink to this definition">#</a></dt>
@ -4867,51 +5009,46 @@ See Timewarp Overview below for additional information.</p>
</section>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>Usage: python -m osxphotos [OPTIONS] COMMAND [ARGS]...
osxphotos: query and export your Photos library
osxphotos: the multi-tool for your Photos library
Options:
--db PHOTOS_LIBRARY_PATH Specify Photos database path. Path to Photos
library/database can be specified using either
--db or directly as PHOTOS_LIBRARY positional
argument. If neither --db or PHOTOS_LIBRARY
provided, will attempt to find the library to use
in the following order: 1. last opened library, 2.
system library, 3. ~/Pictures/Photos
Library.photoslibrary
--json Print output in JSON format.
-v, --version Show the version and exit.
-h, --help Show this message and exit.
-v, --version Show the version and exit.
-h, --help Show this message and exit.
Commands:
about Print information about osxphotos including license.
albums Print out albums found in the Photos library.
diff Compare two Photos databases and print out differences
docs Open osxphotos documentation in your browser.
dump Print list of all photos &amp; associated info from the Photos...
exiftool Run exiftool on previously exported files to update metadata.
export Export photos from the Photos database.
exportdb Utilities for working with the osxphotos export database
help Print help; for help on commands: help &lt;command&gt;.
import Import photos and videos into Photos.
info Print out descriptive info of the Photos library database.
inspect Interactively inspect photos selected in Photos.
install Install Python packages into the same environment as osxphotos
keywords Print out keywords found in the Photos library.
labels Print out image classification labels found in the Photos...
list Print list of Photos libraries found on the system.
orphans Find orphaned photos in a Photos library
persons Print out persons (faces) found in the Photos library.
places Print out places found in the Photos library.
query Query the Photos database using 1 or more search options; if...
repl Run interactive osxphotos REPL shell (useful for debugging,...
run Run a python file using same environment as osxphotos.
snap Create snapshot of Photos database to use with diff command
theme Manage osxphotos color themes.
timewarp Adjust date/time/timezone of photos in Apple Photos.
tutorial Display osxphotos tutorial.
uninstall Uninstall Python packages from the osxphotos environment
uuid Print out unique IDs (UUID) of photos selected in Photos
version Check for new version of osxphotos.
about Print information about osxphotos including license.
add-locations Add missing location data to photos in Photos.app using...
albums Print out albums found in the Photos library.
batch-edit Batch edit photo metadata such as title, description,...
diff Compare two Photos databases and print out differences
docs Open osxphotos documentation in your browser.
dump Print list of all photos &amp; associated info from the...
exiftool Run exiftool on previously exported files to update...
export Export photos from the Photos database.
exportdb Utilities for working with the osxphotos export database
help Print help; for help on commands: help &lt;command&gt;.
import Import photos and videos into Photos.
info Print out descriptive info of the Photos library database.
inspect Interactively inspect photos selected in Photos.
install Install Python packages into the same environment as...
keywords Print out keywords found in the Photos library.
labels Print out image classification labels found in the...
list Print list of Photos libraries found on the system.
orphans Find orphaned photos in a Photos library
persons Print out persons (faces) found in the Photos library.
places Print out places found in the Photos library.
query Query the Photos database using 1 or more search...
repl Run interactive osxphotos REPL shell (useful for...
run Run a python file using same environment as osxphotos.
show Show photo, album, or folder in Photos from UUID_OR_NAME
snap Create snapshot of Photos database to use with diff command
sync Sync metadata and albums between Photos libraries.
theme Manage osxphotos color themes.
timewarp Adjust date/time/timezone of photos in Apple Photos.
tutorial Display osxphotos tutorial.
uninstall Uninstall Python packages from the osxphotos environment
uuid Print out unique IDs (UUID) of photos selected in Photos
version Check for new version of osxphotos.
</pre></div>
</div>
</section>

View File

@ -4,7 +4,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="#" /><link rel="search" title="Search" href="search.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/><title>Index - osxphotos 0.60.4 documentation</title>
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/><title>Index - osxphotos 0.62.1 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@ -122,7 +122,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">osxphotos 0.60.4 documentation</div></a>
<a href="index.html"><div class="brand">osxphotos 0.62.1 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -145,7 +145,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
<span class="sidebar-brand-text">osxphotos 0.60.4 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.62.1 documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@ -159,6 +159,7 @@
<li class="toctree-l1"><a class="reference internal" href="cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
<li class="toctree-l1"><a class="reference internal" href="template_help.html">OSXPhotos Template System</a></li>
<li class="toctree-l1"><a class="reference internal" href="package_overview.html">OSXPhotos Python Package Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="API_README.html">OSXPhotos Python API</a></li>
<li class="toctree-l1"><a class="reference internal" href="reference.html">OSXPhotos Python Reference</a></li>
</ul>
@ -423,6 +424,13 @@
<ul>
<li><a href="cli.html#cmdoption-osxphotos-export-convert-to-jpeg">osxphotos-export command line option</a>
</li>
</ul></li>
<li>
--count
<ul>
<li><a href="cli.html#cmdoption-osxphotos-query-count">osxphotos-query command line option</a>
</li>
</ul></li>
<li>
@ -464,8 +472,6 @@
--db
<ul>
<li><a href="cli.html#cmdoption-osxphotos-library">osxphotos command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-albums-library">osxphotos-albums command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-batch-edit-library">osxphotos-batch-edit command line option</a>
@ -766,6 +772,13 @@
<li><a href="cli.html#cmdoption-osxphotos-orphans-export">osxphotos-orphans command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-sync-e">osxphotos-sync command line option</a>
</li>
</ul></li>
<li>
--export-aae
<ul>
<li><a href="cli.html#cmdoption-osxphotos-export-export-aae">osxphotos-export command line option</a>
</li>
</ul></li>
<li>
@ -1137,8 +1150,6 @@
--json
<ul>
<li><a href="cli.html#cmdoption-osxphotos-json">osxphotos command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-albums-json">osxphotos-albums command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-dump-json">osxphotos-dump command line option</a>
@ -1226,8 +1237,6 @@
--library
<ul>
<li><a href="cli.html#cmdoption-osxphotos-library">osxphotos command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-albums-library">osxphotos-albums command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-batch-edit-library">osxphotos-batch-edit command line option</a>
@ -1593,8 +1602,6 @@
<li><a href="cli.html#cmdoption-osxphotos-sync-not-favorite">osxphotos-sync command line option</a>
</li>
</ul></li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li>
--not-hdr
@ -1640,6 +1647,8 @@
<li><a href="cli.html#cmdoption-osxphotos-sync-not-in-album">osxphotos-sync command line option</a>
</li>
</ul></li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li>
--not-incloud
@ -1786,6 +1795,36 @@
<li><a href="cli.html#cmdoption-osxphotos-query-not-shared">osxphotos-query command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-repl-not-shared">osxphotos-repl command line option</a>
</li>
</ul></li>
<li>
--not-shared-library
<ul>
<li><a href="cli.html#cmdoption-osxphotos-add-locations-not-shared-library">osxphotos-add-locations command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-export-not-shared-library">osxphotos-export command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-query-not-shared-library">osxphotos-query command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-repl-not-shared-library">osxphotos-repl command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-sync-not-shared-library">osxphotos-sync command line option</a>
</li>
</ul></li>
<li>
--not-shared-moment
<ul>
<li><a href="cli.html#cmdoption-osxphotos-add-locations-not-shared-moment">osxphotos-add-locations command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-export-not-shared-moment">osxphotos-export command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-query-not-shared-moment">osxphotos-query command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-repl-not-shared-moment">osxphotos-repl command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-sync-not-shared-moment">osxphotos-sync command line option</a>
</li>
</ul></li>
<li>
@ -1974,6 +2013,13 @@
<ul>
<li><a href="cli.html#cmdoption-osxphotos-export-post-command">osxphotos-export command line option</a>
</li>
</ul></li>
<li>
--post-command-error
<ul>
<li><a href="cli.html#cmdoption-osxphotos-export-post-command-error">osxphotos-export command line option</a>
</li>
</ul></li>
<li>
@ -2242,6 +2288,36 @@
<li><a href="cli.html#cmdoption-osxphotos-query-shared">osxphotos-query command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-repl-shared">osxphotos-repl command line option</a>
</li>
</ul></li>
<li>
--shared-library
<ul>
<li><a href="cli.html#cmdoption-osxphotos-add-locations-shared-library">osxphotos-add-locations command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-export-shared-library">osxphotos-export command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-query-shared-library">osxphotos-query command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-repl-shared-library">osxphotos-repl command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-sync-shared-library">osxphotos-sync command line option</a>
</li>
</ul></li>
<li>
--shared-moment
<ul>
<li><a href="cli.html#cmdoption-osxphotos-add-locations-shared-moment">osxphotos-add-locations command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-export-shared-moment">osxphotos-export command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-query-shared-moment">osxphotos-query command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-repl-shared-moment">osxphotos-repl command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-sync-shared-moment">osxphotos-sync command line option</a>
</li>
</ul></li>
<li>
@ -2256,6 +2332,13 @@
<ul>
<li><a href="cli.html#cmdoption-osxphotos-export-sidecar-drop-ext">osxphotos-export command line option</a>
</li>
</ul></li>
<li>
--sidecar-template
<ul>
<li><a href="cli.html#cmdoption-osxphotos-export-sidecar-template">osxphotos-export command line option</a>
</li>
</ul></li>
<li>
@ -3026,10 +3109,16 @@
<li><a href="reference.html#osxphotos.QueryOptions.added_before">added_before (osxphotos.QueryOptions attribute)</a>
</li>
<li><a href="reference.html#osxphotos.QueryOptions.added_in_last">added_in_last (osxphotos.QueryOptions attribute)</a>
</li>
<li><a href="reference.html#osxphotos.PlaceInfo.address">address (osxphotos.PlaceInfo property)</a>
</li>
<li><a href="reference.html#osxphotos.PlaceInfo.address_str">address_str (osxphotos.PlaceInfo property)</a>
</li>
<li><a href="reference.html#osxphotos.ExifTool.addvalues">addvalues() (osxphotos.ExifTool method)</a>
</li>
<li><a href="reference.html#osxphotos.PhotoInfo.adjustments">adjustments (osxphotos.PhotoInfo property)</a>
</li>
<li><a href="reference.html#osxphotos.PhotoInfo.adjustments_path">adjustments_path (osxphotos.PhotoInfo property)</a>
</li>
<li><a href="reference.html#osxphotos.QueryOptions.album">album (osxphotos.QueryOptions attribute)</a>
</li>
@ -3052,11 +3141,11 @@
</li>
</ul></li>
<li><a href="reference.html#osxphotos.PhotosDB.albums_as_dict">albums_as_dict (osxphotos.PhotosDB property)</a>
</li>
<li><a href="reference.html#osxphotos.PhotosDB.albums_shared">albums_shared (osxphotos.PhotosDB property)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#osxphotos.PhotosDB.albums_shared">albums_shared (osxphotos.PhotosDB property)</a>
</li>
<li><a href="reference.html#osxphotos.PhotosDB.albums_shared_as_dict">albums_shared_as_dict (osxphotos.PhotosDB property)</a>
</li>
<li><a href="reference.html#osxphotos.AlbumSortOrder">AlbumSortOrder (class in osxphotos)</a>
@ -3076,6 +3165,8 @@
<ul>
<li><a href="reference.html#osxphotos.ExifTool.asdict">(osxphotos.ExifTool method)</a>
</li>
<li><a href="reference.html#osxphotos.FaceInfo.asdict">(osxphotos.FaceInfo method)</a>
</li>
<li><a href="reference.html#osxphotos.FolderInfo.asdict">(osxphotos.FolderInfo method)</a>
</li>
@ -3086,6 +3177,8 @@
<li><a href="reference.html#osxphotos.PersonInfo.asdict">(osxphotos.PersonInfo method)</a>
</li>
<li><a href="reference.html#osxphotos.PhotoInfo.asdict">(osxphotos.PhotoInfo method)</a>
</li>
<li><a href="reference.html#osxphotos.PlaceInfo.asdict">(osxphotos.PlaceInfo method)</a>
</li>
<li><a href="reference.html#osxphotos.ScoreInfo.asdict">(osxphotos.ScoreInfo method)</a>
</li>
@ -3139,6 +3232,8 @@
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#osxphotos.SearchInfo.camera">camera (osxphotos.SearchInfo property)</a>
</li>
<li><a href="reference.html#osxphotos.FaceInfo.center">center (osxphotos.FaceInfo property)</a>
</li>
<li><a href="reference.html#osxphotos.SearchInfo.city">city (osxphotos.SearchInfo property)</a>
</li>
@ -3167,6 +3262,8 @@
<li><a href="reference.html#osxphotos.FileUtilNoOp.copy">copy() (osxphotos.FileUtilNoOp class method)</a>
</li>
<li><a href="reference.html#osxphotos.SearchInfo.country">country (osxphotos.SearchInfo property)</a>
</li>
<li><a href="reference.html#osxphotos.PlaceInfo.country_code">country_code (osxphotos.PlaceInfo property)</a>
</li>
<li><a href="reference.html#osxphotos.ExportDB.create_file_record">create_file_record() (osxphotos.ExportDB method)</a>
</li>
@ -3282,14 +3379,16 @@
</li>
<li><a href="reference.html#osxphotos.PhotoTemplate.expand_variables_to_str">expand_variables_to_str() (osxphotos.PhotoTemplate method)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#osxphotos.PhotoExporter.export">export() (osxphotos.PhotoExporter method)</a>
<ul>
<li><a href="reference.html#osxphotos.PhotoInfo.export">(osxphotos.PhotoInfo method)</a>
</li>
</ul></li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#osxphotos.ExportOptions.export_aae">export_aae (osxphotos.ExportOptions attribute)</a>
</li>
<li><a href="reference.html#osxphotos.ExportOptions.export_as_hardlink">export_as_hardlink (osxphotos.ExportOptions attribute)</a>
</li>
<li>
@ -3338,7 +3437,11 @@
<li><a href="reference.html#osxphotos.PhotoInfo.face_info">(osxphotos.PhotoInfo property)</a>
</li>
</ul></li>
<li><a href="reference.html#osxphotos.FaceInfo.face_rect">face_rect() (osxphotos.FaceInfo method)</a>
</li>
<li><a href="reference.html#osxphotos.ExportOptions.face_regions">face_regions (osxphotos.ExportOptions attribute)</a>
</li>
<li><a href="reference.html#osxphotos.FaceInfo">FaceInfo (class in osxphotos)</a>
</li>
<li><a href="reference.html#osxphotos.PersonInfo.favorite">favorite (osxphotos.PersonInfo property)</a>
@ -3364,11 +3467,11 @@
</li>
</ul></li>
<li><a href="reference.html#osxphotos.FileUtil">FileUtil (class in osxphotos)</a>
</li>
<li><a href="reference.html#osxphotos.ExportOptions.fileutil">fileutil (osxphotos.ExportOptions attribute)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#osxphotos.ExportOptions.fileutil">fileutil (osxphotos.ExportOptions attribute)</a>
</li>
<li><a href="reference.html#osxphotos.FileUtilNoOp">FileUtilNoOp (class in osxphotos)</a>
</li>
<li><a href="reference.html#osxphotos.PhotoTemplate.filter_predicate">filter_predicate() (osxphotos.PhotoTemplate method)</a>
@ -3527,10 +3630,10 @@
<li><a href="reference.html#osxphotos.QueryOptions.incloud">(osxphotos.QueryOptions attribute)</a>
</li>
</ul></li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#osxphotos.ExportOptions.increment">increment (osxphotos.ExportOptions attribute)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#osxphotos.PhotoInfo.intrash">intrash (osxphotos.PhotoInfo property)</a>
</li>
<li><a href="reference.html#osxphotos.is_debug">is_debug() (in module osxphotos)</a>
@ -3538,6 +3641,8 @@
<li><a href="reference.html#osxphotos.QueryOptions.is_reference">is_reference (osxphotos.QueryOptions attribute)</a>
</li>
<li><a href="reference.html#osxphotos.PhotoInfo.iscloudasset">iscloudasset (osxphotos.PhotoInfo property)</a>
</li>
<li><a href="reference.html#osxphotos.PlaceInfo.ishome">ishome (osxphotos.PlaceInfo property)</a>
</li>
<li><a href="reference.html#osxphotos.PhotoInfo.ismissing">ismissing (osxphotos.PhotoInfo property)</a>
</li>
@ -3561,11 +3666,11 @@
</li>
<li><a href="reference.html#osxphotos.ExportOptions.jpeg_quality">jpeg_quality (osxphotos.ExportOptions attribute)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#osxphotos.ExifTool.json">json() (osxphotos.ExifTool method)</a>
<ul>
<li><a href="reference.html#osxphotos.FaceInfo.json">(osxphotos.FaceInfo method)</a>
</li>
<li><a href="reference.html#osxphotos.PersonInfo.json">(osxphotos.PersonInfo method)</a>
</li>
<li><a href="reference.html#osxphotos.PhotoInfo.json">(osxphotos.PhotoInfo method)</a>
@ -3671,10 +3776,10 @@
</li>
<li><a href="reference.html#osxphotos.QueryOptions.missing_bursts">missing_bursts (osxphotos.QueryOptions attribute)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#osxphotos.MomentInfo.modification_date">modification_date (osxphotos.MomentInfo property)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li>
module
@ -3689,6 +3794,10 @@
<li><a href="reference.html#osxphotos.SearchInfo.month">month (osxphotos.SearchInfo property)</a>
</li>
<li><a href="reference.html#osxphotos.QueryOptions.movies">movies (osxphotos.QueryOptions attribute)</a>
</li>
<li><a href="reference.html#osxphotos.FaceInfo.mpri_reg_rect">mpri_reg_rect (osxphotos.FaceInfo property)</a>
</li>
<li><a href="reference.html#osxphotos.FaceInfo.mwg_rs_area">mwg_rs_area (osxphotos.FaceInfo property)</a>
</li>
</ul></td>
</tr></table>
@ -3698,7 +3807,13 @@
<h2>N</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#osxphotos.QueryOptions.name">name (osxphotos.QueryOptions attribute)</a>
<li><a href="reference.html#osxphotos.PlaceInfo.name">name (osxphotos.PlaceInfo property)</a>
<ul>
<li><a href="reference.html#osxphotos.QueryOptions.name">(osxphotos.QueryOptions attribute)</a>
</li>
</ul></li>
<li><a href="reference.html#osxphotos.PlaceInfo.names">names (osxphotos.PlaceInfo property)</a>
</li>
<li><a href="reference.html#osxphotos.SearchInfo.neighborhoods">neighborhoods (osxphotos.SearchInfo property)</a>
</li>
@ -3751,6 +3866,10 @@
<li><a href="reference.html#osxphotos.QueryOptions.not_selfie">not_selfie (osxphotos.QueryOptions attribute)</a>
</li>
<li><a href="reference.html#osxphotos.QueryOptions.not_shared">not_shared (osxphotos.QueryOptions attribute)</a>
</li>
<li><a href="reference.html#osxphotos.QueryOptions.not_shared_library">not_shared_library (osxphotos.QueryOptions attribute)</a>
</li>
<li><a href="reference.html#osxphotos.QueryOptions.not_shared_moment">not_shared_moment (osxphotos.QueryOptions attribute)</a>
</li>
<li><a href="reference.html#osxphotos.QueryOptions.not_slow_mo">not_slow_mo (osxphotos.QueryOptions attribute)</a>
</li>
@ -3789,12 +3908,6 @@
osxphotos command line option
<ul>
<li><a href="cli.html#cmdoption-osxphotos-library">--db</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-json">--json</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-library">--library</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-v">--version</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-v">-v</a>
@ -3917,6 +4030,10 @@
<li><a href="cli.html#cmdoption-osxphotos-add-locations-not-selfie">--not-selfie</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-add-locations-not-shared">--not-shared</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-add-locations-not-shared-library">--not-shared-library</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-add-locations-not-shared-moment">--not-shared-moment</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-add-locations-not-slow-mo">--not-slow-mo</a>
</li>
@ -3951,6 +4068,10 @@
<li><a href="cli.html#cmdoption-osxphotos-add-locations-selfie">--selfie</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-add-locations-shared">--shared</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-add-locations-shared-library">--shared-library</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-add-locations-shared-moment">--shared-moment</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-add-locations-slow-mo">--slow-mo</a>
</li>
@ -4201,6 +4322,8 @@
<li><a href="cli.html#cmdoption-osxphotos-export-exiftool-option">--exiftool-option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-export-exiftool-path">--exiftool-path</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-export-export-aae">--export-aae</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-export-export-as-hardlink">--export-as-hardlink</a>
</li>
@ -4329,6 +4452,10 @@
<li><a href="cli.html#cmdoption-osxphotos-export-not-selfie">--not-selfie</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-export-not-shared">--not-shared</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-export-not-shared-library">--not-shared-library</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-export-not-shared-moment">--not-shared-moment</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-export-not-slow-mo">--not-slow-mo</a>
</li>
@ -4357,6 +4484,8 @@
<li><a href="cli.html#cmdoption-osxphotos-export-portrait">--portrait</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-export-post-command">--post-command</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-export-post-command-error">--post-command-error</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-export-post-function">--post-function</a>
</li>
@ -4393,10 +4522,16 @@
<li><a href="cli.html#cmdoption-osxphotos-export-selfie">--selfie</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-export-shared">--shared</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-export-shared-library">--shared-library</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-export-shared-moment">--shared-moment</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-export-sidecar">--sidecar</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-export-sidecar-drop-ext">--sidecar-drop-ext</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-export-sidecar-template">--sidecar-template</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-export-skip-bursts">--skip-bursts</a>
</li>
@ -4622,8 +4757,6 @@
<li><a href="cli.html#cmdoption-osxphotos-import-arg-FILES">FILES</a>
</li>
</ul></li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li>
osxphotos-info command line option
@ -4637,6 +4770,8 @@
<li><a href="cli.html#cmdoption-osxphotos-info-arg-PHOTOS_LIBRARY">PHOTOS_LIBRARY</a>
</li>
</ul></li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li>
osxphotos-inspect command line option
@ -4762,6 +4897,8 @@
<li><a href="cli.html#cmdoption-osxphotos-query-burst">--burst</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-query-cloudasset">--cloudasset</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-query-count">--count</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-query-library">--db</a>
</li>
@ -4874,6 +5011,10 @@
<li><a href="cli.html#cmdoption-osxphotos-query-not-selfie">--not-selfie</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-query-not-shared">--not-shared</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-query-not-shared-library">--not-shared-library</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-query-not-shared-moment">--not-shared-moment</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-query-not-slow-mo">--not-slow-mo</a>
</li>
@ -4912,6 +5053,10 @@
<li><a href="cli.html#cmdoption-osxphotos-query-selfie">--selfie</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-query-shared">--shared</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-query-shared-library">--shared-library</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-query-shared-moment">--shared-moment</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-query-slow-mo">--slow-mo</a>
</li>
@ -5065,6 +5210,10 @@
<li><a href="cli.html#cmdoption-osxphotos-repl-not-selfie">--not-selfie</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-repl-not-shared">--not-shared</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-repl-not-shared-library">--not-shared-library</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-repl-not-shared-moment">--not-shared-moment</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-repl-not-slow-mo">--not-slow-mo</a>
</li>
@ -5099,6 +5248,10 @@
<li><a href="cli.html#cmdoption-osxphotos-repl-selfie">--selfie</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-repl-shared">--shared</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-repl-shared-library">--shared-library</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-repl-shared-moment">--shared-moment</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-repl-slow-mo">--slow-mo</a>
</li>
@ -5283,6 +5436,10 @@
<li><a href="cli.html#cmdoption-osxphotos-sync-not-screenshot">--not-screenshot</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-sync-not-selfie">--not-selfie</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-sync-not-shared-library">--not-shared-library</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-sync-not-shared-moment">--not-shared-moment</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-sync-not-slow-mo">--not-slow-mo</a>
</li>
@ -5319,6 +5476,10 @@
<li><a href="cli.html#cmdoption-osxphotos-sync-selfie">--selfie</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-sync-s">--set</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-sync-shared-library">--shared-library</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-sync-shared-moment">--shared-moment</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-sync-slow-mo">--slow-mo</a>
</li>
@ -5554,9 +5715,11 @@
</li>
<li><a href="reference.html#osxphotos.QueryOptions.person">person (osxphotos.QueryOptions attribute)</a>
</li>
<li><a href="reference.html#osxphotos.PhotoInfo.person_info">person_info (osxphotos.PhotoInfo property)</a>
<li><a href="reference.html#osxphotos.FaceInfo.person_info">person_info (osxphotos.FaceInfo property)</a>
<ul>
<li><a href="reference.html#osxphotos.PhotoInfo.person_info">(osxphotos.PhotoInfo property)</a>
</li>
<li><a href="reference.html#osxphotos.PhotosDB.person_info">(osxphotos.PhotosDB property)</a>
</li>
</ul></li>
@ -5571,6 +5734,8 @@
</li>
</ul></li>
<li><a href="reference.html#osxphotos.PhotosDB.persons_as_dict">persons_as_dict (osxphotos.PhotosDB property)</a>
</li>
<li><a href="reference.html#osxphotos.FaceInfo.photo">photo (osxphotos.FaceInfo property)</a>
</li>
<li><a href="reference.html#osxphotos.AlbumInfo.photo_index">photo_index() (osxphotos.AlbumInfo method)</a>
</li>
@ -5590,10 +5755,10 @@
<li><a href="reference.html#osxphotos.QueryOptions.photos">(osxphotos.QueryOptions attribute)</a>
</li>
</ul></li>
<li><a href="reference.html#osxphotos.PhotosDB.photos">photos() (osxphotos.PhotosDB method)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#osxphotos.PhotosDB.photos">photos() (osxphotos.PhotosDB method)</a>
</li>
<li><a href="reference.html#osxphotos.PhotosDB.photos_by_uuid">photos_by_uuid() (osxphotos.PhotosDB method)</a>
</li>
<li>
@ -5630,6 +5795,8 @@
<li><a href="reference.html#osxphotos.PhotoTemplate">PhotoTemplate (class in osxphotos)</a>
</li>
<li><a href="reference.html#osxphotos.ExifTool.pid">pid (osxphotos.ExifTool property)</a>
</li>
<li><a href="reference.html#osxphotos.FaceInfo.pitch">pitch (osxphotos.FaceInfo property)</a>
</li>
<li><a href="reference.html#osxphotos.MomentInfo.pk">pk (osxphotos.MomentInfo property)</a>
</li>
@ -5702,10 +5869,10 @@
</li>
<li><a href="reference.html#osxphotos.PhotoTemplate.render">render() (osxphotos.PhotoTemplate method)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#osxphotos.ExportOptions.render_options">render_options (osxphotos.ExportOptions attribute)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#osxphotos.PhotoInfo.render_template">render_template() (osxphotos.PhotoInfo method)</a>
</li>
<li><a href="reference.html#osxphotos.ExportOptions.replace_keywords">replace_keywords (osxphotos.ExportOptions attribute)</a>
@ -5713,6 +5880,10 @@
<li><a href="reference.html#osxphotos.ExportOptions.rich">rich (osxphotos.ExportOptions attribute)</a>
</li>
<li><a href="reference.html#osxphotos.FileUtilNoOp.rmdir">rmdir() (osxphotos.FileUtilNoOp class method)</a>
</li>
<li><a href="reference.html#osxphotos.FaceInfo.roll">roll (osxphotos.FaceInfo property)</a>
</li>
<li><a href="reference.html#osxphotos.FaceInfo.roll_pitch_yaw">roll_pitch_yaw() (osxphotos.FaceInfo method)</a>
</li>
<li><a href="reference.html#osxphotos.ExifTool.run_commands">run_commands() (osxphotos.ExifTool method)</a>
</li>
@ -5765,18 +5936,38 @@
<li><a href="reference.html#osxphotos.ExportDB.set_photoinfo_for_uuid">set_photoinfo_for_uuid() (osxphotos.ExportDB method)</a>
</li>
<li><a href="reference.html#osxphotos.ExifTool.setvalue">setvalue() (osxphotos.ExifTool method)</a>
</li>
<li><a href="reference.html#osxphotos.PhotoInfo.share_info">share_info (osxphotos.PhotoInfo property)</a>
</li>
<li><a href="reference.html#osxphotos.PhotoInfo.share_participants">share_participants (osxphotos.PhotoInfo property)</a>
</li>
<li><a href="reference.html#osxphotos.PhotoInfo.shared">shared (osxphotos.PhotoInfo property)</a>
<ul>
<li><a href="reference.html#osxphotos.QueryOptions.shared">(osxphotos.QueryOptions attribute)</a>
</li>
</ul></li>
<li><a href="reference.html#osxphotos.PhotoInfo.shared_library">shared_library (osxphotos.PhotoInfo property)</a>
<ul>
<li><a href="reference.html#osxphotos.QueryOptions.shared_library">(osxphotos.QueryOptions attribute)</a>
</li>
</ul></li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#osxphotos.PhotoInfo.shared_moment">shared_moment (osxphotos.PhotoInfo property)</a>
<ul>
<li><a href="reference.html#osxphotos.QueryOptions.shared_moment">(osxphotos.QueryOptions attribute)</a>
</li>
</ul></li>
<li><a href="reference.html#osxphotos.PhotoInfo.shared_moment_info">shared_moment_info (osxphotos.PhotoInfo property)</a>
</li>
<li><a href="reference.html#osxphotos.ExportOptions.sidecar">sidecar (osxphotos.ExportOptions attribute)</a>
</li>
<li><a href="reference.html#osxphotos.ExportOptions.sidecar_drop_ext">sidecar_drop_ext (osxphotos.ExportOptions attribute)</a>
</li>
<li><a href="reference.html#osxphotos.FaceInfo.size_pixels">size_pixels (osxphotos.FaceInfo property)</a>
</li>
<li><a href="reference.html#osxphotos.PhotoInfo.slow_mo">slow_mo (osxphotos.PhotoInfo property)</a>
@ -5973,6 +6164,10 @@
<section id="Y" class="genindex-section">
<h2>Y</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#osxphotos.FaceInfo.yaw">yaw (osxphotos.FaceInfo property)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#osxphotos.QueryOptions.year">year (osxphotos.QueryOptions attribute)</a>

View File

@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="OSXPhotos" href="overview.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
<title>osxphotos 0.60.4 documentation</title>
<title>osxphotos 0.62.1 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@ -124,7 +124,7 @@
</label>
</div>
<div class="header-center">
<a href="#"><div class="brand">osxphotos 0.60.4 documentation</div></a>
<a href="#"><div class="brand">osxphotos 0.62.1 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -147,7 +147,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="#">
<span class="sidebar-brand-text">osxphotos 0.60.4 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.62.1 documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@ -161,6 +161,7 @@
<li class="toctree-l1"><a class="reference internal" href="cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
<li class="toctree-l1"><a class="reference internal" href="template_help.html">OSXPhotos Template System</a></li>
<li class="toctree-l1"><a class="reference internal" href="package_overview.html">OSXPhotos Python Package Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="API_README.html">OSXPhotos Python API</a></li>
<li class="toctree-l1"><a class="reference internal" href="reference.html">OSXPhotos Python Reference</a></li>
</ul>
@ -282,6 +283,306 @@
<li class="toctree-l2"><a class="reference internal" href="package_overview.html#using-the-osxphotos-cli-to-run-python-code">Using the osxphotos CLI to run python code</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="API_README.html">OSXPhotos Python API</a><ul>
<li class="toctree-l2"><a class="reference internal" href="API_README.html#table-of-contents">Table of Contents</a></li>
<li class="toctree-l2"><a class="reference internal" href="API_README.html#id1">Example uses of the Python package</a><ul>
<li class="toctree-l3"><a class="reference internal" href="API_README.html#print-filename-date-created-title-and-keywords-for-all-photos-in-a-library">Print filename, date created, title, and keywords for all photos in a library</a></li>
<li class="toctree-l3"><a class="reference internal" href="API_README.html#building-simple-command-line-tools">Building simple command line tools</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="API_README.html#concurrency">Concurrency</a></li>
<li class="toctree-l2"><a class="reference internal" href="API_README.html#id6">Package Interface</a><ul>
<li class="toctree-l3"><a class="reference internal" href="API_README.html#a-name-photosdb-photosdb-a"><span class="raw-html-m2r"><a name="photosdb">PhotosDB</a></span></a><ul>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#read-a-photos-library-database">Read a Photos library database</a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#open-the-default-last-opened-photos-library">Open the default (last opened) Photos library</a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#open-system-photos-library">Open System Photos library</a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#open-a-specific-photos-library">Open a specific Photos library</a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-photosdbphotos-photos-keywords-none-uuid-none-persons-none-albums-none-images-true-movies-true-from-date-none-to-date-none-intrash-false-a"><span class="raw-html-m2r"><A name="photosdbphotos"></span><code class="docutils literal notranslate"><span class="pre">photos(keywords=None,</span> <span class="pre">uuid=None,</span> <span class="pre">persons=None,</span> <span class="pre">albums=None,</span> <span class="pre">images=True,</span> <span class="pre">movies=True,</span> <span class="pre">from_date=None,</span> <span class="pre">to_date=None,</span> <span class="pre">intrash=False)</span></code>&lt;/a&gt;</a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-getphoto-get-photo-uuid-a"><span class="raw-html-m2r"><a name="getphoto"></span><code class="docutils literal notranslate"><span class="pre">get_photo(uuid)</span></code>&lt;/A&gt;</a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-photosdb-query-query-options-queryoptions-list-photoinfo-a"><span class="raw-html-m2r"><A name="photosdb_query"></span><code class="docutils literal notranslate"><span class="pre">query(options:</span> <span class="pre">QueryOptions)</span> <span class="pre">-&gt;</span> <span class="pre">List[PhotoInfo]:</span></code>&lt;/a&gt;</a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-photosdb-keywords-keywords-a"><span class="raw-html-m2r"><a name="photosdb_keywords">`keywords`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-photosdb-albuminfo-album-info-a"><span class="raw-html-m2r"><a name="photosdb_albuminfo">`album_info`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-photosdb-albums-albums-a"><span class="raw-html-m2r"><a name="photosdb_albums">`albums`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#albums-shared"><code class="docutils literal notranslate"><span class="pre">albums_shared</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-photosdb-import-info-import-info-a"><span class="raw-html-m2r"><a name = "photosdb_import_info">`import_info`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-photosdb-project-info-project-info-a"><span class="raw-html-m2r"><a name="photosdb_project_info">`project_info`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-photosdb-moment-info-moment-info-a"><span class="raw-html-m2r"><a name="photosdb_moment_info">`moment_info`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-photosdb-folder-info-folder-info-a"><span class="raw-html-m2r"><a name="photosdb_folder_info">`folder_info`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-photosdb-folders-folders-a"><span class="raw-html-m2r"><a name="photosdb_folders">`folders`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-photosdb-persons-persons-a"><span class="raw-html-m2r"><a name="photosdb_persons">`persons`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-photosdb-person-info-person-info-a"><span class="raw-html-m2r"><a name="photosdb_person_info">`person_info`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#keywords-as-dict"><code class="docutils literal notranslate"><span class="pre">keywords_as_dict</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#persons-as-dict"><code class="docutils literal notranslate"><span class="pre">persons_as_dict</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#albums-as-dict"><code class="docutils literal notranslate"><span class="pre">albums_as_dict</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#albums-shared-as-dict"><code class="docutils literal notranslate"><span class="pre">albums_shared_as_dict</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-photosdb-labels-labels-a"><span class="raw-html-m2r"><a name="photosdb_labels">`labels`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-photosdb-labels-normalized-labels-normalized-a"><span class="raw-html-m2r"><a name="photosdb_labels_normalized">`labels_normalized`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#labels-as-dict"><code class="docutils literal notranslate"><span class="pre">labels_as_dict</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id19"><code class="docutils literal notranslate"><span class="pre">labels_normalized_as_dict</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#library-path"><code class="docutils literal notranslate"><span class="pre">library_path</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#db-path"><code class="docutils literal notranslate"><span class="pre">db_path</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#db-version"><code class="docutils literal notranslate"><span class="pre">db_version</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#photos-version"><code class="docutils literal notranslate"><span class="pre">photos_version</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#get-db-connection"><code class="docutils literal notranslate"><span class="pre">get_db_connection()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#execute-sql"><code class="docutils literal notranslate"><span class="pre">execute(sql)</span></code></a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="API_README.html#id21">QueryOptions</a><ul>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#attributes">Attributes</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="API_README.html#a-name-photoinfo-photoinfo-a"><span class="raw-html-m2r"><a name="photoinfo">PhotoInfo</a></span></a><ul>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#uuid"><code class="docutils literal notranslate"><span class="pre">uuid</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#filename"><code class="docutils literal notranslate"><span class="pre">filename</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id22"><code class="docutils literal notranslate"><span class="pre">original_filename</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#date"><code class="docutils literal notranslate"><span class="pre">date</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#date-added"><code class="docutils literal notranslate"><span class="pre">date_added</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#date-modified"><code class="docutils literal notranslate"><span class="pre">date_modified</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#description"><code class="docutils literal notranslate"><span class="pre">description</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#title"><code class="docutils literal notranslate"><span class="pre">title</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#keywords"><code class="docutils literal notranslate"><span class="pre">keywords</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id24"><code class="docutils literal notranslate"><span class="pre">albums</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id26"><code class="docutils literal notranslate"><span class="pre">album_info</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#import-info"><code class="docutils literal notranslate"><span class="pre">import_info</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#project-info"><code class="docutils literal notranslate"><span class="pre">project_info</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#persons"><code class="docutils literal notranslate"><span class="pre">persons</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-photoinfo-personinfo-person-info-a"><span class="raw-html-m2r"><a name="photoinfo_personinfo">`person_info`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-photooinfo-faceinfo-face-info-a"><span class="raw-html-m2r"><a name="photooinfo_faceinfo">`face_info`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#path"><code class="docutils literal notranslate"><span class="pre">path</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#path-edited"><code class="docutils literal notranslate"><span class="pre">path_edited</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#path-derivatives"><code class="docutils literal notranslate"><span class="pre">path_derivatives</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#path-raw"><code class="docutils literal notranslate"><span class="pre">path_raw</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#has-raw"><code class="docutils literal notranslate"><span class="pre">has_raw</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#israw"><code class="docutils literal notranslate"><span class="pre">israw</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#raw-original"><code class="docutils literal notranslate"><span class="pre">raw_original</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#height"><code class="docutils literal notranslate"><span class="pre">height</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#width"><code class="docutils literal notranslate"><span class="pre">width</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#orientation"><code class="docutils literal notranslate"><span class="pre">orientation</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id38"><code class="docutils literal notranslate"><span class="pre">original_height</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id40"><code class="docutils literal notranslate"><span class="pre">original_width</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id42"><code class="docutils literal notranslate"><span class="pre">original_orientation</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#original-filesize"><code class="docutils literal notranslate"><span class="pre">original_filesize</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id44"><code class="docutils literal notranslate"><span class="pre">ismissing</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id46"><code class="docutils literal notranslate"><span class="pre">hasadjustments</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#adjustments"><code class="docutils literal notranslate"><span class="pre">adjustments</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#external-edit"><code class="docutils literal notranslate"><span class="pre">external_edit</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#favorite"><code class="docutils literal notranslate"><span class="pre">favorite</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id48"><code class="docutils literal notranslate"><span class="pre">hidden</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#visible"><code class="docutils literal notranslate"><span class="pre">visible</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#intrash"><code class="docutils literal notranslate"><span class="pre">intrash</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#date-trashed"><code class="docutils literal notranslate"><span class="pre">date_trashed</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#location"><code class="docutils literal notranslate"><span class="pre">location</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#place"><code class="docutils literal notranslate"><span class="pre">place</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id50"><code class="docutils literal notranslate"><span class="pre">shared</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#owner"><code class="docutils literal notranslate"><span class="pre">owner</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#comments"><code class="docutils literal notranslate"><span class="pre">comments</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#likes"><code class="docutils literal notranslate"><span class="pre">likes</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#isreference"><code class="docutils literal notranslate"><span class="pre">isreference</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#isphoto"><code class="docutils literal notranslate"><span class="pre">isphoto</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#ismovie"><code class="docutils literal notranslate"><span class="pre">ismovie</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#iscloudasset"><code class="docutils literal notranslate"><span class="pre">iscloudasset</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id61"><code class="docutils literal notranslate"><span class="pre">incloud</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#syndicated"><code class="docutils literal notranslate"><span class="pre">syndicated</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#saved-to-library"><code class="docutils literal notranslate"><span class="pre">saved_to_library</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#shared-moment"><code class="docutils literal notranslate"><span class="pre">shared_moment</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#shared-library"><code class="docutils literal notranslate"><span class="pre">shared_library</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#uti"><code class="docutils literal notranslate"><span class="pre">uti</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#uti-original"><code class="docutils literal notranslate"><span class="pre">uti_original</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#uti-edited"><code class="docutils literal notranslate"><span class="pre">uti_edited</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#uti-raw"><code class="docutils literal notranslate"><span class="pre">uti_raw</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id64"><code class="docutils literal notranslate"><span class="pre">burst</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#burst-selected"><code class="docutils literal notranslate"><span class="pre">burst_selected</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#burst-key"><code class="docutils literal notranslate"><span class="pre">burst_key</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#burst-default-pick"><code class="docutils literal notranslate"><span class="pre">burst_default_pick</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id65"><code class="docutils literal notranslate"><span class="pre">burst_photos</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id67"><code class="docutils literal notranslate"><span class="pre">burst_albums</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id70"><code class="docutils literal notranslate"><span class="pre">burst_album_info</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#live-photo"><code class="docutils literal notranslate"><span class="pre">live_photo</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id74"><code class="docutils literal notranslate"><span class="pre">path_live_photo</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#path-edited-live-photo"><code class="docutils literal notranslate"><span class="pre">path_edited_live_photo</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#portrait"><code class="docutils literal notranslate"><span class="pre">portrait</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#hdr"><code class="docutils literal notranslate"><span class="pre">hdr</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#selfie"><code class="docutils literal notranslate"><span class="pre">selfie</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#time-lapse"><code class="docutils literal notranslate"><span class="pre">time_lapse</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#panorama"><code class="docutils literal notranslate"><span class="pre">panorama</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#slow-mo"><code class="docutils literal notranslate"><span class="pre">slow_mo</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id78"><code class="docutils literal notranslate"><span class="pre">labels</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id80"><code class="docutils literal notranslate"><span class="pre">labels_normalized</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-photoinfo-searchinfo-search-info-a"><span class="raw-html-m2r"><a name="photoinfo_searchinfo">`search_info`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-photoinfo-search-info-normalized-search-info-normalized-a"><span class="raw-html-m2r"><a name="photoinfo_search_info_normalized">`search_info_normalized`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-photoinfo-exif-info-exif-info-a"><span class="raw-html-m2r"><a name="photoinfo_exif_info">`exif_info`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-photoinfo-exiftool-exiftool-a"><span class="raw-html-m2r"><a name="photoinfo_exiftool">`exiftool`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#score"><code class="docutils literal notranslate"><span class="pre">score</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#duplicates"><code class="docutils literal notranslate"><span class="pre">duplicates</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#cloud-guid"><code class="docutils literal notranslate"><span class="pre">cloud_guid</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#cloud-owner-hashed-id"><code class="docutils literal notranslate"><span class="pre">cloud_owner_hashed_id</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#fingerprint"><code class="docutils literal notranslate"><span class="pre">fingerprint</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#hexdigest"><code class="docutils literal notranslate"><span class="pre">hexdigest</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#tables"><code class="docutils literal notranslate"><span class="pre">tables()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#json"><code class="docutils literal notranslate"><span class="pre">json()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#asdict"><code class="docutils literal notranslate"><span class="pre">asdict()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#export"><code class="docutils literal notranslate"><span class="pre">export()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-rendertemplate-render-template-template-str-options-none-a"><span class="raw-html-m2r"><a name="rendertemplate">`render_template(template_str, options=None)`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-photoinfo-detected-text-detected-text-confidence-threshold-text-detection-confidence-threshold-a"><span class="raw-html-m2r"><a name="photoinfo_detected_text">`detected_text(confidence_threshold=TEXT_DETECTION_CONFIDENCE_THRESHOLD)`</a></span></a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="API_README.html#id94">ExifInfo</a></li>
<li class="toctree-l3"><a class="reference internal" href="API_README.html#id95">AlbumInfo</a><ul>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id96"><code class="docutils literal notranslate"><span class="pre">uuid</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id97"><code class="docutils literal notranslate"><span class="pre">title</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-albumphotos-photos-a"><span class="raw-html-m2r"><a name="albumphotos">`photos`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#creation-date"><code class="docutils literal notranslate"><span class="pre">creation_date</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#start-date"><code class="docutils literal notranslate"><span class="pre">start_date</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#end-date"><code class="docutils literal notranslate"><span class="pre">end_date</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#folder-list"><code class="docutils literal notranslate"><span class="pre">folder_list</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#folder-names"><code class="docutils literal notranslate"><span class="pre">folder_names</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#parent"><code class="docutils literal notranslate"><span class="pre">parent</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id101"><code class="docutils literal notranslate"><span class="pre">owner</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id104"><code class="docutils literal notranslate"><span class="pre">asdict()</span></code></a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="API_README.html#id105">ImportInfo</a><ul>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id106"><code class="docutils literal notranslate"><span class="pre">uuid</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-importphotos-photos-a"><span class="raw-html-m2r"><a name="importphotos">`photos`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id108"><code class="docutils literal notranslate"><span class="pre">creation_date</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id109"><code class="docutils literal notranslate"><span class="pre">start_date</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id110"><code class="docutils literal notranslate"><span class="pre">end_date</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id111"><code class="docutils literal notranslate"><span class="pre">asdict()</span></code></a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="API_README.html#id112">ProjectInfo</a><ul>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id113"><code class="docutils literal notranslate"><span class="pre">uuid</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id114"><code class="docutils literal notranslate"><span class="pre">title</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-projectphotos-photos-a"><span class="raw-html-m2r"><a name="projectphotos">`photos`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id116"><code class="docutils literal notranslate"><span class="pre">creation_date</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id117"><code class="docutils literal notranslate"><span class="pre">asdict()</span></code></a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="API_README.html#id118">MomentInfo</a><ul>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#pk"><code class="docutils literal notranslate"><span class="pre">pk</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id119"><code class="docutils literal notranslate"><span class="pre">location</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id120"><code class="docutils literal notranslate"><span class="pre">title</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#subtitle"><code class="docutils literal notranslate"><span class="pre">subtitle</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id121"><code class="docutils literal notranslate"><span class="pre">start_date</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id122"><code class="docutils literal notranslate"><span class="pre">end_date</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id123"><code class="docutils literal notranslate"><span class="pre">date</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#modification-date"><code class="docutils literal notranslate"><span class="pre">modification_date</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id124"><code class="docutils literal notranslate"><span class="pre">photos</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id125"><code class="docutils literal notranslate"><span class="pre">asdict()</span></code></a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="API_README.html#id126">FolderInfo</a><ul>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id127"><code class="docutils literal notranslate"><span class="pre">uuid</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id128"><code class="docutils literal notranslate"><span class="pre">title</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-folderinfo-album-info-album-info-a"><span class="raw-html-m2r"><a name="folderinfo_album_info">`album_info`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-folderinfo-album-info-shared-album-info-shared-a"><span class="raw-html-m2r"><a name="folderinfo_album_info_shared">`album_info_shared`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#subfolders"><code class="docutils literal notranslate"><span class="pre">subfolders</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id132"><code class="docutils literal notranslate"><span class="pre">parent</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#sort-order"><code class="docutils literal notranslate"><span class="pre">sort_order</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#photo-index-photo"><code class="docutils literal notranslate"><span class="pre">photo_index(photo)</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id134"><code class="docutils literal notranslate"><span class="pre">asdict()</span></code></a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="API_README.html#id135">PlaceInfo</a><ul>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#ishome"><code class="docutils literal notranslate"><span class="pre">ishome</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#name"><code class="docutils literal notranslate"><span class="pre">name</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#names"><code class="docutils literal notranslate"><span class="pre">names</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#country-code"><code class="docutils literal notranslate"><span class="pre">country_code</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#address-str"><code class="docutils literal notranslate"><span class="pre">address_str</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#address"><code class="docutils literal notranslate"><span class="pre">address</span></code></a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="API_README.html#id136">ScoreInfo</a></li>
<li class="toctree-l3"><a class="reference internal" href="API_README.html#id137">SearchInfo</a><ul>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id138"><code class="docutils literal notranslate"><span class="pre">labels</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#place-names"><code class="docutils literal notranslate"><span class="pre">place_names</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#streets"><code class="docutils literal notranslate"><span class="pre">streets</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#neighborhoods"><code class="docutils literal notranslate"><span class="pre">neighborhoods</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#locality-names"><code class="docutils literal notranslate"><span class="pre">locality_names</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#city"><code class="docutils literal notranslate"><span class="pre">city</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#state"><code class="docutils literal notranslate"><span class="pre">state</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#state-abbreviation"><code class="docutils literal notranslate"><span class="pre">state_abbreviation</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#country"><code class="docutils literal notranslate"><span class="pre">country</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#month"><code class="docutils literal notranslate"><span class="pre">month</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#year"><code class="docutils literal notranslate"><span class="pre">year</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#bodies-of-water"><code class="docutils literal notranslate"><span class="pre">bodies_of_water</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#holidays"><code class="docutils literal notranslate"><span class="pre">holidays</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#activities"><code class="docutils literal notranslate"><span class="pre">activities</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#season"><code class="docutils literal notranslate"><span class="pre">season</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#venues"><code class="docutils literal notranslate"><span class="pre">venues</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#venue-types"><code class="docutils literal notranslate"><span class="pre">venue_types</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#media-types"><code class="docutils literal notranslate"><span class="pre">media_types</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#all"><code class="docutils literal notranslate"><span class="pre">all</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id139"><code class="docutils literal notranslate"><span class="pre">asdict()</span></code></a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="API_README.html#id140">PersonInfo</a><ul>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id141"><code class="docutils literal notranslate"><span class="pre">name</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#display-name"><code class="docutils literal notranslate"><span class="pre">display_name</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id142"><code class="docutils literal notranslate"><span class="pre">uuid</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#keyphoto"><code class="docutils literal notranslate"><span class="pre">keyphoto</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#facecount"><code class="docutils literal notranslate"><span class="pre">facecount</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-personphotos-photos-a"><span class="raw-html-m2r"><a name="personphotos">`photos`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-personfaceinfo-face-info-a"><span class="raw-html-m2r"><a name="personfaceinfo">`face_info`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-personfavorite-favorite-a"><span class="raw-html-m2r"><a name="personfavorite">`favorite`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-personsortorder-sort-order-a"><span class="raw-html-m2r"><a name="personsortorder">`sort_order`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id144"><code class="docutils literal notranslate"><span class="pre">json()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id145"><code class="docutils literal notranslate"><span class="pre">asdict()</span></code></a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="API_README.html#id146">FaceInfo</a><ul>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-faceinfo-uuid-uuid-a"><span class="raw-html-m2r"><a name="faceinfo_uuid">`uuid`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-faceinfo-name-name-a"><span class="raw-html-m2r"><a name="faceinfo_name">`name`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#asset-uuid"><code class="docutils literal notranslate"><span class="pre">asset_uuid</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-faceinfo-person-info-person-info-a"><span class="raw-html-m2r"><a name="faceinfo_person_info">`person_info`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-faceinfo-photo-photo-a"><span class="raw-html-m2r"><a name="faceinfo_photo">`photo`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#mwg-rs-area"><code class="docutils literal notranslate"><span class="pre">mwg_rs_area</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#mpri-reg-rect"><code class="docutils literal notranslate"><span class="pre">mpri_reg_rect</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#face-rect"><code class="docutils literal notranslate"><span class="pre">face_rect()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#center"><code class="docutils literal notranslate"><span class="pre">center</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#size-pixels"><code class="docutils literal notranslate"><span class="pre">size_pixels</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#roll-pitch-yaw"><code class="docutils literal notranslate"><span class="pre">roll_pitch_yaw()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#roll">roll</a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#pitch">pitch</a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#yaw">yaw</a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#additional-properties"><code class="docutils literal notranslate"><span class="pre">Additional</span> <span class="pre">properties</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-faceinfo-asdict-asdict-a"><span class="raw-html-m2r"><a name="faceinfo_asdict">`asdict()`</a></span></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#a-name-faceinfo-json-json-a"><span class="raw-html-m2r"><a name="faceinfo_json">`json()`</a></span></a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="API_README.html#id149">CommentInfo</a></li>
<li class="toctree-l3"><a class="reference internal" href="API_README.html#id150">LikeInfo</a></li>
<li class="toctree-l3"><a class="reference internal" href="API_README.html#id151">AdjustmentsInfo</a></li>
<li class="toctree-l3"><a class="reference internal" href="API_README.html#id152">PhotoTables</a></li>
<li class="toctree-l3"><a class="reference internal" href="API_README.html#id153">Raw Photos</a><ul>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#raw-related-attributes">Raw-Related Attributes</a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#example">Example</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="API_README.html#id162">Template System</a></li>
<li class="toctree-l3"><a class="reference internal" href="API_README.html#a-name-exiftoolexiftool-exiftool-a"><span class="raw-html-m2r"><a name="exiftoolExifTool">ExifTool</a></span></a><ul>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#exiftool-methods">ExifTool methods</a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#implementation-note">Implementation Note</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="API_README.html#a-name-photoexporter-photoexporter-a"><span class="raw-html-m2r"><a name="photoexporter">PhotoExporter</a></span></a><ul>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#export-dest-filename-none-options-optional-exportoptions-none-exportresults"><code class="docutils literal notranslate"><span class="pre">export(dest,</span> <span class="pre">filename=None,</span> <span class="pre">options:</span> <span class="pre">Optional[ExportOptions]=None)</span> <span class="pre">-&gt;</span> <span class="pre">ExportResults</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#exportoptions"><code class="docutils literal notranslate"><span class="pre">ExportOptions</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#exportresults"><code class="docutils literal notranslate"><span class="pre">ExportResults</span></code></a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="API_README.html#a-name-textdetection-text-detection-a"><span class="raw-html-m2r"><a name="textdetection">Text Detection</a></span></a></li>
<li class="toctree-l3"><a class="reference internal" href="API_README.html#id165">Utility Functions</a><ul>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id166"><code class="docutils literal notranslate"><span class="pre">get_system_library_path()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#id167"><code class="docutils literal notranslate"><span class="pre">get_last_library_path()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="API_README.html#list-photo-libraries"><code class="docutils literal notranslate"><span class="pre">list_photo_libraries()</span></code></a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="API_README.html#id168">Additional Examples</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="reference.html">OSXPhotos Python Reference</a><ul>
<li class="toctree-l2"><a class="reference internal" href="reference.html#osxphotos.AlbumInfo"><code class="docutils literal notranslate"><span class="pre">AlbumInfo</span></code></a><ul>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.AlbumInfo.asdict"><code class="docutils literal notranslate"><span class="pre">AlbumInfo.asdict()</span></code></a></li>
@ -361,6 +662,7 @@
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.ExportOptions.render_options"><code class="docutils literal notranslate"><span class="pre">ExportOptions.render_options</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.ExportOptions.replace_keywords"><code class="docutils literal notranslate"><span class="pre">ExportOptions.replace_keywords</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.ExportOptions.rich"><code class="docutils literal notranslate"><span class="pre">ExportOptions.rich</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.ExportOptions.export_aae"><code class="docutils literal notranslate"><span class="pre">ExportOptions.export_aae</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.ExportOptions.sidecar_drop_ext"><code class="docutils literal notranslate"><span class="pre">ExportOptions.sidecar_drop_ext</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.ExportOptions.sidecar"><code class="docutils literal notranslate"><span class="pre">ExportOptions.sidecar</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.ExportOptions.strip"><code class="docutils literal notranslate"><span class="pre">ExportOptions.strip</span></code></a></li>
@ -384,6 +686,22 @@
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.ExportResults.datetime"><code class="docutils literal notranslate"><span class="pre">ExportResults.datetime</span></code></a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="reference.html#osxphotos.FaceInfo"><code class="docutils literal notranslate"><span class="pre">FaceInfo</span></code></a><ul>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.FaceInfo.asdict"><code class="docutils literal notranslate"><span class="pre">FaceInfo.asdict()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.FaceInfo.center"><code class="docutils literal notranslate"><span class="pre">FaceInfo.center</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.FaceInfo.face_rect"><code class="docutils literal notranslate"><span class="pre">FaceInfo.face_rect()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.FaceInfo.json"><code class="docutils literal notranslate"><span class="pre">FaceInfo.json()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.FaceInfo.mpri_reg_rect"><code class="docutils literal notranslate"><span class="pre">FaceInfo.mpri_reg_rect</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.FaceInfo.mwg_rs_area"><code class="docutils literal notranslate"><span class="pre">FaceInfo.mwg_rs_area</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.FaceInfo.person_info"><code class="docutils literal notranslate"><span class="pre">FaceInfo.person_info</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.FaceInfo.photo"><code class="docutils literal notranslate"><span class="pre">FaceInfo.photo</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.FaceInfo.pitch"><code class="docutils literal notranslate"><span class="pre">FaceInfo.pitch</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.FaceInfo.roll"><code class="docutils literal notranslate"><span class="pre">FaceInfo.roll</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.FaceInfo.roll_pitch_yaw"><code class="docutils literal notranslate"><span class="pre">FaceInfo.roll_pitch_yaw()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.FaceInfo.size_pixels"><code class="docutils literal notranslate"><span class="pre">FaceInfo.size_pixels</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.FaceInfo.yaw"><code class="docutils literal notranslate"><span class="pre">FaceInfo.yaw</span></code></a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="reference.html#osxphotos.FileUtil"><code class="docutils literal notranslate"><span class="pre">FileUtil</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="reference.html#osxphotos.FileUtilNoOp"><code class="docutils literal notranslate"><span class="pre">FileUtilNoOp</span></code></a><ul>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.FileUtilNoOp.convert_to_jpeg"><code class="docutils literal notranslate"><span class="pre">FileUtilNoOp.convert_to_jpeg()</span></code></a></li>
@ -444,6 +762,7 @@
</li>
<li class="toctree-l2"><a class="reference internal" href="reference.html#osxphotos.PhotoInfo"><code class="docutils literal notranslate"><span class="pre">PhotoInfo</span></code></a><ul>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PhotoInfo.adjustments"><code class="docutils literal notranslate"><span class="pre">PhotoInfo.adjustments</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PhotoInfo.adjustments_path"><code class="docutils literal notranslate"><span class="pre">PhotoInfo.adjustments_path</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PhotoInfo.album_info"><code class="docutils literal notranslate"><span class="pre">PhotoInfo.album_info</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PhotoInfo.albums"><code class="docutils literal notranslate"><span class="pre">PhotoInfo.albums</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PhotoInfo.asdict"><code class="docutils literal notranslate"><span class="pre">PhotoInfo.asdict()</span></code></a></li>
@ -523,7 +842,12 @@
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PhotoInfo.search_info"><code class="docutils literal notranslate"><span class="pre">PhotoInfo.search_info</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PhotoInfo.search_info_normalized"><code class="docutils literal notranslate"><span class="pre">PhotoInfo.search_info_normalized</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PhotoInfo.selfie"><code class="docutils literal notranslate"><span class="pre">PhotoInfo.selfie</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PhotoInfo.share_info"><code class="docutils literal notranslate"><span class="pre">PhotoInfo.share_info</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PhotoInfo.share_participants"><code class="docutils literal notranslate"><span class="pre">PhotoInfo.share_participants</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PhotoInfo.shared"><code class="docutils literal notranslate"><span class="pre">PhotoInfo.shared</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PhotoInfo.shared_library"><code class="docutils literal notranslate"><span class="pre">PhotoInfo.shared_library</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PhotoInfo.shared_moment"><code class="docutils literal notranslate"><span class="pre">PhotoInfo.shared_moment</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PhotoInfo.shared_moment_info"><code class="docutils literal notranslate"><span class="pre">PhotoInfo.shared_moment_info</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PhotoInfo.slow_mo"><code class="docutils literal notranslate"><span class="pre">PhotoInfo.slow_mo</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PhotoInfo.syndicated"><code class="docutils literal notranslate"><span class="pre">PhotoInfo.syndicated</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PhotoInfo.tables"><code class="docutils literal notranslate"><span class="pre">PhotoInfo.tables()</span></code></a></li>
@ -592,7 +916,16 @@
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PhotosDB.query"><code class="docutils literal notranslate"><span class="pre">PhotosDB.query()</span></code></a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="reference.html#osxphotos.PlaceInfo"><code class="docutils literal notranslate"><span class="pre">PlaceInfo</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="reference.html#osxphotos.PlaceInfo"><code class="docutils literal notranslate"><span class="pre">PlaceInfo</span></code></a><ul>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PlaceInfo.address"><code class="docutils literal notranslate"><span class="pre">PlaceInfo.address</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PlaceInfo.address_str"><code class="docutils literal notranslate"><span class="pre">PlaceInfo.address_str</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PlaceInfo.asdict"><code class="docutils literal notranslate"><span class="pre">PlaceInfo.asdict()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PlaceInfo.country_code"><code class="docutils literal notranslate"><span class="pre">PlaceInfo.country_code</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PlaceInfo.ishome"><code class="docutils literal notranslate"><span class="pre">PlaceInfo.ishome</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PlaceInfo.name"><code class="docutils literal notranslate"><span class="pre">PlaceInfo.name</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PlaceInfo.names"><code class="docutils literal notranslate"><span class="pre">PlaceInfo.names</span></code></a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="reference.html#osxphotos.ProjectInfo"><code class="docutils literal notranslate"><span class="pre">ProjectInfo</span></code></a><ul>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.ProjectInfo.folder_list"><code class="docutils literal notranslate"><span class="pre">ProjectInfo.folder_list</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.ProjectInfo.folder_names"><code class="docutils literal notranslate"><span class="pre">ProjectInfo.folder_names</span></code></a></li>
@ -683,6 +1016,10 @@
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.QueryOptions.not_syndicated"><code class="docutils literal notranslate"><span class="pre">QueryOptions.not_syndicated</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.QueryOptions.saved_to_library"><code class="docutils literal notranslate"><span class="pre">QueryOptions.saved_to_library</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.QueryOptions.not_saved_to_library"><code class="docutils literal notranslate"><span class="pre">QueryOptions.not_saved_to_library</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.QueryOptions.shared_moment"><code class="docutils literal notranslate"><span class="pre">QueryOptions.shared_moment</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.QueryOptions.not_shared_moment"><code class="docutils literal notranslate"><span class="pre">QueryOptions.not_shared_moment</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.QueryOptions.shared_library"><code class="docutils literal notranslate"><span class="pre">QueryOptions.shared_library</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.QueryOptions.not_shared_library"><code class="docutils literal notranslate"><span class="pre">QueryOptions.not_shared_library</span></code></a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="reference.html#osxphotos.ScoreInfo"><code class="docutils literal notranslate"><span class="pre">ScoreInfo</span></code></a><ul>

Binary file not shown.

View File

@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="OSXPhotos Tutorial" href="tutorial.html" /><link rel="prev" title="Welcome to OSXPhotoss documentation!" href="index.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
<title>OSXPhotos - osxphotos 0.60.4 documentation</title>
<title>OSXPhotos - osxphotos 0.62.1 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@ -124,7 +124,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">osxphotos 0.60.4 documentation</div></a>
<a href="index.html"><div class="brand">osxphotos 0.62.1 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -147,7 +147,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
<span class="sidebar-brand-text">osxphotos 0.60.4 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.62.1 documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@ -161,6 +161,7 @@
<li class="toctree-l1"><a class="reference internal" href="cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
<li class="toctree-l1"><a class="reference internal" href="template_help.html">OSXPhotos Template System</a></li>
<li class="toctree-l1"><a class="reference internal" href="package_overview.html">OSXPhotos Python Package Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="API_README.html">OSXPhotos Python API</a></li>
<li class="toctree-l1"><a class="reference internal" href="reference.html">OSXPhotos Python Reference</a></li>
</ul>

View File

@ -3,10 +3,10 @@
<head><meta charset="utf-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<meta name="color-scheme" content="light dark"><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="OSXPhotos Python Reference" href="reference.html" /><link rel="prev" title="OSXPhotos Template System" href="template_help.html" />
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="OSXPhotos Python API" href="API_README.html" /><link rel="prev" title="OSXPhotos Template System" href="template_help.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
<title>OSXPhotos Python Package Overview - osxphotos 0.60.4 documentation</title>
<title>OSXPhotos Python Package Overview - osxphotos 0.62.1 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@ -124,7 +124,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">osxphotos 0.60.4 documentation</div></a>
<a href="index.html"><div class="brand">osxphotos 0.62.1 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -147,7 +147,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
<span class="sidebar-brand-text">osxphotos 0.60.4 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.62.1 documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@ -161,6 +161,7 @@
<li class="toctree-l1"><a class="reference internal" href="cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
<li class="toctree-l1"><a class="reference internal" href="template_help.html">OSXPhotos Template System</a></li>
<li class="toctree-l1 current current-page"><a class="current reference internal" href="#">OSXPhotos Python Package Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="API_README.html">OSXPhotos Python API</a></li>
<li class="toctree-l1"><a class="reference internal" href="reference.html">OSXPhotos Python Reference</a></li>
</ul>
@ -387,12 +388,12 @@ as well as <code class="docutils literal notranslate"><span class="pre">{functio
<footer>
<div class="related-pages">
<a class="next-page" href="reference.html">
<a class="next-page" href="API_README.html">
<div class="page-info">
<div class="context">
<span>Next</span>
</div>
<div class="title">OSXPhotos Python Reference</div>
<div class="title">OSXPhotos Python API</div>
</div>
<svg class="furo-related-icon"><use href="#svg-arrow-right"></use></svg>
</a>

View File

@ -4,7 +4,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/><title>Python Module Index - osxphotos 0.60.4 documentation</title>
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/><title>Python Module Index - osxphotos 0.62.1 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@ -122,7 +122,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">osxphotos 0.60.4 documentation</div></a>
<a href="index.html"><div class="brand">osxphotos 0.62.1 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -145,7 +145,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
<span class="sidebar-brand-text">osxphotos 0.60.4 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.62.1 documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@ -159,6 +159,7 @@
<li class="toctree-l1"><a class="reference internal" href="cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
<li class="toctree-l1"><a class="reference internal" href="template_help.html">OSXPhotos Template System</a></li>
<li class="toctree-l1"><a class="reference internal" href="package_overview.html">OSXPhotos Python Package Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="API_README.html">OSXPhotos Python API</a></li>
<li class="toctree-l1"><a class="reference internal" href="reference.html">OSXPhotos Python Reference</a></li>
</ul>

File diff suppressed because one or more lines are too long

View File

@ -4,7 +4,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="#" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/><title>Search - osxphotos 0.60.4 documentation</title><link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/><title>Search - osxphotos 0.62.1 documentation</title><link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo-extensions.css?digest=30d1aed668e5c3a91c3e3bf6a60b675221979f0e" />
@ -121,7 +121,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">osxphotos 0.60.4 documentation</div></a>
<a href="index.html"><div class="brand">osxphotos 0.62.1 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -144,7 +144,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
<span class="sidebar-brand-text">osxphotos 0.60.4 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.62.1 documentation</span>
</a><form class="sidebar-search-container" method="get" action="#" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@ -158,6 +158,7 @@
<li class="toctree-l1"><a class="reference internal" href="cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
<li class="toctree-l1"><a class="reference internal" href="template_help.html">OSXPhotos Template System</a></li>
<li class="toctree-l1"><a class="reference internal" href="package_overview.html">OSXPhotos Python Package Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="API_README.html">OSXPhotos Python API</a></li>
<li class="toctree-l1"><a class="reference internal" href="reference.html">OSXPhotos Python Reference</a></li>
</ul>

File diff suppressed because one or more lines are too long

View File

@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="OSXPhotos Python Package Overview" href="package_overview.html" /><link rel="prev" title="OSXPhotos Command Line Interface (CLI)" href="cli.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
<title>OSXPhotos Template System - osxphotos 0.60.4 documentation</title>
<title>OSXPhotos Template System - osxphotos 0.62.1 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@ -124,7 +124,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">osxphotos 0.60.4 documentation</div></a>
<a href="index.html"><div class="brand">osxphotos 0.62.1 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -147,7 +147,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
<span class="sidebar-brand-text">osxphotos 0.60.4 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.62.1 documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@ -161,6 +161,7 @@
<li class="toctree-l1"><a class="reference internal" href="cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
<li class="toctree-l1 current current-page"><a class="current reference internal" href="#">OSXPhotos Template System</a></li>
<li class="toctree-l1"><a class="reference internal" href="package_overview.html">OSXPhotos Python Package Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="API_README.html">OSXPhotos Python API</a></li>
<li class="toctree-l1"><a class="reference internal" href="reference.html">OSXPhotos Python Reference</a></li>
</ul>
@ -320,8 +321,8 @@
<p>If you want to include “{” or “}” in the output, use “{openbrace}” or “{closebrace}” template substitution.</p>
<p>e.g. <code class="docutils literal notranslate"><span class="pre">&quot;{created.year}/{openbrace}{title}{closebrace}&quot;</span></code> would result in <code class="docutils literal notranslate"><span class="pre">&quot;2020/{Photo</span> <span class="pre">Title}&quot;</span></code>.</p>
<p><strong>Variables</strong></p>
<p>You can define variables for later use in the template string using the format <code class="docutils literal notranslate"><span class="pre">{var:NAME,VALUE}</span></code>. Variables may then be referenced using the format <code class="docutils literal notranslate"><span class="pre">%NAME</span></code>. For example: <code class="docutils literal notranslate"><span class="pre">{var:foo,bar}</span></code> defines the variable <code class="docutils literal notranslate"><span class="pre">%foo</span></code> to have value <code class="docutils literal notranslate"><span class="pre">bar</span></code>. This can be useful if you want to re-use a complex template value in multiple places within your template string or for allowing the use of characters that would otherwise be prohibited in a template string. For example, the “pipe” (<code class="docutils literal notranslate"><span class="pre">|</span></code>) character is not allowed in a find/replace pair but you can get around this limitation like so: <code class="docutils literal notranslate"><span class="pre">{var:pipe,{pipe}}{title[-,%pipe]}</span></code> which replaces the <code class="docutils literal notranslate"><span class="pre">-</span></code> character with <code class="docutils literal notranslate"><span class="pre">|</span></code> (the value of <code class="docutils literal notranslate"><span class="pre">%pipe</span></code>).</p>
<p>Variables can also be referenced as fields in the template string, for example: <code class="docutils literal notranslate"><span class="pre">{var:year,created.year}{original_name}-{%year}</span></code>. In some cases, use of variables can make your template string more readable. Variables can be used as template fields, as values for filters, as values for conditional operations, or as default values. When used as a conditional value or default value, variables should be treated like any other field and enclosed in braces as conditional and default values are evaluated as template strings. For example: <code class="docutils literal notranslate"><span class="pre">{var:name,Katie}{person</span> <span class="pre">contains</span> <span class="pre">{%name}?{%name},Not-{%name}}</span></code>.</p>
<p>You can define variables for later use in the template string using the format <code class="docutils literal notranslate"><span class="pre">{var:NAME,VALUE}</span></code> where <code class="docutils literal notranslate"><span class="pre">VALUE</span></code> is a template statement. Variables may then be referenced using the format <code class="docutils literal notranslate"><span class="pre">%NAME</span></code>. For example: <code class="docutils literal notranslate"><span class="pre">{var:foo,bar}</span></code> defines the variable <code class="docutils literal notranslate"><span class="pre">%foo</span></code> to have value <code class="docutils literal notranslate"><span class="pre">bar</span></code>. This can be useful if you want to re-use a complex template value in multiple places within your template string or for allowing the use of characters that would otherwise be prohibited in a template string. For example, the “pipe” (<code class="docutils literal notranslate"><span class="pre">|</span></code>) character is not allowed in a find/replace pair but you can get around this limitation like so: <code class="docutils literal notranslate"><span class="pre">{var:pipe,{pipe}}{title[-,%pipe]}</span></code> which replaces the <code class="docutils literal notranslate"><span class="pre">-</span></code> character with <code class="docutils literal notranslate"><span class="pre">|</span></code> (the value of <code class="docutils literal notranslate"><span class="pre">%pipe</span></code>).</p>
<p>Variables can also be referenced as fields in the template string, for example: <code class="docutils literal notranslate"><span class="pre">{var:year,{created.year}}{original_name}-{%year}</span></code>. In some cases, use of variables can make your template string more readable. Variables can be used as template fields, as values for filters, as values for conditional operations, or as default values. When used as a conditional value or default value, variables should be treated like any other field and enclosed in braces as conditional and default values are evaluated as template strings. For example: <code class="docutils literal notranslate"><span class="pre">{var:name,Katie}{person</span> <span class="pre">contains</span> <span class="pre">{%name}?{%name},Not-{%name}}</span></code>.</p>
<p>If you need to use a <code class="docutils literal notranslate"><span class="pre">%</span></code> (percent sign character), you can escape the percent sign by using <code class="docutils literal notranslate"><span class="pre">%%</span></code>. You can also use the <code class="docutils literal notranslate"><span class="pre">{percent}</span></code> template field where a template field is required. For example:</p>
<p><code class="docutils literal notranslate"><span class="pre">{title[:,%%]}</span></code> replaces the <code class="docutils literal notranslate"><span class="pre">:</span></code> with <code class="docutils literal notranslate"><span class="pre">%</span></code> and <code class="docutils literal notranslate"><span class="pre">{title</span> <span class="pre">contains</span> <span class="pre">Foo?{title}{percent},{title}}</span></code> adds <code class="docutils literal notranslate"><span class="pre">%</span></code> to the title if it contains <code class="docutils literal notranslate"><span class="pre">Foo</span></code>.</p>
<section id="id1">
@ -613,7 +614,7 @@
</td>
</tr>
<tr class="row-odd"><td><p>{osxphotos_version}</p></td>
<td><p>The osxphotos version, e.g. 0.60.4</p></td>
<td><p>The osxphotos version, e.g. 0.62.1</p></td>
</tr>
<tr class="row-even"><td><p>{osxphotos_cmd_line}</p></td>
<td><p>The full command line used to run osxphotos</p></td>

View File

@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="OSXPhotos Command Line Interface (CLI)" href="cli.html" /><link rel="prev" title="OSXPhotos" href="overview.html" />
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
<title>OSXPhotos Tutorial - osxphotos 0.60.4 documentation</title>
<title>OSXPhotos Tutorial - osxphotos 0.62.1 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@ -124,7 +124,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">osxphotos 0.60.4 documentation</div></a>
<a href="index.html"><div class="brand">osxphotos 0.62.1 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@ -147,7 +147,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
<span class="sidebar-brand-text">osxphotos 0.60.4 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.62.1 documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@ -161,6 +161,7 @@
<li class="toctree-l1"><a class="reference internal" href="cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
<li class="toctree-l1"><a class="reference internal" href="template_help.html">OSXPhotos Template System</a></li>
<li class="toctree-l1"><a class="reference internal" href="package_overview.html">OSXPhotos Python Package Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="API_README.html">OSXPhotos Python API</a></li>
<li class="toctree-l1"><a class="reference internal" href="reference.html">OSXPhotos Python Reference</a></li>
</ul>

3287
docsrc/source/api_readme.rst Normal file

File diff suppressed because it is too large Load Diff

View File

@ -14,6 +14,7 @@ Welcome to OSXPhotos's documentation!
cli
template_help
package_overview
API_README
reference

View File

@ -162,9 +162,9 @@ e.g. ``"{created.year}/{openbrace}{title}{closebrace}"`` would result in ``"2020
**Variables**
You can define variables for later use in the template string using the format ``{var:NAME,VALUE}``. Variables may then be referenced using the format ``%NAME``. For example: ``{var:foo,bar}`` defines the variable ``%foo`` to have value ``bar``. This can be useful if you want to re-use a complex template value in multiple places within your template string or for allowing the use of characters that would otherwise be prohibited in a template string. For example, the "pipe" (\ ``|``\ ) character is not allowed in a find/replace pair but you can get around this limitation like so: ``{var:pipe,{pipe}}{title[-,%pipe]}`` which replaces the ``-`` character with ``|`` (the value of ``%pipe``\ ).
You can define variables for later use in the template string using the format ``{var:NAME,VALUE}`` where ``VALUE`` is a template statement. Variables may then be referenced using the format ``%NAME``. For example: ``{var:foo,bar}`` defines the variable ``%foo`` to have value ``bar``. This can be useful if you want to re-use a complex template value in multiple places within your template string or for allowing the use of characters that would otherwise be prohibited in a template string. For example, the "pipe" (\ ``|``\ ) character is not allowed in a find/replace pair but you can get around this limitation like so: ``{var:pipe,{pipe}}{title[-,%pipe]}`` which replaces the ``-`` character with ``|`` (the value of ``%pipe``\ ).
Variables can also be referenced as fields in the template string, for example: ``{var:year,created.year}{original_name}-{%year}``. In some cases, use of variables can make your template string more readable. Variables can be used as template fields, as values for filters, as values for conditional operations, or as default values. When used as a conditional value or default value, variables should be treated like any other field and enclosed in braces as conditional and default values are evaluated as template strings. For example: ``{var:name,Katie}{person contains {%name}?{%name},Not-{%name}}``.
Variables can also be referenced as fields in the template string, for example: ``{var:year,{created.year}}{original_name}-{%year}``. In some cases, use of variables can make your template string more readable. Variables can be used as template fields, as values for filters, as values for conditional operations, or as default values. When used as a conditional value or default value, variables should be treated like any other field and enclosed in braces as conditional and default values are evaluated as template strings. For example: ``{var:name,Katie}{person contains {%name}?{%name},Not-{%name}}``.
If you need to use a ``%`` (percent sign character), you can escape the percent sign by using ``%%``. You can also use the ``{percent}`` template field where a template field is required. For example:
@ -361,7 +361,7 @@ Template Substitutions
* - {tab}
- :A tab: '\t'
* - {osxphotos_version}
- The osxphotos version, e.g. '0.60.4'
- The osxphotos version, e.g. '0.62.1'
* - {osxphotos_cmd_line}
- The full command line used to run osxphotos
* - {album}

View File

@ -0,0 +1,107 @@
"""Add the photo size in form widthxheight to each photo's caption/description in Photos
Run this with `osxphotos run add_size_to_caption.py`
Run `osxphotos run add_size_to_caption.py --help` for help.
Intended to be run with osxphotos; see https://github.com/RhetTbull/osxphotos
This may be helpful for allowing Smart Albums in Photos to filter by photo size.
Reference this reddit post: https://www.reddit.com/r/ApplePhotos/comments/15r4fk6/smart_album_filter_for_photovideo_dimensions/
"""
from __future__ import annotations
import click
import photoscript
import osxphotos
from osxphotos.cli import echo, echo_error, query_command, verbose
from osxphotos.utils import pluralize
@query_command
@click.option(
"--original",
is_flag=True,
help="If photo is edited, use original image size instead of edited image size",
)
@click.option(
"--clear",
is_flag=True,
help="Remove existing size information from description",
)
def main(photos: list[osxphotos.PhotoInfo], original: bool, clear: bool, **kwargs):
"""Add the photo size in form widthxheight to each photo's caption in Photos
If a photo has a caption, the size will be appended to the caption.
Use --original to use the original image size instead of the edited image size.
Use --clear to remove existing size information from caption.
"""
# filter out any shared photos
photos = [p for p in photos if not p.shared]
echo(f"Processing {len(photos)} {pluralize(len(photos), 'photo', 'photos')}...")
if clear:
clear_size_str_from_photos(photos, original)
else:
add_size_str_to_photos(photos, original)
echo("Done.")
def compute_size_str(photo: osxphotos.PhotoInfo, original: bool) -> str:
"""Return the size string for a given photo"""
return (
f"{photo.original_width}x{photo.original_height}"
if original
else f"{photo.width}x{photo.height}"
)
def add_size_str_to_photos(photos: list[osxphotos.PhotoInfo], original: bool):
"""Add size string to photo description/caption"""
for photo in photos:
size_str = compute_size_str(photo, original)
description = photo.description or "" # description can be None
if size_str in description:
verbose(
f"Skipping {photo.original_filename} ({photo.uuid}) ({size_str} already in caption)"
)
continue
new_desc = f"{photo.description}\n{size_str}" if description else size_str
verbose(
f"Updating caption for {photo.original_filename} ({photo.uuid}) to {new_desc}"
)
update_description(photo, new_desc)
def clear_size_str_from_photos(photos: list[osxphotos.PhotoInfo], original: bool):
"""Clear size string from photo description/caption"""
for photo in photos:
size_str = compute_size_str(photo, original)
description = photo.description or "" # description can be None
if size_str not in description:
verbose(
f"Skipping {photo.original_filename} ({photo.uuid}) ({size_str} not in caption)"
)
continue
new_desc = description.replace(size_str, "").strip()
verbose(
f"Setting caption for {photo.original_filename} ({photo.uuid}) to {new_desc}"
)
update_description(photo, new_desc)
def update_description(photo: osxphotos.PhotoInfo, new_desc: str):
"""Update photo caption"""
try:
photoscript.Photo(photo.uuid).description = new_desc
except Exception as e:
echo_error(
f"Error updating caption for {photo.original_filename} ({photo.uuid}): {e}"
)
if __name__ == "__main__":
main()

View File

@ -21,7 +21,6 @@ from osxphotos.sqlitekvstore import SQLiteKVStore
class Latitude(click.ParamType):
name = "Latitude"
def convert(self, value, param, ctx):
@ -37,7 +36,6 @@ class Latitude(click.ParamType):
class Longitude(click.ParamType):
name = "Longitude"
def convert(self, value, param, ctx):

View File

@ -23,10 +23,7 @@ to your function. You can then do whatever you want with the photos.
from __future__ import annotations
import osxphotos
from osxphotos.cli import (
selection_command,
verbose,
)
from osxphotos.cli import selection_command, verbose
@selection_command

View File

@ -2,9 +2,10 @@
import sys
import osxphotos
import click
import osxphotos
@click.command()
@click.argument("album1")

View File

@ -0,0 +1,22 @@
<%doc>
This is an example Mako template for use with --sidecar-template
For more information on Mako templates, see https://docs.makotemplates.org/en/latest/
The template will be passed three variables for rendering:
photo: a PhotoInfo object for the photo being exported
photo_path: a pathlib.Path object for the photo file being exported
sidecar_path: a pathlib.Path object for the sidecar file being written
</%doc>
<%def name="rating(photo)" filter="trim">\
% if photo.favorite:
★★★★★
% else:
★☆☆☆☆
% endif
</%def>\
Photo: ${photo_path.name}
UUID: ${photo.uuid}
Sidecar: ${sidecar_path.name}
Rating: ${rating(photo)}

View File

@ -0,0 +1,11 @@
<%doc>
Mako template to dump a full json representation of the photo object
Can be run from the command line with:
osxphotos export /path/to/export --sidecar-template custom_sidecar_json.mako "{filepath}.json" yes no yes
The template will be passed three variables for rendering:
photo: a PhotoInfo object for the photo being exported
photo_path: a pathlib.Path object for the photo file being exported
sidecar_path: a pathlib.Path object for the sidecar file being written
</%doc>
${photo.json(shallow=False, indent=4)}

View File

@ -0,0 +1,223 @@
<%doc>
This is an example Mako template for use with --sidecar-template which produces an XMP sidecar file
For more information on Mako templates, see https://docs.makotemplates.org/en/latest/
The template will be passed three variables for rendering:
photo: a PhotoInfo object for the photo being exported
photo_path: a pathlib.Path object for the photo file being exported
sidecar_path: a pathlib.Path object for the sidecar file being written
</%doc>
<%def name="photoshop_sidecar_for_extension(extension)">
% if extension is None:
<photoshop:SidecarForExtension></photoshop:SidecarForExtension>
% else:
<photoshop:SidecarForExtension>${extension}</photoshop:SidecarForExtension>
% endif
</%def>
<%def name="dc_description(desc)">
% if desc is None:
<dc:description>
<rdf:Alt>
<rdf:li xml:lang='x-default'/>
</rdf:Alt>
</dc:description>
% else:
<dc:description>
<rdf:Alt>
<rdf:li xml:lang='x-default'>${desc | x}</rdf:li>
</rdf:Alt>
</dc:description>
% endif
</%def>
<%def name="dc_title(title)">
% if title is None:
<dc:title>
<rdf:Alt>
<rdf:li xml:lang='x-default'/>
</rdf:Alt>
</dc:title>
% else:
<dc:title>
<rdf:Alt>
<rdf:li xml:lang='x-default'>${title | x}</rdf:li>
</rdf:Alt>
</dc:title>
% endif
</%def>
<%def name="dc_subject(subject)">
% if subject:
<dc:subject>
<rdf:Bag>
% for subj in subject:
<rdf:li>${subj | x}</rdf:li>
% endfor
</rdf:Bag>
</dc:subject>
% endif
</%def>
<%def name="dc_datecreated(date)">
% if date is not None:
<photoshop:DateCreated>${date.isoformat()}</photoshop:DateCreated>
% endif
</%def>
<%def name="iptc_personinimage(persons)">
% if persons:
<Iptc4xmpExt:PersonInImage>
<rdf:Bag>
% for person in persons:
<rdf:li>${person | x}</rdf:li>
% endfor
</rdf:Bag>
</Iptc4xmpExt:PersonInImage>
% endif
</%def>
<%def name="dk_tagslist(keywords)">
% if keywords:
<digiKam:TagsList>
<rdf:Seq>
% for keyword in keywords:
<rdf:li>${keyword | x}</rdf:li>
% endfor
</rdf:Seq>
</digiKam:TagsList>
% endif
</%def>
<%def name="adobe_createdate(date)">
% if date is not None:
<xmp:CreateDate>${date.strftime("%Y-%m-%dT%H:%M:%S")}</xmp:CreateDate>
% endif
</%def>
<%def name="adobe_modifydate(date)">
% if date is not None:
<xmp:ModifyDate>${date.strftime("%Y-%m-%dT%H:%M:%S")}</xmp:ModifyDate>
% endif
</%def>
<%def name="xmp_rating(rating)">
% if rating is not None:
<xmp:Rating>${rating}</xmp:Rating>
% endif
</%def>
<%def name="gps_info(latitude, longitude)">
% if latitude is not None and longitude is not None:
<exif:GPSLongitude>${int(abs(longitude))},${(abs(longitude) % 1) * 60}${"E" if longitude >= 0 else "W"}</exif:GPSLongitude>
<exif:GPSLatitude>${int(abs(latitude))},${(abs(latitude) % 1) * 60}${"N" if latitude >= 0 else "S"}</exif:GPSLatitude>
% endif
</%def>
<%def name="mwg_face_regions(photo)">
% if photo.face_info:
<mwg-rs:Regions rdf:parseType="Resource">
<mwg-rs:AppliedToDimensions rdf:parseType="Resource">
<stDim:h>${photo.width if photo.orientation in [5, 6, 7, 8] else photo.height}</stDim:h>
<stDim:w>${photo.height if photo.orientation in [5, 6, 7, 8] else photo.width}</stDim:w>
<stDim:unit>pixel</stDim:unit>
</mwg-rs:AppliedToDimensions>
<mwg-rs:RegionList>
<rdf:Bag>
% for face in photo.face_info:
<rdf:li rdf:parseType="Resource">
<mwg-rs:Area rdf:parseType="Resource">
<stArea:h>${'{0:.6f}'.format(face.mwg_rs_area.h)}</stArea:h>
<stArea:w>${'{0:.6f}'.format(face.mwg_rs_area.w)}</stArea:w>
<stArea:x>${'{0:.6f}'.format(face.mwg_rs_area.x)}</stArea:x>
<stArea:y>${'{0:.6f}'.format(face.mwg_rs_area.y)}</stArea:y>
<stArea:unit>normalized</stArea:unit>
</mwg-rs:Area>
<mwg-rs:Name>${face.name}</mwg-rs:Name>
<mwg-rs:Rotation>${face.roll}</mwg-rs:Rotation>
<mwg-rs:Type>Face</mwg-rs:Type>
</rdf:li>
% endfor
</rdf:Bag>
</mwg-rs:RegionList>
</mwg-rs:Regions>
% endif
</%def>
<%def name="mpri_face_regions(photo)">
% if photo.face_info:
<MP:RegionInfo rdf:parseType="Resource">
<MPRI:Regions>
<rdf:Bag>
% for face in photo.face_info:
<rdf:li rdf:parseType="Resource">
<MPReg:PersonDisplayName>${face.name}</MPReg:PersonDisplayName>
<MPReg:Rectangle>${'{0:.6f}'.format(face.mpri_reg_rect.x)}, ${'{0:.6f}'.format(face.mpri_reg_rect.y)}, ${'{0:.6f}'.format(face.mpri_reg_rect.h)}, ${'{0:.6f}'.format(face.mpri_reg_rect.w)}</MPReg:Rectangle>
</rdf:li>
% endfor
</rdf:Bag>
</MPRI:Regions>
</MP:RegionInfo>
% endif
</%def>
<?xpacket begin="${"\uFEFF"}" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="osxphotos">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/">
<%
extension = photo_path.suffix[1:].lower() if photo_path.suffix else ""
%>
${photoshop_sidecar_for_extension(extension)}
${dc_description(photo.description)}
${dc_title(photo.title)}
<%
subjects = photo.keywords + photo.persons
%>
${dc_subject(subjects)}
${dc_datecreated(photo.date)}
</rdf:Description>
<rdf:Description rdf:about=""
xmlns:Iptc4xmpExt='http://iptc.org/std/Iptc4xmpExt/2008-02-29/'>
${iptc_personinimage(photo.persons)}
</rdf:Description>
<rdf:Description rdf:about=""
xmlns:digiKam='http://www.digikam.org/ns/1.0/'>
${dk_tagslist(photo.keywords)}
</rdf:Description>
<rdf:Description rdf:about=""
xmlns:xmp='http://ns.adobe.com/xap/1.0/'>
${adobe_createdate(photo.date)}
${adobe_modifydate(photo.date)}
${xmp_rating("5" if photo.favorite else None)}
</rdf:Description>
<rdf:Description rdf:about=""
xmlns:exif='http://ns.adobe.com/exif/1.0/'>
${gps_info(*photo.location)}
</rdf:Description>
<rdf:Description rdf:about=""
xmlns:mwg-rs="http://www.metadataworkinggroup.com/schemas/regions/"
xmlns:stArea="http://ns.adobe.com/xmp/sType/Area#"
xmlns:stDim="http://ns.adobe.com/xap/1.0/sType/Dimensions#">
${mwg_face_regions(photo)}
</rdf:Description>
<rdf:Description rdf:about=""
xmlns:MP="http://ns.microsoft.com/photo/1.2/"
xmlns:MPRI="http://ns.microsoft.com/photo/1.2/t/RegionInfo#"
xmlns:MPReg="http://ns.microsoft.com/photo/1.2/t/Region#">
${mpri_face_regions(photo)}
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
<?xpacket end="w"?>

View File

@ -1,6 +1,7 @@
import osxphotos
import os.path
import osxphotos
def main():
db = osxphotos.utils.get_system_library_path()

View File

@ -32,7 +32,7 @@ import osxphotos
default=False,
)
def export(export_path, default_album, library_path, edited):
""" Export all photos, organized by album """
"""Export all photos, organized by album"""
export_path = os.path.expanduser(export_path)
library_path = os.path.expanduser(library_path) if library_path else None
@ -66,11 +66,11 @@ def export(export_path, default_album, library_path, edited):
os.makedirs(dest_dir)
filename = p.original_filename
# export the photo but only if --edited, photo has adjustments, and
# export the photo but only if --edited, photo has adjustments, and
# path_edited is not None (can be None if edited photo is missing)
if edited and p.hasadjustments and p.path_edited:
# export edited version
# use original filename with _edited appended but make sure suffix is
# use original filename with _edited appended but make sure suffix is
# same as edited file
edited_filename = f"{pathlib.Path(filename).stem}_edited{pathlib.Path(p.path_edited).suffix}"
exported = p.export(dest_dir, edited_filename, edited=True)

View File

@ -32,7 +32,7 @@ import osxphotos
default=None,
)
def export(export_path, library_path, uuid):
""" export photos to export_path and draw faces """
"""export photos to export_path and draw faces"""
library_path = os.path.expanduser(library_path) if library_path else None
if library_path is not None:
photosdb = osxphotos.PhotosDB(library_path)
@ -61,7 +61,7 @@ def export(export_path, library_path, uuid):
def get_circle_points(xy, radius):
""" Returns tuples of (x0, y0), (x1, y1) for a circle centered at x, y with radius
"""Returns tuples of (x0, y0), (x1, y1) for a circle centered at x, y with radius
Arguments:
xy: tuple of x, y coordinates

View File

@ -77,7 +77,9 @@ def place_folder(photo: osxphotos.PhotoInfo) -> str:
return ""
def photos_folders(photo: osxphotos.PhotoInfo, options: osxphotos.phototemplate.RenderOptions, **kwargs) -> Union[List, str]:
def photos_folders(
photo: osxphotos.PhotoInfo, options: osxphotos.phototemplate.RenderOptions, **kwargs
) -> Union[List, str]:
"""template function for use with --directory to export photos in a folder structure similar to Photos
Args:

View File

@ -29,7 +29,9 @@ def main():
exported = photo.export(tempdir.name, use_photos_export=True, timeout=300)
if photo.hasadjustments:
exported.extend(
photo.export(tempdir.name, use_photos_export=True, edited=True, timeout=300)
photo.export(
tempdir.name, use_photos_export=True, edited=True, timeout=300
)
)
for filename in exported:
print(f"Removing temporary file {filename}")

View File

@ -10,7 +10,7 @@ from osxphotos._constants import TIME_DELTA
@dataclass
class Comment:
""" Class for shared photo comments """
"""Class for shared photo comments"""
uuid: str
sort_fok: int
@ -22,7 +22,7 @@ class Comment:
@dataclass
class Like:
""" Class for shared photo likes """
"""Class for shared photo likes"""
uuid: str
sort_fok: int
@ -32,10 +32,10 @@ class Like:
def get_shared_person_info(photosdb, hashed_person_id):
""" returns tuple of (first name, last name, full name)
for person invited to shared album with
"""returns tuple of (first name, last name, full name)
for person invited to shared album with
ZINVITEEHASHEDPERSONID = hashed_person_id
Args:
photosdb: a osxphotos.PhotosDB object
hashed_person_id: str, value of ZINVITEEHASHEDPERSONID to lookup
@ -66,12 +66,12 @@ def get_shared_person_info(photosdb, hashed_person_id):
def get_comments(photosdb, uuid):
""" return comments and likes, if any, for photo with uuid
"""return comments and likes, if any, for photo with uuid
Args:
photosdb: a osxphotos.PhotosDB object
uuid: uuid of the photo
Returns:
tuple of (list of comments as Comment objects or [] if no comments, list of likes as Like objects or [] if no likes)
"""

View File

@ -15,14 +15,14 @@ import time
import click
import osxphotos
from osxphotos.cli import get_photos_db, _list_libraries
from osxphotos.cli import _list_libraries, get_photos_db
def show(photo):
""" open image with default image viewer
Note: This is for debugging only -- it will actually open any filetype which could
be very, very bad.
"""open image with default image viewer
Note: This is for debugging only -- it will actually open any filetype which could
be very, very bad.
Args:
photo: PhotoInfo object or a path to a photo on disk

View File

@ -1,57 +1,88 @@
""" Example function for use with osxphotos export --post-function option """
from typing import Callable
from __future__ import annotations
import pathlib
from typing import Any, Callable
from osxphotos import ExportResults, PhotoInfo
from osxphotos.cli import echo_error
def post_function(
photo: PhotoInfo, results: ExportResults, verbose: Callable, **kwargs
):
photo: PhotoInfo, results: ExportResults, verbose: Callable[[Any], None], **kwargs
) -> ExportResults | None:
"""Call this with osxphotos export /path/to/export --post-function post_function.py::post_function
This will get called immediately after the photo has been exported
Args:
photo: PhotoInfo instance for the photo that's just been exported
see https://rhettbull.github.io/osxphotos/reference.html#osxphotos.PhotoInfo for details
results: ExportResults instance with information about the files associated with the exported photo
see https://rhettbull.github.io/osxphotos/reference.html#osxphotos.ExportResults for details
verbose: A function to print verbose output if --verbose is set; if --verbose is not set, acts as a no-op (nothing gets printed)
**kwargs: reserved for future use; recommend you include **kwargs so your function still works if additional arguments are added in future versions
Returns:
ExportResults instance or None
If returning an ExportResults instance, it must be a new instance; do not modify the instance passed in as an argument.
You should set only the following values in ExportResults:
user_written: list[str], list of files written by your function
user_skipped: list[str], list of files skipped by your function
user_error: list[tuple[str, str]], list of tuples of (filename, error) for any errors generated by your function
For full description of ExportResults see: https://rhettbull.github.io/osxphotos/reference.html#osxphotos.ExportResults
Notes:
Use verbose(str) instead of print if you want your function to conditionally output text depending on --verbose flag
Any string printed with verbose that contains "warning" or "error" (case-insensitive) will be printed with the appropriate warning or error color
Will not be called if --dry-run flag is enabled
Will be called immediately after export and before any --post-command commands are executed
The function will not be called if --dry-run flag is enabled
The function be called immediately after export and before any --post-command commands are executed
If your function does not write any files, you can optionally return None instead of an ExportResults instance
If you return ExportResults, any files in user_written or user_skipped will be included when
writing reports and will be preserved when using --cleanup
If you want files previously written by the post_function, but not written this time,
to be preserved when using --cleanup, you should include them in user_skipped
If the function raises an exception, osxphotos will abort the export and exit with an error.
If you want the export to continue, you should catch any exceptions and return an ExportResults instance
with the error(s) in specified in ExportResults.user_error which is a list of tuples of (filename, error)
The verbose function can be used to print text to stdout if --verbose is set
If --verbose is not set, verbose acts as a no-op (nothing gets printed)
Verbose output may be stylized with tags as follows; tags must be enclosed in square brackets
and closed with [/] to end the style:
[change]: something change
[no_change]: indicate no change
[count]: a count
[error]: an error
[filename]: a filename
[filepath]: a filepath
[num]: a number
[time]: a time or date
[tz]: a timezone
[warning]: a warning
[uuid]: a uuid
"""
# ExportResults has the following properties
# fields with filenames contain the full path to the file
# exported: list of all files exported
# new: list of all new files exported (--update)
# updated: list of all files updated (--update)
# skipped: list of all files skipped (--update)
# exif_updated: list of all files that were updated with --exiftool
# touched: list of all files that had date updated with --touch-file
# converted_to_jpeg: list of files converted to jpeg with --convert-to-jpeg
# sidecar_json_written: list of all JSON sidecar files written
# sidecar_json_skipped: list of all JSON sidecar files skipped (--update)
# sidecar_exiftool_written: list of all exiftool sidecar files written
# sidecar_exiftool_skipped: list of all exiftool sidecar files skipped (--update)
# sidecar_xmp_written: list of all XMP sidecar files written
# sidecar_xmp_skipped: list of all XMP sidecar files skipped (--update)
# missing: list of all missing files
# error: list tuples of (filename, error) for any errors generated during export
# exiftool_warning: list of tuples of (filename, warning) for any warnings generated by exiftool with --exiftool
# exiftool_error: list of tuples of (filename, error) for any errors generated by exiftool with --exiftool
# xattr_written: list of files that had extended attributes written
# xattr_skipped: list of files that where extended attributes were skipped (--update)
# deleted_files: list of deleted files
# deleted_directories: list of deleted directories
# exported_album: list of tuples of (filename, album_name) for exported files added to album with --add-exported-to-album
# skipped_album: list of tuples of (filename, album_name) for skipped files added to album with --add-skipped-to-album
# missing_album: list of tuples of (filename, album_name) for missing files added to album with --add-missing-to-album
# metadata_changed: list of filenames that had metadata changes since last export
for filename in results.exported:
post_results = ExportResults()
for filename in results.exported + results.skipped:
# do your processing here
verbose(f"post_function: {photo.original_filename} exported as {filename}")
# simulate doing some processing
new_filename = pathlib.Path(f"{filename}.new")
if new_filename.exists():
verbose(f"Skipping file [filepath]{new_filename}[/] as it already exists")
post_results.user_skipped.append(new_filename)
else:
verbose(f"Writing new file [filepath]{new_filename}[/]")
new_filename.touch()
post_results.user_written.append(new_filename)
# if you encounter an error, add it to user_error
# echo_error will print the error to stderr with the appropriate formatting
# echo_error(f"Encountered an error processing [filepath]{filename}[/]: [error]some error[/]")
# post_results.user_error.append((filename, "some error"))
# if your function does not write any files, you can return None
return post_results

View File

@ -1,8 +1,10 @@
""" Example function for use with osxphotos import --post-function option """
import typing as t
import photoscript
import pathlib
import typing as t
import photoscript
from osxphotos.cli.import_cli import ReportRecord

View File

@ -3,6 +3,7 @@ import os.path
import osxphotos
def main():
db = os.path.expanduser("~/Pictures/Photos Library.photoslibrary")
photosdb = osxphotos.PhotosDB(db)
@ -15,11 +16,14 @@ def main():
print(photosdb.albums_as_dict)
# find all photos with Keyword = Foo and containing John Smith
photos = photosdb.photos(keywords=["Foo"],persons=["John Smith"])
photos = photosdb.photos(keywords=["Foo"], persons=["John Smith"])
# find all photos that include Alice Smith but do not contain the keyword Bar
photos = [p for p in photosdb.photos(persons=["Alice Smith"])
if p not in photosdb.photos(keywords=["Bar"]) ]
photos = [
p
for p in photosdb.photos(persons=["Alice Smith"])
if p not in photosdb.photos(keywords=["Bar"])
]
for p in photos:
print(
p.uuid,
@ -34,5 +38,6 @@ def main():
p.path,
)
if __name__ == "__main__":
main()
main()

View File

@ -10,8 +10,8 @@
from typing import List
def myfilter(values: List[str]) -> List[str]:
""" Custom filter to append "foo-" to template value """
"""Custom filter to append "foo-" to template value"""
values = ["foo-" + val for val in values]
return values

View File

@ -7,7 +7,7 @@ from typing import Callable
from osxphotos import ExportResults, PhotoInfo
from osxphotos.exiftool import ExifTool
from osxphotos.utils import normalize_unicode
from osxphotos.unicode import normalize_unicode
# Update this for your custom keyword to rating mapping
RATINGS = {

View File

@ -13,7 +13,7 @@ from .exiftool import ExifTool
from .export_db import ExportDB, ExportDBTemp
from .fileutil import FileUtil, FileUtilNoOp
from .momentinfo import MomentInfo
from .personinfo import PersonInfo
from .personinfo import FaceInfo, PersonInfo
from .photoexporter import ExportOptions, ExportResults, PhotoExporter
from .photoinfo import PhotoInfo
from .photosdb import PhotosDB
@ -21,10 +21,10 @@ from .photosdb._photosdb_process_comments import CommentInfo, LikeInfo
from .phototables import PhotoTables
from .phototemplate import PhotoTemplate
from .placeinfo import PlaceInfo
from .platform import is_macos
from .queryoptions import QueryOptions
from .scoreinfo import ScoreInfo
from .searchinfo import SearchInfo
from .utils import is_macos
if is_macos:
from .photosalbum import PhotosAlbum, PhotosAlbumPhotoScript
@ -48,6 +48,7 @@ __all__ = [
"ExportDBTemp",
"ExportOptions",
"ExportResults",
"FaceInfo",
"FileUtil",
"FileUtilNoOp",
"FolderInfo",

View File

@ -18,23 +18,23 @@ OSXPHOTOS_URL = "https://github.com/RhetTbull/osxphotos"
# Apple Epoch is Jan 1, 2001
TIME_DELTA = (datetime(2001, 1, 1, 0, 0) - datetime(1970, 1, 1, 0, 0)).total_seconds()
# Unicode format to use for comparing strings
UNICODE_FORMAT = "NFC"
# which Photos library database versions have been tested
# Photos 2.0 (10.12.6) == 2622
# Photos 3.0 (10.13.6) == 3301
# Photos 4.0 (10.14.5) == 4016
# Photos 4.0 (10.14.6) == 4025
# Photos 5.0 (10.15.0) == 6000 or 5001
# Photos 5.0+ (10.15.0) == 6000 or 5001
_TESTED_DB_VERSIONS = ["6000", "5001", "4025", "4016", "3301", "2622"]
# database model versions (applies to Photos 5, Photos 6)
# database model versions (applies to Photos 5+)
# these come from PLModelVersion key in binary plist in Z_METADATA.Z_PLIST
# Photos 5 (10.15.1) == 13537
# Photos 5 (10.15.4, 10.15.5, 10.15.6) == 13703
# Photos 6 (10.16.0 Beta) == 14104
_TEST_MODEL_VERSIONS = ["13537", "13703", "14104"]
# Photos 7 (12.0.1) == 15323
# Photos 8 (13.0.0) == 16320
# Photos 9 (14.0.0 dev preview) = 17120
_TEST_MODEL_VERSIONS = ["13537", "13703", "14104", "15323", "16320", "17120"]
_PHOTOS_2_VERSION = "2622"
@ -42,7 +42,7 @@ _PHOTOS_2_VERSION = "2622"
_PHOTOS_3_VERSION = "3301"
# versions 5.0 and later have a different database structure
_PHOTOS_4_VERSION = "4025" # latest Mojove version on 10.14.6
_PHOTOS_4_VERSION = "4025" # latest Mojave version on 10.14.6
_PHOTOS_5_VERSION = "5000" # I've seen both 5001 and 6000. 6000 is most common on Catalina and up but there are some version 5001 database in the wild
# Ranges for model version by Photos version
@ -50,8 +50,15 @@ _PHOTOS_5_MODEL_VERSION = [13000, 13999]
_PHOTOS_6_MODEL_VERSION = [14000, 14999]
_PHOTOS_7_MODEL_VERSION = [15000, 15999] # Dev preview: 15134, 12.1: 15331
_PHOTOS_8_MODEL_VERSION = [16000, 16999] # Ventura dev preview: 16119
_PHOTOS_9_MODEL_VERSION = [17000, 17999] # Sonoma dev preview: 17120
# some table names differ between Photos 5 and Photos 6
# the preview versions of 12.0.0 had a difference schema for syndication info so need to check model version before processing
_PHOTOS_SYNDICATION_MODEL_VERSION = 15323 # 12.0.1
# shared iCloud library versions; dev preview doesn't contain same columns as release version
_PHOTOS_SHARED_LIBRARY_VERSION = 16320 # 13.0
# some table names differ between Photos 5 and later versions
_DB_TABLE_NAMES = {
5: {
"ASSET": "ZGENERICASSET",
@ -64,6 +71,8 @@ _DB_TABLE_NAMES = {
"ASSET_ALBUM_JOIN": "Z_26ASSETS.Z_26ALBUMS",
"ASSET_ALBUM_TABLE": "Z_26ASSETS",
"HDR_TYPE": "ZCUSTOMRENDEREDVALUE",
"DETECTED_FACE_PERSON_FK": "ZDETECTEDFACE.ZPERSON",
"DETECTED_FACE_ASSET_FK": "ZDETECTEDFACE.ZASSET",
},
6: {
"ASSET": "ZASSET",
@ -76,6 +85,8 @@ _DB_TABLE_NAMES = {
"ASSET_ALBUM_JOIN": "Z_26ASSETS.Z_26ALBUMS",
"ASSET_ALBUM_TABLE": "Z_26ASSETS",
"HDR_TYPE": "ZCUSTOMRENDEREDVALUE",
"DETECTED_FACE_PERSON_FK": "ZDETECTEDFACE.ZPERSON",
"DETECTED_FACE_ASSET_FK": "ZDETECTEDFACE.ZASSET",
},
7: {
"ASSET": "ZASSET",
@ -88,6 +99,8 @@ _DB_TABLE_NAMES = {
"ASSET_ALBUM_JOIN": "Z_27ASSETS.Z_27ALBUMS",
"ASSET_ALBUM_TABLE": "Z_27ASSETS",
"HDR_TYPE": "ZHDRTYPE",
"DETECTED_FACE_PERSON_FK": "ZDETECTEDFACE.ZPERSON",
"DETECTED_FACE_ASSET_FK": "ZDETECTEDFACE.ZASSET",
},
8: {
"ASSET": "ZASSET",
@ -100,6 +113,22 @@ _DB_TABLE_NAMES = {
"ASSET_ALBUM_JOIN": "Z_28ASSETS.Z_28ALBUMS",
"ASSET_ALBUM_TABLE": "Z_28ASSETS",
"HDR_TYPE": "ZHDRTYPE",
"DETECTED_FACE_PERSON_FK": "ZDETECTEDFACE.ZPERSON",
"DETECTED_FACE_ASSET_FK": "ZDETECTEDFACE.ZASSET",
},
9: {
"ASSET": "ZASSET",
"KEYWORD_JOIN": "Z_1KEYWORDS.Z_40KEYWORDS",
"ALBUM_JOIN": "Z_28ASSETS.Z_3ASSETS",
"ALBUM_SORT_ORDER": "Z_28ASSETS.Z_FOK_3ASSETS",
"IMPORT_FOK": "null",
"DEPTH_STATE": "ZASSET.ZDEPTHTYPE",
"UTI_ORIGINAL": "ZINTERNALRESOURCE.ZCOMPACTUTI",
"ASSET_ALBUM_JOIN": "Z_28ASSETS.Z_28ALBUMS",
"ASSET_ALBUM_TABLE": "Z_28ASSETS",
"HDR_TYPE": "ZHDRTYPE",
"DETECTED_FACE_PERSON_FK": "ZDETECTEDFACE.ZPERSONFORFACE",
"DETECTED_FACE_ASSET_FK": "ZDETECTEDFACE.ZASSETFORFACE",
},
}
@ -130,6 +159,7 @@ _TESTED_OS_VERSIONS = [
("13", "2"),
("13", "3"),
("13", "4"),
("14", "0"),
]
# Photos 5 has persons who are empty string if unidentified face

View File

@ -1,3 +1,3 @@
""" version info """
__version__ = "0.60.4"
__version__ = "0.62.1"

View File

@ -5,7 +5,6 @@ import sys
from rich import print
from rich.traceback import install as install_traceback
from osxphotos.utils import is_macos
from osxphotos.debug import (
debug_breakpoint,
debug_watch,
@ -14,6 +13,7 @@ from osxphotos.debug import (
set_debug,
wrap_function,
)
from osxphotos.platform import is_macos
# apply any debug functions
# need to do this before importing anything else so that the debug functions

View File

@ -7,8 +7,9 @@ import datetime
import click
import osxphotos
from osxphotos.platform import assert_macos
from osxphotos.queryoptions import IncompatibleQueryOptions, query_options_from_kwargs
from osxphotos.utils import assert_macos, pluralize
from osxphotos.utils import pluralize
from .cli_params import QUERY_OPTIONS, THEME_OPTION, TIMESTAMP_OPTION, VERBOSE_OPTION
from .click_rich_echo import rich_click_echo as echo

View File

@ -12,8 +12,8 @@ import click
import osxphotos
from osxphotos.phototemplate import RenderOptions
from osxphotos.platform import assert_macos
from osxphotos.sqlitekvstore import SQLiteKVStore
from osxphotos.utils import assert_macos
assert_macos()

View File

@ -9,11 +9,11 @@ import click
from osxphotos._constants import PROFILE_SORT_KEYS
from osxphotos._version import __version__
from osxphotos.utils import is_macos
from osxphotos.platform import is_macos
from .about import about
from .albums import albums
from .cli_params import DB_OPTION, DEBUG_OPTIONS, JSON_OPTION, VERSION_OPTION
from .cli_params import DEBUG_OPTIONS, VERSION_OPTION
from .common import OSXPHOTOS_HIDDEN
from .debug_dump import debug_dump
from .docs import docs_command
@ -62,8 +62,6 @@ CTX_SETTINGS = dict(help_option_names=["-h", "--help"])
@click.group(context_settings=CTX_SETTINGS)
@VERSION_OPTION
@DB_OPTION
@JSON_OPTION
@DEBUG_OPTIONS
@click.option(
"--profile", is_flag=True, hidden=OSXPHOTOS_HIDDEN, help="Enable profiling"
@ -83,12 +81,12 @@ CTX_SETTINGS = dict(help_option_names=["-h", "--help"])
"Default = 'cumulative'.",
)
@click.pass_context
def cli_main(ctx, db, json_, profile, profile_sort, **kwargs):
def cli_main(ctx, profile, profile_sort, **kwargs):
"""osxphotos: the multi-tool for your Photos library"""
# Note: kwargs is used to catch any debug options passed in
# the debug options are handled in cli/__init__.py
# before this function is called
ctx.obj = CLI_Obj(db=db, json=json_, group=cli_main)
ctx.obj = CLI_Obj(group=cli_main)
if profile:
click.echo("Profiling...")
profile_sort = profile_sort or ["cumulative"]

View File

@ -3,13 +3,14 @@
from __future__ import annotations
import functools
from typing import Any, Callable
import click
import contextlib
import functools
from textwrap import dedent
from typing import Any, Callable
from ..utils import is_macos
import click
from ..platform import is_macos
from .common import OSXPHOTOS_HIDDEN, print_version
from .param_types import *
@ -610,6 +611,26 @@ _QUERY_PARAMETERS_DICT = {
is_flag=True,
help="Search for syndicated photos that have not saved to the library",
),
"--shared-moment": click.Option(
["--shared-moment"],
is_flag=True,
help="Search for photos that are part of a shared moment",
),
"--not-shared-moment": click.Option(
["--not-shared-moment"],
is_flag=True,
help="Search for photos that are not part of a shared moment",
),
"--shared-library": click.Option(
["--shared-library"],
is_flag=True,
help="Search for photos that are part of a shared library",
),
"--not-shared-library": click.Option(
["--not-shared-library"],
is_flag=True,
help="Search for photos that are not part of a shared library",
),
"--regex": click.Option(
["--regex"],
metavar="REGEX TEMPLATE",

View File

@ -15,7 +15,8 @@ from xdg import xdg_config_home, xdg_data_home
import osxphotos
from osxphotos._constants import APP_NAME
from osxphotos._version import __version__
from osxphotos.utils import get_latest_version, get_macos_version
from osxphotos.platform import get_macos_version
from osxphotos.utils import get_latest_version
# used to show/hide hidden commands
OSXPHOTOS_HIDDEN = not bool(os.getenv("OSXPHOTOS_SHOW_HIDDEN", default=False))

View File

@ -1,11 +1,10 @@
"""Detect dark mode on MacOS >= 10.14 or fake it elsewhere"""
from osxphotos.utils import is_macos
from osxphotos.platform import is_macos
if is_macos:
import objc
import Foundation
import objc
def theme():
with objc.autorelease_pool():

View File

@ -93,13 +93,25 @@ def debug_dump(
pprint.pprint(photosdb._dbpersons_fullname)
elif attr == "photos":
photos = photosdb.query(options=query_options)
uuid = [photo.uuid for photo in photos]
for uuid_ in uuid:
print(f"_dbphotos['{uuid_}']:")
for p in photos:
# print info on each photo
# catch any errors and continue (because if we're using debug-dump, it might be because of an error)
print(f"photo: {p.uuid}")
print(f"_dbphotos['{p.uuid}']:")
try:
pprint.pprint(photosdb._dbphotos[uuid_])
print(photosdb._dbphotos[p.uuid])
except KeyError:
print(f"Did not find uuid {uuid_} in _dbphotos")
print(f"Did not find uuid {p.uuid} in _dbphotos")
print("PhotoInfo:")
try:
print(p.asdict(shallow=False))
except Exception as e:
print(f"Error dumping PhotoInfo.asdict(): {e}")
print("ZASSET")
print(p.tables().ZASSET.rows_dict())
print("ZADDITIONALASSETATTRIBUTES")
print(p.tables().ZADDITIONALASSETATTRIBUTES.rows_dict())
print("-" * 40)
else:
try:
val = getattr(photosdb, attr)

View File

@ -1,5 +1,7 @@
"""export command for osxphotos CLI"""
from __future__ import annotations
import atexit
import inspect
import os
@ -9,11 +11,12 @@ import shlex
import subprocess
import sys
import time
from typing import Iterable, List, Optional, Tuple
from typing import Any, Callable, Iterable, List, Literal, Optional, Tuple
import click
import osxphotos
import osxphotos.gitignorefile
from osxphotos._constants import (
_EXIF_TOOL_URL,
_OSXPHOTOS_NONE_SENTINEL,
@ -45,16 +48,11 @@ from osxphotos.path_utils import is_valid_filepath, sanitize_filename, sanitize_
from osxphotos.photoexporter import ExportOptions, ExportResults, PhotoExporter
from osxphotos.photoinfo import PhotoInfoNone
from osxphotos.phototemplate import PhotoTemplate, RenderOptions
from osxphotos.platform import get_macos_version, is_macos
from osxphotos.queryoptions import load_uuid_from_file, query_options_from_kwargs
from osxphotos.unicode import normalize_fs_path
from osxphotos.uti import get_preferred_uti_extension
from osxphotos.utils import (
format_sec_to_hhmmss,
get_macos_version,
is_macos,
normalize_fs_path,
pluralize,
under_test,
)
from osxphotos.utils import format_sec_to_hhmmss, pluralize, under_test
if is_macos:
from osxmetadata import (
@ -93,9 +91,10 @@ from .common import (
)
from .help import ExportCommand, get_help_msg
from .list import _list_libraries
from .param_types import ExportDBType, FunctionCall, TemplateString
from .param_types import CSVOptions, ExportDBType, FunctionCall, TemplateString
from .report_writer import ReportWriterNoOp, export_report_writer_factory
from .rich_progress import rich_progress
from .sidecar import generate_user_sidecar
from .verbose import get_verbose_console, verbose_print
@ -302,6 +301,15 @@ from .verbose import get_verbose_console, verbose_print
"Note: --download-missing does not currently export all burst images; "
"only the primary photo will be exported--associated burst images will be skipped.",
)
@click.option(
"--export-aae",
is_flag=True,
help="Also export an adjustments file detailing edits made to the original. "
"The resulting file is named photoname.AAE. "
"Note that to import these files back to Photos succesfully, you also need to "
"export the edited photo and match the filename format Photos.app expects: "
"--filename 'IMG_{edited_version?E,}{id:04d}' --edited-suffix ''",
)
@click.option(
"--sidecar",
default=None,
@ -335,6 +343,53 @@ from .verbose import get_verbose_console, verbose_print
"Warning: this may result in sidecar filename collisions if there are files of different "
"types but the same name in the output directory, e.g. 'IMG_1234.JPG' and 'IMG_1234.MOV'.",
)
@click.option(
"--sidecar-template",
metavar="MAKO_TEMPLATE_FILE SIDECAR_FILENAME_TEMPLATE OPTIONS",
multiple=True,
type=click.Tuple(
[
click.Path(dir_okay=False, file_okay=True, exists=True),
TemplateString(),
CSVOptions(
[
"write_skipped",
"strip_whitespace",
"strip_lines",
"skip_zero",
"catch_errors",
"none",
]
),
]
),
help="Create a custom sidecar file for each photo exported with user provided Mako template (MAKO_TEMPLATE_FILE). "
"MAKO_TEMPLATE_FILE must be a valid Mako template (see https://www.makotemplates.org/). "
"The template will passed the following variables: photo (PhotoInfo object for the photo being exported), "
"sidecar_path (pathlib.Path object for the path to the sidecar being written), and "
"photo_path (pathlib.Path object for the path to the exported photo. "
"SIDECAR_FILENAME_TEMPLATE must be a valid template string (see Templating System in help) "
"which will be rendered to generate the filename of the sidecar file. "
"The `{filepath}` template variable may be used in the SIDECAR_FILENAME_TEMPLATE to refer to the filename of the "
"photo being exported. "
"OPTIONS is a comma-separated list of strings providing additional options to the template. "
"Valid options are: write_skipped, strip_whitespace, strip_lines, skip_zero, catch_errors, none. "
"write_skipped will cause the sidecar file to be written even if the photo is skipped during export. "
"If write_skipped is not passed as an option, the sidecar file will not be written if the photo is skipped during export. "
"strip_whitespace and strip_lines indicate whether or not to strip whitespace and blank lines, respectively, "
"from the resulting sidecar file. "
"skip_zero causes the sidecar file to be skipped if the rendered template is zero-length. "
"catch_errors causes errors in the template to be caught and logged but not raised. "
"Without catch_errors, osxphotos will abort the export if an error occurs in the template. "
"For example, to create a sidecar file with extension .xmp using a template file named 'sidecar.mako' "
"and write a sidecar for skipped photos and strip blank lines but not whitespace: "
"`--sidecar-template sidecar.mako '{filepath}.xmp' write_skipped,strip_lines`. "
"To do the same but to drop the photo extension from the sidecar filename: "
"`--sidecar-template sidecar.mako '{filepath.parent}/{filepath.stem}.xmp' write_skipped,strip_lines`. "
"If you are not passing any options, you must pass 'none' as the last argument to --sidecar-template: "
"`--sidecar-template sidecar.mako '{filepath}.xmp' none`. "
"For an example Mako file see https://raw.githubusercontent.com/RhetTbull/osxphotos/main/examples/custom_sidecar.mako",
)
@click.option(
"--exiftool",
is_flag=True,
@ -558,27 +613,43 @@ from .verbose import get_verbose_console, verbose_print
"For example, photos which had previously been exported and were subsequently deleted in Photos. "
"WARNING: --cleanup will delete *any* files in the export directory that were not exported by osxphotos, "
"for example, your own scripts or other files. Be sure this is what you intend before using "
"--cleanup. Use --dry-run with --cleanup first if you're not certain.",
"--cleanup. Use --dry-run with --cleanup first if you're not certain. "
"To prevent files not generated by osxphotos from being deleted, you may specify one or more rules"
"in a file named `.osxphotos_keep` in the export directory. "
"This file uses the same format as a .gitignore file and should contain one rule per line; "
"lines starting with a `#` will be ignored. "
"Reference https://git-scm.com/docs/gitignore#_pattern_format for details. "
"In addition to the standard .gitignore rules, the rules may also be the absolute path to a file or directory. "
"For example if export destination is `/Volumes/Photos` and you want to keep all `.txt` files, "
'in the top level of the export directory, you can specify `/*.txt"` in the .osxphotos_keep file. '
"If you want to keep all `.txt` files in the export directory and all subdirectories, "
"you can specify `**/*.txt`. "
"If present, the .osxphotos_keep file will be read after the export is completed and any rules found in the file "
"will be added to the list of rules to keep. "
"See also --keep.",
)
@click.option(
"--keep",
metavar="KEEP_PATH",
metavar="KEEP_RULE",
nargs=1,
multiple=True,
help="When used with --cleanup, prevents file or directory KEEP_PATH from being deleted "
help="When used with --cleanup, prevents file or directory matching KEEP_RULE from being deleted "
"when cleanup is run. Use this if there are files in the export directory that you don't "
"want to be deleted when --cleanup is run. "
"KEEP_PATH may be a file path, e.g. '/Volumes/Photos/keep.jpg', "
"or a file path and wild card, e.g. '/Volumes/Photos/*.txt', "
"or a directory, e.g. '/Volumes/Photos/KeepMe'. "
"KEEP_PATH may be an absolute path or a relative path. "
"If it is relative, it must be relative to the export destination. "
"KEEP_RULE follows the same format rules a .gitignore file. "
"Reference https://git-scm.com/docs/gitignore#_pattern_format for details. "
"In addition to the standard .gitignore rules, KEEP_RULE may also be the absolute path to a file or directory. "
"For example if export destination is `/Volumes/Photos` and you want to keep all `.txt` files, "
'you can specify `--keep "/Volumes/Photos/*.txt"` or `--keep "*.txt"`. '
"If wild card is used, KEEP_PATH must be enclosed in quotes to prevent the shell from expanding the wildcard, "
'e.g. `--keep "/Volumes/Photos/*.txt"`. '
"If KEEP_PATH is a directory, all files and directories contained in KEEP_PATH will be kept. "
"--keep may be repeated to keep additional files/directories.",
'in the top level of the export directory, you can specify `--keep "/*.txt"`. '
"If you want to keep all `.txt` files in the export directory and all subdirectories, "
'you can specify `--keep "**/*.txt"`. '
"If wild card is used, KEEP_RULE must be enclosed in quotes to prevent the shell from expanding the wildcard. "
"--keep may be repeated to keep additional files/directories. "
"Rules may also be included in a file named `.osxphotos_keep` in the export directory. "
"If present, this file will be read after the export is completed and any rules found in the file "
"will be added to the list of rules to keep. "
"This file uses the same format as a .gitignore file and should contain one rule per line; "
"lines starting with a `#` will be ignored. ",
)
@click.option(
"--add-exported-to-album",
@ -614,11 +685,22 @@ from .verbose import get_verbose_console, verbose_print
"COMMAND is an osxphotos template string, for example: '--post-command exported \"echo {filepath|shell_quote} >> {export_dir}/exported.txt\"', "
"which appends the full path of all exported files to the file 'exported.txt'. "
"You can run more than one command by repeating the '--post-command' option with different arguments. "
"See also --post-command-error and --post-function."
"See Post Command below.",
type=click.Tuple(
[click.Choice(POST_COMMAND_CATEGORIES, case_sensitive=False), TemplateString()]
),
)
@click.option(
"--post-command-error",
metavar="ACTION",
help="Specify either `continue` or `break` for ACTION to control behavior when a post-command fails. "
"If `continue`, osxphotos will log the error and continue processing. "
"If `break`, osxphotos will stop processing any additional --post-command commands for the current photo "
"but will continue with the export. "
"Without --post-command-error, osxphotos will abort the export if a post-command encounters an error. ",
type=click.Choice(["continue", "break"], case_sensitive=False),
)
@click.option(
"--post-function",
metavar="filename.py::function",
@ -841,6 +923,7 @@ def export(
place,
portrait,
post_command,
post_command_error,
post_function,
preview,
preview_if_missing,
@ -857,8 +940,10 @@ def export(
screenshot,
selfie,
shared,
export_aae,
sidecar,
sidecar_drop_ext,
sidecar_template,
skip_bursts,
skip_edited,
skip_live,
@ -890,6 +975,10 @@ def export(
not_syndicated,
saved_to_library,
not_saved_to_library,
shared_moment,
not_shared_moment,
shared_library,
not_shared_library,
selected=False, # Isn't provided on unsupported platforms
# debug, # debug, watch, breakpoint handled in cli/__init__.py
# watch,
@ -990,6 +1079,7 @@ def export(
exiftool_merge_persons = cfg.exiftool_merge_persons
exiftool_option = cfg.exiftool_option
exiftool_path = cfg.exiftool_path
export_aae = cfg.export_aae
export_as_hardlink = cfg.export_as_hardlink
export_by_date = cfg.export_by_date
exportdb = cfg.exportdb
@ -1048,10 +1138,14 @@ def export(
not_panorama = cfg.not_panorama
not_portrait = cfg.not_portrait
not_reference = cfg.not_reference
not_saved_to_library = cfg.not_saved_to_library
not_screenshot = cfg.not_screenshot
not_selfie = cfg.not_selfie
not_shared = cfg.not_shared
not_shared_library = cfg.not_shared_library
not_shared_moment = cfg.not_shared_moment
not_slow_mo = cfg.not_slow_mo
not_syndicated = cfg.not_syndicated
not_time_lapse = cfg.not_time_lapse
only_movies = cfg.only_movies
only_new = cfg.only_new
@ -1065,6 +1159,7 @@ def export(
place = cfg.place
portrait = cfg.portrait
post_command = cfg.post_command
post_command_error = cfg.post_command_error
post_function = cfg.post_function
preview = cfg.preview
preview_if_missing = cfg.preview_if_missing
@ -1077,12 +1172,16 @@ def export(
replace_keywords = cfg.replace_keywords
report = cfg.report
retry = cfg.retry
saved_to_library = cfg.saved_to_library
screenshot = cfg.screenshot
selected = cfg.selected
selfie = cfg.selfie
shared = cfg.shared
shared_library = cfg.shared_library
shared_moment = cfg.shared_moment
sidecar = cfg.sidecar
sidecar_drop_ext = cfg.sidecar_drop_ext
sidecar_template = cfg.sidecar_template
skip_bursts = cfg.skip_bursts
skip_edited = cfg.skip_edited
skip_live = cfg.skip_live
@ -1092,6 +1191,7 @@ def export(
skip_uuid_from_file = cfg.skip_uuid_from_file
slow_mo = cfg.slow_mo
strip = cfg.strip
syndicated = cfg.syndicated
theme = cfg.theme
time_lapse = cfg.time_lapse
timestamp = cfg.timestamp
@ -1107,14 +1207,11 @@ def export(
uti = cfg.uti
uuid = cfg.uuid
uuid_from_file = cfg.uuid_from_file
# this is the one option that is named differently in the config file than the variable passed by --verbose (verbose_flag)
verbose_flag = cfg.verbose
verbose_flag = (
cfg.verbose
) # this is named differently in the config file than the variable passed by --verbose (verbose_flag)
xattr_template = cfg.xattr_template
year = cfg.year
syndicated = cfg.syndicated
not_syndicated = cfg.not_syndicated
saved_to_library = cfg.saved_to_library
not_saved_to_library = cfg.not_saved_to_library
# config file might have changed verbose
verbose = verbose_print(verbose=verbose_flag, timestamp=timestamp, theme=theme)
@ -1166,6 +1263,7 @@ def export(
("title", "no_title"),
("syndicated", "not_syndicated"),
("saved_to_library", "not_saved_to_library"),
("shared_moment", "not_shared_moment"),
]
dependent_options = [
("append", ("report")),
@ -1463,18 +1561,30 @@ def export(
kwargs["photo"] = p
kwargs["photo_num"] = photo_num
export_results = export_photo(**kwargs)
if post_function:
for function in post_function:
# post function is tuple of (function, filename.py::function_name)
verbose(f"Calling post-function [bold]{function[1]}")
if not dry_run:
try:
function[0](p, export_results, verbose)
except Exception as e:
rich_echo_error(
f"[error]Error running post-function [italic]{function[1]}[/italic]: {e}"
)
# generate custom sidecars if needed
if sidecar_template:
export_results += generate_user_sidecar(
photo=p,
export_results=export_results,
sidecar_template=sidecar_template,
exiftool_path=exiftool_path,
export_dir=dest,
dry_run=dry_run,
verbose=verbose,
)
# run post functions
if run_results := run_post_function(
photo=p,
post_function=post_function,
export_results=export_results,
verbose=verbose,
dry_run=dry_run,
):
export_results += run_results
# run post command
run_post_command(
photo=p,
post_command=post_command,
@ -1482,7 +1592,7 @@ def export(
export_dir=dest,
dry_run=dry_run,
exiftool_path=exiftool_path,
export_db=export_db,
on_error=post_command_error,
verbose=verbose,
)
@ -1644,47 +1754,60 @@ def export(
if cleanup:
db_file = str(pathlib.Path(export_db_path).resolve())
db_files = [db_file, db_file + "-wal", db_file + "-shm"]
keep_file = str(pathlib.Path(dest) / ".osxphotos_keep")
all_files = (
results.exported
+ results.skipped
+ results.exif_updated
+ results.touched
+ results.converted_to_jpeg
+ results.aae_written
+ results.sidecar_json_written
+ results.sidecar_json_skipped
+ results.sidecar_exiftool_written
+ results.sidecar_exiftool_skipped
+ results.sidecar_xmp_written
+ results.sidecar_xmp_skipped
+ results.sidecar_user_written
+ results.sidecar_user_skipped
+ results.user_written
+ results.user_skipped
# include missing so a file that was already in export directory
# but was missing on --update doesn't get deleted
# (better to have old version than none)
+ results.missing
# include files that have error in case they exist from previous export
+ [r[0] for r in results.error]
# don't delete export database files
+ db_files
# include the .osxphotos_keep file
+ [keep_file]
)
# if --report, add report file to keep list to prevent it from being deleted
if report:
all_files.append(report)
# gather any files that should be kept from both .osxphotos_keep and --keep
dirs_to_keep = []
if keep:
files_to_keep, dirs_to_keep = collect_files_to_keep(keep, dest)
all_files += files_to_keep
files_to_keep, dirs_to_keep = collect_files_to_keep(keep, dest)
all_files += files_to_keep
rich_echo(f"Cleaning up [filepath]{dest}")
cleaned_files, cleaned_dirs = cleanup_files(
dest, all_files, dirs_to_keep, fileutil, verbose=verbose
)
file_str = "files" if len(cleaned_files) != 1 else "file"
dir_str = "directories" if len(cleaned_dirs) != 1 else "directory"
rich_echo(
f"Deleted: [num]{len(cleaned_files)}[/num] {file_str}, [num]{len(cleaned_dirs)}[/num] {dir_str}"
)
report_writer.write(
ExportResults(deleted_files=cleaned_files, deleted_directories=cleaned_dirs)
)
results.deleted_files = cleaned_files
results.deleted_directories = cleaned_dirs
@ -1707,6 +1830,7 @@ def export_photo(
dest=None,
verbose=None,
export_by_date=None,
export_aae=None,
sidecar=None,
sidecar_drop_ext=False,
update=None,
@ -1754,7 +1878,7 @@ def export_photo(
num_photos=1,
tmpdir=None,
update_errors=False,
):
) -> ExportResults:
"""Helper function for export that does the actual export
Args:
@ -1795,6 +1919,7 @@ def export_photo(
preview_suffix: str, template to use as suffix for preview images
replace_keywords: if True, --keyword-template replaces keywords instead of adding keywords
retry: retry up to retry # of times if there's an error
export_aae: bool; if True, will also save adjustments
sidecar_drop_ext: bool; if True, drops photo extension from sidecar name
sidecar: list zero, 1 or 2 of ["json","xmp"] of sidecar variety to export
skip_original_if_edited: bool; if True does not export original if photo has been edited
@ -1804,6 +1929,7 @@ def export_photo(
use_photos_export: bool; if True forces the use of AppleScript to export even if photo not missing
verbose: callable for verbose output
tmpdir: optional str; temporary directory to use for export
Returns:
list of path(s) of exported photo or None if photo was missing
@ -1961,6 +2087,7 @@ def export_photo(
preview_suffix=rendered_preview_suffix,
replace_keywords=replace_keywords,
retry=retry,
export_aae=export_aae,
sidecar_drop_ext=sidecar_drop_ext,
sidecar_flags=sidecar_flags,
touch_file=touch_file,
@ -2077,6 +2204,7 @@ def export_photo(
preview_suffix=rendered_preview_suffix,
replace_keywords=replace_keywords,
retry=retry,
export_aae=export_aae,
sidecar_drop_ext=sidecar_drop_ext,
sidecar_flags=sidecar_flags if not export_original else 0,
touch_file=touch_file,
@ -2164,6 +2292,7 @@ def export_photo_to_directory(
preview_suffix,
replace_keywords,
retry,
export_aae,
sidecar_drop_ext,
sidecar_flags,
touch_file,
@ -2173,7 +2302,7 @@ def export_photo_to_directory(
use_photokit,
verbose,
tmpdir,
):
) -> ExportResults:
"""Export photo to directory dest_path"""
results = ExportResults()
@ -2228,6 +2357,7 @@ def export_photo_to_directory(
render_options=render_options,
replace_keywords=replace_keywords,
rich=True,
export_aae=export_aae,
sidecar=sidecar_flags,
sidecar_drop_ext=sidecar_drop_ext,
tmpdir=tmpdir,
@ -2467,22 +2597,40 @@ def collect_files_to_keep(
"""Collect all files to keep for --keep/--cleanup.
Args:
keep: Iterable of filepaths to keep; each path may be a filepath, a filepath/wildcard, or a directory path.
keep: Iterable of patterns to keep; each pattern is a pattern that follows gitignore syntax
export_dir: the export directory which will be used to resolve paths when paths in keep are relative instead of absolute
Returns:
tuple of [files_to_keep], [dirs_to_keep]
"""
export_dir = pathlib.Path(export_dir)
keepers = []
export_dir = pathlib.Path(export_dir).expanduser()
export_dir_str = str(export_dir)
KEEP_RULEs = []
# parse .osxphotos_keep file if it exists
keep_file: pathlib.Path = export_dir / ".osxphotos_keep"
if keep_file.is_file():
for line in keep_file.read_text().splitlines():
line = line.rstrip("\r\n")
KEEP_RULEs.append(line)
# parse any patterns passed via --keep
# do this after the file so negations to the file could be applied via --keep
for k in keep:
keeper = pathlib.Path(k).expanduser()
if not keeper.is_absolute():
# relative path: relative to export_dir
keeper = export_dir / keeper
if keeper.is_dir():
keepers.extend(keeper.glob("**/*"))
keepers.extend(keeper.parent.glob(keeper.name))
if k.startswith(export_dir_str):
# allow full path to be specified for keep (e.g. --keep /path/to/file)
KEEP_RULEs.append(k.replace(export_dir_str, ""))
else:
KEEP_RULEs.append(k)
if not KEEP_RULEs:
return [], []
# have some rules to apply
matcher = osxphotos.gitignorefile.parse_pattern_list(KEEP_RULEs, export_dir)
keepers = []
keepers = [path for path in export_dir.rglob("*") if matcher(path)]
files_to_keep = [str(k) for k in keepers if k.is_file()]
dirs_to_keep = [str(k) for k in keepers if k.is_dir()]
return files_to_keep, dirs_to_keep
@ -2711,20 +2859,52 @@ def write_extended_attributes(
return list(written), [f for f in skipped if f not in written]
def run_post_function(
photo: osxphotos.PhotoInfo,
post_function: tuple[
tuple[
Callable[
[osxphotos.PhotoInfo, ExportResults, Callable[[Any], None]],
None | ExportResults,
],
str,
],
...,
],
export_results: ExportResults,
verbose: Callable[[Any], None],
dry_run: bool,
) -> ExportResults:
"""Run the --post-function functions"""
returned_results = ExportResults()
for function in post_function:
# post function is tuple of (function, filename.py::function_name)
verbose(f"Calling post-function [bold]{function[1]}")
if not dry_run:
try:
if results := function[0](photo, export_results, verbose):
returned_results += results
except Exception as e:
rich_echo_error(
f"[error]Error running post-function [italic]{function[1]}[/italic]: {e}"
)
raise e
return returned_results
def run_post_command(
photo,
post_command,
export_results,
export_dir,
dry_run,
exiftool_path,
export_db,
verbose,
photo: osxphotos.PhotoInfo,
post_command: tuple[tuple[str, str]],
export_results: ExportResults,
export_dir: str | pathlib.Path,
dry_run: bool,
exiftool_path: str,
on_error: Literal["break", "continue"] | None,
verbose: Callable[[Any], None],
):
"""Run --post-command commands"""
# todo: pass in RenderOptions from export? (e.g. so it contains strip, etc?)
# todo: need a shell_quote template type:
# {shell_quote,{filepath}/foo/bar}
# that quotes everything in the default value
for category, command_template in post_command:
files = getattr(export_results, category)
for f in files:
@ -2738,7 +2918,6 @@ def run_post_command(
if command:
verbose(f'Running command: "{command}"')
if not dry_run:
args = shlex.split(command)
cwd = pathlib.Path(f).parent
run_error = None
run_results = None
@ -2747,11 +2926,18 @@ def run_post_command(
except Exception as e:
run_error = e
finally:
run_error = run_error or run_results.returncode
if run_error:
rich_echo_error(
f'[error]Error running command "{command}": {run_error}'
)
returncode = run_results.returncode if run_results else None
if run_error or returncode:
# there was an error running the command
error_str = f'Error running command "{command}": return code: {returncode}, exception: {run_error}'
rich_echo_error(f"[error]{error_str}[/]")
if not on_error:
# no error handling specified, raise exception
raise RuntimeError(error_str)
if on_error == "break":
# break out of loop and return
return
# else on_error must be continue
def render_and_validate_report(report: str, exiftool_path: str, export_dir: str) -> str:

View File

@ -19,14 +19,14 @@ from osxphotos.export_db_utils import (
export_db_backup,
export_db_check_signatures,
export_db_get_errors,
export_db_get_last_library,
export_db_get_last_run,
export_db_get_version,
export_db_migrate_photos_library,
export_db_save_config_to_file,
export_db_touch_files,
export_db_update_signatures,
export_db_vacuum,
export_db_migrate_photos_library,
export_db_get_last_library,
)
from osxphotos.utils import pluralize

View File

@ -20,7 +20,7 @@ from osxphotos.phototemplate import (
TEMPLATE_SUBSTITUTIONS_PATHLIB,
get_template_help,
)
from osxphotos.utils import is_macos
from osxphotos.platform import is_macos
if is_macos:
from osxmetadata import MDITEM_ATTRIBUTE_DATA, MDITEM_ATTRIBUTE_SHORT_NAMES

View File

@ -41,8 +41,10 @@ from osxphotos.exiftool import ExifToolCaching, get_exiftool_path
from osxphotos.photoinfo import PhotoInfoNone
from osxphotos.photosalbum import PhotosAlbumPhotoScript
from osxphotos.phototemplate import PhotoTemplate, RenderOptions
from osxphotos.platform import assert_macos
from osxphotos.sqlitekvstore import SQLiteKVStore
from osxphotos.utils import assert_macos, pluralize
from osxphotos.unicode import normalize_unicode
from osxphotos.utils import pluralize
assert_macos()
@ -357,11 +359,12 @@ def set_photo_metadata(
merge_keywords: bool,
) -> MetaData:
"""Set metadata (title, description, keywords) for a Photo object"""
photo.title = metadata.title
photo.description = metadata.description
photo.title = normalize_unicode(metadata.title)
photo.description = normalize_unicode(metadata.description)
keywords = metadata.keywords.copy()
keywords = normalize_unicode(keywords)
if merge_keywords:
if old_keywords := photo.keywords:
if old_keywords := normalize_unicode(photo.keywords):
keywords.extend(old_keywords)
keywords = list(set(keywords))
photo.keywords = keywords
@ -420,7 +423,7 @@ def set_photo_title(
verbose(
f"Setting title of photo [filename]{filepath.name}[/] to '{title_text[0]}'"
)
photo.title = title_text[0]
photo.title = normalize_unicode(title_text[0])
return title_text[0]
else:
return ""
@ -448,7 +451,7 @@ def set_photo_description(
verbose(
f"Setting description of photo [filename]{filepath.name}[/] to '{description_text[0]}'"
)
photo.description = description_text[0]
photo.description = normalize_unicode(description_text[0])
return description_text[0]
else:
return ""
@ -469,8 +472,9 @@ def set_photo_keywords(
kw = render_photo_template(filepath, relative_filepath, keyword, exiftool_path)
keywords.extend(kw)
if keywords:
keywords = normalize_unicode(keywords)
if merge:
if old_keywords := photo.keywords:
if old_keywords := normalize_unicode(photo.keywords):
keywords.extend(old_keywords)
keywords = list(set(keywords))
verbose(f"Setting keywords of photo [filename]{filepath.name}[/] to {keywords}")
@ -1418,7 +1422,13 @@ def import_cli(
verbose_flag,
walk,
):
"""Import photos and videos into Photos."""
"""Import photos and videos into Photos. Photos will be imported into the
most recently opened Photos library.
Photos are imported one at a time thus the "Imports" album in Photos will show
a new import group for each photo imported. Batch import into a single import
group will be added in a future release.
"""
verbose = verbose_print(verbose=verbose_flag, timestamp=timestamp, theme=theme)

View File

@ -101,6 +101,22 @@ def orphans(ctx, cli_obj, export, db, verbose_flag, timestamp, theme):
)
scan_for_files(directory, uuids_in_library)
# scopes directory (Photos 7+)
if photosdb.photos_version >= 7:
verbose_("Scanning scopes cloudsharing files")
directory = joinpath(
photosdb.library_path, "scopes", "cloudsharing", "resources"
)
scan_for_files(directory, uuids_in_library)
verbose_("Scanning scopes syndication files")
directory = joinpath(photosdb.library_path, "scopes", "syndication")
scan_for_files(directory, uuids_in_library)
verbose_("Scanning scopes momentshared files")
directory = joinpath(photosdb.library_path, "scopes", "momentshared")
scan_for_files(directory, uuids_in_library)
# find orphans
possible_orphans = []
for uuid, files in uuids_in_library.items():

View File

@ -1,4 +1,7 @@
"""Click parameter types for osxphotos CLI"""
from __future__ import annotations
import datetime
import os
import pathlib
@ -18,6 +21,8 @@ from osxphotos.utils import expand_and_validate_filepath, load_function
__all__ = [
"BitMathSize",
"BooleanString",
"CSVOptions",
"DateOffset",
"DateTimeISO8601",
"DeprecatedPath",
@ -302,3 +307,46 @@ class Longitude(click.ParamType):
self.fail(
f"Invalid longitude {value}. Must be a floating point number between -180 and 180."
)
class BooleanString(click.ParamType):
"""A boolean string in the format True/False, Yes/No, T/F, Y/N, 1/0 (case insensitive)"""
name = "BooleanString"
def convert(self, value, param, ctx):
if value.lower() in ["true", "yes", "t", "y", "1"]:
return True
elif value.lower() in ["false", "no", "f", "n", "0"]:
return False
else:
self.fail(
f"Invalid boolean string {value}. Must be one of True/False, Yes/No, T/F, Y/N, 1/0 (case insensitive)."
)
class CSVOptions(click.ParamType):
"""A comma-separated list of option values, not case sensitive"""
name = "CSVOptions"
def __init__(self, options: list[str]):
"""Initialize CSVOptions
Args:
options: list of valid options as str
Note:
The convert method returns a tuple[str, ...] of the options selected
"""
self._csv_options = options
def convert(self, value, param, ctx) -> tuple[str, ...]:
values = value.split(",")
values = [v.lower().strip() for v in values]
for v in values:
if v not in self._csv_options:
self.fail(
f"Invalid option {v}. Must be one of {','.join(self._csv_options)}"
)
return tuple(values)

View File

@ -20,8 +20,9 @@ from rich.panel import Panel
from osxphotos import PhotoInfo, PhotosDB
from osxphotos._constants import _UNKNOWN_PERSON, search_category_factory
from osxphotos.platform import assert_macos
from osxphotos.rich_utils import add_rich_markup_tag
from osxphotos.utils import assert_macos, dd_to_dms_str
from osxphotos.utils import dd_to_dms_str
assert_macos()
@ -175,6 +176,18 @@ def inspect_photo(
if photo.moment_info:
properties.append(bold("Moment: ") + f"{photo.moment_info.title or '-'}")
if photo.shared_moment:
info = photo.shared_moment_info
title = info.title if info else "-"
expiry = info.expiry_date.isoformat() if info and info.expiry_date else "-"
share_url = info.share_url if info else "-"
properties.append(
bold("Shared Moment: ") + f"{title} expiry: {expiry} url: {share_url}"
)
if photo.syndicated:
...
if photo.comments:
comments = [f"{c.user}: {c.text}" for c in photo.comments]
properties.append(
@ -259,6 +272,13 @@ def format_flags(photo: PhotoInfo) -> str:
flags.append("in cloud")
if photo.shared:
flags.append("shared")
if photo.syndicated:
flags.append("syndicated") # sourcery skip
flags.append(
"saved to library" if photo.saved_to_library else "not saved to library"
)
if photo.shared_library:
flags.append("shared iCloud library")
flag_str += f"{', '.join(flags) or '-'}"
return flag_str

View File

@ -1,6 +1,7 @@
"""query command for osxphotos CLI"""
import sys
import click
import osxphotos
@ -11,8 +12,8 @@ from osxphotos.cli.click_rich_echo import (
)
from osxphotos.debug import set_debug
from osxphotos.phototemplate import RenderOptions
from osxphotos.platform import assert_macos, is_macos
from osxphotos.queryoptions import query_options_from_kwargs
from osxphotos.utils import assert_macos, is_macos
if is_macos:
from osxphotos.photosalbum import PhotosAlbum
@ -51,6 +52,9 @@ MACOS_OPTIONS = make_click_option_decorator(
@click.command()
@DB_OPTION
@JSON_OPTION
@click.option(
"--count", is_flag=True, help="Print count of photos matching query and exit."
)
@QUERY_OPTIONS
@DELETED_OPTIONS
@MACOS_OPTIONS
@ -81,6 +85,7 @@ def query(
db,
field,
json_,
count,
print_template,
quiet,
photos_library,
@ -136,6 +141,10 @@ def query(
# below needed for to make CliRunner work for testing
cli_json = cli_obj.json if cli_obj is not None else None
if count:
click.echo(len(photos))
return
if add_to_album and photos:
assert_macos()

View File

@ -20,13 +20,13 @@ from osxphotos._constants import _PHOTOS_4_VERSION
from osxphotos.cli.click_rich_echo import rich_echo_error as echo_error
from osxphotos.photoinfo import PhotoInfo
from osxphotos.photosdb import PhotosDB
from osxphotos.platform import assert_macos, is_macos
from osxphotos.pyrepl import embed_repl
from osxphotos.queryoptions import (
IncompatibleQueryOptions,
QueryOptions,
query_options_from_kwargs,
)
from osxphotos.utils import assert_macos, is_macos
if is_macos:
import photoscript

View File

@ -98,6 +98,11 @@ class ExportReportWriterCSV(ReportWriterABC):
"cleanup_deleted_file",
"cleanup_deleted_directory",
"exported_album",
"sidecar_user",
"sidecar_user_error",
"user_written",
"user_skipped",
"user_error",
]
mode = "a" if append else "w"
@ -197,9 +202,9 @@ class ExportReportWriterSQLite(ReportWriterABC):
cursor = self._conn.cursor()
cursor.execute(
"INSERT INTO report "
"(datetime, filename, exported, new, updated, skipped, exif_updated, touched, converted_to_jpeg, sidecar_xmp, sidecar_json, sidecar_exiftool, missing, error, exiftool_warning, exiftool_error, extended_attributes_written, extended_attributes_skipped, cleanup_deleted_file, cleanup_deleted_directory, exported_album, report_id) "
"(datetime, filename, exported, new, updated, skipped, exif_updated, touched, converted_to_jpeg, sidecar_xmp, sidecar_json, sidecar_exiftool, missing, error, exiftool_warning, exiftool_error, extended_attributes_written, extended_attributes_skipped, cleanup_deleted_file, cleanup_deleted_directory, exported_album, report_id, sidecar_user, sidecar_user_error, user_written, user_skipped, user_error) " # noqa
"VALUES "
"(:datetime, :filename, :exported, :new, :updated, :skipped, :exif_updated, :touched, :converted_to_jpeg, :sidecar_xmp, :sidecar_json, :sidecar_exiftool, :missing, :error, :exiftool_warning, :exiftool_error, :extended_attributes_written, :extended_attributes_skipped, :cleanup_deleted_file, :cleanup_deleted_directory, :exported_album, :report_id);",
"(:datetime, :filename, :exported, :new, :updated, :skipped, :exif_updated, :touched, :converted_to_jpeg, :sidecar_xmp, :sidecar_json, :sidecar_exiftool, :missing, :error, :exiftool_warning, :exiftool_error, :extended_attributes_written, :extended_attributes_skipped, :cleanup_deleted_file, :cleanup_deleted_directory, :exported_album, :report_id, :sidecar_user, :sidecar_user_error, :user_written, :user_skipped, :user_error);", # noqa
data,
)
self._conn.commit()
@ -262,6 +267,39 @@ class ExportReportWriterSQLite(ReportWriterABC):
self._conn.cursor().execute("ALTER TABLE report ADD COLUMN report_id TEXT;")
self._conn.commit()
# migrate report table and add sidecar_user column if needed (#1123)
if "sidecar_user" not in sqlite_columns(self._conn, "report"):
self._conn.cursor().execute(
"ALTER TABLE report ADD COLUMN sidecar_user INTEGER;"
)
self._conn.commit()
# migrate report table and add sidecar_user_error if needed (#1123)
if "sidecar_user_error" not in sqlite_columns(self._conn, "report"):
self._conn.cursor().execute(
"ALTER TABLE report ADD COLUMN sidecar_user_error TEXT;"
)
self._conn.commit()
# migrate report table and add user_written, skipped, error if needed (#1136)
if "user_written" not in sqlite_columns(self._conn, "report"):
self._conn.cursor().execute(
"ALTER TABLE report ADD COLUMN user_written INTEGER;"
)
self._conn.commit()
if "user_skipped" not in sqlite_columns(self._conn, "report"):
self._conn.cursor().execute(
"ALTER TABLE report ADD COLUMN user_skipped INTEGER;"
)
self._conn.commit()
if "user_error" not in sqlite_columns(self._conn, "report"):
self._conn.cursor().execute(
"ALTER TABLE report ADD COLUMN user_error TEXT;"
)
self._conn.commit()
# create report_summary view
c.execute(
"""
@ -347,6 +385,11 @@ def prepare_export_results_for_writing(
"cleanup_deleted_file": false,
"cleanup_deleted_directory": false,
"exported_album": "",
"sidecar_user": false,
"sidecar_user_error": "",
"user_written": false,
"user_skipped": false,
"user_error": "",
}
for result in export_results.exported:
@ -421,6 +464,28 @@ def prepare_export_results_for_writing(
for result, album in export_results.exported_album:
all_results[str(result)]["exported_album"] = album
for result in export_results.sidecar_user_written:
all_results[str(result)]["sidecar_user"] = true
all_results[str(result)]["exported"] = true
for result in export_results.sidecar_user_skipped:
all_results[str(result)]["sidecar_user"] = true
all_results[str(result)]["skipped"] = true
for result in export_results.sidecar_user_error:
all_results[str(result[0])]["sidecar_user_error"] = result[1]
for result in export_results.user_written:
all_results[str(result)]["user_written"] = true
all_results[str(result)]["exported"] = true
for result in export_results.user_skipped:
all_results[str(result)]["user_skipped"] = true
all_results[str(result)]["skipped"] = true
for result in export_results.user_error:
all_results[str(result[0])]["user_error"] = result[1]
return all_results

View File

@ -8,7 +8,8 @@ import click
from osxphotos._constants import UUID_PATTERN
from osxphotos.export_db_utils import get_uuid_for_filepath
from osxphotos.photosdb.photosdb_utils import get_photos_library_version
from osxphotos.utils import get_last_library_path, assert_macos
from osxphotos.platform import assert_macos
from osxphotos.utils import get_last_library_path
assert_macos()

181
osxphotos/cli/sidecar.py Normal file
View File

@ -0,0 +1,181 @@
"""Generate custom sidecar files for use wit `osxphotos export` command and --sidecar-template option"""
from __future__ import annotations
import pathlib
from functools import cache
from typing import Callable
import click
from mako.template import Template
from osxphotos.cli.click_rich_echo import rich_echo_error
from osxphotos.photoexporter import ExportResults
from osxphotos.photoinfo import PhotoInfo
from osxphotos.phototemplate import PhotoTemplate, RenderOptions
@cache
def get_template(template: str) -> Template:
"""Get template from cache or load from file"""
return Template(filename=template)
def generate_user_sidecar(
photo: PhotoInfo,
export_results: ExportResults,
sidecar_template: tuple[tuple[str, str, tuple[str, ...]], ...],
exiftool_path: str,
export_dir: str,
dry_run: bool,
verbose: Callable[..., None],
) -> ExportResults:
"""Generate custom sidecar files for use with `osxphotos export` command and --sidecar-template option
Args:
photo: PhotoInfo object for photo
export_results: ExportResults object
sidecar_template: tuple of (template_file, filename_template) for sidecar template
strip_sidecar: bool, strip whitespace and blank lines from sidecar
exiftool_path: str, path to exiftool
export_dir: str, path to export directory
dry_run: bool, if True, do not actually write sidecar files
verbose: Callable[..., None], verbose logging function
Returns:
ExportResults object with sidecar_user_written and sidecar_user_skipped set
"""
sidecar_results = ExportResults()
for (
template_file,
filename_template,
options,
) in sidecar_template:
strip_whitespace = "strip_whitespace" in options
strip_lines = "strip_lines" in options
write_skipped = "write_skipped" in options
skip_zero = "skip_zero" in options
catch_errors = "catch_errors" in options
if not write_skipped:
# skip writing sidecar if photo not exported
# but if run with --update and --cleanup, a sidecar file may have been written
# in the past, so check if it exists and if so keep it
for filepath in export_results.skipped:
template_filename = _render_sidecar_filename(
photo=photo,
filepath=filepath,
filename_template=filename_template,
export_dir=export_dir,
exiftool_path=exiftool_path,
)
if template_filename and pathlib.Path(template_filename).exists():
verbose(
f"Skipping existing sidecar file [filepath]{template_filename}[/]"
)
sidecar_results.sidecar_user_skipped.append(template_filename)
# write sidecar files for exported and missing files (and skipped if write_skipped)
files_to_process = export_results.exported + export_results.missing
if write_skipped:
files_to_process += export_results.skipped
for filepath in files_to_process:
template_filename = _render_sidecar_filename(
photo=photo,
filepath=filepath,
filename_template=filename_template,
export_dir=export_dir,
exiftool_path=exiftool_path,
)
if not template_filename:
raise click.BadOptionUsage(
f"Invalid SIDECAR_FILENAME_TEMPLATE for --sidecar-template '{filename_template}'"
)
verbose(f"Writing sidecar file [filepath]{template_filename}[/]")
if error := _render_sidecar_and_write_data(
template_file=template_file,
photo=photo,
template_filename=template_filename,
filepath=filepath,
strip_whitespace=strip_whitespace,
strip_lines=strip_lines,
skip_zero=skip_zero,
catch_errors=catch_errors,
verbose=verbose,
dry_run=dry_run,
):
sidecar_results.sidecar_user_error.append((template_filename, error))
else:
sidecar_results.sidecar_user_written.append(template_filename)
print(sidecar_results)
return sidecar_results
def _render_sidecar_filename(
photo: PhotoInfo,
filepath: str,
filename_template: str,
export_dir: str,
exiftool_path: str,
):
"""Render sidecar filename template"""
render_options = RenderOptions(export_dir=export_dir, filepath=filepath)
photo_template = PhotoTemplate(photo, exiftool_path=exiftool_path)
template_filename, _ = photo_template.render(
filename_template, options=render_options
)
template_filename = template_filename[0] if template_filename else None
return template_filename
def _render_sidecar_and_write_data(
template_file: str,
photo: PhotoInfo,
template_filename: str,
filepath: str,
strip_whitespace: bool,
strip_lines: bool,
skip_zero: bool,
catch_errors: bool,
verbose: Callable[..., None],
dry_run: bool,
) -> Exception | None:
"""Render sidecar template and write data to file
Returns:
None if no errors, otherwise Exception if catch_errors is True
If catch_errors is False, raises exception if error
"""
sidecar = get_template(template_file)
try:
sidecar_data = sidecar.render(
photo=photo,
sidecar_path=pathlib.Path(template_filename),
photo_path=pathlib.Path(filepath),
)
except Exception as e:
if catch_errors:
rich_echo_error(f"[error]Error rendering sidecar template: {e}[/]")
return e
raise e
if strip_whitespace:
# strip whitespace
sidecar_data = "\n".join(line.strip() for line in sidecar_data.split("\n"))
if strip_lines:
# strip blank lines
sidecar_data = "\n".join(
line for line in sidecar_data.split("\n") if line.strip()
)
if not dry_run:
# write sidecar file
if skip_zero and not sidecar_data:
verbose(f"Skipping empty sidecar file [filepath]{template_filename}[/]")
return
with open(template_filename, "w") as f:
f.write(sidecar_data)
return None

View File

@ -15,13 +15,14 @@ from osxphotos.photoinfo import PhotoInfoNone
from osxphotos.photosalbum import PhotosAlbum
from osxphotos.photosdb.photosdb_utils import get_db_version
from osxphotos.phototemplate import PhotoTemplate, RenderOptions
from osxphotos.platform import assert_macos
from osxphotos.queryoptions import (
IncompatibleQueryOptions,
QueryOptions,
query_options_from_kwargs,
)
from osxphotos.sqlitekvstore import SQLiteKVStore
from osxphotos.utils import assert_macos, pluralize
from osxphotos.utils import pluralize
assert_macos()

View File

@ -25,11 +25,13 @@ from osxphotos.photodates import (
update_photo_time_for_new_timezone,
)
from osxphotos.phototz import PhotoTimeZone, PhotoTimeZoneUpdater
from osxphotos.utils import assert_macos, noop, pluralize
from osxphotos.platform import assert_macos
from osxphotos.utils import noop, pluralize
assert_macos()
from photoscript import PhotosLibrary
from osxphotos.photosalbum import PhotosAlbumPhotoScript
from .cli_params import THEME_OPTION, TIMESTAMP_OPTION, VERBOSE_OPTION

View File

@ -2,7 +2,7 @@
import click
from osxphotos.utils import assert_macos
from osxphotos.platform import assert_macos
assert_macos()

View File

@ -219,7 +219,7 @@ def _verbose_print_function(
styled_args = []
timestamp_str = f"{str(datetime.now())} -- " if timestamp else ""
for arg in args:
if type(arg) == str:
if isinstance(arg, str):
arg = timestamp_str + arg
if "error" in arg.lower():
arg = click.style(arg, fg=CLI_COLOR_ERROR)
@ -236,7 +236,7 @@ def _verbose_print_function(
timestamp_str = time_stamp() if timestamp else ""
new_args = []
for arg in args:
if type(arg) == str:
if isinstance(arg, str):
if "error" in arg.lower():
arg = f"[error]{arg}"
if ERROR_EMOJI:
@ -257,7 +257,7 @@ def _verbose_print_function(
timestamp_str = time_stamp() if timestamp else ""
new_args = []
for arg in args:
if type(arg) == str:
if isinstance(arg, str):
if "error" in arg.lower():
arg = f"[error]{arg}"
if ERROR_EMOJI:

View File

@ -1,11 +1,14 @@
"""about command for osxphotos CLI"""
import click
import os
import click
import packaging
from osxphotos._constants import OSXPHOTOS_URL
from osxphotos._version import __version__
from .common import get_latest_version
import packaging
@click.command(name="version")

View File

@ -7,11 +7,13 @@ from osxphotos import PhotosDB
from osxphotos.exiftool import ExifTool
from .datetime_utils import datetime_naive_to_local, datetime_to_new_tz
from .utils import assert_macos, noop
from .platform import assert_macos
from .utils import noop
assert_macos()
from photoscript import Photo
from .exif_datetime_updater import get_exif_date_time_offset
from .phototz import PhotoTimeZone

Binary file not shown.

View File

@ -58,7 +58,7 @@ def exiftool_can_write(suffix: str) -> bool:
def escape_str(s):
"""escape string for use with exiftool -E"""
if type(s) != str:
if not isinstance(s, str):
return s
s = html.escape(s)
s = s.replace("\n", "&#xa;")
@ -69,7 +69,7 @@ def escape_str(s):
def unescape_str(s):
"""unescape an HTML string returned by exiftool -E"""
if type(s) != str:
if not isinstance(s, str):
return s
# avoid " in values which result in json.loads() throwing an exception, #636
s = s.replace("&quot;", '\\"')

View File

@ -27,7 +27,7 @@ import osxphotos
from ._constants import OSXPHOTOS_EXPORT_DB, SQLITE_CHECK_SAME_THREAD
from ._version import __version__
from .fileutil import FileUtil
from .utils import normalize_fs_path
from .unicode import normalize_fs_path
__all__ = [
"ExportDB",

View File

@ -10,7 +10,8 @@ from abc import ABC, abstractmethod
from tempfile import TemporaryDirectory
from .imageconverter import ImageConverter
from .utils import is_macos, normalize_fs_path
from .platform import is_macos
from .unicode import normalize_fs_path
if is_macos:
import Foundation

Some files were not shown because too many files have changed in this diff Show More