Added retry to export_db for #674
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -396,7 +396,7 @@ If called in context manager, returns True (execution is delayed until exiting c
|
|||||||
<dt class="sig sig-object py" id="osxphotos.ExportDB.get_file_record">
|
<dt class="sig sig-object py" id="osxphotos.ExportDB.get_file_record">
|
||||||
<span class="sig-name descname"><span class="pre">get_file_record</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">filename</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">Union</span><span class="p"><span class="pre">[</span></span><span class="pre">pathlib.Path</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">str</span><span class="p"><span class="pre">]</span></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">osxphotos.export_db.ExportRecord</span></span></span><a class="reference internal" href="_modules/osxphotos/export_db.html#ExportDB.get_file_record"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#osxphotos.ExportDB.get_file_record" title="Permalink to this definition">#</a></dt>
|
<span class="sig-name descname"><span class="pre">get_file_record</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">filename</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">Union</span><span class="p"><span class="pre">[</span></span><span class="pre">pathlib.Path</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">str</span><span class="p"><span class="pre">]</span></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">osxphotos.export_db.ExportRecord</span></span></span><a class="reference internal" href="_modules/osxphotos/export_db.html#ExportDB.get_file_record"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#osxphotos.ExportDB.get_file_record" title="Permalink to this definition">#</a></dt>
|
||||||
<dd><p>get info for filename and uuid</p>
|
<dd><p>get info for filename and uuid</p>
|
||||||
<p>Returns: an ExportRecord object</p>
|
<p>Returns: an ExportRecord object or None if filename not found</p>
|
||||||
</dd></dl>
|
</dd></dl>
|
||||||
<dl class="py method">
|
<dl class="py method">
|
||||||
<dt class="sig sig-object py" id="osxphotos.ExportDB.get_photoinfo_for_uuid">
|
<dt class="sig sig-object py" id="osxphotos.ExportDB.get_photoinfo_for_uuid">
|
||||||
|
|||||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
|||||||
""" Helper class for managing database used by PhotoExporter for tracking state of exports and updates """
|
""" Helper class for managing database used by PhotoExporter for tracking state of exports and updates """
|
||||||
|
|
||||||
|
|
||||||
|
import contextlib
|
||||||
import datetime
|
import datetime
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
@@ -13,6 +14,8 @@ from sqlite3 import Error
|
|||||||
from tempfile import TemporaryDirectory
|
from tempfile import TemporaryDirectory
|
||||||
from typing import Optional, Tuple, Union
|
from typing import Optional, Tuple, Union
|
||||||
|
|
||||||
|
from tenacity import retry, stop_after_attempt
|
||||||
|
|
||||||
from ._constants import OSXPHOTOS_EXPORT_DB
|
from ._constants import OSXPHOTOS_EXPORT_DB
|
||||||
from ._version import __version__
|
from ._version import __version__
|
||||||
from .fileutil import FileUtil
|
from .fileutil import FileUtil
|
||||||
@@ -27,6 +30,9 @@ __all__ = [
|
|||||||
OSXPHOTOS_EXPORTDB_VERSION = "6.0"
|
OSXPHOTOS_EXPORTDB_VERSION = "6.0"
|
||||||
OSXPHOTOS_ABOUT_STRING = f"Created by osxphotos version {__version__} (https://github.com/RhetTbull/osxphotos) on {datetime.datetime.now()}"
|
OSXPHOTOS_ABOUT_STRING = f"Created by osxphotos version {__version__} (https://github.com/RhetTbull/osxphotos) on {datetime.datetime.now()}"
|
||||||
|
|
||||||
|
# max retry attempts for methods which use tenacity.retry
|
||||||
|
MAX_RETRY_ATTEMPTS = 5
|
||||||
|
|
||||||
|
|
||||||
class ExportDB:
|
class ExportDB:
|
||||||
"""Interface to sqlite3 database used to store state information for osxphotos export command"""
|
"""Interface to sqlite3 database used to store state information for osxphotos export command"""
|
||||||
@@ -63,20 +69,19 @@ class ExportDB:
|
|||||||
def get_file_record(self, filename: Union[pathlib.Path, str]) -> "ExportRecord":
|
def get_file_record(self, filename: Union[pathlib.Path, str]) -> "ExportRecord":
|
||||||
"""get info for filename and uuid
|
"""get info for filename and uuid
|
||||||
|
|
||||||
Returns: an ExportRecord object
|
Returns: an ExportRecord object or None if filename not found
|
||||||
"""
|
"""
|
||||||
filename = self._relative_filepath(filename)
|
filename = self._relative_filepath(filename)
|
||||||
filename_normalized = self._normalize_filepath(filename)
|
filename_normalized = self._normalize_filepath(filename)
|
||||||
conn = self._conn
|
conn = self._conn
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
row = c.execute(
|
|
||||||
|
if _ := c.execute(
|
||||||
"SELECT uuid FROM export_data WHERE filepath_normalized = ?;",
|
"SELECT uuid FROM export_data WHERE filepath_normalized = ?;",
|
||||||
(filename_normalized,),
|
(filename_normalized,),
|
||||||
).fetchone()
|
).fetchone():
|
||||||
|
return ExportRecord(conn, filename_normalized)
|
||||||
if not row:
|
return None
|
||||||
return None
|
|
||||||
return ExportRecord(conn, filename_normalized)
|
|
||||||
|
|
||||||
def create_file_record(
|
def create_file_record(
|
||||||
self, filename: Union[pathlib.Path, str], uuid: str
|
self, filename: Union[pathlib.Path, str], uuid: str
|
||||||
@@ -362,13 +367,11 @@ class ExportDB:
|
|||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
"""ensure the database connection is closed"""
|
"""ensure the database connection is closed"""
|
||||||
try:
|
with contextlib.suppress(Exception):
|
||||||
self._conn.close()
|
self._conn.close()
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _insert_run_info(self):
|
def _insert_run_info(self):
|
||||||
dt = datetime.datetime.utcnow().isoformat()
|
dt = datetime.datetime.now(datetime.timezone.utc).isoformat()
|
||||||
python_path = sys.executable
|
python_path = sys.executable
|
||||||
cmd = sys.argv[0]
|
cmd = sys.argv[0]
|
||||||
args = " ".join(sys.argv[1:]) if len(sys.argv) > 1 else ""
|
args = " ".join(sys.argv[1:]) if len(sys.argv) > 1 else ""
|
||||||
@@ -593,6 +596,7 @@ class ExportDBInMemory(ExportDB):
|
|||||||
self._conn = self._open_export_db(self._dbfile)
|
self._conn = self._open_export_db(self._dbfile)
|
||||||
self._insert_run_info()
|
self._insert_run_info()
|
||||||
|
|
||||||
|
@retry(stop=stop_after_attempt(MAX_RETRY_ATTEMPTS))
|
||||||
def write_to_disk(self):
|
def write_to_disk(self):
|
||||||
"""Write changes from in-memory database back to disk"""
|
"""Write changes from in-memory database back to disk"""
|
||||||
|
|
||||||
@@ -677,10 +681,8 @@ class ExportDBInMemory(ExportDB):
|
|||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
"""close the database connection"""
|
"""close the database connection"""
|
||||||
try:
|
with contextlib.suppress(Error):
|
||||||
self.close()
|
self.close()
|
||||||
except Error as e:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class ExportDBTemp(ExportDBInMemory):
|
class ExportDBTemp(ExportDBInMemory):
|
||||||
@@ -720,11 +722,10 @@ class ExportRecord:
|
|||||||
"""return filepath"""
|
"""return filepath"""
|
||||||
conn = self._conn
|
conn = self._conn
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
row = c.execute(
|
if row := c.execute(
|
||||||
"SELECT filepath FROM export_data WHERE filepath_normalized = ?;",
|
"SELECT filepath FROM export_data WHERE filepath_normalized = ?;",
|
||||||
(self._filepath_normalized,),
|
(self._filepath_normalized,),
|
||||||
).fetchone()
|
).fetchone():
|
||||||
if row:
|
|
||||||
return row[0]
|
return row[0]
|
||||||
|
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
@@ -741,11 +742,10 @@ class ExportRecord:
|
|||||||
"""return uuid"""
|
"""return uuid"""
|
||||||
conn = self._conn
|
conn = self._conn
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
row = c.execute(
|
if row := c.execute(
|
||||||
"SELECT uuid FROM export_data WHERE filepath_normalized = ?;",
|
"SELECT uuid FROM export_data WHERE filepath_normalized = ?;",
|
||||||
(self._filepath_normalized,),
|
(self._filepath_normalized,),
|
||||||
).fetchone()
|
).fetchone():
|
||||||
if row:
|
|
||||||
return row[0]
|
return row[0]
|
||||||
|
|
||||||
raise ValueError(f"No uuid found in database for {self._filepath_normalized}")
|
raise ValueError(f"No uuid found in database for {self._filepath_normalized}")
|
||||||
@@ -755,11 +755,10 @@ class ExportRecord:
|
|||||||
"""returns the digest value"""
|
"""returns the digest value"""
|
||||||
conn = self._conn
|
conn = self._conn
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
row = c.execute(
|
if row := c.execute(
|
||||||
"SELECT digest FROM export_data WHERE filepath_normalized = ?;",
|
"SELECT digest FROM export_data WHERE filepath_normalized = ?;",
|
||||||
(self._filepath_normalized,),
|
(self._filepath_normalized,),
|
||||||
).fetchone()
|
).fetchone():
|
||||||
if row:
|
|
||||||
return row[0]
|
return row[0]
|
||||||
|
|
||||||
raise ValueError(f"No digest found in database for {self._filepath_normalized}")
|
raise ValueError(f"No digest found in database for {self._filepath_normalized}")
|
||||||
@@ -781,11 +780,10 @@ class ExportRecord:
|
|||||||
"""returns exifdata value for record"""
|
"""returns exifdata value for record"""
|
||||||
conn = self._conn
|
conn = self._conn
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
row = c.execute(
|
if row := c.execute(
|
||||||
"SELECT exifdata FROM export_data WHERE filepath_normalized = ?;",
|
"SELECT exifdata FROM export_data WHERE filepath_normalized = ?;",
|
||||||
(self._filepath_normalized,),
|
(self._filepath_normalized,),
|
||||||
).fetchone()
|
).fetchone():
|
||||||
if row:
|
|
||||||
return row[0]
|
return row[0]
|
||||||
|
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
@@ -812,11 +810,10 @@ class ExportRecord:
|
|||||||
"""return source file signature value"""
|
"""return source file signature value"""
|
||||||
conn = self._conn
|
conn = self._conn
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
row = c.execute(
|
if row := c.execute(
|
||||||
"SELECT src_mode, src_size, src_mtime FROM export_data WHERE filepath_normalized = ?;",
|
"SELECT src_mode, src_size, src_mtime FROM export_data WHERE filepath_normalized = ?;",
|
||||||
(self._filepath_normalized,),
|
(self._filepath_normalized,),
|
||||||
).fetchone()
|
).fetchone():
|
||||||
if row:
|
|
||||||
mtime = int(row[2]) if row[2] is not None else None
|
mtime = int(row[2]) if row[2] is not None else None
|
||||||
return (row[0], row[1], mtime)
|
return (row[0], row[1], mtime)
|
||||||
|
|
||||||
@@ -846,11 +843,10 @@ class ExportRecord:
|
|||||||
"""return destination file signature"""
|
"""return destination file signature"""
|
||||||
conn = self._conn
|
conn = self._conn
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
row = c.execute(
|
if row := c.execute(
|
||||||
"SELECT dest_mode, dest_size, dest_mtime FROM export_data WHERE filepath_normalized = ?;",
|
"SELECT dest_mode, dest_size, dest_mtime FROM export_data WHERE filepath_normalized = ?;",
|
||||||
(self._filepath_normalized,),
|
(self._filepath_normalized,),
|
||||||
).fetchone()
|
).fetchone():
|
||||||
if row:
|
|
||||||
mtime = int(row[2]) if row[2] is not None else None
|
mtime = int(row[2]) if row[2] is not None else None
|
||||||
return (row[0], row[1], mtime)
|
return (row[0], row[1], mtime)
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ PyYAML>=5.4.1,<6.0.0
|
|||||||
requests>=2.27.1,<3.0.0
|
requests>=2.27.1,<3.0.0
|
||||||
rich>=11.2.0,<13.0.0
|
rich>=11.2.0,<13.0.0
|
||||||
rich_theme_manager>=0.7.0
|
rich_theme_manager>=0.7.0
|
||||||
|
tenacity>=8.0.1,<9.0.0
|
||||||
textx>=2.3.0,<2.4.0
|
textx>=2.3.0,<2.4.0
|
||||||
toml>=0.10.2,<0.11.0
|
toml>=0.10.2,<0.11.0
|
||||||
wrapt>=1.13.3,<1.14.0
|
wrapt>=1.13.3,<1.14.0
|
||||||
|
|||||||
1
setup.py
1
setup.py
@@ -98,6 +98,7 @@ setup(
|
|||||||
"requests>=2.27.1,<3.0.0",
|
"requests>=2.27.1,<3.0.0",
|
||||||
"rich>=11.2.0,<13.0.0",
|
"rich>=11.2.0,<13.0.0",
|
||||||
"rich_theme_manager>=0.7.0",
|
"rich_theme_manager>=0.7.0",
|
||||||
|
"tenacity>=8.0.1,<9.0.0",
|
||||||
"textx>=2.3.0,<3.0.0",
|
"textx>=2.3.0,<3.0.0",
|
||||||
"toml>=0.10.2,<0.11.0",
|
"toml>=0.10.2,<0.11.0",
|
||||||
"wrapt>=1.13.3,<1.14.0",
|
"wrapt>=1.13.3,<1.14.0",
|
||||||
|
|||||||
Reference in New Issue
Block a user