Compare commits

..

4 Commits

Author SHA1 Message Date
Bastian Venthur
8656780e5b added type annotations 2023-11-12 17:11:25 +01:00
Bastian Venthur
ff1099de60 wip 2023-11-12 17:04:53 +01:00
Bastian Venthur
a0374a777e put import at correct place 2023-11-12 17:03:53 +01:00
Bastian Venthur
55eb9d7482 WIP 2023-11-12 17:02:03 +01:00
31 changed files with 247 additions and 253 deletions

View File

@@ -1,38 +0,0 @@
name: CI/CD Pipeline
on:
push:
branches:
- main
tags:
- "v**"
jobs:
job1:
runs-on: ubuntu-latest
steps:
- uses: https://github.com/actions/checkout@v4
- uses: https://github.com/actions/setup-python@v5
with:
python-version: "3.11"
- run: |
make venv
- run: |
make lint
- run: |
make mypy
- run: |
make test
- run: |
make test-release
-
name: Push to docker pypi registry.
env:
TWINE_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
TWINE_PASSWORD: ${{ secrets.REGISTRY_TOKEN }}
TWINE_REPOSITORY_URL: "https://gitea.raer.me/api/packages/freyjagp/pypi"
run: |
venv/bin/python3 -m twine upload --verbose dist/*

11
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"

82
.github/workflows/python-package.yaml vendored Normal file
View File

@@ -0,0 +1,82 @@
name: CI/CD Pipeline
on:
- push
- pull_request
jobs:
test:
name: Test Python ${{ matrix.python-version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest
python-version:
- "3.8"
- "3.9"
- "3.10"
- "3.11"
- "3.12"
exclude:
# 3.8 on windows fails due to some pip issue
- os: windows-latest
python-version: "3.8"
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- run: |
make venv
- run: |
make test
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: "3.x"
- run: |
make venv
- run: |
make lint
mypy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: "3.x"
- run: |
make venv
- run: |
make mypy
test-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: "3.x"
- run: |
make venv
- run: |
make test-release

View File

@@ -1,41 +1,5 @@
# Changelog
## [2.4.0] -- 2024-10-26
* Merged master (original dev's work) into main (my fork)
* update gitea workflow to hopefully build/push any updates made to my fork of blag.
## [2.4.0] -- 2024-09-05
* added strikethru and footnotes to blag renders.
## [unreleased] --
## [2.3.2] -- 2024-10-13
* Ignore FileNotFoundError when trying to get the last modified time of files
in directories. This happens for example with temporary emacs files.
* Added changelog to docs
* removed ruff's target-version from pyproject.toml, this value defaults to the
projects requires-python
## [2.3.1] -- 2024-07-06
* added manpage
* added makefile target for generating blog's manpage
* added makefile target for serving blags docs locally
* mkdocs: disabled loading of google fonts, using locally installed system
fonts instead
* Debian: simplified html docs directory for blag-doc package
* Debian: changed section from Python to Web
* updated dependencies
## [2.3.0] -- 2024-04-24
* fixed devsever so it does not crash anymore when the (re-)build fails
* dropped support for Python 3.8 and 3.9
* updated dependencies
## [2.2.1] -- 2023-11-11
* fixed `suggests` to blag-doc

View File

@@ -57,14 +57,6 @@ update-pygmentize: $(VENV)
docs: $(VENV)
$(BIN)/mkdocs build
.PHONY: serve-docs
serve-docs: $(VENV)
$(BIN)/mkdocs serve
.PHONY: manpage
manpage: $(VENV)
help2man $(BIN)/blag --no-info -n "blog-aware, static site generator" -o debian/blag.1
.PHONY: clean
clean:
rm -rf build dist *.egg-info

View File

@@ -24,7 +24,7 @@ blag is named after [the blag of the webcomic xkcd][blagxkcd].
* Integrated devserver
* Available on [PyPI][]
blag runs on Linux, Mac and Windows and requires Python >= 3.10
blag runs on Linux, Mac and Windows and requires Python >= 3.8
[markdown]: https://daringfireball.net/projects/markdown/
[jinja2]: https://palletsprojects.com/p/jinja/

View File

@@ -2,11 +2,15 @@
"""blag's core methods."""
# remove when we don't support py38 anymore
from __future__ import annotations
import argparse
import configparser
import logging
import os
import shutil
import sqlite3
import sys
from typing import Any
@@ -281,6 +285,8 @@ def build(args: argparse.Namespace) -> None:
generate_index(articles, index_template, args.output_dir)
generate_archive(articles, archive_template, args.output_dir)
generate_tags(articles, tags_template, tag_template, args.output_dir)
generate_search(articles, pages, 'corpus.db')
logger.info("Done.")
def process_markdown(
@@ -508,5 +514,48 @@ def generate_tags(
fh.write(result)
def generate_search(
articles: list[tuple[str, dict[str, Any]]],
pages: list[tuple[str, dict[str, Any]]],
db: str,
) -> None:
"""Generate Search.
Parameters
----------
articles, pages
db
path to sqlite file
"""
logger.info("Generating full text search.")
conn = sqlite3.connect(db)
with conn:
conn.executescript("""
drop table if exists corpus;
create virtual table corpus using fts5(
link,
text,
tokenize = porter
);
""")
with conn:
for dst, context in articles:
text = context['content']
conn.execute("""
insert into corpus(link, text)
values(:link, :text)
""", dict(link=dst, text=text))
for dst, context in pages:
text = context['content']
conn.execute("""
insert into corpus(link, text)
values(:link, :text)
""", dict(link=dst, text=text))
if __name__ == "__main__":
main()

View File

@@ -6,6 +6,9 @@ site if necessary.
"""
# remove when we don't support py38 anymore
from __future__ import annotations
import argparse
import logging
import multiprocessing
@@ -42,19 +45,14 @@ def get_last_modified(dirs: list[str]) -> float:
for dir in dirs:
for root, dirs, files in os.walk(dir):
for f in files:
try:
mtime = os.stat(os.path.join(root, f)).st_mtime
except FileNotFoundError:
# ignore files that have been deleted since the os.walk
# call (for example temporary emacs files)
continue
mtime = os.stat(os.path.join(root, f)).st_mtime
if mtime > last_mtime:
last_mtime = mtime
return last_mtime
def autoreload(args: argparse.Namespace, wait: int=1) -> NoReturn:
def autoreload(args: argparse.Namespace) -> NoReturn:
"""Start the autoreloader.
This method monitors the given directories for changes (i.e. the
@@ -68,9 +66,6 @@ def autoreload(args: argparse.Namespace, wait: int=1) -> NoReturn:
----------
args
contains the input-, template- and static dir
wait
number of seconds the devsever waits before checking for updated
content
"""
dirs = [args.input_dir, args.template_dir, args.static_dir]
@@ -79,18 +74,12 @@ def autoreload(args: argparse.Namespace, wait: int=1) -> NoReturn:
# loop to avoid serving stale contents
last_mtime = 0.0
while True:
# make sure the devsever does not crash when the build fails with an
# exception
try:
mtime = get_last_modified(dirs)
if mtime > last_mtime:
last_mtime = mtime
logger.info("Change detected, rebuilding...")
blag.build(args)
time.sleep(wait)
except Exception:
logger.exception("Error occurred during rebuild:")
logger.info("Devserver did not crash, you may continue editing.")
mtime = get_last_modified(dirs)
if mtime > last_mtime:
last_mtime = mtime
logger.info("Change detected, rebuilding...")
blag.build(args)
time.sleep(1)
def serve(args: argparse.Namespace) -> None:

View File

@@ -5,6 +5,9 @@ processing.
"""
# remove when we don't support py38 anymore
from __future__ import annotations
import logging
from datetime import datetime
from urllib.parse import urlsplit, urlunsplit
@@ -30,8 +33,6 @@ def markdown_factory() -> Markdown:
"""
md = Markdown(
extensions=[
"footnotes", # Add footnotes support
"pymdownx.tilde", # Add strukethrough support
"meta",
"fenced_code",
"codehilite",

View File

@@ -1,5 +1,8 @@
"""Helper methods for blag's quickstart command."""
# remove when we don't support py38 anymore
from __future__ import annotations
import argparse
import configparser
import os

View File

@@ -4,36 +4,35 @@ span.linenos { color: inherit; background-color: transparent; padding-left: 5px;
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.hll { background-color: #49483e }
.c { color: #959077 } /* Comment */
.err { color: #ed007e; background-color: #1e0010 } /* Error */
.c { color: #75715e } /* Comment */
.err { color: #960050; background-color: #1e0010 } /* Error */
.esc { color: #f8f8f2 } /* Escape */
.g { color: #f8f8f2 } /* Generic */
.k { color: #66d9ef } /* Keyword */
.l { color: #ae81ff } /* Literal */
.n { color: #f8f8f2 } /* Name */
.o { color: #ff4689 } /* Operator */
.o { color: #f92672 } /* Operator */
.x { color: #f8f8f2 } /* Other */
.p { color: #f8f8f2 } /* Punctuation */
.ch { color: #959077 } /* Comment.Hashbang */
.cm { color: #959077 } /* Comment.Multiline */
.cp { color: #959077 } /* Comment.Preproc */
.cpf { color: #959077 } /* Comment.PreprocFile */
.c1 { color: #959077 } /* Comment.Single */
.cs { color: #959077 } /* Comment.Special */
.gd { color: #ff4689 } /* Generic.Deleted */
.ch { color: #75715e } /* Comment.Hashbang */
.cm { color: #75715e } /* Comment.Multiline */
.cp { color: #75715e } /* Comment.Preproc */
.cpf { color: #75715e } /* Comment.PreprocFile */
.c1 { color: #75715e } /* Comment.Single */
.cs { color: #75715e } /* Comment.Special */
.gd { color: #f92672 } /* Generic.Deleted */
.ge { color: #f8f8f2; font-style: italic } /* Generic.Emph */
.ges { color: #f8f8f2; font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.gr { color: #f8f8f2 } /* Generic.Error */
.gh { color: #f8f8f2 } /* Generic.Heading */
.gi { color: #a6e22e } /* Generic.Inserted */
.go { color: #66d9ef } /* Generic.Output */
.gp { color: #ff4689; font-weight: bold } /* Generic.Prompt */
.gp { color: #f92672; font-weight: bold } /* Generic.Prompt */
.gs { color: #f8f8f2; font-weight: bold } /* Generic.Strong */
.gu { color: #959077 } /* Generic.Subheading */
.gu { color: #75715e } /* Generic.Subheading */
.gt { color: #f8f8f2 } /* Generic.Traceback */
.kc { color: #66d9ef } /* Keyword.Constant */
.kd { color: #66d9ef } /* Keyword.Declaration */
.kn { color: #ff4689 } /* Keyword.Namespace */
.kn { color: #f92672 } /* Keyword.Namespace */
.kp { color: #66d9ef } /* Keyword.Pseudo */
.kr { color: #66d9ef } /* Keyword.Reserved */
.kt { color: #66d9ef } /* Keyword.Type */
@@ -52,9 +51,9 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left:
.nn { color: #f8f8f2 } /* Name.Namespace */
.nx { color: #a6e22e } /* Name.Other */
.py { color: #f8f8f2 } /* Name.Property */
.nt { color: #ff4689 } /* Name.Tag */
.nt { color: #f92672 } /* Name.Tag */
.nv { color: #f8f8f2 } /* Name.Variable */
.ow { color: #ff4689 } /* Operator.Word */
.ow { color: #f92672 } /* Operator.Word */
.pm { color: #f8f8f2 } /* Punctuation.Marker */
.w { color: #f8f8f2 } /* Text.Whitespace */
.mb { color: #ae81ff } /* Literal.Number.Bin */

View File

@@ -16,7 +16,6 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left:
.cs { color: #3D7B7B; font-style: italic } /* Comment.Special */
.gd { color: #A00000 } /* Generic.Deleted */
.ge { font-style: italic } /* Generic.Emph */
.ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.gr { color: #E40000 } /* Generic.Error */
.gh { color: #000080; font-weight: bold } /* Generic.Heading */
.gi { color: #008400 } /* Generic.Inserted */

View File

@@ -1,3 +1,3 @@
"""Version information for the blag package."""
__VERSION__ = "2.4.1"
__VERSION__ = "2.2.1"

View File

@@ -1 +1 @@
site/*
site/

28
debian/blag.1 vendored
View File

@@ -1,28 +0,0 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
.TH BLAG "1" "July 2024" "blag 2.3.0" "User Commands"
.SH NAME
blag \- blog-aware, static site generator
.SH DESCRIPTION
usage: blag [\-h] [\-\-version] [\-v] {build,quickstart,serve} ...
.SS "positional arguments:"
.IP
{build,quickstart,serve}
.TP
build
Build website.
.TP
quickstart
Quickstart blag, creating necessary configuration.
.TP
serve
Start development server.
.SS "options:"
.TP
\fB\-h\fR, \fB\-\-help\fR
show this help message and exit
.TP
\fB\-\-version\fR
show program's version number and exit
.TP
\fB\-v\fR, \fB\-\-verbose\fR
Verbose output.

31
debian/changelog vendored
View File

@@ -1,34 +1,3 @@
blag (2.3.2) unstable; urgency=medium
* Ignore FileNotFoundError when trying to get the last modified time of
files in directories. This happens for example with temporary emacs files.
* Added changelog to docs
* removed ruff's target-version from pyproject.toml, this value defaults to
the projects requires-python
-- Bastian Venthur <venthur@debian.org> Sun, 13 Oct 2024 20:12:29 +0200
blag (2.3.1) unstable; urgency=medium
* added manpage
* added makefile target for generating blog's manpage
* added makefile target for serving blags docs locally
* mkdocs: disabled loading of google fonts, using locally installed system
fonts instead
* Debian: simplified html docs directory for blag-doc package
* Debian: changed section in debian/control from Python to Web
* updated dependencies
-- Bastian Venthur <venthur@debian.org> Sat, 06 Jul 2024 15:33:36 +0200
blag (2.3.0) unstable; urgency=medium
* fixed devsever so it does not crash anymore when the (re-)build fails
* dropped support for Python 3.8 and 3.9
* updated dependencies
-- Bastian Venthur <venthur@debian.org> Wed, 24 Apr 2024 22:25:31 +0200
blag (2.2.1) unstable; urgency=medium
* fixed suggests field to blag-doc (Closes: #1055769)

16
debian/control vendored
View File

@@ -1,24 +1,24 @@
Source: blag
Section: web
Section: python
Priority: optional
Maintainer: Bastian Venthur <venthur@debian.org>
Rules-Requires-Root: no
Build-Depends:
debhelper-compat (= 13),
dh-python,
dh-sequence-python3,
mkdocs,
mkdocs-material,
mkdocstrings-python-handlers,
dh-python,
pybuild-plugin-pyproject,
python3-setuptools,
python3-all,
python3-markdown,
python3-feedgenerator,
python3-jinja2,
python3-markdown,
python3-pygments,
python3-pytest,
python3-pytest-cov,
python3-setuptools,
mkdocs,
mkdocs-material,
mkdocstrings-python-handlers,
#Testsuite: autopkgtest-pkg-python
Standards-Version: 4.6.0.1
Homepage: https://github.com/venthur/blag
@@ -28,8 +28,8 @@ Vcs-Git: https://github.com/venthur/blag.git
Package: blag
Architecture: all
Depends:
${misc:Depends},
${python3:Depends},
${misc:Depends},
Suggests:
blag-doc,
Description: Blog-aware, static site generator

1
debian/manpages vendored
View File

@@ -1 +0,0 @@
debian/blag.1

View File

@@ -1 +0,0 @@
../CHANGELOG.md

View File

@@ -16,7 +16,7 @@ blag is named after [the blag of the webcomic xkcd][blagxkcd].
## Features
* Write content in [Markdown][]
* Good looking default theme:
* Good looking default theme
![Blag Screenshot](blag.png)
* Theming support using [Jinja2][] templates
* Generation of Atom feeds for blog content
@@ -24,7 +24,7 @@ blag is named after [the blag of the webcomic xkcd][blagxkcd].
* Integrated devserver
* Available on [PyPI][]
blag runs on Linux, Mac and Windows and requires Python >= 3.10
blag runs on Linux, Mac and Windows and requires Python >= 3.8
[markdown]: https://daringfireball.net/projects/markdown/
[jinja2]: https://palletsprojects.com/p/jinja/

View File

@@ -13,13 +13,10 @@ nav:
- blag.markdown: markdown.md
- blag.devserver: devserver.md
- blag.quickstart: quickstart.md
- Changelog: CHANGELOG.md
theme:
name: material
highlightjs: true
# disable google fonts, use system fonts
font: false
markdown_extensions:
- pymdownx.superfences

View File

@@ -11,7 +11,7 @@ description = "blog-aware, static site generator"
keywords = ["markdown", "blag", "blog", "static site generator", "cli"]
readme = "README.md"
license = { file="LICENSE" }
requires-python = ">=3.10"
requires-python = ">=3.8"
dynamic = ["version"]
dependencies = [
"markdown",
@@ -64,9 +64,6 @@ addopts = """
"""
[tool.ruff]
line-length = 79
[tool.ruff.lint]
select = [
"F", # pyflakes
"E", "W", # pycodestyle
@@ -75,7 +72,11 @@ select = [
"D", # pydocstyle
"UP" # pyupgrade
]
pydocstyle.convention = "numpy"
line-length = 79
target-version = "py38"
[tool.ruff.pydocstyle]
convention = "numpy"
[tool.mypy]
files = "blag,tests"

View File

@@ -1,11 +1,11 @@
build==1.2.2.post1
mkdocs==1.6.1
mkdocs-material==9.5.39
mkdocstrings[python]==0.26.1
twine==5.1.1
wheel==0.44.0
pytest==8.3.3
pytest-cov==5.0.0
ruff==0.6.9
mypy==1.11.2
types-markdown==3.7.0.20240822
build==1.0.3
mkdocs==1.5.3
mkdocs-material==9.4.8
mkdocstrings[python]==0.23.0
twine==4.0.2
wheel==0.41.3
pytest==7.4.3
pytest-cov==4.1.0
ruff==0.1.5
mypy==1.6.1
types-markdown==3.5.0.1

View File

@@ -1,5 +1,4 @@
markdown==3.7
markdown==3.5.1
feedgenerator==2.1.0
jinja2==3.1.4
pygments==2.18.0
pymdown-extensions==10.9
jinja2==3.1.2
pygments==2.16.1

View File

@@ -1,9 +1,13 @@
"""Pytest fixtures."""
# remove when we don't support py38 anymore
from __future__ import annotations
import os
from argparse import Namespace
from collections.abc import Callable, Iterator
from tempfile import TemporaryDirectory
from typing import Callable, Iterator
import pytest
from jinja2 import Environment, Template

View File

@@ -1,5 +1,9 @@
"""Test blag."""
# remove when we don't support py38 anymore
from __future__ import annotations
import os
from argparse import Namespace
from datetime import datetime

View File

@@ -1,12 +1,16 @@
"""Tests for the devserver module."""
# remove when we don't support py38 anymore
from __future__ import annotations
import threading
import time
from argparse import Namespace
from blag import devserver
import pytest
WAITTIME = 0.1
from blag import devserver
def test_get_last_modified(cleandir: str) -> None:
@@ -15,13 +19,13 @@ def test_get_last_modified(cleandir: str) -> None:
t1 = devserver.get_last_modified(["content"])
# wait a bit, create a file and measure again
time.sleep(WAITTIME)
time.sleep(0.1)
with open("content/test", "w") as fh:
fh.write("boo")
t2 = devserver.get_last_modified(["content"])
# wait a bit and take time again
time.sleep(WAITTIME)
time.sleep(0.1)
t3 = devserver.get_last_modified(["content"])
assert t2 > t1
@@ -36,14 +40,14 @@ def test_autoreload_builds_immediately(args: Namespace) -> None:
t = threading.Thread(
target=devserver.autoreload,
args=(args, WAITTIME),
args=(args,),
daemon=True,
)
t0 = devserver.get_last_modified(["build"])
t.start()
# try for 5 seconds...
for i in range(5):
time.sleep(WAITTIME)
time.sleep(1)
t1 = devserver.get_last_modified(["build"])
print(t1)
if t1 > t0:
@@ -51,11 +55,14 @@ def test_autoreload_builds_immediately(args: Namespace) -> None:
assert t1 > t0
@pytest.mark.filterwarnings(
"ignore::pytest.PytestUnhandledThreadExceptionWarning"
)
def test_autoreload(args: Namespace) -> None:
"""Test autoreload."""
t = threading.Thread(
target=devserver.autoreload,
args=(args, WAITTIME),
args=(args,),
daemon=True,
)
t.start()
@@ -68,32 +75,8 @@ def test_autoreload(args: Namespace) -> None:
# try for 5 seconds to see if we rebuild once...
for i in range(5):
time.sleep(WAITTIME)
time.sleep(1)
t1 = devserver.get_last_modified(["build"])
if t1 > t0:
break
assert t1 > t0
def test_autoreload_does_not_crash(args: Namespace) -> None:
"""Test autoreload does not crash if build fails."""
t = threading.Thread(
target=devserver.autoreload,
args=(args, WAITTIME),
daemon=True,
)
t.start()
t0 = devserver.get_last_modified(["build"])
# create a file that causes build to crash
with open("content/test.md", "w") as fh:
fh.write("date: ")
# try for 5 seconds to see if we rebuild once...
for i in range(5):
time.sleep(WAITTIME)
t1 = devserver.get_last_modified(["build"])
if t1 > t0:
break
assert t.is_alive()

View File

@@ -1,5 +1,9 @@
"""Test markdown module."""
# remove when we don't support py38 anymore
from __future__ import annotations
from datetime import datetime
from typing import Any

View File

@@ -1,5 +1,9 @@
"""Tests for the quickstart module."""
# remove when we don't support py38 anymore
from __future__ import annotations
import os
from pytest import MonkeyPatch

View File

@@ -1,5 +1,9 @@
"""Test the templates."""
# remove when we don't support py38 anymore
from __future__ import annotations
import datetime
from jinja2 import Template

View File

@@ -1,5 +1,9 @@
"""Test the version module."""
# remove when we don't support py38 anymore
from __future__ import annotations
import blag