Skip to content

Commit

Permalink
Refactor MailMover.move() logic
Browse files Browse the repository at this point in the history
Following the #188 issue, we needed to change move() function,
to be able to move, and upgrade the database a bit more lightly:
* Copy the original file to the destination
* Add the new file to the database
* Remove the original file
* Remove the original mail from db
  • Loading branch information
GuillaumeSeren committed Mar 25, 2018
1 parent 6ae8a17 commit cf37c01
Showing 1 changed file with 43 additions and 26 deletions.
69 changes: 43 additions & 26 deletions afew/MailMover.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ def move(self, maildir, rules):
'''
# identify and move messages
logging.info("checking mails in '{}'".format(maildir))
to_delete_fnames = []
# Open DB R/W if are not in dry-run
if not self.dry_run:
self.db = notmuch.Database(self.db_path,
mode=notmuch.Database.MODE.READ_WRITE)
moved = False
for query in rules.keys():
destination = '{}/{}/cur/'.format(self.db_path, rules[query])
Expand All @@ -59,7 +62,7 @@ def move(self, maildir, rules):
messages = notmuch.Query(self.db, main_query).search_messages()
for message in messages:
# a single message (identified by Message-ID) can be in several
# places; only touch the one(s) that exists in this maildir
# places; only touch the one(s) that exists in this maildir
all_message_fnames = message.get_filenames()
to_move_fnames = [name for name in all_message_fnames
if maildir in name]
Expand All @@ -72,31 +75,45 @@ def move(self, maildir, rules):
if self.dry_run:
continue
try:
shutil.copy2(fname, self.get_new_name(fname, destination))
to_delete_fnames.append(fname)
except shutil.SameFileError:
logging.warn("trying to move '{}' onto itself".format(fname))
continue
logging.info("Copy original mail: "+fname)
logging.info("Path of mail: "+os.path.dirname(fname))
logging.info("Copy to: "+destination)
dbpath = self.db.get_path()
logging.info("Path of DB: "+dbpath)
relpath=os.path.relpath(os.path.dirname(destination), dbpath)
filename = os.path.basename(fname)
logging.info("filename: "+filename)
logging.info("Relative path DB -> file: " + relpath)
# 1 COPY
shutil.copy2(fname, self.get_new_name(
fname,
destination))
dest_file_rel = dbpath+'/'+relpath+'/'+filename
logging.info("Add new copy to the DB: "+dest_file_rel)
# OPEN DB R/W
logging.info("Open DB R/W")
# print vars(self.db)
# 2 Add NEW MESSAGE TO DB
moved_message = notmuch.Database.add_message(self.db, dest_file_rel)
logging.info("Delete original mail file: "+fname)
os.remove(fname)
# 3 REMOVE ORIGINAL
logging.info("Delete the original mail in DB")
# 4 REMOVE ORIGINAL FROM DB
notmuch.Database.remove_message(self.db, fname)
except IOError as e:
logging.warn('Error IO: '+format(e))
except shutil.Error as e:
# this is ugly, but shutil does not provide more
# finely individuated errors
if str(e).endswith("already exists"):
continue
else:
raise

# remove mail from source locations only after all copies are finished
for fname in set(to_delete_fnames):
os.remove(fname)

# update notmuch database
if not self.dry_run:
if moved:
logging.info("updating database")
self.__update_db(maildir)
else:
logging.info("Would update database")

logging.warn('Error shutil: '+format(e))
continue
except OSError as e:
logging.warn('Error OS: '+format(e))
continue
except notmuch.NotmuchError as e:
logging.warn('Error notmuch: '+format(e))
continue
# Return the moved flag
return moved

#
# private:
Expand Down

0 comments on commit cf37c01

Please sign in to comment.