# Buggy code
def _convert_ebook_format(self):
    error_message = None
    file_path = self.queue[self.current]["file_path"]
    bookid = self.queue[self.current]["bookid"]
    format_old_ext = (
        "." + self.queue[self.current]["settings"]["old_book_format"].lower()
    )
    format_new_ext = (
        "." + self.queue[self.current]["settings"]["new_book_format"].lower()
    )

    # check to see if destination format already exists -
    # if it does - mark the conversion task as complete and return a success
    # this will allow send to kindle workflow to continue to work
    if os.path.isfile(file_path + format_new_ext):
        web.app.logger.info(
            "Book id %d already converted to %s", bookid, format_new_ext
        )
        cur_book = (
            web.db.session.query(web.db.Books).filter(web.db.Books.id == bookid).first()
        )
        self.queue[self.current]["path"] = file_path
        self.queue[self.current]["title"] = cur_book.title
        self._handleSuccess()
        return file_path + format_new_ext
    else:
        web.app.logger.info(
            "Book id %d - target format of %s does not exist. Moving forward with convert.",
            bookid,
            format_new_ext,
        )

    # check if converter-executable is existing
    if not os.path.exists(web.ub.config.config_converterpath):
        # ToDo Text is not translated
        self._handleError(
            "Convertertool %s not found" % web.ub.config.config_converterpath
        )
        return

    try:
        # check which converter to use kindlegen is "1"
        if format_old_ext == ".epub" and format_new_ext == ".mobi":
            if web.ub.config.config_ebookconverter == 1:
                if os.name == "nt":
                    command = (
                        web.ub.config.config_converterpath + ' "' + file_path + '.epub"'
                    )
                    if sys.version_info < (3, 0):
                        command = command.encode(sys.getfilesystemencoding())
                else:
                    command = [web.ub.config.config_converterpath, file_path + ".epub"]
                    if sys.version_info < (3, 0):
                        command = [
                            x.encode(sys.getfilesystemencoding()) for x in command
                        ]
        if web.ub.config.config_ebookconverter == 2:
            # Linux py2.7 encode as list without quotes no empty element for parameters
            # linux py3.x no encode and as list without quotes no empty element for parameters
            # windows py2.7 encode as string with quotes empty element for parameters is okay
            # windows py 3.x no encode and as string with quotes empty element for parameters is okay
            # separate handling for windows and linux
            if os.name == "nt":
                command = (
                    web.ub.config.config_converterpath
                    + ' "'
                    + file_path
                    + format_old_ext
                    + '" "'
                    + file_path
                    + format_new_ext
                    + '" '
                    + web.ub.config.config_calibre
                )
                if sys.version_info < (3, 0):
                    command = command.encode(sys.getfilesystemencoding())
            else:
                command = [
                    web.ub.config.config_converterpath,
                    (file_path + format_old_ext),
                    (file_path + format_new_ext),
                ]
                if web.ub.config.config_calibre:
                    command.append(web.ub.config.config_calibre)
                if sys.version_info < (3, 0):
                    command = [x.encode(sys.getfilesystemencoding()) for x in command]

        p = subprocess.Popen(command, stdout=subprocess.PIPE, universal_newlines=True)
    except OSError as e:
        self._handleError(_("Ebook-converter failed: %(error)s", error=e))
        return

    if web.ub.config.config_ebookconverter == 1:
        nextline = p.communicate()[0]
        # Format of error message (kindlegen translates its output texts):
        # Error(prcgen):E23006: Language not recognized in metadata.The dc:Language field is mandatory.Aborting.
        conv_error = re.search(".*\(.*\):(E\d+):\s(.*)", nextline, re.MULTILINE)
        # If error occoures, store error message for logfile
        if conv_error:
            error_message = _(
                "Kindlegen failed with Error %(error)s. Message: %(message)s",
                error=conv_error.group(1),
                message=conv_error.group(2).strip(),
            )
        web.app.logger.debug("convert_kindlegen: " + nextline)
    else:
        while p.poll() is None:
            nextline = p.stdout.readline()
            if os.name == "nt" and sys.version_info < (3, 0):
                nextline = nextline.decode("windows-1252")
            web.app.logger.debug(nextline.strip("\r\n"))
            # parse progress string from calibre-converter
            progress = re.search("(\d+)%\s.*", nextline)
            if progress:
                self.UIqueue[self.current]["progress"] = progress.group(1) + " %"

    # process returncode
    check = p.returncode

    # kindlegen returncodes
    # 0 = Info(prcgen):I1036: Mobi file built successfully
    # 1 = Info(prcgen):I1037: Mobi file built with WARNINGS!
    # 2 = Info(prcgen):I1038: MOBI file could not be generated because of errors!
    if (check < 2 and web.ub.config.config_ebookconverter == 1) or (
        check == 0 and web.ub.config.config_ebookconverter == 2
    ):
        cur_book = (
            web.db.session.query(web.db.Books).filter(web.db.Books.id == bookid).first()
        )
        if os.path.isfile(file_path + format_new_ext):
            new_format = web.db.Data(
                name=cur_book.data[0].name,
                book_format=self.queue[self.current]["settings"]["new_book_format"],
                book=bookid,
                uncompressed_size=os.path.getsize(file_path + format_new_ext),
            )
            cur_book.data.append(new_format)
            web.db.session.commit()
            self.queue[self.current]["path"] = cur_book.path
            self.queue[self.current]["title"] = cur_book.title
            if web.ub.config.config_use_google_drive:
                os.remove(file_path + format_old_ext)
            self._handleSuccess()
            return file_path + format_new_ext
        else:
            error_message = format_new_ext.upper() + " format not found on disk"
    web.app.logger.info("ebook converter failed with error while converting book")
    if not error_message:
        error_message = "Ebook converter failed with unknown error"
    self._handleError(error_message)
    return


