Fix relationships between site and the menu models.

Make strings consistent across API.
This commit is contained in:
Dorian 2016-11-21 23:56:15 -05:00
parent 6520e57696
commit b229400557
9 changed files with 33 additions and 20 deletions

View File

@ -121,5 +121,5 @@ desc("Bootstrap DB")
task("bootstrap", function()
exec("docker-compose", "up", "-d", "db")
local db_connection_flag = string.format("--db-connection=%s", db_connection)
exec("docker-compose", "run", "api", "inv", "db.bootstrap", db_connection_flag)
exec("docker-compose", "run", "api", "inv", "db.bootstrap", db_connection_flag, '--reset-db')
end)

View File

@ -41,7 +41,7 @@ def make_json_app(import_name, **kwargs):
error_code = http.HTTPStatus.INTERNAL_SERVER_ERROR
if isinstance(error, exceptions.HTTPException):
error_code = error.code
error_json = {"error": {"code": error_code, "message": error_message}}
error_json = {'error': {'code': error_code, 'message': error_message}}
response = flask.jsonify(error_json)
response.status_code = error_code

View File

@ -18,6 +18,7 @@ def register_views():
rookeries_views = [
'rookeries.views',
'rookeries.pages.views',
'rookeries.sites.views',
'rookeries.security',
]
for views_modules in rookeries_views:

View File

