Feature add keep 730 (#740)

* Implemented #730, --keep

* Implemented #739, fixed --keep to accept relative paths

* Updated to macos-latest

Ref: https://github.com/actions/virtual-environments/issues/5583

* Release files for #730
This commit is contained in:
Rhet Turnbull
2022-07-27 08:14:00 -07:00
committed by GitHub
parent fb4329e0ed
commit 76625b9e84
24 changed files with 336 additions and 49 deletions

View File

@@ -9,7 +9,7 @@ jobs:
strategy:
max-parallel: 4
matrix:
os: [macos-10.15]
os: [macos-latest]
python-version: ['3.8', '3.9', '3.10']
steps:

View File

@@ -2005,7 +2005,7 @@ cog.out(get_template_field_table())
|{lf}|A line feed: '\n', alias for {newline}|
|{cr}|A carriage return: '\r'|
|{crlf}|a carriage return + line feed: '\r\n'|
|{osxphotos_version}|The osxphotos version, e.g. '0.50.9'|
|{osxphotos_version}|The osxphotos version, e.g. '0.50.10'|
|{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|

View File

@@ -1195,6 +1195,29 @@ Options:
you intend before using --cleanup. Use --dry-
run with --cleanup first if you're not
certain.
--keep KEEP_PATH When used with --cleanup, prevents file or
directory KEEP_PATH from being deleted when
cleanup is run. Use this if there are files in
the export directory that you don't want to be
deleted when --cleanup is run. KEEP_PATH may
be a file path, e.g.
'/Volumes/Photos/keep.jpg', or a file path and
wild card, e.g. '/Volumes/Photos/*.txt', or a
directory, e.g. '/Volumes/Photos/KeepMe'.
KEEP_PATH may be an absolute path or a
relative path. If it is relative, it must be
relative to the export destination. For
example if export destination is
`/Volumes/Photos` and you want to keep all
`.txt` files, you can specify `--keep
"/Volumes/Photos/*.txt"` or `--keep "*.txt"`.
If wild card is used, KEEP_PATH must be
enclosed in quotes to prevent the shell from
expanding the wildcard, e.g. `--keep
"/Volumes/Photos/*.txt"`. If KEEP_PATH is a
directory, all files and directories contained
in KEEP_PATH will be kept. --keep may be
repeated to keep additional files/directories.
--add-exported-to-album ALBUM Add all exported photos to album ALBUM in
Photos. Album ALBUM will be created if it
doesn't exist. All exported photos will be
@@ -1926,7 +1949,7 @@ Substitution Description
{lf} A line feed: '\n', alias for {newline}
{cr} A carriage return: '\r'
{crlf} a carriage return + line feed: '\r\n'
{osxphotos_version} The osxphotos version, e.g. '0.50.9'
{osxphotos_version} The osxphotos version, e.g. '0.50.10'
{osxphotos_cmd_line} The full command line used to run osxphotos
The following substitutions may result in multiple values. Thus if specified
@@ -2403,7 +2426,7 @@ The following template field substitutions are availabe for use the templating s
|{lf}|A line feed: '\n', alias for {newline}|
|{cr}|A carriage return: '\r'|
|{crlf}|a carriage return + line feed: '\r\n'|
|{osxphotos_version}|The osxphotos version, e.g. '0.50.9'|
|{osxphotos_version}|The osxphotos version, e.g. '0.50.10'|
|{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|

View File

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

View File

@@ -5,7 +5,7 @@
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../genindex.html" /><link rel="search" title="Search" href="../search.html" />
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/>
<title>Overview: module code - osxphotos 0.50.9 documentation</title>
<title>Overview: module code - osxphotos 0.50.10 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/copybutton.css" />
@@ -123,7 +123,7 @@
</label>
</div>
<div class="header-center">
<a href="../index.html"><div class="brand">osxphotos 0.50.9 documentation</div></a>
<a href="../index.html"><div class="brand">osxphotos 0.50.10 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.9 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.50.10 documentation</span>
</a><form class="sidebar-search-container" method="get" action="../search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">

View File

@@ -346,7 +346,7 @@ Template Substitutions
* - {crlf}
- a carriage return + line feed: '\r\n'
* - {osxphotos_version}
- The osxphotos version, e.g. '0.50.9'
- The osxphotos version, e.g. '0.50.10'
* - {osxphotos_cmd_line}
- The full command line used to run osxphotos
* - {album}

View File

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

View File

@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="OSXPhotos Template System" href="template_help.html" /><link rel="prev" title="OSXPhotos Tutorial" href="tutorial.html" />
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/>
<title>OSXPhotos Command Line Interface (CLI) - osxphotos 0.50.9 documentation</title>
<title>OSXPhotos Command Line Interface (CLI) - osxphotos 0.50.10 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/copybutton.css" />
@@ -124,7 +124,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">osxphotos 0.50.9 documentation</div></a>
<a href="index.html"><div class="brand">osxphotos 0.50.10 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.50.9 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.50.10 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">
@@ -1159,6 +1159,11 @@ to modify this behavior.</p>
<dd><p>Cleanup export directory by deleting any files which were not included in this export set. For example, photos which had previously been exported and were subsequently deleted in Photos. WARNING: cleanup will delete <em>any</em> files in the export directory that were not exported by osxphotos, for example, your own scripts or other files. Be sure this is what you intend before using cleanup. Use dry-run with cleanup first if youre not certain.</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-keep">
<span class="sig-name descname"><span class="pre">--keep</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;KEEP_PATH&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-export-keep" title="Permalink to this definition">#</a></dt>
<dd><p>When used with cleanup, prevents file or directory KEEP_PATH from being deleted when cleanup is run. Use this if there are files in the export directory that you dont want to be deleted when cleanup is run. KEEP_PATH may be a file path, e.g. /Volumes/Photos/keep.jpg, or a file path and wild card, e.g. /Volumes/Photos/<em>.txt, or a directory, e.g. /Volumes/Photos/KeepMe. KEEP_PATH may be an absolute path or a relative path. If it is relative, it must be relative to the export destination. For example if export destination is `/Volumes/Photos` and you want to keep all `.txt` files, you can specify `keep “/Volumes/Photos/</em>.txt”` or <cite>keep “*.txt”</cite>. If wild card is used, KEEP_PATH must be enclosed in quotes to prevent the shell from expanding the wildcard, e.g. <cite>keep “/Volumes/Photos/*.txt”</cite>. If KEEP_PATH is a directory, all files and directories contained in KEEP_PATH will be kept. keep may be repeated to keep additional files/directories.</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-add-exported-to-album">
<span class="sig-name descname"><span class="pre">--add-exported-to-album</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;ALBUM&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-export-add-exported-to-album" title="Permalink to this definition">#</a></dt>
<dd><p>Add all exported photos to album ALBUM in Photos. Album ALBUM will be created if it doesnt exist. All exported photos will be added to this album. This only works if the Photos library being exported is the last-opened (default) library in Photos. This feature is currently experimental. I dont know how well it will work on large export sets.</p>

View File

@@ -4,7 +4,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="#" /><link rel="search" title="Search" href="search.html" />
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/><title>Index - osxphotos 0.50.9 documentation</title>
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/><title>Index - osxphotos 0.50.10 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/copybutton.css" />
@@ -122,7 +122,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">osxphotos 0.50.9 documentation</div></a>
<a href="index.html"><div class="brand">osxphotos 0.50.10 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.50.9 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.50.10 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">
@@ -939,6 +939,13 @@
<li><a href="cli.html#cmdoption-osxphotos-places-json">osxphotos-places command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-query-json">osxphotos-query command line option</a>
</li>
</ul></li>
<li>
--keep
<ul>
<li><a href="cli.html#cmdoption-osxphotos-export-keep">osxphotos-export command line option</a>
</li>
</ul></li>
<li>
@@ -3122,6 +3129,8 @@
<li><a href="cli.html#cmdoption-osxphotos-export-jpeg-ext">--jpeg-ext</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-export-jpeg-quality">--jpeg-quality</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-export-keep">--keep</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-export-keyword">--keyword</a>
</li>

View File

@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="OSXPhotos" href="overview.html" />
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/>
<title>osxphotos 0.50.9 documentation</title>
<title>osxphotos 0.50.10 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/copybutton.css" />
@@ -124,7 +124,7 @@
</label>
</div>
<div class="header-center">
<a href="#"><div class="brand">osxphotos 0.50.9 documentation</div></a>
<a href="#"><div class="brand">osxphotos 0.50.10 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.50.9 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.50.10 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">

Binary file not shown.

View File

@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="OSXPhotos Tutorial" href="tutorial.html" /><link rel="prev" title="Welcome to OSXPhotoss documentation!" href="index.html" />
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/>
<title>OSXPhotos - osxphotos 0.50.9 documentation</title>
<title>OSXPhotos - osxphotos 0.50.10 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/copybutton.css" />
@@ -124,7 +124,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">osxphotos 0.50.9 documentation</div></a>
<a href="index.html"><div class="brand">osxphotos 0.50.10 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.50.9 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.50.10 documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">

View File

@@ -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-4.4.0, furo 2022.04.07"/>
<title>OSXPhotos Python Package Overview - osxphotos 0.50.9 documentation</title>
<title>OSXPhotos Python Package Overview - osxphotos 0.50.10 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/copybutton.css" />
@@ -124,7 +124,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">osxphotos 0.50.9 documentation</div></a>
<a href="index.html"><div class="brand">osxphotos 0.50.10 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.50.9 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.50.10 documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">

View File

@@ -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-4.4.0, furo 2022.04.07"/><title>Python Module Index - osxphotos 0.50.9 documentation</title>
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/><title>Python Module Index - osxphotos 0.50.10 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/copybutton.css" />
@@ -122,7 +122,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">osxphotos 0.50.9 documentation</div></a>
<a href="index.html"><div class="brand">osxphotos 0.50.10 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.50.9 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.50.10 documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">

View File

@@ -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-4.4.0, furo 2022.04.07"/>
<title>OSXPhotos python API - osxphotos 0.50.9 documentation</title>
<title>OSXPhotos python API - osxphotos 0.50.10 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/copybutton.css" />
@@ -124,7 +124,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">osxphotos 0.50.9 documentation</div></a>
<a href="index.html"><div class="brand">osxphotos 0.50.10 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.50.9 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.50.10 documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">

View File

@@ -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-4.4.0, furo 2022.04.07"/><title>Search - osxphotos 0.50.9 documentation</title><link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/><title>Search - osxphotos 0.50.10 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/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.50.9 documentation</div></a>
<a href="index.html"><div class="brand">osxphotos 0.50.10 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.50.9 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.50.10 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

View File

@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="OSXPhotos Python Package Overview" href="package_overview.html" /><link rel="prev" title="OSXPhotos Command Line Interface (CLI)" href="cli.html" />
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/>
<title>OSXPhotos Template System - osxphotos 0.50.9 documentation</title>
<title>OSXPhotos Template System - osxphotos 0.50.10 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/copybutton.css" />
@@ -124,7 +124,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">osxphotos 0.50.9 documentation</div></a>
<a href="index.html"><div class="brand">osxphotos 0.50.10 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.50.9 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.50.10 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">
@@ -589,7 +589,7 @@
<td><p>a carriage return + line feed: rn</p></td>
</tr>
<tr class="row-even"><td><p>{osxphotos_version}</p></td>
<td><p>The osxphotos version, e.g. 0.50.9</p></td>
<td><p>The osxphotos version, e.g. 0.50.10</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>

View File

@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="OSXPhotos Command Line Interface (CLI)" href="cli.html" /><link rel="prev" title="OSXPhotos" href="overview.html" />
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/>
<title>OSXPhotos Tutorial - osxphotos 0.50.9 documentation</title>
<title>OSXPhotos Tutorial - osxphotos 0.50.10 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/copybutton.css" />
@@ -124,7 +124,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">osxphotos 0.50.9 documentation</div></a>
<a href="index.html"><div class="brand">osxphotos 0.50.10 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.50.9 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.50.10 documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">

View File

@@ -346,7 +346,7 @@ Template Substitutions
* - {crlf}
- a carriage return + line feed: '\r\n'
* - {osxphotos_version}
- The osxphotos version, e.g. '0.50.9'
- The osxphotos version, e.g. '0.50.10'
* - {osxphotos_cmd_line}
- The full command line used to run osxphotos
* - {album}

View File

@@ -1,3 +1,3 @@
""" version info """
__version__ = "0.50.9"
__version__ = "0.50.10"

View File

@@ -11,7 +11,7 @@ import shlex
import subprocess
import sys
import time
from typing import Dict
from typing import Iterable, List, Tuple
import click
import osxmetadata
@@ -546,6 +546,26 @@ from .verbose import get_verbose_console, time_stamp, verbose_print
"for example, your own scripts or other files. Be sure this is what you intend before using "
"--cleanup. Use --dry-run with --cleanup first if you're not certain.",
)
@click.option(
"--keep",
metavar="KEEP_PATH",
nargs=1,
multiple=True,
help="When used with --cleanup, prevents file or directory KEEP_PATH from being deleted "
"when cleanup is run. Use this if there are files in the export directory that you don't "
"want to be deleted when --cleanup is run. "
"KEEP_PATH may be a file path, e.g. '/Volumes/Photos/keep.jpg', "
"or a file path and wild card, e.g. '/Volumes/Photos/*.txt', "
"or a directory, e.g. '/Volumes/Photos/KeepMe'. "
"KEEP_PATH may be an absolute path or a relative path. "
"If it is relative, it must be relative to the export destination. "
"For example if export destination is `/Volumes/Photos` and you want to keep all `.txt` files, "
'you can specify `--keep "/Volumes/Photos/*.txt"` or `--keep "*.txt"`. '
"If wild card is used, KEEP_PATH must be enclosed in quotes to prevent the shell from expanding the wildcard, "
'e.g. `--keep "/Volumes/Photos/*.txt"`. '
"If KEEP_PATH is a directory, all files and directories contained in KEEP_PATH will be kept. "
"--keep may be repeated to keep additional files/directories.",
)
@click.option(
"--add-exported-to-album",
metavar="ALBUM",
@@ -757,6 +777,7 @@ def export(
is_reference,
jpeg_ext,
jpeg_quality,
keep,
keyword_template,
keyword,
label,
@@ -976,6 +997,7 @@ def export(
in_album = cfg.in_album
jpeg_ext = cfg.jpeg_ext
jpeg_quality = cfg.jpeg_quality
keep = (cfg.keep,)
keyword = cfg.keyword
keyword_template = cfg.keyword_template
label = cfg.label
@@ -1115,6 +1137,7 @@ def export(
("exiftool_option", ("exiftool")),
("ignore_signature", ("update", "force_update")),
("jpeg_quality", ("convert_to_jpeg")),
("keep", ("cleanup")),
("missing", ("download_missing", "use_photos_export")),
("only_new", ("update", "force_update")),
("append", ("report")),
@@ -1689,9 +1712,18 @@ def export(
+ [r[0] for r in results.error]
+ db_files
)
# if --report, add report file to keep list to prevent it from being deleted
if report:
all_files.append(report)
dirs_to_keep = []
if keep:
files_to_keep, dirs_to_keep = collect_files_to_keep(keep, dest)
all_files += files_to_keep
rich_echo(f"Cleaning up [filepath]{dest}")
cleaned_files, cleaned_dirs = cleanup_files(
dest, all_files, fileutil, verbose_=verbose_
dest, all_files, dirs_to_keep, fileutil, verbose_=verbose_
)
file_str = "files" if len(cleaned_files) != 1 else "file"
dir_str = "directories" if len(cleaned_dirs) != 1 else "directory"
@@ -2453,7 +2485,6 @@ def find_files_in_branch(pathname, filename):
# walk down the tree
for root, _, filenames in os.walk(pathname):
# for directory in directories:
# print(os.path.join(root, directory))
for fname in filenames:
if fname == filename and pathlib.Path(root) != pathname:
files.append(os.path.join(root, fname))
@@ -2470,14 +2501,43 @@ def find_files_in_branch(pathname, filename):
return files
def cleanup_files(dest_path, files_to_keep, fileutil, verbose_):
def collect_files_to_keep(
keep: Iterable[str], export_dir: str
) -> Tuple[List[str], List[str]]:
"""Collect all files to keep for --keep/--cleanup.
Args:
keep: Iterable of filepaths to keep; each path may be a filepath, a filepath/wildcard, or a directory path.
export_dir: the export directory which will be used to resolve paths when paths in keep are relative instead of absolute
Returns:
tuple of [files_to_keep], [dirs_to_keep]
"""
export_dir = pathlib.Path(export_dir)
keepers = []
for k in keep:
keeper = pathlib.Path(k).expanduser()
if not keeper.is_absolute():
# relative path: relative to export_dir
keeper = export_dir / keeper
if keeper.is_dir():
keepers.extend(keeper.glob("**/*"))
keepers.extend(keeper.parent.glob(keeper.name))
files_to_keep = [str(k) for k in keepers if k.is_file()]
dirs_to_keep = [str(k) for k in keepers if k.is_dir()]
return files_to_keep, dirs_to_keep
def cleanup_files(dest_path, files_to_keep, dirs_to_keep, fileutil, verbose_):
"""cleanup dest_path by deleting and files and empty directories
not in files_to_keep
Args:
dest_path: path to directory to clean
files_to_keep: list of full file paths to keep (not delete)
fileutile: FileUtil object
dirs_to_keep: list of full dir paths to keep (not delete if they are empty)
fileutil: FileUtil object
verbose_: verbose callable for printing verbose output
Returns:
tuple of (list of files deleted, list of directories deleted)
@@ -2497,6 +2557,8 @@ def cleanup_files(dest_path, files_to_keep, fileutil, verbose_):
deleted_dirs = []
# walk directory tree bottom up and verify contents are empty
for dirpath, _, _ in os.walk(dest_path, topdown=False):
if dirpath in dirs_to_keep:
continue
if not list(pathlib.Path(dirpath).glob("*")):
# directory and directory is empty
verbose_(f"Deleting empty directory {dirpath}")

Binary file not shown.

View File

@@ -5913,6 +5913,35 @@ def test_export_cleanup():
assert not pathlib.Path("./foo/delete_me_too.txt").is_file()
def test_export_cleanup_report():
"""test export with --cleanup flag with --report in the export dir (#739)"""
runner = CliRunner()
cwd = os.getcwd()
# pylint: disable=not-context-manager
with runner.isolated_filesystem():
result = runner.invoke(export, [os.path.join(cwd, CLI_PHOTOS_DB), ".", "-V"])
assert result.exit_code == 0
tmpdir = os.getcwd()
# run cleanup without dry-run
result = runner.invoke(
export,
[
os.path.join(cwd, CLI_PHOTOS_DB),
".",
"-V",
"--update",
"--cleanup",
"--report",
f"{tmpdir}/report.db",
],
)
assert "Deleted: 0 files, 0 directories" in result.output
assert pathlib.Path("./report.db").is_file()
def test_export_cleanup_empty_album():
"""test export with --cleanup flag with an empty album (#481)"""
@@ -6055,6 +6084,165 @@ def test_export_cleanup_exiftool_accented_album_name_same_filenames():
assert "Deleted: 0 files, 0 directories" in result.output
def test_export_cleanup_keep():
"""test export with --cleanup --keep options"""
runner = CliRunner()
cwd = os.getcwd()
# pylint: disable=not-context-manager
with runner.isolated_filesystem():
tmpdir = os.getcwd()
result = runner.invoke(export, [os.path.join(cwd, CLI_PHOTOS_DB), ".", "-V"])
assert result.exit_code == 0
# create file and a directory that should be deleted
os.mkdir("./empty_dir")
os.mkdir("./delete_me_dir")
with open("./delete_me.txt", "w") as fd:
fd.write("delete me!")
with open("./delete_me_dir/delete_me.txt", "w") as fd:
fd.write("delete me!")
# create files and directories that should be kept
os.mkdir("./keep_me")
os.mkdir("./keep_me/keep_me_2")
with open("./keep_me.txt", "w") as fd:
fd.write("keep me!")
with open("./report.db", "w") as fd:
fd.write("keep me!")
with open("./keep_me/keep_me.txt", "w") as fd:
fd.write("keep me")
# run cleanup with dry-run
result = runner.invoke(
export,
[
os.path.join(cwd, CLI_PHOTOS_DB),
".",
"-V",
"--update",
"--cleanup",
"--keep",
f"{tmpdir}/keep_me",
"--keep",
f"{tmpdir}/keep_me.txt",
"--keep",
f"{tmpdir}/*.db",
"--dry-run",
],
)
assert "Deleted: 2 files, 1 directory" in result.output
assert pathlib.Path("./delete_me.txt").is_file()
assert pathlib.Path("./delete_me_dir/delete_me.txt").is_file()
assert pathlib.Path("./empty_dir").is_dir()
# run cleanup without dry-run
result = runner.invoke(
export,
[
os.path.join(cwd, CLI_PHOTOS_DB),
".",
"-V",
"--update",
"--cleanup",
"--keep",
f"{tmpdir}/keep_me",
"--keep",
f"{tmpdir}/keep_me.txt",
"--keep",
f"{tmpdir}/*.db",
],
)
assert "Deleted: 2 files, 2 directories" in result.output
assert not pathlib.Path("./delete_me.txt").is_file()
assert not pathlib.Path("./delete_me_dir/delete_me_too.txt").is_file()
assert not pathlib.Path("./empty_dir").is_dir()
assert pathlib.Path("./keep_me.txt").is_file()
assert pathlib.Path("./keep_me").is_dir()
assert pathlib.Path("./keep_me/keep_me.txt").is_file()
assert pathlib.Path("./keep_me/keep_me_2").is_dir()
assert pathlib.Path("./report.db").is_file()
def test_export_cleanup_keep_relative_path():
"""test export with --cleanup --keep options with relative paths"""
runner = CliRunner()
cwd = os.getcwd()
# pylint: disable=not-context-manager
with runner.isolated_filesystem():
result = runner.invoke(export, [os.path.join(cwd, CLI_PHOTOS_DB), ".", "-V"])
assert result.exit_code == 0
# create file and a directory that should be deleted
os.mkdir("./empty_dir")
os.mkdir("./delete_me_dir")
with open("./delete_me.txt", "w") as fd:
fd.write("delete me!")
with open("./delete_me_dir/delete_me.txt", "w") as fd:
fd.write("delete me!")
# create files and directories that should be kept
os.mkdir("./keep_me")
os.mkdir("./keep_me/keep_me_2")
with open("./keep_me.txt", "w") as fd:
fd.write("keep me!")
with open("./report.db", "w") as fd:
fd.write("keep me!")
with open("./keep_me/keep_me.txt", "w") as fd:
fd.write("keep me")
# run cleanup with dry-run
result = runner.invoke(
export,
[
os.path.join(cwd, CLI_PHOTOS_DB),
".",
"-V",
"--update",
"--cleanup",
"--keep",
"keep_me",
"--keep",
"keep_me.txt",
"--keep",
"*.db",
"--dry-run",
],
)
assert "Deleted: 2 files, 1 directory" in result.output
assert pathlib.Path("./delete_me.txt").is_file()
assert pathlib.Path("./delete_me_dir/delete_me.txt").is_file()
assert pathlib.Path("./empty_dir").is_dir()
# run cleanup without dry-run
result = runner.invoke(
export,
[
os.path.join(cwd, CLI_PHOTOS_DB),
".",
"-V",
"--update",
"--cleanup",
"--keep",
"keep_me",
"--keep",
"keep_me.txt",
"--keep",
"*.db",
],
)
assert "Deleted: 2 files, 2 directories" in result.output
assert not pathlib.Path("./delete_me.txt").is_file()
assert not pathlib.Path("./delete_me_dir/delete_me_too.txt").is_file()
assert not pathlib.Path("./empty_dir").is_dir()
assert pathlib.Path("./keep_me.txt").is_file()
assert pathlib.Path("./keep_me").is_dir()
assert pathlib.Path("./keep_me/keep_me.txt").is_file()
assert pathlib.Path("./keep_me/keep_me_2").is_dir()
assert pathlib.Path("./report.db").is_file()
def test_save_load_config():
"""test --save-config, --load-config"""