diff --git a/etiquette/objects.py b/etiquette/objects.py index 3904782..d7a3b65 100644 --- a/etiquette/objects.py +++ b/etiquette/objects.py @@ -357,7 +357,10 @@ class Bookmark(ObjectBase): self.url = url cur = self.photodb.sql.cursor() - cur.execute('UPDATE bookmarks SET title = ?, url = ? WHERE id == ?', [self.title, self.url, self.id]) + cur.execute( + 'UPDATE bookmarks SET title = ?, url = ? WHERE id == ?', + [self.title, self.url, self.id] + ) if commit: self.photodb.log.debug('Committing - edit bookmark') self.photodb.sql.commit() @@ -422,15 +425,15 @@ class Photo(ObjectBase): if self.has_tag(tag, check_children=False): return - # If the tag is above one we already have, keep our current one. + # If the new tag is less specific than one we already have, + # keep our current one. existing = self.has_tag(tag, check_children=True) if existing: message = 'Preferring existing {exi:s} over {tag:s}'.format(exi=existing, tag=tag) self.photodb.log.debug(message) return - # If the tag is beneath one we already have, remove our current one - # in favor of the new, more specific tag. + # If the new tag is more specific, remove our current one for it. for parent in tag.walk_parents(): if self.has_tag(parent, check_children=False): self.photodb.log.debug('Preferring new {tag:s} over {par:s}'.format(tag=tag, par=parent)) @@ -585,10 +588,11 @@ class Photo(ObjectBase): def has_tag(self, tag, *, check_children=True): ''' - Return the Tag object if this photo contains that tag. Otherwise return False. + Return the Tag object if this photo contains that tag. + Otherwise return False. check_children: - If True, children of the requested tag are counted + If True, children of the requested tag are accepted. ''' tag = self.photodb.get_tag(tag) @@ -609,6 +613,9 @@ class Photo(ObjectBase): return False def make_thumbnail_filepath(self): + ''' + Create the filepath that should be the location of our thumbnail. + ''' chunked_id = helpers.chunk_sequence(self.id, 3) basename = chunked_id[-1] folder = chunked_id[:-1] @@ -695,8 +702,10 @@ class Photo(ObjectBase): def rename_file(self, new_filename, *, move=False, commit=True): ''' Rename the file on the disk as well as in the database. - If `move` is True, allow this operation to move the file. - Otherwise, slashes will be considered an error. + + move: + If True, allow the file to be moved into another directory. + Otherwise, the rename must be local. ''' old_path = self.real_path old_path.correct_case() @@ -856,11 +865,15 @@ class Tag(ObjectBase, GroupableMixin): ) for relationship in generator: photoid = relationship[constants.SQL_PHOTOTAG['photoid']] - query = 'SELECT * FROM photo_tag_rel WHERE photoid == ? AND tagid == ?' - cur.execute(query, [photoid, mastertag.id]) + cur.execute( + 'SELECT * FROM photo_tag_rel WHERE photoid == ? AND tagid == ?', + [photoid, mastertag.id] + ) if cur.fetchone() is None: - query = 'INSERT INTO photo_tag_rel VALUES(?, ?)' - cur.execute(query, [photoid, mastertag.id]) + cur.execute( + 'INSERT INTO photo_tag_rel VALUES(?, ?)', + [photoid, mastertag.id] + ) # Then delete the relationships with the old tag self.delete() @@ -906,7 +919,10 @@ class Tag(ObjectBase, GroupableMixin): raise exceptions.NoSuchSynonym(synname) cur = self.photodb.sql.cursor() - cur.execute('SELECT * FROM tag_synonyms WHERE mastername == ? AND name == ?', [self.name, synname]) + cur.execute( + 'SELECT * FROM tag_synonyms WHERE mastername == ? AND name == ?', + [self.name, synname] + ) fetch = cur.fetchone() if fetch is None: raise exceptions.NoSuchSynonym(synname) diff --git a/etiquette/photodb.py b/etiquette/photodb.py index 57c6464..36c371a 100644 --- a/etiquette/photodb.py +++ b/etiquette/photodb.py @@ -884,6 +884,7 @@ class PDBTagMixin: if isinstance(tagname, objects.Tag): tagname = tagname.name + tagname = tagname.strip('.+') tagname = tagname.split('.')[-1].split('+')[0] tagname = self.normalize_tagname(tagname) diff --git a/templates/photo.html b/templates/photo.html index 33dc76b..3c7c89b 100644 --- a/templates/photo.html +++ b/templates/photo.html @@ -124,6 +124,10 @@

Tags

