mirror of
https://github.com/leoncvlt/loconotion.git
synced 2024-08-30 18:12:12 +00:00
Fix file locations so that both tests and CLI work
This commit is contained in:
parent
8a2c230f90
commit
0c326e6d16
@ -1,168 +1,14 @@
|
|||||||
import argparse
|
|
||||||
import copy
|
|
||||||
import logging
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import urllib.parse
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
from .notionparser import Parser
|
|
||||||
|
|
||||||
log = logging.getLogger("loconotion")
|
|
||||||
|
|
||||||
try:
|
|
||||||
import colorama
|
|
||||||
import requests
|
|
||||||
import toml
|
|
||||||
|
|
||||||
except ModuleNotFoundError as error:
|
|
||||||
log.critical(f"ModuleNotFoundError: {error}. Have you installed the requirements?")
|
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
args = get_args()
|
|
||||||
log = setup_logging(args)
|
|
||||||
parser = init_parser(args, log)
|
|
||||||
parser.run()
|
|
||||||
|
|
||||||
|
|
||||||
def get_args():
|
|
||||||
# set up argument parser and return parsed args
|
|
||||||
argparser = argparse.ArgumentParser(
|
|
||||||
description="Generate static websites from Notion.so pages"
|
|
||||||
)
|
|
||||||
argparser.add_argument(
|
|
||||||
"target",
|
|
||||||
help="The config file containing the site properties, or the url"
|
|
||||||
" of the Notion.so page to generate the site from",
|
|
||||||
)
|
|
||||||
argparser.add_argument(
|
|
||||||
"--chromedriver",
|
|
||||||
help="Use a specific chromedriver executable instead of the auto-installing one",
|
|
||||||
)
|
|
||||||
argparser.add_argument(
|
|
||||||
"--single-page",
|
|
||||||
action="store_true",
|
|
||||||
help="Only parse the first page, then stop",
|
|
||||||
)
|
|
||||||
argparser.add_argument(
|
|
||||||
"--dark-theme",
|
|
||||||
action="store_true",
|
|
||||||
help="Use dark themed version of the target Notion.so page",
|
|
||||||
)
|
|
||||||
argparser.add_argument(
|
|
||||||
"--timeout",
|
|
||||||
type=int,
|
|
||||||
default=5,
|
|
||||||
help="Time in seconds to wait for the loading of lazy-loaded dynamic elements (default 5)."
|
|
||||||
" If content from the page seems to be missing, try increasing this value",
|
|
||||||
)
|
|
||||||
argparser.add_argument(
|
|
||||||
"--clean",
|
|
||||||
action="store_true",
|
|
||||||
help="Delete all previously cached files for the site before generating it",
|
|
||||||
)
|
|
||||||
argparser.add_argument(
|
|
||||||
"--clean-css",
|
|
||||||
action="store_true",
|
|
||||||
help="Delete previously cached .css files for the site before generating it",
|
|
||||||
)
|
|
||||||
argparser.add_argument(
|
|
||||||
"--clean-js",
|
|
||||||
action="store_true",
|
|
||||||
help="Delete previously cached .js files for the site before generating it",
|
|
||||||
)
|
|
||||||
argparser.add_argument(
|
|
||||||
"--non-headless",
|
|
||||||
action="store_true",
|
|
||||||
help="Run chromedriver in non-headless mode",
|
|
||||||
)
|
|
||||||
argparser.add_argument(
|
|
||||||
"-v", "--verbose", action="store_true", help="Increase output log verbosity"
|
|
||||||
)
|
|
||||||
return argparser.parse_args()
|
|
||||||
|
|
||||||
|
|
||||||
def setup_logging(args):
|
|
||||||
# set up some pretty logs
|
|
||||||
log = logging.getLogger("loconotion")
|
|
||||||
log.setLevel(logging.INFO if not args.verbose else logging.DEBUG)
|
|
||||||
log_screen_handler = logging.StreamHandler(stream=sys.stdout)
|
|
||||||
log.addHandler(log_screen_handler)
|
|
||||||
log.propagate = False
|
|
||||||
try:
|
|
||||||
LOG_COLORS = {
|
|
||||||
logging.DEBUG: colorama.Fore.GREEN,
|
|
||||||
logging.INFO: colorama.Fore.BLUE,
|
|
||||||
logging.WARNING: colorama.Fore.YELLOW,
|
|
||||||
logging.ERROR: colorama.Fore.RED,
|
|
||||||
logging.CRITICAL: colorama.Back.RED,
|
|
||||||
}
|
|
||||||
|
|
||||||
class ColorFormatter(logging.Formatter):
|
|
||||||
def format(self, record, *args, **kwargs):
|
|
||||||
# if the corresponding logger has children, they may receive modified
|
|
||||||
# record, so we want to keep it intact
|
|
||||||
new_record = copy.copy(record)
|
|
||||||
if new_record.levelno in LOG_COLORS:
|
|
||||||
new_record.levelname = "{color_begin}{level}{color_end}".format(
|
|
||||||
level=new_record.levelname,
|
|
||||||
color_begin=LOG_COLORS[new_record.levelno],
|
|
||||||
color_end=colorama.Style.RESET_ALL,
|
|
||||||
)
|
|
||||||
return super(ColorFormatter, self).format(new_record, *args, **kwargs)
|
|
||||||
|
|
||||||
log_screen_handler.setFormatter(
|
|
||||||
ColorFormatter(
|
|
||||||
fmt="%(asctime)s %(levelname)-8s %(message)s",
|
|
||||||
datefmt="{color_begin}[%H:%M:%S]{color_end}".format(
|
|
||||||
color_begin=colorama.Style.DIM, color_end=colorama.Style.RESET_ALL
|
|
||||||
),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
except ModuleNotFoundError as identifier:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return log
|
|
||||||
|
|
||||||
|
|
||||||
def init_parser(args, log):
|
|
||||||
# initialise the website parser
|
|
||||||
try:
|
|
||||||
if urllib.parse.urlparse(args.target).scheme:
|
|
||||||
try:
|
|
||||||
requests.get(args.target)
|
|
||||||
except requests.ConnectionError as exception:
|
|
||||||
log.critical("Connection error")
|
|
||||||
|
|
||||||
if "notion.so" in args.target or "notion.site" in args.target:
|
|
||||||
log.info("Initialising parser with simple page url")
|
|
||||||
config = {"page": args.target}
|
|
||||||
parser = Parser(config=config, args=vars(args))
|
|
||||||
else:
|
|
||||||
log.critical(f"{args.target} is not a notion.so page")
|
|
||||||
|
|
||||||
elif Path(args.target).is_file():
|
|
||||||
with open(args.target, encoding="utf-8") as f:
|
|
||||||
parsed_config = toml.loads(f.read())
|
|
||||||
log.info("Initialising parser with configuration file")
|
|
||||||
log.debug(parsed_config)
|
|
||||||
parser = Parser(config=parsed_config, args=vars(args))
|
|
||||||
|
|
||||||
else:
|
|
||||||
log.critical(f"Config file {args.target} does not exist")
|
|
||||||
|
|
||||||
except FileNotFoundError as e:
|
|
||||||
log.critical(f"FileNotFoundError: {e}")
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
return parser
|
|
||||||
|
|
||||||
|
import modules.main as main
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
try:
|
try:
|
||||||
main()
|
args = main.get_args()
|
||||||
|
log = main.setup_logging(args)
|
||||||
|
parser = main.init_parser(args, log)
|
||||||
|
parser.run()
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
log.critical("Interrupted by user")
|
log.critical("Interrupted by user")
|
||||||
try:
|
try:
|
||||||
|
152
loconotion/modules/main.py
Normal file
152
loconotion/modules/main.py
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
import argparse
|
||||||
|
import copy
|
||||||
|
import logging
|
||||||
|
import sys
|
||||||
|
import urllib.parse
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from .notionparser import Parser
|
||||||
|
|
||||||
|
log = logging.getLogger("loconotion")
|
||||||
|
|
||||||
|
try:
|
||||||
|
import colorama
|
||||||
|
import requests
|
||||||
|
import toml
|
||||||
|
|
||||||
|
except ModuleNotFoundError as error:
|
||||||
|
log.critical(f"ModuleNotFoundError: {error}. Have you installed the requirements?")
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
|
||||||
|
def get_args():
|
||||||
|
# set up argument parser and return parsed args
|
||||||
|
argparser = argparse.ArgumentParser(
|
||||||
|
description="Generate static websites from Notion.so pages"
|
||||||
|
)
|
||||||
|
argparser.add_argument(
|
||||||
|
"target",
|
||||||
|
help="The config file containing the site properties, or the url"
|
||||||
|
" of the Notion.so page to generate the site from",
|
||||||
|
)
|
||||||
|
argparser.add_argument(
|
||||||
|
"--chromedriver",
|
||||||
|
help="Use a specific chromedriver executable instead of the auto-installing one",
|
||||||
|
)
|
||||||
|
argparser.add_argument(
|
||||||
|
"--single-page",
|
||||||
|
action="store_true",
|
||||||
|
help="Only parse the first page, then stop",
|
||||||
|
)
|
||||||
|
argparser.add_argument(
|
||||||
|
"--dark-theme",
|
||||||
|
action="store_true",
|
||||||
|
help="Use dark themed version of the target Notion.so page",
|
||||||
|
)
|
||||||
|
argparser.add_argument(
|
||||||
|
"--timeout",
|
||||||
|
type=int,
|
||||||
|
default=5,
|
||||||
|
help="Time in seconds to wait for the loading of lazy-loaded dynamic elements (default 5)."
|
||||||
|
" If content from the page seems to be missing, try increasing this value",
|
||||||
|
)
|
||||||
|
argparser.add_argument(
|
||||||
|
"--clean",
|
||||||
|
action="store_true",
|
||||||
|
help="Delete all previously cached files for the site before generating it",
|
||||||
|
)
|
||||||
|
argparser.add_argument(
|
||||||
|
"--clean-css",
|
||||||
|
action="store_true",
|
||||||
|
help="Delete previously cached .css files for the site before generating it",
|
||||||
|
)
|
||||||
|
argparser.add_argument(
|
||||||
|
"--clean-js",
|
||||||
|
action="store_true",
|
||||||
|
help="Delete previously cached .js files for the site before generating it",
|
||||||
|
)
|
||||||
|
argparser.add_argument(
|
||||||
|
"--non-headless",
|
||||||
|
action="store_true",
|
||||||
|
help="Run chromedriver in non-headless mode",
|
||||||
|
)
|
||||||
|
argparser.add_argument(
|
||||||
|
"-v", "--verbose", action="store_true", help="Increase output log verbosity"
|
||||||
|
)
|
||||||
|
return argparser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
def setup_logging(args):
|
||||||
|
# set up some pretty logs
|
||||||
|
log = logging.getLogger("loconotion")
|
||||||
|
log.setLevel(logging.INFO if not args.verbose else logging.DEBUG)
|
||||||
|
log_screen_handler = logging.StreamHandler(stream=sys.stdout)
|
||||||
|
log.addHandler(log_screen_handler)
|
||||||
|
log.propagate = False
|
||||||
|
try:
|
||||||
|
LOG_COLORS = {
|
||||||
|
logging.DEBUG: colorama.Fore.GREEN,
|
||||||
|
logging.INFO: colorama.Fore.BLUE,
|
||||||
|
logging.WARNING: colorama.Fore.YELLOW,
|
||||||
|
logging.ERROR: colorama.Fore.RED,
|
||||||
|
logging.CRITICAL: colorama.Back.RED,
|
||||||
|
}
|
||||||
|
|
||||||
|
class ColorFormatter(logging.Formatter):
|
||||||
|
def format(self, record, *args, **kwargs):
|
||||||
|
# if the corresponding logger has children, they may receive modified
|
||||||
|
# record, so we want to keep it intact
|
||||||
|
new_record = copy.copy(record)
|
||||||
|
if new_record.levelno in LOG_COLORS:
|
||||||
|
new_record.levelname = "{color_begin}{level}{color_end}".format(
|
||||||
|
level=new_record.levelname,
|
||||||
|
color_begin=LOG_COLORS[new_record.levelno],
|
||||||
|
color_end=colorama.Style.RESET_ALL,
|
||||||
|
)
|
||||||
|
return super(ColorFormatter, self).format(new_record, *args, **kwargs)
|
||||||
|
|
||||||
|
log_screen_handler.setFormatter(
|
||||||
|
ColorFormatter(
|
||||||
|
fmt="%(asctime)s %(levelname)-8s %(message)s",
|
||||||
|
datefmt="{color_begin}[%H:%M:%S]{color_end}".format(
|
||||||
|
color_begin=colorama.Style.DIM, color_end=colorama.Style.RESET_ALL
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
except ModuleNotFoundError as identifier:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return log
|
||||||
|
|
||||||
|
|
||||||
|
def init_parser(args, log):
|
||||||
|
# initialise the website parser
|
||||||
|
try:
|
||||||
|
if urllib.parse.urlparse(args.target).scheme:
|
||||||
|
try:
|
||||||
|
requests.get(args.target)
|
||||||
|
except requests.ConnectionError as exception:
|
||||||
|
log.critical("Connection error")
|
||||||
|
|
||||||
|
if "notion.so" in args.target or "notion.site" in args.target:
|
||||||
|
log.info("Initialising parser with simple page url")
|
||||||
|
config = {"page": args.target}
|
||||||
|
parser = Parser(config=config, args=vars(args))
|
||||||
|
else:
|
||||||
|
log.critical(f"{args.target} is not a notion.so page")
|
||||||
|
|
||||||
|
elif Path(args.target).is_file():
|
||||||
|
with open(args.target, encoding="utf-8") as f:
|
||||||
|
parsed_config = toml.loads(f.read())
|
||||||
|
log.info("Initialising parser with configuration file")
|
||||||
|
log.debug(parsed_config)
|
||||||
|
parser = Parser(config=parsed_config, args=vars(args))
|
||||||
|
|
||||||
|
else:
|
||||||
|
log.critical(f"Config file {args.target} does not exist")
|
||||||
|
|
||||||
|
except FileNotFoundError as e:
|
||||||
|
log.critical(f"FileNotFoundError: {e}")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
return parser
|
@ -1,5 +1,5 @@
|
|||||||
import pytest
|
import pytest
|
||||||
from loconotion.notionparser import Parser
|
from modules.notionparser import Parser
|
||||||
|
|
||||||
def test_parse_sample_page():
|
def test_parse_sample_page():
|
||||||
config={"page": "https://www.notion.so/Loconotion-Example-Page-03c403f4fdc94cc1b315b9469a8950ef"}
|
config={"page": "https://www.notion.so/Loconotion-Example-Page-03c403f4fdc94cc1b315b9469a8950ef"}
|
Loading…
Reference in New Issue
Block a user