Add a comment/review or remark
    :param recID: record id
    :param uid: user id
    :param action:  'DISPLAY' to display add form
                    'SUBMIT' to submit comment once form is filled
                    'REPLY' to reply to an existing comment
    :param ln: language
    :param msg: the body of the comment/review or remark
    :param score: star score of the review
    :param note: title of the review
    :param priority: priority of remark (int)
    :param reviews: boolean, if enabled will add a review, if disabled will add a comment
    :param comID: if replying, this is the comment id of the comment we are replying to
    :param editor_type: the kind of editor/input used for the comment: 'textarea', 'ckeditor'
    :param can_attach_files: if user can attach files to comments or not
    :param subscribe: if True, subscribe user to receive new comments by email
    :param req: request object. Used to register callback to send email notification
    :param attached_files: newly attached files to this comment, mapping filename to filepath
    :type attached_files: dict
    :param warnings: list of warning tuples (warning_text, warning_color) that should be considered
    :return:
             - html add form if action is display or reply
             - html successful added form if action is submit

def perform_request_add_comment_or_remark(recID=0,
                                          uid=-1,
                                          action='DISPLAY',
                                          ln=CFG_SITE_LANG,
                                          msg=None,
                                          score=None,
                                          note=None,
                                          priority=None,
                                          reviews=0,
                                          comID=0,
                                          client_ip_address=None,
                                          editor_type='textarea',
                                          can_attach_files=False,
                                          subscribe=False,
                                          req=None,
                                          attached_files=None,
                                          warnings=None):
    """
    Add a comment/review or remark
    :param recID: record id
    :param uid: user id
    :param action:  'DISPLAY' to display add form
                    'SUBMIT' to submit comment once form is filled
                    'REPLY' to reply to an existing comment
    :param ln: language
    :param msg: the body of the comment/review or remark
    :param score: star score of the review
    :param note: title of the review
    :param priority: priority of remark (int)
    :param reviews: boolean, if enabled will add a review, if disabled will add a comment
    :param comID: if replying, this is the comment id of the comment we are replying to
    :param editor_type: the kind of editor/input used for the comment: 'textarea', 'ckeditor'
    :param can_attach_files: if user can attach files to comments or not
    :param subscribe: if True, subscribe user to receive new comments by email
    :param req: request object. Used to register callback to send email notification
    :param attached_files: newly attached files to this comment, mapping filename to filepath
    :type attached_files: dict
    :param warnings: list of warning tuples (warning_text, warning_color) that should be considered
    :return:
             - html add form if action is display or reply
             - html successful added form if action is submit
    """
    _ = gettext_set_language(ln)
    if warnings is None:
        warnings = []

    _ = gettext_set_language(ln)

    # check arguments
    check_recID_is_in_range(recID, warnings, ln)
    if uid <= 0:
        try:
            raise InvenioWebCommentError(
                _('%(uid)s is an invalid user ID.', uid=uid))
        except InvenioWebCommentError as exc:
            register_exception()
            body = webcomment_templates.tmpl_error(exc.message, ln)
            return body
        #errors.append(('ERR_WEBCOMMENT_UID_INVALID', uid))
        return ''

    if attached_files is None:
        attached_files = {}

    user_contact_info = query_get_user_contact_info(uid)
    nickname = ''
    if user_contact_info:
        if user_contact_info[0]:
            nickname = user_contact_info[0]
    # show the form
    if action == 'DISPLAY':
        if reviews and CFG_WEBCOMMENT_ALLOW_REVIEWS:
            return webcomment_templates.tmpl_add_comment_form_with_ranking(
                recID,
                uid,
                nickname,
                ln,
                msg,
                score,
                note,
                warnings,
                can_attach_files=can_attach_files)
        elif not reviews and CFG_WEBCOMMENT_ALLOW_COMMENTS:
            return webcomment_templates.tmpl_add_comment_form(
                recID,
                uid,
                nickname,
                ln,
                msg,
                warnings,
                can_attach_files=can_attach_files)
        else:
            try:
                raise InvenioWebCommentError(
                    _('Comments on records have been disallowed by the administrator.'))
            except InvenioWebCommentError as exc:
                register_exception(req=req)
                body = webcomment_templates.tmpl_error(exc.message, ln)
                return body
            # errors.append(('ERR_WEBCOMMENT_COMMENTS_NOT_ALLOWED',))

    elif action == 'REPLY':
        if reviews and CFG_WEBCOMMENT_ALLOW_REVIEWS:
            try:
                raise InvenioWebCommentError(_('Cannot reply to a review.'))
            except InvenioWebCommentError as exc:
                register_exception(req=req)
                body = webcomment_templates.tmpl_error(exc.message, ln)
                return body
            # errors.append(('ERR_WEBCOMMENT_REPLY_REVIEW',))
            return webcomment_templates.tmpl_add_comment_form_with_ranking(
                recID,
                uid,
                nickname,
                ln,
                msg,
                score,
                note,
                warnings,
                can_attach_files=can_attach_files)
        elif not reviews and CFG_WEBCOMMENT_ALLOW_COMMENTS:
            textual_msg = msg
            if comID > 0:
                comment = query_get_comment(comID)
                if comment:
                    user_info = UserInfo(comment[2])
                    if user_info:
                        date_creation = convert_datetext_to_dategui(
                            str(comment[4]))
                        # Build two msg: one mostly textual, the other one with
                        # HTML markup, for the CkEditor.
                        msg = _("%(x_name)s wrote on %(x_date)s:") % {
                            'x_name': user_info[2],
                            'x_date': date_creation}
                        textual_msg = msg
                        # 1 For CkEditor input
                        msg += '\n\n'
                        msg += comment[3]
                        msg = email_quote_txt(text=msg)
                        # Now that we have a text-quoted version, transform into
                        # something that CkEditor likes, using <blockquote> that
                        # do still enable users to insert comments inline
                        msg = email_quoted_txt2html(
                            text=msg,
                            indent_html=(
                                '<blockquote><div>',
                                '&nbsp;&nbsp;</div></blockquote>'),
                            linebreak_html="&nbsp;<br/>",
                            indent_block=False)
                        # Add some space for users to easily add text
                        # around the quoted message
                        msg = '<br/>' + msg + '<br/>'
                        # Due to how things are done, we need to
                        # escape the whole msg again for the editor
                        msg = cgi.escape(msg)

                        # 2 For textarea input
                        textual_msg += "\n\n"
                        textual_msg += comment[3]
                        textual_msg = email_quote_txt(text=textual_msg)
            return webcomment_templates.tmpl_add_comment_form(
                recID,
                uid,
                nickname,
                ln,
                msg,
                warnings,
                textual_msg,
                can_attach_files=can_attach_files,
                reply_to=comID)
        else:
            try:
                raise InvenioWebCommentError(
                    _('Comments on records have been disallowed by the administrator.'))
            except InvenioWebCommentError as exc:
                register_exception(req=req)
                body = webcomment_templates.tmpl_error(exc.message, ln)
                return body
            # errors.append(('ERR_WEBCOMMENT_COMMENTS_NOT_ALLOWED',))

    # check before submitting form
    elif action == 'SUBMIT':
        if reviews and CFG_WEBCOMMENT_ALLOW_REVIEWS:
            if note.strip() in [
                    "", "None"] and not CFG_WEBCOMMENT_ALLOW_SHORT_REVIEWS:
                try:
                    raise InvenioWebCommentWarning(
                        _('You must enter a title.'))
                except InvenioWebCommentWarning as exc:
                    register_exception(stream='warning', req=req)
                    warnings.append((exc.message, ''))
                # warnings.append(('WRN_WEBCOMMENT_ADD_NO_TITLE',))
            if score == 0 or score > 5:
                try:
                    raise InvenioWebCommentWarning(
                        _('You must choose a score.'))
                except InvenioWebCommentWarning as exc:
                    register_exception(stream='warning', req=req)
                    warnings.append((exc.message, ''))
                # warnings.append(("WRN_WEBCOMMENT_ADD_NO_SCORE",))
        if msg.strip() in [
                "", "None"] and not CFG_WEBCOMMENT_ALLOW_SHORT_REVIEWS:
            try:
                raise InvenioWebCommentWarning(_('You must enter a text.'))
            except InvenioWebCommentWarning as exc:
                register_exception(stream='warning', req=req)
                warnings.append((exc.message, ''))
            # warnings.append(('WRN_WEBCOMMENT_ADD_NO_BODY',))
        # if no warnings, submit
        if len(warnings) == 0:
            if reviews:
                if check_user_can_review(recID, client_ip_address, uid):
                    success = query_add_comment_or_remark(
                        reviews,
                        recID=recID,
                        uid=uid,
                        msg=msg,
                        note=note,
                        score=score,
                        priority=0,
                        client_ip_address=client_ip_address,
                        editor_type=editor_type,
                        req=req,
                        reply_to=comID)
                else:
                    try:
                        raise InvenioWebCommentWarning(
                            _('You already wrote a review for this record.'))
                    except InvenioWebCommentWarning as exc:
                        register_exception(stream='warning', req=req)
                        warnings.append((exc.message, ''))
                    # warnings.append('WRN_WEBCOMMENT_CANNOT_REVIEW_TWICE')
                    success = 1
            else:
                if check_user_can_comment(recID, client_ip_address, uid):
                    success = query_add_comment_or_remark(
                        reviews,
                        recID=recID,
                        uid=uid,
                        msg=msg,
                        note=note,
                        score=score,
                        priority=0,
                        client_ip_address=client_ip_address,
                        editor_type=editor_type,
                        req=req,
                        reply_to=comID,
                        attached_files=attached_files)
                    if success > 0 and subscribe:
                        subscribe_user_to_discussion(recID, uid)
                else:
                    try:
                        raise InvenioWebCommentWarning(
                            _('You already posted a comment short ago. Please retry later.'))
                    except InvenioWebCommentWarning as exc:
                        register_exception(stream='warning', req=req)
                        warnings.append((exc.message, ''))
                    # warnings.append('WRN_WEBCOMMENT_TIMELIMIT')
                    success = 1
            if success > 0:
                if CFG_WEBCOMMENT_ADMIN_NOTIFICATION_LEVEL > 0:
                    notify_admin_of_new_comment(comID=success)
                return webcomment_templates.tmpl_add_comment_successful(
                    recID, ln, reviews, warnings, success)
            else:
                try:
                    raise InvenioWebCommentError(
                        _('Failed to insert your comment to the database. Please try again.'))
                except InvenioWebCommentError as exc:
                    register_exception(req=req)
                    body = webcomment_templates.tmpl_error(exc.message, ln)
                    return body
                # errors.append(('ERR_WEBCOMMENT_DB_INSERT_ERROR'))
        # if are warnings or if inserting comment failed, show user where
        # warnings are
        if reviews and CFG_WEBCOMMENT_ALLOW_REVIEWS:
            return webcomment_templates.tmpl_add_comment_form_with_ranking(
                recID,
                uid,
                nickname,
                ln,
                msg,
                score,
                note,
                warnings,
                can_attach_files=can_attach_files)
        else:
            return webcomment_templates.tmpl_add_comment_form(
                recID,
                uid,
                nickname,
                ln,
                msg,
                warnings,
                can_attach_files=can_attach_files)
    # unknown action send to display
    else:
        try:
            raise InvenioWebCommentWarning(
                _('Unknown action --> showing you the default add comment form.'))
        except InvenioWebCommentWarning as exc:
            register_exception(stream='warning', req=req)
            warnings.append((exc.message, ''))
        # warnings.append(('WRN_WEBCOMMENT_ADD_UNKNOWN_ACTION',))
        if reviews and CFG_WEBCOMMENT_ALLOW_REVIEWS:
            return webcomment_templates.tmpl_add_comment_form_with_ranking(
                recID,
                uid,
                ln,
                msg,
                score,
                note,
                warnings,
                can_attach_files=can_attach_files)
        else:
            return webcomment_templates.tmpl_add_comment_form(
                recID,
                uid,
                ln,
                msg,
                warnings,
                can_attach_files=can_attach_files)

    return ''