first working version with tests

This commit is contained in:
Karl Voit 2013-05-14 22:49:44 +02:00
parent b8039e2d7c
commit 31044e073b
2 changed files with 112 additions and 48 deletions

View file

@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Time-stamp: <2013-05-14 18:20:58 vk>
# Time-stamp: <2013-05-14 22:41:20 vk>
## TODO:
## * fix parts marked with «FIXXME»
@ -31,7 +31,7 @@ FILENAME_TAG_SEPARATOR = u' -- '
BETWEEN_TAG_SEPARATOR = u' '
USAGE = u"\n\
" + sys.argv[0] + u"\n\
" + sys.argv[0] + u" [<options>] <list of files>\n\
\n\
FIXXME\n\
https://github.com/novoid/FIXXME\n\
@ -64,6 +64,9 @@ parser.add_option("-r", "--remove", "-d", "--delete", action="store_true",
parser.add_option("-i", "--interactive", action="store_true",
help="interactive mode: ask for (a)dding or (r)emoving and name of tag(s)")
parser.add_option("-s", "--dryrun", dest="dryrun", action="store_true",
help="enable dryrun mode: just simulate what would happen, do not modify files")
parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
help="enable verbose mode")
@ -199,29 +202,52 @@ def removing_tag_from_filename(filename, tagname):
u'.' + extension
def query_folder(folder, list_of_files_found):
"""Walk the folder and its sub-folders and collect files matching
INCLUDE_FILES_REGEX whose folder do not match
EXCLUDE_FOLDERS_REGEX."""
def extract_tags_from_argument(argument):
"""
@param argument: string containing one or more tags
@param return: a list of unicode tags
"""
## http://stackoverflow.com/questions/5141437/filtering-os-walk-dirs-and-files
for root, dirs, files in os.walk(folder):
# exclude dirs
dirs[:] = [os.path.join(root, d) for d in dirs]
dirs[:] = [d for d in dirs if not re.match(EXCLUDE_FOLDERS_REGEX, d)]
# exclude/include files
files = [f for f in files if re.match(INCLUDE_FILES_REGEX, f)]
files = [os.path.join(root, f) for f in files]
for fname in files:
list_of_files_found.append(fname)
return list_of_files_found
return argument.split(unicode(BETWEEN_TAG_SEPARATOR))
def extract_filenames_from_argument(argument):
"""
@param argument: string containing one or more file names
@param return: a list of unicode file names
"""
return argument
def handle_file(filename, tags, do_remove, dryrun):
"""
@param filename: list containing one or more file names
@param tags: list containing one or more tags
@param do_remove: boolean which defines if tags should be added (False) or removed (True)
@param dryrun: boolean which defines if files should be changed (False) or not (True)
@param return: error value
"""
if os.path.isdir(filename):
logging.warning("Skipping directory \"%s\" because this tool only renames file names." % filename)
return
elif not os.path.isfile(filename):
logging.error("Skipping \"%s\" because this tool only renames existing file names." % filename)
return
new_filename = filename
for tagname in tags:
if do_remove:
new_filename = removing_tag_from_filename(new_filename, tagname)
else:
new_filename = adding_tag_to_filename(new_filename, tagname)
if dryrun:
logging.info("renaming: \"%s\" > \"%s\"" % (filename, new_filename))
else:
logging.debug("renaming \"%s\" > \"%s\" ..." % (filename, new_filename))
os.rename(filename, new_filename)
def main():
@ -248,23 +274,41 @@ def main():
error_exit(3, "I found option \"--tag\" and option \"--interactive\". \n" +
"Please choose either tag option OR interactive mode.")
## interactive mode and remove flag is given (FIXXME: make it possible in future versions)
if options.interactive and options.remove:
error_exit(4, "I found option \"--interactive\" and option \"--remove\". \n" +
"Please choose either interactive mode OR specify tag(s) to remove together with the \"--tag\" option.")
tags = []
if options.interactive:
## extract list of tags
## FIXXME
if options.remove:
logging.info("Interactive mode: tags get REMOVED from file names ...")
else:
logging.info("Interactive mode: tags get ADDED to file names ...")
## extract list of files
## FIXXME
## interactive: ask for list of tags
logging.debug("interactive mode: asking for tags ...")
## iterate over files
## FIXXME
print "Please enter one or more tags (separated by \"" + BETWEEN_TAG_SEPARATOR + "\"): (abort with Ctrl-C)"
entered_tags = sys.stdin.readline().strip()
tags = extract_tags_from_argument(entered_tags)
else:
## non-interactive: extract list of tags
logging.debug("non-interactive mode: extracting tags from argument ...")
tags = extract_tags_from_argument(options.tags)
logging.debug("tags found: [%s]" % '], ['.join(tags))
logging.debug("extracting list of files ...")
logging.debug("len(args) [%s]" % str(len(args)))
if len(args)<1:
error_exit(5, "Please add at least one file name as argument")
files = extract_filenames_from_argument(args)
logging.debug("filenames found: [%s]" % '], ['.join(files))
logging.debug("iterate over files ...")
for filename in files:
handle_file(filename, tags, options.remove, options.dryrun)
logging.info("successfully finished.")

View file

@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Time-stamp: <2013-05-14 18:21:24 vk>
# Time-stamp: <2013-05-14 22:49:16 vk>
## invoke tests using following command line:
## ~/src/vktag % PYTHONPATH="~/src/vktag:" tests/unit_tests.py --verbose
@ -57,13 +57,10 @@ class TestMethods(unittest.TestCase):
pass
class NO_TestFiles(unittest.TestCase):
class TestFileWithoutTags(unittest.TestCase):
tempdir = None
testfile_without_tags = 'file_without_tags.txt'
testfile_with_multiple_dots_and_no_tags = 'file.without.tags.txt'
testfile_with_tag_foo = 'filename -- foo.txt'
testfile_with_tag_bar = 'filename -- bar.txt'
testfilename = 'a test file . for you.txt'
def setUp(self):
@ -73,13 +70,10 @@ class NO_TestFiles(unittest.TestCase):
print "\ntemporary directory: " + self.tempdir
## create set of test files:
self.create_tmp_file(self.testfile_without_tags)
self.create_tmp_file(self.testfile_with_multiple_dots_and_no_tags)
self.create_tmp_file(self.testfile_with_tag_foo)
self.create_tmp_file(self.testfile_with_tag_bar)
self.create_tmp_file(self.testfilename)
## double-check set-up:
self.assertTrue(self.file_exists(self.testfile_without_tags))
self.assertTrue(self.file_exists(self.testfilename))
def create_tmp_file(self, name):
@ -92,14 +86,40 @@ class NO_TestFiles(unittest.TestCase):
return os.path.isfile(os.path.join(self.tempdir, name))
def test_all(self):
def test_add_and_remove_tags(self):
print "testing: foo bar\n"
self.assertEqual(3 * 4, 12)
## adding a tag to a file without any tags:
filetag.handle_file(os.path.join(self.tempdir, self.testfilename), [u'bar'], False, False)
self.assertEqual(self.file_exists(u'a test file . for you -- bar.txt'), True)
## adding a second tag:
filetag.handle_file(os.path.join(self.tempdir, u'a test file . for you -- bar.txt'),
[u'foo'], do_remove=False, dryrun=False)
self.assertEqual(self.file_exists(u'a test file . for you -- bar foo.txt'), True)
## adding two tags:
filetag.handle_file(os.path.join(self.tempdir, u'a test file . for you -- bar foo.txt'),
[u'one', u'two'], do_remove=False, dryrun=False)
self.assertEqual(self.file_exists(u'a test file . for you -- bar foo one two.txt'), True)
## simulating another tag:
filetag.handle_file(os.path.join(self.tempdir, u'a test file . for you -- bar foo one two.txt'),
[u'one', u'two'], do_remove=False, dryrun=True)
self.assertEqual(self.file_exists(u'a test file . for you -- bar foo one two.txt'), True)
## removing three tag:
filetag.handle_file(os.path.join(self.tempdir, u'a test file . for you -- bar foo one two.txt'),
[u'bar', u'one', u'foo'], do_remove=True, dryrun=False)
self.assertEqual(self.file_exists(u'a test file . for you -- two.txt'), True)
## removing last tag:
filetag.handle_file(os.path.join(self.tempdir, u'a test file . for you -- two.txt'),
[u'two'], do_remove=True, dryrun=False)
self.assertEqual(self.file_exists(u'a test file . for you.txt'), True)
def tearDown(self):
rmtree(self.tempdir)