ecm.py 7.82 KB
import os
import time
import base64
import requests
from common.redis_cache import redis_handler as rh
from settings import conf
from apps.doc.exceptions import ECMException
from common.mixins import GenericView


class ECM(GenericView):

    def __init__(self):
        self.oauth_token = None
        self.username = conf.ECM_USER
        self.pwd = conf.ECM_PWD
        self.oauth_url = conf.ECM_OAUTH_URL
        self.download_url = conf.ECM_DOWNLOAD_URL
        self.upload_url = conf.ECM_UPLOAD_URL
        self.search_url = conf.ECM_SEARCH_URL
        self.oauth_headers = {
            'Content-Type': 'application/x-www-form-urlencoded'
        }
        self.oauth_payload = {
            'grant_type': 'client_credentials',
            'client_id': conf.ECM_OAUTH_ID,
            'client_secret': conf.ECM_OAUTH_SECRET,
            'scope': conf.ECM_OAUTH_SCOPE,
        }
        self.token_key = 'access_token'
        self.token_type = 'Bearer'
        self.token_type_key = 'token_type'
        self.expires_key = 'expires_in'
        self.settlement_type = 'settlement'
        self.doc_type_map = {
            'ACCEPTANCE': ('acceptance', conf.ECM_FOLDER_CA, conf.ECM_FOLDER_CA_HIL),
            'SETTLEMENT': (self.settlement_type, conf.ECM_FOLDER_SE, conf.ECM_FOLDER_SE_HIL),
            'CONTRACTMANAGEMENT': ('contract_management', conf.ECM_FOLDER_CA, conf.ECM_FOLDER_CA_HIL),
            'INSURANCE': ('insurance', conf.ECM_FOLDER_SE, conf.ECM_FOLDER_SE_HIL),
        }
        self.doc_base_map = {
            'AFC': 'SF5_CN',
            'HIL': 'SF5_CL',
        }
        self.b_region_name_map = {
            'AFC': 'CN',
            'HIL': 'CL',
        }
        self.prefix = 'OCR'
        self.upload_fields = ["r_object_type", "r_creation_date",
                              "r_creator_name", "r_modify_date", "r_modifier", "owner", "b_short_application_no",
                              "b_short_contract_no", "b_customer_id", "b_customer_name", "b_customer_mobile",
                              "b_coborrower_id", "b_coborrower_name", "b_guarantor_id", "b_guarantor_name",
                              "b_frontend_partner", "b_dealer_code", "b_dealer_name", "b_comment",
                              "b_contract_no", "b_location", "b_company_name", "b_certificate_code", "b_vin",
                              "b_registration_no", "b_F2I_name"]
        self.log_base = '[ecm]'

    def update_oauth_token(self):
        response = requests.post(self.oauth_url, headers=self.oauth_headers, data=self.oauth_payload, verify=False)
        if response.status_code != 200:
            raise ECMException('ECM Oauth response with code: {0}'.format(response.status_code))
        token = response.json().get(self.token_key)
        if not isinstance(token, str):
            raise ECMException('ECM Oauth can not get token: {0}'.format(response.json()))
        self.oauth_token = token
        self.token_type = response.json().get(self.token_type_key, self.token_type)
        expires = response.json().get(self.expires_key, 3600)
        if isinstance(expires, int):
            expires_int = expires - 10
        elif isinstance(expires, str):
            expires_int = int(expires) - 10
        else:
            expires_int = 3600 - 10
        rh.set_ecm_token(self.oauth_token, expires_int)

    def get_oauth_token(self):
        # if self.oauth_token is None:
            # redis获取token
        self.oauth_token = rh.get_ecm_token()
        if self.oauth_token is None:
            self.update_oauth_token()
        return self.oauth_token

    def get_headers(self):
        return {
            'Authorization': '{0} {1}'.format(self.token_type, self.get_oauth_token()),
            'client_id': conf.ECM_OAUTH_ID, 
            'client_secret': conf.ECM_OAUTH_SECRET
            }

    def download(self, save_path, object_id, document_scheme, business_type):
        doc_type, _, _ = self.doc_type_map.get(document_scheme)
        download_json = {
            "userName": self.username,
            "password": self.pwd,
            "docbase": self.doc_base_map.get(business_type),
            "documentType": doc_type,
            "objectId": object_id,
            "b_input_date": time.strftime("%m/%d/%Y %X"),
            "b_credit_signing_date": time.strftime("%m/%d/%Y %X"),
            "b_credit_check": True,
            "b_id_number": '',
        }
        header_info = self.get_headers()
        self.running_log.info("{0} download header_info:{1}".format(self.log_base, header_info))
        self.running_log.info("{0} download args_info:{1}".format(self.log_base, download_json))
        response = requests.post(self.download_url, headers=header_info, json=download_json, verify=False)
        if response.status_code != 200:
            raise ECMException('ECM download failed with code: {0}'.format(response.status_code))
        base64_data = response.json().get('Envelope', {}).get('Body', {}).get('getResponse', {}).get('return', {}).get(
            'DataObjects', {}).get('Contents', {}).get('Value')
        if not isinstance(base64_data, str):
            raise ECMException('ECM download failed: {0}'.format(response.json()))
        with open(save_path, "wb") as fh:
            fh.write(base64.b64decode(base64_data.encode()))

    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 upload(self, file_path, doc, business_type, need_follow):
        doc_type, folder_afc, folder_hil = self.doc_type_map.get(doc.document_scheme)
        folder = folder_afc if business_type == 'AFC' else folder_hil
        object_name = '关注' + self.get_doc_file_name(doc.document_name) if need_follow else self.get_doc_file_name(doc.document_name)
        args = {
            "username": self.username,
            "password": self.pwd,
            "docbase": self.doc_base_map.get(business_type),
            "documentType": doc_type,
            "object_name": object_name,
            "folder": folder,
            "format": "excel12book",
            "r_content_type": "excel12book",
            "b_application_no": doc.application_id,
            "b_region": "0",
            "b_region_name": self.b_region_name_map.get(business_type),
            "b_input_date": time.strftime("%m/%d/%Y %X"),
            "b_credit_signing_date": time.strftime("%m/%d/%Y %X"),
            "b_credit_check": True,
            "b_id_number": '',
            # "file_base64_content": "",
        }
        for key in self.upload_fields:
            args[key] = ''
        with open(file_path, 'rb') as f:
            base64_data = base64.b64encode(f.read())
            # 获取解码后的base64值
            file_data = base64_data.decode()
        args['file_base64_content'] = file_data
        header_info = self.get_headers()
        self.running_log.info("{0} upload header_info:{1}".format(self.log_base, header_info))
        self.running_log.info("{0} upload args_info:{1}".format(self.log_base, args))
        response = requests.post(self.upload_url, headers=header_info, json=args, verify=False)
        if response.status_code != 200:
            raise ECMException('ECM upload failed with code: {0} , with headers: {1} , with content: {2}'.format(
                response.status_code, response.headers, response.text))
        if 'ns12:createResponse' not in response.json().get('S:Envelope', {}).get('S:Body', {}):
            raise ECMException('ECM upload failed: {0} , with headers: {1}'.format(response.json(), response.headers))