Skip to content

Commit

Permalink
Shg/logs (#172)
Browse files Browse the repository at this point in the history
* refactor code to pass logger as argument instead of importing the logger in every module

* refactor tests to work with new logger setup

* flake8

* update changelog and version number
  • Loading branch information
sHermanGriffiths authored Mar 20, 2024
1 parent 987381e commit fde1673
Show file tree
Hide file tree
Showing 23 changed files with 175 additions and 197 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,10 @@ Here are some features we're planning to add in the future:

## Changelog

### v0.10.0
- Instead of importing the logger from the `n2y.logger` module, pass it as an argument wherever
necessary to allow custom loggers to be used.

### v0.9.1
- Delete print statement in `rich_text.py`

Expand Down
29 changes: 16 additions & 13 deletions n2y/audit.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import argparse
import logging
import os
import sys
import logging
import argparse

from n2y.logger import logger, HANDLER
from n2y.notion import Client
from n2y.page import Page
from n2y.blocks import LinkToPageBlock
from n2y.database import Database
from n2y.mentions import PageMention
from n2y.errors import UseNextClass
from n2y.blocks import LinkToPageBlock
from n2y.logger import HANDLER
from n2y.logger import logger as log
from n2y.mentions import PageMention
from n2y.notion import Client
from n2y.page import Page
from n2y.utils import id_from_share_link


plugin_key = "audit"


Expand Down Expand Up @@ -49,10 +49,11 @@ def __init__(self, client, notion_data, page, get_children=True):
def cli_main():
args = sys.argv[1:]
access_token = os.environ.get("NOTION_ACCESS_TOKEN", None)

sys.exit(main(args, access_token))


def main(raw_args, access_token):
def main(raw_args, access_token, logger=log):
parser = argparse.ArgumentParser(
description="Audit a set of Notion pages for external links",
formatter_class=argparse.RawTextHelpFormatter,
Expand Down Expand Up @@ -99,7 +100,7 @@ def main(raw_args, access_token):
},
}

client = Client(access_token)
client = Client(access_token, logger=logger)
client.load_plugin(plugins)

node = client.get_page_or_database(object_id)
Expand All @@ -109,7 +110,7 @@ def main(raw_args, access_token):
"Unable to find database or page with id %s. "
"Perhaps its not shared with the integration?"
)
logger.error(msg, object_id)
client.logger.error(msg, object_id)
return 2

references = {}
Expand Down Expand Up @@ -148,13 +149,15 @@ def audit_node(node, references, depth):


def audit_database(database, references, depth):
logger.info("%sDatabase %s", " " * depth, database.title.to_plain_text())
database.client.logger.info(
"%sDatabase %s", " " * depth, database.title.to_plain_text()
)
for page in database.children:
audit_page(page, references, depth + 1)


def audit_page(page, references, depth):
logger.info("%sAuditing %s", " " * depth, page.title.to_plain_text())
page.client.logger.info("%sAuditing %s", " " * depth, page.title.to_plain_text())
assert page.notion_id not in references # expect that each page is visited once
page.block # load all of the blocks
references[page.notion_id] = page.plugin_data.get(plugin_key, [])
Expand Down
25 changes: 13 additions & 12 deletions n2y/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
TableHead,
)

from n2y.logger import logger
from n2y.notion_mocks import mock_block, mock_rich_text_array
from n2y.utils import header_id_from_text, pandoc_write_or_log_errors, yaml_map_to_meta

Expand All @@ -60,7 +59,7 @@ def __init__(self, client, notion_data, page=None, get_children=True):
2. In some cases a block may choose not to get child blocks.
Currently, all blocks load all children.
"""
logger.debug('Instantiating "%s" block', type(self).__name__)
client.logger.debug('Instantiating "%s" block', type(self).__name__)
self.client = client
self.page = page

Expand Down Expand Up @@ -235,7 +234,7 @@ def get_children(self):
if header[0] > base:
subsections[index].append(header)
if header[0] < base:
logger.warning(
self.client.logger.warning(
f'Skipping out-of-order header "{header[1][0]}" in table of'
" contents for page named"
f" {self.page.title.to_plain_text()} ({self.page.notion_url})."
Expand Down Expand Up @@ -268,9 +267,7 @@ def to_pandoc(self):
def generate_item_block(self, section: list[Header]):
header = section.pop(0)
header_text = pandoc_write_or_log_errors(
header[2],
format="gfm",
options=[],
header[2], "gfm", [], self.client.logger
)[:-1]
rich_text = mock_rich_text_array([(header_text, None, f"#{header[1][0]}")])
type_data = {
Expand Down Expand Up @@ -304,7 +301,7 @@ def get_children(self):
try:
subsections[index].append(header)
except IndexError:
logger.warning(
self.client.logger.warning(
f'Skipping out-of-order header "{header[1][0]}" in table of'
" contents for page named"
f" {self.page.title.to_plain_text()} ({self.page.notion_url})."
Expand Down Expand Up @@ -553,7 +550,7 @@ def to_pandoc(self):
if pandoc_language not in self.pandoc_highlight_languages:
if pandoc_language != "plain text":
msg = 'Dropping syntax highlighting for unsupported language "%s" (%s)'
logger.warning(msg, pandoc_language, self.notion_url)
self.client.logger.warning(msg, pandoc_language, self.notion_url)
language = []
else:
language = [pandoc_language]
Expand Down Expand Up @@ -761,7 +758,7 @@ class TemplateBlock(NoopBlock):

class WarningBlock(NoopBlock):
def to_pandoc(self):
logger.warning(
self.client.logger.warning(
'Skipping unsupported "%s" block (%s)', self.notion_type, self.notion_url
)
return None
Expand Down Expand Up @@ -871,10 +868,14 @@ def _get_synced_block_children(self):

def to_pandoc(self):
if not self.shared:
# logger.warning('Skipping un-shared synced block (%s)', self.notion_url)
self.client.logger.warning(
"Skipping un-shared synced block (%s)", self.notion_url
)
return None
elif self.is_recursive:
logger.warning("Skipping recursive synced block (%s)", self.notion_url)
self.client.logger.warning(
"Skipping recursive synced block (%s)", self.notion_url
)
return None
return self.children_to_pandoc()

Expand All @@ -900,7 +901,7 @@ def to_pandoc(self):

if node is None:
msg = "Permission denied when attempting to access linked node (%r)"
logger.warning(msg, self.notion_url)
self.client.logger.warning(msg, self.notion_url)
return None
else:
title = node.title.to_pandoc()
Expand Down
4 changes: 0 additions & 4 deletions n2y/comment.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import logging

from n2y.utils import fromisoformat

logger = logging.getLogger(__name__)


class Comment:
"""
Expand Down
31 changes: 13 additions & 18 deletions n2y/config.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
import logging
import copy
import string

