Skip to content

Commit

Permalink
server: Added changelog for views - fix #65 !!! TEMP !!!
Browse files Browse the repository at this point in the history
  • Loading branch information
andras-tim committed Nov 26, 2015
1 parent ea13824 commit 4f2a48e
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 2 deletions.
24 changes: 24 additions & 0 deletions docs/server/rpc/changelog.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.. StoreKeeper documentation
Changelog
=========

API endpoint for changelog.

Data management
---------------

``/api/changelog``
^^^^^^^^^^^^^^^^^^
.. autoflask:: app.server:app
:endpoints: changelog_list

``/api/changelog/<str:model>``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autoflask:: app.server:app
:endpoints: changelog_model_list

``/api/changelog/<str:model>/<int:id>``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autoflask:: app.server:app
:endpoints: changelog_model_object_list
1 change: 1 addition & 0 deletions docs/server/rpc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Endpoints

acquisitions
barcodes
changelog
config
customers
error
Expand Down
45 changes: 45 additions & 0 deletions server/app/models.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,27 @@
from datetime import datetime
from enum import Enum, unique

from app.server import db, bcrypt
from app.modules.view_helper_for_models import nested_fields


@unique
class Models(Enum):
user = 0
user_config = 1
vendor = 2
unit = 3
customer = 4
item = 5
barcode = 6
work = 7
work_item = 8
acquisition = 9
acquisition_item = 10
stocktaking = 11
stocktaking_item = 12


class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(30), nullable=False, unique=True, index=True)
Expand Down Expand Up @@ -250,3 +268,30 @@ class StocktakingItem(db.Model):

def __repr__(self)-> str:
return '{!s} [{!r}]'.format(self.id, self.item)


@nested_fields(user=User)
class Changelog(db.Model):
id = db.Column(db.Integer, primary_key=True)
timestamp = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
changed_model_id = db.Column(db.Integer, nullable=False)
changed_object_id = db.Column(db.Integer, nullable=False)
original_object = db.Column(db.Text, nullable=False)
changes = db.Column(db.Text, nullable=False)

user = db.relationship('User', lazy='joined')

def __repr__(self)-> str:
return '{!s} [{!s}, user={!s}]'.format(self.id, self.timestamp, self.user)

@property
def changed_model(self) -> str:
return Models(self.changed_model_id).name

@changed_model.setter
def changed_model(self, new_value: (Models, db.Model)):
if isinstance(new_value, db.Model):
raise NotImplementedError

self.changed_model_id = new_value.value
18 changes: 18 additions & 0 deletions server/app/modules/example_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,3 +244,21 @@ class ExampleErrors:
'stack': 'ReferenceError: foo is not defined\n'
' at Scope.printLabel (http://.../storekeeper.js:58678:21)\n'
' at ...'})


class ExampleChangeLogs:
LOG1_ADMIN_POST_USER1 = ExampleUser(getters={'id': 1, 'timestamp': ExampleTimestamp.utcnow(),
'user': ExampleUsers.ADMIN.get(),
'changed_model': 'User',
'changed_object': None,
'changes': json.dumps(ExampleUsers.USER1.get())})
LOG2_USER1_POST_VENDOR1 = ExampleUser(getters={'id': 2, 'timestamp': ExampleTimestamp.utcnow(),
'user': ExampleUsers.USER1.get(),
'changed_model': 'Vendor',
'changed_object': None,
'changes': json.dumps(ExampleVendors.VENDOR1.get())})
LOG3_USER1_POST_VENDOR2 = ExampleUser(getters={'id': 3, 'timestamp': ExampleTimestamp.utcnow(),
'user': ExampleUsers.USER1.get(),
'changed_model': 'Vendor',
'changed_object': None,
'changes': json.dumps(ExampleVendors.VENDOR2.get())})
4 changes: 4 additions & 0 deletions server/app/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,3 +238,7 @@ class ErrorDeserializer(Serializer):
message = fields.Str(required=True)
stack = fields.Str()
cause = fields.Str()


class ChangelogSerializer(BasicSerializer):
fields = ('id', 'timestamp', 'user', 'changed_model', 'changed_object', 'changes')
8 changes: 6 additions & 2 deletions server/app/views/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from app.modules.yaml_config import ConfigObject
from app.modules.restful_api import RestfulApiWithoutSimpleAuth

from app.views import common, acquisition, barcode, config, customer, error, item, session, stocktaking, unit, user, \
vendor, work
from app.views import common, acquisition, barcode, changelog, config, customer, error, item, session, stocktaking, \
unit, user, vendor, work


def initialize_endpoints(app_config: ConfigObject, api: RestfulApiWithoutSimpleAuth):
Expand All @@ -14,6 +14,10 @@ def initialize_endpoints(app_config: ConfigObject, api: RestfulApiWithoutSimpleA

'barcode_list': (barcode.BarcodeListView, '/barcodes'),

'changelog_list': (changelog.ChangelogListView, '/changelog'),
'changelog_model_list': (changelog.ChangelogModelListView, '/changelog/<string:model>'),
'changelog_model_object_list': (changelog.ChangelogModelObjectListView, '/changelog/<string:model>/<int:id>'),

'config': (config.ConfigView, '/config'),

'customer_list': (customer.CustomerListView, '/customers'),
Expand Down
38 changes: 38 additions & 0 deletions server/app/views/changelog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from app.models import Changelog
from app.views.base_views import BaseListView
from app.modules.example_data import ExampleChangeLogs
from app.serializers import ChangelogSerializer
from app.views.common import api_func


class ChangelogListView(BaseListView):
_model = Changelog
_serializer = ChangelogSerializer()

@api_func('Show global changelog', url_tail='/changelog',
response=[ExampleChangeLogs.LOG1_ADMIN_POST_USER1.get(),
ExampleChangeLogs.LOG2_USER1_POST_VENDOR1.get()])
def get(self):
return None


class ChangelogModelListView(BaseListView):
_model = Changelog
_serializer = ChangelogSerializer()

@api_func('Show changelog of users', url_tail='/changelog/user',
response=[ExampleChangeLogs.LOG1_ADMIN_POST_USER1.get(),
ExampleChangeLogs.LOG2_USER1_POST_VENDOR1.get()])
def get(self):
return None


class ChangelogModelObjectListView(BaseListView):
_model = Changelog
_serializer = ChangelogSerializer()

@api_func('Show changelog of user#2', url_tail='/changelog/user/2',
response=[ExampleChangeLogs.LOG1_ADMIN_POST_USER1.get(),
ExampleChangeLogs.LOG2_USER1_POST_VENDOR1.get()])
def get(self):
return None
18 changes: 18 additions & 0 deletions server/test/e2e/views/test_changelog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from app.modules.example_data import ExampleVendors as Vendors, ExampleUsers as Users, ExampleChangeLogs as Logs
from test.e2e.base_session_test import CommonSessionTest


class TestChangelog(CommonSessionTest):
ENDPOINT = '/changelog'
INIT_PUSH = [
('/users', [Users.USER1]),
]

def setUp(self):
super().setUp()
self.assertApiLogin(credential=Users.USER1)
self.assertApiPost(endpoint='/vendors', data=Vendors.VENDOR1.set())

def test_list_changelog(self):
self.assertApiGet(expected_data=[Logs.LOG1_ADMIN_POST_USER1,
Logs.LOG2_USER1_POST_VENDOR1])

0 comments on commit 4f2a48e

Please sign in to comment.