diff --git a/test_phototagger.py b/test_phototagger.py index 541bf74..02373ea 100644 --- a/test_phototagger.py +++ b/test_phototagger.py @@ -1,215 +1,35 @@ -import os -import phototagger import unittest import random -class PhotoDBTest(unittest.TestCase): +class EtiquetteTest(unittest.TestCase): def setUp(self): self.P = phototagger.PhotoDB(':memory:') - -class AlbumTest(PhotoDBTest): - ''' - Test the creation and properties of albums - ''' - def test_create_album(self): - album = self.P.new_album() - test = self.P.get_album(album.id) - self.assertEqual(album, test) - - album = self.P.new_album(title='test1', description='test2') - self.assertEqual(album.title, 'test1') - self.assertEqual(album.description, 'test2') - - def test_delete_album_nonrecursive(self): - album = self.P.new_album() - album.delete() - self.assertRaises(phototagger.NoSuchAlbum, self.P.get_album, album.id) - - def test_edit_album(self): - album = self.P.new_album(title='t1', description='d1') - album.edit(title='t2') - self.assertEqual(album.title, 't2') - self.assertEqual(album.description, 'd1') - - album.edit(title='t3', description='d2') - self.assertEqual(album.title, 't3') - self.assertEqual(album.description, 'd2') - - album.edit(description='d3') - album = self.P.get_album(album.id) - self.assertEqual(album.title, 't3') - self.assertEqual(album.description, 'd3') +class AlbumTest(EtiquetteTest): + pass -class PhotoTest(PhotoDBTest): - ''' - Test the creation and properties of photos - ''' - def test_create_photo(self): - photo = self.P.new_photo('samples\\bolts.jpg') - self.assertGreater(photo.area, 1) - - def test_delete_photo(self): - pass - - def test_reload_metadata(self): - pass +class BookmarkTest(EtiquetteTest): + pass -class TagTest(PhotoDBTest): - ''' - Test the creation and properties of tags - ''' - def test_normalize_tagname(self): - tag = self.P.new_tag('test normalize') - self.assertEqual(tag.name, 'test_normalize') - - tag = self.P.new_tag('TEST!!NORMALIZE') - self.assertEqual(tag.name, 'testnormalize') - - self.assertRaises(phototagger.TagTooShort, self.P.new_tag, '') - self.assertRaises(phototagger.TagTooShort, self.P.new_tag, '!??*&') - self.assertRaises(phototagger.TagTooLong, self.P.new_tag, 'a'*(phototagger.MAX_TAG_NAME_LENGTH+1)) - - def test_create_tag(self): - tag = self.P.new_tag('test create tag') - self.assertEqual(tag.name, 'test_create_tag') - self.assertRaises(phototagger.TagExists, self.P.new_tag, 'test create tag') - - def test_delete_tag_nonrecursive(self): - tag = self.P.new_tag('test delete tag non') - tag.delete() - self.assertRaises(phototagger.NoSuchTag, self.P.get_tag, tag.name) - - def test_rename_tag(self): - tag = self.P.new_tag('test rename pre') - self.assertEqual(tag.name, 'test_rename_pre') - tag.rename('test rename post') - self.assertEqual(self.P.get_tag('test rename post'), tag) - self.assertRaises(phototagger.NoSuchTag, self.P.get_tag, 'test rename pre') - self.assertRaises(phototagger.TagTooShort, tag.rename, '??') - tag.rename(tag.name) # does nothing +class PhotoTest(EtiquetteTest): + pass -class SearchTest(PhotoDBTest): - def search_extension(self): - pass - def search_minmaxers(self): - pass - def search_notags(self): - pass - def search_tags(self): - pass +class PhotoDBTest(EtiquetteTest): + pass -class SynonymTest(PhotoDBTest): - ''' - Test the creation and management of synonyms - ''' - def test_create_synonym(self): - tag = self.P.new_tag('test create syn') - tag2 = self.P.new_tag('getting in the way') - tag.add_synonym('test make syn') - - test = self.P.get_tag('test make syn') - self.assertEqual(test, tag) - self.assertTrue('test_make_syn' in tag.synonyms()) - - self.assertRaises(phototagger.TagExists, tag.add_synonym, 'test make syn') - - def test_delete_synonym(self): - tag = self.P.new_tag('test del syn') - tag.add_synonym('test rem syn') - tag.remove_synonym('test rem syn') - self.assertRaises(phototagger.NoSuchSynonym, tag.remove_synonym, 'test rem syn') - - def test_convert_tag_to_synonym(self): - tag1 = self.P.new_tag('convert 1') - tag2 = self.P.new_tag('convert 2') - tag2.convert_to_synonym(tag1) - - test = self.P.get_tag(tag2) - self.assertEqual(test, tag1) - self.assertTrue('convert_2' in tag1.synonyms()) - - def test_get_synonyms(self): - tag = self.P.new_tag('test get syns') - tag.add_synonym('test get syns1') - tag.add_synonym('test get syns2') - tag.add_synonym('test get syns3') - self.assertEqual(len(tag.synonyms()), 3) +class SearchTest(EtiquetteTest): + pass -class AlbumGroupTest(PhotoDBTest): - ''' - Test the relationships between albums as they form and leave groups - ''' - def test_delete_album_recursive(self): - pass - - def test_join_album(self): - pass - - def test_leave_album(self): - pass - - def test_album_children(self): - pass - - def test_album_parents(self): - pass +class TagTest(EtiquetteTest): + pass -class TagGroupTest(PhotoDBTest): - ''' - Test the relationships between tags as they form and leave groups - ''' - def test_delete_tag_recursive(self): - pass - - def test_join_tag(self): - pass - - def test_leave_tag(self): - pass - - def test_tag_children(self): - pass - - def test_tag_parents(self): - pass - - def test_tag_qualified_name(self): - pass +class UserTest(EtiquetteTest): + pass -class AlbumPhotoTest(PhotoDBTest): - ''' - Test the relationships between albums and photos - ''' - def test_add_photo(self): - pass - - def test_remove_photo(self): - pass - - -class PhotoTagTest(PhotoDBTest): - ''' - Test the relationships between photos and tags - ''' - def test_photo_has_tag(self): - pass - - def test_add_tag(self): - pass - - def test_remove_tag(self): - pass - - - - -if __name__ == '__main__': - unittest.main()