def _add_image_to_gridfs(self, image_id, image_content, image_content_type): d = GridFS(mongo_connection['rotator_database']).put( image_content, content_type=image_content_type, md5hash=image_id) d.addCallback(self._image_to_gridfs_success, image_id) log_me('_add_image_to_gridfs', image_id, image_content_type)
def render_GET(self, request): # pylint: disable=invalid-name assert check_content_type(request) log_me('render_GET') search_by = dict() is_one_item = False get_content = False postpath = cut_path(request.postpath) log_me(request.prepath, request.path, request.uri, postpath) if postpath: search_by['_id'] = postpath[0] is_one_item = True if len(postpath) > 1: if postpath[1] == 'content': get_content = True d = mongo_connection.get('rotator_database').metadata.find(search_by) if get_content: d.addCallback(self._get_image_content_success, request) d.addErrback(self._get_image_content_failure, request) else: request.setHeader('content-type', 'application/json') d.addCallback(self._image_info_success, request, is_one_item) d.addErrback(self._image_info_failure, request) return server.NOT_DONE_YET
def init_mongodb(self): log_me('init_mongodb') collections = yield self.rotator_database.collection_names() for collection_name in collections: yield self.rotator_database.drop_collection(collection_name) defer.returnValue(True)
def _image_get_info(self, value, request): d = mongo_connection.get('rotator_database').metadata.find({}) d.addCallback(self._image_info_success, request, False) d.addErrback(self._image_info_failure, request) log_me('_image_get_info ', value) return server.NOT_DONE_YET
def _output_delete_success(self, value, request): # pylint: disable=no-self-use log_me('_output_delete_success', value) request.setResponseCode(200) request.write(dumps({'error': ERROR_CHECK_BACK_LATER})) request.finish()
def _image_delete_failure(self, *args): if len(args) == 1: error, request = None, args[0] else: error, request = args log_me('_image_delete_failure', error) return self._image_get_info(None, request)
def _process_image_success(self, value): image_id, _, rotated_contents, image_content_type = value rotated_image_id = md5(rotated_contents).hexdigest() d = deferToThread(self._add_image_to_gridfs, rotated_image_id, rotated_contents, image_content_type) d.addCallback(self._update_image_status, image_id, rotated_image_id) log_me('_process_image_success', image_id, rotated_image_id)
def _get_image_content_failure(self, error, request): # pylint: disable=no-self-use log_me('_get_image_content_failure', error) request.setResponseCode(404) request.setHeader('content-type', 'application/json') request.write(dumps({'error': str(error)})) request.finish()
def _output_content(self, value, request): open_file = BytesIO(value) log_me('_output_content', open_file) d = FileSender().beginFileTransfer(open_file, request) d.addCallback(self._output_content_success, open_file, request) d.addErrback(self._get_image_content_failure, request) return server.NOT_DONE_YET
def _remove_metadata(self, metadata, request, search_by): gridfs_image_ids = [value.get('gridfs_id') for value in metadata] d = mongo_connection.get('rotator_database').metadata.remove(search_by) d.addCallback(self._image_delete_success, request, gridfs_image_ids) d.addErrback(self._image_delete_failure, request) log_me('_remove_metadata ', search_by, gridfs_image_ids) return server.NOT_DONE_YET
def _output_content_success(self, *args): # pylint: disable=no-self-use _, open_file, request = args log_me('_output_content_success', open_file) open_file.close() request.setResponseCode(200) request.finish()
def _image_to_gridfs_success(self, value, image_id): # pylint: disable=no-self-use mongo_connection.get('rotator_database').metadata.find_and_modify( query={'_id': image_id}, update={'$set': { 'gridfs_id': value }}, upsert=True) log_me('_image_to_gridfs_success', image_id)
def _get_gridfs_info(self, *args): log_me('_get_gridfs_info', args) value, request = args request.setHeader('content-type', str(value.contentType)) d = value.read() d.addCallback(self._output_content, request) d.addErrback(self._get_image_content_failure, request) return server.NOT_DONE_YET
def _image_info_success(self, value, request, is_one_item, is_posted=False): # pylint: disable=no-self-use images_list = list() for image_dict in value: image_dict['links'] = [ generate_link(request, image_dict['_id'], 'self', 'GET'), generate_link(request, image_dict['_id'], 'delete', 'DELETE'), generate_link(request, cut_path([image_dict['_id'], 'content']), 'content', 'GET') ] if image_dict.get('status') == 'processed': image_dict['links'].append( generate_link( request, cut_path([image_dict['rotated_image_id'], 'content']), 'rotated', 'GET')) image_dict['id'] = image_dict.pop('_id') try: image_dict.pop('gridfs_id') except KeyError: pass log_me(image_dict) images_list.append(image_dict) if is_one_item: try: return_dict = {'image': images_list[0]} request.setResponseCode(200) except IndexError: return_dict = {'error': ERROR_IMAGE_NOT_FOUND} request.setResponseCode(404) else: return_dict = {'images': images_list} if is_posted: return_dict['error'] = ERROR_CHECK_BACK_LATER request.setResponseCode(201) else: request.setResponseCode(200) return_dict['version'] = API_VERSION request.write(dumps(return_dict)) request.finish()
def _image_delete_success(self, value, request, file_ids): dl = [] for file_id in file_ids: dl.append( GridFS(mongo_connection['rotator_database']).delete(file_id)) d = defer.DeferredList(dl) d.addCallback(self._output_delete_success, request) d.addErrback(self._image_delete_failure, request) log_me('_image_delete_success', value, file_ids) return server.NOT_DONE_YET
def _update_image_status(self, value, image_id, rotated_image_id): # pylint: disable=unused-argument,no-self-use mongo_connection.get('rotator_database').metadata.find_and_modify( query={'_id': image_id}, update={ '$set': { 'status': 'processed', 'rotated_image_id': rotated_image_id } }, upsert=True) log_me('_update_image_status', image_id)
def _test_request(self, *args, **kwargs): method, path = args request = Request(method, path) resource = yield self.site.getResourceFor(request) request.path = request.prepath + request.postpath if args: request.args = kwargs yield _render(resource, request) log_me(resource, request) defer.returnValue((resource, request))
def _get_image_content_success(self, value, request): log_me('_get_image_content_success', value) if value and len(value): gridfs_id = value[0].get('gridfs_id') log_me('gridfs_id', gridfs_id) d = GridFS(mongo_connection['rotator_database']).get(gridfs_id) d.addCallback(self._get_gridfs_info, request) d.addErrback(self._get_image_content_failure, request) return server.NOT_DONE_YET else: return self._get_image_content_failure( ERROR_IMAGE_NOT_FOUND_IN_GRIDFS, request)
def _process_image(self, image_id, image_content, image_content_type, angle): deferToThread(self._add_image_to_gridfs, image_id, image_content, image_content_type) image = Image.open(BytesIO(image_content)) rotated_image = image.rotate(angle) output = StringIO() rotated_image.save(output, format=IMAGE_PIL_FORMATS.get(image_content_type)) rotated_contents = output.getvalue() output.close() log_me('_process_image', image_id, image_content_type) return image_id, image_content, rotated_contents, image_content_type
def test_rotator(self): yield self.init_mongodb() global_dict = dict() for name in sorted(dir(self)): if name.startswith('step'): step = getattr(self, name) try: # pylint: disable=broad-except return_dict = yield step(global_dict) log_me(return_dict) global_dict.update(return_dict) except Exception as broad_exception: self.fail("{} failed ({}: {})".format( step, type(broad_exception), broad_exception ))
def tearDown(self): log_me('tearDown') from rotator.api import mongo_connection mongo_connection.get('connection').disconnect() mongo_connection['connected'] = False