diff --git a/CHANGELOG.md b/CHANGELOG.md index 141fb297..6f86a69d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ ml). ## [1.0.5-beta] - [addend] #124 adding endpoint for extract the internal stats of use +- [addend] #122 system for verify all documents that it's produced from devicehub ## [1.0.4-beta] - [addend] #95 adding endpoint for check the hash of one report diff --git a/ereuse_devicehub/__init__.py b/ereuse_devicehub/__init__.py index a20c909b..53f0b176 100644 --- a/ereuse_devicehub/__init__.py +++ b/ereuse_devicehub/__init__.py @@ -1 +1 @@ -__version__ = "1.0.4-beta" +__version__ = "1.0.5-beta" diff --git a/ereuse_devicehub/migrations/versions/6a2a939d5668_drop_unique_org_for_tag.py b/ereuse_devicehub/migrations/versions/6a2a939d5668_drop_unique_org_for_tag.py new file mode 100644 index 00000000..17e0290e --- /dev/null +++ b/ereuse_devicehub/migrations/versions/6a2a939d5668_drop_unique_org_for_tag.py @@ -0,0 +1,62 @@ +"""drop unique org for tag + +Revision ID: 6a2a939d5668 +Revises: eca457d8b2a4 +Create Date: 2021-02-25 18:47:47.441195 + +""" +from alembic import op +import sqlalchemy as sa +from alembic import context + + +# revision identifiers, used by Alembic. +revision = '6a2a939d5668' +down_revision = 'eca457d8b2a4' +branch_labels = None +depends_on = None + + +def get_inv(): + INV = context.get_x_argument(as_dictionary=True).get('inventory') + if not INV: + raise ValueError("Inventory value is not specified") + return INV + + +def upgrade_data(): + con = op.get_bind() + tags = con.execute(f"select id from {get_inv()}.tag") + i = 1 + for c in tags: + id_tag = c.id + internal_id = i + i += 1 + sql = f"update {get_inv()}.tag set internal_id='{internal_id}' where id='{id_tag}';" + con.execute(sql) + + sql = f"CREATE SEQUENCE {get_inv()}.tag_internal_id_seq START {i};" + con.execute(sql) + + +def upgrade(): + op.drop_constraint('one tag id per organization', 'tag', schema=f'{get_inv()}') + op.drop_constraint('one secondary tag per organization', 'tag', schema=f'{get_inv()}') + op.create_primary_key('one tag id per owner', 'tag', ['id', 'owner_id'], schema=f'{get_inv()}'), + op.create_unique_constraint('one secondary tag per owner', 'tag', ['secondary', 'owner_id'], schema=f'{get_inv()}'), + op.add_column('tag', sa.Column('internal_id', sa.BigInteger(), nullable=True, + comment='The identifier of the tag for this database. Used only\n internally for software; users should not use this.\n'), schema=f'{get_inv()}') + + upgrade_data() + + op.alter_column('tag', sa.Column('internal_id', sa.BigInteger(), nullable=False, + comment='The identifier of the tag for this database. Used only\n internally for software; users should not use this.\n'), schema=f'{get_inv()}') + + +def downgrade(): + op.drop_constraint('one tag id per owner', 'tag', schema=f'{get_inv()}') + op.drop_constraint('one secondary tag per owner', 'tag', schema=f'{get_inv()}') + op.create_primary_key('one tag id per organization', 'tag', ['id', 'org_id'], schema=f'{get_inv()}'), + op.create_unique_constraint('one secondary tag per organization', 'tag', ['secondary', 'org_id'], schema=f'{get_inv()}'), + op.drop_column('tag', 'internal_id', schema=f'{get_inv()}') + op.execute(f"DROP SEQUENCE {get_inv()}.tag_internal_id_seq;") diff --git a/ereuse_devicehub/resources/action/__init__.py b/ereuse_devicehub/resources/action/__init__.py index 7fd91eb8..a584f038 100644 --- a/ereuse_devicehub/resources/action/__init__.py +++ b/ereuse_devicehub/resources/action/__init__.py @@ -250,6 +250,11 @@ class MakeAvailable(ActionDef): SCHEMA = schemas.MakeAvailable +class TradeDef(ActionDef): + VIEW = None + SCHEMA = schemas.Trade + + class CancelTradeDef(ActionDef): VIEW = None SCHEMA = schemas.CancelTrade diff --git a/ereuse_devicehub/resources/documents/device_row.py b/ereuse_devicehub/resources/documents/device_row.py index bc24ea86..e2128bc4 100644 --- a/ereuse_devicehub/resources/documents/device_row.py +++ b/ereuse_devicehub/resources/documents/device_row.py @@ -50,8 +50,7 @@ class DeviceRow(OrderedDict): self['Tag 2 Type'] = self['Tag 2 ID'] = self['Tag 2 Organization'] = '' self['Tag 3 Type'] = self['Tag 3 ID'] = self['Tag 3 Organization'] = '' for i, tag in zip(range(1, 3), device.tags): - # TODO @cayop we need redefined how save the Tag Type info - self['Tag {} Type'.format(i)] = 'unamed' + self['Tag {} Type'.format(i)] = 'unamed' if tag.provider else 'named' self['Tag {} ID'.format(i)] = tag.id self['Tag {} Organization'.format(i)] = tag.org.name diff --git a/ereuse_devicehub/resources/documents/documents.py b/ereuse_devicehub/resources/documents/documents.py index 692e6992..cc47fd30 100644 --- a/ereuse_devicehub/resources/documents/documents.py +++ b/ereuse_devicehub/resources/documents/documents.py @@ -27,7 +27,7 @@ from ereuse_devicehub.resources.documents.device_row import (DeviceRow, StockRow InternalStatsRow) from ereuse_devicehub.resources.lot import LotView from ereuse_devicehub.resources.lot.models import Lot -from ereuse_devicehub.resources.hash_reports import insert_hash, ReportHash +from ereuse_devicehub.resources.hash_reports import insert_hash, ReportHash, verify_hash class Format(enum.Enum): @@ -80,6 +80,7 @@ class DocumentView(DeviceView): res = flask_weasyprint.render_pdf( flask_weasyprint.HTML(string=template), download_filename='{}.pdf'.format(type) ) + insert_hash(res.data) else: res = flask.make_response(template) return res @@ -186,7 +187,9 @@ class LotsDocumentView(LotView): cw.writerow(l.keys()) first = False cw.writerow(l.values()) - output = make_response(data.getvalue()) + bfile = data.getvalue().encode('utf-8') + output = make_response(bfile) + insert_hash(bfile) output.headers['Content-Disposition'] = 'attachment; filename=lots-info.csv' output.headers['Content-type'] = 'text/csv' return output @@ -223,7 +226,9 @@ class StockDocumentView(DeviceView): cw.writerow(d.keys()) first = False cw.writerow(d.values()) - output = make_response(data.getvalue()) + bfile = data.getvalue().encode('utf-8') + output = make_response(bfile) + insert_hash(bfile) output.headers['Content-Disposition'] = 'attachment; filename=devices-stock.csv' output.headers['Content-type'] = 'text/csv' return output @@ -247,12 +252,32 @@ class StampsView(View): This view render one public ans static page for see the links for to do the check of one csv file """ - def get(self): + def get_url_path(self): url = urlutils.URL(request.url) url.normalize() url.path_parts = url.path_parts[:-2] + ['check', ''] - url_path = url.to_text() - return flask.render_template('documents/stamp.html', rq_url=url_path) + return url.to_text() + + def get(self): + result = ('', '') + return flask.render_template('documents/stamp.html', rq_url=self.get_url_path(), + result=result) + + def post(self): + result = ('', '') + if 'docUpload' in request.files: + file_check = request.files['docUpload'] + bad = 'There are no coincidences. The attached file data does not come \ + from our backend or it has been subsequently modified.' + ok = '100% coincidence. The attached file contains data 100% existing in \ + to our backend' + result = ('Bad', bad) + if file_check.mimetype in ['text/csv', 'application/pdf']: + if verify_hash(file_check): + result = ('Ok', ok) + + return flask.render_template('documents/stamp.html', rq_url=self.get_url_path(), + result=result) class InternalStatsView(DeviceView): @@ -345,7 +370,7 @@ class DocumentDef(Resource): self.add_url_rule('/check/', defaults={}, view_func=check_view, methods=get) stamps_view = StampsView.as_view('StampsView', definition=self, auth=app.auth) - self.add_url_rule('/stamps/', defaults={}, view_func=stamps_view, methods=get) + self.add_url_rule('/stamps/', defaults={}, view_func=stamps_view, methods={'GET', 'POST'}) internalstats_view = InternalStatsView.as_view( 'InternalStatsView', definition=self, auth=app.auth) diff --git a/ereuse_devicehub/resources/documents/templates/documents/stamp.html b/ereuse_devicehub/resources/documents/templates/documents/stamp.html index c204c2ff..d07efc49 100644 --- a/ereuse_devicehub/resources/documents/templates/documents/stamp.html +++ b/ereuse_devicehub/resources/documents/templates/documents/stamp.html @@ -38,6 +38,17 @@