def publish_book(*args, **kwargs): # global x # Entire publisher is at the moment hard coded for pdf output # set logger logger.debug(kwargs) book = models.Book.objects.get(id=kwargs['bookid']) book_url = "%s/%s/_export/" % (settings.BOOKTYPE_URL, book.url_title) data = { "assets": { "input.epub": book_url }, "input": "input.epub", "outputs": {} } for _format in kwargs['formats']: _ext = "pdf" _suffix = "-{}".format(_format.upper()) if _format == "epub3": _ext = "epub" elif _format == "epub2": _ext = "epub" elif _format == "mobi": _ext = "mobi" elif _format == "xhtml": _ext = "zip" elif _format == "icml": _ext = "zip" elif _format == "docx": _ext = "zip" elif _format == "pdfreactor": _ext = "pdf" elif _format == "pdfreactor-screenpdf": _ext = "pdf" format_settings = get_settings_as_dictionary(book, _format) data["outputs"][_format] = { "profile": _format, "config": { "project_id": book.url_title, "settings": format_settings, "theme": get_theme(book) }, "output": "{0}_{1}{2}.{3}".format( book.url_title, datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'), _suffix, _ext ) } if 'cover_image' in format_settings: if format_settings['cover_image'].strip() != '': cover_url = "{}/{}/_cover/{}".format( settings.BOOKTYPE_URL, book.url_title, format_settings['cover_image'] ) data['assets']['{}_cover_image'.format(_format)] = cover_url data["outputs"][_format]["config"]["cover_image"] = '{}_cover_image'.format(_format) logger.debug(data) output_results = {} # _format: False for _format in data["outputs"].iterkeys()} convert_url = '{}/_convert/'.format(settings.CONVERT_URL) result = download.fetch_url(convert_url, data, method='POST') if not result: logger.error('Could not send the publishing request to [{}]'.format(convert_url)) sputnik.addMessageToChannel2( kwargs['clientid'], kwargs['sputnikid'], "/booktype/book/%s/%s/" % (book.pk, kwargs['version']), { "command": "book_published", "state": 'FAILURE' }, myself=True ) return task_id = result['task_id'] start_time = time.time() EXPORT_WAIT_FOR = config.get_configuration('EXPORT_WAIT_FOR', 90) # noqa logger.debug('Waiting for the task %s to finish. Will wait for %s seconds.', task_id, EXPORT_WAIT_FOR) while True: if time.time() - start_time > EXPORT_WAIT_FOR: logger.error('Publishing request timed out after %s seconds.', int(time.time() - start_time)) sputnik.addMessageToChannel2( kwargs['clientid'], kwargs['sputnikid'], "/booktype/book/%s/%s/" % (book.pk, kwargs['version']), { "command": "book_published", "state": 'FAILURE' }, myself=True ) break dta = download.fetch_url('{}/_convert/{}'.format(settings.CONVERT_URL, task_id), {}, method='GET') if not dta: logger.error( 'Could not communicate with a server to fetch polling data.') if dta['state'] == 'SUCCESS': for _key in data["outputs"].iterkeys(): if 'state' in dta['result'][_key]: if dta['result'][_key]['state'] == 'SUCCESS': output_results[_key] = True elif dta['result'][_key]['state'] == 'FAILURE': output_results[_key] = False if len(output_results) == len(data["outputs"].keys()): _now = datetime.datetime.now() export_name = "Book export - {0}".format( datetime.datetime( _now.year, _now.month, _now.day, _now.hour, _now.minute, _now.second ) ) exporter = User.objects.get(username=kwargs["username"]) exprt = BookExport( version=book.get_version(), name=export_name, user=exporter, task_id=task_id, created=_now, published=None, status=0) exprt.save() _files = {} for output_type, result in dta['result'].iteritems(): if 'state' in result: if result['state'] == 'SUCCESS': status = 0 description = '' filename = result['result']['output'] filesize = result['result'].get('size', 0) pages = result['result'].get('pages', 0) else: status = 1 description = result.get('error', '') filename = None filesize = 0 pages = 0 ef = ExportFile( export=exprt, typeof=output_type, filesize=filesize, pages=pages, status=status, description=description, filename=filename) ef.save() _files[output_type] = { 'filename': filename, 'status': status, 'description': description, 'filesize': filesize, 'pages': pages} sputnik.addMessageToChannel2( kwargs['clientid'], kwargs['sputnikid'], "/booktype/book/%s/%s/" % (book.pk, kwargs['version']), { "command": "book_published", "state": 'SUCCESS', "name": export_name, "username": kwargs["username"], "task_id": task_id, "created": _now.strftime("%d.%m.%Y %H:%M:%S"), "published": "", "status": 0, "files": _files, "comments": [] }, myself=True ) logger.info('Successfully received status of the conversion task %s.', task_id) # emulate user object and request object needed for send_notification function user = namedtuple('user', 'username')(username=kwargs['username']) request = namedtuple('request', 'user clientID sputnikID')(user=user, clientID=kwargs['clientid'], sputnikID=kwargs['sputnikid']) send_notification(request, kwargs['bookid'], kwargs['version'], "notification_book_export_was_successful", export_name) break if dta['state'] == 'FAILURE': logger.error('Convert returned FAILURE status. Publishing will not be finished.') sputnik.addMessageToChannel2( kwargs['clientid'], kwargs['sputnikid'], "/booktype/book/%s/%s/" % (book.pk, kwargs['version']), { "command": "book_published", "state": 'FAILURE' }, myself=True ) break time.sleep(0.5)
def send_request(book_url, conf, request): data = {"assets": {"input.epub": book_url}, "input": "input.epub", "outputs": {}} mpdf_settings = {} _ext = "pdf" if conf["format"] == "epub": _ext = "epub" if conf["format"] == "mobi": _ext = "mobi" _css = request.POST.get("css", "") tag = "/* CUSTOM */" if _css.find(tag) != -1: _css = _css[_css.find(tag) :] else: _css = "" if conf["format"] == "mpdf": mpdf_settings = { "size": request.POST.get("booksize", "A4"), "custom_width": request.POST.get("custom_width", 0), "custom_height": request.POST.get("custom_height", 0), "side_margin": request.POST.get("side_margin", 0), "bottom_margin": request.POST.get("bottom_margin", 0), "top_margin": request.POST.get("top_margin", 0), "gutter": request.POST.get("gutter", 0), "show_header": "on", "header_margin": 5, "show_footer": "on", "footer_margin": 5, "bleed_size": 0, "styling": _css, "crop_marks": "off", } if conf["format"] == "screenpdf": mpdf_settings = { "size": request.POST.get("booksize", "A4"), "custom_width": request.POST.get("custom_width", 0), "custom_height": request.POST.get("custom_height", 0), "side_margin": request.POST.get("side_margin", 0), "bottom_margin": request.POST.get("bottom_margin", 0), "top_margin": request.POST.get("top_margin", 0), "gutter": request.POST.get("gutter", 0), "show_header": "on", "header_margin": 5, "show_footer": "on", "footer_margin": 5, "bleed_size": 0, "styling": _css, "crop_marks": "off", } data["outputs"][conf["format"]] = { "profile": conf["format"], "config": {"project_id": conf["title"], "settings": mpdf_settings, "theme": {}}, "output": "{}.{}".format(conf["title"], _ext), } if "cover_url" in request.POST: if conf["format"] == "screenpdf": data["assets"]["screenpdf_cover_image"] = request.POST.get("cover_url", "") data["outputs"][conf["format"]]["config"]["cover_image"] = "screenpdf_cover_image" elif conf["format"] == "epub": data["assets"]["epub_cover_image"] = request.POST.get("cover_url", "") data["outputs"][conf["format"]]["config"]["cover_image"] = "epub_cover_image" elif conf["format"] == "mobi": data["assets"]["mobi_cover_image"] = request.POST.get("cover_url", "") data["outputs"][conf["format"]]["config"]["cover_image"] = "mobi_cover_image" output_results = {} convert_url = "{}/_convert/".format(settings.CONVERT_URL) result = download.fetch_url(convert_url, data, method="POST") if not result: return None task_id = result["task_id"] start_time = time.time() while True: if time.time() - start_time > 60 * 8: break dta = download.fetch_url(settings.CONVERT_URL, task_id, {}, "GET") if not dta: dta = {"state": ""} logger.exception("Could not read response data.") if dta["state"] == "SUCCESS": for _key in data["outputs"].iterkeys(): if "state" in dta["result"][_key]: if dta["result"][_key]["state"] == "SUCCESS": output_results[_key] = True elif dta["result"][_key]["state"] == "FAILURE": output_results[_key] = False if len(output_results) == len(data["outputs"].keys()): def _x(_key): d = {} if "result" in dta["result"][_key]: d = dta["result"][_key]["result"] d["status"] = output_results[_key] return d urls = {_key: _x(_key) for _key in output_results.iterkeys()} _now = datetime.datetime.now() _files = {} for output_type, result in dta["result"].iteritems(): if "state" in result: if result["state"] == "SUCCESS": return result else: logger.error("Some kind of error in publishing.") break if dta["state"] == "FAILURE": logger.error("Some kind of error in publishing.") break return None
def publish_book(*args, **kwargs): # global x # Entire publisher is at the moment hard coded for pdf output # set logger logger.debug(kwargs) book = models.Book.objects.get(id=kwargs['bookid']) book_url = "%s/%s/_export/" % (settings.BOOKTYPE_URL, book.url_title) data = { "assets": { "input.epub": book_url }, "input": "input.epub", "outputs": {} } for _format in kwargs['formats']: _ext = "pdf" _suffix = "" if _format == "epub": _ext = "epub" elif _format == "mobi": _ext = "mobi" elif _format == "xhtml": _ext = "zip" _suffix = "-XHTML" elif _format == "icml": _ext = "zip" _suffix = "-ICML" elif _format == "docx": _ext = "zip" _suffix = "-DOCX" format_settings = get_settings_as_dictionary(book, _format) data["outputs"][_format] = { "profile": _format, "config": { "project_id": book.url_title, "settings": format_settings, "theme": get_theme(book, kwargs["username"]) }, "output": "{0}_{1}{2}.{3}".format( book.url_title, datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'), _suffix, _ext ) } if 'cover_image' in format_settings: if format_settings['cover_image'].strip() != '': cover_url = "{}/{}/_cover/{}".format( settings.BOOKTYPE_URL, book.url_title, format_settings['cover_image'] ) data['assets']['{}_cover_image'.format(_format)] = cover_url data["outputs"][_format]["config"]["cover_image"] = '{}_cover_image'.format(_format) logger.debug(data) output_results = {} # _format: False for _format in data["outputs"].iterkeys()} convert_url = '{}/_convert/'.format(settings.CONVERT_URL) result = download.fetch_url(convert_url, data, method='POST') if not result: logger.error('Could not send the publishing request to [{}]'.format(convert_url)) sputnik.addMessageToChannel2( kwargs['clientid'], kwargs['sputnikid'], "/booktype/book/%s/%s/" % (book.pk, kwargs['version']), { "command": "book_published", "state": 'FAILURE' }, myself=True ) return task_id = result['task_id'] start_time = time.time() EXPORT_WAIT_FOR = config.get_configuration('EXPORT_WAIT_FOR', 90) # noqa logger.debug('Waiting for the task %s to finish. Will wait for %s seconds.', task_id, EXPORT_WAIT_FOR) while True: if time.time() - start_time > EXPORT_WAIT_FOR: logger.error('Publishing request timed out after %s seconds.', int(time.time() - start_time)) sputnik.addMessageToChannel2( kwargs['clientid'], kwargs['sputnikid'], "/booktype/book/%s/%s/" % (book.pk, kwargs['version']), { "command": "book_published", "state": 'FAILURE' }, myself=True ) break dta = download.fetch_url('{}/_convert/{}'.format(settings.CONVERT_URL, task_id), {}, method='GET') if not dta: logger.error( 'Could not communicate with a server to fetch polling data.') if dta['state'] == 'SUCCESS': for _key in data["outputs"].iterkeys(): if 'state' in dta['result'][_key]: if dta['result'][_key]['state'] == 'SUCCESS': output_results[_key] = True elif dta['result'][_key]['state'] == 'FAILURE': output_results[_key] = False if len(output_results) == len(data["outputs"].keys()): _now = datetime.datetime.now() export_name = "Book export - {0}".format( datetime.datetime( _now.year, _now.month, _now.day, _now.hour, _now.minute, _now.second ) ) exporter = User.objects.get(username=kwargs["username"]) exprt = BookExport( version=book.get_version(), name=export_name, user=exporter, task_id=task_id, created=_now, published=None, status=0) exprt.save() _files = {} for output_type, result in dta['result'].iteritems(): if 'state' in result: if result['state'] == 'SUCCESS': status = 0 description = '' filename = result['result']['output'] filesize = result['result'].get('size', 0) pages = result['result'].get('pages', 0) else: status = 1 description = result.get('error', '') filename = None filesize = 0 pages = 0 ef = ExportFile( export=exprt, typeof=output_type, filesize=filesize, pages=pages, status=status, description=description, filename=filename) ef.save() _files[output_type] = { 'filename': filename, 'status': status, 'description': description, 'filesize': filesize, 'pages': pages} sputnik.addMessageToChannel2( kwargs['clientid'], kwargs['sputnikid'], "/booktype/book/%s/%s/" % (book.pk, kwargs['version']), { "command": "book_published", "state": 'SUCCESS', "name": export_name, "username": kwargs["username"], "task_id": task_id, "created": _now.strftime("%d.%m.%Y %H:%M:%S"), "published": "", "status": 0, "files": _files, "comments": [] }, myself=True ) logger.info('Successfully received status of the conversion task %s.', task_id) # emulate user object and request object needed for send_notification function user = namedtuple('user', 'username')(username=kwargs['username']) request = namedtuple('request', 'user clientID sputnikID')(user=user, clientID=kwargs['clientid'], sputnikID=kwargs['sputnikid']) send_notification(request, kwargs['bookid'], kwargs['version'], "notification_book_export_was_successful", export_name) break if dta['state'] == 'FAILURE': logger.error('Convert returned FAILURE status. Publishing will not be finished.') sputnik.addMessageToChannel2( kwargs['clientid'], kwargs['sputnikid'], "/booktype/book/%s/%s/" % (book.pk, kwargs['version']), { "command": "book_published", "state": 'FAILURE' }, myself=True ) break time.sleep(0.5)
def send_request(book_url, conf, request): data = { "assets": { "input.epub": book_url }, "input": "input.epub", "outputs": {} } mpdf_settings = {} _ext = 'pdf' if conf['format'] == 'epub': _ext = 'epub' if conf['format'] == 'mobi': _ext = 'mobi' _css = request.POST.get('css', '') tag = '/* CUSTOM */' if _css.find(tag) != -1: _css = _css[_css.find(tag):] else: _css = '' if conf['format'] == 'mpdf': mpdf_settings = { 'size': request.POST.get('booksize', 'A4'), 'custom_width': request.POST.get('custom_width', 0), 'custom_height': request.POST.get('custom_height', 0), 'side_margin': request.POST.get('side_margin', 0), 'bottom_margin': request.POST.get('bottom_margin', 0), 'top_margin': request.POST.get('top_margin', 0), 'gutter': request.POST.get('gutter', 0), 'show_header': 'on', 'header_margin': 5, 'show_footer': 'on', 'footer_margin': 5, 'bleed_size': 0, 'styling': _css, 'crop_marks': 'off' } if conf['format'] == 'screenpdf': mpdf_settings = { 'size': request.POST.get('booksize', 'A4'), 'custom_width': request.POST.get('custom_width', 0), 'custom_height': request.POST.get('custom_height', 0), 'side_margin': request.POST.get('side_margin', 0), 'bottom_margin': request.POST.get('bottom_margin', 0), 'top_margin': request.POST.get('top_margin', 0), 'gutter': request.POST.get('gutter', 0), 'show_header': 'on', 'header_margin': 5, 'show_footer': 'on', 'footer_margin': 5, 'bleed_size': 0, 'styling': _css, 'crop_marks': 'off' } data["outputs"][conf['format']] = { "profile": conf['format'], "config": { "project_id": conf['title'], "settings": mpdf_settings, "theme": {} }, "output": "{}.{}".format(conf['title'], _ext) } if 'cover_url' in request.POST: if conf['format'] == 'screenpdf': data['assets']['screenpdf_cover_image'] = request.POST.get( 'cover_url', '') data['outputs'][conf['format']]['config'][ 'cover_image'] = 'screenpdf_cover_image' elif conf['format'] == 'epub': data['assets']['epub_cover_image'] = request.POST.get( 'cover_url', '') data['outputs'][ conf['format']]['config']['cover_image'] = 'epub_cover_image' elif conf['format'] == 'mobi': data['assets']['mobi_cover_image'] = request.POST.get( 'cover_url', '') data['outputs'][ conf['format']]['config']['cover_image'] = 'mobi_cover_image' output_results = {} convert_url = '{}/_convert/'.format(settings.CONVERT_URL) result = download.fetch_url(convert_url, data, method='POST') if not result: return None task_id = result['task_id'] start_time = time.time() while True: if time.time() - start_time > 60 * 8: break dta = download.fetch_url(settings.CONVERT_URL, task_id, {}, 'GET') if not dta: dta = {'state': ''} logger.exception('Could not read response data.') if dta['state'] == 'SUCCESS': for _key in data["outputs"].iterkeys(): if 'state' in dta['result'][_key]: if dta['result'][_key]['state'] == 'SUCCESS': output_results[_key] = True elif dta['result'][_key]['state'] == 'FAILURE': output_results[_key] = False if len(output_results) == len(data["outputs"].keys()): def _x(_key): d = {} if 'result' in dta['result'][_key]: d = dta['result'][_key]['result'] d['status'] = output_results[_key] return d urls = {_key: _x(_key) for _key in output_results.iterkeys()} _now = datetime.datetime.now() _files = {} for output_type, result in dta['result'].iteritems(): if 'state' in result: if result['state'] == 'SUCCESS': return result else: logger.error('Some kind of error in publishing.') break if dta['state'] == 'FAILURE': logger.error('Some kind of error in publishing.') break return None