# Traceback (OperationalError)
ERROR:cps.web:Exception on /book/125 [GET]
Traceback (most recent call last):
File "/Users/jgillman/Code/calibre-web/vendor/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/Users/jgillman/Code/calibre-web/vendor/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/jgillman/Code/calibre-web/vendor/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/jgillman/Code/calibre-web/vendor/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/jgillman/Code/calibre-web/vendor/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/jgillman/Code/calibre-web/vendor/flask_login.py", line 717, in decorated_view
return func(*args, **kwargs)
File "/Users/jgillman/Code/calibre-web/cps/web.py", line 381, in show_book
return render_template('detail.html', entry=entries,  cc=cc, title=entries.title, books_shelfs=book_in_shelfs)
File "/Users/jgillman/Code/calibre-web/vendor/flask/templating.py", line 128, in render_template
context, ctx.app)
File "/Users/jgillman/Code/calibre-web/vendor/flask/templating.py", line 110, in _render
rv = template.render(context)
File "/Users/jgillman/Code/calibre-web/vendor/jinja2/environment.py", line 969, in render
return self.environment.handle_exception(exc_info, True)
File "/Users/jgillman/Code/calibre-web/vendor/jinja2/environment.py", line 742, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Users/jgillman/Code/calibre-web/cps/templates/detail.html", line 1, in top-level template code
{% extends "layout.html" %}
File "/Users/jgillman/Code/calibre-web/cps/templates/layout.html", line 136, in top-level template code
{% block body %}{% endblock %}
File "/Users/jgillman/Code/calibre-web/cps/templates/detail.html", line 66, in block "body"
{% if entry['custom_column_' ~ c.id]|length > 0 %}
File "/Users/jgillman/Code/calibre-web/vendor/jinja2/environment.py", line 387, in getitem
return getattr(obj, attr)
File "/Users/jgillman/Code/calibre-web/vendor/sqlalchemy/orm/attributes.py", line 316, in __get__
return self.impl.get(instance_state(instance), dict_)
File "/Users/jgillman/Code/calibre-web/vendor/sqlalchemy/orm/attributes.py", line 613, in get
value = self.callable_(state, passive)
File "/Users/jgillman/Code/calibre-web/vendor/sqlalchemy/orm/strategies.py", line 524, in _load_for_state
return self._emit_lazyload(session, state, ident_key, passive)
File "/Users/jgillman/Code/calibre-web/vendor/sqlalchemy/orm/strategies.py", line 585, in _emit_lazyload
result = q.all()
File "/Users/jgillman/Code/calibre-web/vendor/sqlalchemy/orm/query.py", line 2241, in all
return list(self)
File "/Users/jgillman/Code/calibre-web/vendor/sqlalchemy/orm/query.py", line 2353, in __iter__
return self._execute_and_instances(context)
File "/Users/jgillman/Code/calibre-web/vendor/sqlalchemy/orm/query.py", line 2368, in _execute_and_instances
result = conn.execute(querycontext.statement, self._params)
File "/Users/jgillman/Code/calibre-web/vendor/sqlalchemy/engine/base.py", line 662, in execute
params)
File "/Users/jgillman/Code/calibre-web/vendor/sqlalchemy/engine/base.py", line 761, in _execute_clauseelement
compiled_sql, distilled_params
File "/Users/jgillman/Code/calibre-web/vendor/sqlalchemy/engine/base.py", line 874, in _execute_context
context)
File "/Users/jgillman/Code/calibre-web/vendor/sqlalchemy/engine/base.py", line 1024, in _handle_dbapi_exception
exc_info
File "/Users/jgillman/Code/calibre-web/vendor/sqlalchemy/util/compat.py", line 196, in raise_from_cause
reraise(type(exception), exception, tb=exc_tb)
File "/Users/jgillman/Code/calibre-web/vendor/sqlalchemy/engine/base.py", line 867, in _execute_context
context)
File "/Users/jgillman/Code/calibre-web/vendor/sqlalchemy/engine/default.py", line 324, in do_execute
cursor.execute(statement, parameters)
OperationalError: (OperationalError) no such table: books_custom_column_1_link u'SELECT custom_column_1.id AS custom_column_1_id, custom_column_1.value AS custom_column_1_value \
nFROM custom_column_1, books_custom_column_1_link \nWHERE ? = books_custom_column_1_link.book AND custom_column_1.id = books_custom_column_1_link.value' (125,)
ERROR:tornado.access:500 GET /book/125 (::1) 89.60ms

