Source code for journal_manager.core.api

"""
Core methods that form the journal-manager api. 
"""

from danoan.journal_manager.core import exceptions, model

import os
from pathlib import Path
from typing import List, Optional

ENV_JOURNAL_MANAGER_CONFIG_FOLDER = "JOURNAL_MANAGER_CONFIG_FOLDER"


# -------------------- Configuration API --------------------


[docs]def get_configuration_folder() -> Path: """ Return the value stored by environment variable JOURNAL_MANAGER_CONFIG_FOLDER Raises: ConfigurationFolderDoesNotExist: if JOURNAL_MANAGER_CONFIG_FOLDER is not set. """ if ENV_JOURNAL_MANAGER_CONFIG_FOLDER not in os.environ: raise exceptions.ConfigurationFolderDoesNotExist() return Path(os.environ[ENV_JOURNAL_MANAGER_CONFIG_FOLDER]).expanduser()
[docs]def get_configuration_filepath(): """ Return the path to the journal-manager configuration file. """ return get_configuration_folder().joinpath("config.toml")
[docs]def get_configuration_file() -> model.ConfigurationFile: """ Return ConfigurationFile dataclass instantiated from the configuration file. Raises: ConfigurationFileDoesNotExist: if configuration file does not exist. """ if not get_configuration_filepath().exists(): raise exceptions.ConfigurationFileDoesNotExist() return model.ConfigurationFile.read(get_configuration_filepath())
[docs]def get_template_list_file() -> model.JournalTemplateList: """ Return JournalTemplateList dataclass instantiated from the templates register file. """ config_file = get_configuration_file() return model.JournalTemplateList.read(config_file.template_data_filepath)
[docs]def get_journal_data_file() -> model.JournalDataList: """ Return JournalDataList dataclass instantiated from the journals register file. """ config_file = get_configuration_file() return model.JournalDataList.read(config_file.journal_data_filepath)
[docs]def create_configuration_file( journal_folder_default: Path, templates_folder_default: Path ): """ Create journal-manager application configuration file. Additionally, it creates two more configuration files: - journal_data.toml - template_data.toml and a folder to store journal templates. Args: journal_folder_default: Default location to store journals. templates_folder_default: Default location to store journal templates. text_editor_default: Path to the default editor used by journal-manager. """ get_configuration_folder().mkdir(parents=True) journal_folder_default.mkdir(parents=True) templates_folder_default.mkdir(parents=True) journal_data_filepath = ( Path.expanduser(get_configuration_folder()) .joinpath("journal_data.toml") .as_posix() ) journal_template_data_filepath = ( Path.expanduser(get_configuration_folder()) .joinpath("template_data.toml") .as_posix() ) parameters = model.Parameters() with open(get_configuration_filepath().as_posix(), "w") as f: model.ConfigurationFile( journal_folder_default.as_posix(), templates_folder_default.as_posix(), journal_data_filepath, journal_template_data_filepath, parameters, ).write(f) with open(journal_data_filepath, "w") as f: model.JournalDataList([]).write(f) with open(journal_template_data_filepath, "w") as f: model.JournalTemplateList([]).write(f)
[docs]def is_valid_template_path(template_path: Path): """ Validates a journal templates folder. The journal template folder must contain the file mkdocs.tpl.yml. Args: template_path: The journal template folder to check. """ mkdocs_template_path = Path(template_path).joinpath("mkdocs.tpl.yml") return mkdocs_template_path.exists()
# -------------------- Data Model Query API --------------------
[docs]def find_template_by_name( template_file: model.JournalTemplateList, template_name: str ) -> Optional[model.JournalTemplate]: """ Search a registered template by name. If the template is not found, a None object is returned. Args: template_file: Dataclass representation of the journal template register file. template_name: Template name. """ for entry in template_file.list_of_template_data: if entry.name == template_name: return entry return None
[docs]def find_journal( journal_data_file: model.JournalDataList, journal_components: model.JournalData, logic_operator: model.LogicOperator, ) -> List[model.JournalData]: """ Search among the registered journals all entries that matches the query. The `journal_components` is an instance of JournalData. Attributes with a None value are not considered in the search. Args: journal_data_file: Dataclass representation of the journal register file. journal_components: Journal attributes being searched. logic_operator: If OR, all journals matching at least one attribute are returned. If AND, a journal must match all attributes to be returned. """ results: List[model.JournalData] = [] for journal_data in journal_data_file.list_of_journal_data: potential_matches = 0 concrete_matches = 0 for key, value in journal_components.__dict__.items(): if value is None: continue potential_matches += 1 if journal_data.__dict__[key] == value: concrete_matches += 1 if logic_operator == model.LogicOperator.OR: if concrete_matches > 0: results.append(journal_data) elif logic_operator == model.LogicOperator.AND: if concrete_matches == potential_matches: results.append(journal_data) return results
[docs]def find_journal_by_name( journal_data_file: model.JournalDataList, journal_name: str ) -> Optional[model.JournalData]: """ Search a registered journal by name. If the journal is not found, a None object is returned. Args: journal_data_file: Dataclass representation of the journal register file. journal_name: Journal name. """ journal_components = model.JournalData(journal_name, None, None, None, None) results = find_journal( journal_data_file, journal_components, model.LogicOperator.AND ) if len(results) > 0: return results[0] else: return None
[docs]def find_journal_by_location( journal_data_file: model.JournalDataList, journal_location: str ) -> Optional[model.JournalData]: """ Search a registered journal by location. If the journal is not found, a None object is returned. Args: journal_data_file: Dataclass representation of the journal register file. journal_location: Path to the journal folder. """ journal_components = model.JournalData( None, journal_location, None, None, None ) results = find_journal( journal_data_file, journal_components, model.LogicOperator.AND ) if len(results) > 0: return results[0] else: return None
[docs]def update_journal( journal_data_file: model.JournalDataList, journal_data: model.JournalData ): """ Update journal entry in the journal data file. Args: journal_data_file: Dataclass representation of the journal register file. journal_data: Updated journal. """ for i, entry in enumerate(journal_data_file.list_of_journal_data): if entry.name == journal_data.name: journal_data_file.list_of_journal_data[i] = journal_data break with open(get_configuration_file().journal_data_filepath, "w") as f: journal_data_file.write(f)