Verified Commit 998399d5 authored by Patrick van der Leer's avatar Patrick van der Leer
Browse files

mid work commit

parent 96e09ad7
......@@ -26,7 +26,6 @@ def init(config_object=ProdConfig):
CORS(app, resources={r'/api/*': {"origins": "*"}})
configure_extensions(app)
configure_logging(app)
configure_error_handlers(app)
configure_blueprints(app)
configure_shellcontext(app)
......@@ -43,12 +42,9 @@ def configure_extensions(app):
ext.bcrypt.init_app(app)
ext.cache.init_app(app)
ext.db.init_app(app)
import eBookHub.models.core
ext.migrate.init_app(app, db)
ext.login_manager.init_app(app)
ext.redis.init_app(app)
if app.config.get("SENTRY") and not app.testing:
ext.sentry.init_app(app)
if app.config['DEBUG_TB_ENABLED']:
from flask_debugtoolbar import DebugToolbarExtension
......
from inspect import isfunction, ismethod
from datetime import datetime as dt
from sqlalchemy.ext.declarative import DeclarativeMeta
from sqlalchemy.orm.collections import InstrumentedList
from .extensions import db
class PrettyPrint:
_exclude_from_meta_dump: list = []
def __unicode__(self):
return "[%s(%s)]" % (self.__class__.__name__, ', '.join(
'%s=%s' % (k, self.__dict__[k]) for k in sorted(self.__dict__) if '_sa_' != k[:4]))
def serialize(self, _visited_objs=None):
if _visited_objs is None:
_visited_objs = []
def _serialize(obj, versions=True):
if isinstance(obj.__class__, DeclarativeMeta):
# don't re-visit self
if obj in _visited_objs:
return None
_visited_objs.append(self)
# an SQLAlchemy class
fields = {}
skip = ["metadata", "query", "query_class"]
for field in [x for x in dir(obj) if not x.startswith('_') and x not in skip]:
# temp fix
if isfunction(obj.__getattribute__(field)) or ismethod(obj.__getattribute__(field)):
continue
from flask_sqlalchemy import BaseQuery
from sqlalchemy.orm.dynamic import AppenderQuery
if isinstance(obj.__getattribute__(field), dt):
fields[field] = str(obj.__getattribute__(field))
elif field == "versions" and versions:
fields[field] = [_serialize(version, False) for version in obj.versions]
elif isinstance(obj.__getattribute__(field), BaseQuery):
fields[field] = []
for y in obj.__getattribute__(field):
if not hasattr(y, 'serialize'):
continue
tmp = y.serialize(_visited_objs)
if tmp is not None and len(tmp) > 0:
fields[field].append(tmp)
elif isinstance(obj.__getattribute__(field), db.Model):
if not hasattr(obj.__getattribute__(field), 'serialize'):
continue
tmp = obj.__getattribute__(field).serialize(_visited_objs)
if tmp and len(tmp) > 0:
fields[field] = tmp
elif isinstance(obj.__getattribute__(field), InstrumentedList):
entries = [x.serialize(_visited_objs) for x in obj.__getattribute__(field)]
if len(entries) > 0:
fields[field] = entries
else:
try:
fields[field] = obj.__getattribute__(field).decode()
except AttributeError:
fields[field] = obj.__getattribute__(field)
return fields
return _serialize(self)
class SoftDeleteMixin(object):
deleted = db.Column(db.Boolean, default=False)
def delete(self, commit=True, hard_delete=False):
"""Remove/SoftDelete the record from the database."""
if hard_delete:
db.session.delete(self)
else:
self.deleted = True
return commit and db.session.commit()
def soft_delete(self, commit=True):
return self.delete(commit=commit, hard_delete=False)
def hard_delete(self, commit=True):
return self.delete(commit=commit, hard_delete=True)
class Model(db.Model, PrettyPrint):
"""Base model class that includes CRUD convenience methods."""
__abstract__ = True
def __init__(self, *arg, **kwargs):
"""To prevent IDE from bitching about wrong arguments"""
super().__init__(*arg, **kwargs)
def get_field_names(self):
for p in self.__mapper__.iterate_properties:
yield p.key
__all__ = [
db,
Model
]
class Author(object):
name = None
sortable_name = None
from sqlalchemy.orm import validates
from eBookHub.database import Model, db
from eBookHub.validators.isbn import validate_isbn10, validate_isbn13
Column = db.Column
class Author(Model):
id = db.Column(db.Integer, primary_key=True)
name = Column(db.String(255))
sortable_name = Column(db.String(255))
def set_name(self, name):
self.name = name
# todo
self.sortable_name = name
class Book(object):
title = None
sortable_title = None
authors = []
class Book(Model):
id = db.Column(db.Integer, primary_key=True)
title = Column(db.String(255))
sortable_title = Column(db.String(255))
# authors = []
class BookEdition(object):
......@@ -32,26 +43,12 @@ class BookEdition(object):
rating = None
publisher = None
def set_title(self, title):
self.title = title
# self.sortable_title = title_sort(title)
def lookup_author(self, name):
for author in self.authors:
if author.name == name or author.sortable_name == name:
return author
return False
def set_authors(self, authors):
if isinstance(authors, list):
for author in authors:
self.add_author(author)
else:
self.add_author(authors)
def add_author(self, author):
if self.lookup_author(author):
return
_author = Author()
_author.set_name(author)
self.authors.append(_author)
@validates('isbn_10')
def validate_isbn_10(self, key, value):
validate_isbn10(value)
return value
@validates('isbn_13')
def validate_isbn_13(self, key, value):
validate_isbn13(value)
return value
import random
import factory
from eBookHub import db
from eBookHub.models.core import Author, Book
class AuthorFactory(factory.alchemy.SQLAlchemyModelFactory):
class Meta:
model = Author
sqlalchemy_session = db.session
id = factory.Sequence(lambda n: n)
name = factory.Faker('name')
class BookFactory(factory.alchemy.SQLAlchemyModelFactory):
class Meta:
model = Book
sqlalchemy_session = db.session
id = factory.Sequence(lambda n: n)
title = factory.Faker('name')
@factory.post_generation
def authors(self, create, extracted, **kwargs):
return AuthorFactory.create_batch(random.randint(1, 4))
import os
from flask.helpers import get_debug_flag
from pycountry import languages as pycountry_languages
from .config import DevConfig, TestConfig, ProdConfig
languages = {language.alpha_2: language.name for language in pycountry_languages if hasattr(language, 'alpha_2')}
def get_config():
if get_debug_flag():
......@@ -12,9 +13,16 @@ def get_config():
return TestConfig
return ProdConfig
def get_test_flag(default=None):
env = os.environ
val = env.get('FLASK_TEST') or env.get('FLASK_TESTING')
if not val:
return default
return val not in ('0', 'false', 'no')
__all__ = [
languages,
get_config
]
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment