diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index 7e0d535..c2e5ca8 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1,2 +1,2 @@
-custom: https://donate.getpelican.com
+github: justinmayer
liberapay: pelican
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 37ddfa7..ba41c23 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -7,102 +7,89 @@ env:
jobs:
test:
- name: Test - ${{ matrix.python-version }}
+ name: Test - Python ${{ matrix.python-version }}
runs-on: ubuntu-latest
strategy:
matrix:
- python-version: ["3.8", "3.9"]
+ python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
steps:
- - uses: actions/checkout@v3
- - name: Set up Python ${{ matrix.python-version }}
- uses: actions/setup-python@v4
+ - uses: actions/checkout@v4
+
+ - name: Set up Python ${{ matrix.python-version }} & PDM
+ uses: pdm-project/setup-pdm@v4
with:
python-version: ${{ matrix.python-version }}
- - name: Set up Pip cache
- uses: actions/cache@v3
- id: pip-cache
- with:
- path: ~/.cache/pip
- key: pip-${{ hashFiles('**/pyproject.toml') }}
- - name: Upgrade Pip
- run: python -m pip install --upgrade pip
- - name: Install Poetry
- run: python -m pip install poetry
- - name: Set up Poetry cache
- uses: actions/cache@v3
- id: poetry-cache
- with:
- path: ~/.cache/pypoetry/virtualenvs
- key: poetry-${{ hashFiles('**/poetry.lock') }}
- - name: Install dependencies
- run: |
- poetry run pip install --upgrade pip
- poetry install
- - name: Run tests
- run: poetry run invoke tests
+ cache: true
+ cache-dependency-path: ./pyproject.toml
+ - name: Install dependencies
+ run: pdm install
+
+ - name: Run tests
+ run: pdm run invoke tests
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
+
- name: Validate links in Markdown files
uses: JustinBeckwith/linkinator-action@v1
with:
retry: true
- - name: Set up Python
- uses: actions/setup-python@v4
- with:
- python-version: "3.9"
- - name: Set Poetry cache
- uses: actions/cache@v3
- id: poetry-cache
- with:
- path: ~/.cache/pypoetry/virtualenvs
- key: poetry-${{ hashFiles('**/poetry.lock') }}
- - name: Upgrade Pip
- run: python -m pip install --upgrade pip
- - name: Install Poetry
- run: python -m pip install poetry
- - name: Install dependencies
- run: |
- poetry run pip install --upgrade pip
- poetry install
- - name: Run linters
- run: poetry run invoke lint
+ - name: Set up Python & PDM
+ uses: pdm-project/setup-pdm@v4
+ with:
+ python-version: "3.10"
+
+ - name: Install dependencies
+ run: pdm install
+
+ - name: Run linters
+ run: pdm run invoke lint --diff
deploy:
name: Deploy
environment: Deployment
needs: [test, lint]
runs-on: ubuntu-latest
- if: ${{ github.ref=='refs/heads/main' && github.event_name!='pull_request' }}
+ if: github.ref=='refs/heads/main' && github.event_name!='pull_request'
+
+ permissions:
+ contents: write
+ id-token: write
steps:
- - uses: actions/checkout@v3
- - name: Setup Python
- uses: actions/setup-python@v4
+ - uses: actions/checkout@v4
with:
- python-version: "3.9"
+ token: ${{ secrets.GH_TOKEN }}
+
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.10"
+
- name: Check release
id: check_release
run: |
- python -m pip install --upgrade pip
- python -m pip install poetry githubrelease httpx==0.16.1 autopub
- echo "##[set-output name=release;]$(autopub check)"
+ python -m pip install autopub httpx
+ python -m pip install https://github.com/scikit-build/github-release/archive/master.zip
+ autopub check
+
- name: Publish
- if: ${{ steps.check_release.outputs.release=='' }}
+ if: ${{ steps.check_release.outputs.autopub_release=='true' }}
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
- PYPI_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: |
- git remote set-url origin https://$GITHUB_TOKEN@github.com/${{ github.repository }}
autopub prepare
- poetry build
autopub commit
+ autopub build
autopub githubrelease
- poetry publish -u __token__ -p $PYPI_PASSWORD
+
+ - name: Upload package to PyPI
+ if: ${{ steps.check_release.outputs.autopub_release=='true' }}
+ uses: pypa/gh-action-pypi-publish@release/v1
diff --git a/.gitignore b/.gitignore
index c04bc49..12568d5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
-poetry.lock
+.pdm-python
+pdm.lock
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 08632cf..9cdbf84 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -5,11 +5,12 @@ ci:
# See https://pre-commit.com/hooks.html for info on hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.4.0
+ rev: v4.6.0
hooks:
- id: check-added-large-files
- id: check-ast
- id: check-case-conflict
+ - id: check-docstring-first
- id: check-merge-conflict
- id: check-toml
- id: check-yaml
@@ -19,19 +20,9 @@ repos:
- id: forbid-new-submodules
- id: trailing-whitespace
- - repo: https://github.com/psf/black
- rev: 23.3.0
+ - repo: https://github.com/astral-sh/ruff-pre-commit
+ rev: v0.5.0
hooks:
- - id: black
-
- - repo: https://github.com/PyCQA/flake8
- rev: 6.0.0
- hooks:
- - id: flake8
- args: [--max-line-length=88]
- language_version: python3
-
- - repo: https://github.com/PyCQA/isort
- rev: 5.12.0
- hooks:
- - id: isort
+ - id: ruff
+ - id: ruff-format
+ args: ["--check"]
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7eb580f..a7c7fc0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,22 @@
CHANGELOG
=========
+1.2.1 - 2025-03-23
+------------------
+
+Add title to Bluesky
+
+Contributed by [Daniel Lemos](https://github.com/xspager) via [PR #34](https://github.com/pelican-plugins/share-post/pull/34/)
+
+
+1.2.0 - 2025-01-29
+------------------
+
+Add Bluesky support
+
+Contributed by [Leonardo Giordani](https://github.com/lgiordani) via [PR #33](https://github.com/pelican-plugins/share-post/pull/33/)
+
+
1.1.0 - 2023-08-31
------------------
diff --git a/README.md b/README.md
index 5871750..8e26419 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,7 @@
[](https://github.com/pelican-plugins/share-post/actions)
[](https://pypi.org/project/pelican-share-post/)
+[](https://pypi.org/project/pelican-share-post/)

Share Post is a Pelican plugin that creates share links in articles that allow site visitors to share the current article with others in a privacy-friendly manner.
@@ -18,6 +19,8 @@ This plugin can be installed via:
python -m pip install pelican-share-post
+As long as you have not explicitly added a `PLUGINS` setting to your Pelican settings file, then the newly-installed plugin should be automatically detected and enabled. Otherwise, you must add `share_post` to your existing `PLUGINS` list. For more information, please see the [How to Use Plugins](https://docs.getpelican.com/en/latest/plugins.html#how-to-use-plugins) documentation.
+
Usage
-----
@@ -33,6 +36,7 @@ article.share_post = {
"mastodon": "",
"reddit": "",
"twitter": "",
+ "bluesky": "",
}
```
@@ -53,11 +57,13 @@ You can then access those variables in your template. For example:
❄
LinkedIn
❄
- Mastodon
+ Mastodon
❄
Reddit
❄
Twitter
+ ❄
+ Bluesky
{% endif %}
diff --git a/pelican/plugins/share_post/__init__.py b/pelican/plugins/share_post/__init__.py
index 4185ce8..40c66ed 100644
--- a/pelican/plugins/share_post/__init__.py
+++ b/pelican/plugins/share_post/__init__.py
@@ -1 +1 @@
-from .share_post import * # noqa
+from .share_post import * # noqa: F403,PGH004,RUF100
diff --git a/pelican/plugins/share_post/share_post.py b/pelican/plugins/share_post/share_post.py
index f779c15..2f829c1 100644
--- a/pelican/plugins/share_post/share_post.py
+++ b/pelican/plugins/share_post/share_post.py
@@ -1,6 +1,4 @@
-"""
-Share Post
-==========
+"""Share Post plugin for Pelican.
This plugin was originally created by
Talha Mansoor
@@ -98,6 +96,12 @@ def create_link_linkedin(title, url, content):
)
+@create_link
+def create_link_bluesky(title, url, content):
+ # https://docs.bsky.app/docs/advanced-guides/intent-links
+ return f"https://bsky.app/intent/compose?text={title}%20{url}"
+
+
def create_share_links(content):
if isinstance(content, contents.Static):
return
@@ -111,10 +115,10 @@ def create_share_links(content):
except AttributeError:
sub_title = ""
- title = quote(f"{main_title}{sub_title}".encode("utf-8"))
+ title = quote(f"{main_title}{sub_title}".encode())
site_url = content.settings["SITEURL"]
- url = quote(f"{site_url}/{content.url}".encode("utf-8"))
+ url = quote(f"{site_url}/{content.url}".encode())
content.share_post = {}
for func in _create_link_functions:
diff --git a/pelican/plugins/share_post/test_share_post.py b/pelican/plugins/share_post/test_share_post.py
index a35fc59..5ff33f9 100644
--- a/pelican/plugins/share_post/test_share_post.py
+++ b/pelican/plugins/share_post/test_share_post.py
@@ -1,7 +1,5 @@
import os
-from share_post import run_plugin
-
from pelican.generators import ArticlesGenerator
from pelican.tests.support import get_context, get_settings
@@ -26,7 +24,7 @@ def test_share_post(tmp_folder):
)
generator.generate_context()
- run_plugin([generator])
+ share_post.run_plugin([generator])
share_links = generator.articles[0].share_post
@@ -63,3 +61,8 @@ def test_share_post(tmp_folder):
share_links["reddit"]
== "https://www.reddit.com/submit?url=/test-post.html&title=Test%20post"
)
+
+ assert (
+ share_links["bluesky"]
+ == "https://bsky.app/intent/compose?text=Test%20post%20/test-post.html"
+ )
diff --git a/pyproject.toml b/pyproject.toml
index 4610bc5..90ed39b 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,51 +1,63 @@
-[tool.poetry]
+[project]
name = "pelican-share-post"
-version = "1.1.0"
+version = "1.2.1"
description = "A Pelican plugin to create share URLs of article"
-authors = ["Talha Mansoor ", "Justin Mayer "]
-license = "MIT"
+authors = [{name = "Talha Mansoor", email = "talha131@gmail.com"}, {name = "Justin Mayer", email = "entroP@gmail.com"}]
+license = {text = "MIT"}
readme = "README.md"
keywords = ["pelican", "plugin", "social"]
-repository = "https://github.com/pelican-plugins/share-post"
-documentation = "https://docs.getpelican.com"
-packages = [
- { include = "pelican" },
-]
-
classifiers = [
"Development Status :: 5 - Production/Stable",
"Environment :: Console",
"Framework :: Pelican",
"Framework :: Pelican :: Plugins",
"Intended Audience :: End Users/Desktop",
+ "License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
+ "Programming Language :: Python :: 3",
+ "Programming Language :: Python :: 3.8",
+ "Programming Language :: Python :: 3.9",
+ "Programming Language :: Python :: 3.10",
+ "Programming Language :: Python :: 3.11",
+ "Programming Language :: Python :: 3.12",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Software Development :: Libraries :: Python Modules",
]
+requires-python = ">=3.8.1,<4.0"
+dependencies = [
+ "pelican>=4.5",
+ "beautifulsoup4>=4.9.3",
+]
-[tool.poetry.urls]
-"Funding" = "https://donate.getpelican.com/"
+[project.urls]
+Homepage = "https://github.com/pelican-plugins/share-post"
"Issue Tracker" = "https://github.com/pelican-plugins/share-post/issues"
+Funding = "https://donate.getpelican.com/"
-[tool.poetry.dependencies]
-python = ">=3.7,<4.0"
-pelican = ">=4.5"
-markdown = {version = ">=3.2.2", optional = true}
-beautifulsoup4 = "^4.9.3"
+[project.optional-dependencies]
+markdown = ["markdown>=3.4"]
-[tool.poetry.dev-dependencies]
-black = ">=22.3.0"
-flake8 = "^3.9"
-flake8-black = "^0.3"
-invoke = "^2.1"
-isort = "^5.4"
-markdown = "^3.4"
-pytest = "^6.0"
-pytest-cov = "^2.8"
-pytest-sugar = "^0.9.7"
+[tool.pdm]
-[tool.poetry.extras]
-markdown = ["markdown"]
+[tool.pdm.dev-dependencies]
+lint = [
+ "invoke>=2.2",
+ "ruff>=0.5.0,<0.6.0"
+]
+test = [
+ "markdown>=3.4",
+ "pytest>=7.0",
+ "pytest-cov>=4.0",
+ "pytest-sugar>=1.0",
+]
+
+[tool.pdm.build]
+source-includes = [
+ "CHANGELOG.md",
+ "CONTRIBUTING.md",
+]
+includes = ["pelican/"]
+excludes = ["**/.DS_Store", "**/test_data/**", "tasks.py"]
[tool.autopub]
project-name = "Share Post"
@@ -53,18 +65,45 @@ git-username = "botpub"
git-email = "52496925+botpub@users.noreply.github.com"
append-github-contributor = true
-[tool.isort]
-# Maintain compatibility with Black
-profile = "black"
-multi_line_output = 3
+[tool.ruff.lint]
+select = [
+ "B", # flake8-bugbear
+ "BLE", # flake8-blind-except
+ "C4", # flake8-comprehensions
+ "D", # pydocstyle
+ "E", # pycodestyle
+ "F", # pyflakes
+ "I", # isort
+ "ICN", # flake8-import-conventions
+ "ISC", # flake8-implicit-str-concat
+ "PGH", # pygrep-hooks
+ "PL", # pylint
+ "RET", # flake8-return
+ "RUF", # ruff-specific rules
+ "SIM", # flake8-simplify
+ "T10", # flake8-debugger
+ "T20", # flake8-print
+ "TID", # flake8-tidy-imports
+ "TRY", # tryceratops
+ "UP", # pyupgrade
+ "W", # pycodestyle
+ "YTT", # flake8-2020
+]
-# Sort imports within their section independent of the import type
-force_sort_within_sections = true
+ignore = [
+ "D100", # missing docstring in public module
+ "D103", # missing docstring in public method
+ "D104", # missing docstring in public package
+ "D203", # blank line before class docstring
+ "D213", # multi-line docstring summary should start at the second line
+ "ISC001", # disabled so `ruff format` works without warning
+]
-# Designate "pelican" as separate import section
-known_pelican = "pelican"
-sections = "FUTURE,STDLIB,THIRDPARTY,PELICAN,FIRSTPARTY,LOCALFOLDER"
+[tool.ruff.lint.isort]
+combine-as-imports = true
+force-sort-within-sections = true
+known-first-party = ["pelican"]
[build-system]
-requires = ["poetry-core>=1.0.0"]
-build-backend = "poetry.core.masonry.api"
+requires = ["pdm-backend"]
+build-backend = "pdm.backend"
diff --git a/tasks.py b/tasks.py
index f0fbc52..3a8b167 100644
--- a/tasks.py
+++ b/tasks.py
@@ -1,14 +1,15 @@
from inspect import cleandoc
+import logging
import os
from pathlib import Path
from shutil import which
-import sys
from invoke import task
+logger = logging.getLogger(__name__)
+
PKG_NAME = "share_post"
PKG_PATH = Path(f"pelican/plugins/{PKG_NAME}")
-TOOLS = ("poetry", "pre-commit")
ACTIVE_VENV = os.environ.get("VIRTUAL_ENV", None)
VENV_HOME = Path(os.environ.get("WORKON_HOME", "~/.local/share/virtualenvs"))
@@ -16,52 +17,50 @@ VENV_PATH = Path(ACTIVE_VENV) if ACTIVE_VENV else (VENV_HOME.expanduser() / PKG_
VENV = str(VENV_PATH.expanduser())
BIN_DIR = "bin" if os.name != "nt" else "Scripts"
VENV_BIN = Path(VENV) / Path(BIN_DIR)
-POETRY = which("poetry") if which("poetry") else (VENV_BIN / "poetry")
-CMD_PREFIX = f"{VENV_BIN}/" if ACTIVE_VENV else f"{POETRY} run "
+
+TOOLS = ("pdm", "pre-commit")
+PDM = which("pdm") if which("pdm") else (VENV_BIN / "pdm")
+CMD_PREFIX = f"{VENV_BIN}/" if ACTIVE_VENV else f"{PDM} run "
PRECOMMIT = which("pre-commit") if which("pre-commit") else f"{CMD_PREFIX}pre-commit"
-PTY = True if os.name != "nt" else False
+PTY = os.name != "nt"
@task
-def tests(c):
- """Run the test suite."""
- c.run(f"{CMD_PREFIX}pytest", pty=PTY)
+def tests(c, deprecations=False):
+ """Run the test suite, optionally with `--deprecations`."""
+ deprecations_flag = "" if deprecations else "-W ignore::DeprecationWarning"
+ c.run(f"{CMD_PREFIX}pytest {deprecations_flag}", pty=PTY)
@task
-def black(c, check=False, diff=False):
- """Run Black auto-formatter, optionally with `--check` or `--diff`."""
+def format(c, check=False, diff=False):
+ """Run Ruff's auto-formatter, optionally with `--check` or `--diff`."""
check_flag, diff_flag = "", ""
if check:
check_flag = "--check"
if diff:
diff_flag = "--diff"
- c.run(f"{CMD_PREFIX}black {check_flag} {diff_flag} {PKG_PATH} tasks.py")
+ c.run(
+ f"{CMD_PREFIX}ruff format {check_flag} {diff_flag} {PKG_PATH} tasks.py", pty=PTY
+ )
@task
-def isort(c, check=False, diff=False):
- """Ensure imports are sorted according to project standards."""
- check_flag, diff_flag = "", ""
- if check:
- check_flag = "-c"
+def ruff(c, fix=False, diff=False):
+ """Run Ruff to ensure code meets project standards."""
+ diff_flag, fix_flag = "", ""
+ if fix:
+ fix_flag = "--fix"
if diff:
diff_flag = "--diff"
- c.run(f"{CMD_PREFIX}isort {check_flag} {diff_flag} .")
+ c.run(f"{CMD_PREFIX}ruff check {diff_flag} {fix_flag} .", pty=PTY)
@task
-def flake8(c):
- """Check code for PEP8 compliance via Flake8."""
- c.run(f"{CMD_PREFIX}flake8 {PKG_PATH} tasks.py")
-
-
-@task
-def lint(c, diff=False):
+def lint(c, fix=False, diff=False):
"""Check code style via linting tools."""
- isort(c, check=True, diff=diff)
- black(c, check=True, diff=diff)
- flake8(c)
+ ruff(c, fix=fix, diff=diff)
+ format(c, check=(not fix), diff=diff)
@task
@@ -69,34 +68,34 @@ def tools(c):
"""Install development tools in the virtual environment if not already on PATH."""
for tool in TOOLS:
if not which(tool):
- print(f"** Installing {tool}.")
+ logger.info(f"** Installing {tool} **")
c.run(f"{CMD_PREFIX}pip install {tool}")
@task
def precommit(c):
- """Install pre-commit hooks to `.git/hooks/pre-commit`."""
- print("** Installing pre-commit hooks.")
+ """Install pre-commit hooks to .git/hooks/pre-commit."""
+ logger.info("** Installing pre-commit hooks **")
c.run(f"{PRECOMMIT} install")
@task
def setup(c):
"""Set up the development environment."""
- if which("poetry") or ACTIVE_VENV:
+ if which("pdm") or ACTIVE_VENV:
tools(c)
- c.run(f"{CMD_PREFIX}python -m pip install --upgrade pip")
- c.run(f"{POETRY} install")
+ c.run(f"{CMD_PREFIX}python -m pip install --upgrade pip", pty=PTY)
+ c.run(f"{PDM} update --dev", pty=PTY)
precommit(c)
- print("\nDevelopment environment should now be set up and ready!\n")
+ logger.info("\nDevelopment environment should now be set up and ready!\n")
else:
error_message = """
- Poetry is not installed, and there is no active virtual environment available.
+ PDM is not installed, and there is no active virtual environment available.
You can either manually create and activate a virtual environment, or you can
- install Poetry via:
+ install PDM via:
- curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -
+ curl -sSL https://raw.githubusercontent.com/pdm-project/pdm/main/install-pdm.py | python3 -
Once you have taken one of the above two steps, run `invoke setup` again.
""" # noqa: E501
- sys.exit(cleandoc(error_message))
+ raise SystemExit(cleandoc(error_message))
diff --git a/tox.ini b/tox.ini
deleted file mode 100644
index abbd0dc..0000000
--- a/tox.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[flake8]
-max-line-length = 88
-ignore = E203, W503