@ -28,7 +28,7 @@ class Page(database.ModelBase):
self.content = content
def __repr__(self) -> str:
return '<JournalEntry %r>' % self.slug
return '<JournalEntry {!r}>'.format(self.slug)
def to_json(self) -> dict:
return {

View File

@ -20,7 +20,7 @@ from rookeries.main import rookeries_app
logger = logging.getLogger(__name__)
@rookeries_app.route("/api/pages", methods=['GET'])
@rookeries_app.route('/api/pages', methods=['GET'])
def serve_landing_page():
"""
Serving up a landing page with Markdown content.
@ -28,10 +28,10 @@ def serve_landing_page():
:request page: The name of the page to display.
"""
# TODO: Remove hardcoding of landing url
return serve_page("about")
return serve_page('about')
@rookeries_app.route("/api/pages/<slug>", methods=['GET'])
@rookeries_app.route('/api/pages/<slug>', methods=['GET'])
def serve_page(slug):
"""
Serving up a page with Markdown content.
@ -45,18 +45,18 @@ def serve_page(slug):
try:
journal_entry = db_session.query(models.Page).filter_by(slug=slug).first()
except Exception as err:
logger.error("Error retrieving '%s' page because of: %s", slug, err)
logger.error('Error retrieving "%s" page because of: %s', slug, err)
flask.abort(http.HTTPStatus.INTERNAL_SERVER_ERROR)
if journal_entry is None:
logger.warn("Unable to find retrieve page: %s", slug)
logger.warn('Unable to find retrieve page: %s', slug)
flask.abort(http.HTTPStatus.NOT_FOUND)
return flask.jsonify(journal_entry.to_json())
@flask_jwt.jwt_required
@rookeries_app.route("/api/pages/<slug>", methods=['POST', 'PUT'])
@rookeries_app.route('/api/pages/<slug>', methods=['POST', 'PUT'])
def save_page(slug):
updated_journal_entry = flask.request.json
db_session = database.SQLAlchemy.session
@ -70,7 +70,7 @@ def save_page(slug):
content=updated_journal_entry['content'])
db_session.add(journal_entry)
except Exception as err:
logger.error("Error retrieving '%s' page because of: %s", slug, err)
logger.error('Error retrieving "%s" page because of: %s', slug, err)
flask.abort(http.HTTPStatus.INTERNAL_SERVER_ERROR)
else:
journal_entry.slug = slug

View File

@ -22,7 +22,6 @@ class Site(database.ModelBase):
# TODO: Add in tag line, copyright notice, favicon and logo image, other attributes in here.
config = sqlalchemy.Column(sqlalchemy.JSON)
menu = orm.relationship("SiteMap", order_by="SiteMenu.orderinal", back_populates="site")
def __init__(self, name, url, config=None):
self.name = name
@ -30,7 +29,7 @@ class Site(database.ModelBase):
self.config = config or {}
def __repr__(self) -> str:
return '<Site %r - %r>' % self.name, self.url
return '<Site {!r} - {!r}>'.format(self.name, self.url)
def to_json(self) -> dict:
return {
@ -47,8 +46,12 @@ class SiteMenu(database.ModelBase):
id = sqlalchemy.Column(sqlalchemy.Integer(), primary_key=True)
orderinal = sqlalchemy.Column(sqlalchemy.Integer(), unique=True)
title = sqlalchemy.Column(sqlalchemy.String())
site = orm.relationship("Site", back_populates="menu")
page = orm.relationship("Page")
site_id = sqlalchemy.Column(sqlalchemy.Integer(), sqlalchemy.ForeignKey('site.id'))
site = orm.relationship('Site', back_populates='menu')
page_id = sqlalchemy.Column(sqlalchemy.Integer(), sqlalchemy.ForeignKey('page.id'))
page = orm.relationship('Page')
def __init__(self, title, site, page):
self.title = title
@ -56,10 +59,14 @@ class SiteMenu(database.ModelBase):
self.page = page
def __repr__(self) -> str:
return '<SiteMenu %r>' % self.slug
return '<SiteMenu {!r} - {!r}>'.format(self.orderinal, self.title)
def to_json(self) -> dict:
return {
'title': self.title,
'orderinal': self.orderinal,
'page': self.page.slug,
}
Site.menu = orm.relationship(SiteMenu, order_by=SiteMenu.orderinal, back_populates="site")

View File

@ -18,7 +18,7 @@ logger = logging.getLogger(__name__)
@rookeries_app.route('/api/config')
def app_config():
# TODO Make testable and configurable
logger.warning("Use of hardcoded data in '%s'", flask.request.path)
logger.warning('Use of hardcoded data in "%s"', flask.request.path)
webapp_config = {
'siteName': 'Rookeries',
'siteTagline': 'Simple Site Scaffolding!',
@ -32,7 +32,7 @@ def app_config():
@rookeries_app.route('/api/menu')
def menu_config():
# TODO Make testable and configurable
logger.warning("Use of hardcoded data in '%s'", flask.request.path)
logger.warning('Use of hardcoded data in "%s"', flask.request.path)
nav_menu = {'menu': generate_menu()}
return flask.jsonify(nav_menu)

View File

@ -20,12 +20,12 @@ from tasks.utils import environment
from tests.fixtures import sample_site
DEFAULT_DB_CONNECTION = "postgresql+psycopg2://admin:password@localhost:5432/rookeries"
DEFAULT_DB_CONNECTION = 'postgresql+psycopg2://admin:password@localhost:5432/rookeries'
def get_db_connection_uri(db_connection, db_name):
db_connection = os.environ.get(rookeries_db.EXTERNAL_DB_URI_PARAM, db_connection)
return "/".join((db_connection.rsplit("/", maxsplit=1)[0], db_name))
return '/'.join((db_connection.rsplit('/', maxsplit=1)[0], db_name))
@inv.task
@ -67,7 +67,7 @@ def test_database(db_connection=DEFAULT_DB_CONNECTION, keep_test_db=False,
try:
db_connection = os.environ.get(rookeries_db.EXTERNAL_DB_URI_PARAM, db_connection)
db_connection = "/".join((db_connection.rsplit("/", maxsplit=1)[0], test_db_name))
db_connection = '/'.join((db_connection.rsplit('/', maxsplit=1)[0], test_db_name))
if not sqlalchemy_utils.database_exists(db_connection):
sqlalchemy_utils.create_database(db_connection)

View File

@ -9,6 +9,7 @@ import pathlib
from sqlalchemy import orm
from rookeries.sites import models as site_models
from rookeries.pages import models as journal_models
@ -28,7 +29,11 @@ def sample_page_collection():
def populate_database(db_engine):
site = site_models.Site(name='Test Site', url='https://test.rookeries.org/', config={'header': 'Test Site!'})
docs = [journal_models.Page(**doc) for doc in sample_page_collection()]
session = orm.sessionmaker(bind=db_engine)()
session.add_all(docs)
session.add(site)
session.commit()