diff --git a/README.org b/README.org index 57f99b7..3b15422 100644 --- a/README.org +++ b/README.org @@ -1,8 +1,8 @@ -## Time-stamp: <2014-11-08 14:10:14 vk> +## Time-stamp: <2015-01-02 14:14:25 vk> ## -*- coding: utf-8 -*- ## This file is best viewed with GNU Emacs Org-mode: http://orgmode.org/ -* filetag.py +* filetags This Python script adds or removes tags to file names in the following form: @@ -18,7 +18,7 @@ possible length limitations). - *Target group*: users who are able to use command line tools and who are using tags in file names. -- Hosted on github: https://github.com/novoid/filetag +- Hosted on github: https://github.com/novoid/filetags ** Why @@ -43,23 +43,23 @@ GNU/Linux. ** Usage -: filetag.py --tag foo a_file_name.txt +: filetags.py --tag foo a_file_name.txt ... adds tag "foo" such that it results in ~a_file_name -- foo.txt~ -: filetag.py -i *.jpeg +: filetags.py -i *.jpeg ... interactive mode: asking for list of tags (for the JPEG files) from the user -: filetag.py --tag "foo bar" "file name 1.jpg" "file name 2 -- foo.txt" "file name 3 -- bar.csv" +: filetags.py --tag "foo bar" "file name 1.jpg" "file name 2 -- foo.txt" "file name 3 -- bar.csv" ... adds tag "foo" such that it results in ... : "file name 1 -- foo bar.jpg" : "file name 2 -- foo bar.txt" : "file name 3 -- bar foo.csv" -: filetag.py --remove --tag foo "foo a_file_name -- foo.txt" +: filetags.py --remove --tag foo "foo a_file_name -- foo.txt" ... removes tag "foo" such that it results in ~foo a_file_name.txt~ For a complete list of parameters, please try: -: filetag.py --help +: filetags.py --help ** Bonus: integrating into Geeqie (or similar file browsers) @@ -73,18 +73,18 @@ Using GNU/Linux, this is quite easy accomplished. The only thing that is not straight forward is the need for a wrapper script. The wrapper script does provide a shell window for entering the tags. -~vk-filetag-interactive-adding-wrapper-with-gnome-terminal.sh~ looks like: +~vk-filetags-interactive-adding-wrapper-with-gnome-terminal.sh~ looks like: : #!/bin/sh : : /usr/bin/gnome-terminal \ : --geometry=73x5+330+5 \ : --tab-with-profile=big \ : --hide-menubar \ -: -x /home/vk/src/filetag/filetag.py --interactive "${@}" +: -x /home/vk/src/filetags/filetags.py --interactive "${@}" : : #end -~vk-filetag-interactive-removing-wrapper-with-gnome-terminal.sh~ +~vk-filetags-interactive-removing-wrapper-with-gnome-terminal.sh~ looks like: : #!/bin/sh : @@ -92,7 +92,7 @@ looks like: : --geometry=73x5+330+5 \ : --tab-with-profile=big \ : --hide-menubar \ -: -x /home/vk/src/filetag/filetag.py --interactive --remove "${@}" +: -x /home/vk/src/filetags/filetags.py --interactive --remove "${@}" : : #end @@ -102,10 +102,10 @@ image files: ~$HOME/.config/geeqie/applications/add-tags.desktop~ looks like: : [Desktop Entry] -: Name=filetag -: GenericName=filetag +: Name=filetags +: GenericName=filetags : Comment= -: Exec=/home/vk/src/misc/vk-filetag-interactive-adding-wrapper-with-gnome-terminal.sh %F +: Exec=/home/vk/src/misc/vk-filetags-interactive-adding-wrapper-with-gnome-terminal.sh %F : Icon= : Terminal=true : Type=Application @@ -116,10 +116,10 @@ image files: ~$HOME/.config/geeqie/applications/remove-tags.desktop~ looks like: : [Desktop Entry] -: Name=filetag -: GenericName=filetag +: Name=filetags +: GenericName=filetags : Comment= -: Exec=/home/vk/src/misc/vk-filetag-interactive-removing-wrapper-with-gnome-terminal.sh %F +: Exec=/home/vk/src/misc/vk-filetags-interactive-removing-wrapper-with-gnome-terminal.sh %F : Icon= : Terminal=true : Type=Application @@ -132,7 +132,7 @@ In order to be able to use the keyboard shortcuts ~t~ (adding tags) and ~T~ (removing tags), you can define them in geeqie: 1. Edit > Preferences > Preferences ... > Keyboard. 2. Scroll to the bottom of the list. -3. Double click in the ~KEY~-column of ~filetag~ and ~filetag-remove~ +3. Double click in the ~KEY~-column of ~filetags~ and ~filetags-remove~ and choose your desired keyboard shortcut accordingly. I hope this method is as handy for you as it is for me :-) @@ -143,7 +143,7 @@ You know the problem: got back from Paris and you can not show 937 image files to your friends. It's just too much. My solution: I tag to define selections. For example, I am using -~sel~ for the ultimate cool photographs using ~filetag~, of course. +~sel~ for the ultimate cool photographs using ~filetags~, of course. Within geeqie, I redefined ~S~ (usually mapped to "sort manager") to an external shell script (below) which creates a temporary folder @@ -232,14 +232,14 @@ you might like to read. In short: -For *tagging*, please refer to [[https://github.com/novoid/filetag][filetag]] and its documentation. +For *tagging*, please refer to [[https://github.com/novoid/filetags][filetags]] and its documentation. See [[https://github.com/novoid/date2name][date2name]] for easily adding ISO *time-stamps or date-stamps* to files. For *easily naming and tagging* files within file browsers that allow integration of external tools, see [[https://github.com/novoid/appendfilename][appendfilename]] (once more) and -[[https://github.com/novoid/filetag][filetag]]. +[[https://github.com/novoid/filetags][filetags]]. Moving to the archive folders is done using [[https://github.com/novoid/move2archive][move2archive]]. diff --git a/filetag.py b/filetags.py similarity index 100% rename from filetag.py rename to filetags.py diff --git a/tests/unit_tests.py b/tests/unit_tests.py index 3a67320..aa3a29e 100755 --- a/tests/unit_tests.py +++ b/tests/unit_tests.py @@ -1,13 +1,13 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Time-stamp: <2014-12-20 22:21:19 vk> +# Time-stamp: <2015-01-02 14:17:50 vk> ## invoke tests using following command line: -## ~/src/vktag % PYTHONPATH="~/src/filetag:" tests/unit_tests.py --verbose +## ~/src/vktag % PYTHONPATH="~/src/filetags:" tests/unit_tests.py --verbose import unittest import os -import filetag +import filetags import tempfile import os.path from shutil import rmtree @@ -20,53 +20,53 @@ class TestMethods(unittest.TestCase): def test_contains_tag(self): - self.assertEqual(filetag.contains_tag(u'Some file name -- foo.jpeg', u'foo'), True) - self.assertEqual(filetag.contains_tag(u'Some file name -- foo bar.jpeg', u'foo'), True) - self.assertEqual(filetag.contains_tag(u'Some file name -- bar foo.jpeg', u'foo'), True) - self.assertEqual(filetag.contains_tag(u'Some file name -- foobar.jpeg', u'foo'), False) - self.assertEqual(filetag.contains_tag(u'Some file name -- foo.jpeg', u'bar'), False) - self.assertEqual(filetag.contains_tag(u'Some foo file name -- bar.jpeg', u'foo'), False) + self.assertEqual(filetags.contains_tag(u'Some file name -- foo.jpeg', u'foo'), True) + self.assertEqual(filetags.contains_tag(u'Some file name -- foo bar.jpeg', u'foo'), True) + self.assertEqual(filetags.contains_tag(u'Some file name -- bar foo.jpeg', u'foo'), True) + self.assertEqual(filetags.contains_tag(u'Some file name -- foobar.jpeg', u'foo'), False) + self.assertEqual(filetags.contains_tag(u'Some file name -- foo.jpeg', u'bar'), False) + self.assertEqual(filetags.contains_tag(u'Some foo file name -- bar.jpeg', u'foo'), False) ## without tagname -> check if any tags are found: - self.assertEqual(filetag.contains_tag(u'Some file name -- foo.jpeg'), True) - self.assertEqual(filetag.contains_tag(u'Some file name -- foo bar.jpeg'), True) - self.assertEqual(filetag.contains_tag(u'Some file name.jpeg'), False) + self.assertEqual(filetags.contains_tag(u'Some file name -- foo.jpeg'), True) + self.assertEqual(filetags.contains_tag(u'Some file name -- foo bar.jpeg'), True) + self.assertEqual(filetags.contains_tag(u'Some file name.jpeg'), False) def test_adding_tag_to_filename(self): - self.assertEqual(filetag.adding_tag_to_filename(u'Some file name.jpeg', u'bar'), + self.assertEqual(filetags.adding_tag_to_filename(u'Some file name.jpeg', u'bar'), u'Some file name -- bar.jpeg') - self.assertEqual(filetag.adding_tag_to_filename(u'Some file name -- foo.jpeg', u'bar'), + self.assertEqual(filetags.adding_tag_to_filename(u'Some file name -- foo.jpeg', u'bar'), u'Some file name -- foo bar.jpeg') - self.assertEqual(filetag.adding_tag_to_filename(u'Some file name -- foo.jpeg', u'foo'), + self.assertEqual(filetags.adding_tag_to_filename(u'Some file name -- foo.jpeg', u'foo'), u'Some file name -- foo.jpeg') def test_removing_tag_from_filename(self): - self.assertEqual(filetag.removing_tag_from_filename(u'Some file name -- bar.jpeg', u'bar'), + self.assertEqual(filetags.removing_tag_from_filename(u'Some file name -- bar.jpeg', u'bar'), u'Some file name.jpeg') - self.assertEqual(filetag.removing_tag_from_filename(u'Some file name -- foo bar.jpeg', u'bar'), + self.assertEqual(filetags.removing_tag_from_filename(u'Some file name -- foo bar.jpeg', u'bar'), u'Some file name -- foo.jpeg') - self.assertEqual(filetag.removing_tag_from_filename(u'Some file name -- bar.jpeg', u'foo'), + self.assertEqual(filetags.removing_tag_from_filename(u'Some file name -- bar.jpeg', u'foo'), u'Some file name -- bar.jpeg') def test_extract_tags_from_filename(self): - self.assertEqual(filetag.extract_tags_from_filename(u'Some file name - bar.jpeg'), []) - self.assertEqual(filetag.extract_tags_from_filename(u'-- bar.jpeg'), []) - self.assertEqual(filetag.extract_tags_from_filename(u'Some file name.jpeg'), []) - self.assertEqual(filetag.extract_tags_from_filename(u'Some file name - bar.jpeg'), []) - self.assertEqual(filetag.extract_tags_from_filename(u'Some file name -- bar.jpeg'), [u'bar']) - self.assertEqual(filetag.extract_tags_from_filename(u'Some file name -- foo bar baz.jpeg'), + self.assertEqual(filetags.extract_tags_from_filename(u'Some file name - bar.jpeg'), []) + self.assertEqual(filetags.extract_tags_from_filename(u'-- bar.jpeg'), []) + self.assertEqual(filetags.extract_tags_from_filename(u'Some file name.jpeg'), []) + self.assertEqual(filetags.extract_tags_from_filename(u'Some file name - bar.jpeg'), []) + self.assertEqual(filetags.extract_tags_from_filename(u'Some file name -- bar.jpeg'), [u'bar']) + self.assertEqual(filetags.extract_tags_from_filename(u'Some file name -- foo bar baz.jpeg'), [u'foo', u'bar', u'baz']) - self.assertEqual(filetag.extract_tags_from_filename(u'Some file name -- foo bar baz'), + self.assertEqual(filetags.extract_tags_from_filename(u'Some file name -- foo bar baz'), [u'foo', u'bar', u'baz']) def test_add_tag_to_countdict(self): - self.assertEqual(filetag.add_tag_to_countdict(u'tag', {}), {u'tag': 1}) - self.assertEqual(filetag.add_tag_to_countdict(u'tag', {u'tag': 0}), {u'tag': 1}) - self.assertEqual(filetag.add_tag_to_countdict(u'tag', {u'tag': 1}), {u'tag': 2}) - self.assertEqual(filetag.add_tag_to_countdict(u'newtag', {u'oldtag': 1}), {u'oldtag': 1, u'newtag': 1}) - self.assertEqual(filetag.add_tag_to_countdict(u'newtag', {u'oldtag': 2}), {u'oldtag': 2, u'newtag': 1}) + self.assertEqual(filetags.add_tag_to_countdict(u'tag', {}), {u'tag': 1}) + self.assertEqual(filetags.add_tag_to_countdict(u'tag', {u'tag': 0}), {u'tag': 1}) + self.assertEqual(filetags.add_tag_to_countdict(u'tag', {u'tag': 1}), {u'tag': 2}) + self.assertEqual(filetags.add_tag_to_countdict(u'newtag', {u'oldtag': 1}), {u'oldtag': 1, u'newtag': 1}) + self.assertEqual(filetags.add_tag_to_countdict(u'newtag', {u'oldtag': 2}), {u'oldtag': 2, u'newtag': 1}) def tearDown(self): @@ -102,31 +102,31 @@ class TestFileWithoutTags(unittest.TestCase): def test_add_and_remove_tags(self): ## adding a tag to a file without any tags: - filetag.handle_file(os.path.join(self.tempdir, self.testfilename), [u'bar'], False, False) + filetags.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'), + filetags.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'), + filetags.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'), + filetags.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'), + filetags.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'), + filetags.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) @@ -134,56 +134,56 @@ class TestFileWithoutTags(unittest.TestCase): filename = u"file without extension" self.create_tmp_file(filename) - filetag.handle_file(os.path.join(self.tempdir, filename), [u'foo'], False, False) + filetags.handle_file(os.path.join(self.tempdir, filename), [u'foo'], False, False) self.assertEqual(self.file_exists(filename + u' -- foo'), True) def test_list_tags_by_number(self): ## starting with no file with tags: - self.assertEqual(filetag.list_tags_by_number(max_tag_count=1), {}) + self.assertEqual(filetags.list_tags_by_number(max_tag_count=1), {}) ## adding a file tag: - filetag.handle_file(os.path.join(self.tempdir, self.testfilename), [u'bar'], False, False) - self.assertEqual(filetag.list_tags_by_number(max_tag_count=1), {u'bar': 1}) - self.assertEqual(filetag.list_tags_by_number(max_tag_count=0), {u'bar': 1}) + filetags.handle_file(os.path.join(self.tempdir, self.testfilename), [u'bar'], False, False) + self.assertEqual(filetags.list_tags_by_number(max_tag_count=1), {u'bar': 1}) + self.assertEqual(filetags.list_tags_by_number(max_tag_count=0), {u'bar': 1}) ## adding a another file tag: - filetag.handle_file(os.path.join(self.tempdir, u'a test file . for you -- bar.txt'), [u'foo'], False, False) - self.assertEqual(filetag.list_tags_by_number(max_tag_count=1), {u'bar': 1, u'foo': 1}) - self.assertEqual(filetag.list_tags_by_number(max_tag_count=0), {u'bar': 1, u'foo': 1}) + filetags.handle_file(os.path.join(self.tempdir, u'a test file . for you -- bar.txt'), [u'foo'], False, False) + self.assertEqual(filetags.list_tags_by_number(max_tag_count=1), {u'bar': 1, u'foo': 1}) + self.assertEqual(filetags.list_tags_by_number(max_tag_count=0), {u'bar': 1, u'foo': 1}) ## adding a another file: self.create_tmp_file(u'a second file') - filetag.handle_file(os.path.join(self.tempdir, u'a second file'), [u'foo'], False, False) - self.assertEqual(filetag.list_tags_by_number(max_tag_count=1), {u'bar': 1}) - self.assertEqual(filetag.list_tags_by_number(max_tag_count=1), {u'bar': 1}) - self.assertEqual(filetag.list_tags_by_number(max_tag_count=0), {u'bar': 1, u'foo': 2}) + filetags.handle_file(os.path.join(self.tempdir, u'a second file'), [u'foo'], False, False) + self.assertEqual(filetags.list_tags_by_number(max_tag_count=1), {u'bar': 1}) + self.assertEqual(filetags.list_tags_by_number(max_tag_count=1), {u'bar': 1}) + self.assertEqual(filetags.list_tags_by_number(max_tag_count=0), {u'bar': 1, u'foo': 2}) def test_list_tags_by_alphabet(self): ## starting with no file with tags: - self.assertEqual(filetag.list_tags_by_alphabet(only_with_similar_tags=True), {}) + self.assertEqual(filetags.list_tags_by_alphabet(only_with_similar_tags=True), {}) ## adding a file tag: - filetag.handle_file(os.path.join(self.tempdir, self.testfilename), [u'similar1'], False, False) - self.assertEqual(filetag.list_tags_by_alphabet(only_with_similar_tags=True), {}) - self.assertEqual(filetag.list_tags_by_alphabet(only_with_similar_tags=False), {u'similar1': 1}) + filetags.handle_file(os.path.join(self.tempdir, self.testfilename), [u'similar1'], False, False) + self.assertEqual(filetags.list_tags_by_alphabet(only_with_similar_tags=True), {}) + self.assertEqual(filetags.list_tags_by_alphabet(only_with_similar_tags=False), {u'similar1': 1}) ## adding a file tag: - filetag.handle_file(os.path.join(self.tempdir, u'a test file . for you -- similar1.txt'), [u'foo'], False, False) - self.assertEqual(filetag.list_tags_by_alphabet(only_with_similar_tags=True), {}) - self.assertEqual(filetag.list_tags_by_alphabet(only_with_similar_tags=False), {u'foo': 1, u'similar1': 1}) + filetags.handle_file(os.path.join(self.tempdir, u'a test file . for you -- similar1.txt'), [u'foo'], False, False) + self.assertEqual(filetags.list_tags_by_alphabet(only_with_similar_tags=True), {}) + self.assertEqual(filetags.list_tags_by_alphabet(only_with_similar_tags=False), {u'foo': 1, u'similar1': 1}) ## adding a another file: self.create_tmp_file(u'a second file') - filetag.handle_file(os.path.join(self.tempdir, u'a second file'), [u'foo'], False, False) - self.assertEqual(filetag.list_tags_by_alphabet(only_with_similar_tags=True), {}) - self.assertEqual(filetag.list_tags_by_alphabet(only_with_similar_tags=False), {u'foo': 2, u'similar1': 1}) + filetags.handle_file(os.path.join(self.tempdir, u'a second file'), [u'foo'], False, False) + self.assertEqual(filetags.list_tags_by_alphabet(only_with_similar_tags=True), {}) + self.assertEqual(filetags.list_tags_by_alphabet(only_with_similar_tags=False), {u'foo': 2, u'similar1': 1}) ## adding similar tag: - filetag.handle_file(os.path.join(self.tempdir, u'a second file -- foo'), [u'similar2'], False, False) - self.assertEqual(filetag.list_tags_by_alphabet(only_with_similar_tags=True), {u'similar1': 1, u'similar2': 1}) - self.assertEqual(filetag.list_tags_by_alphabet(only_with_similar_tags=False), {u'foo': 2, u'similar1': 1, u'similar2': 1}) + filetags.handle_file(os.path.join(self.tempdir, u'a second file -- foo'), [u'similar2'], False, False) + self.assertEqual(filetags.list_tags_by_alphabet(only_with_similar_tags=True), {u'similar1': 1, u'similar2': 1}) + self.assertEqual(filetags.list_tags_by_alphabet(only_with_similar_tags=False), {u'foo': 2, u'similar1': 1, u'similar2': 1}) def tearDown(self):