Example #1
0
 def fail(self, message = None):
     if self._colorize:
         self._spinner.fail(color(self._current_message, 'error', self._colorize))
         self._spinner.stop()
         self.start(message)
         self._spinner.fail(color(message, 'error', self._colorize))
         self._spinner.stop()
     else:
         msg('ERROR: ' + message)
Example #2
0
 def update(self, message = None):
     if self._quiet:
         return
     if self._colorize:
         self._spinner.succeed(color(self._current_message, 'info', self._colorize))
         self._spinner.stop()
         self.start(message)
     else:
         msg(message)
Example #3
0
 def warn(self, message=None):
     if self._quiet:
         return
     if self._colorize:
         self._spinner.succeed(
             color(self._current_message, 'info', self._colorize))
         self._spinner.stop()
         self._spinner.warn(color(message, 'warn', self._colorize))
         self._current_message = ''
     else:
         msg('WARNING: ' + message)
Example #4
0
 def start(self, message = None):
     if self._quiet:
         return
     if message is None:
         message = ''
     if self._colorize:
         text = color(message, 'info')
         self._spinner = Halo(spinner='bouncingBall', text = text)
         self._spinner.start()
         self._current_message = message
     else:
         msg(message)
Example #5
0
    def all_results(self, path):
        '''Returns all the results from the service as a Python dict.'''
        # Check if we already processed it.
        if path in self._results:
            return self._results[path]

        if __debug__: log('Reading {}', path)
        with io.open(path, 'rb') as image_file:
            image_data = image_file.read()

        # Google Cloud Vision API docs state that images cannot exceed 20 MB:
        # https://cloud.google.com/vision/docs/supported-files
        if len(image_data) > 20 * 1024 * 1024:
            text = 'Error: file "{}" is too large for Google service'.format(
                path)
            msg(text, 'warn')
            return text
        try:
            if __debug__: log('Building Google vision API object')
            client = gv.ImageAnnotatorClient()
            image = gv.types.Image(content=image_data)
            context = gv.types.ImageContext(
                language_hints=['en-t-i0-handwrit'])

            # Iterate over the known API calls and store each result.
            results = {}
            for feature in self._known_features:
                if __debug__:
                    log('Sending image to Google for {} ...', feature)
                response = getattr(client, feature)(image=image,
                                                    image_context=context)
                if __debug__: log('Received result.')
                results[feature] = MessageToDict(response)
            self._results[path] = results
            return results
        except google.api_core.exceptions.PermissionDenied as err:
            text = 'Authentication failure for Google service -- {}'.format(
                err)
            raise ServiceFailure(text)
        except Exception as err:
            text = 'Error: failed to convert "{}": {}'.format(path, err)
            return text
Example #6
0
    def all_results(self, path):
        '''Returns all the results from the service as a Python dict.'''
        # Check if we already processed it.
        if path in self._results:
            return self._results[path]

        vision_base_url = "https://westus.api.cognitive.microsoft.com/vision/v2.0/"
        text_recognition_url = vision_base_url + "recognizeText"

        headers = {
            'Ocp-Apim-Subscription-Key': self.credentials,
            'Content-Type': 'application/octet-stream'
        }
        params = {'mode': 'Handwritten'}
        image_data = open(path, 'rb').read()

        # https://docs.microsoft.com/en-us/azure/cognitive-services/computer-vision/home
        # states "The file size of the image must be less than 4 megabytes (MB)"
        if len(image_data) > 4 * 1024 * 1024:
            text = 'File "{}" is too large for Microsoft service'.format(path)
            msg(text, 'warn')
            return text

        # Post it to the Microsoft cloud service.
        if __debug__: log('Sending file to MS cloud service')
        response = requests.post(text_recognition_url,
                                 headers=headers,
                                 params=params,
                                 data=image_data)
        try:
            response.raise_for_status()
        except HTTPError as err:
            # FIXME this might be a good place to suggest to the user that they
            # visit https://blogs.msdn.microsoft.com/kwill/2017/05/17/http-401-access-denied-when-calling-azure-cognitive-services-apis/
            if response.status_code in [401, 402, 403, 407, 451, 511]:
                text = 'Authentication failure for MS service -- {}'.format(
                    err)
                raise ServiceFailure(text)
            elif response.status_code == 429:
                text = 'Server blocking further requests due to rate limits'
                raise ServiceFailure(text)
            elif response.status_code == 503:
                text = 'Server is unavailable -- try again later'
                raise ServiceFailure(text)
            else:
                text = 'Encountered network communications problem -- {}'.format(
                    err)
                raise ServiceFailure(text)
        except Exception as err:
            import pdb
            pdb.set_trace()
            msg('MS rejected "{}"'.format(path), 'warn')
            return ''

        # The Microsoft API for extracting handwritten text requires two API
        # calls: one call to submit the image for processing, the other to
        # retrieve the text found in the image.  We have to poll and wait
        # until a result is available.
        analysis = {}
        poll = True
        if __debug__: log('Polling MS for results ...')
        while (poll):
            response_final = requests.get(
                response.headers["Operation-Location"], headers=headers)
            analysis = response_final.json()
            time.sleep(1)
            if ("recognitionResult" in analysis):
                poll = False
            if ("status" in analysis and analysis['status'] == 'Failed'):
                poll = False
        if __debug__: log('Results received.')
        self._results[path] = analysis
        return analysis