import os import requests from zeep import Client, xsd from settings import conf from apps.doc import consts from common.redis_cache import redis_handler as rh class EDMS: def __init__(self): self.sm_client = Client(wsdl=conf.SM_WSDL) self.dm_client = Client(wsdl=conf.DM_WSDL) self.df_client = Client(wsdl=conf.DF_WSDL) self.rc_client = Client(wsdl=conf.RC_WSDL) self.download_url = conf.EDMS_DOWNLOAD_URL self.upload_url = conf.EDMS_UPLOAD_URL self.dealer_code = conf.DEALER_CODE self.user_name = conf.EDMS_USER self.pwd = conf.EDMS_PWD self.session_id = None self.prefix = 'OCR' def set_session_id(self): self.session_id = self.sm_client.service.StartSession(login=self.user_name, password=self.pwd, clientType=consts.CUSTOM_CLIENT) rh.set_session_id(self.session_id) return self.session_id def get_session_id(self): if self.session_id is None: # redis获取session_id self.session_id = rh.get_session_id() if self.session_id is None: return self.set_session_id() # 验证session_id is_session_valid = self.sm_client.service.IsSessionValid(sessionId=self.session_id, keepAlive=False) if is_session_valid is True: return self.session_id return self.set_session_id() def get_headers(self): session_id = self.get_session_id() headers = {'Cookie': '{0}={1}'.format(consts.SESSION_PREFIX, session_id)} return headers def get_download_token(self, headers, metadata_version_id): with self.dm_client.settings(extra_http_headers=headers): res = self.dm_client.service.PrepareSingleDocumentToDownload(metadataVersionId=metadata_version_id, token=consts.FIXED_TOKEN, fileSize=consts.FIXED_FILE_SIZE, actionType=consts.DOWNLOAD_ACTION_TYPE) return res.token def download_handler(self, params, headers, save_path): r = requests.get(self.download_url, params=params, headers=headers, stream=True) with open(save_path, "wb") as f: # chunk是指定每次写入的大小,每次只写了512byte for chunk in r.iter_content(chunk_size=1024): if chunk: f.write(chunk) f.flush() def download(self, save_path, metadata_version_id): headers = self.get_headers() token = self.get_download_token(headers, metadata_version_id) params = {'token': token} self.download_handler(params, headers, save_path) def create_upload_token(self, headers): with self.rc_client.settings(extra_http_headers=headers): token = self.rc_client.service.CreateUploadToken(fileSize=consts.FIXED_FILE_SIZE) return token def upload_handler(self, file_path, params, headers): with open(file_path, 'rb') as f: data = f.read() for retry in range(4): res = requests.post(self.upload_url, params=params, headers=headers, data=data) if res.status_code == requests.codes.ok: break else: raise Exception def get_doc_file_name(self, doc_name): if not isinstance(doc_name, str): return self.prefix if doc_name.endswith('.pdf') or doc_name.endswith('.PDF') or \ doc_name.endswith('.pdF') or doc_name.endswith('.pDF') or doc_name.endswith('.pDf') or \ doc_name.endswith('.Pdf') or doc_name.endswith('.PdF') or doc_name.endswith('.PDf'): name, _ = os.path.splitext(doc_name) return '{0}{1}'.format(self.prefix, name) return '{0}{1}'.format(self.prefix, doc_name) def get_doc_info(self, token, doc, business_type, file_path): business_type = consts.BUSINESS_TYPE_DICT.get(business_type) doc_schema_id, auto_filing = consts.DOC_SCHEMA_ID_FILL.get(doc.document_scheme) application_id = doc.application_id doc_file_name = self.get_doc_file_name(doc.document_name) origin_file_name = os.path.basename(file_path) fields_with_value = [ {'FieldId': consts.APPLICATION_ID_META_FIELD_id, 'FieldValue': xsd.AnyObject(xsd.String(), application_id)}, {'FieldId': consts.DEALER_CODE_META_FIELD_id, 'FieldValue': xsd.AnyObject(xsd.String(), self.dealer_code)}, {'FieldId': consts.BUSINESS_TYPE_META_FIELD_id, 'FieldValue': xsd.AnyObject(xsd.String(), business_type)}, ] fields_with_values = {'FieldWithValue': fields_with_value} info = { 'DocumentSchemaId': doc_schema_id, 'DocumentName': doc_file_name, 'FieldsWithValues': fields_with_values, 'UploadToken': token, 'OriginalFileName': origin_file_name, 'SendEmailToMembers': False, 'AutoFilingScriptToUse': auto_filing, 'DocumentSchemaType': consts.DOC_SCHEMA_TYPE, } return info def add_doc_info(self, headers, token, doc, business_type, file_path): info = self.get_doc_info(token, doc, business_type, file_path) with self.dm_client.settings(extra_http_headers=headers): metadata_version_id = self.dm_client.service.AddDocumentInfo(info=info) return metadata_version_id def upload(self, file_path, doc, business_type): # file_path = '/Users/clay/Postman/files/OCRuploadTest4.txt' # file_size = 16 # doc_info = { # 'document_scheme': 'Acceptance', # 'application_id': 'CH-B100014248', # 'doc_file_name': 'OCRuploadTest4.txt', # 'business_type': 'CO00001', # } headers = self.get_headers() token = self.create_upload_token(headers) headers.update({'Content-Type': 'application/octet-stream'}) params = {'token': token} self.upload_handler(file_path, params, headers) headers.pop('Content-Type') metadata_version_id = self.add_doc_info(headers, token, doc, business_type, file_path) return metadata_version_id