From 94ad93ebd789a50c9f32c78e2eeaa861a069eb1a Mon Sep 17 00:00:00 2001 From: Ozzie Isaacs Date: Sat, 25 Jul 2020 19:39:19 +0200 Subject: [PATCH] Added series like custom columns #1501 --- cps/db.py | 76 ++++++++++++++++++++++-------------- cps/jinjia.py | 7 ++++ cps/templates/book_edit.html | 17 ++++---- cps/templates/detail.html | 8 +++- 4 files changed, 69 insertions(+), 39 deletions(-) diff --git a/cps/db.py b/cps/db.py index 1296c84a..014a615d 100644 --- a/cps/db.py +++ b/cps/db.py @@ -34,6 +34,7 @@ from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.exc import OperationalError from flask_login import current_user from sqlalchemy.sql.expression import and_, true, false, text, func, or_ +from sqlalchemy.ext.associationproxy import association_proxy from babel import Locale as LC from babel.core import UnknownLocaleError from flask_babel import gettext as _ @@ -48,7 +49,7 @@ except ImportError: use_unidecode = False -cc_exceptions = ['datetime', 'comments', 'composite', 'series'] +cc_exceptions = ['datetime', 'comments', 'composite'] cc_classes = {} Base = declarative_base() @@ -280,7 +281,7 @@ class Books(Base): flags = Column(Integer, nullable=False, default=1) authors = relationship('Authors', secondary=books_authors_link, backref='books') - tags = relationship('Tags', secondary=books_tags_link, backref='books',order_by="Tags.name") + tags = relationship('Tags', secondary=books_tags_link, backref='books', order_by="Tags.name") comments = relationship('Comments', backref='books') data = relationship('Data', backref='books') series = relationship('Series', secondary=books_series_link, backref='books') @@ -406,33 +407,45 @@ class CalibreDB(threading.Thread): books_custom_column_links = {} for row in cc: if row.datatype not in cc_exceptions: - books_custom_column_links[row.id] = Table('books_custom_column_' + str(row.id) + '_link', Base.metadata, - Column('book', Integer, ForeignKey('books.id'), - primary_key=True), - Column('value', Integer, - ForeignKey('custom_column_' + str(row.id) + '.id'), - primary_key=True) - ) - cc_ids.append([row.id, row.datatype]) - if row.datatype == 'bool': - ccdict = {'__tablename__': 'custom_column_' + str(row.id), - 'id': Column(Integer, primary_key=True), - 'book': Column(Integer, ForeignKey('books.id')), - 'value': Column(Boolean)} - elif row.datatype == 'int': - ccdict = {'__tablename__': 'custom_column_' + str(row.id), - 'id': Column(Integer, primary_key=True), - 'book': Column(Integer, ForeignKey('books.id')), - 'value': Column(Integer)} - elif row.datatype == 'float': - ccdict = {'__tablename__': 'custom_column_' + str(row.id), - 'id': Column(Integer, primary_key=True), - 'book': Column(Integer, ForeignKey('books.id')), - 'value': Column(Float)} + if row.datatype == 'series': + dicttable = {'__tablename__': 'books_custom_column_' + str(row.id) + '_link', + 'id': Column(Integer, primary_key=True), + 'book': Column(Integer, ForeignKey('books.id'), + primary_key=True), + 'map_value': Column('value', Integer, + ForeignKey('custom_column_' + + str(row.id) + '.id'), + primary_key=True), + 'extra': Column(Float), + 'asoc' : relationship('Custom_Column_' + str(row.id), uselist=False), + 'value' : association_proxy('asoc', 'value') + } + books_custom_column_links[row.id] = type(str('Books_Custom_Column_' + str(row.id) + '_link'), + (Base,), dicttable) else: - ccdict = {'__tablename__': 'custom_column_' + str(row.id), - 'id': Column(Integer, primary_key=True), - 'value': Column(String)} + books_custom_column_links[row.id] = Table('books_custom_column_' + str(row.id) + '_link', + Base.metadata, + Column('book', Integer, ForeignKey('books.id'), + primary_key=True), + Column('value', Integer, + ForeignKey('custom_column_' + + str(row.id) + '.id'), + primary_key=True) + ) + cc_ids.append([row.id, row.datatype]) + + ccdict = {'__tablename__': 'custom_column_' + str(row.id), + 'id': Column(Integer, primary_key=True)} + if row.datatype == 'float': + ccdict['value'] = Column(Float) + elif row.datatype == 'int': + ccdict['value'] = Column(Integer) + elif row.datatype == 'bool': + ccdict['value'] = Column(Boolean) + else: + ccdict['value'] = Column(String) + if row.datatype in ['float', 'int', 'bool']: + ccdict['book'] = Column(Integer, ForeignKey('books.id')) cc_classes[row.id] = type(str('Custom_Column_' + str(row.id)), (Base,), ccdict) for cc_id in cc_ids: @@ -440,9 +453,14 @@ class CalibreDB(threading.Thread): setattr(Books, 'custom_column_' + str(cc_id[0]), relationship(cc_classes[cc_id[0]], - primaryjoin=( + primaryjoin=( # ToDo: Check Remove Books.id == cc_classes[cc_id[0]].book), backref='books')) + elif (cc_id[1] == 'series'): + setattr(Books, + 'custom_column_' + str(cc_id[0]), + relationship(books_custom_column_links[cc_id[0]], + backref='books')) else: setattr(Books, 'custom_column_' + str(cc_id[0]), diff --git a/cps/jinjia.py b/cps/jinjia.py index 28c2621a..c91534eb 100644 --- a/cps/jinjia.py +++ b/cps/jinjia.py @@ -111,3 +111,10 @@ def timestamptodate(date, fmt=None): @jinjia.app_template_filter('yesno') def yesno(value, yes, no): return yes if value else no + +@jinjia.app_template_filter('formatfloat') +def formatfloat(value, decimals=1): + formatedstring = '%d' % value + if (value % 1) != 0: + formatedstring = ('%s.%d' % (formatedstring, (value % 1) * 10**decimals)).rstrip('0') + return formatedstring diff --git a/cps/templates/book_edit.html b/cps/templates/book_edit.html index 8bbe2460..96620a35 100644 --- a/cps/templates/book_edit.html +++ b/cps/templates/book_edit.html @@ -132,19 +132,20 @@ {% endif %} - {% if c.datatype in ['text', 'series'] and not c.is_multiple %} - 0 %} - value="{{ book['custom_column_' ~ c.id][0].value }}" - {% endif %}> - {% endif %} - - {% if c.datatype in ['text', 'series'] and c.is_multiple %} + {% if c.datatype == 'text' %} 0 %} value="{% for column in book['custom_column_' ~ c.id] %}{{ column.value.strip() }}{% if not loop.last %}, {% endif %}{% endfor %}"{% endif %}> {% endif %} + {% if c.datatype == 'series' %} + 0 %} + value="{% for column in book['custom_column_' ~ c.id] %} {{ '%s [%s]' % (book['custom_column_' ~ c.id][0].value, book['custom_column_' ~ c.id][0].extra|formatfloat(2)) }}{% if not loop.last %}, {% endif %}{% endfor %}" + {% endif %}> + {% endif %} + + {% if c.datatype == 'enumeration' %}