Skip to content

Commit

Permalink
Start of rename based on filename generation
Browse files Browse the repository at this point in the history
  • Loading branch information
clach04 committed Dec 9, 2023
1 parent 3eb97a2 commit 33b5498
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 27 deletions.
77 changes: 52 additions & 25 deletions puren_tonbo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1106,39 +1106,49 @@ def note_contents_save_native_filename(note_text, filename=None, original_filena
folder - if specified (new) filename and original_filename are relative. if missing filename and original_filename are absolute
"""
# Start - restrictions/checks that should be removed
"""
if original_filename is not None:
# then if folder specified, original_filename MUST be absolute path
# then if folder missing , original_filename MUST be relative path
raise NotImplementedError('original_filename is not None')
#original_filename = unicode_path(original_filename)
"""
# End - restrictions/checks that should be removed

if handler is None:
raise NotImplementedError('handler is required')
raise NotImplementedError('handler is required') # Idea filename required, then use that to detemine handler
filename_generator_func = None
if filename is None:
if folder:
# relative path names for files as given as input to this function
if original_filename:
original_filename = os.path.join(folder, original_filename) # TODO abspath for safety?
folder = os.path.dirname(original_filename)
if original_filename and filename_generator in (None, FILENAME_TIMESTAMP, FILENAME_UUID4):
# do not rename... or they could have passed in the "new name"
filename = original_filename
log.debug('filename is original_filename: %r', filename)
else:
# folder not set, so absolute paths given as input to this function
folder = os.path.dirname(original_filename)
if folder:
# relative path names for files as given as input to this function
if original_filename:
original_filename = os.path.join(folder, original_filename) # TODO abspath for safety?
folder = os.path.dirname(original_filename)
else:
# folder not set, so absolute paths given as input to this function
folder = os.path.dirname(original_filename)

validate_filename_generator(filename_generator)
filename_generator_func = filename_generators[filename_generator]
file_extension = handler.extensions[0] # pick the first one
filename_without_path_and_extension = filename_generator_func(note_text)
validate_filename_generator(filename_generator)
filename_generator_func = filename_generators[filename_generator]
file_extension = handler.extensions[0] # pick the first one
filename_without_path_and_extension = filename_generator_func(note_text)

filename = os.path.join(folder, filename_without_path_and_extension + file_extension)
# now check if generated filename already exists, if so need to make unique
unique_counter = 1
while os.path.exists(filename):
#log.warn('generated filename %r already exists', filename)
unique_part = '(%d)' % unique_counter # match Tombo duplicate names avoidance
filename = os.path.join(folder, filename_without_path_and_extension + unique_part + file_extension)
unique_counter += 1
filename = os.path.join(folder, filename_without_path_and_extension + file_extension)
# now check if generated filename already exists, if so need to make unique
unique_counter = 1
while os.path.exists(filename):
#log.warn('generated filename %r already exists', filename)
unique_part = '(%d)' % unique_counter # match Tombo duplicate names avoidance
filename = os.path.join(folder, filename_without_path_and_extension + unique_part + file_extension)
unique_counter += 1

# TODO handle format conversion (e.g. original text, new encrypted)
log.debug('generated filename: %r', filename)
# TODO handle format conversion (e.g. original text, new encrypted)
log.debug('generated filename: %r', filename)
else:
filename = unicode_path(filename)

Expand Down Expand Up @@ -1237,10 +1247,19 @@ def note_contents_save_native_filename(note_text, filename=None, original_filena
if backup:
if os.path.exists(filename):
file_replace(filename, filename + '.bak') # backup existing
elif original_filename and os.path.exists(original_filename):
file_replace(original_filename, original_filename + '.bak') # backup existing
# TODO do the same for original

if use_tempfile:
file_replace(tmp_out_filename, filename)

# handle rename/delete
if filename_generator_func:
# filename generator was used, have have an old file to cleanup
if original_filename and filename != original_filename and os.path.exists(original_filename):
os.remove(original_filename)

def validate_filename_generator(filename_generator):
if filename_generator not in (
FILENAME_TIMESTAMP,
Expand Down Expand Up @@ -1722,7 +1741,7 @@ def note_contents(self, filename, get_pass=None, dos_newlines=True, return_bytes
else:
return self.to_string(plain_str)

def note_contents_save(self, note_text, filename=None, original_filename=None, folder=None, get_pass=None, dos_newlines=True, backup=True, filename_generator=FILENAME_FIRSTLINE, handler_class=None):
def note_contents_save(self, note_text, filename=None, original_filename=None, folder=None, get_pass=None, dos_newlines=True, backup=True, use_tempfile=True, filename_generator=FILENAME_FIRSTLINE, handler_class=None):
"""Save/write/encrypt the notes contents, also see note_contents() for load/read/decrypt
FIXME make calls to note_contents_save_filename() function instead
Expand All @@ -1739,6 +1758,9 @@ def note_contents_save(self, note_text, filename=None, original_filename=None, f
See note_contents_save_native_filename() docs
TODO refactor, there is code duplication (and some differences) between method note_contents_save() and functions note_contents_save_filename() / note_contents_save_native_filename()
"""
# FIXME filename/path validation shold take place first before calling note_contents_save_native_filename()
#return note_contents_save_native_filename(note_text, filename=filename, original_filename=original_filename, folder=folder, handler=handler_class, dos_newlines=dos_newlines, backup=backup, use_tempfile=use_tempfile, note_encoding=self.note_encoding, filename_generator=filename_generator)

# sanity checks
if filename is not None and folder is not None:
raise NotImplementedError('incompatible/inconsistent filename: %r folder: %r ' % (filename, folder))
Expand Down Expand Up @@ -1778,7 +1800,6 @@ def note_contents_save(self, note_text, filename=None, original_filename=None, f
filename = self.abspath2relative(native_filename)
generated_filename = True


filename = self.unicode_path(filename)
fullpath_native_filename = self.native_full_path(filename)
if original_filename and filename != original_filename:
Expand All @@ -1790,13 +1811,19 @@ def note_contents_save(self, note_text, filename=None, original_filename=None, f
else:
handler = handler_class()

#return note_contents_save_native_filename(note_text, filename=filename, original_filename=original_filename, folder=folder, handler=handler_class, dos_newlines=dos_newlines, backup=backup, use_tempfile=use_tempfile, note_encoding=self.note_encoding, filename_generator=filename_generator)
# filename=fullpath_native_filename
# folder=None
return note_contents_save_native_filename(note_text, filename=fullpath_native_filename, original_filename=original_filename, folder=None, handler=handler, dos_newlines=dos_newlines, backup=backup, use_tempfile=use_tempfile, note_encoding=self.note_encoding, filename_generator=filename_generator)


# x TODO unicode filename
# x TODO handler lookup
# TODO handler password pass in - see load code above
# TODO original filename and rename
plain_str_bytes = self.to_bytes(note_text)

use_tempfile = True # do not offer external control over this
#use_tempfile = True # do not offer external control over this?
if use_tempfile:
timestamp_now = datetime.datetime.now().strftime('%Y%m%d_%H%M%S')
out_file = tempfile.NamedTemporaryFile(
Expand Down
48 changes: 46 additions & 2 deletions puren_tonbo/tests/testsuite.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"""

import glob
import os
import pdb
import sys
Expand Down Expand Up @@ -615,7 +616,7 @@ def setUpClass(self):
def tearDownClass(self):
shutil.rmtree(self.data_folder)

def do_one_test(self, buffer_plain_str, new_filename=None, original_filename=None, folder=None, dos_newlines=None, test_password_bytes=None, filename_generator=puren_tonbo.FILENAME_FIRSTLINE, expected_filenames=None):
def do_one_test(self, buffer_plain_str, new_filename=None, original_filename=None, folder=None, dos_newlines=None, test_password_bytes=None, backup=True, use_tempfile=True, filename_generator=puren_tonbo.FILENAME_FIRSTLINE, expected_filenames=None):
if not expected_filenames:
self.assertTrue(False, 'expected_filenames required... not implemented')
test_note_filename = new_filename or expected_filenames[0]
Expand All @@ -628,6 +629,8 @@ def do_one_test(self, buffer_plain_str, new_filename=None, original_filename=Non

kwargs = dict(
filename_generator=filename_generator,
backup=backup,
use_tempfile=use_tempfile,
)
if dos_newlines is not None:
kwargs['dos_newlines'] = dos_newlines
Expand Down Expand Up @@ -668,6 +671,39 @@ def do_one_test(self, buffer_plain_str, new_filename=None, original_filename=Non
if os.path.exists(full_pathname):
os.remove(full_pathname) # TODO ignore does not exist errors (only), for now skip attempt

# simple, flat, non-nested cleanup
for filename in glob.glob(os.path.join(folder, '*')):
os.remove(filename)

def test_filename_gen_one_rename_two_with_password_with_backup(self):
buffer_plain_str = '''two
file WAS one.
'''
#pdb.set_trace()
file_extension = self.handler_class.extensions[0] # pick the first one
folder = self.data_folder
note_root = puren_tonbo.FileSystemNotes(folder, self.note_encoding)
note_root.note_contents_save('junk', filename='one' + file_extension, filename_generator=None, get_pass=self.test_password_bytes)

# NOTE implicit backup
self.do_one_test(buffer_plain_str, original_filename='one' + file_extension, dos_newlines=False, test_password_bytes=self.test_password_bytes, expected_filenames=['two' + file_extension, 'one.txt.bak'])

def test_filename_gen_one_rename_two_with_password_with_nobackup(self):
buffer_plain_str = '''two
file WAS one.
'''
#pdb.set_trace()
file_extension = self.handler_class.extensions[0] # pick the first one
folder = self.data_folder
note_root = puren_tonbo.FileSystemNotes(folder, self.note_encoding)
note_root.note_contents_save('junk', filename='one' + file_extension, filename_generator=None, get_pass=self.test_password_bytes)

self.do_one_test(buffer_plain_str, original_filename='one' + file_extension, dos_newlines=False, test_password_bytes=self.test_password_bytes, backup=False, expected_filenames=['two' + file_extension])

def test_filename_gen_one_with_password_already_exist(self):
buffer_plain_str = '''one
Expand Down Expand Up @@ -710,7 +746,7 @@ def test_filename_gen_one_no_password(self):


class TestFileSystemNotesWriteFunctionSaveRawPlainText(TestFileSystemNotesWriteClassSaveRawPlainText):
def do_one_test(self, buffer_plain_str, new_filename=None, original_filename=None, folder=None, dos_newlines=None, test_password_bytes=None, filename_generator=puren_tonbo.FILENAME_FIRSTLINE, expected_filenames=None):
def do_one_test(self, buffer_plain_str, new_filename=None, original_filename=None, folder=None, dos_newlines=None, test_password_bytes=None, backup=True, use_tempfile=True, filename_generator=puren_tonbo.FILENAME_FIRSTLINE, expected_filenames=None):
if not expected_filenames:
self.assertTrue(False, 'expected_filenames required... not implemented')
test_note_filename = new_filename or expected_filenames[0]
Expand All @@ -724,6 +760,8 @@ def do_one_test(self, buffer_plain_str, new_filename=None, original_filename=Non

kwargs = dict(
filename_generator=filename_generator,
backup=backup,
use_tempfile=use_tempfile,
)
if dos_newlines is not None:
kwargs['dos_newlines'] = dos_newlines
Expand All @@ -749,7 +787,9 @@ def do_one_test(self, buffer_plain_str, new_filename=None, original_filename=Non
data = note_root.note_contents(test_note_filename, password, dos_newlines=dos_newlines)
self.assertEqual(buffer_plain_str, data)

expected_filenames.sort()
for (dirname, dirnames, filenames) in os.walk(folder):
filenames.sort()
#print(dirname, dirnames, filenames)
self.assertEqual((folder, [], expected_filenames), (dirname, dirnames, filenames))

Expand All @@ -760,6 +800,10 @@ def do_one_test(self, buffer_plain_str, new_filename=None, original_filename=Non
if os.path.exists(full_pathname):
os.remove(full_pathname) # TODO ignore does not exist errors (only), for now skip attempt

# simple, flat, non-nested cleanup
for filename in glob.glob(os.path.join(folder, '*')):
os.remove(filename)

class TestFileSystemNotesWriteClassSaveEncryptedChi(TestFileSystemNotesWriteClassSaveRawPlainText):
handler_class = puren_tonbo.TomboBlowfish # Tombo chi

Expand Down

0 comments on commit 33b5498

Please sign in to comment.