WhakerKit 2.0

https://sourceforge.net/projects/whakerkit/

Module whakerkit.responses

Class DepositResponse

Description

The bake system for the page with documents of an authenticated user.

Declare a global JS "docManager" which is an instance of "DocumentsManager()". Declare a global JS "asideManager which is an instance of "AsideManager()".

Constructor

View Source
def __init__(self, name: str=None):
    super(DepositResponse, self).__init__(name, title=get_msg(MSG_TITLE_TAB))
    self.__doc_manager = WhakerKitDocsManager()

Public functions

create

Create the deposit page.

View Source
def create(self):
    """Create the deposit page.

        """
    WhakerkitAuthResponse.create(self)
    self.set_pagename('depot_perso.html')
    self._htree.head.script(src=whakerkit.sg.whakerexa + 'js/sortatable.js', script_type='application/javascript')
    self._htree.head.link(rel='stylesheet', href=whakerkit.sg.whakerexa + 'css/sortatable.css', link_type='text/css')
    self._htree.head.script(src=whakerkit.sg.path + 'statics/js/documents.js', script_type='module')
    self._htree.head.script(src=whakerkit.sg.path + 'statics/js/doc_details.js', script_type='module')
    new_body_script = HTMLNode(self._htree.get_body_identifier(), 'body_script', 'script', value=BODY_SCRIPT)
    new_body_script.add_attribute('type', 'module')
    self._htree.set_body_script(new_body_script)

get_documents

Return the serialized content with the list of author documents.

Returns
  • (str)
View Source
def get_documents(self) -> str:
    """Return the serialized content with the list of author documents.

        :return: (str)

        """
    logging.info(' ... Get all the documents of the user from its author name')
    author = WhakerKitDocsManager.format_author(self._author)
    docs = self.__doc_manager.filter_docs([('author', 'iexact', [author])])
    div = HTMLNode(None, None, 'div')
    self.__append_all_docs(div, docs)
    return div.serialize()

describe_document

Describe a document in the list of existing ones.

Parameters
  • folder_name: (str) Name of the folder of a specific document
  • description: (str) New description of the document
View Source
def describe_document(self, folder_name: str, description: str):
    """Describe a document in the list of existing ones.

        :param folder_name: (str) Name of the folder of a specific document
        :param description: (str) New description of the document

        """
    logging.info(f' ... Describe document in {folder_name} with description: {description}')
    doc = Document.create_document_by_folder_name(folder_name)
    if doc.author != WhakerKitDocsManager.format_author(self._author):
        raise Exception(get_msg(MSG_NON_AUTHORIZED))
    self.__doc_manager.set_doc_description(doc, description)

delete_document

Delete a document in the list of existing ones.

Parameters
  • folder_name: (str) Name of the folder of a specific document
Returns
  • (bool) True if the file was deleted successfully, False otherwise
View Source
def delete_document(self, folder_name: str=''):
    """Delete a document in the list of existing ones.

        :param folder_name: (str) Name of the folder of a specific document
        :return: (bool) True if the file was deleted successfully, False otherwise

        """
    logging.info(f' ... Delete document in {folder_name}')
    doc = Document.create_document_by_folder_name(folder_name)
    if doc.author != WhakerKitDocsManager.format_author(self._author):
        raise Exception(get_msg(MSG_NON_AUTHORIZED))
    self.__doc_manager.invalidate_doc(doc)

upload_document

Save a given file as a document.

Parameters
  • filename: (str) Filename of the document to be uploaded
  • content: (str) Document content
Returns
  • (bool) True if the document was uploaded, False otherwise
View Source
def upload_document(self, filename: str, content: str | bytes) -> bool:
    """Save a given file as a document.

        :param filename: (str) Filename of the document to be uploaded
        :param content: (str) Document content
        :return: (bool) True if the document was uploaded, False otherwise

        """
    filename = WhakerKitDocsManager.format_filename(filename)
    author = WhakerKitDocsManager.format_author(self._author)
    logging.info(f'Upload document: {filename} from author: {author}')
    document = ImmutableDocument(author=author, filename=filename, content=content)
    self.__doc_manager.add_doc(document)
    return self.__doc_manager.save_doc(document)

