edms.py 3.96 KB
import requests
from zeep import Client
from settings import conf
from . import consts
from common.redis_cache import redis_handler as rh


class EDMS:

    def __init__(self, user_name, pwd):
        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.user_name = user_name
        self.pwd = pwd
        self.session_id = None

    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=512):
                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, file_size):
        with self.rc_client.settings(extra_http_headers=headers):
            token = self.rc_client.service.CreateUploadToken(fileSize=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 add_doc_info(self, headers, token, app_info):
        with self.dm_client.settings(extra_http_headers=headers):
            res = self.dm_client.service.AddDocumentInfo()
        return res

    def upload(self, file_path, file_size, app_info):
        headers = self.get_headers()
        token = self.create_upload_token(headers, file_size)
        headers.update({'Content-Type': 'application/octet-stream'})
        params = {'token': token}
        self.upload_handler(file_path, params, headers)
        headers.pop('Content-Type')
        self.add_doc_info(headers, token, app_info)