예제 #1
0
    def _render2(self):

        IPersistentLogger(self.context).log('convert')
        payload = decode_json_payload(self.request)

        if 'mapping' not in payload:
            raise ValueError('No "mapping" found in JSON payload')

        rules = payload['mapping']
        conversion_id = payload.get('converter', 'docx2ditatopic')
        conversion_endpoint_url = ENDPOINTS[conversion_id]['url']
        rewriter = RuleRewriter(rules)

        handle = self.context.webdav_handle()
        zip_tmp = temp_zip(suffix='.zip')
        with fs.zipfs.ZipFS(zip_tmp, 'w') as zip_fp:
            for name in handle.walkfiles():
                if name.endswith('.sha256'):
                    continue
                name_in_zip = rewriter.rewrite(name)
                if name_in_zip:
                    with handle.open(name, 'rb') as fp_in, \
                            zip_fp.open(name_in_zip, 'wb') as fp:
                        fp.write(fp_in.read())

        
        with delete_after(zip_tmp):
            zip_out = convert_crex(zip_tmp, crex_url=conversion_endpoint_url)
        store_zip(self.context, zip_out, 'current')

        conversion_info = self.get_crex_info()
        conversion_info['status'] = CREX_STATUS_SUCCESS
        self.set_crex_info(conversion_info)

        with delete_after(zip_out):
            self.request.response.setHeader(
                'content-length', str(os.path.getsize(zip_out)))
            self.request.response.setHeader('content-type', 'application/zip')
            self.request.response.setHeader(
                'content-disposition', 'attachment; filename={}.zip'.format(self.context.getId()))
            return filestream_iterator(zip_out)
예제 #2
0
def convert_crex(zip_path, crex_url=None, crex_username=None, crex_password=None):
    """ Send ZIP archive with content to be converted to C-Rex.
        Returns name of ZIP file with converted resources.
    """

    ts = time.time()
    registry = getUtility(IRegistry)
    settings = registry.forInterface(ICRexSettings)

    crex_conversion_url = crex_url or settings.crex_conversion_url
    crex_conversion_username = crex_username or settings.crex_conversion_username
    crex_conversion_password = crex_password or settings.crex_conversion_password
    crex_token = settings.crex_conversion_token

    # Fetch authentication token if necessary (older than one hour)
    crex_token_last_fetched = settings.crex_conversion_token_last_fetched or datetime.datetime(
        2000, 1, 1)
    diff = datetime.datetime.utcnow() - crex_token_last_fetched

    if not crex_token or diff.total_seconds() > 3600:
        f = furl.furl(crex_conversion_url)
        token_url = '{}://{}/api/Token'.format(
            f.scheme, f.host, crex_conversion_url)
        headers = {'content-type': 'application/x-www-form-urlencoded'}
        params = dict(
            username=crex_conversion_username,
            password=crex_conversion_password,
            grant_type='password')
        result = requests.post(token_url, data=params, headers=headers)
        if result.status_code != 200:
            msg = u'Error retrieving DOCX conversion token from webservice (HTTP code {}, Message {})'.format(
                result.status_code, result.text)
            LOG.error(msg)
            raise CRexConversionError(msg)
        data = result.json()
        crex_token = data['access_token']
        settings.crex_conversion_token = crex_token
        settings.crex_conversion_token_last_fetched = datetime.datetime.utcnow()
        LOG.info('Fetching new DOCX authentication token - successful')
    else:
        LOG.info('Fetching DOCX authentication token from Plone cache')

    headers = {'authorization': 'Bearer {}'.format(crex_token)}

    with open(zip_path, 'rb') as fp:
        try:
            LOG.info(u'Starting C-Rex conversion of {}, size {} '.format(zip_path,
                                                                         os.path.getsize(zip_path)))
            result = requests.post(
                crex_conversion_url, files=dict(source=fp), headers=headers)
        except requests.ConnectionError:
            msg = u'Connection to C-REX webservice failed'
            raise CRexConversionError(msg)

        if result.status_code == 200:
            msg = u'Conversion successful (HTTP code {}, duration: {:2.1f} seconds))'.format(
                result.status_code, time.time() - ts)
            LOG.info(msg)
            zip_out = temp_zip(suffix='.zip')
            with open(zip_out, 'wb') as fp:
                fp.write(result.content)
            return zip_out

        else:
            # Forbidden -> invalid token -> invalidate token stored in Plone
            if result.status_code == 401:
                settings.crex_conversion_token = u''
                settings.crex_conversion_token_last_fetched = datetime.datetime(
                    1999, 1, 1)
            msg = u'Conversion failed (HTTP code {}, message {})'.format(
                result.status_code, result.text)
            LOG.error(msg)
            raise CRexConversionError(msg)