Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db5c4a216f | ||
|
|
369fa553e8 | ||
|
|
29968269ff | ||
|
|
381141bc09 | ||
|
|
caa279e394 | ||
|
|
bd01e41714 | ||
|
|
32b23a09cb | ||
|
|
4857598324 | ||
|
|
b937874f66 | ||
|
|
69eb4b070c | ||
|
|
8c46b8e545 | ||
|
|
b6ab618154 |
@@ -464,6 +464,15 @@
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "djbeadle",
|
||||
"name": "Daniel Beadle",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/6235378?v=4",
|
||||
"profile": "https://danielbeadle.net",
|
||||
"contributions": [
|
||||
"ideas"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[bumpversion]
|
||||
current_version = 0.56.3
|
||||
current_version = 0.56.6
|
||||
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)
|
||||
serialize = {major}.{minor}.{patch}
|
||||
|
||||
|
||||
@@ -238,7 +238,7 @@ Returns a list of the keywords found in the Photos library
|
||||
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](#albums) and [burst_album_info](#burst_album_info).
|
||||
|
||||
#### `albums`
|
||||
|
||||
@@ -278,7 +278,7 @@ Returns the [MomentInfo](#momentinfo) object for the photo or `None` if the pho
|
||||
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](#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.
|
||||
|
||||
@@ -402,6 +402,15 @@ photosdb.db_version
|
||||
|
||||
Returns the version number for Photos library database. You likely won't need this but it's provided in case needed for debugging. PhotosDB will print a warning to `sys.stderr` if you open a database version that has not been tested.
|
||||
|
||||
#### `photos_version`
|
||||
|
||||
```python
|
||||
# assumes photosdb is a PhotosDB object (see above)
|
||||
photosdb.photos_version
|
||||
```
|
||||
|
||||
Returns the version number as int for version of Photos that created the library, e.g. 2, 3, 4, 5...
|
||||
|
||||
#### `get_db_connection()`
|
||||
|
||||
Returns tuple of (connection, cursor) for the working copy of the Photos database. This is useful for debugging or prototyping new features.
|
||||
@@ -428,7 +437,7 @@ conn.close()
|
||||
photos = photosdb.photos([keywords=['keyword',]], [uuid=['uuid',]], [persons=['person',]], [albums=['album',]],[from_date=datetime.datetime],[to_date=datetime.datetime])
|
||||
```
|
||||
|
||||
Returns a list of [PhotoInfo](#PhotoInfo) objects. Each PhotoInfo object represents a photo in the Photos Libary.
|
||||
Returns a list of [PhotoInfo](#photoinfo) objects. Each PhotoInfo object represents a photo in the Photos Libary.
|
||||
|
||||
If called with no parameters, returns a list of every photo in the Photos library.
|
||||
|
||||
@@ -593,7 +602,7 @@ Returns a list of albums the photo is contained in. See also [album_info](#album
|
||||
|
||||
#### `album_info`
|
||||
|
||||
Returns a list of [AlbumInfo](#AlbumInfo) objects representing the albums the photo is contained in or empty list of the photo is not in any albums. See also [albums](#albums).
|
||||
Returns a list of [AlbumInfo](#albuminfo) objects representing the albums the photo is contained in or empty list of the photo is not in any albums. See also [albums](#albums).
|
||||
|
||||
#### `import_info`
|
||||
|
||||
@@ -729,7 +738,7 @@ Returns latitude and longitude as a tuple of floats (latitude, longitude). If l
|
||||
|
||||
#### `place`
|
||||
|
||||
Returns a [PlaceInfo](#PlaceInfo) object with reverse geolocation data or None if there is the photo has no reverse geolocation information.
|
||||
Returns a [PlaceInfo](#placeinfo) object with reverse geolocation data or None if there is the photo has no reverse geolocation information.
|
||||
|
||||
#### `shared`
|
||||
|
||||
@@ -842,7 +851,7 @@ If a burst photo which has unselected burst images (e.g. the burst images are in
|
||||
|
||||
#### `burst_album_info`
|
||||
|
||||
If photo is non-selected burst photo, teturns a list of [AlbumInfo](#AlbumInfo) objects representing the albums any other photos in the same burst set are contained in. Otherwise, returns `PhotoInfo.album_info`. See also [burst_albums](#burst_albums) and [album_info](#album_info).
|
||||
If photo is non-selected burst photo, teturns a list of [AlbumInfo](#albuminfo) objects representing the albums any other photos in the same burst set are contained in. Otherwise, returns `PhotoInfo.album_info`. See also [burst_albums](#burst_albums) and [album_info](#album_info).
|
||||
|
||||
#### `live_photo`
|
||||
|
||||
@@ -1129,7 +1138,7 @@ Returns the title or name of the album.
|
||||
|
||||
#### <a name="albumphotos">`photos`</a>
|
||||
|
||||
Returns a list of [PhotoInfo](#PhotoInfo) objects representing each photo contained in the album sorted in the same order as in Photos. (e.g. if photos were manually sorted in the Photos albums, photos returned by `photos` will be in same order as they appear in the Photos album)
|
||||
Returns a list of [PhotoInfo](#photoinfo) objects representing each photo contained in the album sorted in the same order as in Photos. (e.g. if photos were manually sorted in the Photos albums, photos returned by `photos` will be in same order as they appear in the Photos album)
|
||||
|
||||
#### `creation_date`
|
||||
|
||||
@@ -1145,7 +1154,7 @@ Returns the date of latest photo in the album as a timezone aware datetime.datet
|
||||
|
||||
#### `folder_list`
|
||||
|
||||
Returns a hierarchical list of [FolderInfo](#FolderInfo) objects representing the folders the album is contained in. For example, if album "AlbumInFolder" is in SubFolder2 of Folder1 as illustrated below, would return a list of `FolderInfo` objects representing ["Folder1", "SubFolder2"]
|
||||
Returns a hierarchical list of [FolderInfo](#folderinfo) objects representing the folders the album is contained in. For example, if album "AlbumInFolder" is in SubFolder2 of Folder1 as illustrated below, would return a list of `FolderInfo` objects representing ["Folder1", "SubFolder2"]
|
||||
|
||||
```txt
|
||||
Photos Library
|
||||
@@ -1169,7 +1178,7 @@ Photos Library
|
||||
|
||||
#### `parent`
|
||||
|
||||
Returns a [FolderInfo](#FolderInfo) object representing the albums parent folder or `None` if album is not a in a folder.
|
||||
Returns a [FolderInfo](#folderinfo) object representing the albums parent folder or `None` if album is not a in a folder.
|
||||
|
||||
#### `owner`
|
||||
|
||||
@@ -1189,7 +1198,7 @@ Returns the universally unique identifier (uuid) of the import session. This is
|
||||
|
||||
#### <a name="importphotos">`photos`</a>
|
||||
|
||||
Returns a list of [PhotoInfo](#PhotoInfo) objects representing each photo contained in the import session.
|
||||
Returns a list of [PhotoInfo](#photoinfo) objects representing each photo contained in the import session.
|
||||
|
||||
#### `creation_date`
|
||||
|
||||
@@ -1219,7 +1228,7 @@ Returns the title or name of the project.
|
||||
|
||||
#### <a name="projectphotos">`photos`</a>
|
||||
|
||||
Returns a list of [PhotoInfo](#PhotoInfo) objects representing each photo contained in the project.
|
||||
Returns a list of [PhotoInfo](#photoinfo) objects representing each photo contained in the project.
|
||||
|
||||
#### `creation_date`
|
||||
|
||||
@@ -1283,21 +1292,21 @@ Returns the title or name of the folder.
|
||||
|
||||
#### `album_info`
|
||||
|
||||
Returns a list of [AlbumInfo](#AlbumInfo) objects representing each album contained in the folder.
|
||||
Returns a list of [AlbumInfo](#albuminfo) objects representing each album contained in the folder.
|
||||
|
||||
#### `album_info_shared`
|
||||
|
||||
Returns a list of [AlbumInfo](#AlbumInfo) objects for each shared album in the photos database.
|
||||
Returns a list of [AlbumInfo](#albuminfo) objects for each shared album in the photos database.
|
||||
|
||||
**Note**: Only valid for Photos 5+; on Photos <= 4, prints warning and returns empty list.
|
||||
|
||||
#### `subfolders`
|
||||
|
||||
Returns a list of [FolderInfo](#FolderInfo) objects representing the sub-folders of the folder.
|
||||
Returns a list of [FolderInfo](#folderinfo) objects representing the sub-folders of the folder.
|
||||
|
||||
#### `parent`
|
||||
|
||||
Returns a [FolderInfo](#FolderInfo) object representing the folder's parent folder or `None` if album is not a in a folder.
|
||||
Returns a [FolderInfo](#folderinfo) object representing the folder's parent folder or `None` if album is not a in a folder.
|
||||
|
||||
#### `sort_order`
|
||||
|
||||
@@ -1572,6 +1581,14 @@ Returns a list of PhotoInfo objects representing all photos the person appears i
|
||||
|
||||
Returns a list of [FaceInfo](#faceinfo) objects associated with this person sorted by quality score. Highest quality face is result[0] and lowest quality face is result[n].
|
||||
|
||||
#### <a name="personfavorite">`favorite`</a>
|
||||
|
||||
Returns True if Person has been marked as a favorite in Photos, otherwise False. Available on Photos 5+ only; on Photos <=4, returns False.
|
||||
|
||||
#### <a name="personsortorder">`sort_order`</a>
|
||||
|
||||
Returns the sort order for the person in the Photos People view. Available on Photos 5+ only; on Photos <= 4, returns None.
|
||||
|
||||
#### `json()`
|
||||
|
||||
Returns a json string representation of the PersonInfo instance.
|
||||
@@ -2016,7 +2033,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.56.3'|
|
||||
|{osxphotos_version}|The osxphotos version, e.g. '0.56.6'|
|
||||
|{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|
|
||||
|
||||
60
CHANGELOG.md
60
CHANGELOG.md
@@ -4,6 +4,44 @@ All notable changes to this project will be documented in this file. Dates are d
|
||||
|
||||
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
|
||||
#### [v0.56.5](https://github.com/RhetTbull/osxphotos/compare/v0.56.4...v0.56.5)
|
||||
|
||||
> 21 January 2023
|
||||
|
||||
- Release files for 0.56.5 [`#948`](https://github.com/RhetTbull/osxphotos/pull/948)
|
||||
- Bug timewarp sync 946 [`#947`](https://github.com/RhetTbull/osxphotos/pull/947)
|
||||
- add djbeadle as a contributor for ideas [`#945`](https://github.com/RhetTbull/osxphotos/pull/945)
|
||||
- Bug timewarp sync 946 (#947) [`#946`](https://github.com/RhetTbull/osxphotos/issues/946)
|
||||
|
||||
#### [v0.56.4](https://github.com/RhetTbull/osxphotos/compare/v0.56.3...v0.56.4)
|
||||
|
||||
> 21 January 2023
|
||||
|
||||
- Updated release files for v0.56.4 [`#944`](https://github.com/RhetTbull/osxphotos/pull/944)
|
||||
- Updated search info for Ventura, #937 [`#943`](https://github.com/RhetTbull/osxphotos/pull/943)
|
||||
- Bug slow import 934 [`#942`](https://github.com/RhetTbull/osxphotos/pull/942)
|
||||
|
||||
#### [v0.56.3](https://github.com/RhetTbull/osxphotos/compare/v0.56.2...v0.56.3)
|
||||
|
||||
> 16 January 2023
|
||||
|
||||
- Release files for 0.56.3 [`#933`](https://github.com/RhetTbull/osxphotos/pull/933)
|
||||
- Feature add locations 929 [`#932`](https://github.com/RhetTbull/osxphotos/pull/932)
|
||||
- Fixed handling of shared albums in sync [`aca2333`](https://github.com/RhetTbull/osxphotos/commit/aca233347792827d0d6b63bbeccd242c6741b354)
|
||||
|
||||
#### [v0.56.2](https://github.com/RhetTbull/osxphotos/compare/v0.56.1...v0.56.2)
|
||||
|
||||
> 15 January 2023
|
||||
|
||||
- Release 0.56.2 [`#928`](https://github.com/RhetTbull/osxphotos/pull/928)
|
||||
- On import consider GPS Location from XMP if EXIF is not available. [`#912`](https://github.com/RhetTbull/osxphotos/pull/912)
|
||||
- Added score info to inspect, #899 [`#927`](https://github.com/RhetTbull/osxphotos/pull/927)
|
||||
- Updated PhotoScript version to use faster folder/album code [`#926`](https://github.com/RhetTbull/osxphotos/pull/926)
|
||||
- Fixed 'Photos 5 only' text, #916 [`#925`](https://github.com/RhetTbull/osxphotos/pull/925)
|
||||
- Update README.md [`#923`](https://github.com/RhetTbull/osxphotos/pull/923)
|
||||
- add mave2k as a contributor for doc [`#924`](https://github.com/RhetTbull/osxphotos/pull/924)
|
||||
- add mave2k as a contributor for doc [`#924`](https://github.com/RhetTbull/osxphotos/pull/924)
|
||||
|
||||
#### [v0.56.1](https://github.com/RhetTbull/osxphotos/compare/v0.56.0...v0.56.1)
|
||||
|
||||
> 14 January 2023
|
||||
@@ -1480,7 +1518,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
> 17 April 2021
|
||||
|
||||
- Fixed bug for multi-field templates and --xattr-template, #422 [`6a28867`](https://github.com/RhetTbull/osxphotos/commit/6a288676a14ce23380181d43db19128afdda7731)
|
||||
- Add @ubrandes as a contributor [`874ad2f`](https://github.com/RhetTbull/osxphotos/commit/874ad2fa34d8306c071cd479625a9aa97f6488b2)
|
||||
- Add @ubrandes as a contributor [`874ad2f`](https://github.com/RhetTbull/osxphotos/commit/874ad2fa34d8306c071cd479625a9aa97f6488b2)
|
||||
|
||||
#### [v0.42.1](https://github.com/RhetTbull/osxphotos/compare/v0.41.11...v0.42.1)
|
||||
|
||||
@@ -1663,7 +1701,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
|
||||
> 2 February 2021
|
||||
|
||||
- Add @davidjroos as a contributor [`8dbedef`](https://github.com/RhetTbull/osxphotos/commit/8dbedef1874882815afb4a885184249aae73bf9f)
|
||||
- Add @davidjroos as a contributor [`8dbedef`](https://github.com/RhetTbull/osxphotos/commit/8dbedef1874882815afb4a885184249aae73bf9f)
|
||||
- Fixed documentation, #359 [`77371b6`](https://github.com/RhetTbull/osxphotos/commit/77371b6e5d8a9b8662b7b7d540378beb897f6988)
|
||||
|
||||
#### [v0.40.5](https://github.com/RhetTbull/osxphotos/compare/v0.40.3...v0.40.5)
|
||||
@@ -1715,7 +1753,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
> 18 January 2021
|
||||
|
||||
- Beta fix for Digikam reading XMP [`3799594`](https://github.com/RhetTbull/osxphotos/commit/379959447373f951ffca372598ea8f1d5834fe52)
|
||||
- Add @martinhrpi as a contributor [`db43017`](https://github.com/RhetTbull/osxphotos/commit/db430173b59732f944ca52b53c928370684580df)
|
||||
- Add @martinhrpi as a contributor [`db43017`](https://github.com/RhetTbull/osxphotos/commit/db430173b59732f944ca52b53c928370684580df)
|
||||
|
||||
#### [v0.39.21](https://github.com/RhetTbull/osxphotos/compare/v0.39.20...v0.39.21)
|
||||
|
||||
@@ -1751,8 +1789,8 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
|
||||
- Fixed test for M1, added about command, closes #315 [`#315`](https://github.com/RhetTbull/osxphotos/issues/315)
|
||||
- Fixed time zone for tests [`165f9b0`](https://github.com/RhetTbull/osxphotos/commit/165f9b08f5056d1f0b2ca7c74cec84d42b635663)
|
||||
- Add @narensankar0529 as a contributor [`039118c`](https://github.com/RhetTbull/osxphotos/commit/039118c1aaa217f46354b351ea36b0729e3e1c35)
|
||||
- Update @narensankar0529 as a contributor [`61f649e`](https://github.com/RhetTbull/osxphotos/commit/61f649e59d53a3e3011602476b72cc64951d38c0)
|
||||
- Add @narensankar0529 as a contributor [`039118c`](https://github.com/RhetTbull/osxphotos/commit/039118c1aaa217f46354b351ea36b0729e3e1c35)
|
||||
- Update @narensankar0529 as a contributor [`61f649e`](https://github.com/RhetTbull/osxphotos/commit/61f649e59d53a3e3011602476b72cc64951d38c0)
|
||||
|
||||
#### [v0.39.16](https://github.com/RhetTbull/osxphotos/compare/v0.39.15...v0.39.16)
|
||||
|
||||
@@ -1782,9 +1820,9 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
- Added PhotoInfo.visible, PhotoInfo.date_trashed, closes #333, #334 [`#333`](https://github.com/RhetTbull/osxphotos/issues/333)
|
||||
- Create terminalizer-demo.yml [`5dc2eea`](https://github.com/RhetTbull/osxphotos/commit/5dc2eeaf9a7265873c81db23bbc86d3023189a26)
|
||||
- Force cleanup of objects with autorelease pool [`b67f11a`](https://github.com/RhetTbull/osxphotos/commit/b67f11a3bb95c08a39a185b6d884092870e949f2)
|
||||
- doc: Recorded screencast and updated of readme [`658e8ac`](https://github.com/RhetTbull/osxphotos/commit/658e8ac096d141fce48483dbfc1426bea317d806)
|
||||
- doc: Recorded screencast and updated of readme [`658e8ac`](https://github.com/RhetTbull/osxphotos/commit/658e8ac096d141fce48483dbfc1426bea317d806)
|
||||
- doc: fixed toc in readme [`aba50c5`](https://github.com/RhetTbull/osxphotos/commit/aba50c5c733420dc30f861d866a2c0bdc8933714)
|
||||
- Add @Rott-Apple as a contributor [`71cb015`](https://github.com/RhetTbull/osxphotos/commit/71cb01572d2d946df18dd7b36f95b2f2e5b48f86)
|
||||
- Add @Rott-Apple as a contributor [`71cb015`](https://github.com/RhetTbull/osxphotos/commit/71cb01572d2d946df18dd7b36f95b2f2e5b48f86)
|
||||
|
||||
#### [v0.39.11](https://github.com/RhetTbull/osxphotos/compare/v0.39.10...v0.39.11)
|
||||
|
||||
@@ -1840,7 +1878,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
- doc simplify readme [`02ef0f9`](https://github.com/RhetTbull/osxphotos/commit/02ef0f9a254e83a3729a09cea1ae523407074896)
|
||||
- Added exception handling/capture for convert-to-jpeg, issue #322 [`05f111a`](https://github.com/RhetTbull/osxphotos/commit/05f111a287e882ed6b451a550a87753501316aba)
|
||||
- Cleanup up the readme [`38842ff`](https://github.com/RhetTbull/osxphotos/commit/38842ff9249e6f5b3069a88a759c8df97ddce51c)
|
||||
- Add @synox as a contributor [`83915c6`](https://github.com/RhetTbull/osxphotos/commit/83915c65abb880036f80ebd830eb1e34292f9599)
|
||||
- Add @synox as a contributor [`83915c6`](https://github.com/RhetTbull/osxphotos/commit/83915c65abb880036f80ebd830eb1e34292f9599)
|
||||
|
||||
#### [v0.39.5](https://github.com/RhetTbull/osxphotos/compare/v0.39.4...v0.39.5)
|
||||
|
||||
@@ -1986,7 +2024,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
- Documentation fix for #293. Thanks to @finestream [`#295`](https://github.com/RhetTbull/osxphotos/pull/295)
|
||||
- Patch 1 [`#1`](https://github.com/RhetTbull/osxphotos/pull/1)
|
||||
- Added additional test cases for #286, --ignore-signature [`880a9b6`](https://github.com/RhetTbull/osxphotos/commit/880a9b67a14787ef23ae68ad3164d7eda1af16ec)
|
||||
- Add @finestream as a contributor [`ad860b1`](https://github.com/RhetTbull/osxphotos/commit/ad860b1500dffd846322e05562ba4f2019cd1017)
|
||||
- Add @finestream as a contributor [`ad860b1`](https://github.com/RhetTbull/osxphotos/commit/ad860b1500dffd846322e05562ba4f2019cd1017)
|
||||
- Fixed issue #296 [`a7c688c`](https://github.com/RhetTbull/osxphotos/commit/a7c688cfc2221833e0252d71bbe596eee5f9a6e8)
|
||||
- Updated README.md [`d40b16a`](https://github.com/RhetTbull/osxphotos/commit/d40b16a456c64014674505b7c715c80b977da76a)
|
||||
- Update __main__.py [`e097f3a`](https://github.com/RhetTbull/osxphotos/commit/e097f3aad546b5be5eabab529bd2c35ce3056876)
|
||||
@@ -2108,7 +2146,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
- Fix EXIF GPS format for XMP sidecar, thanks to @jstrine for the fix! [`#270`](https://github.com/RhetTbull/osxphotos/pull/270)
|
||||
- Continue even if the original filename is None, thanks to @jstrine for the fix! [`#268`](https://github.com/RhetTbull/osxphotos/pull/268)
|
||||
- Added test for missing original_filename [`116cb66`](https://github.com/RhetTbull/osxphotos/commit/116cb662fbddf9153f6858c6ea97dc7f65c77705)
|
||||
- Add @jstrine as a contributor [`7460bc8`](https://github.com/RhetTbull/osxphotos/commit/7460bc88fcc5e1e7435c9b9bcdf7ec9c7c5e39ea)
|
||||
- Add @jstrine as a contributor [`7460bc8`](https://github.com/RhetTbull/osxphotos/commit/7460bc88fcc5e1e7435c9b9bcdf7ec9c7c5e39ea)
|
||||
- Escape characters which cause XML parsing issues [`c42050a`](https://github.com/RhetTbull/osxphotos/commit/c42050a10cac40b0b5ac70c587e07f257a9b50dd)
|
||||
- Fix tests for apostrophe [`d0d2e80`](https://github.com/RhetTbull/osxphotos/commit/d0d2e8080096bf66f93a830386800ce713680c51)
|
||||
- Fix test for XMP sidecar with GPS info [`c27cfb1`](https://github.com/RhetTbull/osxphotos/commit/c27cfb1223fa82b9e5549b93c283e9444693270a)
|
||||
@@ -2218,7 +2256,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
|
||||
- Updated --exiftool to set dates/times as Photos does, issue #247 [`11459d1`](https://github.com/RhetTbull/osxphotos/commit/11459d1da4d7d13e36e9db4bdc940b74baad9d11)
|
||||
- Partial fix for issue #247 on Mojave [`6ac3111`](https://github.com/RhetTbull/osxphotos/commit/6ac311199e9f7afe6170cbbd68ceaa1bb9f0682b)
|
||||
- Add @mwort as a contributor [`9cff8e8`](https://github.com/RhetTbull/osxphotos/commit/9cff8e89c6e939d3d371a4f60649f6e5595a55b9)
|
||||
- Add @mwort as a contributor [`9cff8e8`](https://github.com/RhetTbull/osxphotos/commit/9cff8e89c6e939d3d371a4f60649f6e5595a55b9)
|
||||
|
||||
#### [v0.36.2](https://github.com/RhetTbull/osxphotos/compare/v0.36.1...v0.36.2)
|
||||
|
||||
|
||||
99
README.md
99
README.md
@@ -7,7 +7,7 @@
|
||||
[](https://pepy.tech/project/osxphotos)
|
||||
[](https://www.reddit.com/r/osxphotos/)
|
||||
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
||||
[](#contributors)
|
||||
[](#contributors)
|
||||
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
||||
|
||||
OSXPhotos provides the ability to interact with and query Apple's Photos.app library on macOS. 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.
|
||||
@@ -112,56 +112,68 @@ If you have questions, would like to show off projects created with OSXPhotos, o
|
||||
|
||||
This package will install a command line utility called `osxphotos` that allows you to query the Photos database. Alternatively, you can also run the command line utility like this: `python3 -m osxphotos`
|
||||
|
||||
<!--[[[cog
|
||||
from osxphotos.cli import cli_main
|
||||
from click.testing import CliRunner
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(cli_main, ["--help"])
|
||||
help = result.output.replace("Usage: cli-main", "Usage: osxphotos")
|
||||
cog.out(
|
||||
"```\n{}\n```".format(help)
|
||||
)
|
||||
]]] -->
|
||||
```
|
||||
> osxphotos
|
||||
Usage: 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.
|
||||
--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.
|
||||
-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 & 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 <command>.
|
||||
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.
|
||||
diff Compare two Photos databases and print out differences
|
||||
docs Open osxphotos documentation in your browser.
|
||||
dump Print list of all photos & 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 <command>.
|
||||
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 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;...
|
||||
repl Run interactive osxphotos REPL shell (useful for...
|
||||
run Run a python file using same environment as osxphotos.
|
||||
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.
|
||||
|
||||
```
|
||||
<!--[[[end]]] -->
|
||||
|
||||
To get help on a specific command, use `osxphotos help command_name`, for example, `osxphotos help export` to get help on the `export` command.
|
||||
|
||||
@@ -2041,7 +2053,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.56.3'
|
||||
{osxphotos_version} The osxphotos version, e.g. '0.56.6'
|
||||
{osxphotos_cmd_line} The full command line used to run osxphotos
|
||||
|
||||
The following substitutions may result in multiple values. Thus if specified
|
||||
@@ -2525,7 +2537,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.56.3'|
|
||||
|{osxphotos_version}|The osxphotos version, e.g. '0.56.6'|
|
||||
|{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|
|
||||
@@ -2637,6 +2649,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://qkeddy.github.io/quin-eddy-development-portfolio/"><img src="https://avatars.githubusercontent.com/u/9737814?v=4?s=75" width="75px;" alt="Quin Eddy"/><br /><sub><b>Quin Eddy</b></sub></a><br /><a href="#ideas-qkeddy" title="Ideas, Planning, & Feedback">🤔</a> <a href="#data-qkeddy" title="Data">🔣</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/johnsturgeon"><img src="https://avatars.githubusercontent.com/u/9746310?v=4?s=75" width="75px;" alt="John Sturgeon"/><br /><sub><b>John Sturgeon</b></sub></a><br /><a href="https://github.com/RhetTbull/osxphotos/issues?q=author%3Ajohnsturgeon" title="Bug reports">🐛</a> <a href="https://github.com/RhetTbull/osxphotos/commits?author=johnsturgeon" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mave2k"><img src="https://avatars.githubusercontent.com/u/8629837?v=4?s=75" width="75px;" alt="mave2k"/><br /><sub><b>mave2k</b></sub></a><br /><a href="https://github.com/RhetTbull/osxphotos/commits?author=mave2k" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://danielbeadle.net"><img src="https://avatars.githubusercontent.com/u/6235378?v=4?s=75" width="75px;" alt="Daniel Beadle"/><br /><sub><b>Daniel Beadle</b></sub></a><br /><a href="#ideas-djbeadle" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
3
build.sh
3
build.sh
@@ -12,6 +12,7 @@ cog -d -o osxphotos/phototemplate.md osxphotos/phototemplate.cog.md
|
||||
|
||||
echo "Updating README.md"
|
||||
python3 utils/update_readme.py
|
||||
cog -r README.md
|
||||
|
||||
echo "Updating API_README.md"
|
||||
cog -r API_README.md
|
||||
@@ -53,4 +54,4 @@ ARCHSTR=$(uname -m)
|
||||
ZIPNAME=osxphotos_MacOS_exe_darwin_${ARCHSTR}_v${OSXPHOTOSVERSION}.zip
|
||||
echo "Zipping CLI executable to $ZIPNAME"
|
||||
cd dist && zip $ZIPNAME osxphotos && cd ..
|
||||
rm dist/osxphotos
|
||||
rm dist/osxphotos
|
||||
|
||||
@@ -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: 82c8e42e2b834f1c1ae542ffd6f70cd2
|
||||
config: 825fec5d85827d180b8ee7b12122503b
|
||||
tags: 645f666f9bcd5a90fca523b33c5a78b7
|
||||
|
||||
@@ -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.56.3 documentation</title>
|
||||
<title>Overview: module code - osxphotos 0.56.6 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.56.3 documentation</div></a>
|
||||
<a href="../index.html"><div class="brand">osxphotos 0.56.6 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.56.3 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.56.6 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">
|
||||
|
||||
@@ -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.55.7 documentation</title>
|
||||
<title>osxphotos._constants - osxphotos 0.56.4 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.55.7 documentation</div></a>
|
||||
<a href="../../index.html"><div class="brand">osxphotos 0.56.4 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.55.7 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.56.4 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">
|
||||
@@ -195,9 +195,9 @@
|
||||
</div>
|
||||
<article role="main">
|
||||
<h1>Source code for osxphotos._constants</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">"""</span>
|
||||
<span class="sd">Constants used by osxphotos </span>
|
||||
<span class="sd">"""</span>
|
||||
<span></span><span class="sd">""" Constants used by osxphotos """</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">os.path</span>
|
||||
<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span>
|
||||
@@ -335,7 +335,9 @@
|
||||
<span class="n">_PHOTOS_8_SHARED_PHOTO_PATH</span> <span class="o">=</span> <span class="s2">"scopes/cloudsharing/data"</span>
|
||||
|
||||
<span class="c1"># Where are shared iCloud derivatives located?</span>
|
||||
<span class="n">_PHOTOS_5_SHARED_DERIVATIVE_PATH</span> <span class="o">=</span> <span class="s2">"resources/cloudsharing/resources/derivatives/masters"</span>
|
||||
<span class="n">_PHOTOS_5_SHARED_DERIVATIVE_PATH</span> <span class="o">=</span> <span class="p">(</span>
|
||||
<span class="s2">"resources/cloudsharing/resources/derivatives/masters"</span>
|
||||
<span class="p">)</span>
|
||||
<span class="n">_PHOTOS_8_SHARED_DERIVATIVE_PATH</span> <span class="o">=</span> <span class="s2">"scopes/cloudsharing/resources/derivatives/masters"</span>
|
||||
|
||||
<span class="c1"># What type of file? Based on ZGENERICASSET.ZKIND in Photos 5 database</span>
|
||||
@@ -410,11 +412,11 @@
|
||||
<span class="n">TITLE</span> <span class="o">=</span> <span class="mi">2017</span>
|
||||
<span class="n">DESCRIPTION</span> <span class="o">=</span> <span class="mi">2018</span>
|
||||
<span class="n">HOME</span> <span class="o">=</span> <span class="mi">2020</span>
|
||||
<span class="n">WORK</span> <span class="o">=</span> <span class="mi">2036</span>
|
||||
<span class="n">PERSON</span> <span class="o">=</span> <span class="mi">2021</span>
|
||||
<span class="n">ACTIVITY</span> <span class="o">=</span> <span class="mi">2027</span>
|
||||
<span class="n">HOLIDAY</span> <span class="o">=</span> <span class="mi">2029</span>
|
||||
<span class="n">SEASON</span> <span class="o">=</span> <span class="mi">2030</span>
|
||||
<span class="n">WORK</span> <span class="o">=</span> <span class="mi">2036</span>
|
||||
<span class="n">VENUE</span> <span class="o">=</span> <span class="mi">2038</span>
|
||||
<span class="n">VENUE_TYPE</span> <span class="o">=</span> <span class="mi">2039</span>
|
||||
<span class="n">PHOTO_TYPE_VIDEO</span> <span class="o">=</span> <span class="mi">2044</span>
|
||||
@@ -427,6 +429,7 @@
|
||||
<span class="n">PHOTO_TYPE_PORTRAIT</span> <span class="o">=</span> <span class="mi">2053</span>
|
||||
<span class="n">PHOTO_TYPE_SELFIES</span> <span class="o">=</span> <span class="mi">2054</span>
|
||||
<span class="n">PHOTO_TYPE_FAVORITES</span> <span class="o">=</span> <span class="mi">2055</span>
|
||||
<span class="n">PHOTO_TYPE_ANIMATED</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Photos 8+ only</span>
|
||||
<span class="n">MEDIA_TYPES</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="n">PHOTO_TYPE_VIDEO</span><span class="p">,</span>
|
||||
<span class="n">PHOTO_TYPE_SLOMO</span><span class="p">,</span>
|
||||
@@ -441,7 +444,23 @@
|
||||
<span class="p">]</span>
|
||||
<span class="n">PHOTO_NAME</span> <span class="o">=</span> <span class="mi">2056</span>
|
||||
<span class="n">CAMERA</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Photos 8+ only</span>
|
||||
<span class="n">TEXT_FOUND</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Photos 8+ only</span>
|
||||
<span class="n">DETECTED_TEXT</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Photos 8+ only</span>
|
||||
<span class="n">SOURCE</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Photos 8+ only</span>
|
||||
|
||||
<span class="nd">@classmethod</span>
|
||||
<span class="k">def</span> <span class="nf">categories</span><span class="p">(</span><span class="bp">cls</span><span class="p">)</span> <span class="o">-></span> <span class="nb">dict</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="nb">str</span><span class="p">]:</span>
|
||||
<span class="sd">"""Return categories as dict of value: name"""</span>
|
||||
<span class="c1"># a bit of a hack to basically reverse the enum</span>
|
||||
<span class="k">return</span> <span class="p">{</span>
|
||||
<span class="n">value</span><span class="p">:</span> <span class="n">name</span>
|
||||
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
|
||||
<span class="k">if</span> <span class="n">name</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
|
||||
<span class="ow">and</span> <span class="ow">not</span> <span class="n">name</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"__"</span><span class="p">)</span>
|
||||
<span class="ow">and</span> <span class="ow">not</span> <span class="n">callable</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
|
||||
<span class="ow">and</span> <span class="n">name</span><span class="o">.</span><span class="n">isupper</span><span class="p">()</span>
|
||||
<span class="ow">and</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="p">(</span><span class="nb">list</span><span class="p">,</span> <span class="nb">dict</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">))</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
|
||||
<span class="k">class</span> <span class="nc">SearchCategory_Photos8</span><span class="p">(</span><span class="n">SearchCategory</span><span class="p">):</span>
|
||||
@@ -449,6 +468,20 @@
|
||||
|
||||
<span class="c1"># Many of the category values changed in Ventura / Photos 8</span>
|
||||
<span class="c1"># and some new categories were added</span>
|
||||
<span class="n">CITY</span> <span class="o">=</span> <span class="mi">5</span>
|
||||
<span class="n">LOCALITY_4</span> <span class="o">=</span> <span class="mi">4</span>
|
||||
<span class="n">SUB_LOCALITY_5</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">SUB_LOCALITY_6</span> <span class="o">=</span> <span class="mi">6</span>
|
||||
<span class="n">LOCALITY_8</span> <span class="o">=</span> <span class="mi">8</span>
|
||||
<span class="n">NAMED_AREA</span> <span class="o">=</span> <span class="mi">7</span>
|
||||
<span class="n">ALL_LOCALITY</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="n">LOCALITY_4</span><span class="p">,</span>
|
||||
<span class="n">SUB_LOCALITY_6</span><span class="p">,</span>
|
||||
<span class="n">LOCALITY_8</span><span class="p">,</span>
|
||||
<span class="n">NAMED_AREA</span><span class="p">,</span>
|
||||
<span class="p">]</span>
|
||||
<span class="n">HOME</span> <span class="o">=</span> <span class="mi">1000</span>
|
||||
<span class="n">WORK</span> <span class="o">=</span> <span class="mi">1001</span>
|
||||
<span class="n">LABEL</span> <span class="o">=</span> <span class="mi">1500</span>
|
||||
<span class="n">MONTH</span> <span class="o">=</span> <span class="mi">1100</span>
|
||||
<span class="n">YEAR</span> <span class="o">=</span> <span class="mi">1101</span>
|
||||
@@ -458,11 +491,55 @@
|
||||
<span class="n">TITLE</span> <span class="o">=</span> <span class="mi">1201</span>
|
||||
<span class="n">DESCRIPTION</span> <span class="o">=</span> <span class="mi">1202</span>
|
||||
<span class="n">DETECTED_TEXT</span> <span class="o">=</span> <span class="mi">1203</span> <span class="c1"># new in Photos 8</span>
|
||||
<span class="n">TEXT_FOUND</span> <span class="o">=</span> <span class="mi">1205</span> <span class="c1"># new in Photos 8</span>
|
||||
<span class="n">PERSON</span> <span class="o">=</span> <span class="mi">1300</span>
|
||||
<span class="n">ACTIVITY</span> <span class="o">=</span> <span class="mi">1600</span>
|
||||
<span class="n">VENUE</span> <span class="o">=</span> <span class="mi">1700</span>
|
||||
<span class="n">VENUE_TYPE</span> <span class="o">=</span> <span class="mi">1701</span>
|
||||
<span class="n">PHOTO_TYPE_VIDEO</span> <span class="o">=</span> <span class="mi">1901</span>
|
||||
<span class="n">PHOTO_TYPE_SELFIES</span> <span class="o">=</span> <span class="mi">1915</span>
|
||||
<span class="n">PHOTO_TYPE_LIVE</span> <span class="o">=</span> <span class="mi">1906</span>
|
||||
<span class="n">PHOTO_TYPE_PORTRAIT</span> <span class="o">=</span> <span class="mi">1914</span>
|
||||
<span class="n">PHOTO_TYPE_FAVORITES</span> <span class="o">=</span> <span class="mi">2000</span>
|
||||
<span class="n">PHOTO_TYPE_PANORAMA</span> <span class="o">=</span> <span class="mi">1908</span>
|
||||
<span class="n">PHOTO_TYPE_TIMELAPSE</span> <span class="o">=</span> <span class="mi">1909</span>
|
||||
<span class="n">PHOTO_TYPE_SLOMO</span> <span class="o">=</span> <span class="mi">1905</span>
|
||||
<span class="n">PHOTO_TYPE_BURSTS</span> <span class="o">=</span> <span class="mi">1913</span>
|
||||
<span class="n">PHOTO_TYPE_SCREENSHOT</span> <span class="o">=</span> <span class="mi">1907</span>
|
||||
<span class="n">PHOTO_TYPE_ANIMATED</span> <span class="o">=</span> <span class="mi">1912</span>
|
||||
<span class="n">PHOTO_TYPE_RAW</span> <span class="o">=</span> <span class="mi">1902</span>
|
||||
<span class="n">MEDIA_TYPES</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="n">PHOTO_TYPE_VIDEO</span><span class="p">,</span>
|
||||
<span class="n">PHOTO_TYPE_SLOMO</span><span class="p">,</span>
|
||||
<span class="n">PHOTO_TYPE_LIVE</span><span class="p">,</span>
|
||||
<span class="n">PHOTO_TYPE_SCREENSHOT</span><span class="p">,</span>
|
||||
<span class="n">PHOTO_TYPE_PANORAMA</span><span class="p">,</span>
|
||||
<span class="n">PHOTO_TYPE_TIMELAPSE</span><span class="p">,</span>
|
||||
<span class="n">PHOTO_TYPE_BURSTS</span><span class="p">,</span>
|
||||
<span class="n">PHOTO_TYPE_PORTRAIT</span><span class="p">,</span>
|
||||
<span class="n">PHOTO_TYPE_SELFIES</span><span class="p">,</span>
|
||||
<span class="n">PHOTO_TYPE_FAVORITES</span><span class="p">,</span>
|
||||
<span class="n">PHOTO_TYPE_ANIMATED</span><span class="p">,</span>
|
||||
<span class="p">]</span>
|
||||
<span class="n">PHOTO_NAME</span> <span class="o">=</span> <span class="mi">2100</span>
|
||||
<span class="n">CAMERA</span> <span class="o">=</span> <span class="mi">2300</span> <span class="c1"># new in Photos 8</span>
|
||||
<span class="n">SOURCE</span> <span class="o">=</span> <span class="mi">2200</span> <span class="c1"># new in Photos 8, shows the app/software source for the photo, e.g. Messages, Safari, etc.</span>
|
||||
|
||||
<span class="nd">@classmethod</span>
|
||||
<span class="k">def</span> <span class="nf">categories</span><span class="p">(</span><span class="bp">cls</span><span class="p">)</span> <span class="o">-></span> <span class="nb">dict</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="nb">str</span><span class="p">]:</span>
|
||||
<span class="sd">"""Return categories as dict of value: name"""</span>
|
||||
<span class="c1"># need to get the categories from the base class and update with the new values</span>
|
||||
<span class="n">classdict</span> <span class="o">=</span> <span class="n">SearchCategory</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
|
||||
<span class="n">classdict</span> <span class="o">|=</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
|
||||
<span class="k">return</span> <span class="p">{</span>
|
||||
<span class="n">value</span><span class="p">:</span> <span class="n">name</span>
|
||||
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">classdict</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
|
||||
<span class="k">if</span> <span class="n">name</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
|
||||
<span class="ow">and</span> <span class="ow">not</span> <span class="n">name</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"__"</span><span class="p">)</span>
|
||||
<span class="ow">and</span> <span class="ow">not</span> <span class="n">callable</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
|
||||
<span class="ow">and</span> <span class="n">name</span><span class="o">.</span><span class="n">isupper</span><span class="p">()</span>
|
||||
<span class="ow">and</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="p">(</span><span class="nb">list</span><span class="p">,</span> <span class="nb">dict</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">))</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
|
||||
<span class="k">def</span> <span class="nf">search_category_factory</span><span class="p">(</span><span class="n">version</span><span class="p">:</span> <span class="nb">int</span><span class="p">)</span> <span class="o">-></span> <span class="n">SearchCategory</span><span class="p">:</span>
|
||||
|
||||
@@ -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.56.1 documentation</title>
|
||||
<title>osxphotos.debug - osxphotos 0.56.4 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.56.1 documentation</div></a>
|
||||
<a href="../../index.html"><div class="brand">osxphotos 0.56.4 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.56.1 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.56.4 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">
|
||||
|
||||
@@ -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.55.6 documentation</title>
|
||||
<title>osxphotos.exiftool - osxphotos 0.56.4 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.55.6 documentation</div></a>
|
||||
<a href="../../index.html"><div class="brand">osxphotos 0.56.4 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.55.6 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.56.4 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">
|
||||
|
||||
@@ -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.55.3 documentation</title>
|
||||
<title>osxphotos.export_db - osxphotos 0.56.4 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.55.3 documentation</div></a>
|
||||
<a href="../../index.html"><div class="brand">osxphotos 0.56.4 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.55.3 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.56.4 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">
|
||||
|
||||
@@ -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.personinfo - osxphotos 0.50.4 documentation</title>
|
||||
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
|
||||
<title>osxphotos.personinfo - osxphotos 0.56.5 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.50.4 documentation</div></a>
|
||||
<a href="../../index.html"><div class="brand">osxphotos 0.56.5 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.50.4 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.56.5 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">
|
||||
@@ -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,25 +195,27 @@
|
||||
</div>
|
||||
<article role="main">
|
||||
<h1>Source code for osxphotos.personinfo</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">""" PhotoInfo and FaceInfo classes to expose info about persons and faces in the Photos library """</span>
|
||||
<span></span><span class="sd">""" PhotoInfo and FaceInfo classes to expose info about persons and faces in the Photos library """</span>
|
||||
|
||||
<span class="kn">import</span> <span class="nn">json</span>
|
||||
<span class="kn">import</span> <span class="nn">logging</span>
|
||||
<span class="kn">import</span> <span class="nn">math</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">namedtuple</span>
|
||||
<span class="kn">from</span> <span class="nn">functools</span> <span class="kn">import</span> <span class="n">cached_property</span>
|
||||
|
||||
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"PersonInfo"</span><span class="p">,</span> <span class="s2">"FaceInfo"</span><span class="p">,</span> <span class="s2">"rotate_image_point"</span><span class="p">]</span>
|
||||
<span class="kn">import</span> <span class="nn">osxphotos</span>
|
||||
|
||||
<span class="n">MWG_RS_Area</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s2">"MWG_RS_Area"</span><span class="p">,</span> <span class="p">[</span><span class="s2">"x"</span><span class="p">,</span> <span class="s2">"y"</span><span class="p">,</span> <span class="s2">"h"</span><span class="p">,</span> <span class="s2">"w"</span><span class="p">])</span>
|
||||
<span class="n">MPRI_Reg_Rect</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s2">"MPRI_Reg_Rect"</span><span class="p">,</span> <span class="p">[</span><span class="s2">"x"</span><span class="p">,</span> <span class="s2">"y"</span><span class="p">,</span> <span class="s2">"h"</span><span class="p">,</span> <span class="s2">"w"</span><span class="p">])</span>
|
||||
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"PersonInfo"</span><span class="p">,</span> <span class="s2">"FaceInfo"</span><span class="p">,</span> <span class="s2">"rotate_image_point"</span><span class="p">]</span>
|
||||
|
||||
<span class="n">MWG_RS_Area</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s2">"MWG_RS_Area"</span><span class="p">,</span> <span class="p">[</span><span class="s2">"x"</span><span class="p">,</span> <span class="s2">"y"</span><span class="p">,</span> <span class="s2">"h"</span><span class="p">,</span> <span class="s2">"w"</span><span class="p">])</span>
|
||||
<span class="n">MPRI_Reg_Rect</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s2">"MPRI_Reg_Rect"</span><span class="p">,</span> <span class="p">[</span><span class="s2">"x"</span><span class="p">,</span> <span class="s2">"y"</span><span class="p">,</span> <span class="s2">"h"</span><span class="p">,</span> <span class="s2">"w"</span><span class="p">])</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="PersonInfo"><a class="viewcode-back" href="../../reference.html#osxphotos.PersonInfo">[docs]</a><span class="k">class</span> <span class="nc">PersonInfo</span><span class="p">:</span>
|
||||
<span class="sd">"""Info about a person in the Photos library"""</span>
|
||||
<span class="sd">"""Info about a person in the Photos library"""</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>
|
||||
<span class="sd">"""Creates a new PersonInfo instance</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="s2">"osxphotos.PhotosDB"</span><span class="p">,</span> <span class="n">pk</span><span class="p">:</span> <span class="nb">int</span><span class="p">):</span>
|
||||
<span class="sd">"""Creates a new PersonInfo instance</span>
|
||||
|
||||
<span class="sd"> Arguments:</span>
|
||||
<span class="sd"> db: instance of PhotosDB object</span>
|
||||
@@ -220,16 +223,16 @@
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> PersonInfo instance</span>
|
||||
<span class="sd"> """</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">pk</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="p">:</span> <span class="s2">"osxphotos.PhotosDB"</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="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="n">pk</span>
|
||||
|
||||
<span class="n">person</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">_dbpersons_pk</span><span class="p">[</span><span class="n">pk</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">uuid</span> <span class="o">=</span> <span class="n">person</span><span class="p">[</span><span class="s2">"uuid"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">person</span><span class="p">[</span><span class="s2">"fullname"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">display_name</span> <span class="o">=</span> <span class="n">person</span><span class="p">[</span><span class="s2">"displayname"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">keyface</span> <span class="o">=</span> <span class="n">person</span><span class="p">[</span><span class="s2">"keyface"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">facecount</span> <span class="o">=</span> <span class="n">person</span><span class="p">[</span><span class="s2">"facecount"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">uuid</span> <span class="o">=</span> <span class="n">person</span><span class="p">[</span><span class="s2">"uuid"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">person</span><span class="p">[</span><span class="s2">"fullname"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">display_name</span> <span class="o">=</span> <span class="n">person</span><span class="p">[</span><span class="s2">"displayname"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">keyface</span> <span class="o">=</span> <span class="n">person</span><span class="p">[</span><span class="s2">"keyface"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">facecount</span> <span class="o">=</span> <span class="n">person</span><span class="p">[</span><span class="s2">"facecount"</span><span class="p">]</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">keyphoto</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
@@ -237,9 +240,9 @@
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_keyphoto</span>
|
||||
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
||||
<span class="n">person</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">_dbpersons_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="k">if</span> <span class="n">person</span><span class="p">[</span><span class="s2">"photo_uuid"</span><span class="p">]:</span>
|
||||
<span class="k">if</span> <span class="n">person</span><span class="p">[</span><span class="s2">"photo_uuid"</span><span class="p">]:</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">key_photo</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">get_photo</span><span class="p">(</span><span class="n">person</span><span class="p">[</span><span class="s2">"photo_uuid"</span><span class="p">])</span>
|
||||
<span class="n">key_photo</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">get_photo</span><span class="p">(</span><span class="n">person</span><span class="p">[</span><span class="s2">"photo_uuid"</span><span class="p">])</span>
|
||||
<span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
|
||||
<span class="n">key_photo</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
@@ -249,14 +252,14 @@
|
||||
|
||||
<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">"""Returns list of PhotoInfo objects associated with this person"""</span>
|
||||
<span class="sd">"""Returns list of PhotoInfo objects associated with this person"""</span>
|
||||
<span class="k">return</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="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbfaces_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="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">face_info</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Returns a list of FaceInfo objects associated with this person sorted by quality score</span>
|
||||
<span class="sd">"""Returns a list of FaceInfo objects associated with this person sorted by quality score</span>
|
||||
<span class="sd"> Highest quality face is result[0] and lowest quality face is result[n]</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">faces</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_faceinfo_person</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="k">return</span> <span class="nb">sorted</span><span class="p">(</span>
|
||||
@@ -268,30 +271,60 @@
|
||||
<span class="c1"># no faces</span>
|
||||
<span class="k">return</span> <span class="p">[]</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">favorite</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Returns True if person is a favorite, False otherwise; Photos 5+ only; returns False on Photos <= 4"""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbpersons_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">"type"</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">sort_order</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Returns sort order of person; favorite persons are sorted before non-favorite persons"; Photos 5+ only; returns 0 on Photos <= 4"""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbpersons_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">"manualorder"</span><span class="p">]</span>
|
||||
|
||||
<span class="nd">@cached_property</span>
|
||||
<span class="k">def</span> <span class="nf">feature_less</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Returns True if person has been marked as "Feature This Person Less" in Photos, False otherwise; Photos 8+ only; returns False on Photos <= 7"""</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"><</span> <span class="mi">8</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="kc">False</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">results</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">execute</span><span class="p">(</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> SELECT ZTYPE</span>
|
||||
<span class="sd"> FROM ZUSERFEEDBACK</span>
|
||||
<span class="sd"> WHERE ZPERSON = ?</span>
|
||||
<span class="sd"> """</span><span class="p">,</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="p">)</span><span class="o">.</span><span class="n">fetchone</span><span class="p">():</span>
|
||||
<span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="n">results</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
|
||||
<span class="k">return</span> <span class="kc">False</span>
|
||||
|
||||
<div class="viewcode-block" id="PersonInfo.asdict"><a class="viewcode-back" href="../../reference.html#osxphotos.PersonInfo.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 dictionary representation of class instance"""</span>
|
||||
<span class="sd">"""Returns dictionary representation of class instance"""</span>
|
||||
<span class="n">keyphoto</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">keyphoto</span><span class="o">.</span><span class="n">uuid</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">keyphoto</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="k">else</span> <span class="kc">None</span>
|
||||
<span class="k">return</span> <span class="p">{</span>
|
||||
<span class="s2">"uuid"</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="s2">"name"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
|
||||
<span class="s2">"displayname"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">display_name</span><span class="p">,</span>
|
||||
<span class="s2">"keyface"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">keyface</span><span class="p">,</span>
|
||||
<span class="s2">"facecount"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">facecount</span><span class="p">,</span>
|
||||
<span class="s2">"keyphoto"</span><span class="p">:</span> <span class="n">keyphoto</span><span class="p">,</span>
|
||||
<span class="s2">"uuid"</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="s2">"name"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
|
||||
<span class="s2">"displayname"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">display_name</span><span class="p">,</span>
|
||||
<span class="s2">"keyface"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">keyface</span><span class="p">,</span>
|
||||
<span class="s2">"facecount"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">facecount</span><span class="p">,</span>
|
||||
<span class="s2">"keyphoto"</span><span class="p">:</span> <span class="n">keyphoto</span><span class="p">,</span>
|
||||
<span class="s2">"favorite"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">favorite</span><span class="p">,</span>
|
||||
<span class="s2">"sort_order"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">sort_order</span><span class="p">,</span>
|
||||
<span class="s2">"feature_less"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">feature_less</span><span class="p">,</span>
|
||||
<span class="p">}</span></div>
|
||||
|
||||
<div class="viewcode-block" id="PersonInfo.json"><a class="viewcode-back" href="../../reference.html#osxphotos.PersonInfo.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">"""Returns JSON representation of class instance"""</span>
|
||||
<span class="sd">"""Returns JSON representation of class instance"""</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">"PersonInfo(name=</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">, display_name=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">display_name</span><span class="si">}</span><span class="s2">, 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">, facecount=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">facecount</span><span class="si">}</span><span class="s2">)"</span>
|
||||
<span class="k">return</span> <span class="sa">f</span><span class="s2">"PersonInfo(name=</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">, display_name=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">display_name</span><span class="si">}</span><span class="s2">, 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">, facecount=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">facecount</span><span class="si">}</span><span class="s2">)"</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__eq__</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="p">(</span>
|
||||
<span class="nb">all</span><span class="p">(</span>
|
||||
<span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">field</span><span class="p">)</span> <span class="o">==</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">field</span><span class="p">)</span>
|
||||
<span class="k">for</span> <span class="n">field</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">"_db"</span><span class="p">,</span> <span class="s2">"_pk"</span><span class="p">]</span>
|
||||
<span class="k">for</span> <span class="n">field</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">"_db"</span><span class="p">,</span> <span class="s2">"_pk"</span><span class="p">]</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
|
||||
<span class="k">else</span> <span class="kc">False</span>
|
||||
@@ -302,10 +335,10 @@
|
||||
|
||||
|
||||
<span class="k">class</span> <span class="nc">FaceInfo</span><span class="p">:</span>
|
||||
<span class="sd">"""Info about a face in the Photos library"""</span>
|
||||
<span class="sd">"""Info about a face in the Photos library"""</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>
|
||||
<span class="sd">"""Creates a new FaceInfo instance</span>
|
||||
<span class="sd">"""Creates a new FaceInfo instance</span>
|
||||
|
||||
<span class="sd"> Arguments:</span>
|
||||
<span class="sd"> db: instance of PhotosDB object</span>
|
||||
@@ -313,59 +346,59 @@
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> FaceInfo instance</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="sd"> """</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">pk</span>
|
||||
|
||||
<span class="n">face</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_faceinfo_pk</span><span class="p">[</span><span class="n">pk</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_info</span> <span class="o">=</span> <span class="n">face</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">uuid</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"uuid"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"fullname"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">asset_uuid</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"asset_uuid"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_person_pk</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"person"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">center_x</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"centerx"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">center_y</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"centery"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">size</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"size"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">quality</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"quality"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">source_width</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"sourcewidth"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">source_height</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"sourceheight"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">has_smile</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"has_smile"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">manual</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"manual"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">face_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"facetype"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">age_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"agetype"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">eye_makeup_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"eyemakeuptype"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">eye_state</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"eyestate"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">facial_hair_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"facialhairtype"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">gender_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"gendertype"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">glasses_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"glassestype"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">hair_color_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"haircolortype"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">intrash</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"intrash"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">lip_makeup_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"lipmakeuptype"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">smile_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"smiletype"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">uuid</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"uuid"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"fullname"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">asset_uuid</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"asset_uuid"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_person_pk</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"person"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">center_x</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"centerx"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">center_y</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"centery"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">size</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"size"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">quality</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"quality"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">source_width</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"sourcewidth"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">source_height</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"sourceheight"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">has_smile</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"has_smile"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">manual</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"manual"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">face_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"facetype"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">age_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"agetype"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">eye_makeup_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"eyemakeuptype"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">eye_state</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"eyestate"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">facial_hair_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"facialhairtype"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">gender_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"gendertype"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">glasses_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"glassestype"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">hair_color_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"haircolortype"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">intrash</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"intrash"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">lip_makeup_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"lipmakeuptype"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">smile_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"smiletype"</span><span class="p">]</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">center</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Coordinates, in PIL format, for center of face</span>
|
||||
<span class="sd">"""Coordinates, in PIL format, for center of face</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> tuple of coordinates in form (x, y)</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">return</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="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">size_pixels</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Size of face in pixels (centered around center_x, center_y)</span>
|
||||
<span class="sd">"""Size of face in pixels (centered around center_x, center_y)</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> size, in int pixels, of a circle drawn around the center of the face</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">photo</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">photo</span>
|
||||
<span class="n">size_reference</span> <span class="o">=</span> <span class="n">photo</span><span class="o">.</span><span class="n">width</span> <span class="k">if</span> <span class="n">photo</span><span class="o">.</span><span class="n">width</span> <span class="o">></span> <span class="n">photo</span><span class="o">.</span><span class="n">height</span> <span class="k">else</span> <span class="n">photo</span><span class="o">.</span><span class="n">height</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">size</span> <span class="o">*</span> <span class="n">size_reference</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">person_info</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""PersonInfo instance for person associated with this face"""</span>
|
||||
<span class="sd">"""PersonInfo instance for person associated with this face"""</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">_person</span>
|
||||
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
||||
@@ -374,18 +407,18 @@
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">photo</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""PhotoInfo instance associated with this face"""</span>
|
||||
<span class="sd">"""PhotoInfo instance associated with this face"""</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">_photo</span>
|
||||
<span class="k">except</span> <span class="ne">AttributeError</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="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">get_photo</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">asset_uuid</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_photo</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="n">logging</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Could not get photo for 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">"</span><span class="p">)</span>
|
||||
<span class="n">logging</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Could not get photo for 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">"</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_photo</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">mwg_rs_area</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Get coordinates for Metadata Working Group Region Area.</span>
|
||||
<span class="sd">"""Get coordinates for Metadata Working Group Region Area.</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> MWG_RS_Area named tuple with x, y, h, w where:</span>
|
||||
@@ -396,7 +429,7 @@
|
||||
|
||||
<span class="sd"> Reference:</span>
|
||||
<span class="sd"> https://photo.stackexchange.com/questions/106410/how-does-xmp-define-the-face-region</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="sd"> """</span>
|
||||
<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">center_x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">center_y</span>
|
||||
<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">_fix_orientation</span><span class="p">((</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">))</span>
|
||||
|
||||
@@ -411,7 +444,7 @@
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">mpri_reg_rect</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Get coordinates for Microsoft Photo Region Rectangle.</span>
|
||||
<span class="sd">"""Get coordinates for Microsoft Photo Region Rectangle.</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> MPRI_Reg_Rect named tuple with x, y, h, w where:</span>
|
||||
@@ -422,7 +455,7 @@
|
||||
|
||||
<span class="sd"> Reference:</span>
|
||||
<span class="sd"> https://docs.microsoft.com/en-us/windows/win32/wic/-wic-people-tagging</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="sd"> """</span>
|
||||
<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">center_x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">center_y</span>
|
||||
<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">_fix_orientation</span><span class="p">((</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">))</span>
|
||||
|
||||
@@ -440,13 +473,13 @@
|
||||
<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>
|
||||
<span class="sd">"""Get face rectangle coordinates for current version of the associated image</span>
|
||||
<span class="sd">"""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>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> list [(x0, x1), (y0, y1)] of coordinates in reference frame used by PIL</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">photo</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">photo</span>
|
||||
<span class="n">size_reference</span> <span class="o">=</span> <span class="n">photo</span><span class="o">.</span><span class="n">width</span> <span class="k">if</span> <span class="n">photo</span><span class="o">.</span><span class="n">width</span> <span class="o">></span> <span class="n">photo</span><span class="o">.</span><span class="n">height</span> <span class="k">else</span> <span class="n">photo</span><span class="o">.</span><span class="n">height</span>
|
||||
<span class="n">radius</span> <span class="o">=</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">size</span> <span class="o">/</span> <span class="mi">2</span><span class="p">)</span> <span class="o">*</span> <span class="n">size_reference</span>
|
||||
@@ -456,34 +489,34 @@
|
||||
<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">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">"""Roll, pitch, yaw of face in radians as tuple"""</span>
|
||||
<span class="sd">"""Roll, pitch, yaw of face in radians as tuple"""</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">"roll"</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">"roll"</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">"pitch"</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">"pitch"</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">"yaw"</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">"yaw"</span><span class="p">]</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">"roll"</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">"roll"</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">"pitch"</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">"pitch"</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">"yaw"</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">"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>
|
||||
|
||||
<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>
|
||||
<span class="sd">"""Return roll angle in radians of the face region"""</span>
|
||||
<span class="sd">"""Return roll angle in radians of the face region"""</span>
|
||||
<span class="n">roll</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</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="n">roll</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">pitch</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Return pitch angle in radians of the face region"""</span>
|
||||
<span class="sd">"""Return pitch angle in radians of the face region"""</span>
|
||||
<span class="n">_</span><span class="p">,</span> <span class="n">pitch</span><span class="p">,</span> <span class="n">_</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="n">pitch</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">yaw</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Return yaw angle in radians of the face region"""</span>
|
||||
<span class="sd">"""Return yaw angle in radians of the face region"""</span>
|
||||
<span class="n">_</span><span class="p">,</span> <span class="n">_</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="n">yaw</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">_fix_orientation</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">xy</span><span class="p">):</span>
|
||||
<span class="sd">"""Translate an (x, y) tuple based on image orientation</span>
|
||||
<span class="sd">"""Translate an (x, y) tuple based on image orientation</span>
|
||||
|
||||
<span class="sd"> Arguments:</span>
|
||||
<span class="sd"> xy: tuple of (x, y) coordinates for point to translate</span>
|
||||
@@ -491,7 +524,7 @@
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> (x, y) tuple of translated coordinates</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="c1"># Reference: https://github.com/neilpa/phace/blob/7594776480505d0c389688a42099c94ac5d34f3f/cmd/phace/draw.go#L79-L94</span>
|
||||
|
||||
<span class="n">orientation</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">orientation</span>
|
||||
@@ -515,15 +548,15 @@
|
||||
<span class="k">elif</span> <span class="n">orientation</span> <span class="o">==</span> <span class="mi">8</span><span class="p">:</span>
|
||||
<span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">y</span><span class="p">,</span> <span class="n">x</span>
|
||||
<span class="k">elif</span> <span class="n">orientation</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
|
||||
<span class="c1"># set by osxphotos if adjusted orientation cannot be read, assume it's 1</span>
|
||||
<span class="c1"># set by osxphotos if adjusted orientation cannot be read, assume it's 1</span>
|
||||
<span class="n">y</span> <span class="o">=</span> <span class="mf">1.0</span> <span class="o">-</span> <span class="n">y</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">logging</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Unhandled orientation: </span><span class="si">{</span><span class="n">orientation</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="n">logging</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Unhandled orientation: </span><span class="si">{</span><span class="n">orientation</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||||
|
||||
<span class="k">return</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="k">def</span> <span class="nf">_make_point</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">xy</span><span class="p">):</span>
|
||||
<span class="sd">"""Translate an (x, y) tuple based on image orientation</span>
|
||||
<span class="sd">"""Translate an (x, y) tuple based on image orientation</span>
|
||||
<span class="sd"> and convert to image coordinates</span>
|
||||
|
||||
<span class="sd"> Arguments:</span>
|
||||
@@ -532,7 +565,7 @@
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> (x, y) tuple of translated coordinates in pixels in PIL format/reference frame</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="c1"># Reference: https://github.com/neilpa/phace/blob/7594776480505d0c389688a42099c94ac5d34f3f/cmd/phace/draw.go#L79-L94</span>
|
||||
|
||||
<span class="n">orientation</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">orientation</span>
|
||||
@@ -544,7 +577,7 @@
|
||||
<span class="k">return</span> <span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">x</span> <span class="o">*</span> <span class="n">dx</span><span class="p">),</span> <span class="nb">int</span><span class="p">(</span><span class="n">y</span> <span class="o">*</span> <span class="n">dy</span><span class="p">))</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">_make_point_with_rotation</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">xy</span><span class="p">):</span>
|
||||
<span class="sd">"""Translate an (x, y) tuple based on image orientation and rotation</span>
|
||||
<span class="sd">"""Translate an (x, y) tuple based on image orientation and rotation</span>
|
||||
<span class="sd"> and convert to image coordinates</span>
|
||||
|
||||
<span class="sd"> Arguments:</span>
|
||||
@@ -553,7 +586,7 @@
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> (x, y) tuple of translated coordinates in pixels in PIL format/reference frame</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="c1"># convert to image coordinates</span>
|
||||
<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="n">xy</span><span class="p">)</span>
|
||||
@@ -566,58 +599,58 @@
|
||||
<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>
|
||||
<span class="sd">"""Returns dict representation of class instance"""</span>
|
||||
<span class="sd">"""Returns dict representation of class instance"""</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>
|
||||
<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">"uuid"</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="s2">"name"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
|
||||
<span class="s2">"asset_uuid"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">asset_uuid</span><span class="p">,</span>
|
||||
<span class="s2">"_person_pk"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_person_pk</span><span class="p">,</span>
|
||||
<span class="s2">"center_x"</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="s2">"center_y"</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="s2">"center"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">center</span><span class="p">,</span>
|
||||
<span class="s2">"size"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">size</span><span class="p">,</span>
|
||||
<span class="s2">"face_rect"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">face_rect</span><span class="p">(),</span>
|
||||
<span class="s2">"mpri_reg_rect"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">mpri_reg_rect</span><span class="o">.</span><span class="n">_asdict</span><span class="p">(),</span>
|
||||
<span class="s2">"mwg_rs_area"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">mwg_rs_area</span><span class="o">.</span><span class="n">_asdict</span><span class="p">(),</span>
|
||||
<span class="s2">"roll"</span><span class="p">:</span> <span class="n">roll</span><span class="p">,</span>
|
||||
<span class="s2">"pitch"</span><span class="p">:</span> <span class="n">pitch</span><span class="p">,</span>
|
||||
<span class="s2">"yaw"</span><span class="p">:</span> <span class="n">yaw</span><span class="p">,</span>
|
||||
<span class="s2">"quality"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">quality</span><span class="p">,</span>
|
||||
<span class="s2">"source_width"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">source_width</span><span class="p">,</span>
|
||||
<span class="s2">"source_height"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">source_height</span><span class="p">,</span>
|
||||
<span class="s2">"has_smile"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_smile</span><span class="p">,</span>
|
||||
<span class="s2">"manual"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">manual</span><span class="p">,</span>
|
||||
<span class="s2">"face_type"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">face_type</span><span class="p">,</span>
|
||||
<span class="s2">"age_type"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">age_type</span><span class="p">,</span>
|
||||
<span class="s2">"eye_makeup_type"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">eye_makeup_type</span><span class="p">,</span>
|
||||
<span class="s2">"eye_state"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">eye_state</span><span class="p">,</span>
|
||||
<span class="s2">"facial_hair_type"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">facial_hair_type</span><span class="p">,</span>
|
||||
<span class="s2">"gender_type"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">gender_type</span><span class="p">,</span>
|
||||
<span class="s2">"glasses_type"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">glasses_type</span><span class="p">,</span>
|
||||
<span class="s2">"hair_color_type"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">hair_color_type</span><span class="p">,</span>
|
||||
<span class="s2">"intrash"</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">"lip_makeup_type"</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">"smile_type"</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="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">"uuid"</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="s2">"name"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
|
||||
<span class="s2">"asset_uuid"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">asset_uuid</span><span class="p">,</span>
|
||||
<span class="s2">"_person_pk"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_person_pk</span><span class="p">,</span>
|
||||
<span class="s2">"center_x"</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="s2">"center_y"</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="s2">"center"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">center</span><span class="p">,</span>
|
||||
<span class="s2">"size"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">size</span><span class="p">,</span>
|
||||
<span class="s2">"face_rect"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">face_rect</span><span class="p">(),</span>
|
||||
<span class="s2">"mpri_reg_rect"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">mpri_reg_rect</span><span class="o">.</span><span class="n">_asdict</span><span class="p">(),</span>
|
||||
<span class="s2">"mwg_rs_area"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">mwg_rs_area</span><span class="o">.</span><span class="n">_asdict</span><span class="p">(),</span>
|
||||
<span class="s2">"roll"</span><span class="p">:</span> <span class="n">roll</span><span class="p">,</span>
|
||||
<span class="s2">"pitch"</span><span class="p">:</span> <span class="n">pitch</span><span class="p">,</span>
|
||||
<span class="s2">"yaw"</span><span class="p">:</span> <span class="n">yaw</span><span class="p">,</span>
|
||||
<span class="s2">"quality"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">quality</span><span class="p">,</span>
|
||||
<span class="s2">"source_width"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">source_width</span><span class="p">,</span>
|
||||
<span class="s2">"source_height"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">source_height</span><span class="p">,</span>
|
||||
<span class="s2">"has_smile"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_smile</span><span class="p">,</span>
|
||||
<span class="s2">"manual"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">manual</span><span class="p">,</span>
|
||||
<span class="s2">"face_type"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">face_type</span><span class="p">,</span>
|
||||
<span class="s2">"age_type"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">age_type</span><span class="p">,</span>
|
||||
<span class="s2">"eye_makeup_type"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">eye_makeup_type</span><span class="p">,</span>
|
||||
<span class="s2">"eye_state"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">eye_state</span><span class="p">,</span>
|
||||
<span class="s2">"facial_hair_type"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">facial_hair_type</span><span class="p">,</span>
|
||||
<span class="s2">"gender_type"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">gender_type</span><span class="p">,</span>
|
||||
<span class="s2">"glasses_type"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">glasses_type</span><span class="p">,</span>
|
||||
<span class="s2">"hair_color_type"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">hair_color_type</span><span class="p">,</span>
|
||||
<span class="s2">"intrash"</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">"lip_makeup_type"</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">"smile_type"</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="k">def</span> <span class="nf">json</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Return JSON representation of FaceInfo instance"""</span>
|
||||
<span class="sd">"""Return JSON representation of FaceInfo instance"""</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">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">"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">)"</span>
|
||||
<span class="k">return</span> <span class="sa">f</span><span class="s2">"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">)"</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__repr__</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">"FaceInfo(db=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="si">}</span><span class="s2">, pk=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_pk</span><span class="si">}</span><span class="s2">)"</span>
|
||||
<span class="k">return</span> <span class="sa">f</span><span class="s2">"FaceInfo(db=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="si">}</span><span class="s2">, pk=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_pk</span><span class="si">}</span><span class="s2">)"</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__eq__</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">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">)):</span>
|
||||
<span class="k">return</span> <span class="kc">False</span>
|
||||
|
||||
<span class="k">return</span> <span class="nb">all</span><span class="p">(</span>
|
||||
<span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">field</span><span class="p">)</span> <span class="o">==</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">field</span><span class="p">)</span> <span class="k">for</span> <span class="n">field</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">"_db"</span><span class="p">,</span> <span class="s2">"_pk"</span><span class="p">]</span>
|
||||
<span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">field</span><span class="p">)</span> <span class="o">==</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">field</span><span class="p">)</span> <span class="k">for</span> <span class="n">field</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">"_db"</span><span class="p">,</span> <span class="s2">"_pk"</span><span class="p">]</span>
|
||||
<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>
|
||||
@@ -625,7 +658,7 @@
|
||||
|
||||
|
||||
<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>
|
||||
<span class="sd">"""rotate image point about xm, ym by angle in radians</span>
|
||||
<span class="sd">"""rotate image point about xm, ym by angle in radians</span>
|
||||
|
||||
<span class="sd"> Arguments:</span>
|
||||
<span class="sd"> x: x coordinate of point to rotate</span>
|
||||
@@ -637,7 +670,7 @@
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> tuple of rotated points (xr, yr)</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="c1"># translate point relative to the mid point</span>
|
||||
<span class="n">x</span> <span class="o">=</span> <span class="n">x</span> <span class="o">-</span> <span class="n">xmid</span>
|
||||
<span class="n">y</span> <span class="o">=</span> <span class="n">y</span> <span class="o">-</span> <span class="n">ymid</span>
|
||||
@@ -688,7 +721,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>
|
||||
|
||||
@@ -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.55.6 documentation</title>
|
||||
<title>osxphotos.photoexporter - osxphotos 0.56.4 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.55.6 documentation</div></a>
|
||||
<a href="../../index.html"><div class="brand">osxphotos 0.56.4 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.55.6 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.56.4 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">
|
||||
|
||||
@@ -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.56.1 documentation</title>
|
||||
<title>osxphotos.photoinfo - osxphotos 0.56.5 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.56.1 documentation</div></a>
|
||||
<a href="../../index.html"><div class="brand">osxphotos 0.56.5 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.56.1 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.56.5 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">
|
||||
@@ -195,9 +195,7 @@
|
||||
</div>
|
||||
<article role="main">
|
||||
<h1>Source code for osxphotos.photoinfo</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">"""</span>
|
||||
<span class="sd">PhotoInfo class</span>
|
||||
<span class="sd">Represents a single photo in the Photos library and provides access to the photo's attributes</span>
|
||||
<span></span><span class="sd">""" PhotoInfo class: Represents a single photo in the Photos library and provides access to the photo's attributes</span>
|
||||
<span class="sd">PhotosDB.photos() returns a list of PhotoInfo objects</span>
|
||||
<span class="sd">"""</span>
|
||||
|
||||
@@ -214,11 +212,13 @@
|
||||
<span class="kn">import</span> <span class="nn">plistlib</span>
|
||||
<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">timedelta</span><span class="p">,</span> <span class="n">timezone</span>
|
||||
<span class="kn">from</span> <span class="nn">functools</span> <span class="kn">import</span> <span class="n">cached_property</span>
|
||||
<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">Optional</span>
|
||||
<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Any</span><span class="p">,</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">Optional</span>
|
||||
|
||||
<span class="kn">import</span> <span class="nn">yaml</span>
|
||||
<span class="kn">from</span> <span class="nn">osxmetadata</span> <span class="kn">import</span> <span class="n">OSXMetaData</span>
|
||||
|
||||
<span class="kn">import</span> <span class="nn">osxphotos</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">._constants</span> <span class="kn">import</span> <span class="p">(</span>
|
||||
<span class="n">_DB_TABLE_NAMES</span><span class="p">,</span>
|
||||
<span class="n">_MOVIE_TYPE</span><span class="p">,</span>
|
||||
@@ -272,10 +272,10 @@
|
||||
<span class="sd"> including keywords, persons, albums, uuid, path, etc.</span>
|
||||
<span class="sd"> """</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">uuid</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">info</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_uuid</span> <span class="o">=</span> <span class="n">uuid</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_info</span> <span class="o">=</span> <span class="n">info</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="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="s2">"osxphotos.PhotosDB"</span><span class="p">,</span> <span class="n">uuid</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">info</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</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="nb">str</span> <span class="o">=</span> <span class="n">uuid</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_info</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">=</span> <span class="n">info</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="p">:</span> <span class="s2">"osxphotos.PhotosDB"</span> <span class="o">=</span> <span class="n">db</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_verbose</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">_verbose</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
|
||||
@@ -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.56.2 documentation</title>
|
||||
<title>osxphotos.photosdb.photosdb - osxphotos 0.56.5 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.56.2 documentation</div></a>
|
||||
<a href="../../../index.html"><div class="brand">osxphotos 0.56.5 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.56.2 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.56.5 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">
|
||||
@@ -200,18 +200,21 @@
|
||||
<span class="sd">Processes a Photos.app library database to extract information about photos</span>
|
||||
<span class="sd">"""</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">logging</span>
|
||||
<span class="kn">import</span> <span class="nn">os</span>
|
||||
<span class="kn">import</span> <span class="nn">os.path</span>
|
||||
<span class="kn">import</span> <span class="nn">pathlib</span>
|
||||
<span class="kn">import</span> <span class="nn">platform</span>
|
||||
<span class="kn">import</span> <span class="nn">re</span>
|
||||
<span class="kn">import</span> <span class="nn">sqlite3</span>
|
||||
<span class="kn">import</span> <span class="nn">sys</span>
|
||||
<span class="kn">import</span> <span class="nn">tempfile</span>
|
||||
<span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">OrderedDict</span>
|
||||
<span class="kn">from</span> <span class="nn">collections.abc</span> <span class="kn">import</span> <span class="n">Iterable</span>
|
||||
<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span><span class="p">,</span> <span class="n">timedelta</span><span class="p">,</span> <span class="n">timezone</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">typing</span> <span class="kn">import</span> <span class="n">Any</span><span class="p">,</span> <span class="n">List</span><span class="p">,</span> <span class="n">Optional</span>
|
||||
<span class="kn">from</span> <span class="nn">unicodedata</span> <span class="kn">import</span> <span class="n">normalize</span>
|
||||
|
||||
<span class="kn">import</span> <span class="nn">bitmath</span>
|
||||
@@ -521,8 +524,15 @@
|
||||
<span class="c1"># _db_version is set from photos.db</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_db_version</span> <span class="o">=</span> <span class="n">get_db_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="c1"># _photos_version is set from Photos.sqlite which only exists for Photos 5+</span>
|
||||
<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">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db_version</span> <span class="o">==</span> <span class="mi">4</span> <span class="k">else</span> <span class="mi">5</span>
|
||||
|
||||
<span class="n">db_ver_int</span> <span class="o">=</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="k">if</span> <span class="n">db_ver_int</span> <span class="o"><</span> <span class="mi">3000</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">2</span>
|
||||
<span class="k">elif</span> <span class="n">db_ver_int</span> <span class="o"><</span> <span class="mi">4000</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">3</span>
|
||||
<span class="k">elif</span> <span class="n">db_ver_int</span> <span class="o"><</span> <span class="mi">5000</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">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="c1"># If Photos >= 5, actual data isn'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">></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>
|
||||
@@ -782,6 +792,11 @@
|
||||
<span class="sd">"""returns path to the Photos library PhotosDB was initialized with"""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_library_path</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">photos_version</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns version of Photos app that created the library"""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_photos_ver</span>
|
||||
|
||||
<div class="viewcode-block" id="PhotosDB.get_db_connection"><a class="viewcode-back" href="../../../reference.html#osxphotos.PhotosDB.get_db_connection">[docs]</a> <span class="k">def</span> <span class="nf">get_db_connection</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Get connection to the working copy of the Photos database</span>
|
||||
|
||||
@@ -890,6 +905,8 @@
|
||||
<span class="s2">"displayname"</span><span class="p">:</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">person</span><span class="p">[</span><span class="mi">4</span><span class="p">]),</span>
|
||||
<span class="s2">"photo_uuid"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="s2">"keyface_uuid"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="s2">"type"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> <span class="c1"># Photos 5+</span>
|
||||
<span class="s2">"manualorder"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="c1"># Photos 5+</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_dbpersons_fullname</span><span class="p">[</span><span class="n">fullname</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">pk</span><span class="p">)</span>
|
||||
@@ -1872,7 +1889,9 @@
|
||||
<span class="sd"> ZPERSON.ZFULLNAME,</span>
|
||||
<span class="sd"> ZPERSON.ZFACECOUNT,</span>
|
||||
<span class="sd"> ZPERSON.ZKEYFACE,</span>
|
||||
<span class="sd"> ZPERSON.ZDISPLAYNAME</span>
|
||||
<span class="sd"> ZPERSON.ZDISPLAYNAME,</span>
|
||||
<span class="sd"> ZPERSON.ZTYPE,</span>
|
||||
<span class="sd"> ZPERSON.ZMANUALORDER</span>
|
||||
<span class="sd"> FROM ZPERSON</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="p">)</span>
|
||||
@@ -1883,6 +1902,8 @@
|
||||
<span class="c1"># 3 ZPERSON.ZFACECOUNT,</span>
|
||||
<span class="c1"># 4 ZPERSON.ZKEYFACE,</span>
|
||||
<span class="c1"># 5 ZPERSON.ZDISPLAYNAME</span>
|
||||
<span class="c1"># 6 ZPERSON.ZTYPE, # ZTYPE = 1 == favorite, 0 == not favorite</span>
|
||||
<span class="c1"># 7 ZPERSON.ZMANUALORDER # favorites are sorted by ZMANUALORDER</span>
|
||||
|
||||
<span class="k">for</span> <span class="n">person</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
||||
<span class="n">pk</span> <span class="o">=</span> <span class="n">person</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
||||
@@ -1900,6 +1921,8 @@
|
||||
<span class="s2">"displayname"</span><span class="p">:</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">person</span><span class="p">[</span><span class="mi">5</span><span class="p">]),</span>
|
||||
<span class="s2">"photo_uuid"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="s2">"keyface_uuid"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="s2">"type"</span><span class="p">:</span> <span class="n">person</span><span class="p">[</span><span class="mi">6</span><span class="p">],</span>
|
||||
<span class="s2">"manualorder"</span><span class="p">:</span> <span class="n">person</span><span class="p">[</span><span class="mi">7</span><span class="p">],</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_dbpersons_fullname</span><span class="p">[</span><span class="n">fullname</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">pk</span><span class="p">)</span>
|
||||
@@ -3748,10 +3771,11 @@
|
||||
|
||||
<span class="k">return</span> <span class="n">photos</span></div>
|
||||
|
||||
<div class="viewcode-block" id="PhotosDB.execute"><a class="viewcode-back" href="../../../reference.html#osxphotos.PhotosDB.execute">[docs]</a> <span class="k">def</span> <span class="nf">execute</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sql</span><span class="p">):</span>
|
||||
<div class="viewcode-block" id="PhotosDB.execute"><a class="viewcode-back" href="../../../reference.html#osxphotos.PhotosDB.execute">[docs]</a> <span class="k">def</span> <span class="nf">execute</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sql</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">params</span><span class="p">:</span> <span class="n">Any</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="o">-></span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">Cursor</span><span class="p">:</span>
|
||||
<span class="sd">"""Execute sql statement and return cursor"""</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_db_connection</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_db_connection</span><span class="p">()</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db_connection</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">sql</span><span class="p">)</span></div>
|
||||
<span class="n">params</span> <span class="o">=</span> <span class="n">params</span> <span class="ow">or</span> <span class="p">()</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db_connection</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">sql</span><span class="p">,</span> <span class="n">params</span><span class="p">)</span></div>
|
||||
|
||||
<span class="k">def</span> <span class="nf">_duplicate_signature</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">uuid</span><span class="p">):</span>
|
||||
<span class="sd">"""Compute a signature for finding possible duplicates"""</span>
|
||||
|
||||
@@ -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.56.2 documentation</title>
|
||||
<title>osxphotos.scoreinfo - osxphotos 0.56.4 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.56.2 documentation</div></a>
|
||||
<a href="../../index.html"><div class="brand">osxphotos 0.56.4 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.56.2 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.56.4 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">
|
||||
|
||||
@@ -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.54.1 documentation</title>
|
||||
<title>osxphotos.searchinfo - osxphotos 0.56.4 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.54.1 documentation</div></a>
|
||||
<a href="../../index.html"><div class="brand">osxphotos 0.56.4 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.54.1 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.56.4 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">
|
||||
@@ -336,6 +336,13 @@
|
||||
<span class="k">return</span> <span class="p">[]</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_categories</span><span class="o">.</span><span class="n">DETECTED_TEXT</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">text_found</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Returns True if photos has detected text (macOS 13+ / Photos 8+ only)"""</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_photo</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_photos_ver</span> <span class="o"><</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="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_categories</span><span class="o">.</span><span class="n">TEXT_FOUND</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">camera</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns camera name (macOS 13+ / Photos 8+ only)"""</span>
|
||||
@@ -344,10 +351,18 @@
|
||||
<span class="n">camera</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_categories</span><span class="o">.</span><span class="n">CAMERA</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">camera</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">camera</span> <span class="k">else</span> <span class="s2">""</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">source</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns source of the photo (e.g. "Messages", "Safar", etc) (macOS 13+ / Photos 8+ only)"""</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_photo</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_photos_ver</span> <span class="o"><</span> <span class="mi">8</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="s2">""</span>
|
||||
<span class="n">source</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_categories</span><span class="o">.</span><span class="n">SOURCE</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">source</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">source</span> <span class="k">else</span> <span class="s2">""</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">all</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""return all search info properties in a single list"""</span>
|
||||
<span class="nb">all</span> <span class="o">=</span> <span class="p">(</span>
|
||||
<span class="n">all_</span> <span class="o">=</span> <span class="p">(</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">labels</span>
|
||||
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">place_names</span>
|
||||
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">streets</span>
|
||||
@@ -362,23 +377,23 @@
|
||||
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">detected_text</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">city</span><span class="p">:</span>
|
||||
<span class="nb">all</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">city</span><span class="p">]</span>
|
||||
<span class="n">all_</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">city</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">state</span><span class="p">:</span>
|
||||
<span class="nb">all</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">state</span><span class="p">]</span>
|
||||
<span class="n">all_</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">state</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">state_abbreviation</span><span class="p">:</span>
|
||||
<span class="nb">all</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">state_abbreviation</span><span class="p">]</span>
|
||||
<span class="n">all_</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">state_abbreviation</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">country</span><span class="p">:</span>
|
||||
<span class="nb">all</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">country</span><span class="p">]</span>
|
||||
<span class="n">all_</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">country</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">month</span><span class="p">:</span>
|
||||
<span class="nb">all</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">month</span><span class="p">]</span>
|
||||
<span class="n">all_</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">month</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">year</span><span class="p">:</span>
|
||||
<span class="nb">all</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">year</span><span class="p">]</span>
|
||||
<span class="n">all_</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">year</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">season</span><span class="p">:</span>
|
||||
<span class="nb">all</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">season</span><span class="p">]</span>
|
||||
<span class="n">all_</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">season</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">camera</span><span class="p">:</span>
|
||||
<span class="nb">all</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">camera</span><span class="p">]</span>
|
||||
<span class="n">all_</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">camera</span><span class="p">]</span>
|
||||
|
||||
<span class="k">return</span> <span class="nb">all</span>
|
||||
<span class="k">return</span> <span class="n">all_</span>
|
||||
|
||||
<div class="viewcode-block" id="SearchInfo.asdict"><a class="viewcode-back" href="../../reference.html#osxphotos.SearchInfo.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">"""return dict of search info"""</span>
|
||||
@@ -403,6 +418,7 @@
|
||||
<span class="s2">"media_types"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">media_types</span><span class="p">,</span>
|
||||
<span class="s2">"detected_text"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">detected_text</span><span class="p">,</span>
|
||||
<span class="s2">"camera"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">camera</span><span class="p">,</span>
|
||||
<span class="s2">"source"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">source</span><span class="p">,</span>
|
||||
<span class="p">}</span></div>
|
||||
|
||||
<span class="k">def</span> <span class="nf">_get_text_for_category</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">category</span><span class="p">):</span>
|
||||
|
||||
@@ -357,7 +357,7 @@ Template Substitutions
|
||||
* - {tab}
|
||||
- :A tab: '\t'
|
||||
* - {osxphotos_version}
|
||||
- The osxphotos version, e.g. '0.56.3'
|
||||
- The osxphotos version, e.g. '0.56.6'
|
||||
* - {osxphotos_cmd_line}
|
||||
- The full command line used to run osxphotos
|
||||
* - {album}
|
||||
|
||||
2
docs/_static/documentation_options.js
vendored
2
docs/_static/documentation_options.js
vendored
@@ -1,6 +1,6 @@
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
|
||||
VERSION: '0.56.3',
|
||||
VERSION: '0.56.6',
|
||||
LANGUAGE: 'en',
|
||||
COLLAPSE_INDEX: false,
|
||||
BUILDER: 'html',
|
||||
|
||||
@@ -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.56.3 documentation</title>
|
||||
<title>OSXPhotos Command Line Interface (CLI) - osxphotos 0.56.6 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.56.3 documentation</div></a>
|
||||
<a href="index.html"><div class="brand">osxphotos 0.56.6 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.56.3 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.56.6 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">
|
||||
@@ -4404,6 +4404,12 @@ See Timewarp Overview below for additional information.</p>
|
||||
<dd><p>Pull date/time and timezone for selected photos from EXIF metadata in the original file into Photos and update the associated data in Photos to match the EXIF data. –pull-exif will be executed before any other updates are performed on the photo. It is possible for images to have missing EXIF data, for example the date/time could be set but there might be no timezone set in the EXIF metadata. Missing data will be handled thusly: if date/time/timezone are all present in the EXIF data, the photo’s date/time/timezone will be updated. If timezone is missing but date/time is present, only the photo’s date/time will be updated. If date/time is missing but the timezone is present, only the photo’s timezone will be updated unless –use-file-time is set in which case, the photo’s file modification date/time will be used in place of EXIF date/time. If the date is present but the time is missing, the time will be set to 00:00:00. Requires the third-party exiftool utility be installed (see <a class="reference external" href="https://exiftool.org/">https://exiftool.org/</a>). See also –push-exif.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-M">
|
||||
<span id="cmdoption-osxphotos-timewarp-m"></span><span id="cmdoption-osxphotos-timewarp-parse-date"></span><span class="sig-name descname"><span class="pre">-M</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">--parse-date</span></span><span class="sig-prename descclassname"> <span class="pre"><DATE_PATTERN></span></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-M" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Parse date from filename using DATE_PATTERN and set photo’s date to match. If file does not match DATE_PATTERN, the date will not be changed. DATE_PATTERN is a strptime-compatible pattern with extensions as pattern described below. If DATE_PATTERN matches time zone information, the photo’s timezone will be set to match. For example, if your photos are named ‘IMG_1234_2022_11_23_12_34_56.jpg’ where the date/time is ‘2022-11-23 12:34:56’, you could use the pattern ‘%Y_%m_%d_%H_%M_%S’ or ‘IMG_*_%Y_%m_%d_%H_%M_%S’ to further narrow the pattern to only match files with ‘<a href="#id5"><span class="problematic" id="id6">IMG_xxxx_</span></a>’ in the name.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-F">
|
||||
<span id="cmdoption-osxphotos-timewarp-f"></span><span id="cmdoption-osxphotos-timewarp-function"></span><span class="sig-name descname"><span class="pre">-F</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">--function</span></span><span class="sig-prename descclassname"> <span class="pre"><filename.py::function></span></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-F" title="Permalink to this definition">#</a></dt>
|
||||
@@ -4411,14 +4417,14 @@ See Timewarp Overview below for additional information.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-m">
|
||||
<span id="cmdoption-osxphotos-timewarp-match-time"></span><span class="sig-name descname"><span class="pre">-m</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">--match-time</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-m" title="Permalink to this definition">#</a></dt>
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-0">
|
||||
<span id="cmdoption-osxphotos-timewarp-match-time"></span><span class="sig-name descname"><span class="pre">-m</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">--match-time</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-0" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>When used with –timezone, adjusts the photo time so that the timestamp in the new timezone matches the timestamp in the old timezone. For example, if photo has time of 12:00 and timezone of GMT+01:00 and new timezone is specified as ‘–timezone +02:00’ (one hour ahead of current GMT+01:00 timezone), the photo’s new time will be 12:00 GMT+02:00. That is, the timezone will have changed but the timestamp of the photo will match the previous timestamp. Use –match-time when the camera’s time was correct for the time the photo was taken but the timezone was missing or wrong and you want to adjust the timezone while preserving the photo’s time. See also –timezone.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-0">
|
||||
<span id="cmdoption-osxphotos-timewarp-use-file-time"></span><span class="sig-name descname"><span class="pre">-f</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">--use-file-time</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-0" title="Permalink to this definition">#</a></dt>
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-1">
|
||||
<span id="cmdoption-osxphotos-timewarp-use-file-time"></span><span class="sig-name descname"><span class="pre">-f</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">--use-file-time</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-1" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>When used with –pull-exif, the file modification date/time will be used if date/time is missing from the EXIF data.</p>
|
||||
</dd></dl>
|
||||
|
||||
|
||||
@@ -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.56.3 documentation</title>
|
||||
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/><title>Index - osxphotos 0.56.6 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.56.3 documentation</div></a>
|
||||
<a href="index.html"><div class="brand">osxphotos 0.56.6 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.56.3 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.56.6 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">
|
||||
@@ -1264,7 +1264,7 @@
|
||||
--match-time
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-m">osxphotos-timewarp command line option</a>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-0">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@@ -1797,6 +1797,8 @@
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-import-P">osxphotos-import command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-M">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@@ -2411,7 +2413,7 @@
|
||||
--use-file-time
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-0">osxphotos-timewarp command line option</a>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-1">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@@ -2645,7 +2647,7 @@
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-f">osxphotos-query command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-0">osxphotos-timewarp command line option</a>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-1">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-uuid-f">osxphotos-uuid command line option</a>
|
||||
</li>
|
||||
@@ -2702,6 +2704,13 @@
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-import-l">osxphotos-import command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
-M
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-M">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@@ -2712,7 +2721,7 @@
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-sync-m">osxphotos-sync command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-m">osxphotos-timewarp command line option</a>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-0">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@@ -3172,13 +3181,17 @@
|
||||
</ul></li>
|
||||
<li><a href="reference.html#osxphotos.ExportOptions.face_regions">face_regions (osxphotos.ExportOptions attribute)</a>
|
||||
</li>
|
||||
<li><a href="reference.html#osxphotos.PhotoInfo.favorite">favorite (osxphotos.PhotoInfo property)</a>
|
||||
<li><a href="reference.html#osxphotos.PersonInfo.favorite">favorite (osxphotos.PersonInfo property)</a>
|
||||
|
||||
<ul>
|
||||
<li><a href="reference.html#osxphotos.PhotoInfo.favorite">(osxphotos.PhotoInfo property)</a>
|
||||
</li>
|
||||
<li><a href="reference.html#osxphotos.QueryOptions.favorite">(osxphotos.QueryOptions attribute)</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li><a href="reference.html#osxphotos.ExportOptions.favorite_rating">favorite_rating (osxphotos.ExportOptions attribute)</a>
|
||||
</li>
|
||||
<li><a href="reference.html#osxphotos.PersonInfo.feature_less">feature_less (osxphotos.PersonInfo property)</a>
|
||||
</li>
|
||||
<li><a href="reference.html#osxphotos.FileUtilNoOp.file_sig">file_sig() (osxphotos.FileUtilNoOp class method)</a>
|
||||
</li>
|
||||
@@ -3192,11 +3205,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>
|
||||
@@ -5096,9 +5109,11 @@
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-L">--library</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-m">--match-time</a>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-0">--match-time</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-o">--output-file</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-M">--parse-date</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-plain">--plain</a>
|
||||
</li>
|
||||
@@ -5116,7 +5131,7 @@
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-z">--timezone</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-0">--use-file-time</a>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-1">--use-file-time</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-V">--verbose</a>
|
||||
</li>
|
||||
@@ -5132,13 +5147,15 @@
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-F">-F</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-0">-f</a>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-1">-f</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-i">-i</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-L">-L</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-m">-m</a>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-M">-M</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-0">-m</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-o">-o</a>
|
||||
</li>
|
||||
@@ -5276,10 +5293,10 @@
|
||||
<li><a href="reference.html#osxphotos.QueryOptions.photos">(osxphotos.QueryOptions attribute)</a>
|
||||
</li>
|
||||
</ul></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>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="reference.html#osxphotos.PhotosDB.photos_by_uuid">photos_by_uuid() (osxphotos.PhotosDB method)</a>
|
||||
</li>
|
||||
<li>
|
||||
@@ -5305,6 +5322,8 @@
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-arg-PHOTOS_LIBRARY">osxphotos-query command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li><a href="reference.html#osxphotos.PhotosDB.photos_version">photos_version (osxphotos.PhotosDB property)</a>
|
||||
</li>
|
||||
<li><a href="reference.html#osxphotos.PhotosAlbum">PhotosAlbum (class in osxphotos)</a>
|
||||
</li>
|
||||
<li><a href="reference.html#osxphotos.PhotosAlbumPhotoScript">PhotosAlbumPhotoScript (class in osxphotos)</a>
|
||||
@@ -5444,14 +5463,14 @@
|
||||
</li>
|
||||
<li><a href="reference.html#osxphotos.ExifTool.setvalue">setvalue() (osxphotos.ExifTool method)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<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>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<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>
|
||||
@@ -5463,6 +5482,12 @@
|
||||
</li>
|
||||
</ul></li>
|
||||
<li><a href="reference.html#osxphotos.AlbumInfo.sort_order">sort_order (osxphotos.AlbumInfo property)</a>
|
||||
|
||||
<ul>
|
||||
<li><a href="reference.html#osxphotos.PersonInfo.sort_order">(osxphotos.PersonInfo property)</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li><a href="reference.html#osxphotos.SearchInfo.source">source (osxphotos.SearchInfo property)</a>
|
||||
</li>
|
||||
<li><a href="reference.html#osxphotos.MomentInfo.start_date">start_date (osxphotos.MomentInfo property)</a>
|
||||
</li>
|
||||
@@ -5493,6 +5518,8 @@
|
||||
<h2>T</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="reference.html#osxphotos.SearchInfo.text_found">text_found (osxphotos.SearchInfo property)</a>
|
||||
</li>
|
||||
<li><a href="reference.html#osxphotos.PhotoInfo.time_lapse">time_lapse (osxphotos.PhotoInfo property)</a>
|
||||
|
||||
<ul>
|
||||
|
||||
@@ -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.56.3 documentation</title>
|
||||
<title>osxphotos 0.56.6 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.56.3 documentation</div></a>
|
||||
<a href="#"><div class="brand">osxphotos 0.56.6 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.56.3 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.56.6 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">
|
||||
@@ -422,8 +422,11 @@
|
||||
<li class="toctree-l2"><a class="reference internal" href="reference.html#osxphotos.PersonInfo"><code class="docutils literal notranslate"><span class="pre">PersonInfo</span></code></a><ul>
|
||||
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PersonInfo.asdict"><code class="docutils literal notranslate"><span class="pre">PersonInfo.asdict()</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PersonInfo.face_info"><code class="docutils literal notranslate"><span class="pre">PersonInfo.face_info</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PersonInfo.favorite"><code class="docutils literal notranslate"><span class="pre">PersonInfo.favorite</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PersonInfo.feature_less"><code class="docutils literal notranslate"><span class="pre">PersonInfo.feature_less</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PersonInfo.json"><code class="docutils literal notranslate"><span class="pre">PersonInfo.json()</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PersonInfo.photos"><code class="docutils literal notranslate"><span class="pre">PersonInfo.photos</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PersonInfo.sort_order"><code class="docutils literal notranslate"><span class="pre">PersonInfo.sort_order</span></code></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="reference.html#osxphotos.PhotoExporter"><code class="docutils literal notranslate"><span class="pre">PhotoExporter</span></code></a><ul>
|
||||
@@ -572,6 +575,7 @@
|
||||
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PhotosDB.persons_as_dict"><code class="docutils literal notranslate"><span class="pre">PhotosDB.persons_as_dict</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PhotosDB.photos"><code class="docutils literal notranslate"><span class="pre">PhotosDB.photos()</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PhotosDB.photos_by_uuid"><code class="docutils literal notranslate"><span class="pre">PhotosDB.photos_by_uuid()</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PhotosDB.photos_version"><code class="docutils literal notranslate"><span class="pre">PhotosDB.photos_version</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.PhotosDB.project_info"><code class="docutils literal notranslate"><span class="pre">PhotosDB.project_info</span></code></a></li>
|
||||
<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>
|
||||
@@ -681,9 +685,11 @@
|
||||
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.SearchInfo.neighborhoods"><code class="docutils literal notranslate"><span class="pre">SearchInfo.neighborhoods</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.SearchInfo.place_names"><code class="docutils literal notranslate"><span class="pre">SearchInfo.place_names</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.SearchInfo.season"><code class="docutils literal notranslate"><span class="pre">SearchInfo.season</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.SearchInfo.source"><code class="docutils literal notranslate"><span class="pre">SearchInfo.source</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.SearchInfo.state"><code class="docutils literal notranslate"><span class="pre">SearchInfo.state</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.SearchInfo.state_abbreviation"><code class="docutils literal notranslate"><span class="pre">SearchInfo.state_abbreviation</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.SearchInfo.streets"><code class="docutils literal notranslate"><span class="pre">SearchInfo.streets</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.SearchInfo.text_found"><code class="docutils literal notranslate"><span class="pre">SearchInfo.text_found</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.SearchInfo.venue_types"><code class="docutils literal notranslate"><span class="pre">SearchInfo.venue_types</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.SearchInfo.venues"><code class="docutils literal notranslate"><span class="pre">SearchInfo.venues</span></code></a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="reference.html#osxphotos.SearchInfo.year"><code class="docutils literal notranslate"><span class="pre">SearchInfo.year</span></code></a></li>
|
||||
|
||||
BIN
docs/objects.inv
BIN
docs/objects.inv
Binary file not shown.
@@ -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 OSXPhotos’s documentation!" href="index.html" />
|
||||
|
||||
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
|
||||
<title>OSXPhotos - osxphotos 0.56.3 documentation</title>
|
||||
<title>OSXPhotos - osxphotos 0.56.6 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.56.3 documentation</div></a>
|
||||
<a href="index.html"><div class="brand">osxphotos 0.56.6 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.56.3 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.56.6 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">
|
||||
|
||||
@@ -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 API" href="reference.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.56.3 documentation</title>
|
||||
<title>OSXPhotos Python Package Overview - osxphotos 0.56.6 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.56.3 documentation</div></a>
|
||||
<a href="index.html"><div class="brand">osxphotos 0.56.6 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.56.3 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.56.6 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">
|
||||
|
||||
@@ -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.56.3 documentation</title>
|
||||
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/><title>Python Module Index - osxphotos 0.56.6 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.56.3 documentation</div></a>
|
||||
<a href="index.html"><div class="brand">osxphotos 0.56.6 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.56.3 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.56.6 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">
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="prev" title="OSXPhotos Python Package Overview" href="package_overview.html" />
|
||||
|
||||
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
|
||||
<title>OSXPhotos python API - osxphotos 0.56.3 documentation</title>
|
||||
<title>OSXPhotos python API - osxphotos 0.56.6 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.56.3 documentation</div></a>
|
||||
<a href="index.html"><div class="brand">osxphotos 0.56.6 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.56.3 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.56.6 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">
|
||||
@@ -1295,7 +1295,7 @@ including folders, albums, etc</p>
|
||||
|
||||
<dl class="py class">
|
||||
<dt class="sig sig-object py" id="osxphotos.PersonInfo">
|
||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">osxphotos.</span></span><span class="sig-name descname"><span class="pre">PersonInfo</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">db</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">pk</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/osxphotos/personinfo.html#PersonInfo"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#osxphotos.PersonInfo" title="Permalink to this definition">#</a></dt>
|
||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">osxphotos.</span></span><span class="sig-name descname"><span class="pre">PersonInfo</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">db</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="#osxphotos.PhotosDB" title="osxphotos.photosdb.photosdb.PhotosDB"><span class="pre">PhotosDB</span></a></span></em>, <em class="sig-param"><span class="n"><span class="pre">pk</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/osxphotos/personinfo.html#PersonInfo"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#osxphotos.PersonInfo" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Info about a person in the Photos library</p>
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="osxphotos.PersonInfo.asdict">
|
||||
@@ -1310,6 +1310,18 @@ including folders, albums, etc</p>
|
||||
Highest quality face is result[0] and lowest quality face is result[n]</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py property">
|
||||
<dt class="sig sig-object py" id="osxphotos.PersonInfo.favorite">
|
||||
<em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">favorite</span></span><a class="headerlink" href="#osxphotos.PersonInfo.favorite" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Returns True if person is a favorite, False otherwise; Photos 5+ only; returns False on Photos <= 4</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py property">
|
||||
<dt class="sig sig-object py" id="osxphotos.PersonInfo.feature_less">
|
||||
<em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">feature_less</span></span><a class="headerlink" href="#osxphotos.PersonInfo.feature_less" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Returns True if person has been marked as “Feature This Person Less” in Photos, False otherwise; Photos 8+ only; returns False on Photos <= 7</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="osxphotos.PersonInfo.json">
|
||||
<span class="sig-name descname"><span class="pre">json</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/osxphotos/personinfo.html#PersonInfo.json"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#osxphotos.PersonInfo.json" title="Permalink to this definition">#</a></dt>
|
||||
@@ -1322,6 +1334,12 @@ Highest quality face is result[0] and lowest quality face is result[n]</p>
|
||||
<dd><p>Returns list of PhotoInfo objects associated with this person</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py property">
|
||||
<dt class="sig sig-object py" id="osxphotos.PersonInfo.sort_order">
|
||||
<em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">sort_order</span></span><a class="headerlink" href="#osxphotos.PersonInfo.sort_order" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Returns sort order of person; favorite persons are sorted before non-favorite persons”; Photos 5+ only; returns 0 on Photos <= 4</p>
|
||||
</dd></dl>
|
||||
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py class">
|
||||
@@ -1420,7 +1438,7 @@ network drive or other slower external storage).</p>
|
||||
|
||||
<dl class="py class">
|
||||
<dt class="sig sig-object py" id="osxphotos.PhotoInfo">
|
||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">osxphotos.</span></span><span class="sig-name descname"><span class="pre">PhotoInfo</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">db</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">uuid</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">info</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/osxphotos/photoinfo.html#PhotoInfo"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#osxphotos.PhotoInfo" title="Permalink to this definition">#</a></dt>
|
||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">osxphotos.</span></span><span class="sig-name descname"><span class="pre">PhotoInfo</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">db</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="#osxphotos.PhotosDB" title="osxphotos.photosdb.photosdb.PhotosDB"><span class="pre">PhotosDB</span></a></span></em>, <em class="sig-param"><span class="n"><span class="pre">uuid</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">info</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">dict</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">Any</span><span class="p"><span class="pre">]</span></span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/osxphotos/photoinfo.html#PhotoInfo"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#osxphotos.PhotoInfo" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Info about a specific photo, contains all the details about the photo
|
||||
including keywords, persons, albums, uuid, path, etc.</p>
|
||||
<dl class="py property">
|
||||
@@ -2314,7 +2332,7 @@ valid only on Photos 5; on Photos <= 4, prints warning and returns empty dict
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="osxphotos.PhotosDB.execute">
|
||||
<span class="sig-name descname"><span class="pre">execute</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">sql</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/osxphotos/photosdb/photosdb.html#PhotosDB.execute"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#osxphotos.PhotosDB.execute" title="Permalink to this definition">#</a></dt>
|
||||
<span class="sig-name descname"><span class="pre">execute</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">sql</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">params</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">Any</span><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><span class="pre">None</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">Cursor</span></span></span><a class="reference internal" href="_modules/osxphotos/photosdb/photosdb.html#PhotosDB.execute"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#osxphotos.PhotosDB.execute" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Execute sql statement and return cursor</p>
|
||||
</dd></dl>
|
||||
|
||||
@@ -2482,6 +2500,12 @@ Returns photos regardless of intrash state.</p>
|
||||
</dl>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py property">
|
||||
<dt class="sig sig-object py" id="osxphotos.PhotosDB.photos_version">
|
||||
<em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">photos_version</span></span><a class="headerlink" href="#osxphotos.PhotosDB.photos_version" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>returns version of Photos app that created the library</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py property">
|
||||
<dt class="sig sig-object py" id="osxphotos.PhotosDB.project_info">
|
||||
<em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">project_info</span></span><a class="headerlink" href="#osxphotos.PhotosDB.project_info" title="Permalink to this definition">#</a></dt>
|
||||
@@ -3500,6 +3524,12 @@ Projects are cards, calendars, slideshows, etc.</p>
|
||||
<dd><p>returns season name</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py property">
|
||||
<dt class="sig sig-object py" id="osxphotos.SearchInfo.source">
|
||||
<em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">source</span></span><a class="headerlink" href="#osxphotos.SearchInfo.source" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>returns source of the photo (e.g. “Messages”, “Safar”, etc) (macOS 13+ / Photos 8+ only)</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py property">
|
||||
<dt class="sig sig-object py" id="osxphotos.SearchInfo.state">
|
||||
<em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">state</span></span><a class="headerlink" href="#osxphotos.SearchInfo.state" title="Permalink to this definition">#</a></dt>
|
||||
@@ -3518,6 +3548,12 @@ Projects are cards, calendars, slideshows, etc.</p>
|
||||
<dd><p>returns list of street names</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py property">
|
||||
<dt class="sig sig-object py" id="osxphotos.SearchInfo.text_found">
|
||||
<em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">text_found</span></span><a class="headerlink" href="#osxphotos.SearchInfo.text_found" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Returns True if photos has detected text (macOS 13+ / Photos 8+ only)</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py property">
|
||||
<dt class="sig sig-object py" id="osxphotos.SearchInfo.venue_types">
|
||||
<em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">venue_types</span></span><a class="headerlink" href="#osxphotos.SearchInfo.venue_types" title="Permalink to this definition">#</a></dt>
|
||||
@@ -3743,8 +3779,11 @@ Projects are cards, calendars, slideshows, etc.</p>
|
||||
<li><a class="reference internal" href="#osxphotos.PersonInfo"><code class="docutils literal notranslate"><span class="pre">PersonInfo</span></code></a><ul>
|
||||
<li><a class="reference internal" href="#osxphotos.PersonInfo.asdict"><code class="docutils literal notranslate"><span class="pre">PersonInfo.asdict()</span></code></a></li>
|
||||
<li><a class="reference internal" href="#osxphotos.PersonInfo.face_info"><code class="docutils literal notranslate"><span class="pre">PersonInfo.face_info</span></code></a></li>
|
||||
<li><a class="reference internal" href="#osxphotos.PersonInfo.favorite"><code class="docutils literal notranslate"><span class="pre">PersonInfo.favorite</span></code></a></li>
|
||||
<li><a class="reference internal" href="#osxphotos.PersonInfo.feature_less"><code class="docutils literal notranslate"><span class="pre">PersonInfo.feature_less</span></code></a></li>
|
||||
<li><a class="reference internal" href="#osxphotos.PersonInfo.json"><code class="docutils literal notranslate"><span class="pre">PersonInfo.json()</span></code></a></li>
|
||||
<li><a class="reference internal" href="#osxphotos.PersonInfo.photos"><code class="docutils literal notranslate"><span class="pre">PersonInfo.photos</span></code></a></li>
|
||||
<li><a class="reference internal" href="#osxphotos.PersonInfo.sort_order"><code class="docutils literal notranslate"><span class="pre">PersonInfo.sort_order</span></code></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#osxphotos.PhotoExporter"><code class="docutils literal notranslate"><span class="pre">PhotoExporter</span></code></a><ul>
|
||||
@@ -3893,6 +3932,7 @@ Projects are cards, calendars, slideshows, etc.</p>
|
||||
<li><a class="reference internal" href="#osxphotos.PhotosDB.persons_as_dict"><code class="docutils literal notranslate"><span class="pre">PhotosDB.persons_as_dict</span></code></a></li>
|
||||
<li><a class="reference internal" href="#osxphotos.PhotosDB.photos"><code class="docutils literal notranslate"><span class="pre">PhotosDB.photos()</span></code></a></li>
|
||||
<li><a class="reference internal" href="#osxphotos.PhotosDB.photos_by_uuid"><code class="docutils literal notranslate"><span class="pre">PhotosDB.photos_by_uuid()</span></code></a></li>
|
||||
<li><a class="reference internal" href="#osxphotos.PhotosDB.photos_version"><code class="docutils literal notranslate"><span class="pre">PhotosDB.photos_version</span></code></a></li>
|
||||
<li><a class="reference internal" href="#osxphotos.PhotosDB.project_info"><code class="docutils literal notranslate"><span class="pre">PhotosDB.project_info</span></code></a></li>
|
||||
<li><a class="reference internal" href="#osxphotos.PhotosDB.query"><code class="docutils literal notranslate"><span class="pre">PhotosDB.query()</span></code></a></li>
|
||||
</ul>
|
||||
@@ -4002,9 +4042,11 @@ Projects are cards, calendars, slideshows, etc.</p>
|
||||
<li><a class="reference internal" href="#osxphotos.SearchInfo.neighborhoods"><code class="docutils literal notranslate"><span class="pre">SearchInfo.neighborhoods</span></code></a></li>
|
||||
<li><a class="reference internal" href="#osxphotos.SearchInfo.place_names"><code class="docutils literal notranslate"><span class="pre">SearchInfo.place_names</span></code></a></li>
|
||||
<li><a class="reference internal" href="#osxphotos.SearchInfo.season"><code class="docutils literal notranslate"><span class="pre">SearchInfo.season</span></code></a></li>
|
||||
<li><a class="reference internal" href="#osxphotos.SearchInfo.source"><code class="docutils literal notranslate"><span class="pre">SearchInfo.source</span></code></a></li>
|
||||
<li><a class="reference internal" href="#osxphotos.SearchInfo.state"><code class="docutils literal notranslate"><span class="pre">SearchInfo.state</span></code></a></li>
|
||||
<li><a class="reference internal" href="#osxphotos.SearchInfo.state_abbreviation"><code class="docutils literal notranslate"><span class="pre">SearchInfo.state_abbreviation</span></code></a></li>
|
||||
<li><a class="reference internal" href="#osxphotos.SearchInfo.streets"><code class="docutils literal notranslate"><span class="pre">SearchInfo.streets</span></code></a></li>
|
||||
<li><a class="reference internal" href="#osxphotos.SearchInfo.text_found"><code class="docutils literal notranslate"><span class="pre">SearchInfo.text_found</span></code></a></li>
|
||||
<li><a class="reference internal" href="#osxphotos.SearchInfo.venue_types"><code class="docutils literal notranslate"><span class="pre">SearchInfo.venue_types</span></code></a></li>
|
||||
<li><a class="reference internal" href="#osxphotos.SearchInfo.venues"><code class="docutils literal notranslate"><span class="pre">SearchInfo.venues</span></code></a></li>
|
||||
<li><a class="reference internal" href="#osxphotos.SearchInfo.year"><code class="docutils literal notranslate"><span class="pre">SearchInfo.year</span></code></a></li>
|
||||
|
||||
@@ -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.56.3 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.56.6 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.56.3 documentation</div></a>
|
||||
<a href="index.html"><div class="brand">osxphotos 0.56.6 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.56.3 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.56.6 documentation</span>
|
||||
|
||||
</a><form class="sidebar-search-container" method="get" action="#" role="search">
|
||||
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -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.56.3 documentation</title>
|
||||
<title>OSXPhotos Template System - osxphotos 0.56.6 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.56.3 documentation</div></a>
|
||||
<a href="index.html"><div class="brand">osxphotos 0.56.6 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.56.3 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.56.6 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">
|
||||
@@ -608,7 +608,7 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="row-even"><td><p>{osxphotos_version}</p></td>
|
||||
<td><p>The osxphotos version, e.g. ‘0.56.3’</p></td>
|
||||
<td><p>The osxphotos version, e.g. ‘0.56.6’</p></td>
|
||||
</tr>
|
||||
<tr class="row-odd"><td><p>{osxphotos_cmd_line}</p></td>
|
||||
<td><p>The full command line used to run osxphotos</p></td>
|
||||
|
||||
@@ -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.56.3 documentation</title>
|
||||
<title>OSXPhotos Tutorial - osxphotos 0.56.6 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.56.3 documentation</div></a>
|
||||
<a href="index.html"><div class="brand">osxphotos 0.56.6 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.56.3 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.56.6 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">
|
||||
|
||||
@@ -357,7 +357,7 @@ Template Substitutions
|
||||
* - {tab}
|
||||
- :A tab: '\t'
|
||||
* - {osxphotos_version}
|
||||
- The osxphotos version, e.g. '0.56.3'
|
||||
- The osxphotos version, e.g. '0.56.6'
|
||||
* - {osxphotos_cmd_line}
|
||||
- The full command line used to run osxphotos
|
||||
* - {album}
|
||||
|
||||
@@ -3,9 +3,15 @@
|
||||
import typing as t
|
||||
import photoscript
|
||||
import pathlib
|
||||
from osxphotos.cli.import_cli import ReportRecord
|
||||
|
||||
|
||||
def post_function(
|
||||
photo: photoscript.Photo, filepath: pathlib.Path, verbose: t.Callable, **kwargs
|
||||
photo: photoscript.Photo,
|
||||
filepath: pathlib.Path,
|
||||
verbose: t.Callable,
|
||||
report_record: ReportRecord,
|
||||
**kwargs,
|
||||
):
|
||||
"""Call this with osxphotos import /file/to/import --post-function post_function.py::post_function
|
||||
This will get called immediately after the photo has been imported into Photos
|
||||
@@ -15,6 +21,7 @@ def post_function(
|
||||
photo: photoscript.Photo instance for the photo that's just been imported
|
||||
filepath: pathlib.Path to the file that was imported (this is the path to the source file, not the path inside the Photos library)
|
||||
verbose: A function to print verbose output if --verbose is set; if --verbose is not set, acts as a no-op (nothing gets printed)
|
||||
report_record: ReportRecord instance for the photo that's just been imported; update this if you want to change the report output
|
||||
**kwargs: reserved for future use; recommend you include **kwargs so your function still works if additional arguments are added in future versions
|
||||
|
||||
Notes:
|
||||
@@ -25,4 +32,16 @@ def post_function(
|
||||
|
||||
# add a note to the photo's description
|
||||
verbose("Adding note to description")
|
||||
photo.description = f"{photo.description} (imported with osxphotos)"
|
||||
description = photo.description
|
||||
description = (
|
||||
f"{description} (imported with osxphotos)"
|
||||
if description
|
||||
else "(imported with osxphotos)"
|
||||
)
|
||||
|
||||
# update report_record if you modify the photo and want the report to reflect the change
|
||||
# the report_record object passed to the function is mutable so you can update it directly
|
||||
report_record.description = description
|
||||
|
||||
# update the photo's description via the Photo object
|
||||
photo.description = description
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""
|
||||
Constants used by osxphotos
|
||||
"""
|
||||
""" Constants used by osxphotos """
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os.path
|
||||
from datetime import datetime
|
||||
@@ -138,7 +138,9 @@ _PHOTOS_5_SHARED_PHOTO_PATH = "resources/cloudsharing/data"
|
||||
_PHOTOS_8_SHARED_PHOTO_PATH = "scopes/cloudsharing/data"
|
||||
|
||||
# Where are shared iCloud derivatives located?
|
||||
_PHOTOS_5_SHARED_DERIVATIVE_PATH = "resources/cloudsharing/resources/derivatives/masters"
|
||||
_PHOTOS_5_SHARED_DERIVATIVE_PATH = (
|
||||
"resources/cloudsharing/resources/derivatives/masters"
|
||||
)
|
||||
_PHOTOS_8_SHARED_DERIVATIVE_PATH = "scopes/cloudsharing/resources/derivatives/masters"
|
||||
|
||||
# What type of file? Based on ZGENERICASSET.ZKIND in Photos 5 database
|
||||
@@ -213,11 +215,11 @@ class SearchCategory:
|
||||
TITLE = 2017
|
||||
DESCRIPTION = 2018
|
||||
HOME = 2020
|
||||
WORK = 2036
|
||||
PERSON = 2021
|
||||
ACTIVITY = 2027
|
||||
HOLIDAY = 2029
|
||||
SEASON = 2030
|
||||
WORK = 2036
|
||||
VENUE = 2038
|
||||
VENUE_TYPE = 2039
|
||||
PHOTO_TYPE_VIDEO = 2044
|
||||
@@ -230,6 +232,7 @@ class SearchCategory:
|
||||
PHOTO_TYPE_PORTRAIT = 2053
|
||||
PHOTO_TYPE_SELFIES = 2054
|
||||
PHOTO_TYPE_FAVORITES = 2055
|
||||
PHOTO_TYPE_ANIMATED = None # Photos 8+ only
|
||||
MEDIA_TYPES = [
|
||||
PHOTO_TYPE_VIDEO,
|
||||
PHOTO_TYPE_SLOMO,
|
||||
@@ -244,7 +247,23 @@ class SearchCategory:
|
||||
]
|
||||
PHOTO_NAME = 2056
|
||||
CAMERA = None # Photos 8+ only
|
||||
TEXT_FOUND = None # Photos 8+ only
|
||||
DETECTED_TEXT = None # Photos 8+ only
|
||||
SOURCE = None # Photos 8+ only
|
||||
|
||||
@classmethod
|
||||
def categories(cls) -> dict[int, str]:
|
||||
"""Return categories as dict of value: name"""
|
||||
# a bit of a hack to basically reverse the enum
|
||||
return {
|
||||
value: name
|
||||
for name, value in cls.__dict__.items()
|
||||
if name is not None
|
||||
and not name.startswith("__")
|
||||
and not callable(name)
|
||||
and name.isupper()
|
||||
and not isinstance(value, (list, dict, tuple))
|
||||
}
|
||||
|
||||
|
||||
class SearchCategory_Photos8(SearchCategory):
|
||||
@@ -252,6 +271,20 @@ class SearchCategory_Photos8(SearchCategory):
|
||||
|
||||
# Many of the category values changed in Ventura / Photos 8
|
||||
# and some new categories were added
|
||||
CITY = 5
|
||||
LOCALITY_4 = 4
|
||||
SUB_LOCALITY_5 = None
|
||||
SUB_LOCALITY_6 = 6
|
||||
LOCALITY_8 = 8
|
||||
NAMED_AREA = 7
|
||||
ALL_LOCALITY = [
|
||||
LOCALITY_4,
|
||||
SUB_LOCALITY_6,
|
||||
LOCALITY_8,
|
||||
NAMED_AREA,
|
||||
]
|
||||
HOME = 1000
|
||||
WORK = 1001
|
||||
LABEL = 1500
|
||||
MONTH = 1100
|
||||
YEAR = 1101
|
||||
@@ -261,11 +294,55 @@ class SearchCategory_Photos8(SearchCategory):
|
||||
TITLE = 1201
|
||||
DESCRIPTION = 1202
|
||||
DETECTED_TEXT = 1203 # new in Photos 8
|
||||
TEXT_FOUND = 1205 # new in Photos 8
|
||||
PERSON = 1300
|
||||
ACTIVITY = 1600
|
||||
VENUE = 1700
|
||||
VENUE_TYPE = 1701
|
||||
PHOTO_TYPE_VIDEO = 1901
|
||||
PHOTO_TYPE_SELFIES = 1915
|
||||
PHOTO_TYPE_LIVE = 1906
|
||||
PHOTO_TYPE_PORTRAIT = 1914
|
||||
PHOTO_TYPE_FAVORITES = 2000
|
||||
PHOTO_TYPE_PANORAMA = 1908
|
||||
PHOTO_TYPE_TIMELAPSE = 1909
|
||||
PHOTO_TYPE_SLOMO = 1905
|
||||
PHOTO_TYPE_BURSTS = 1913
|
||||
PHOTO_TYPE_SCREENSHOT = 1907
|
||||
PHOTO_TYPE_ANIMATED = 1912
|
||||
PHOTO_TYPE_RAW = 1902
|
||||
MEDIA_TYPES = [
|
||||
PHOTO_TYPE_VIDEO,
|
||||
PHOTO_TYPE_SLOMO,
|
||||
PHOTO_TYPE_LIVE,
|
||||
PHOTO_TYPE_SCREENSHOT,
|
||||
PHOTO_TYPE_PANORAMA,
|
||||
PHOTO_TYPE_TIMELAPSE,
|
||||
PHOTO_TYPE_BURSTS,
|
||||
PHOTO_TYPE_PORTRAIT,
|
||||
PHOTO_TYPE_SELFIES,
|
||||
PHOTO_TYPE_FAVORITES,
|
||||
PHOTO_TYPE_ANIMATED,
|
||||
]
|
||||
PHOTO_NAME = 2100
|
||||
CAMERA = 2300 # new in Photos 8
|
||||
SOURCE = 2200 # new in Photos 8, shows the app/software source for the photo, e.g. Messages, Safari, etc.
|
||||
|
||||
@classmethod
|
||||
def categories(cls) -> dict[int, str]:
|
||||
"""Return categories as dict of value: name"""
|
||||
# need to get the categories from the base class and update with the new values
|
||||
classdict = SearchCategory.__dict__.copy()
|
||||
classdict |= cls.__dict__.copy()
|
||||
return {
|
||||
value: name
|
||||
for name, value in classdict.items()
|
||||
if name is not None
|
||||
and not name.startswith("__")
|
||||
and not callable(name)
|
||||
and name.isupper()
|
||||
and not isinstance(value, (list, dict, tuple))
|
||||
}
|
||||
|
||||
|
||||
def search_category_factory(version: int) -> SearchCategory:
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
""" version info """
|
||||
|
||||
__version__ = "0.56.3"
|
||||
__version__ = "0.56.6"
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
"""import command for osxphotos CLI to import photos into Photos"""
|
||||
|
||||
# Note: the style in this module is a bit different than much of the other osxphotos code
|
||||
# As an experiment, I've used mostly functions instead of classes (e.g. the report writer
|
||||
# functions vs ReportWriter class used by export) and I've kept everything for import
|
||||
# self-contained in this one file
|
||||
from __future__ import annotations
|
||||
|
||||
import csv
|
||||
import datetime
|
||||
@@ -59,6 +56,12 @@ from .common import THEME_OPTION
|
||||
from .rich_progress import rich_progress
|
||||
from .verbose import get_verbose_console, verbose_print
|
||||
|
||||
# Note: the style in this module is a bit different than much of the other osxphotos code
|
||||
# As an experiment, I've used mostly functions instead of classes (e.g. the report writer
|
||||
# functions vs ReportWriter class used by export) and I've kept everything for import
|
||||
# self-contained in this one file
|
||||
|
||||
|
||||
MetaData = namedtuple("MetaData", ["title", "description", "keywords", "location"])
|
||||
|
||||
OSXPHOTOS_ABOUT_STRING = f"Created by osxphotos version {__version__} (https://github.com/RhetTbull/osxphotos) on {datetime.datetime.now()}"
|
||||
@@ -165,7 +168,8 @@ def import_photo(
|
||||
Args:
|
||||
filepath: path to the file to import
|
||||
dup_check: enable or disable Photo's duplicate check on import
|
||||
verbose: Callable"""
|
||||
verbose: Callable
|
||||
"""
|
||||
if imported := PhotosLibrary().import_photos(
|
||||
[filepath], skip_duplicate_check=not dup_check
|
||||
):
|
||||
@@ -207,7 +211,7 @@ def add_photo_to_albums(
|
||||
split_folder: str,
|
||||
exiftool_path: Path,
|
||||
verbose: Callable[..., None],
|
||||
):
|
||||
) -> list[str]:
|
||||
"""Add photo to one or more albums"""
|
||||
albums = []
|
||||
for a in album:
|
||||
@@ -225,6 +229,7 @@ def add_photo_to_albums(
|
||||
a, verbose=verbose, split_folder=split_folder, rich=True
|
||||
)
|
||||
photos_album.add(photo)
|
||||
return albums
|
||||
|
||||
|
||||
def clear_photo_metadata(photo: Photo, filepath: Path, verbose: Callable[..., None]):
|
||||
@@ -348,7 +353,11 @@ def location_from_file(
|
||||
return latitude, longitude
|
||||
|
||||
|
||||
def set_photo_metadata(photo: Photo, metadata: MetaData, merge_keywords: bool):
|
||||
def set_photo_metadata(
|
||||
photo: Photo,
|
||||
metadata: MetaData,
|
||||
merge_keywords: bool,
|
||||
) -> MetaData:
|
||||
"""Set metadata (title, description, keywords) for a Photo object"""
|
||||
photo.title = metadata.title
|
||||
photo.description = metadata.description
|
||||
@@ -358,6 +367,7 @@ def set_photo_metadata(photo: Photo, metadata: MetaData, merge_keywords: bool):
|
||||
keywords.extend(old_keywords)
|
||||
keywords = list(set(keywords))
|
||||
photo.keywords = keywords
|
||||
return MetaData(metadata.title, metadata.description, keywords, metadata.location)
|
||||
|
||||
|
||||
def set_photo_metadata_from_exiftool(
|
||||
@@ -366,12 +376,12 @@ def set_photo_metadata_from_exiftool(
|
||||
exiftool_path: str,
|
||||
merge_keywords: bool,
|
||||
verbose: Callable[..., None],
|
||||
):
|
||||
) -> MetaData:
|
||||
"""Set photo's metadata by reading metadata form file with exiftool"""
|
||||
verbose(f"Setting metadata and location from EXIF for [filename]{filepath.name}[/]")
|
||||
metadata = metadata_from_file(filepath, exiftool_path)
|
||||
if any([metadata.title, metadata.description, metadata.keywords]):
|
||||
set_photo_metadata(photo, metadata, merge_keywords)
|
||||
metadata = set_photo_metadata(photo, metadata, merge_keywords)
|
||||
verbose(f"Set metadata for [filename]{filepath.name}[/]:")
|
||||
verbose(
|
||||
f"title='{metadata.title}', description='{metadata.description}', keywords={metadata.keywords}"
|
||||
@@ -387,6 +397,7 @@ def set_photo_metadata_from_exiftool(
|
||||
)
|
||||
else:
|
||||
verbose(f"No location to set for [filename]{filepath.name}[/]")
|
||||
return metadata
|
||||
|
||||
|
||||
def set_photo_title(
|
||||
@@ -396,7 +407,7 @@ def set_photo_title(
|
||||
title_template: str,
|
||||
exiftool_path: str,
|
||||
verbose: Callable[..., None],
|
||||
):
|
||||
) -> str:
|
||||
"""Set title of photo"""
|
||||
title_text = render_photo_template(
|
||||
filepath, relative_filepath, title_template, exiftool_path
|
||||
@@ -412,6 +423,9 @@ def set_photo_title(
|
||||
f"Setting title of photo [filename]{filepath.name}[/] to '{title_text[0]}'"
|
||||
)
|
||||
photo.title = title_text[0]
|
||||
return title_text[0]
|
||||
else:
|
||||
return ""
|
||||
|
||||
|
||||
def set_photo_description(
|
||||
@@ -421,7 +435,7 @@ def set_photo_description(
|
||||
description_template: str,
|
||||
exiftool_path: str,
|
||||
verbose: Callable[..., None],
|
||||
):
|
||||
) -> str:
|
||||
"""Set description of photo"""
|
||||
description_text = render_photo_template(
|
||||
filepath, relative_filepath, description_template, exiftool_path
|
||||
@@ -437,6 +451,9 @@ def set_photo_description(
|
||||
f"Setting description of photo [filename]{filepath.name}[/] to '{description_text[0]}'"
|
||||
)
|
||||
photo.description = description_text[0]
|
||||
return description_text[0]
|
||||
else:
|
||||
return ""
|
||||
|
||||
|
||||
def set_photo_keywords(
|
||||
@@ -447,7 +464,7 @@ def set_photo_keywords(
|
||||
exiftool_path: str,
|
||||
merge: bool,
|
||||
verbose: Callable[..., None],
|
||||
):
|
||||
) -> list[str]:
|
||||
"""Set keywords of photo"""
|
||||
keywords = []
|
||||
for keyword in keyword_template:
|
||||
@@ -460,6 +477,7 @@ def set_photo_keywords(
|
||||
keywords = list(set(keywords))
|
||||
verbose(f"Setting keywords of photo [filename]{filepath.name}[/] to {keywords}")
|
||||
photo.keywords = keywords
|
||||
return keywords
|
||||
|
||||
|
||||
def set_photo_location(
|
||||
@@ -467,17 +485,18 @@ def set_photo_location(
|
||||
filepath: Path,
|
||||
location: Tuple[float, float],
|
||||
verbose: Callable[..., None],
|
||||
):
|
||||
) -> tuple[float, float]:
|
||||
"""Set location of photo"""
|
||||
verbose(
|
||||
f"Setting location of photo [filename]{filepath.name}[/] to {location[0]}, {location[1]}"
|
||||
)
|
||||
photo.location = location
|
||||
return location
|
||||
|
||||
|
||||
def set_photo_date_from_filename(
|
||||
photo: Photo, filepath: Path, parse_date: str, verbose: Callable[..., None]
|
||||
):
|
||||
) -> datetime.datetime | None:
|
||||
"""Set date of photo from filename"""
|
||||
# TODO: handle timezone (use code from timewarp), for now convert timezone to local timezone
|
||||
try:
|
||||
@@ -495,11 +514,12 @@ def set_photo_date_from_filename(
|
||||
verbose(
|
||||
f"[warning]Could not parse date from filename [filename]{filepath.name}[/][/]"
|
||||
)
|
||||
return
|
||||
return None
|
||||
verbose(
|
||||
f"Setting date of photo [filename]{filepath.name}[/] to [time]{date.strftime('%Y-%m-%d %H:%M:%S')}[/]"
|
||||
)
|
||||
photo.date = date
|
||||
return date
|
||||
|
||||
|
||||
def get_relative_filepath(filepath: Path, relative_to: Optional[str]) -> Path:
|
||||
@@ -592,6 +612,8 @@ def check_templates_and_exit(
|
||||
|
||||
@dataclass
|
||||
class ReportRecord:
|
||||
"""Dataclass that records metadata on each file imported for writing to report"""
|
||||
|
||||
albums: List[str] = field(default_factory=list)
|
||||
description: str = ""
|
||||
error: bool = False
|
||||
@@ -619,6 +641,13 @@ class ReportRecord:
|
||||
)
|
||||
return cls(**dict_data)
|
||||
|
||||
def update_from_metadata(self, metadata: MetaData):
|
||||
"""Update a ReportRecord with data from a MetaData"""
|
||||
self.title = metadata.title
|
||||
self.description = metadata.description
|
||||
self.keywords = metadata.keywords
|
||||
self.location = metadata.location
|
||||
|
||||
def asdict(self):
|
||||
return asdict(self)
|
||||
|
||||
@@ -632,15 +661,15 @@ class ReportRecord:
|
||||
|
||||
def update_report_record(report_record: ReportRecord, photo: Photo, filepath: Path):
|
||||
"""Update a ReportRecord with data from a Photo"""
|
||||
report_record.albums = [a.title for a in photo.albums]
|
||||
report_record.description = photo.description
|
||||
|
||||
# do not update albums as they are added to the report record as they are imported (#934)
|
||||
report_record.filename = filepath.name
|
||||
report_record.filepath = filepath
|
||||
report_record.imported = True
|
||||
report_record.uuid = photo.uuid
|
||||
report_record.title = photo.title
|
||||
report_record.description = photo.description
|
||||
report_record.keywords = photo.keywords
|
||||
report_record.location = photo.location
|
||||
report_record.title = photo.title
|
||||
report_record.uuid = photo.uuid
|
||||
|
||||
return report_record
|
||||
|
||||
@@ -1477,11 +1506,13 @@ def import_cli(
|
||||
report_data[filepath] = ReportRecord(
|
||||
filepath=filepath, filename=filepath.name
|
||||
)
|
||||
report_record = report_data[filepath]
|
||||
photo, error = import_photo(filepath, dup_check, verbose)
|
||||
if error:
|
||||
error_count += 1
|
||||
report_data[filepath].error = True
|
||||
report_record.error = True
|
||||
continue
|
||||
report_record.imported = True
|
||||
imported_count += 1
|
||||
|
||||
if clear_metadata:
|
||||
@@ -1492,12 +1523,21 @@ def import_cli(
|
||||
|
||||
if exiftool:
|
||||
set_photo_metadata_from_exiftool(
|
||||
photo, filepath, exiftool_path, merge_keywords, verbose
|
||||
photo,
|
||||
filepath,
|
||||
exiftool_path,
|
||||
merge_keywords,
|
||||
verbose,
|
||||
)
|
||||
|
||||
if title:
|
||||
set_photo_title(
|
||||
photo, filepath, relative_filepath, title, exiftool_path, verbose
|
||||
photo,
|
||||
filepath,
|
||||
relative_filepath,
|
||||
title,
|
||||
exiftool_path,
|
||||
verbose,
|
||||
)
|
||||
|
||||
if description:
|
||||
@@ -1526,9 +1566,10 @@ def import_cli(
|
||||
|
||||
if parse_date:
|
||||
set_photo_date_from_filename(photo, filepath, parse_date, verbose)
|
||||
# TODO: ReportRecord doesn't currently record date
|
||||
|
||||
if album:
|
||||
add_photo_to_albums(
|
||||
report_record.albums = add_photo_to_albums(
|
||||
photo,
|
||||
filepath,
|
||||
relative_filepath,
|
||||
@@ -1543,14 +1584,15 @@ def import_cli(
|
||||
# post function is tuple of (function, filename.py::function_name)
|
||||
verbose(f"Calling post-function [bold]{function[1]}")
|
||||
try:
|
||||
function[0](photo, filepath, verbose)
|
||||
function[0](photo, filepath, verbose, report_record)
|
||||
except Exception as e:
|
||||
rich_echo_error(
|
||||
f"[error]Error running post-function [italic]{function[1]}[/italic]: {e}"
|
||||
)
|
||||
|
||||
update_report_record(report_data[filepath], photo, filepath)
|
||||
import_db.set(str(filepath), report_data[filepath])
|
||||
# update report data
|
||||
update_report_record(report_record, photo, filepath)
|
||||
import_db.set(str(filepath), report_record)
|
||||
|
||||
progress.advance(task)
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ from rich.live import Live
|
||||
from rich.panel import Panel
|
||||
|
||||
from osxphotos import PhotoInfo, PhotosDB
|
||||
from osxphotos._constants import _UNKNOWN_PERSON
|
||||
from osxphotos._constants import _UNKNOWN_PERSON, search_category_factory
|
||||
from osxphotos.rich_utils import add_rich_markup_tag
|
||||
from osxphotos.text_detection import detect_text as detect_text_in_photo
|
||||
from osxphotos.utils import dd_to_dms_str
|
||||
@@ -65,6 +65,22 @@ def trim(text: str, pad: str = "") -> str:
|
||||
return text if len(text) <= width else f"{text[: width- 3]}..."
|
||||
|
||||
|
||||
def format_search_info(photo: PhotoInfo) -> str:
|
||||
"""Format search info for photo"""
|
||||
categories = sorted(list(photo._db._db_searchinfo_categories.keys()))
|
||||
search_info = photo.search_info
|
||||
if not search_info:
|
||||
return ""
|
||||
search_info_strs = []
|
||||
category_dict = search_category_factory(photo._db.photos_version).categories()
|
||||
for category in categories:
|
||||
if text := search_info._get_text_for_category(category):
|
||||
text = ", ".join(t for t in text if t) if isinstance(text, list) else text
|
||||
category_name = str(category_dict.get(category, category)).lower()
|
||||
search_info_strs.append(f"{bold(category_name)}: {text}")
|
||||
return ", ".join(search_info_strs)
|
||||
|
||||
|
||||
def inspect_photo(
|
||||
photo: PhotoInfo,
|
||||
detected_text: Optional[str] = None,
|
||||
@@ -138,8 +154,10 @@ def inspect_photo(
|
||||
+ f"{', '.join(dd_to_dms_str(*photo.location)) if photo.location[0] else '-'}",
|
||||
bold("Place: ") + f"{photo.place.name if photo.place else '-'}",
|
||||
bold("Categories/Labels: ") + f"{', '.join(photo.labels) or '-'}",
|
||||
bold("Search Info: ") + format_search_info(photo),
|
||||
]
|
||||
)
|
||||
|
||||
properties.append(format_flags(photo))
|
||||
properties.append(format_albums(photo))
|
||||
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
""" Fix time / date / timezone for photos in Apple Photos """
|
||||
|
||||
import datetime
|
||||
import os
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from functools import partial
|
||||
from textwrap import dedent
|
||||
from typing import Callable, Optional
|
||||
|
||||
import click
|
||||
from photoscript import Photo, PhotosLibrary
|
||||
from photoscript import PhotosLibrary
|
||||
from rich.console import Console
|
||||
|
||||
from osxphotos._constants import APP_NAME
|
||||
@@ -16,10 +15,14 @@ from osxphotos.compare_exif import PhotoCompare
|
||||
from osxphotos.datetime_utils import datetime_naive_to_local, datetime_to_new_tz
|
||||
from osxphotos.exif_datetime_updater import ExifDateTimeUpdater
|
||||
from osxphotos.exiftool import get_exiftool_path
|
||||
from osxphotos.photodates import (
|
||||
set_photo_date_from_filename,
|
||||
update_photo_date_time,
|
||||
update_photo_from_function,
|
||||
update_photo_time_for_new_timezone,
|
||||
)
|
||||
from osxphotos.photosalbum import PhotosAlbumPhotoScript
|
||||
from osxphotos.phototz import PhotoTimeZone, PhotoTimeZoneUpdater
|
||||
from osxphotos.timeutils import update_datetime
|
||||
from osxphotos.timezones import Timezone
|
||||
from osxphotos.utils import noop, pluralize
|
||||
|
||||
from .click_rich_echo import (
|
||||
@@ -38,6 +41,7 @@ from .param_types import (
|
||||
DateOffset,
|
||||
DateTimeISO8601,
|
||||
FunctionCall,
|
||||
StrpDateTimePattern,
|
||||
TimeOffset,
|
||||
TimeString,
|
||||
UTCOffset,
|
||||
@@ -49,110 +53,6 @@ from .verbose import get_verbose_console, verbose_print
|
||||
DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S%z"
|
||||
|
||||
|
||||
def update_photo_date_time(
|
||||
photo: Photo,
|
||||
date,
|
||||
time,
|
||||
date_delta,
|
||||
time_delta,
|
||||
verbose_print: Callable,
|
||||
):
|
||||
"""Update date, time in photo"""
|
||||
photo_date = photo.date
|
||||
new_photo_date = update_datetime(
|
||||
photo_date, date=date, time=time, date_delta=date_delta, time_delta=time_delta
|
||||
)
|
||||
filename = photo.filename
|
||||
uuid = photo.uuid
|
||||
if new_photo_date != photo_date:
|
||||
photo.date = new_photo_date
|
||||
verbose_print(
|
||||
f"Updated date/time for photo [filename]{filename}[/filename] "
|
||||
f"([uuid]{uuid}[/uuid]) from: [time]{photo_date}[/time] to [time]{new_photo_date}[/time]"
|
||||
)
|
||||
else:
|
||||
verbose_print(
|
||||
f"Skipped date/time update for photo [filename]{filename}[/filename] "
|
||||
f"([uuid]{uuid}[/uuid]): nothing to do"
|
||||
)
|
||||
|
||||
|
||||
def update_photo_time_for_new_timezone(
|
||||
library_path: str,
|
||||
photo: Photo,
|
||||
new_timezone: Timezone,
|
||||
verbose_print: Callable,
|
||||
):
|
||||
"""Update time in photo to keep it the same time but in a new timezone
|
||||
|
||||
For example, photo time is 12:00+0100 and new timezone is +0200,
|
||||
so adjust photo time by 1 hour so it will now be 12:00+0200 instead of
|
||||
13:00+0200 as it would be with no adjustment to the time"""
|
||||
old_timezone = PhotoTimeZone(library_path=library_path).get_timezone(photo)[0]
|
||||
# need to move time in opposite direction of timezone offset so that
|
||||
# photo time is the same time but in the new timezone
|
||||
delta = old_timezone - new_timezone.offset
|
||||
photo_date = photo.date
|
||||
new_photo_date = update_datetime(
|
||||
dt=photo_date, time_delta=datetime.timedelta(seconds=delta)
|
||||
)
|
||||
filename = photo.filename
|
||||
uuid = photo.uuid
|
||||
if photo_date != new_photo_date:
|
||||
photo.date = new_photo_date
|
||||
verbose_print(
|
||||
f"Adjusted date/time for photo [filename]{filename}[/filename] ([uuid]{uuid}[/uuid]) to match "
|
||||
f"previous time [time]{photo_date}[time] but in new timezone [tz]{new_timezone}[/tz]."
|
||||
)
|
||||
else:
|
||||
verbose_print(
|
||||
f"Skipping date/time update for photo [filename]{filename}[/filename] ([uuid]{photo.uuid}[/uuid]), "
|
||||
f"already matches new timezone [tz]{new_timezone}[/tz]"
|
||||
)
|
||||
|
||||
|
||||
def update_photo_from_function(
|
||||
library_path: str,
|
||||
function: Callable,
|
||||
verbose_print: Callable,
|
||||
photo: Photo,
|
||||
path: Optional[str],
|
||||
):
|
||||
"""Update photo from function call"""
|
||||
photo_tz_sec, _, photo_tz_name = PhotoTimeZone(
|
||||
library_path=library_path
|
||||
).get_timezone(photo)
|
||||
dt_new, tz_new = function(
|
||||
photo=photo,
|
||||
path=path,
|
||||
tz_sec=photo_tz_sec,
|
||||
tz_name=photo_tz_name,
|
||||
verbose=verbose_print,
|
||||
)
|
||||
if dt_new != photo.date:
|
||||
old_date = photo.date
|
||||
photo.date = dt_new
|
||||
verbose_print(
|
||||
f"Updated date/time for photo [filename]{photo.filename}[/filename] "
|
||||
f"([uuid]{photo.uuid}[/uuid]) from: [time]{old_date}[/time] to [time]{dt_new}[/time]"
|
||||
)
|
||||
else:
|
||||
verbose_print(
|
||||
f"Skipped date/time update for photo [filename]{photo.filename}[/filename] "
|
||||
f"([uuid]{photo.uuid}[/uuid]): nothing to do"
|
||||
)
|
||||
if tz_new != photo_tz_sec:
|
||||
tz_updater = PhotoTimeZoneUpdater(
|
||||
timezone=Timezone(tz_new), verbose=verbose_print, library_path=library_path
|
||||
)
|
||||
tz_updater.update_photo(photo)
|
||||
else:
|
||||
verbose_print(
|
||||
f"Skipped timezone update for photo [filename]{photo.filename}[/filename] "
|
||||
f"([uuid]{photo.uuid}[/uuid]): nothing to do"
|
||||
)
|
||||
|
||||
|
||||
class TimeWarpCommand(click.Command):
|
||||
"""Custom click.Command that overrides get_help() to show additional help info for export"""
|
||||
|
||||
@@ -223,6 +123,40 @@ if the EXIF data is missing, use the file modification date/time; show verbose o
|
||||
|
||||
`osxphotos timewarp --pull-exif --use-file-time --verbose`
|
||||
|
||||
## Parsing Dates/Times from Filenames
|
||||
|
||||
The --parse-date option allows you to parse dates/times from the original filename of the photo.
|
||||
This is useful if you files with dates/times embedded in the filename but not in the metadata.
|
||||
|
||||
|
||||
The argument to `--parse-date` is a pattern string that is used to parse the date/time
|
||||
from the filename. The pattern string is a superset of the python `strftime/strptime`
|
||||
format with the following additions:
|
||||
|
||||
- *: Match any number of characters
|
||||
- ^: Match the beginning of the string
|
||||
- $: Match the end of the string
|
||||
- {n}: Match exactly n characters
|
||||
- {n,}: Match at least n characters
|
||||
- {n,m}: Match at least n characters and at most m characters
|
||||
- In addition to `%%` for a literal `%`, the following format codes are supported:
|
||||
`%^`, `%$`, `%*`, `%|`, `%{`, `%}` for `^`, `$`, `*`, `|`, `{`, `}` respectively
|
||||
- |: join multiple format codes; each code is tried in order until one matches
|
||||
- Unlike the standard library, the leading zero is not optional for
|
||||
%d, %m, %H, %I, %M, %S, %j, %U, %W, and %V
|
||||
- For optional leading zero, use %-d, %-m, %-H, %-I, %-M, %-S, %-j, %-U, %-W, and %-V
|
||||
|
||||
For more information on strptime format codes, see:
|
||||
https://docs.python.org/3/library/datetime.html?highlight=strptime#strftime-and-strptime-format-codes
|
||||
|
||||
**Note**: The time zone of the parsed date/time is assumed to be the local time zone.
|
||||
If the parse pattern includes a time zone, the photo's time will be converted from
|
||||
the specified time zone to the local time zone. osxphotos import does not
|
||||
currently support setting the time zone of imported photos.
|
||||
See also `osxphotos help timewarp` for more information on the timewarp
|
||||
command which can be used to change the time zone of photos after import.
|
||||
|
||||
|
||||
"""
|
||||
),
|
||||
width=formatter.width,
|
||||
@@ -322,6 +256,19 @@ if the EXIF data is missing, use the file modification date/time; show verbose o
|
||||
"Requires the third-party exiftool utility be installed (see https://exiftool.org/). "
|
||||
"See also --push-exif.",
|
||||
)
|
||||
@click.option(
|
||||
"--parse-date",
|
||||
"-M",
|
||||
metavar="DATE_PATTERN",
|
||||
type=StrpDateTimePattern(),
|
||||
help="Parse date from filename using DATE_PATTERN and set photo's date to match. "
|
||||
"If file does not match DATE_PATTERN, the date will not be changed. "
|
||||
"DATE_PATTERN is a strptime-compatible pattern with extensions as pattern described below. "
|
||||
"If DATE_PATTERN matches time zone information, the photo's timezone will be set to match. "
|
||||
"For example, if your photos are named 'IMG_1234_2022_11_23_12_34_56.jpg' where the date/time is "
|
||||
"'2022-11-23 12:34:56', you could use the pattern '%Y_%m_%d_%H_%M_%S' or "
|
||||
"'IMG_*_%Y_%m_%d_%H_%M_%S' to further narrow the pattern to only match files with 'IMG_xxxx_' in the name.",
|
||||
)
|
||||
@click.option(
|
||||
"--function",
|
||||
"-F",
|
||||
@@ -363,7 +310,7 @@ if the EXIF data is missing, use the file modification date/time; show verbose o
|
||||
help="When used with --compare-exif, adds any photos with date/time/timezone differences "
|
||||
"between Photos/EXIF to album ALBUM. If ALBUM does not exist, it will be created.",
|
||||
)
|
||||
@click.option("--verbose", "-V", "verbose", is_flag=True, help="Show verbose output.")
|
||||
@click.option("--verbose", "-V", "verbose_", is_flag=True, help="Show verbose output.")
|
||||
@click.option(
|
||||
"--library",
|
||||
"-L",
|
||||
@@ -419,9 +366,10 @@ def timewarp(
|
||||
use_file_time,
|
||||
add_to_album,
|
||||
exiftool_path,
|
||||
verbose,
|
||||
verbose_,
|
||||
library,
|
||||
theme,
|
||||
parse_date,
|
||||
plain,
|
||||
output_file,
|
||||
terminal_width,
|
||||
@@ -446,6 +394,7 @@ def timewarp(
|
||||
timezone,
|
||||
inspect,
|
||||
compare_exif,
|
||||
parse_date,
|
||||
push_exif,
|
||||
pull_exif,
|
||||
function,
|
||||
@@ -453,7 +402,8 @@ def timewarp(
|
||||
):
|
||||
raise click.UsageError(
|
||||
"At least one of --date, --date-delta, --time, --time-delta, "
|
||||
"--timezone, --inspect, --compare-exif, --push-exif, --pull-exif, --function "
|
||||
"--timezone, --inspect, --compare-exif, --push-exif, --pull-exif, "
|
||||
"--parse-date, --function "
|
||||
"must be specified."
|
||||
)
|
||||
|
||||
@@ -472,8 +422,8 @@ def timewarp(
|
||||
# configure colored rich output
|
||||
# TODO: this is all a little hacky, find a better way to do this
|
||||
color_theme = get_theme(theme)
|
||||
verbose_ = verbose_print(
|
||||
verbose,
|
||||
verbose = verbose_print(
|
||||
verbose_,
|
||||
timestamp,
|
||||
rich=True,
|
||||
theme=color_theme,
|
||||
@@ -499,7 +449,7 @@ def timewarp(
|
||||
|
||||
if any([compare_exif, push_exif, pull_exif]):
|
||||
exiftool_path = exiftool_path or get_exiftool_path()
|
||||
verbose_(f"exiftool path: [filename]{exiftool_path}[/filename]")
|
||||
verbose(f"exiftool path: [filename]{exiftool_path}[/filename]")
|
||||
|
||||
try:
|
||||
photos = PhotosLibrary().selection
|
||||
@@ -533,6 +483,7 @@ def timewarp(
|
||||
push_exif,
|
||||
pull_exif,
|
||||
function,
|
||||
parse_date,
|
||||
]
|
||||
)
|
||||
and not force
|
||||
@@ -556,13 +507,19 @@ def timewarp(
|
||||
time=time,
|
||||
date_delta=date_delta,
|
||||
time_delta=time_delta,
|
||||
verbose_print=verbose_,
|
||||
verbose=verbose,
|
||||
)
|
||||
|
||||
update_photo_time_for_new_timezone_ = partial(
|
||||
update_photo_time_for_new_timezone,
|
||||
library_path=library,
|
||||
verbose_print=verbose_,
|
||||
verbose=verbose,
|
||||
)
|
||||
|
||||
set_photo_date_from_filename_ = partial(
|
||||
set_photo_date_from_filename,
|
||||
library_path=library,
|
||||
verbose=verbose,
|
||||
)
|
||||
|
||||
if function:
|
||||
@@ -570,7 +527,7 @@ def timewarp(
|
||||
update_photo_from_function,
|
||||
library_path=library,
|
||||
function=function[0],
|
||||
verbose_print=verbose_,
|
||||
verbose=verbose,
|
||||
)
|
||||
else:
|
||||
update_photo_from_function_ = noop
|
||||
@@ -579,14 +536,20 @@ def timewarp(
|
||||
tzinfo = PhotoTimeZone(library_path=library)
|
||||
if photos:
|
||||
rich_echo(
|
||||
"[filename]filename[/filename], [uuid]uuid[/uuid], [time]photo time (local)[/time], [time]photo time[/time], [tz]timezone offset[/tz], [tz]timezone name[/tz]"
|
||||
"[filename]filename[/filename], [uuid]uuid[/uuid], "
|
||||
"[time]photo time (local)[/time], "
|
||||
"[time]photo time[/time], "
|
||||
"[tz]timezone offset[/tz], [tz]timezone name[/tz]"
|
||||
)
|
||||
for photo in photos:
|
||||
tz_seconds, tz_str, tz_name = tzinfo.get_timezone(photo)
|
||||
photo_date_local = datetime_naive_to_local(photo.date)
|
||||
photo_date_tz = datetime_to_new_tz(photo_date_local, tz_seconds)
|
||||
rich_echo(
|
||||
f"[filename]{photo.filename}[/filename], [uuid]{photo.uuid}[/uuid], [time]{photo_date_local.strftime(DATETIME_FORMAT)}[/time], [time]{photo_date_tz.strftime(DATETIME_FORMAT)}[/time], [tz]{tz_str}[/tz], [tz]{tz_name}[/tz]"
|
||||
f"[filename]{photo.filename}[/filename], [uuid]{photo.uuid}[/uuid], "
|
||||
f"[time]{photo_date_local.strftime(DATETIME_FORMAT)}[/time], "
|
||||
f"[time]{photo_date_tz.strftime(DATETIME_FORMAT)}[/time], "
|
||||
f"[tz]{tz_str}[/tz], [tz]{tz_name}[/tz]"
|
||||
)
|
||||
sys.exit(0)
|
||||
|
||||
@@ -596,7 +559,7 @@ def timewarp(
|
||||
if photos:
|
||||
photocomp = PhotoCompare(
|
||||
library_path=library,
|
||||
verbose=verbose_,
|
||||
verbose=verbose,
|
||||
exiftool_path=exiftool_path,
|
||||
)
|
||||
if not album:
|
||||
@@ -622,12 +585,12 @@ def timewarp(
|
||||
if album:
|
||||
if diff_results.diff:
|
||||
different_photos += 1
|
||||
verbose_(
|
||||
verbose(
|
||||
f"Photo {filename} ({uuid}) has different date/time/timezone, adding to album '{album.name}'"
|
||||
)
|
||||
album.add(photo)
|
||||
else:
|
||||
verbose_(f"Photo {filename} ({uuid}) has same date/time/timezone")
|
||||
verbose(f"Photo {filename} ({uuid}) has same date/time/timezone")
|
||||
else:
|
||||
rich_echo(
|
||||
f"{filename}, {uuid}, "
|
||||
@@ -644,14 +607,14 @@ def timewarp(
|
||||
|
||||
if timezone:
|
||||
tz_updater = PhotoTimeZoneUpdater(
|
||||
timezone, verbose=verbose_, library_path=library
|
||||
timezone, verbose=verbose, library_path=library
|
||||
)
|
||||
|
||||
if any([push_exif, pull_exif, function]):
|
||||
# ExifDateTimeUpdater used to get photo path for --function
|
||||
exif_updater = ExifDateTimeUpdater(
|
||||
library_path=library,
|
||||
verbose=verbose_,
|
||||
verbose=verbose,
|
||||
exiftool_path=exiftool_path,
|
||||
plain=plain,
|
||||
)
|
||||
@@ -663,6 +626,8 @@ def timewarp(
|
||||
total=num_photos,
|
||||
)
|
||||
for p in photos:
|
||||
if parse_date:
|
||||
set_photo_date_from_filename_(p, p.filename, parse_date)
|
||||
if pull_exif:
|
||||
exif_updater.update_photos_from_exif(
|
||||
p, use_file_modify_date=use_file_time
|
||||
@@ -676,7 +641,7 @@ def timewarp(
|
||||
if timezone:
|
||||
tz_updater.update_photo(p)
|
||||
if function:
|
||||
verbose_(f"Calling function [bold]{function[1]}")
|
||||
verbose(f"Calling function [bold]{function[1]}")
|
||||
photo_path = exif_updater.get_photo_path(p)
|
||||
update_photo_from_function_(photo=p, path=photo_path)
|
||||
if push_exif:
|
||||
|
||||
Binary file not shown.
@@ -3,8 +3,10 @@
|
||||
import json
|
||||
import logging
|
||||
import math
|
||||
|
||||
from collections import namedtuple
|
||||
from functools import cached_property
|
||||
|
||||
import osxphotos
|
||||
|
||||
__all__ = ["PersonInfo", "FaceInfo", "rotate_image_point"]
|
||||
|
||||
@@ -15,7 +17,7 @@ MPRI_Reg_Rect = namedtuple("MPRI_Reg_Rect", ["x", "y", "h", "w"])
|
||||
class PersonInfo:
|
||||
"""Info about a person in the Photos library"""
|
||||
|
||||
def __init__(self, db=None, pk=None):
|
||||
def __init__(self, db: "osxphotos.PhotosDB", pk: int):
|
||||
"""Creates a new PersonInfo instance
|
||||
|
||||
Arguments:
|
||||
@@ -25,8 +27,8 @@ class PersonInfo:
|
||||
Returns:
|
||||
PersonInfo instance
|
||||
"""
|
||||
self._db = db
|
||||
self._pk = pk
|
||||
self._db: "osxphotos.PhotosDB" = db
|
||||
self._pk: int = pk
|
||||
|
||||
person = self._db._dbpersons_pk[pk]
|
||||
self.uuid = person["uuid"]
|
||||
@@ -72,6 +74,33 @@ class PersonInfo:
|
||||
# no faces
|
||||
return []
|
||||
|
||||
@property
|
||||
def favorite(self):
|
||||
"""Returns True if person is a favorite, False otherwise; Photos 5+ only; returns False on Photos <= 4"""
|
||||
return self._db._dbpersons_pk[self._pk]["type"] == 1
|
||||
|
||||
@property
|
||||
def sort_order(self):
|
||||
"""Returns sort order of person; favorite persons are sorted before non-favorite persons"; Photos 5+ only; returns 0 on Photos <= 4"""
|
||||
return self._db._dbpersons_pk[self._pk]["manualorder"]
|
||||
|
||||
@cached_property
|
||||
def feature_less(self):
|
||||
"""Returns True if person has been marked as "Feature This Person Less" in Photos, False otherwise; Photos 8+ only; returns False on Photos <= 7"""
|
||||
if self._db.photos_version < 8:
|
||||
return False
|
||||
|
||||
if results := self._db.execute(
|
||||
"""
|
||||
SELECT ZTYPE
|
||||
FROM ZUSERFEEDBACK
|
||||
WHERE ZPERSON = ?
|
||||
""",
|
||||
(self._pk,),
|
||||
).fetchone():
|
||||
return bool(results[0])
|
||||
return False
|
||||
|
||||
def asdict(self):
|
||||
"""Returns dictionary representation of class instance"""
|
||||
keyphoto = self.keyphoto.uuid if self.keyphoto is not None else None
|
||||
@@ -82,6 +111,9 @@ class PersonInfo:
|
||||
"keyface": self.keyface,
|
||||
"facecount": self.facecount,
|
||||
"keyphoto": keyphoto,
|
||||
"favorite": self.favorite,
|
||||
"sort_order": self.sort_order,
|
||||
"feature_less": self.feature_less,
|
||||
}
|
||||
|
||||
def json(self):
|
||||
|
||||
181
osxphotos/photodates.py
Normal file
181
osxphotos/photodates.py
Normal file
@@ -0,0 +1,181 @@
|
||||
"""Utilities for working with Photo dates in Apple Photos; used by osxphotos timewarp command"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
import pathlib
|
||||
from typing import Callable
|
||||
|
||||
import photoscript
|
||||
from strpdatetime import strpdatetime
|
||||
|
||||
from .datetime_utils import (
|
||||
datetime_has_tz,
|
||||
datetime_remove_tz,
|
||||
datetime_tz_to_utc,
|
||||
datetime_utc_to_local,
|
||||
utc_offset_seconds,
|
||||
)
|
||||
from .phototz import PhotoTimeZone, PhotoTimeZoneUpdater
|
||||
from .timeutils import update_datetime
|
||||
from .timezones import Timezone
|
||||
|
||||
|
||||
def update_photo_date_time(
|
||||
photo: photoscript.Photo,
|
||||
date,
|
||||
time,
|
||||
date_delta,
|
||||
time_delta,
|
||||
verbose: Callable,
|
||||
):
|
||||
"""Update date, time in photo"""
|
||||
photo_date = photo.date
|
||||
new_photo_date = update_datetime(
|
||||
photo_date, date=date, time=time, date_delta=date_delta, time_delta=time_delta
|
||||
)
|
||||
filename = photo.filename
|
||||
uuid = photo.uuid
|
||||
if new_photo_date != photo_date:
|
||||
photo.date = new_photo_date
|
||||
verbose(
|
||||
f"Updated date/time for photo [filename]{filename}[/filename] "
|
||||
f"([uuid]{uuid}[/uuid]) from: [time]{photo_date}[/time] to [time]{new_photo_date}[/time]"
|
||||
)
|
||||
else:
|
||||
verbose(
|
||||
f"Skipped date/time update for photo [filename]{filename}[/filename] "
|
||||
f"([uuid]{uuid}[/uuid]): nothing to do"
|
||||
)
|
||||
|
||||
|
||||
def update_photo_from_function(
|
||||
library_path: str,
|
||||
function: Callable,
|
||||
verbose: Callable[..., None],
|
||||
photo: photoscript.Photo,
|
||||
path: str | None,
|
||||
):
|
||||
"""Update photo from function call"""
|
||||
photo_tz_sec, _, photo_tz_name = PhotoTimeZone(
|
||||
library_path=library_path
|
||||
).get_timezone(photo)
|
||||
dt_new, tz_new = function(
|
||||
photo=photo,
|
||||
path=path,
|
||||
tz_sec=photo_tz_sec,
|
||||
tz_name=photo_tz_name,
|
||||
verbose=verbose,
|
||||
)
|
||||
if dt_new != photo.date:
|
||||
old_date = photo.date
|
||||
photo.date = dt_new
|
||||
verbose(
|
||||
f"Updated date/time for photo [filename]{photo.filename}[/filename] "
|
||||
f"([uuid]{photo.uuid}[/uuid]) from: [time]{old_date}[/time] to [time]{dt_new}[/time]"
|
||||
)
|
||||
else:
|
||||
verbose(
|
||||
f"Skipped date/time update for photo [filename]{photo.filename}[/filename] "
|
||||
f"([uuid]{photo.uuid}[/uuid]): nothing to do"
|
||||
)
|
||||
if tz_new != photo_tz_sec:
|
||||
tz_updater = PhotoTimeZoneUpdater(
|
||||
timezone=Timezone(tz_new), verbose=verbose, library_path=library_path
|
||||
)
|
||||
tz_updater.update_photo(photo)
|
||||
else:
|
||||
verbose(
|
||||
f"Skipped timezone update for photo [filename]{photo.filename}[/filename] "
|
||||
f"([uuid]{photo.uuid}[/uuid]): nothing to do"
|
||||
)
|
||||
|
||||
|
||||
def update_photo_time_for_new_timezone(
|
||||
library_path: str,
|
||||
photo: photoscript.Photo,
|
||||
new_timezone: Timezone,
|
||||
verbose: Callable[..., None],
|
||||
):
|
||||
"""Update time in photo to keep it the same time but in a new timezone
|
||||
|
||||
For example, photo time is 12:00+0100 and new timezone is +0200,
|
||||
so adjust photo time by 1 hour so it will now be 12:00+0200 instead of
|
||||
13:00+0200 as it would be with no adjustment to the time"""
|
||||
old_timezone = PhotoTimeZone(library_path=library_path).get_timezone(photo)[0]
|
||||
# need to move time in opposite direction of timezone offset so that
|
||||
# photo time is the same time but in the new timezone
|
||||
delta = old_timezone - new_timezone.offset
|
||||
photo_date = photo.date
|
||||
new_photo_date = update_datetime(
|
||||
dt=photo_date, time_delta=datetime.timedelta(seconds=delta)
|
||||
)
|
||||
filename = photo.filename
|
||||
uuid = photo.uuid
|
||||
if photo_date != new_photo_date:
|
||||
photo.date = new_photo_date
|
||||
verbose(
|
||||
f"Adjusted date/time for photo [filename]{filename}[/] ([uuid]{uuid}[/]) to [time]{new_photo_date}[/] "
|
||||
f"to match previous time [time]{photo_date}[/] but in new timezone [tz]{new_timezone}[/]."
|
||||
)
|
||||
else:
|
||||
verbose(
|
||||
f"Skipping date/time update for photo [filename]{filename}[/] ([uuid]{photo.uuid}[/]), "
|
||||
f"already matches new timezone [tz]{new_timezone}[/]"
|
||||
)
|
||||
|
||||
|
||||
def set_photo_date_from_filename(
|
||||
photo: photoscript.Photo,
|
||||
filepath: pathlib.Path | str,
|
||||
parse_date: str,
|
||||
verbose: Callable[..., None],
|
||||
library_path: str | None = None,
|
||||
) -> datetime.datetime | None:
|
||||
"""Set date of photo from filename
|
||||
|
||||
Args:
|
||||
photo: Photo to set date
|
||||
filepath: Path to photo's original file
|
||||
parse_date: strptime format string to parse date from filename
|
||||
verbose: verbose function to use for logging
|
||||
library_path: Path to Photos library; if not provided, will attempt to determine automatically
|
||||
|
||||
Returns:
|
||||
datetime.datetime: date set on photo or None if date could not be parsed
|
||||
"""
|
||||
|
||||
if not isinstance(filepath, pathlib.Path):
|
||||
filepath = pathlib.Path(filepath)
|
||||
|
||||
try:
|
||||
date = strpdatetime(filepath.name, parse_date)
|
||||
except ValueError:
|
||||
verbose(
|
||||
f"[warning]Could not parse date from filename [filename]{filepath.name}[/][/]"
|
||||
)
|
||||
return None
|
||||
|
||||
# first, set date on photo without timezone (Photos will assume local timezone)
|
||||
date_no_tz = datetime_remove_tz(date) if datetime_has_tz(date) else date
|
||||
verbose(
|
||||
f"Setting date of photo [filename]{filepath.name}[/] to [time]{date_no_tz.strftime('%Y-%m-%d %H:%M:%S')}[/]"
|
||||
)
|
||||
photo.date = date_no_tz
|
||||
if datetime_has_tz(date):
|
||||
# if timezone, need to update timezone and also the date/time to match
|
||||
photo_tz_sec, _, photo_tz_name = PhotoTimeZone(
|
||||
library_path=library_path
|
||||
).get_timezone(photo)
|
||||
tz_new_secs = int(utc_offset_seconds(date))
|
||||
if photo_tz_sec != tz_new_secs:
|
||||
tz_new = Timezone(tz_new_secs)
|
||||
update_photo_time_for_new_timezone(library_path, photo, tz_new, verbose)
|
||||
tz_updater = PhotoTimeZoneUpdater(
|
||||
timezone=tz_new,
|
||||
verbose=verbose,
|
||||
library_path=library_path,
|
||||
)
|
||||
tz_updater.update_photo(photo)
|
||||
|
||||
return date
|
||||
@@ -1,6 +1,4 @@
|
||||
"""
|
||||
PhotoInfo class
|
||||
Represents a single photo in the Photos library and provides access to the photo's attributes
|
||||
""" PhotoInfo class: Represents a single photo in the Photos library and provides access to the photo's attributes
|
||||
PhotosDB.photos() returns a list of PhotoInfo objects
|
||||
"""
|
||||
|
||||
@@ -17,11 +15,13 @@ import pathlib
|
||||
import plistlib
|
||||
from datetime import timedelta, timezone
|
||||
from functools import cached_property
|
||||
from typing import Dict, Optional
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
import yaml
|
||||
from osxmetadata import OSXMetaData
|
||||
|
||||
import osxphotos
|
||||
|
||||
from ._constants import (
|
||||
_DB_TABLE_NAMES,
|
||||
_MOVIE_TYPE,
|
||||
@@ -75,10 +75,10 @@ class PhotoInfo:
|
||||
including keywords, persons, albums, uuid, path, etc.
|
||||
"""
|
||||
|
||||
def __init__(self, db=None, uuid=None, info=None):
|
||||
self._uuid = uuid
|
||||
self._info = info
|
||||
self._db = db
|
||||
def __init__(self, db: "osxphotos.PhotosDB", uuid: str, info: dict[str, Any]):
|
||||
self._uuid: str = uuid
|
||||
self._info: dict[str, Any] = info
|
||||
self._db: "osxphotos.PhotosDB" = db
|
||||
self._verbose = self._db._verbose
|
||||
|
||||
@property
|
||||
|
||||
@@ -3,18 +3,21 @@ PhotosDB class
|
||||
Processes a Photos.app library database to extract information about photos
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os
|
||||
import os.path
|
||||
import pathlib
|
||||
import platform
|
||||
import re
|
||||
import sqlite3
|
||||
import sys
|
||||
import tempfile
|
||||
from collections import OrderedDict
|
||||
from collections.abc import Iterable
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from typing import List, Optional
|
||||
from typing import Any, List, Optional
|
||||
from unicodedata import normalize
|
||||
|
||||
import bitmath
|
||||
@@ -324,8 +327,15 @@ class PhotosDB:
|
||||
# _db_version is set from photos.db
|
||||
self._db_version = get_db_version(self._tmp_db)
|
||||
# _photos_version is set from Photos.sqlite which only exists for Photos 5+
|
||||
self._photos_ver = 4 if self._db_version == 4 else 5
|
||||
|
||||
db_ver_int = int(self._db_version)
|
||||
if db_ver_int < 3000:
|
||||
self._photos_ver = 2
|
||||
elif db_ver_int < 4000:
|
||||
self._photos_ver = 3
|
||||
elif db_ver_int < 5000:
|
||||
self._photos_ver = 4
|
||||
else:
|
||||
self._photos_ver = 5
|
||||
# If Photos >= 5, actual data isn't in photos.db but in Photos.sqlite
|
||||
if int(self._db_version) > int(_PHOTOS_4_VERSION):
|
||||
dbpath = pathlib.Path(self._dbfile).parent
|
||||
@@ -585,6 +595,11 @@ class PhotosDB:
|
||||
"""returns path to the Photos library PhotosDB was initialized with"""
|
||||
return self._library_path
|
||||
|
||||
@property
|
||||
def photos_version(self):
|
||||
"""returns version of Photos app that created the library"""
|
||||
return self._photos_ver
|
||||
|
||||
def get_db_connection(self):
|
||||
"""Get connection to the working copy of the Photos database
|
||||
|
||||
@@ -693,6 +708,8 @@ class PhotosDB:
|
||||
"displayname": normalize_unicode(person[4]),
|
||||
"photo_uuid": None,
|
||||
"keyface_uuid": None,
|
||||
"type": None, # Photos 5+
|
||||
"manualorder": 0, # Photos 5+
|
||||
}
|
||||
try:
|
||||
self._dbpersons_fullname[fullname].append(pk)
|
||||
@@ -1675,7 +1692,9 @@ class PhotosDB:
|
||||
ZPERSON.ZFULLNAME,
|
||||
ZPERSON.ZFACECOUNT,
|
||||
ZPERSON.ZKEYFACE,
|
||||
ZPERSON.ZDISPLAYNAME
|
||||
ZPERSON.ZDISPLAYNAME,
|
||||
ZPERSON.ZTYPE,
|
||||
ZPERSON.ZMANUALORDER
|
||||
FROM ZPERSON
|
||||
"""
|
||||
)
|
||||
@@ -1686,6 +1705,8 @@ class PhotosDB:
|
||||
# 3 ZPERSON.ZFACECOUNT,
|
||||
# 4 ZPERSON.ZKEYFACE,
|
||||
# 5 ZPERSON.ZDISPLAYNAME
|
||||
# 6 ZPERSON.ZTYPE, # ZTYPE = 1 == favorite, 0 == not favorite
|
||||
# 7 ZPERSON.ZMANUALORDER # favorites are sorted by ZMANUALORDER
|
||||
|
||||
for person in c:
|
||||
pk = person[0]
|
||||
@@ -1703,6 +1724,8 @@ class PhotosDB:
|
||||
"displayname": normalize_unicode(person[5]),
|
||||
"photo_uuid": None,
|
||||
"keyface_uuid": None,
|
||||
"type": person[6],
|
||||
"manualorder": person[7],
|
||||
}
|
||||
try:
|
||||
self._dbpersons_fullname[fullname].append(pk)
|
||||
@@ -3551,10 +3574,11 @@ class PhotosDB:
|
||||
|
||||
return photos
|
||||
|
||||
def execute(self, sql):
|
||||
def execute(self, sql: str, params: Any | None = None) -> sqlite3.Cursor:
|
||||
"""Execute sql statement and return cursor"""
|
||||
self._db_connection, _ = self.get_db_connection()
|
||||
return self._db_connection.cursor().execute(sql)
|
||||
params = params or ()
|
||||
return self._db_connection.cursor().execute(sql, params)
|
||||
|
||||
def _duplicate_signature(self, uuid):
|
||||
"""Compute a signature for finding possible duplicates"""
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# Ensure you have a backup before using!
|
||||
# You have been warned.
|
||||
|
||||
import datetime
|
||||
import pathlib
|
||||
import sqlite3
|
||||
from typing import Callable, Optional, Tuple
|
||||
@@ -147,6 +148,12 @@ class PhotoTimeZoneUpdater:
|
||||
c = conn.cursor()
|
||||
c.execute(sql_update)
|
||||
conn.commit()
|
||||
|
||||
# now need to update some other property in the photo via Photos API or
|
||||
# changes won't be synced to the cloud (#946)
|
||||
photo.date = photo.date + datetime.timedelta(seconds=1)
|
||||
photo.date = photo.date - datetime.timedelta(seconds=1)
|
||||
|
||||
self.verbose(
|
||||
f"Updated timezone for photo [filename]{photo.filename}[/filename] ([uuid]{photo.uuid}[/uuid]) "
|
||||
+ f"from [tz]{tz_name}[/tz], offset=[tz]{tz_offset}[/tz] "
|
||||
|
||||
@@ -139,6 +139,13 @@ class SearchInfo:
|
||||
return []
|
||||
return self._get_text_for_category(self._categories.DETECTED_TEXT)
|
||||
|
||||
@property
|
||||
def text_found(self):
|
||||
"""Returns True if photos has detected text (macOS 13+ / Photos 8+ only)"""
|
||||
if self._photo._db._photos_ver < 8:
|
||||
return []
|
||||
return self._get_text_for_category(self._categories.TEXT_FOUND)
|
||||
|
||||
@property
|
||||
def camera(self):
|
||||
"""returns camera name (macOS 13+ / Photos 8+ only)"""
|
||||
@@ -147,10 +154,18 @@ class SearchInfo:
|
||||
camera = self._get_text_for_category(self._categories.CAMERA)
|
||||
return camera[0] if camera else ""
|
||||
|
||||
@property
|
||||
def source(self):
|
||||
"""returns source of the photo (e.g. "Messages", "Safar", etc) (macOS 13+ / Photos 8+ only)"""
|
||||
if self._photo._db._photos_ver < 8:
|
||||
return ""
|
||||
source = self._get_text_for_category(self._categories.SOURCE)
|
||||
return source[0] if source else ""
|
||||
|
||||
@property
|
||||
def all(self):
|
||||
"""return all search info properties in a single list"""
|
||||
all = (
|
||||
all_ = (
|
||||
self.labels
|
||||
+ self.place_names
|
||||
+ self.streets
|
||||
@@ -165,23 +180,23 @@ class SearchInfo:
|
||||
+ self.detected_text
|
||||
)
|
||||
if self.city:
|
||||
all += [self.city]
|
||||
all_ += [self.city]
|
||||
if self.state:
|
||||
all += [self.state]
|
||||
all_ += [self.state]
|
||||
if self.state_abbreviation:
|
||||
all += [self.state_abbreviation]
|
||||
all_ += [self.state_abbreviation]
|
||||
if self.country:
|
||||
all += [self.country]
|
||||
all_ += [self.country]
|
||||
if self.month:
|
||||
all += [self.month]
|
||||
all_ += [self.month]
|
||||
if self.year:
|
||||
all += [self.year]
|
||||
all_ += [self.year]
|
||||
if self.season:
|
||||
all += [self.season]
|
||||
all_ += [self.season]
|
||||
if self.camera:
|
||||
all += [self.camera]
|
||||
all_ += [self.camera]
|
||||
|
||||
return all
|
||||
return all_
|
||||
|
||||
def asdict(self):
|
||||
"""return dict of search info"""
|
||||
@@ -206,6 +221,7 @@ class SearchInfo:
|
||||
"media_types": self.media_types,
|
||||
"detected_text": self.detected_text,
|
||||
"camera": self.camera,
|
||||
"source": self.source,
|
||||
}
|
||||
|
||||
def _get_text_for_category(self, category):
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -3,14 +3,14 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>hostname</key>
|
||||
<string>ddrucker-mba.local</string>
|
||||
<string>Mac-mini.local</string>
|
||||
<key>hostuuid</key>
|
||||
<string>3C58BD83-C174-52E3-B12D-D7EBDED55622</string>
|
||||
<string>8E774325-0506-5746-9991-6B8189271107</string>
|
||||
<key>pid</key>
|
||||
<integer>940</integer>
|
||||
<integer>61681</integer>
|
||||
<key>processname</key>
|
||||
<string>photolibraryd</string>
|
||||
<key>uid</key>
|
||||
<integer>502</integer>
|
||||
<integer>501</integer>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -17,6 +17,15 @@
|
||||
<key>kZoomLevelIdentifierPhotosGrid</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
<key>PXPeopleCandidateWidgetKey</key>
|
||||
<dict>
|
||||
<key>PXPeopleCandidateWidgetKey2023.01.22</key>
|
||||
<array>
|
||||
<string>3DDC8F83-FDAB-4943-AE53-19428BEEED9D/L0/070</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>PXPeopleHomeSortingType</key>
|
||||
<integer>0</integer>
|
||||
<key>Photos</key>
|
||||
<dict>
|
||||
<key>CollapsedSidebarSectionIdentifiers</key>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -902,13 +902,15 @@
|
||||
<key>lastSeenDates</key>
|
||||
<dict>
|
||||
<key>com.apple.photos.CPAnalytics.assetCollectionViewed</key>
|
||||
<string>11/12/22</string>
|
||||
<string>1/22/23</string>
|
||||
<key>com.apple.photos.CPAnalytics.mediaViewed</key>
|
||||
<string>11/12/22</string>
|
||||
<string>1/22/23</string>
|
||||
<key>com.apple.photos.CPAnalytics.search.session</key>
|
||||
<string>11/12/22</string>
|
||||
<key>screen_CuratedLibrary_AllPhotos</key>
|
||||
<string>11/12/22</string>
|
||||
<string>1/22/23</string>
|
||||
<key>screen_PhotosDetails_People</key>
|
||||
<string>1/22/23</string>
|
||||
<key>screen_PhotosView</key>
|
||||
<string>11/12/22</string>
|
||||
</dict>
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>PLThumbnailManagerRebuildingTablesOnly</key>
|
||||
<true/>
|
||||
<key>PLThumbnailManagerThumbnailFormatKey</key>
|
||||
<integer>5005</integer>
|
||||
<key>PLThumbnailManagerThumbnailFormatsKey</key>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>LibrarySchemaVersion</key>
|
||||
<integer>5001</integer>
|
||||
<key>MetaSchemaVersion</key>
|
||||
<integer>3</integer>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
tests/TestTimeWarp-13.1.0.photoslibrary/database/Photos.sqlite
Normal file
BIN
tests/TestTimeWarp-13.1.0.photoslibrary/database/Photos.sqlite
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>hostname</key>
|
||||
<string>Mac-mini.local</string>
|
||||
<key>hostuuid</key>
|
||||
<string>8E774325-0506-5746-9991-6B8189271107</string>
|
||||
<key>pid</key>
|
||||
<integer>61681</integer>
|
||||
<key>processname</key>
|
||||
<string>photolibraryd</string>
|
||||
<key>uid</key>
|
||||
<integer>501</integer>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
tests/TestTimeWarp-13.1.0.photoslibrary/database/metaSchema.db
Normal file
BIN
tests/TestTimeWarp-13.1.0.photoslibrary/database/metaSchema.db
Normal file
Binary file not shown.
BIN
tests/TestTimeWarp-13.1.0.photoslibrary/database/photos.db
Normal file
BIN
tests/TestTimeWarp-13.1.0.photoslibrary/database/photos.db
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>insertAlbum</key>
|
||||
<array/>
|
||||
<key>insertAsset</key>
|
||||
<array/>
|
||||
<key>insertHighlight</key>
|
||||
<array/>
|
||||
<key>insertMemory</key>
|
||||
<array/>
|
||||
<key>insertMoment</key>
|
||||
<array/>
|
||||
<key>removeAlbum</key>
|
||||
<array/>
|
||||
<key>removeAsset</key>
|
||||
<array/>
|
||||
<key>removeHighlight</key>
|
||||
<array/>
|
||||
<key>removeMemory</key>
|
||||
<array/>
|
||||
<key>removeMoment</key>
|
||||
<array/>
|
||||
<key>renamePerson</key>
|
||||
<array/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>embeddingVersion</key>
|
||||
<string>1</string>
|
||||
<key>featureFlags</key>
|
||||
<string>319</string>
|
||||
<key>featuredContentAllowed</key>
|
||||
<string>1</string>
|
||||
<key>localeIdentifier</key>
|
||||
<string>en_US</string>
|
||||
<key>sceneTaxonomySHA</key>
|
||||
<string>64d078bafc0035e1ec26dfa565c2ac0479fcbab329fda1c16cd17e0fdbf2f4c0,4afa5d3c45c08a664cf73cff957aaeeae3a325d2970aada51268407b9ad0f03e</string>
|
||||
<key>searchIndexVersion</key>
|
||||
<string>16025</string>
|
||||
</dict>
|
||||
</plist>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 2.1 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.6 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.8 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.5 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.6 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.6 MiB |
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CollapsedSidebarSectionIdentifiers</key>
|
||||
<array/>
|
||||
<key>IPXWorkspaceControllerZoomLevelsKey</key>
|
||||
<dict>
|
||||
<key>kZoomLevelIdentifierPhotosGrid</key>
|
||||
<integer>2</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>FaceProcessingInternalVersion</key>
|
||||
<integer>11</integer>
|
||||
</dict>
|
||||
</plist>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user