def save(self, document_id: int, **kwargs): self.serializer.load({'id': document_id}, partial=True) file = get_request_file() data = self.serializer.valid_request_file(file) document = self.manager.find(document_id) filepath = f'{document.directory_path}/{document.internal_filename}' try: fs = FileStorage() fs.save_bytes(data.get('file_data'), filepath, override=True) data = { 'name': data.get('filename'), 'mime_type': data.get('mime_type'), 'size': fs.get_filesize(filepath), } self.manager.save(document_id, **data) except Exception as e: if os.path.exists(filepath): os.remove(filepath) logger.debug(e) raise InternalServerError() else: return document.reload()
def test_update_document(client: CustomFlaskClient, auth_header: any): pdf_file = '%s/example.pdf' % current_app.config.get('MOCKUP_DIRECTORY') document = (DocumentModel.select().where( DocumentModel.deleted_at.is_null()).order_by( fn.Random()).limit(1).get()) db_wrapper.database.close() document_id = document.id data = { 'document': open(pdf_file, 'rb'), } headers = auth_header() headers['Content-Type'] = 'multipart/form-data' response = client.put(f'/api/documents/{document_id}', data=data, headers=headers) json_response = response.get_json() json_data = json_response.get('data') parse_url = urlparse(json_data.get('url')) assert 200 == response.status_code assert isinstance(json_data.get('created_by').get('id'), int) assert pdf_file == json_data.get('name') assert document.mime_type == json_data.get('mime_type') assert FileStorage.get_filesize(pdf_file) == json_data.get('size') assert parse_url.scheme and parse_url.netloc assert document.created_at.strftime('%Y-%m-%d %H:%M:%S') == json_data.get( 'created_at') assert json_data.get('updated_at') > json_data.get('created_at') assert json_data.get('deleted_at') is None
def test_save_document(client: CustomFlaskClient, auth_header: any): pdf_file = '%s/example.pdf' % current_app.config.get('MOCKUP_DIRECTORY') data = { 'document': open(pdf_file, 'rb'), } headers = auth_header() headers['Content-Type'] = 'multipart/form-data' response = client.post('/api/documents', data=data, headers=headers) json_response = response.get_json() json_data = json_response.get('data') parse_url = urlparse(json_data.get('url')) assert 201 == response.status_code assert 1 == json_data.get('created_by').get('id') assert pdf_file == json_data.get('name') assert 'application/pdf' == json_data.get('mime_type') assert FileStorage.get_filesize(pdf_file) == json_data.get('size') assert parse_url.scheme and parse_url.netloc assert json_data.get('created_at') assert json_data.get('updated_at') == json_data.get('created_at') assert json_data.get('deleted_at') is None
def __init__(self): super(DocumentService, self).__init__() self.manager = DocumentManager() self.serializer = DocumentSerializer() self.file_storage = FileStorage()
class DocumentService(BaseService): def __init__(self): super(DocumentService, self).__init__() self.manager = DocumentManager() self.serializer = DocumentSerializer() self.file_storage = FileStorage() def create(self, **kwargs): data = self.serializer.valid_request_file(kwargs) file_extension = mimetypes.guess_extension(data.get('mime_type')) internal_filename = '%s%s' % (uuid.uuid1().hex, file_extension) filepath = '%s/%s' % (current_app.config.get('STORAGE_DIRECTORY'), internal_filename) try: self.file_storage.save_bytes(data.get('file_data'), filepath) data = { 'created_by': current_user.id, 'name': data.get('filename'), 'internal_filename': internal_filename, 'mime_type': data.get('mime_type'), 'directory_path': current_app.config.get('STORAGE_DIRECTORY'), 'size': self.file_storage.get_filesize(filepath), } document = self.manager.create(**data) except Exception as e: if os.path.exists(filepath): os.remove(filepath) logger.debug(e) raise InternalServerError() else: return document def find(self, document_id: int, *args): self.serializer.load({'id': document_id}, partial=True) return self.manager.find(document_id, *args) def save(self, document_id: int, **kwargs): self.serializer.load({'id': document_id}, partial=True) file = get_request_file() data = self.serializer.valid_request_file(file) document = self.manager.find(document_id) filepath = f'{document.directory_path}/{document.internal_filename}' try: fs = FileStorage() fs.save_bytes(data.get('file_data'), filepath, override=True) data = { 'name': data.get('filename'), 'mime_type': data.get('mime_type'), 'size': fs.get_filesize(filepath), } self.manager.save(document_id, **data) except Exception as e: if os.path.exists(filepath): os.remove(filepath) logger.debug(e) raise InternalServerError() else: return document.reload() def delete(self, document_id: int): self.serializer.load({'id': document_id}, partial=True) return self.manager.delete(document_id) def get_document_content(self, document_id: int, **kwargs): self.serializer.load({'id': document_id}, partial=True) request_args = DocumentAttachmentSerializer().load(kwargs, unknown=EXCLUDE) as_attachment = request_args.get('as_attachment', 0) document = self.manager.find(document_id) mime_type = document.mime_type file_extension = mimetypes.guess_extension(mime_type) attachment_filename = document.name if document.name.find( file_extension) else f'{document.name}{file_extension}' kwargs = { 'path_or_file': document.get_filepath(), 'mimetype': mime_type, 'as_attachment': as_attachment, } if as_attachment: kwargs['attachment_filename'] = attachment_filename return send_file(**kwargs)
def export_user_data_in_word_task(self, created_by: int, request_data: dict, to_pdf: int): def _write_docx_content(rows: list, document: docx.Document) -> None: header_fields = rows[0] assert len(header_fields) == len(_COLUMN_DISPLAY_ORDER) table = document.add_table(rows=len(rows), cols=len(header_fields)) for i in range(len(rows)): row = table.rows[i] for j, table_cell in enumerate(rows[i]): row.cells[j].text = str(table_cell) self.update_state(state='PROGRESS', meta={ 'current': i, 'total': self.total_progress, 'status': 'In progress...', }) user_list = _get_user_data(request_data) # Word table rows + 2 (Word table header and save data in database) self.total_progress = len(user_list) + 2 tempfile_suffix = '.docx' tempfile = NamedTemporaryFile(suffix=tempfile_suffix) table_data = [] mime_type = PDF_MIME_TYPE if to_pdf else MS_WORD_MIME_TYPE self.update_state(state='PROGRESS', meta={ 'current': 0, 'total': self.total_progress, 'status': 'In progress...', }) _add_table_column_names(table_data, set(_COLUMN_DISPLAY_ORDER)) _add_table_user_data(user_list, table_data) document = docx.Document() _write_docx_content(table_data, document) document.save(tempfile.name) directory_path = current_app.config.get('STORAGE_DIRECTORY') temp_filename = FileStorage.get_basename(tempfile.name, include_path=False) if to_pdf: convert_to(directory_path, tempfile.name) else: dst = f'{directory_path}/{temp_filename}{tempfile_suffix}' FileStorage.copy_file(tempfile.name, dst) file_extension = mimetypes.guess_extension(mime_type) internal_filename = '%s%s' % (uuid.uuid1().hex, file_extension) filepath = '%s/%s' % (directory_path, internal_filename) try: file_prefix = datetime.utcnow().strftime('%Y%m%d') basename = f'{file_prefix}_users' filename = f'{basename}{file_extension}' src = '%s/%s%s' % (directory_path, temp_filename, file_extension) FileStorage.rename(src, filepath) data = { 'created_by': created_by, 'name': filename, 'internal_filename': internal_filename, 'mime_type': mime_type, 'directory_path': directory_path, 'size': FileStorage.get_filesize(filepath), } document = DocumentModel.create(**data) except Exception as e: if os.path.exists(filepath): os.remove(filepath) logger.debug(e) raise e document_serializer = DocumentSerializer(exclude=('internal_filename',)) document_data = document_serializer.dump(document) return { 'current': self.total_progress, 'total': self.total_progress, 'status': 'Task completed!', 'result': document_data, }
def export_user_data_in_excel_task(self, created_by: int, request_data: dict): def _write_excel_rows(rows: list, workbook: Workbook, worksheet: Worksheet) -> int: excel_longest_word = '' for i, row in enumerate(rows, 1): row_format = None if i == 1: row_format = workbook.add_format({ 'bold': True, 'bg_color': '#cccccc', }) elif i % 2 == 0: row_format = workbook.add_format({ 'bg_color': '#f1f1f1', }) range_cells = 'A%s:I10' % i row_longest_word = find_longest_word(row) if len(row_longest_word) > len(excel_longest_word): excel_longest_word = row_longest_word worksheet.write_row(range_cells, row, row_format) self.update_state(state='PROGRESS', meta={ 'current': i, 'total': self.total_progress, 'status': 'In progress...', }) return len(excel_longest_word) user_list = _get_user_data(request_data) # Excel rows + 2 (Excel header row and save data in database) self.total_progress = len(user_list) + 2 tempfile = NamedTemporaryFile() excel_rows = [] self.update_state(state='PROGRESS', meta={ 'current': 0, 'total': self.total_progress, 'status': 'In progress...', }) workbook = xlsxwriter.Workbook(tempfile.name) worksheet = workbook.add_worksheet() worksheet.set_zoom(120) _get_excel_column_names(excel_rows) _get_excel_user_data(user_list, excel_rows) _add_excel_autofilter(worksheet) excel_longest_word = _write_excel_rows(excel_rows, workbook, worksheet) _adjust_each_column_width(excel_rows, worksheet, excel_longest_word) workbook.close() filepath = '' try: mime_type = magic.from_file(tempfile.name, mime=True) file_extension = mimetypes.guess_extension(mime_type) internal_filename = '%s%s' % (uuid.uuid1().hex, file_extension) directory_path = current_app.config.get('STORAGE_DIRECTORY') filepath = f'{directory_path}/{internal_filename}' data = tempfile.file.read() fs = FileStorage() fs.save_bytes(data, filepath) file_prefix = datetime.utcnow().strftime('%Y%m%d') basename = f'{file_prefix}_users' filename = f'{basename}{file_extension}' data = { 'created_by': created_by, 'name': filename, 'internal_filename': internal_filename, 'mime_type': mime_type, 'directory_path': directory_path, 'size': fs.get_filesize(filepath), } document = DocumentModel.create(**data) except Exception: if os.path.exists(filepath): os.remove(filepath) raise document_serializer = DocumentSerializer(exclude=('internal_filename', )) document_data = document_serializer.dump(document) return { 'current': self.total_progress, 'total': self.total_progress, 'status': 'Task completed!', 'result': document_data, }