Small cleanups
Comment and sql linewrapping; move Add Tag box to top of ul instead of bottom to stay in view better
This commit is contained in:
parent
2deff86e13
commit
b3da21bf33
4 changed files with 49 additions and 212 deletions
|
@ -357,7 +357,10 @@ class Bookmark(ObjectBase):
|
||||||
self.url = url
|
self.url = url
|
||||||
|
|
||||||
cur = self.photodb.sql.cursor()
|
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:
|
if commit:
|
||||||
self.photodb.log.debug('Committing - edit bookmark')
|
self.photodb.log.debug('Committing - edit bookmark')
|
||||||
self.photodb.sql.commit()
|
self.photodb.sql.commit()
|
||||||
|
@ -422,15 +425,15 @@ class Photo(ObjectBase):
|
||||||
if self.has_tag(tag, check_children=False):
|
if self.has_tag(tag, check_children=False):
|
||||||
return
|
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)
|
existing = self.has_tag(tag, check_children=True)
|
||||||
if existing:
|
if existing:
|
||||||
message = 'Preferring existing {exi:s} over {tag:s}'.format(exi=existing, tag=tag)
|
message = 'Preferring existing {exi:s} over {tag:s}'.format(exi=existing, tag=tag)
|
||||||
self.photodb.log.debug(message)
|
self.photodb.log.debug(message)
|
||||||
return
|
return
|
||||||
|
|
||||||
# If the tag is beneath one we already have, remove our current one
|
# If the new tag is more specific, remove our current one for it.
|
||||||
# in favor of the new, more specific tag.
|
|
||||||
for parent in tag.walk_parents():
|
for parent in tag.walk_parents():
|
||||||
if self.has_tag(parent, check_children=False):
|
if self.has_tag(parent, check_children=False):
|
||||||
self.photodb.log.debug('Preferring new {tag:s} over {par:s}'.format(tag=tag, par=parent))
|
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):
|
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:
|
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)
|
tag = self.photodb.get_tag(tag)
|
||||||
|
|
||||||
|
@ -609,6 +613,9 @@ class Photo(ObjectBase):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def make_thumbnail_filepath(self):
|
def make_thumbnail_filepath(self):
|
||||||
|
'''
|
||||||
|
Create the filepath that should be the location of our thumbnail.
|
||||||
|
'''
|
||||||
chunked_id = helpers.chunk_sequence(self.id, 3)
|
chunked_id = helpers.chunk_sequence(self.id, 3)
|
||||||
basename = chunked_id[-1]
|
basename = chunked_id[-1]
|
||||||
folder = chunked_id[:-1]
|
folder = chunked_id[:-1]
|
||||||
|
@ -695,8 +702,10 @@ class Photo(ObjectBase):
|
||||||
def rename_file(self, new_filename, *, move=False, commit=True):
|
def rename_file(self, new_filename, *, move=False, commit=True):
|
||||||
'''
|
'''
|
||||||
Rename the file on the disk as well as in the database.
|
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 = self.real_path
|
||||||
old_path.correct_case()
|
old_path.correct_case()
|
||||||
|
@ -856,11 +865,15 @@ class Tag(ObjectBase, GroupableMixin):
|
||||||
)
|
)
|
||||||
for relationship in generator:
|
for relationship in generator:
|
||||||
photoid = relationship[constants.SQL_PHOTOTAG['photoid']]
|
photoid = relationship[constants.SQL_PHOTOTAG['photoid']]
|
||||||
query = 'SELECT * FROM photo_tag_rel WHERE photoid == ? AND tagid == ?'
|
cur.execute(
|
||||||
cur.execute(query, [photoid, mastertag.id])
|
'SELECT * FROM photo_tag_rel WHERE photoid == ? AND tagid == ?',
|
||||||
|
[photoid, mastertag.id]
|
||||||
|
)
|
||||||
if cur.fetchone() is None:
|
if cur.fetchone() is None:
|
||||||
query = 'INSERT INTO photo_tag_rel VALUES(?, ?)'
|
cur.execute(
|
||||||
cur.execute(query, [photoid, mastertag.id])
|
'INSERT INTO photo_tag_rel VALUES(?, ?)',
|
||||||
|
[photoid, mastertag.id]
|
||||||
|
)
|
||||||
|
|
||||||
# Then delete the relationships with the old tag
|
# Then delete the relationships with the old tag
|
||||||
self.delete()
|
self.delete()
|
||||||
|
@ -906,7 +919,10 @@ class Tag(ObjectBase, GroupableMixin):
|
||||||
raise exceptions.NoSuchSynonym(synname)
|
raise exceptions.NoSuchSynonym(synname)
|
||||||
|
|
||||||
cur = self.photodb.sql.cursor()
|
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()
|
fetch = cur.fetchone()
|
||||||
if fetch is None:
|
if fetch is None:
|
||||||
raise exceptions.NoSuchSynonym(synname)
|
raise exceptions.NoSuchSynonym(synname)
|
||||||
|
|
|
@ -884,6 +884,7 @@ class PDBTagMixin:
|
||||||
if isinstance(tagname, objects.Tag):
|
if isinstance(tagname, objects.Tag):
|
||||||
tagname = tagname.name
|
tagname = tagname.name
|
||||||
|
|
||||||
|
tagname = tagname.strip('.+')
|
||||||
tagname = tagname.split('.')[-1].split('+')[0]
|
tagname = tagname.split('.')[-1].split('+')[0]
|
||||||
tagname = self.normalize_tagname(tagname)
|
tagname = self.normalize_tagname(tagname)
|
||||||
|
|
||||||
|
|
|
@ -124,6 +124,10 @@
|
||||||
<!-- TAG INFO -->
|
<!-- TAG INFO -->
|
||||||
<h4>Tags</h4>
|
<h4>Tags</h4>
|
||||||
<ul id="this_tags">
|
<ul id="this_tags">
|
||||||
|
<li>
|
||||||
|
<input id="add_tag_textbox" type="text" autofocus>
|
||||||
|
<button id="add_tag_button" class="add_tag_button" onclick="submit_tag(receive_callback);">add</button>
|
||||||
|
</li>
|
||||||
{% set tags = photo.sorted_tags() %}
|
{% set tags = photo.sorted_tags() %}
|
||||||
{% for tag in tags %}
|
{% for tag in tags %}
|
||||||
<li>
|
<li>
|
||||||
|
@ -134,10 +138,6 @@
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<li>
|
|
||||||
<input id="add_tag_textbox" type="text" autofocus>
|
|
||||||
<button id="add_tag_button" class="add_tag_button" onclick="submit_tag(receive_callback);">add</button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<!-- METADATA & DOWNLOAD -->
|
<!-- METADATA & DOWNLOAD -->
|
||||||
|
|
|
@ -1,215 +1,35 @@
|
||||||
import os
|
|
||||||
import phototagger
|
|
||||||
import unittest
|
import unittest
|
||||||
import random
|
import random
|
||||||
|
|
||||||
class PhotoDBTest(unittest.TestCase):
|
class EtiquetteTest(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.P = phototagger.PhotoDB(':memory:')
|
self.P = phototagger.PhotoDB(':memory:')
|
||||||
|
|
||||||
|
class AlbumTest(EtiquetteTest):
|
||||||
class AlbumTest(PhotoDBTest):
|
pass
|
||||||
'''
|
|
||||||
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 PhotoTest(PhotoDBTest):
|
class BookmarkTest(EtiquetteTest):
|
||||||
'''
|
pass
|
||||||
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 TagTest(PhotoDBTest):
|
class PhotoTest(EtiquetteTest):
|
||||||
'''
|
pass
|
||||||
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 SearchTest(PhotoDBTest):
|
class PhotoDBTest(EtiquetteTest):
|
||||||
def search_extension(self):
|
pass
|
||||||
pass
|
|
||||||
def search_minmaxers(self):
|
|
||||||
pass
|
|
||||||
def search_notags(self):
|
|
||||||
pass
|
|
||||||
def search_tags(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class SynonymTest(PhotoDBTest):
|
class SearchTest(EtiquetteTest):
|
||||||
'''
|
pass
|
||||||
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 AlbumGroupTest(PhotoDBTest):
|
class TagTest(EtiquetteTest):
|
||||||
'''
|
pass
|
||||||
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 TagGroupTest(PhotoDBTest):
|
class UserTest(EtiquetteTest):
|
||||||
'''
|
pass
|
||||||
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 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()
|
|
||||||
|
|
Loading…
Reference in a new issue