Skip to content

Commit

Permalink
Lints and actions
Browse files Browse the repository at this point in the history
  • Loading branch information
Vasily Negrebetskiy committed Aug 28, 2024
1 parent 705c2d1 commit e40b316
Show file tree
Hide file tree
Showing 12 changed files with 1,228 additions and 56 deletions.
2 changes: 2 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[flake8]
max-line-length=120
19 changes: 11 additions & 8 deletions .github/workflows/development.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: "3.11"
python-version: "3.12"
- name: Check with linter
run: pip install flake8 && flake8

Expand All @@ -25,12 +25,15 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
python-version: "3.12"
- name: Install dependencies
run: pip install -r requirements.txt
run: |
pip install poetry==1.8.3
poetry export --without-hashes --with=dev --format=requirements.txt > requirements.txt
pip install --no-cache-dir -r requirements.txt
- name: Run tests
run: pytest
16 changes: 13 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
FROM python:3.11-slim
FROM python:3.12-slim AS builder

WORKDIR /build

COPY ./pyproject.toml ./poetry.lock /build

RUN pip install poetry==1.8.3
RUN poetry export --without-hashes --only=main --format=requirements.txt > requirements.txt


FROM python:3.12-slim AS runner

WORKDIR /app

RUN apt-get update
RUN apt-get install -y libpango-1.0-0 libpangoft2-1.0-0

COPY ./requirements.txt /app
RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
COPY --from=builder /build/requirements.txt /app
RUN pip install --no-cache-dir -r /app/requirements.txt

COPY ./muckraker /app/muckraker

Expand Down
1 change: 0 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
version: '3'
services:

app:
Expand Down
10 changes: 5 additions & 5 deletions muckraker/main.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from asyncio import gather
import uuid
from asyncio import gather
from io import BytesIO
from pathlib import Path
from tempfile import TemporaryDirectory
Expand All @@ -13,7 +13,7 @@
from . import __version__
from .models import Issue
from .render import render_issue
from .sqlcache import SQLCache, CacheError
from .sqlcache import CacheError, SQLCache

CACHE_PATH = "cache.sqlite"
MAX_IMAGE_NUM = 4
Expand Down Expand Up @@ -106,7 +106,7 @@ async def get_issue(issue_id: str):
body=issue_dict["body"],
fonts=issue_dict["fonts"],
output=pdf_path,
image_dir=dir_path
image_dir=dir_path,
)
with open(pdf_path, "rb") as fd:
buf = BytesIO(fd.read())
Expand All @@ -118,5 +118,5 @@ async def get_issue(issue_id: str):
# Delete cached data
await cache.delete_issue(issue_id)

headers = {'Content-Disposition': 'attachment; filename="out.pdf"'}
return Response(pdf_bytes, headers=headers, media_type='application/pdf')
headers = {"Content-Disposition": 'attachment; filename="out.pdf"'}
return Response(pdf_bytes, headers=headers, media_type="application/pdf")
22 changes: 7 additions & 15 deletions muckraker/md_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@


class FilterExtension(Extension):
""" Ignore some tags """
"""Ignore some tags"""

def extendMarkdown(self, md: Markdown) -> None:
md.inlinePatterns.deregister("link")
Expand All @@ -26,17 +26,13 @@ def extendMarkdown(self, md: Markdown) -> None:


class ImagePathProcessor(ImageInlineProcessor):
""" Return an `img` element from the given match. """
"""Return an `img` element from the given match."""

def __init__(self, pattern: str, md: Markdown, image_dir: str = ""):
def __init__(self, pattern: str, md: Markdown, image_dir: str = "") -> None:
super().__init__(pattern, md)
self.image_dir = image_dir

def handleMatch(
self,
m: re.Match[str],
data: str
) -> tuple[etree.Element | None, int | None, int | None]:
def handleMatch(self, m: re.Match[str], data: str) -> tuple[etree.Element | None, int | None, int | None]:
el, start, ind = super().handleMatch(m, data)
src_path = Path(el.get("src"))
src_path = Path(self.image_dir) / src_path
Expand All @@ -45,9 +41,9 @@ def handleMatch(


class ImagePathExtension(Extension):
""" Modify image paths so that Weasyprint could handle them """
"""Modify image paths so that Weasyprint could handle them"""

def __init__(self, **kwargs):
def __init__(self, **kwargs) -> None:
self.config = {"image_dir": ["", "Images root directory"]}
super().__init__(**kwargs)

Expand All @@ -56,9 +52,5 @@ def extendMarkdown(self, md: Markdown) -> None:
md.inlinePatterns.deregister("image_reference")
md.inlinePatterns.deregister("short_image_ref")

processor = ImagePathProcessor(
IMAGE_LINK_RE,
md,
self.getConfig("image_dir")
)
processor = ImagePathProcessor(IMAGE_LINK_RE, md, self.getConfig("image_dir"))
md.inlinePatterns.register(processor, "image_path", 140)
2 changes: 1 addition & 1 deletion muckraker/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class Issue(BaseModel):
body: str = Field(max_length=MAX_BODY_LEN)
fonts: Optional[IssueFonts] = IssueFonts()

@model_validator(mode='before')
@model_validator(mode="before")
@classmethod
def validate_to_json(cls, value):
if isinstance(value, str):
Expand Down
27 changes: 11 additions & 16 deletions muckraker/render.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,17 @@ def font_size_css(selector: str, size_pt: int | None):
return f"{selector} {{ font-size: {size_pt}pt !important; }}\n"


def render_issue(
page: dict,
header: dict,
body: str,
fonts: dict,
output: str,
image_dir: str = ""
) -> None:
def render_issue(page: dict, header: dict, body: str, fonts: dict, output: str, image_dir: str = "") -> None:
# Sanitize Markdown and convert it to HTML
body = nh3.clean(body, tags=TAGS)
md = Markdown(extensions=[
"tables",
"sane_lists",
FilterExtension(),
ImagePathExtension(image_dir=image_dir)
])
md = Markdown(
extensions=[
"tables",
"sane_lists",
FilterExtension(),
ImagePathExtension(image_dir=image_dir),
]
)
body = md.convert(body)

# Sanitize all str header fields
Expand All @@ -55,7 +50,7 @@ def render_issue(
page=page,
header=header,
body=body,
static="file://" + str(STATIC.resolve())
static="file://" + str(STATIC.resolve()),
)

# Configure fonts
Expand All @@ -74,7 +69,7 @@ def render_issue(
HTML(string=html).write_pdf(
output,
stylesheets=[css, fonts_css],
font_config=font_config
font_config=font_config,
)


Expand Down
2 changes: 1 addition & 1 deletion muckraker/sqlcache.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def __init__(self, path: str) -> None:
""")

async def put_issue(self, issue_id: str, issue_dict: dict) -> None:
data = json.dumps(issue_dict).encode('utf-8')
data = json.dumps(issue_dict).encode("utf-8")
async with aiosqlite.connect(self.path) as db:
await db.execute("INSERT INTO issues (issue_id, data) VALUES (?, ?)", (issue_id, data))
await db.commit()
Expand Down
Loading

0 comments on commit e40b316

Please sign in to comment.