diff --git a/ereuse_devicehub/resources/tradedocument/models.py b/ereuse_devicehub/resources/tradedocument/models.py index d4274fd8..409d34eb 100644 --- a/ereuse_devicehub/resources/tradedocument/models.py +++ b/ereuse_devicehub/resources/tradedocument/models.py @@ -7,6 +7,7 @@ from flask import current_app as app, g from sqlalchemy.dialects.postgresql import UUID from ereuse_devicehub.db import db from ereuse_devicehub.resources.user.models import User +from sortedcontainers import SortedSet from ereuse_devicehub.resources.models import STR_SM_SIZE, Thing, listener_reset_field_updated_in_actual_time from sqlalchemy import BigInteger, Boolean, Column, Float, ForeignKey, Integer, \ @@ -15,7 +16,7 @@ from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.orm import ColumnProperty, backref, relationship, validates from sqlalchemy.util import OrderedSet from sqlalchemy_utils import ColorType -from teal.db import CASCADE_DEL, POLYMORPHIC_ID, POLYMORPHIC_ON, \ +from teal.db import CASCADE_OWN, CASCADE_DEL, POLYMORPHIC_ID, POLYMORPHIC_ON, \ check_lower, check_range from teal.resource import url_for_resource @@ -24,6 +25,11 @@ from ereuse_devicehub.resources.enums import BatteryTechnology, CameraFacing, Co DataStorageInterface, DisplayTech, PrinterTechnology, RamFormat, RamInterface, Severity, TransferState +_sorted_documents = { + 'order_by': lambda: TradeDocument.created, + 'collection_class': SortedSet +} + class TradeDocument(Thing): """This represent a document involved in a trade action. Every document is added to a lot. @@ -59,10 +65,20 @@ class TradeDocument(Thing): nullable=False, default=lambda: g.user.id) owner = db.relationship(User, primaryjoin=owner_id == User.id) + lot_id = db.Column(UUID(as_uuid=True), + db.ForeignKey('lot.id'), + nullable=False) + lot = db.relationship('Lot', + backref=backref('documents', + lazy=True, + cascade=CASCADE_OWN, + **_sorted_documents), + primaryjoin='TradeDocument.lot_id == Lot.id') + lot.comment = """Lot to which the document is associated""" file_name = Column(db.CIText()) file_name.comment = """This is the name of the file when user up the document.""" - file_name_disk = Column(db.CIText()) - file_name_disk.comment = """This is the name of the file as devicehub save in server.""" + path_name = Column(db.CIText()) + path_name.comment = """This is the name of the file as devicehub save in server.""" __table_args__ = ( db.Index('document_id', id, postgresql_using='hash'), @@ -81,15 +97,6 @@ class TradeDocument(Thing): """ return sorted(self.actions_multiple_docs, key=lambda x: x.created) - @property - def path_to_file(self) -> str: - """The path of one file is defined by the owner, file_name and created time. - - """ - base = app.config['PATH_DOCUMENTS_STORAGE'] - file_name = "{0.date}-{0.filename}".format(self) - base = os.path.join(base, g.user.email, file_name) - return sorted(self.actions_multiple_docs, key=lambda x: x.created) def last_action_of(self, *types): """Gets the last action of the given types. diff --git a/ereuse_devicehub/resources/tradedocument/schemas.py b/ereuse_devicehub/resources/tradedocument/schemas.py index 86c2e213..549017c4 100644 --- a/ereuse_devicehub/resources/tradedocument/schemas.py +++ b/ereuse_devicehub/resources/tradedocument/schemas.py @@ -1,8 +1,13 @@ -from marshmallow.fields import DateTime, Integer -from teal.marshmallow import SanitizedStr +import base64 +from marshmallow.fields import DateTime, Integer, Raw +from teal.marshmallow import SanitizedStr +from marshmallow import ValidationError, validates_schema + +from ereuse_devicehub.marshmallow import NestedOn from ereuse_devicehub.resources.schemas import Thing from ereuse_devicehub.resources.tradedocument import models as m +from ereuse_devicehub.resources.lot import schemas as s_lot class TradeDocument(Thing): @@ -12,4 +17,14 @@ class TradeDocument(Thing): id_document = SanitizedStr(default='', description=m.TradeDocument.id_document.comment) description = SanitizedStr(default='', description=m.TradeDocument.description.comment) file_name = SanitizedStr(default='', description=m.TradeDocument.file_name.comment) - # lot = NestedOn('Lot', dump_only=True, description=m.TradeDocument.lot.__doc__) + file = Raw(type='file') + lot = NestedOn(s_lot.Lot, only_query='id', description=m.TradeDocument.lot.__doc__) + + + @validates_schema + def validate_filestream(self, data): + if not data.get('file'): + txt = 'Error, no there are any file for save' + raise ValidationError(txt) + + data['file'] = base64.b64decode(data['file']) diff --git a/ereuse_devicehub/resources/tradedocument/views.py b/ereuse_devicehub/resources/tradedocument/views.py index 69b206c9..212c6264 100644 --- a/ereuse_devicehub/resources/tradedocument/views.py +++ b/ereuse_devicehub/resources/tradedocument/views.py @@ -1,15 +1,40 @@ - -import marshmallow -from flask import g, current_app as app, render_template, request, Response -from flask.json import jsonify -from flask_sqlalchemy import Pagination -from marshmallow import fields, fields as f, validate as v, Schema as MarshmallowSchema +import os +from datetime import datetime +from flask import current_app as app, request, g, Response +from marshmallow import ValidationError from teal.resource import View -from ereuse_devicehub import auth from ereuse_devicehub.db import db -from ereuse_devicehub.query import SearchQueryParser, things_response from ereuse_devicehub.resources.tradedocument.models import TradeDocument +from ereuse_devicehub.resources.hash_reports import insert_hash + + +def save_doc(data, user): + """ + This function allow save a snapshot in json format un a TMP_SNAPSHOTS directory + The file need to be saved with one name format with the stamptime and uuid joins + """ + filename = data['file_name'] + lot = data['lot'] + now = datetime.now() + year = now.year + month = now.month + day = now.day + hour = now.hour + minutes = now.minute + + name_file = f"{year}-{month}-{day}-{hour}-{minutes}_{user}_{filename}" + path_dir_base = os.path.join(app.config['PATH_DOCUMENTS_STORAGE'] , user) + path = os.path.join(path_dir_base, str(lot.id)) + path_name = os.path.join(path, name_file) + + os.system(f'mkdir -p {path}') + + with open(path_name, 'wb') as doc_file: + doc_file.write(data['file']) + + return path_name + class TradeDocumentView(View): @@ -19,7 +44,14 @@ class TradeDocumentView(View): def post(self): """Add one document.""" + # import pdb; pdb.set_trace() + data = request.get_json(validate=True) + data['path_name'] = save_doc(data, g.user.email) + bfile = data.pop('file') + insert_hash(bfile) + + # import pdb; pdb.set_trace() doc = TradeDocument(**data) db.session.add(doc) db.session().final_flush()