abstract IO for easier testing in the future
This commit is contained in:
parent
fc4f2fd7a7
commit
a524db1722
5 changed files with 119 additions and 29 deletions
|
@ -5,6 +5,8 @@ from pathlib import Path
|
|||
from app import utils
|
||||
from app.config import Configurator
|
||||
from app.converter.wordpress_markdown import WordpressMarkdownConverter
|
||||
from app.io.reader import FileReader
|
||||
from app.io.writer import FileWriter
|
||||
|
||||
|
||||
class Converter:
|
||||
|
@ -44,7 +46,11 @@ class Converter:
|
|||
_, _, files = next(os.walk(source_path))
|
||||
for file in files:
|
||||
source_abs_path = source_path / Path(file)
|
||||
|
||||
file_reader = FileReader(str(source_abs_path))
|
||||
file_writer = FileWriter(output_path.joinpath(source_abs_path.name))
|
||||
|
||||
self.markdown_converter.convert_jekyll_to_hugo(
|
||||
source_abs_path,
|
||||
output_path,
|
||||
file_reader,
|
||||
file_writer,
|
||||
)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
from pathlib import Path
|
||||
|
||||
import yaml
|
||||
from bs4 import BeautifulSoup, Tag
|
||||
|
||||
from app import utils
|
||||
from app.config import Configurator
|
||||
from app.io.reader import IoReader
|
||||
from app.io.writer import IoWriter
|
||||
from app.utils import key_error_silence
|
||||
|
||||
|
||||
|
@ -106,53 +106,46 @@ class WordpressMarkdownConverter:
|
|||
|
||||
return "\n".join(fixed_lines)
|
||||
|
||||
def read_jekyll_post(self, path: Path):
|
||||
def read_jekyll_post(self, reader: IoReader):
|
||||
"""
|
||||
Read a Jekyll post from the specified path
|
||||
Read a Jekyll post from the reader.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
path : Path
|
||||
The path to the Jekyll post
|
||||
reader : IoReader
|
||||
The IoReader instance for reading.
|
||||
"""
|
||||
# read source
|
||||
with open(path, "r") as fh:
|
||||
contents = fh.read()
|
||||
return contents
|
||||
return reader.read()
|
||||
|
||||
def write_hugo_post(self, output_path, post_header: dict, post_content: str):
|
||||
def write_hugo_post(self, writer: IoWriter, post_header: dict, post_content: str):
|
||||
"""
|
||||
Write a Hugo post to the specified path
|
||||
Write a Hugo post to the specified writer.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
output_path : Path
|
||||
The path to the Hugo post
|
||||
writer : IoWriter
|
||||
The IoWriter instance for writing.
|
||||
post_header : dict
|
||||
The post header
|
||||
post_content : str
|
||||
The post content
|
||||
"""
|
||||
# ensure that output path exists
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
data = ["---\n", yaml.dump(post_header), "---\n", post_content]
|
||||
writer.write("".join(data))
|
||||
|
||||
with open(output_path, "w") as fo:
|
||||
header = ["---\n", yaml.dump(post_header), "---\n"]
|
||||
fo.writelines(header)
|
||||
fo.write(post_content)
|
||||
|
||||
def convert_jekyll_to_hugo(self, jekyll_post_path: Path, hugo_post_output: Path):
|
||||
def convert_jekyll_to_hugo(self, reader: IoReader, writer: IoWriter):
|
||||
"""
|
||||
Convert a Jekyll post to a Hugo post
|
||||
|
||||
Parameters
|
||||
----------
|
||||
jekyll_post_path : Path
|
||||
The path to the Jekyll post
|
||||
hugo_post_output : Path
|
||||
The path to the Hugo post
|
||||
reader : IoReader
|
||||
The IoReader instance for reading.
|
||||
writer : IoWriter
|
||||
The IoWriter instance for writing.
|
||||
"""
|
||||
contents = self.read_jekyll_post(jekyll_post_path)
|
||||
contents = self.read_jekyll_post(reader)
|
||||
|
||||
# fix header
|
||||
header = yaml.safe_load(contents.split("---")[1])
|
||||
|
@ -162,7 +155,7 @@ class WordpressMarkdownConverter:
|
|||
fixed_post_content = self.convert_post_content(post_content)
|
||||
|
||||
self.write_hugo_post(
|
||||
hugo_post_output.joinpath(jekyll_post_path.name),
|
||||
writer,
|
||||
fixed_header,
|
||||
fixed_post_content,
|
||||
)
|
||||
|
|
0
app/io/__init__.py
Normal file
0
app/io/__init__.py
Normal file
39
app/io/reader.py
Normal file
39
app/io/reader.py
Normal file
|
@ -0,0 +1,39 @@
|
|||
from abc import ABCMeta, abstractmethod
|
||||
|
||||
|
||||
class IoReader(metaclass=ABCMeta):
|
||||
"""
|
||||
Abstract class for reading posts.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def read(self) -> str:
|
||||
"""
|
||||
Reads a post.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class StringReader(IoReader):
|
||||
"""
|
||||
Reads a post from a string.
|
||||
"""
|
||||
|
||||
def __init__(self, content: str):
|
||||
self._content = content
|
||||
|
||||
def read(self) -> str:
|
||||
return self._content
|
||||
|
||||
|
||||
class FileReader(IoReader):
|
||||
"""
|
||||
Reads a post from a local file.
|
||||
"""
|
||||
|
||||
def __init__(self, file_path: str):
|
||||
self._file_path = file_path
|
||||
|
||||
def read(self) -> str:
|
||||
with open(self._file_path, "r") as file:
|
||||
return file.read()
|
52
app/io/writer.py
Normal file
52
app/io/writer.py
Normal file
|
@ -0,0 +1,52 @@
|
|||
from abc import abstractmethod, ABCMeta
|
||||
from pathlib import Path
|
||||
from typing import Callable
|
||||
from app import utils
|
||||
|
||||
|
||||
class IoWriter(metaclass=ABCMeta):
|
||||
"""
|
||||
Abstract class for writing posts.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def write(self, data: str):
|
||||
"""
|
||||
Write a post
|
||||
|
||||
Parameters
|
||||
----------
|
||||
data: str
|
||||
The post data to write
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class FileWriter(IoWriter):
|
||||
"""
|
||||
Writes a post to a file.
|
||||
"""
|
||||
|
||||
def __init__(self, output_path: Path):
|
||||
utils.guard_against_none(output_path, "output_path")
|
||||
|
||||
self.output_path = output_path
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
def write(self, data: str):
|
||||
with open(self.output_path, "w") as fo:
|
||||
fo.write(data)
|
||||
|
||||
|
||||
class CallbackWriter(IoWriter):
|
||||
"""
|
||||
Writes a post to a string.
|
||||
"""
|
||||
|
||||
def __init__(self, callback: Callable[[str], None]):
|
||||
utils.guard_against_none(callback, "callback")
|
||||
|
||||
self.callback = callback
|
||||
|
||||
def write(self, data: str):
|
||||
self.callback(data)
|
Loading…
Reference in a new issue