import yaml

from n2y.utils import strip_hyphens


logger = logging.getLogger(__name__)


DEFAULTS = {
"media_root": "media",
"media_url": "./media/",
Expand Down Expand Up @@ -41,8 +36,8 @@
}


def load_config(path):
config = _load_config_from_yaml(path)
def load_config(path, logger):
config = _load_config_from_yaml(path, logger)
if config is None:
return None

Expand All @@ -57,7 +52,7 @@ def load_config(path):
return config


def _load_config_from_yaml(path):
def _load_config_from_yaml(path, logger):
try:
with open(path, "r") as config_file:
config = yaml.safe_load(config_file)
Expand All @@ -67,7 +62,7 @@ def _load_config_from_yaml(path):
except FileNotFoundError:
logger.error("The config file '%s' does not exist", path)
return None
if not validate_config(config):
if not validate_config(config, logger):
logger.error("Invalid config file: %s", path)
return None
return config
Expand Down Expand Up @@ -98,15 +93,15 @@ def merge_default_config(defaults):
return {**master_defaults_copy, **defaults_copy}


def validate_config(config):
def validate_config(config, logger):
if "exports" not in config:
logger.error("Config missing the 'exports' key")
return False
if not isinstance(config["exports"], list) and len(config["exports"]) > 0:
logger.error("Config 'exports' key must be a non-empty list")
return False
for export in config["exports"]:
if not _validate_config_item(export):
if not _validate_config_item(export, logger):
return False
# TODO: validate the export defaults key
return True
Expand All @@ -117,7 +112,7 @@ def valid_notion_id(notion_id):
return len(canonical_id) == 32 and canonical_id.isalnum()


def _validate_config_item(config_item):
def _validate_config_item(config_item, logger):
if "id" not in config_item:
logger.error("Export config item missing the 'id' key")
return False
Expand All @@ -136,23 +131,23 @@ def _validate_config_item(config_item):
)
return False
if "filename_template" in config_item:
if not _valid_filename_template(config_item["filename_template"]):
if not _valid_filename_template(config_item["filename_template"], logger):
return False
if "output" not in config_item:
logger.error("Export config item missing the 'output' key")
return False
if "notion_filter" in config_item:
if not _valid_notion_filter(config_item["notion_filter"]):
if not _valid_notion_filter(config_item["notion_filter"], logger):
return False
if "notion_sorts" in config_item:
if not _valid_notion_sort(config_item["notion_sorts"]):
if not _valid_notion_sort(config_item["notion_sorts"], logger):
return False
# TODO: validate pandoc_format using the `--list-output-types` and `--list-extensions`
# TODO: property map
return True


def _valid_filename_template(filename_template):
def _valid_filename_template(filename_template, logger):
if not isinstance(filename_template, str):
logger.error("filename_template must be a string")
return False
Expand All @@ -172,15 +167,15 @@ def _valid_filename_template(filename_template):
return True


def _valid_notion_filter(notion_filter):
def _valid_notion_filter(notion_filter, logger):
if not (isinstance(notion_filter, list) or isinstance(notion_filter, dict)):
logger.error("notion_filter must be a list or dict")
return False
# TODO validate keys and values
return True


def _valid_notion_sort(notion_sorts):
def _valid_notion_sort(notion_sorts, logger):
if not (isinstance(notion_sorts, list) or isinstance(notion_sorts, dict)):
logger.error("notion_sorts must be a list or dict")
return False
Expand Down
9 changes: 4 additions & 5 deletions n2y/database.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from n2y.logger import logger
from n2y.utils import fromisoformat, sanitize_filename


class Database:
def __init__(self, client, notion_data):
logger.debug("Instantiating database")
client.logger.debug("Instantiating database")
self.client = client

self.notion_data = notion_data
Expand Down Expand Up @@ -47,9 +46,9 @@ def children_filtered(self, filter, sort=None):
if tupled_filter not in self._filtered_children:
self._filtered_children[tupled_filter] = {}
if tupled_sort not in self._filtered_children[tupled_filter]:
self._filtered_children[tupled_filter][
tupled_sort
] = self.client.get_database_pages(self.notion_id, filter, sort)
self._filtered_children[tupled_filter][tupled_sort] = (
self.client.get_database_pages(self.notion_id, filter, sort)
)
children = self._filtered_children[tupled_filter][tupled_sort]
else:
children = self.children
Expand Down
6 changes: 0 additions & 6 deletions n2y/emoji.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
import logging


logger = logging.getLogger(__name__)


class Emoji:
"""
See https://developers.notion.com/reference/emoji-object
Expand Down
Loading

0 comments on commit fde1673

Please sign in to comment.