summaryrefslogtreecommitdiff
path: root/raphodo/renameandmovefile.py
diff options
context:
space:
mode:
authorAntoine Beaupré <anarcat@debian.org>2018-03-14 12:24:17 -0400
committerAntoine Beaupré <anarcat@debian.org>2018-03-14 12:24:17 -0400
commit0a297829eaf3912c939e1b43a3ef6ddeb7607b38 (patch)
tree51733e0d6ffb00f0f7dfe01dccd48b2a598e5153 /raphodo/renameandmovefile.py
parent88c8bd4cd2ee4707f8a43be4d89c4e040dcced2f (diff)
New upstream version 0.9.9upstream/0.9.9
Diffstat (limited to 'raphodo/renameandmovefile.py')
-rwxr-xr-xraphodo/renameandmovefile.py163
1 files changed, 110 insertions, 53 deletions
diff --git a/raphodo/renameandmovefile.py b/raphodo/renameandmovefile.py
index 1405cc5..3dd59b1 100755
--- a/raphodo/renameandmovefile.py
+++ b/raphodo/renameandmovefile.py
@@ -44,7 +44,6 @@ from gettext import gettext as _
import raphodo.exiftool as exiftool
import raphodo.generatename as gn
-import raphodo.problemnotification as pn
from raphodo.preferences import DownloadsTodayTracker, Preferences
from raphodo.constants import (ConflictResolution, FileType, DownloadStatus, RenameAndMoveStatus)
from raphodo.interprocess import (RenameAndMoveFileData, RenameAndMoveFileResults, DaemonProcess)
@@ -126,14 +125,19 @@ class SyncRawJpeg:
Returns SyncRawJpegStatus.no_match and a sequence number
of None if no match
"""
+
if name in self.photos:
if datetime_roughly_equal(self.photos[name].date_time, date_time, 30):
if extension in self.photos[name].extension:
- return SyncRawJpegMatch(SyncRawJpegStatus.error_already_downloaded,
- self.photos[name].sequence_number_used)
+ return SyncRawJpegMatch(
+ SyncRawJpegStatus.error_already_downloaded,
+ self.photos[name].sequence_number_used
+ )
else:
- return SyncRawJpegMatch(SyncRawJpegStatus.matching_pair,
- self.photos[name].sequence_number_used)
+ return SyncRawJpegMatch(
+ SyncRawJpegStatus.matching_pair,
+ self.photos[name].sequence_number_used
+ )
else:
return SyncRawJpegMatch(SyncRawJpegStatus.error_datetime_mismatch, None)
return SyncRawJpegMatch(SyncRawJpegStatus.no_match, None)
@@ -153,10 +157,9 @@ def load_metadata(rpd_file: Union[Photo, Video],
"""
Loads the metadata for the file.
+ :param rpd_file: photo or video
:param et_process: the daemon ExifTool process
- :param temp_file: If true, the the metadata from the temporary file
- rather than the original source file is used. This is important,
- because the metadata can be modified by the filemodify process
+ :param problems: problems encountered renaming the file
:return True if operation succeeded, false otherwise
"""
if rpd_file.metadata is None:
@@ -171,8 +174,8 @@ def load_metadata(rpd_file: Union[Photo, Video],
return True
-def _generate_name(generator: Union[gn.PhotoName, gn.PhotoSubfolder, gn.VideoName,
- gn.VideoSubfolder],
+def _generate_name(generator: Union[gn.PhotoName, gn.PhotoSubfolder, gn.VideoName,
+ gn.VideoSubfolder],
rpd_file: Union[Photo, Video],
et_process: exiftool.ExifTool,
problems: RenamingProblems) -> str:
@@ -205,6 +208,7 @@ def generate_subfolder(rpd_file: Union[Photo, Video],
:param rpd_file: file to work on
:param et_process: the daemon ExifTool process
+ :param problems: problems encountered renaming the file
"""
if rpd_file.file_type == FileType.photo:
@@ -223,12 +227,13 @@ def generate_name(rpd_file: Union[Photo, Video],
:param rpd_file: file to work on
:param et_process: the daemon ExifTool process
+ :param problems: problems encountered renaming the file
"""
if rpd_file.file_type == FileType.photo:
- generator = gn.PhotoName(rpd_file.name_pref_list, problems=problems)
+ generator = gn.PhotoName(pref_list=rpd_file.name_pref_list, problems=problems)
else:
- generator = gn.VideoName(rpd_file.name_pref_list, problems=problems)
+ generator = gn.VideoName(pref_list=rpd_file.name_pref_list, problems=problems)
rpd_file.download_name = _generate_name(generator, rpd_file, et_process, problems)
@@ -268,9 +273,11 @@ class RenameMoveFileWorker(DaemonProcess):
dt = datetime.fromtimestamp(modification_time)
date = dt.strftime("%x")
time = dt.strftime("%X")
- except:
- logging.error("Could not determine the file modification time of %s",
- rpd_file.download_full_file_name)
+ except Exception:
+ logging.error(
+ "Could not determine the file modification time of %s",
+ rpd_file.download_full_file_name
+ )
date = time = ''
source = rpd_file.get_souce_href()
@@ -312,7 +319,7 @@ class RenameMoveFileWorker(DaemonProcess):
"""
Handle cases where file failed to download
"""
- uri=get_uri(
+ uri = get_uri(
full_file_name=rpd_file.full_file_name, camera_details=rpd_file.camera_details
)
device = make_href(name=rpd_file.device_display_name, uri=rpd_file.device_uri)
@@ -365,7 +372,7 @@ class RenameMoveFileWorker(DaemonProcess):
assert isinstance(i1_date_time, datetime)
i1_date = i1_date_time.strftime("%x")
i1_time = i1_date_time.strftime("%X")
- assert isinstance(image2_date_time,datetime)
+ assert isinstance(image2_date_time, datetime)
image2_date = image2_date_time.strftime("%x")
image2_time = image2_date_time.strftime("%X")
@@ -383,7 +390,7 @@ class RenameMoveFileWorker(DaemonProcess):
def _move_associate_file(self, extension: str,
full_base_name: str,
- temp_associate_file: str) -> str:
+ temp_associate_file: str) -> str:
"""
Move (rename) the associate file using the pre-generated name.
@@ -617,7 +624,8 @@ class RenameMoveFileWorker(DaemonProcess):
else:
matching_pair = self.sync_raw_jpeg.matching_pair(
name=photo_name, extension=photo_ext,
- date_time=date_time) # type: SyncRawJpegMatch
+ date_time=date_time
+ ) # type: SyncRawJpegMatch
sequence_to_use = matching_pair.sequence_number
if matching_pair.status == SyncRawJpegStatus.error_already_downloaded:
# this exact file has already been
@@ -628,16 +636,19 @@ class RenameMoveFileWorker(DaemonProcess):
DuplicateFileWhenSyncingProblem(
name=rpd_file.name,
uri=rpd_file.get_uri(),
- file_type = rpd_file.title,
+ file_type=rpd_file.title,
)
)
rpd_file.status = DownloadStatus.download_failed
failed = True
else:
- self.sequences.set_matched_sequence_value(matching_pair.sequence_number)
+ self.sequences.matched_sequences = matching_pair.sequence_number
+ self.sequences.use_matched_sequences = self.sequences.matched_sequences is \
+ not None
if matching_pair.status == SyncRawJpegStatus.error_datetime_mismatch:
self.same_name_different_exif(photo_name, rpd_file)
+
return SyncRawJpegResult(sequence_to_use, failed, photo_name, photo_ext)
def prepare_rpd_file(self, rpd_file: Union[Photo, Video]) -> None:
@@ -661,7 +672,7 @@ class RenameMoveFileWorker(DaemonProcess):
except OSError:
logging.error("Failed to delete temporary file %s", rpd_file.temp_full_file_name)
- def generate_names(self, rpd_file: Union[Photo, Video]) -> bool:
+ def generate_names(self, rpd_file: Union[Photo, Video], synchronize_raw_jpg: bool) -> bool:
rpd_file.strip_characters = self.prefs.strip_characters
@@ -672,18 +683,24 @@ class RenameMoveFileWorker(DaemonProcess):
rpd_file.download_subfolder, rpd_file.name)
self.sequences.stored_sequence_no = self.prefs.stored_sequence_no
+ if self.must_synchronize_raw_jpg and rpd_file.file_type == FileType.video:
+ self.sequences.use_matched_sequences = False
+
rpd_file.sequences = self.sequences
# generate the file name
generate_name(rpd_file, self.exiftool_process, self.problems)
if rpd_file.name_generation_problem:
- logging.warning("Encountered a problem generating file name for file %s",
- rpd_file.name)
+ logging.warning(
+ "Encountered a problem generating file name for file %s",
+ rpd_file.name
+ )
rpd_file.status = DownloadStatus.downloaded_with_warning
else:
- logging.debug("Generated file name %s for file %s", rpd_file.download_name,
- rpd_file.name)
+ logging.debug(
+ "Generated file name %s for file %s", rpd_file.download_name, rpd_file.name
+ )
else:
logging.error("Failed to generate subfolder name for file: %s", rpd_file.name)
@@ -700,8 +717,9 @@ class RenameMoveFileWorker(DaemonProcess):
move_succeeded = False
rpd_file.download_path = os.path.join(rpd_file.download_folder, rpd_file.download_subfolder)
- rpd_file.download_full_file_name = os.path.join(rpd_file.download_path,
- rpd_file.download_name)
+ rpd_file.download_full_file_name = os.path.join(
+ rpd_file.download_path, rpd_file.download_name
+ )
rpd_file.download_full_base_name = os.path.splitext(rpd_file.download_full_file_name)[0]
if not os.path.isdir(rpd_file.download_path):
@@ -727,8 +745,10 @@ class RenameMoveFileWorker(DaemonProcess):
try:
if os.path.exists(rpd_file.download_full_file_name):
raise OSError(errno.EEXIST, "File exists: %s" % rpd_file.download_full_file_name)
- logging.debug("Renaming %s to %s .....",
- rpd_file.temp_full_file_name, rpd_file.download_full_file_name)
+ logging.debug(
+ "Renaming %s to %s .....",
+ rpd_file.temp_full_file_name, rpd_file.download_full_file_name
+ )
os.rename(rpd_file.temp_full_file_name, rpd_file.download_full_file_name)
logging.debug("....successfully renamed file")
move_succeeded = True
@@ -749,19 +769,26 @@ class RenameMoveFileWorker(DaemonProcess):
return move_succeeded
def process_file(self, rpd_file: Union[Photo, Video], download_count: int) -> bool:
+ """
+ Generate file & subfolder name, and move (rename) photo / video
+ :param rpd_file: photo or video
+ :param download_count: used to track the file being downloaded via a counter
+ :return: success or otherwise of operation
+ """
+
move_succeeded = False
self.prepare_rpd_file(rpd_file)
- synchronize_raw_jpg = (self.prefs.must_synchronize_raw_jpg() and
- rpd_file.file_type == FileType.photo)
+ synchronize_raw_jpg = self.must_synchronize_raw_jpg and rpd_file.file_type == FileType.photo
+
if synchronize_raw_jpg:
sync_result = self.sync_raw_jpg(rpd_file)
if sync_result.failed:
return False
- generation_succeeded = self.generate_names(rpd_file)
+ generation_succeeded = self.generate_names(rpd_file, synchronize_raw_jpg)
if generation_succeeded:
move_succeeded = self.move_file(rpd_file)
@@ -782,11 +809,12 @@ class RenameMoveFileWorker(DaemonProcess):
if not synchronize_raw_jpg or (synchronize_raw_jpg and
sync_result.sequence_to_use is None):
- uses_sequence_session_no = self.prefs.any_pref_uses_session_sequence_no()
- uses_sequence_letter = self.prefs.any_pref_uses_sequence_letter_value()
- if uses_sequence_session_no or uses_sequence_letter:
- self.sequences.increment(uses_sequence_session_no, uses_sequence_letter)
- if self.prefs.any_pref_uses_stored_sequence_no():
+
+ if self.uses_sequence_session_no or self.uses_sequence_letter:
+ self.sequences.increment(
+ self.uses_sequence_session_no, self.uses_sequence_letter
+ )
+ if self.uses_stored_sequence_no:
if self.prefs.stored_sequence_no == self.platform_c_maxint:
# wrap value if it exceeds the maximum size value that Qt can display
# in its spinbox
@@ -809,6 +837,32 @@ class RenameMoveFileWorker(DaemonProcess):
return move_succeeded
+ def initialise_downloads_today_stored_number(self) -> None:
+ """
+ Initialize (or reinitialize) Downloads Today and Stored No
+ sequence values from the program preferences.
+ """
+
+ # Synchronize QSettings instance in preferences class
+ self.prefs.sync()
+
+ # Track downloads today, using a class whose purpose is to
+ # take the value in the user prefs, increment, and then
+ # finally used to update the prefs
+ self.downloads_today_tracker = DownloadsTodayTracker(
+ day_start=self.prefs.day_start,
+ downloads_today=self.prefs.downloads_today
+ )
+
+ def initialise_sequence_number_usage(self) -> None:
+ """
+ Determine what type of sequence numbers are being used in file name generation
+ """
+
+ self.uses_sequence_session_no = self.prefs.any_pref_uses_session_sequence_no()
+ self.uses_sequence_letter = self.prefs.any_pref_uses_sequence_letter_value()
+ self.uses_stored_sequence_no = self.prefs.any_pref_uses_stored_sequence_no()
+
def run(self) -> None:
"""
Generate subfolder and filename, and attempt to move the file
@@ -826,6 +880,12 @@ class RenameMoveFileWorker(DaemonProcess):
# suffixes to duplicate files
self.duplicate_files = {}
+ self.initialise_downloads_today_stored_number()
+
+ self.sequences = gn.Sequences(
+ self.downloads_today_tracker, self.prefs.stored_sequence_no
+ )
+
with stdchannel_redirected(sys.stderr, os.devnull):
with exiftool.ExifTool() as self.exiftool_process:
while True:
@@ -839,29 +899,26 @@ class RenameMoveFileWorker(DaemonProcess):
data = pickle.loads(content) # type: RenameAndMoveFileData
if data.message == RenameAndMoveStatus.download_started:
- # Synchronize QSettings instance in preferences class
- self.prefs.sync()
-
- # Track downloads today, using a class whose purpose is to
- # take the value in the user prefs, increment, and then
- # finally used to update the prefs
- self.downloads_today_tracker = DownloadsTodayTracker(
- day_start=self.prefs.day_start,
- downloads_today=self.prefs.downloads_today)
-
- self.sequences = gn.Sequences(self.downloads_today_tracker,
- self.prefs.stored_sequence_no)
+
+ # reinitialize downloads today and stored sequence number
+ # in case the user has updated them via the user interface
+ self.initialise_downloads_today_stored_number()
+ self.sequences.downloads_today_tracker = self.downloads_today_tracker
+ self.sequences.stored_sequence_no = self.prefs.stored_sequence_no
+
dl_today = self.downloads_today_tracker.get_or_reset_downloads_today()
logging.debug("Completed downloads today: %s", dl_today)
+ self.initialise_sequence_number_usage()
+
+ self.must_synchronize_raw_jpg = self.prefs.must_synchronize_raw_jpg()
+
self.problems = RenamingProblems()
elif data.message == RenameAndMoveStatus.download_completed:
if len(self.problems):
self.content = pickle.dumps(
- RenameAndMoveFileResults(
- problems=self.problems
- ),
+ RenameAndMoveFileResults(problems=self.problems),
pickle.HIGHEST_PROTOCOL
)
self.send_message_to_sink()