Private functions

_process_events

Process the given events coming from the POST of any form.

Parameters
  • events: (dict) the posted events
  • kwargs: (dict) the keyword arguments
Returns
  • (bool) True to bake the page, False otherwise
View Source
def _process_events(self, events: dict, **kwargs) -> bool:
    """Process the given events coming from the POST of any form.

        :param events: (dict) the posted events
        :param kwargs: (dict) the keyword arguments
        :return: (bool) True to bake the page, False otherwise

        """
    self._status.code = 200
    has_auth = WhakerkitAuthResponse._process_events(self, events, **kwargs)
    if has_auth is True:
        if self._status.code == 200:
            self.bake(self._data)
        return True
    logging.debug(f'DepositResponse._process_events: {events.keys()}.')
    token = events.get('token')
    if token is not None:
        WhakerkitAuthResponse.authenticate(self, events.get('token', ''))
    if self._is_authenticated is True:
        self._data['token'] = token
        logging.info(f' ... Authenticated user: {self._author}')
        self.__doc_manager.collect_docs()
        if 'upload_file' in events:
            return self.__upload_callback(events['upload_file'])
        elif events.get('event_name', '') == 'delete_document':
            return self.__delete_callback(events)
        elif events.get('event_name', '') == 'describe_document':
            return self.__describe_callback(events)
        elif events.get('event_name', '') == 'increment_downloads':
            return False
        else:
            self.__no_event_callback()
    return True

_bake

Create the dynamic page content in HTML.

View Source
def _bake(self):
    """Create the dynamic page content in HTML.

        """
    if self._is_authenticated is True:
        self._htree.head.meta({'http-equiv': 'refresh', 'content': '1860'})
    self.__append_title()
    self.__bake_anonymous()
    self.__bake_authenticated()

Protected functions

__no_event_callback

Manage the callback when no event.

Returns
  • (bool) True to bake the page, False otherwise
View Source
def __no_event_callback(self) -> bool:
    """Manage the callback when no event.

        :return: (bool) True to bake the page, False otherwise

        """
    try:
        self._data['content'] = self.get_documents()
        self._status.code = 200
        return True
    except Exception as e:
        logging.error(f'Error while retrieving documents: {e}')
        self._data = {'error': str(e)}
        self._status.code = 400
        return False

__upload_callback

Manage the callback for the upload_file event.

The given event is a dictionary like for example: {'filename': 'robots.txt', 'mimetype': 'text/plain', 'filecontent': 'User-agent: * '}}

Parameters
  • upload_event: (dict) the upload event
Returns
  • (bool) True to bake the page, False otherwise
View Source
def __upload_callback(self, upload_event: dict) -> bool:
    """Manage the callback for the upload_file event.

        The given event is a dictionary like for example:
        {'filename': 'robots.txt', 'mime_type': 'text/plain', 'file_content': 'User-agent: *
'}}

        :param upload_event: (dict) the upload event
        :return: (bool) True to bake the page, False otherwise

        """
    content = upload_event.get('file_content', '')
    filename = upload_event.get('filename', '')
    logging.debug(' -- DepositResponse.__upload_callback filename: %s', filename)
    logging.debug(' -- DepositResponse.__upload_callback content length: %s', len(content))
    if len(content) == 0:
        self._status.code = 422
        self._data = {'error': get_msg(MSG_EMPTY_FILE)}
        logging.error(f'File {filename} is empty.')
    else:
        try:
            self.upload_document(filename, content)
            logging.info(f'File {filename} saved successfully.')
            self._status.code = 200
            return True
        except Exception as e:
            self._status.code = 400
            logging.error(f'Error while saving file {filename}: {e}')
            self._data = {'error': get_msg(MSG_UPLOAD_FAILED) + ' ' + str(e)}
    return False

