From 53119f5689155adc7fd48c10b43f8f15a0389cfe Mon Sep 17 00:00:00 2001 From: Rhet Turnbull Date: Sat, 9 May 2020 14:21:55 -0500 Subject: [PATCH] Updated Structure of the code (markdown) --- Structure-of-the-code.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Structure-of-the-code.md b/Structure-of-the-code.md index b7526cf..e6f6027 100644 --- a/Structure-of-the-code.md +++ b/Structure-of-the-code.md @@ -1,5 +1,6 @@ osxphotos is built around a set of classes that each handle a particular aspect of the Photos library: +## osxphotos classes * PhotosDB: reads the Photos library database and extract all relevant metadata about each photo. This is starting point for any use of osxphotos. * PhotoInfo: represents an individual photo in the library and all associated metadata. * AlbumInfo: represents an album in the library. @@ -9,6 +10,7 @@ osxphotos is built around a set of classes that each handle a particular aspect The package code is organized in osxphotos per the table below. Most of the files contain doc strings describing what they contain. +## source files |file|description| |---|---| |`__init__.py`| this is what gets read by "import osxphotos"| @@ -27,7 +29,7 @@ The package code is organized in osxphotos per the table below. Most of the file |`templates/xmp_sidecar.mako`|mako template used to create [XMP](https://en.wikipedia.org/wiki/Extensible_Metadata_Platform) sidecar files| |`utils.py`| various utility methods--this file is getting bloated and needs to be refactored| - +## How osxphotos works Broadly, osxphotos works like this: 1. Opens a readonly copy of `photos.db`. If the file is locked, a temporary copy will be created then opened. 2. Reads `photos.db` to determine which version of Photos created the library (`PhotosDB._get_db_version()`) @@ -36,3 +38,11 @@ Broadly, osxphotos works like this: 5. `_process_database4` and `_process_database5` execute several SQL queries to extract the required data. These methods populate a series of data structures in `PhotosDB` which are then used by the rest of code to create the `PhotoInfo`, `AlbumInfo`, and `FolderInfo` objects. These database structures are ugly...in general, they flatten the SQL database into several different python dicts. The "master" dict is called `_dbphotos`. The key is the [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier) of the photo and the value is another dict containing details about the photo. Read the code for `PhotosDB.__init__()` for additional details. Each of the data structures is documented in the code. 6. The `PhotoInfo`, `AlbumInfo`, and `FolderInfo` objects are created as needed. For example, `PhotosDB.photos()` returns a list of `PhotoInfo` objects representing the photos in the database and `PhotoInfo.album_info` returns a list of `AlbumInfo` objects representing the albums the photo is contained in. + +## Modifying the code +As an example, here's a rough outline of what you'd need to do to add support for a new metadata attribute: +1. Reverse engineer Photos.sqlite and develop an sql query that extracts the data +2. Add this query to `PhotosDB._process_database5` (assuming a Photos 5 library) and store the data in appropriate data structure accessible through `_dbphotos` +3. Add a property to `PhotoInfo` which accesses `_dbphotos` through `self._db` which points to the PhotosDB object +4. If exposing the property to the templating system (`PhotoInfo.render_template()`) and add it to `templates.py` (which is relatively self-documenting) +5. If exposing the property to the command line interface, add it to `__main__.py` \ No newline at end of file