# Fixed code
def _convert_ebook_format(self):
    error_message = None
    file_path = self.queue[self.current]["file_path"]
    bookid = self.queue[self.current]["bookid"]
    format_old_ext = (
        "." + self.queue[self.current]["settings"]["old_book_format"].lower()
    )
    format_new_ext = (
        "." + self.queue[self.current]["settings"]["new_book_format"].lower()
    )

    # check to see if destination format already exists -
    # if it does - mark the conversion task as complete and return a success
    # this will allow send to kindle workflow to continue to work
    if os.path.isfile(file_path + format_new_ext):
        web.app.logger.info(
            "Book id %d already converted to %s", bookid, format_new_ext
        )
        cur_book = (
            web.db.session.query(web.db.Books).filter(web.db.Books.id == bookid).first()
        )
        self.queue[self.current]["path"] = file_path
        self.queue[self.current]["title"] = cur_book.title
        self._handleSuccess()
        return file_path + format_new_ext
    else:
        web.app.logger.info(
            "Book id %d - target format of %s does not exist. Moving forward with convert.",
            bookid,
            format_new_ext,
        )

    # check if converter-executable is existing
    if not os.path.exists(web.ub.config.config_converterpath):
        # ToDo Text is not translated
        self._handleError(
            "Convertertool %s not found" % web.ub.config.config_converterpath
        )
        return

    try:
        # check which converter to use kindlegen is "1"
        if format_old_ext == ".epub" and format_new_ext == ".mobi":
            if web.ub.config.config_ebookconverter == 1:
                if os.name == "nt":
                    command = (
                        web.ub.config.config_converterpath + ' "' + file_path + '.epub"'
                    )
                    if sys.version_info < (3, 0):
                        command = command.encode(sys.getfilesystemencoding())
                else:
                    command = [web.ub.config.config_converterpath, file_path + ".epub"]
                    if sys.version_info < (3, 0):
                        command = [
                            x.encode(sys.getfilesystemencoding()) for x in command
                        ]
        if web.ub.config.config_ebookconverter == 2:
            # Linux py2.7 encode as list without quotes no empty element for parameters
            # linux py3.x no encode and as list without quotes no empty element for parameters
            # windows py2.7 encode as string with quotes empty element for parameters is okay
            # windows py 3.x no encode and as string with quotes empty element for parameters is okay
            # separate handling for windows and linux
            if os.name == "nt":
                command = (
                    web.ub.config.config_converterpath
                    + ' "'
                    + file_path
                    + format_old_ext
                    + '" "'
                    + file_path
                    + format_new_ext
                    + '" '
                    + web.ub.config.config_calibre
                )
                if sys.version_info < (3, 0):
                    command = command.encode(sys.getfilesystemencoding())
            else:
                command = [
                    web.ub.config.config_converterpath,
                    (file_path + format_old_ext),
                    (file_path + format_new_ext),
                ]
                if web.ub.config.config_calibre:
                    parameters = web.ub.config.config_calibre.split(" ")
                    for param in parameters:
                        command.append(param)
                if sys.version_info < (3, 0):
                    command = [x.encode(sys.getfilesystemencoding()) for x in command]

        p = subprocess.Popen(command, stdout=subprocess.PIPE, universal_newlines=True)
    except OSError as e:
        self._handleError(_("Ebook-converter failed: %(error)s", error=e))
        return

    if web.ub.config.config_ebookconverter == 1:
        nextline = p.communicate()[0]
        # Format of error message (kindlegen translates its output texts):
        # Error(prcgen):E23006: Language not recognized in metadata.The dc:Language field is mandatory.Aborting.
        conv_error = re.search(".*\(.*\):(E\d+):\s(.*)", nextline, re.MULTILINE)
        # If error occoures, store error message for logfile
        if conv_error:
            error_message = _(
                "Kindlegen failed with Error %(error)s. Message: %(message)s",
                error=conv_error.group(1),
                message=conv_error.group(2).strip(),
            )
        web.app.logger.debug("convert_kindlegen: " + nextline)
    else:
        while p.poll() is None:
            nextline = p.stdout.readline()
            if os.name == "nt" and sys.version_info < (3, 0):
                nextline = nextline.decode("windows-1252")
            web.app.logger.debug(nextline.strip("\r\n"))
            # parse progress string from calibre-converter
            progress = re.search("(\d+)%\s.*", nextline)
            if progress:
                self.UIqueue[self.current]["progress"] = progress.group(1) + " %"

    # process returncode
    check = p.returncode

    # kindlegen returncodes
    # 0 = Info(prcgen):I1036: Mobi file built successfully
    # 1 = Info(prcgen):I1037: Mobi file built with WARNINGS!
    # 2 = Info(prcgen):I1038: MOBI file could not be generated because of errors!
    if (check < 2 and web.ub.config.config_ebookconverter == 1) or (
        check == 0 and web.ub.config.config_ebookconverter == 2
    ):
        cur_book = (
            web.db.session.query(web.db.Books).filter(web.db.Books.id == bookid).first()
        )
        if os.path.isfile(file_path + format_new_ext):
            new_format = web.db.Data(
                name=cur_book.data[0].name,
                book_format=self.queue[self.current]["settings"][
                    "new_book_format"
                ].upper(),
                book=bookid,
                uncompressed_size=os.path.getsize(file_path + format_new_ext),
            )
            cur_book.data.append(new_format)
            web.db.session.commit()
            self.queue[self.current]["path"] = cur_book.path
            self.queue[self.current]["title"] = cur_book.title
            if web.ub.config.config_use_google_drive:
                os.remove(file_path + format_old_ext)
            self._handleSuccess()
            return file_path + format_new_ext
        else:
            error_message = format_new_ext.upper() + " format not found on disk"
    web.app.logger.info("ebook converter failed with error while converting book")
    if not error_message:
        error_message = "Ebook converter failed with unknown error"
    self._handleError(error_message)
    return