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