Give Tags a description field.
This commit is contained in:
		
							parent
							
								
									a485be3c64
								
							
						
					
					
						commit
						a4a278c173
					
				
					 8 changed files with 60 additions and 16 deletions
				
			
		|  | @ -65,6 +65,7 @@ SQL_PHOTO_COLUMNS = [ | ||||||
| SQL_TAG_COLUMNS = [ | SQL_TAG_COLUMNS = [ | ||||||
|     'id', |     'id', | ||||||
|     'name', |     'name', | ||||||
|  |     'description', | ||||||
| ] | ] | ||||||
| SQL_SYN_COLUMNS = [ | SQL_SYN_COLUMNS = [ | ||||||
|     'name', |     'name', | ||||||
|  | @ -161,8 +162,9 @@ DEFAULT_CONFIGURATION = { | ||||||
|     'enable_new_tag': True, |     'enable_new_tag': True, | ||||||
|     'enable_new_user': True, |     'enable_new_user': True, | ||||||
|     'enable_photo_add_remove_tag': True, |     'enable_photo_add_remove_tag': True, | ||||||
|     'enable_photo_reload_metadata': True, |  | ||||||
|     'enable_photo_generate_thumbnail': True, |     'enable_photo_generate_thumbnail': True, | ||||||
|  |     'enable_photo_reload_metadata': True, | ||||||
|  |     'enable_tag_edit': True, | ||||||
| 
 | 
 | ||||||
|     'min_tag_name_length': 1, |     'min_tag_name_length': 1, | ||||||
|     'max_tag_name_length': 32, |     'max_tag_name_length': 32, | ||||||
|  |  | ||||||
|  | @ -52,6 +52,7 @@ def tag(t, include_synonyms=False): | ||||||
|     j = { |     j = { | ||||||
|         'id': t.id, |         'id': t.id, | ||||||
|         'name': t.name, |         'name': t.name, | ||||||
|  |         'description': t.description, | ||||||
|         'qualified_name': t.qualified_name(), |         'qualified_name': t.qualified_name(), | ||||||
|     } |     } | ||||||
|     if include_synonyms: |     if include_synonyms: | ||||||
|  |  | ||||||
|  | @ -223,8 +223,8 @@ class Album(ObjectBase, GroupableMixin): | ||||||
|         if isinstance(db_row, (list, tuple)): |         if isinstance(db_row, (list, tuple)): | ||||||
|             db_row = dict(zip(constants.SQL_ALBUM_COLUMNS, db_row)) |             db_row = dict(zip(constants.SQL_ALBUM_COLUMNS, db_row)) | ||||||
|         self.id = db_row['id'] |         self.id = db_row['id'] | ||||||
|         self.title = db_row['title'] |         self.title = db_row['title'] or '' | ||||||
|         self.description = db_row['description'] |         self.description = db_row['description'] or '' | ||||||
|         self.name = 'Album %s' % self.id |         self.name = 'Album %s' % self.id | ||||||
|         self.group_getter = self.photodb.get_album |         self.group_getter = self.photodb.get_album | ||||||
|         self._sum_bytes_photos = None |         self._sum_bytes_photos = None | ||||||
|  | @ -501,6 +501,7 @@ class Photo(ObjectBase): | ||||||
| 
 | 
 | ||||||
|         if self.duration: |         if self.duration: | ||||||
|             self.bitrate = (self.bytes / 128) / self.duration |             self.bitrate = (self.bytes / 128) / self.duration | ||||||
|  | 
 | ||||||
|         self.mimetype = helpers.get_mimetype(self.real_filepath) |         self.mimetype = helpers.get_mimetype(self.real_filepath) | ||||||
|         if self.mimetype is None: |         if self.mimetype is None: | ||||||
|             self.simple_mimetype = None |             self.simple_mimetype = None | ||||||
|  | @ -954,6 +955,7 @@ class Tag(ObjectBase, GroupableMixin): | ||||||
|             db_row = dict(zip(constants.SQL_TAG_COLUMNS, db_row)) |             db_row = dict(zip(constants.SQL_TAG_COLUMNS, db_row)) | ||||||
|         self.id = db_row['id'] |         self.id = db_row['id'] | ||||||
|         self.name = db_row['name'] |         self.name = db_row['name'] | ||||||
|  |         self.description = db_row['description'] or '' | ||||||
|         self.group_getter = self.photodb.get_tag |         self.group_getter = self.photodb.get_tag | ||||||
|         self._cached_qualified_name = None |         self._cached_qualified_name = None | ||||||
| 
 | 
 | ||||||
|  | @ -1063,6 +1065,25 @@ class Tag(ObjectBase, GroupableMixin): | ||||||
|             self.photodb.log.debug('Committing - delete tag') |             self.photodb.log.debug('Committing - delete tag') | ||||||
|             self.photodb.commit() |             self.photodb.commit() | ||||||
| 
 | 
 | ||||||
|  |     @decorators.required_feature('enable_tag_edit') | ||||||
|  |     @decorators.transaction | ||||||
|  |     def edit(self, description=None, *, commit=True): | ||||||
|  |         ''' | ||||||
|  |         Change the description. Leave None to keep current value. | ||||||
|  |         ''' | ||||||
|  |         if description is None: | ||||||
|  |             description = self.description | ||||||
|  |         cur = self.photodb.sql.cursor() | ||||||
|  |         cur.execute( | ||||||
|  |             'UPDATE tags SET description = ? WHERE id == ?', | ||||||
|  |             [description, self.id] | ||||||
|  |         ) | ||||||
|  |         self.description = description | ||||||
|  |         self._uncache() | ||||||
|  |         if commit: | ||||||
|  |             self.photodb.log.debug('Committing - edit tag') | ||||||
|  |             self.photodb.commit() | ||||||
|  | 
 | ||||||
|     def qualified_name(self): |     def qualified_name(self): | ||||||
|         ''' |         ''' | ||||||
|         Return the 'group1.group2.tag' string for this tag. |         Return the 'group1.group2.tag' string for this tag. | ||||||
|  | @ -1107,7 +1128,8 @@ class Tag(ObjectBase, GroupableMixin): | ||||||
|         Rename the tag. Does not affect its relation to Photos or tag groups. |         Rename the tag. Does not affect its relation to Photos or tag groups. | ||||||
|         ''' |         ''' | ||||||
|         new_name = self.photodb.normalize_tagname(new_name) |         new_name = self.photodb.normalize_tagname(new_name) | ||||||
|         if new_name == self.name: |         old_name = self.name | ||||||
|  |         if new_name == old_name: | ||||||
|             return |             return | ||||||
| 
 | 
 | ||||||
|         try: |         try: | ||||||
|  | @ -1124,7 +1146,7 @@ class Tag(ObjectBase, GroupableMixin): | ||||||
|         if apply_to_synonyms: |         if apply_to_synonyms: | ||||||
|             cur.execute( |             cur.execute( | ||||||
|                 'UPDATE tag_synonyms SET mastername = ? WHERE mastername = ?', |                 'UPDATE tag_synonyms SET mastername = ? WHERE mastername = ?', | ||||||
|                 [new_name, self.name] |                 [new_name, old_name] | ||||||
|             ) |             ) | ||||||
| 
 | 
 | ||||||
|         self.name = new_name |         self.name = new_name | ||||||
|  |  | ||||||
|  | @ -28,7 +28,7 @@ logging.getLogger('PIL.PngImagePlugin').setLevel(logging.WARNING) | ||||||
| # Note: Setting user_version pragma in init sequence is safe because it only | # Note: Setting user_version pragma in init sequence is safe because it only | ||||||
| # happens after the out-of-date check occurs, so no chance of accidentally | # happens after the out-of-date check occurs, so no chance of accidentally | ||||||
| # overwriting it. | # overwriting it. | ||||||
| DATABASE_VERSION = 7 | DATABASE_VERSION = 8 | ||||||
| DB_INIT = ''' | DB_INIT = ''' | ||||||
| PRAGMA count_changes = OFF; | PRAGMA count_changes = OFF; | ||||||
| PRAGMA cache_size = 10000; | PRAGMA cache_size = 10000; | ||||||
|  | @ -125,7 +125,8 @@ CREATE INDEX IF NOT EXISTS index_tag_synonyms_name on tag_synonyms(name); | ||||||
| ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ||||||
| CREATE TABLE IF NOT EXISTS tags( | CREATE TABLE IF NOT EXISTS tags( | ||||||
|     id TEXT, |     id TEXT, | ||||||
|     name TEXT |     name TEXT, | ||||||
|  |     description TEXT | ||||||
| ); | ); | ||||||
| CREATE INDEX IF NOT EXISTS index_tags_id on tags(id); | CREATE INDEX IF NOT EXISTS index_tags_id on tags(id); | ||||||
| CREATE INDEX IF NOT EXISTS index_tags_name on tags(name); | CREATE INDEX IF NOT EXISTS index_tags_name on tags(name); | ||||||
|  | @ -961,7 +962,7 @@ class PDBTagMixin: | ||||||
| 
 | 
 | ||||||
|     @decorators.required_feature('enable_new_tag') |     @decorators.required_feature('enable_new_tag') | ||||||
|     @decorators.transaction |     @decorators.transaction | ||||||
|     def new_tag(self, tagname, *, commit=True): |     def new_tag(self, tagname, description=None, *, commit=True): | ||||||
|         ''' |         ''' | ||||||
|         Register a new tag and return the Tag object. |         Register a new tag and return the Tag object. | ||||||
|         ''' |         ''' | ||||||
|  | @ -976,11 +977,18 @@ class PDBTagMixin: | ||||||
|         tagid = self.generate_id('tags') |         tagid = self.generate_id('tags') | ||||||
|         self._cached_frozen_children = None |         self._cached_frozen_children = None | ||||||
|         cur = self.sql.cursor() |         cur = self.sql.cursor() | ||||||
|         cur.execute('INSERT INTO tags VALUES(?, ?)', [tagid, tagname]) |         data = { | ||||||
|  |             'id': tagid, | ||||||
|  |             'name': tagname, | ||||||
|  |             'description': description, | ||||||
|  |         } | ||||||
|  |         (qmarks, bindings) = helpers.binding_filler(constants.SQL_TAG_COLUMNS, data) | ||||||
|  |         query = 'INSERT INTO tags VALUES(%s)' % qmarks | ||||||
|  |         cur.execute(query, bindings) | ||||||
|         if commit: |         if commit: | ||||||
|             self.log.debug('Committing - new_tag') |             self.log.debug('Committing - new_tag') | ||||||
|             self.commit() |             self.commit() | ||||||
|         tag = objects.Tag(self, [tagid, tagname]) |         tag = objects.Tag(self, data) | ||||||
|         return tag |         return tag | ||||||
| 
 | 
 | ||||||
|     def normalize_tagname(self, tagname): |     def normalize_tagname(self, tagname): | ||||||
|  |  | ||||||
|  | @ -524,8 +524,8 @@ def get_search_core(): | ||||||
|     total_tags = set() |     total_tags = set() | ||||||
|     for photo in photos: |     for photo in photos: | ||||||
|         for tag in photo.tags(): |         for tag in photo.tags(): | ||||||
|             total_tags.add(tag.qualified_name()) |             total_tags.add(tag) | ||||||
|     total_tags = sorted(total_tags) |     total_tags = sorted(total_tags, key=lambda t: t.qualified_name()) | ||||||
| 
 | 
 | ||||||
|     # PREV-NEXT PAGE URLS |     # PREV-NEXT PAGE URLS | ||||||
|     offset = search_kwargs['offset'] or 0 |     offset = search_kwargs['offset'] or 0 | ||||||
|  | @ -613,6 +613,7 @@ def get_tags_html(specific_tag=None): | ||||||
|         'tags.html', |         'tags.html', | ||||||
|         include_synonyms=include_synonyms, |         include_synonyms=include_synonyms, | ||||||
|         session=session, |         session=session, | ||||||
|  |         specific_tag=specific_tag, | ||||||
|         tags=tags, |         tags=tags, | ||||||
|     ) |     ) | ||||||
|     return response |     return response | ||||||
|  |  | ||||||
|  | @ -270,7 +270,7 @@ form | ||||||
|         <span>Tags on this page (click to join query):</span> |         <span>Tags on this page (click to join query):</span> | ||||||
|         <ul> |         <ul> | ||||||
|             {% for tag in total_tags %} |             {% for tag in total_tags %} | ||||||
|             <li><a href="" class="tag_object">{{tag}}</a></li> |             <li><a href="javascript:void(0)" title="{{tag.description}}" class="tag_object tags_on_this_page">{{tag.name}}</a></li> | ||||||
|             {% endfor %} |             {% endfor %} | ||||||
|         </ul> |         </ul> | ||||||
|         {% endif %} |         {% endif %} | ||||||
|  | @ -560,7 +560,7 @@ var inputted_forbids = []; | ||||||
| {% endfor %} | {% endfor %} | ||||||
| 
 | 
 | ||||||
| /* Assign the click handler to "Tags on this page" results. */ | /* Assign the click handler to "Tags on this page" results. */ | ||||||
| var found_on_page = document.getElementsByClassName("tag_object"); | var found_on_page = document.getElementsByClassName("tags_on_this_page"); | ||||||
| for (var index = 0; index < found_on_page.length; index += 1) | for (var index = 0; index < found_on_page.length; index += 1) | ||||||
| { | { | ||||||
|     var tag_object = found_on_page[index]; |     var tag_object = found_on_page[index]; | ||||||
|  |  | ||||||
|  | @ -67,11 +67,15 @@ body | ||||||
| {{header.make_header(session=session)}} | {{header.make_header(session=session)}} | ||||||
| <div id="content_body"> | <div id="content_body"> | ||||||
|     <div id="left"> |     <div id="left"> | ||||||
|  |         {% if specific_tag is not none %} | ||||||
|  |         <h1>{{specific_tag.name}}</h1> | ||||||
|  |         <p>{{specific_tag.description}}</p> | ||||||
|  |         {% endif %} | ||||||
|         <ul> |         <ul> | ||||||
|             {% for tag in tags %} |             {% for tag in tags %} | ||||||
|             {% set qualified_name = tag.qualified_name() %} |             {% set qualified_name = tag.qualified_name() %} | ||||||
|             <li> |             <li> | ||||||
|                 <a target="_blank" class="tag_object" href="/search?tag_musts={{tag.name}}">{{qualified_name}}</a><!-- |                 <a target="_blank" class="tag_object" title="{{tag.description}}" href="/search?tag_musts={{tag.name}}">{{qualified_name}}</a><!-- | ||||||
|                 --><button class="remove_tag_button" onclick="delete_tag('{{tag.name}}', receive_callback);"></button> |                 --><button class="remove_tag_button" onclick="delete_tag('{{tag.name}}', receive_callback);"></button> | ||||||
|             </li> |             </li> | ||||||
|             {% if include_synonyms %} |             {% if include_synonyms %} | ||||||
|  |  | ||||||
|  | @ -118,7 +118,6 @@ def upgrade_6_to_7(sql): | ||||||
|     for index in indices: |     for index in indices: | ||||||
|         cur.execute('DROP INDEX %s' % index) |         cur.execute('DROP INDEX %s' % index) | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|     cur.execute(''' |     cur.execute(''' | ||||||
|     CREATE TABLE album_associated_directories( |     CREATE TABLE album_associated_directories( | ||||||
|         albumid TEXT, |         albumid TEXT, | ||||||
|  | @ -140,6 +139,13 @@ def upgrade_6_to_7(sql): | ||||||
|     ''') |     ''') | ||||||
|     cur.execute('DROP TABLE deleting_albums') |     cur.execute('DROP TABLE deleting_albums') | ||||||
| 
 | 
 | ||||||
|  | def upgrade_7_to_8(sql): | ||||||
|  |     ''' | ||||||
|  |     Give the Tags table a description field. | ||||||
|  |     ''' | ||||||
|  |     cur = sql.cursor() | ||||||
|  |     cur.execute('ALTER TABLE tags ADD COLUMN description TEXT') | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| def upgrade_all(database_filename): | def upgrade_all(database_filename): | ||||||
|     ''' |     ''' | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue