Skip to content

Commit

Permalink
admin: views for template definitions and counters
Browse files Browse the repository at this point in the history
* Adds admin views for management of TemplateDefinition and Counter.

* Adds a Jinja template for the admin interface, which provides a reset
  row action.

Signed-off-by: Orestis Melkonian <melkon.or@gmail.com>
  • Loading branch information
omelkonian committed Sep 21, 2016
1 parent 2d3e246 commit 79ae908
Show file tree
Hide file tree
Showing 10 changed files with 361 additions and 2 deletions.
104 changes: 104 additions & 0 deletions examples/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# -*- coding: utf-8 -*-
#
# This file is part of Invenio.
# Copyright (C) 2016 CERN.
#
# Invenio is free software; you can redistribute it
# and/or modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# Invenio is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Invenio; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307, USA.
#
# In applying this license, CERN does not
# waive the privileges and immunities granted to it by virtue of its status
# as an Intergovernmental Organization or submit itself to any jurisdiction.


"""Minimal Flask application example for development.
Run example development server:
.. code-block:: console
$ cd examples
$ export FLASK_APP=app.py
$ flask db init
$ flask db create
$ flask fixtures sequences
$ flask run --debugger
"""

from __future__ import absolute_import, print_function

import os

from flask import Flask
from flask_admin import Admin
from flask_babelex import Babel
from flask_cli import FlaskCLI
from invenio_db import InvenioDB, db
from invenio_sequencegenerator.admin import counter_adminview as ca
from invenio_sequencegenerator.admin import templatedefinition_adminview as ta
from invenio_sequencegenerator.api import Sequence, Template

# Create Flask application
from invenio_sequencegenerator.ext import InvenioSequenceGenerator

app = Flask(__name__)
app.config.update(
SECRET_KEY="CHANGE_ME",
SECURITY_PASSWORD_SALT="CHANGE_ME_ALSO",
SQLALCHEMY_DATABASE_URI=os.environ.get(
'SQLALCHEMY_DATABASE_URI', 'sqlite:///test.db'),
SQLALCHEMY_TRACK_MODIFICATIONS=True,
)
FlaskCLI(app)
Babel(app)
InvenioDB(app)
InvenioSequenceGenerator(app)


@app.cli.group()
def fixtures():
"""Command for working with test data."""


@fixtures.command()
def sequences():
"""Load test data fixture."""
pl = Template.create('PL', '{year}: Playlist {counter}', start=1)
fl = Template.create('FL', '{PL} > Audio File {counter:02d}', start=1)
pl15 = Sequence(pl, year=2015)
pl15.next()
pl15.next()
pl16 = Sequence(pl, year=2016)
pl16.next()
fl15 = Sequence(fl, PL='2015: Playlist 2')
fl15.next()
fl15.next()
fl16 = Sequence(fl, PL='2016: Playlist 1')
fl16.next()
db.session.commit()


@app.route('/')
def index():
return '<a href="/admin/">Click me to get to Admin!</a>'


# Create admin
admin = Admin(app, name='Example: Sequence Generator',
template_mode='bootstrap3')

# Add views
admin.add_view(ta['modelview'](ta['model'], db.session))
admin.add_view(ca['modelview'](ca['model'], db.session))
5 changes: 5 additions & 0 deletions invenio_sequencegenerator/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@
>>> from invenio_db import InvenioDB
>>> ext_db = InvenioDB(app)
Also, initialise the Invenio-SequenceGenerator extension:
>>> from invenio_sequencegenerator.ext import InvenioSequenceGenerator
>>> ext_seq = InvenioSequenceGenerator(app)
In order for the following examples to work, you need to work within an
Flask application context so let's push one:
Expand Down
82 changes: 82 additions & 0 deletions invenio_sequencegenerator/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# -*- coding: utf-8 -*-
#
# This file is part of Invenio.
# Copyright (C) 2016 CERN.
#
# Invenio is free software; you can redistribute it
# and/or modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# Invenio is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Invenio; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307, USA.
#
# In applying this license, CERN does not
# waive the privileges and immunities granted to it by virtue of its status
# as an Intergovernmental Organization or submit itself to any jurisdiction.

"""Admin views for invenio-accounts."""

from flask import flash, redirect, request, url_for
from flask_admin import expose
from flask_admin.actions import action
from flask_admin.contrib.sqla import ModelView
from flask_babelex import gettext as _
from invenio_db import db

from .models import Counter, TemplateDefinition


class TemplateDefinitionView(ModelView):
"""Flask-Admin view for template definitions."""

column_list = (
'name',
'meta_template',
'parent_name',
'start',
'step',
)