__describe_callback

Manage the callback for the describe_document event.

Parameters
  • describe_event: (dict) the descript event
Returns
  • (bool) True to bake the page, False otherwise
View Source
def __describe_callback(self, describe_event: dict) -> bool:
    """Manage the callback for the describe_document event.

        :param describe_event: (dict) the descript event
        :return: (bool) True to bake the page, False otherwise

        """
    folder_name = describe_event.get('folder_name', '')
    description = describe_event.get('description', '')
    self._status.code = 401
    description = WhakerKitDocsManager.format_description(description)
    if len(description) == 0:
        self._data = {'error': get_msg(MSG_NO_DESCRIPTION)}
    else:
        try:
            self.describe_document(folder_name, description)
            self._status.code = 200
            return True
        except Exception as e:
            logging.error(f'Error while saving description: {e}')
            self._data = {'error': get_msg(MSG_SERVER_ERROR) + ' ' + str(e)}
    return False

__delete_callback

Manage the callback for the delete_document event.

Parameters
  • delete_event: (dict) the descript event
Returns
  • (bool) True to bake the page, False otherwise
View Source
def __delete_callback(self, delete_event: dict) -> bool:
    """Manage the callback for the delete_document event.

        :param delete_event: (dict) the descript event
        :return: (bool) True to bake the page, False otherwise

        """
    folder_name = delete_event.get('folder_name', '')
    self._status.code = 401
    try:
        self.delete_document(folder_name)
        self._status.code = 200
        return True
    except Exception as e:
        logging.error(f'Error while saving description: {e}')
        self._data = {'error': get_msg(MSG_SERVER_ERROR) + ' ' + str(e)}
    return False

__bake_anonymous

Add dynamic body->main content for an un-authenticated user.

View Source
def __bake_anonymous(self):
    """Add dynamic body->main content for an un-authenticated user.

        """
    section = self._htree.element('section')
    section.add_attribute('id', 'anonymous_section')
    me = HTMLNode(section.identifier, None, 'p', value=get_msg(MSG_NOT_AUTH))
    section.append_child(me)
    login_node = WhakerKitLoginNode(section.identifier)
    section.append_child(login_node)
    if logging.getLogger().getEffectiveLevel() > 1:
        action = "DialogManager.open('" + login_node.identifier + "', true)"
    else:
        action = "authManager.submitLogin('anonymous', '********');"
    btn = create_action_button(section.identifier, action, get_msg(MSG_LOGIN), whakerkit.sg.path + 'statics/icons/authentication.png')
    section.append_child(btn)

__bake_authenticated

Add dynamic body->main for an authenticated user.

View Source
def __bake_authenticated(self):
    """Add dynamic body->main for an authenticated user.

        """
    section = self._htree.element('section')
    section.add_attribute('id', 'authenticated_section')
    me = HTMLNode(section.identifier, None, 'p', value=get_msg(MSG_CONNECTED))
    section.append_child(me)
    token = self._data.get('token', '')
    if token is not None:
        action = "authManager.submitLogout('" + self._data.get('token', '') + "');"
    else:
        action = ''
    btn = create_action_button(section.identifier, action, get_msg(MSG_LOGOUT), whakerkit.sg.path + 'statics/icons/log-out.png')
    btn.add_attribute('type', 'submit')
    if token is None:
        btn.add_attribute('disabled', None)
    section.append_child(btn)
    stitle = HTMLNode(section.identifier, None, 'h2', value=get_msg(MSG_UPLOAD_DOC))
    section.append_child(stitle)
    ssection = HTMLNode(section.identifier, None, 'section')
    ssection.add_attribute('class', 'flex-panel')
    section.append_child(ssection)
    left = HTMLNode(ssection.identifier, None, 'article')
    left.add_attribute('class', 'flex-item width_60')
    ssection.append_child(left)
    self.__append_file_sending(left)
    right = HTMLNode(ssection.identifier, None, 'dialog', value=get_msg(MSG_FILENAME_RECOMMANDATION))
    right.add_attribute('class', 'flex-item width_40 tips')
    right.add_attribute('role', 'alertdialog')
    ssection.append_child(right)
    subsection = HTMLNode(section.identifier, None, 'section')
    subsection.set_attribute('id', 'authenticated_content')
    section.append_child(subsection)

