home / content / repos

repos: 256834907

This data as json

id node_id name full_name private owner html_url description fork created_at updated_at pushed_at homepage size stargazers_count watchers_count language has_issues has_projects has_downloads has_wiki has_pages forks_count archived disabled open_issues_count license topics forks open_issues watchers default_branch permissions temp_clone_token organization network_count subscribers_count readme readme_html allow_forking visibility is_template template_repository web_commit_signoff_required has_discussions
256834907 MDEwOlJlcG9zaXRvcnkyNTY4MzQ5MDc= dogsheep-photos dogsheep/dogsheep-photos 0 53015001 https://github.com/dogsheep/dogsheep-photos Upload your photos to S3 and import metadata about them into a SQLite database 0 2020-04-18T19:22:13Z 2021-11-04T20:45:03Z 2021-11-04T20:45:00Z   68 124 124 Python 1 1 1 1 0 7 0 0 19 apache-2.0 ["datasette", "datasette-io", "datasette-tool", "dogsheep", "sqlite"] 7 19 124 master {"admin": false, "maintain": false, "push": false, "triage": false, "pull": false}   53015001 7 10 # dogsheep-photos [![PyPI](https://img.shields.io/pypi/v/dogsheep-photos.svg)](https://pypi.org/project/dogsheep-photos/) [![Changelog](https://img.shields.io/github/v/release/dogsheep/dogsheep-photos?include_prereleases&label=changelog)](https://github.com/dogsheep/dogsheep-photos/releases) [![CircleCI](https://circleci.com/gh/dogsheep/dogsheep-photos.svg?style=svg)](https://circleci.com/gh/dogsheep/dogsheep-photos) [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/dogsheep/dogsheep-photos/blob/master/LICENSE) Save details of your photos to a SQLite database and upload them to S3. See [Using SQL to find my best photo of a pelican according to Apple Photos](https://simonwillison.net/2020/May/21/apple-photos-sqlite/) for background information on this project. ## What these tools do These tools are a work-in-progress mechanism for taking full ownership of your photos. The core idea is to help implement the following: * Every photo you have taken lives in a single, private Amazon S3 bucket * You have a single SQLite database file which stores metadata about those photos - potentially pulled from multiple different places. This may include EXIF data, Apple Photos, the results of running machine learning APIs against photos and much more besides. * You can then use [Datasette](https://github.com/simonw/datasette) to explore your own photos. I'm a heavy user of Apple Photos so the initial releases of this tool will have a bias towards that, but ideally I would like a subset of these tools to be useful to people no matter which core photo solution they are using. ## Installation $ pip install dogsheep-photos ## Authentication (if using S3) If you want to use S3 to store your photos, you will need to first create S3 credentials for a new, dedicated bucket. You may find the [s3-credentials tool](https://github.com/simonw/s3-credentials) useful for this. Run this command and paste in your credentials. You will need three values: the name of your S3 bucket, your Access key ID and your Secret access key. $ dogsheep-photos s3-auth This will create a file called `auth.json` in your current directory containing the required values. To save the file at a different path or filename, use the `--auth=myauth.json` option. ## Uploading photos Run this command to upload every photo in a specific directory to your S3 bucket: $ dogsheep-photos upload photos.db \ ~/Pictures/Photos\ Library.photoslibrary/original The command will only upload photos that have not yet been uploaded, based on their sha256 hash. `photos.db` will be created with an `uploads` table containing details of which files were uploaded. To see what the command would do without uploading any files, use the `--dry-run` option. The sha256 hash of the photo contents will be used as the name of the file in the bucket, with an extension matching the type of file. This is an implementation of the [Content addressable storage](https://en.wikipedia.org/wiki/Content-addressable_storage) pattern. ## Importing Apple Photos metadata The `apple-photos` command imports metadata from your Apple Photos library. $ photo-to-sqlite apple-photos photos.db Imported metadata includes places, people, albums, quality scores and machine learning labels for the photo contents. ## Creating a subset database You can create a new, subset database of photos using the `create-subset` command. This is useful for creating a shareable SQLite database that only contains metadata for a selected set of photos. Since photo metadata contains latitude and longitude you may not want to share a database that includes photos taken at your home address. `create-subset` takes three arguments: an existing database file created using the `apple-photos` command, the name of the new, shareable database file you would like to create and a SQL query that returns the `sha256` hash values of the photos you would like to include in that database. For example, here's how to create a shareable database of just the photos that have been added to albums containing the word "Public": $ dogsheep-photos create-subset \ photos.db \ public.db \ "select sha256 from apple_photos where albums like '%Public%'" ## Serving photos locally with datasette-media If you don't want to upload your photos to S3 but you still want to browse them using Datasette you can do so using the [datasette-media](https://github.com/simonw/datasette-media) plugin. This plugin adds the ability to serve images and other static files directly from disk, configured using a SQL query. To use it, first install Datasette and the plugin: $ pip install datasette datasette-media If any of your photos are `.HEIC` images taken by an iPhone you should also install the optional `pyheif` dependency: $ pip install pyheif Now create a `metadata.yaml` file configuring the plugin: ```yaml plugins: datasette-media: thumbnail: sql: |- select path as filepath, 200 as resize_height from apple_photos where uuid = :key large: sql: |- select path as filepath, 1024 as resize_height from apple_photos where uuid = :key ``` This will configure two URL endpoints - one for 200 pixel high thumbnails and one for 1024 pixel high larger images. Create your `photos.db` database using the `apple-photos` command, then run Datasette like this: $ datasette -m metadata.yaml Your photos will be served on URLs that look like this: http://127.0.0.1:8001/-/media/thumbnail/F4469918-13F3-43D8-9EC1-734C0E6B60AD http://127.0.0.1:8001/-/media/large/F4469918-13F3-43D8-9EC1-734C0E6B60AD You can find the UUIDs for use in these URLs by running `select uuid from photos_with_apple_metadata`. ### Displaying images using datasette-json-html If you are using `datasette-media` to serve photos you can include images directly in Datasette query results using the [datasette-json-html](https://github.com/simonw/datasette-json-html) plugin. Run `pip install datasette-json-html` to install the plugin, then use queries like this to view your images: ```sql select json_object( 'img_src', '/-/media/thumbnail/' || uuid ) as photo, uuid, date from apple_photos order by date desc limit 10; ``` The `photo` column returned by this query should render as image tags that display the correct images. ### Displaying images using custom template pages Datasette's [custom pages](https://datasette.readthedocs.io/en/stable/custom_templates.html#custom-pages) feature lets you create custom pages for a Datasette instance by dropping HTML templates into a `templates/pages` directory and then running Datasette using `datasette --template-dir=templates/`. You can combine that ability with the [datasette-template-sql](https://github.com/simonw/datasette-template-sql) plugin to create custom template pages that directly display photos served by `datasette-media`. Install the plugin using `pip install datasette-template-sql`. Create a `templates/pages` folder and add the following files: `recent-photos.html` ```html+jinja <h1>Recent photos</h1> <div> {% for photo in sql("select * from apple_photos order by date desc limit 20") %} <img src="/-/media/photo/{{ photo['uuid'] }}"> {% endfor %} </div> ``` `random-photos.html` ```html+jinja <h1>Random photos</h1> <div> {% for photo in sql("with foo as (select * from apple_photos order by date desc limit 5000) select * from foo order by random() limit 20") %} <img src="/-/media/photo/{{ photo['uuid'] }}"> {% endfor %} </div> ``` Now run Datasette like this: $ datasette photos.db -m metadata.yaml --template-dir=templates/ Visiting `http://localhost:8001/recent-photos` will display 20 recent photos. Visiting `http://localhost:8001/random-photos` will display 20 photos randomly selected from your 5,000 most recent. <div id="readme" class="md" data-path="README.md"><article class="markdown-body entry-content container-lg" itemprop="text"><h1><a id="user-content-dogsheep-photos" class="anchor" aria-hidden="true" href="#user-content-dogsheep-photos"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>dogsheep-photos</h1> <p><a href="https://pypi.org/project/dogsheep-photos/" rel="nofollow"><img src="https://camo.githubusercontent.com/c21d10e4250454707420755a0d4b90c97709771d795ffa55b495c98956a3938d/68747470733a2f2f696d672e736869656c64732e696f2f707970692f762f646f6773686565702d70686f746f732e737667" alt="PyPI" data-canonical-src="https://img.shields.io/pypi/v/dogsheep-photos.svg" style="max-width: 100%;"></a> <a href="https://github.com/dogsheep/dogsheep-photos/releases"><img src="https://camo.githubusercontent.com/c7bead2f1c989034f62914278a736eecdfbab79ce4d9b3ab804d1692e230d79d/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f646f6773686565702f646f6773686565702d70686f746f733f696e636c7564655f70726572656c6561736573266c6162656c3d6368616e67656c6f67" alt="Changelog" data-canonical-src="https://img.shields.io/github/v/release/dogsheep/dogsheep-photos?include_prereleases&amp;label=changelog" style="max-width: 100%;"></a> <a href="https://circleci.com/gh/dogsheep/dogsheep-photos" rel="nofollow"><img src="https://camo.githubusercontent.com/3aefe86d4a3560c1ca080cf5b7e4dcc5788b239df8b7a3fed40e622b834c22e8/68747470733a2f2f636972636c6563692e636f6d2f67682f646f6773686565702f646f6773686565702d70686f746f732e7376673f7374796c653d737667" alt="CircleCI" data-canonical-src="https://circleci.com/gh/dogsheep/dogsheep-photos.svg?style=svg" style="max-width: 100%;"></a> <a href="https://github.com/dogsheep/dogsheep-photos/blob/master/LICENSE"><img src="https://camo.githubusercontent.com/1698104e976c681143eb0841f9675c6f802bb7aa832afc0c7a4e719b1f3cf955/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d417061636865253230322e302d626c75652e737667" alt="License" data-canonical-src="https://img.shields.io/badge/license-Apache%202.0-blue.svg" style="max-width: 100%;"></a></p> <p>Save details of your photos to a SQLite database and upload them to S3.</p> <p>See <a href="https://simonwillison.net/2020/May/21/apple-photos-sqlite/" rel="nofollow">Using SQL to find my best photo of a pelican according to Apple Photos</a> for background information on this project.</p> <h2><a id="user-content-what-these-tools-do" class="anchor" aria-hidden="true" href="#user-content-what-these-tools-do"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>What these tools do</h2> <p>These tools are a work-in-progress mechanism for taking full ownership of your photos. The core idea is to help implement the following:</p> <ul> <li>Every photo you have taken lives in a single, private Amazon S3 bucket</li> <li>You have a single SQLite database file which stores metadata about those photos - potentially pulled from multiple different places. This may include EXIF data, Apple Photos, the results of running machine learning APIs against photos and much more besides.</li> <li>You can then use <a href="https://github.com/simonw/datasette">Datasette</a> to explore your own photos.</li> </ul> <p>I'm a heavy user of Apple Photos so the initial releases of this tool will have a bias towards that, but ideally I would like a subset of these tools to be useful to people no matter which core photo solution they are using.</p> <h2><a id="user-content-installation" class="anchor" aria-hidden="true" href="#user-content-installation"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Installation</h2> <div class="snippet-clipboard-content position-relative overflow-auto" data-snippet-clipboard-copy-content="$ pip install dogsheep-photos "><pre><code>$ pip install dogsheep-photos </code></pre></div> <h2><a id="user-content-authentication-if-using-s3" class="anchor" aria-hidden="true" href="#user-content-authentication-if-using-s3"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Authentication (if using S3)</h2> <p>If you want to use S3 to store your photos, you will need to first create S3 credentials for a new, dedicated bucket.</p> <p>You may find the <a href="https://github.com/simonw/s3-credentials">s3-credentials tool</a> useful for this.</p> <p>Run this command and paste in your credentials. You will need three values: the name of your S3 bucket, your Access key ID and your Secret access key.</p> <div class="snippet-clipboard-content position-relative overflow-auto" data-snippet-clipboard-copy-content="$ dogsheep-photos s3-auth "><pre><code>$ dogsheep-photos s3-auth </code></pre></div> <p>This will create a file called <code>auth.json</code> in your current directory containing the required values. To save the file at a different path or filename, use the <code>--auth=myauth.json</code> option.</p> <h2><a id="user-content-uploading-photos" class="anchor" aria-hidden="true" href="#user-content-uploading-photos"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Uploading photos</h2> <p>Run this command to upload every photo in a specific directory to your S3 bucket:</p> <div class="snippet-clipboard-content position-relative overflow-auto" data-snippet-clipboard-copy-content="$ dogsheep-photos upload photos.db \ ~/Pictures/Photos\ Library.photoslibrary/original "><pre><code>$ dogsheep-photos upload photos.db \ ~/Pictures/Photos\ Library.photoslibrary/original </code></pre></div> <p>The command will only upload photos that have not yet been uploaded, based on their sha256 hash.</p> <p><code>photos.db</code> will be created with an <code>uploads</code> table containing details of which files were uploaded.</p> <p>To see what the command would do without uploading any files, use the <code>--dry-run</code> option.</p> <p>The sha256 hash of the photo contents will be used as the name of the file in the bucket, with an extension matching the type of file. This is an implementation of the <a href="https://en.wikipedia.org/wiki/Content-addressable_storage" rel="nofollow">Content addressable storage</a> pattern.</p> <h2><a id="user-content-importing-apple-photos-metadata" class="anchor" aria-hidden="true" href="#user-content-importing-apple-photos-metadata"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Importing Apple Photos metadata</h2> <p>The <code>apple-photos</code> command imports metadata from your Apple Photos library.</p> <div class="snippet-clipboard-content position-relative overflow-auto" data-snippet-clipboard-copy-content="$ photo-to-sqlite apple-photos photos.db "><pre><code>$ photo-to-sqlite apple-photos photos.db </code></pre></div> <p>Imported metadata includes places, people, albums, quality scores and machine learning labels for the photo contents.</p> <h2><a id="user-content-creating-a-subset-database" class="anchor" aria-hidden="true" href="#user-content-creating-a-subset-database"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Creating a subset database</h2> <p>You can create a new, subset database of photos using the <code>create-subset</code> command.</p> <p>This is useful for creating a shareable SQLite database that only contains metadata for a selected set of photos.</p> <p>Since photo metadata contains latitude and longitude you may not want to share a database that includes photos taken at your home address.</p> <p><code>create-subset</code> takes three arguments: an existing database file created using the <code>apple-photos</code> command, the name of the new, shareable database file you would like to create and a SQL query that returns the <code>sha256</code> hash values of the photos you would like to include in that database.</p> <p>For example, here's how to create a shareable database of just the photos that have been added to albums containing the word "Public":</p> <div class="snippet-clipboard-content position-relative overflow-auto" data-snippet-clipboard-copy-content="$ dogsheep-photos create-subset \ photos.db \ public.db \ &quot;select sha256 from apple_photos where albums like '%Public%'&quot; "><pre><code>$ dogsheep-photos create-subset \ photos.db \ public.db \ "select sha256 from apple_photos where albums like '%Public%'" </code></pre></div> <h2><a id="user-content-serving-photos-locally-with-datasette-media" class="anchor" aria-hidden="true" href="#user-content-serving-photos-locally-with-datasette-media"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Serving photos locally with datasette-media</h2> <p>If you don't want to upload your photos to S3 but you still want to browse them using Datasette you can do so using the <a href="https://github.com/simonw/datasette-media">datasette-media</a> plugin. This plugin adds the ability to serve images and other static files directly from disk, configured using a SQL query.</p> <p>To use it, first install Datasette and the plugin:</p> <div class="snippet-clipboard-content position-relative overflow-auto" data-snippet-clipboard-copy-content="$ pip install datasette datasette-media "><pre><code>$ pip install datasette datasette-media </code></pre></div> <p>If any of your photos are <code>.HEIC</code> images taken by an iPhone you should also install the optional <code>pyheif</code> dependency:</p> <div class="snippet-clipboard-content position-relative overflow-auto" data-snippet-clipboard-copy-content="$ pip install pyheif "><pre><code>$ pip install pyheif </code></pre></div> <p>Now create a <code>metadata.yaml</code> file configuring the plugin:</p> <div class="highlight highlight-source-yaml position-relative overflow-auto" data-snippet-clipboard-copy-content="plugins: datasette-media: thumbnail: sql: |- select path as filepath, 200 as resize_height from apple_photos where uuid = :key large: sql: |- select path as filepath, 1024 as resize_height from apple_photos where uuid = :key "><pre><span class="pl-ent">plugins</span>: <span class="pl-ent">datasette-media</span>: <span class="pl-ent">thumbnail</span>: <span class="pl-ent">sql</span>: <span class="pl-s">|-</span> <span class="pl-s"> select path as filepath, 200 as resize_height from apple_photos where uuid = :key</span> <span class="pl-s"></span> <span class="pl-ent">large</span>: <span class="pl-ent">sql</span>: <span class="pl-s">|-</span> <span class="pl-s"> select path as filepath, 1024 as resize_height from apple_photos where uuid = :key</span></pre></div> <p>This will configure two URL endpoints - one for 200 pixel high thumbnails and one for 1024 pixel high larger images.</p> <p>Create your <code>photos.db</code> database using the <code>apple-photos</code> command, then run Datasette like this:</p> <div class="snippet-clipboard-content position-relative overflow-auto" data-snippet-clipboard-copy-content="$ datasette -m metadata.yaml "><pre><code>$ datasette -m metadata.yaml </code></pre></div> <p>Your photos will be served on URLs that look like this:</p> <div class="snippet-clipboard-content position-relative overflow-auto" data-snippet-clipboard-copy-content="http://127.0.0.1:8001/-/media/thumbnail/F4469918-13F3-43D8-9EC1-734C0E6B60AD http://127.0.0.1:8001/-/media/large/F4469918-13F3-43D8-9EC1-734C0E6B60AD "><pre><code>http://127.0.0.1:8001/-/media/thumbnail/F4469918-13F3-43D8-9EC1-734C0E6B60AD http://127.0.0.1:8001/-/media/large/F4469918-13F3-43D8-9EC1-734C0E6B60AD </code></pre></div> <p>You can find the UUIDs for use in these URLs by running <code>select uuid from photos_with_apple_metadata</code>.</p> <h3><a id="user-content-displaying-images-using-datasette-json-html" class="anchor" aria-hidden="true" href="#user-content-displaying-images-using-datasette-json-html"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Displaying images using datasette-json-html</h3> <p>If you are using <code>datasette-media</code> to serve photos you can include images directly in Datasette query results using the <a href="https://github.com/simonw/datasette-json-html">datasette-json-html</a> plugin.</p> <p>Run <code>pip install datasette-json-html</code> to install the plugin, then use queries like this to view your images:</p> <div class="highlight highlight-source-sql position-relative overflow-auto" data-snippet-clipboard-copy-content="select json_object( 'img_src', '/-/media/thumbnail/' || uuid ) as photo, uuid, date from apple_photos order by date desc limit 10; "><pre><span class="pl-k">select</span> json_object( <span class="pl-s"><span class="pl-pds">'</span>img_src<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>/-/media/thumbnail/<span class="pl-pds">'</span></span> <span class="pl-k">||</span> uuid ) <span class="pl-k">as</span> photo, uuid, <span class="pl-k">date</span> <span class="pl-k">from</span> apple_photos <span class="pl-k">order by</span> <span class="pl-k">date</span> <span class="pl-k">desc</span> <span class="pl-k">limit</span> <span class="pl-c1">10</span>;</pre></div> <p>The <code>photo</code> column returned by this query should render as image tags that display the correct images.</p> <h3><a id="user-content-displaying-images-using-custom-template-pages" class="anchor" aria-hidden="true" href="#user-content-displaying-images-using-custom-template-pages"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Displaying images using custom template pages</h3> <p>Datasette's <a href="https://datasette.readthedocs.io/en/stable/custom_templates.html#custom-pages" rel="nofollow">custom pages</a> feature lets you create custom pages for a Datasette instance by dropping HTML templates into a <code>templates/pages</code> directory and then running Datasette using <code>datasette --template-dir=templates/</code>.</p> <p>You can combine that ability with the <a href="https://github.com/simonw/datasette-template-sql">datasette-template-sql</a> plugin to create custom template pages that directly display photos served by <code>datasette-media</code>.</p> <p>Install the plugin using <code>pip install datasette-template-sql</code>.</p> <p>Create a <code>templates/pages</code> folder and add the following files:</p> <p><code>recent-photos.html</code></p> <div class="highlight highlight-text-html-django position-relative overflow-auto" data-snippet-clipboard-copy-content="&lt;h1&gt;Recent photos&lt;/h1&gt; &lt;div&gt; {% for photo in sql(&quot;select * from apple_photos order by date desc limit 20&quot;) %} &lt;img src=&quot;/-/media/photo/{{ photo['uuid'] }}&quot;&gt; {% endfor %} &lt;/div&gt; "><pre>&lt;<span class="pl-ent">h1</span>&gt;Recent photos&lt;/<span class="pl-ent">h1</span>&gt; &lt;<span class="pl-ent">div</span>&gt; <span class="pl-e">{%</span> <span class="pl-k">for</span> <span class="pl-s">photo</span> <span class="pl-k">in</span> <span class="pl-s">sql</span>(<span class="pl-s">"select * from apple_photos order by date desc limit 20"</span>) <span class="pl-e">%}</span> &lt;<span class="pl-ent">img</span> <span class="pl-e">src</span>=<span class="pl-s"><span class="pl-pds">"</span>/-/media/photo/{{ photo['uuid'] }}<span class="pl-pds">"</span></span>&gt; <span class="pl-e">{%</span> <span class="pl-k">endfor</span> <span class="pl-e">%}</span> &lt;/<span class="pl-ent">div</span>&gt;</pre></div> <p><code>random-photos.html</code></p> <div class="highlight highlight-text-html-django position-relative overflow-auto" data-snippet-clipboard-copy-content="&lt;h1&gt;Random photos&lt;/h1&gt; &lt;div&gt; {% for photo in sql(&quot;with foo as (select * from apple_photos order by date desc limit 5000) select * from foo order by random() limit 20&quot;) %} &lt;img src=&quot;/-/media/photo/{{ photo['uuid'] }}&quot;&gt; {% endfor %} &lt;/div&gt; "><pre>&lt;<span class="pl-ent">h1</span>&gt;Random photos&lt;/<span class="pl-ent">h1</span>&gt; &lt;<span class="pl-ent">div</span>&gt; <span class="pl-e">{%</span> <span class="pl-k">for</span> <span class="pl-s">photo</span> <span class="pl-k">in</span> <span class="pl-s">sql</span>(<span class="pl-s">"with foo as (select * from apple_photos order by date desc limit 5000) select * from foo order by random() limit 20"</span>) <span class="pl-e">%}</span> &lt;<span class="pl-ent">img</span> <span class="pl-e">src</span>=<span class="pl-s"><span class="pl-pds">"</span>/-/media/photo/{{ photo['uuid'] }}<span class="pl-pds">"</span></span>&gt; <span class="pl-e">{%</span> <span class="pl-k">endfor</span> <span class="pl-e">%}</span> &lt;/<span class="pl-ent">div</span>&gt;</pre></div> <p>Now run Datasette like this:</p> <div class="snippet-clipboard-content position-relative overflow-auto" data-snippet-clipboard-copy-content="$ datasette photos.db -m metadata.yaml --template-dir=templates/ "><pre><code>$ datasette photos.db -m metadata.yaml --template-dir=templates/ </code></pre></div> <p>Visiting <code>http://localhost:8001/recent-photos</code> will display 20 recent photos. Visiting <code>http://localhost:8001/random-photos</code> will display 20 photos randomly selected from your 5,000 most recent.</p> </article></div> 1 public 0      

Links from other tables

  • 5 rows from repo in releases
Powered by Datasette · Queries took 1.119ms