class CounterView(ModelView):
"""Admin view for counters."""

list_template = 'invenio_sequencegenerator/custom_list.html'

column_list = (
'template_instance',
'counter',
'definition_name',
)

@expose('/reset', methods=('POST',))
def reset_view(self):
"""Reset selected counter."""
start = request.form.get('start', default=0, type=int)
template_instance = request.form['rowid']
Counter.query.get(template_instance).reset(start=start)
db.session.commit()
return redirect(url_for('.index_view'))


templatedefinition_adminview = {
'model': TemplateDefinition,
'modelview': TemplateDefinitionView,
'category': _('Sequences'),
}

counter_adminview = {
'model': Counter,
'modelview': CounterView,
'category': _('Sequences'),
}

__all__ = ('templatedefinition_adminview', 'counter_adminview')
42 changes: 42 additions & 0 deletions invenio_sequencegenerator/ext.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-
#
# This file is part of Invenio.
# Copyright (C) 2016 CERN.
#
# Invenio is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# Invenio is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Invenio; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.

"""Flask extension for Invenio-SequenceGenerator."""

from __future__ import absolute_import, print_function

from flask import Blueprint


class InvenioSequenceGenerator(object):
"""Invenio-SequenceGenerator extension."""

def __init__(self, app=None):
"""Extension initialization."""
if app:
self.init_app(app)

def init_app(self, app):
"""Flask application initialization."""
app.extensions['invenio-sequencegenerator'] = self

# Register dummy blueprint just for loading templates
app.register_blueprint(Blueprint(
'invenio_sequencegenerator', __name__, template_folder='templates')
)
3 changes: 2 additions & 1 deletion invenio_sequencegenerator/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ def derive_parent(target, value, oldvalue, initiator):
TemplateDefinition.name.in_(placeholders)
).one_or_none() if placeholders else None
except MultipleResultsFound:
raise InvalidTemplate('More than 1 parents in template')
raise InvalidTemplate('More than 1 parents '
'in template "{0}".'.format(value))

target.parent = parent

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{#
#
# This file is part of Invenio.
# Copyright (C) 2016 CERN.
#
# Invenio is free software; you can redistribute it
# and/or modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# Invenio is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Invenio; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307, USA.
#
# In applying this license, CERN does not
# waive the privileges and immunities granted to it by virtue of its status
# as an Intergovernmental Organization or submit itself to any jurisdiction.}
#}
{%- extends 'admin/model/list.html' %}
{%- block list_row_actions %}
{{ super() }}
<form class="icon" method="POST" action="{{ url_for('.reset_view') }}">
<input name="start" value="0" type="number" size="1">
<input name="rowid" value="{{ get_pk_value(row) }}" type="hidden">
<button onclick="return confirm(_('Are you sure you want to reset selected counter?'));" title="{{ _('Reset') }}">
<span class="fa fa-step-backward glyphicon glyphicon-step-backward"></span>
</button>
</form>
{%- endblock %}
17 changes: 17 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@
'sqlite': [
'invenio-db[versioning]>=1.0.0a10',
],
'admin': [
'Flask-Admin>=1.4.2',
],
'tests': tests_require,
}

Expand Down Expand Up @@ -100,13 +103,27 @@
include_package_data=True,
platforms='any',
entry_points={
'invenio_base.apps': [
'invenio_sequencegenerator = '
'invenio_sequencegenerator:InvenioSequenceGenerator',
],
'invenio_base.blueprints': [
'invenio_sequencegenerator = '
'invenio_sequencegenerator.ext:blueprint',
],
'invenio_i18n.translations': [
'messages = invenio_sequencegenerator',
],
'invenio_db.models': [
'invenio_sequencegenerator = '
'invenio_sequencegenerator.models',
],
'invenio_admin.views': [
'invenio_sequencegenerator_templatedefinition = '
'invenio_sequencegenerator.admin:templatedefinition_adminview',
'invenio_sequencegenerator_counter = '
'invenio_sequencegenerator.admin:counter_adminview',
],
},
extras_require=extras_require,
install_requires=install_requires,
Expand Down
2 changes: 2 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
from flask import Flask
from invenio_db import db as db_
from invenio_db import InvenioDB
from invenio_sequencegenerator.ext import InvenioSequenceGenerator
from sqlalchemy_utils.functions import create_database, database_exists


Expand All @@ -55,6 +56,7 @@ def app(request):
from flask_cli import FlaskCLI
FlaskCLI(app)
InvenioDB(app)
InvenioSequenceGenerator(app)

with app.app_context():
yield app
Expand Down
Loading

0 comments on commit 79ae908

Please sign in to comment.