__append_title

Append the title.

View Source
def __append_title(self):
    """Append the title."""
    h1 = self._htree.element('h1')
    h1.set_value(get_msg(MSG_TITLE_DEPOSIT))
    dlg = self._htree.element('dialog')
    dlg.add_attribute('id', 'error_dialog')
    dlg.add_attribute('role', 'alertdialog')
    dlg.add_attribute('class', 'error hidden-alert')
    dlg = self._htree.element('dialog')
    dlg.add_attribute('id', 'wait_dialog')
    dlg.add_attribute('role', 'alertdialog')
    dlg.add_attribute('class', 'info hidden-alert')
    dlg.set_value(get_msg(MSG_PLEASE_WAIT))

__append_file_sending

Append a section to send a new document.

Parameters
  • parent
View Source
def __append_file_sending(self, parent: HTMLNode):
    """Append a section to send a new document.

        """
    fn_info = HTMLNode(parent.identifier, None, 'p', value='<br>' + get_msg(MSG_FILENAME_INFO))
    parent.append_child(fn_info)
    input_file = HTMLNode(parent.identifier, None, 'input', attributes={'id': 'file_input', 'type': 'file', 'name': 'file_input'})
    parent.append_child(input_file)
    btn = create_action_button(parent.identifier, 'docManager.sendDocument();', get_msg(MSG_SEND_FILE), whakerkit.sg.path + 'statics/icons/upload.png')
    btn.add_attribute('type', 'submit')
    parent.append_child(btn)

__append_all_docs

Append the table with all documents to the body->main.

It's a table element with all documents of the authenticated author.

Parameters
  • parent
  • documents
View Source
def __append_all_docs(self, parent: HTMLNode, documents: list):
    """Append the table with all documents to the body->main.

        It's a table element with all documents of the authenticated author.

        """
    stitle = HTMLNode(parent.identifier, None, 'h2', value=get_msg(MSG_MANAGE_DOC).format(author=self._author))
    parent.append_child(stitle)
    if documents is not None:
        dm = WhakerKitDocsManager()
        if len(documents) == 0:
            no = HTMLNode(parent.identifier, None, 'p', value=get_msg(MSG_NO_DOCS))
            parent.append_child(no)
            file_node = DocumentsNode(parent.identifier, dm, self._author)
        else:
            no = HTMLNode(parent.identifier, None, 'p', value=get_msg(MSG_NB_DOCS).format(nb_docs=len(documents)))
            parent.append_child(no)
            descr_dlg = HTMLNode(parent.identifier, 'description_dialog', 'dialog', attributes={'id': 'description_dialog'})
            descr_dlg.set_value(f'\n                    <form method="dialog">\n                        <p>{get_msg(MSG_NEW_DESCR)}<br><i><span id="folder_name_span"></span></i></p>\n                        <textarea id="new_description_field" rows="3" cols="55" maxlength="160"\n                                  onkeyup="docManager.currentDescriptionLength();"\n                        ></textarea>\n                        <p><small><span id="new_description_span">--</span>{get_msg(MSG_MAX_LEN_DESCR)}</small></p>\n                        <menu>\n                            <button id="confirm" type="submit">{get_msg(MSG_VALIDATE)}</button>\n                        </menu>\n                    </form>\n                    ')
            parent.append_child(descr_dlg)
            aside = WhakerKitDocAsideNode(parent.identifier)
            parent.append_child(aside)
            dm.add_docs(documents)
            file_node = DocumentsNode(parent.identifier, dm, self._author)
        parent.append_child(file_node)