mirror of
https://github.com/pelican-plugins/share-post.git
synced 2025-10-15 17:08:54 +02:00
Modernize code and add a test
This commit is contained in:
parent
32c4488fb7
commit
5b7dbc440c
14 changed files with 546 additions and 110 deletions
9
pelican/plugins/share_post/conftest.py
Normal file
9
pelican/plugins/share_post/conftest.py
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import pytest
|
||||
|
||||
from pelican.tests.support import temporary_folder
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def tmp_folder():
|
||||
with temporary_folder() as tf:
|
||||
yield tf
|
||||
|
|
@ -1,100 +1,125 @@
|
|||
"""
|
||||
Share Post plugin.
|
||||
Share Post
|
||||
==========
|
||||
|
||||
This plugin adds share URL to article. These links are textual which means no
|
||||
online tracking of your readers.
|
||||
This plugin was originally created by
|
||||
Talha Mansoor <talha131@gmail.com>
|
||||
|
||||
This plugin adds social share URLs to each article.
|
||||
"""
|
||||
|
||||
# If you want to add a new link_processor please
|
||||
# have a look at the create_link decorator and
|
||||
# follow the example of the other functions
|
||||
|
||||
from urllib.parse import quote
|
||||
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
from pelican import contents, signals
|
||||
from pelican.generators import ArticlesGenerator, PagesGenerator
|
||||
|
||||
try:
|
||||
from urllib.parse import quote
|
||||
except ImportError:
|
||||
from urllib import quote
|
||||
_create_link_functions = []
|
||||
|
||||
|
||||
def article_title(content):
|
||||
main_title = BeautifulSoup(content.title, 'html.parser').get_text().strip()
|
||||
sub_title = ''
|
||||
if hasattr(content, 'subtitle'):
|
||||
sub_title = ' ' + BeautifulSoup(content.subtitle, 'html.parser').get_text().strip() # noqa
|
||||
return quote(('%s%s' % (main_title, sub_title)).encode('utf-8'))
|
||||
# Use this decorator to mark a function as
|
||||
# a link creator. The function's prototype shall be
|
||||
# create_link_NAME(title, url, content)
|
||||
# where
|
||||
# NAME is the name of the target, e.g. "dispora" or "facebook"
|
||||
# title is the HTML-safe title of the content
|
||||
# url is the content URL
|
||||
# content is the full object, should you need to extract more data.
|
||||
def create_link(f):
|
||||
_create_link_functions.append(f)
|
||||
return f
|
||||
|
||||
|
||||
def article_url(content):
|
||||
site_url = content.settings['SITEURL']
|
||||
return quote(('%s/%s' % (site_url, content.url)).encode('utf-8'))
|
||||
@create_link
|
||||
def create_link_email(title, url, content):
|
||||
return f"mailto:?subject={title}&body={url}"
|
||||
|
||||
|
||||
def article_summary(content):
|
||||
return quote(BeautifulSoup(content.summary, 'html.parser').get_text().strip().encode('utf-8')) # noqa
|
||||
@create_link
|
||||
def create_link_hacker_news(title, url, content):
|
||||
return f"https://news.ycombinator.com/submitlink?t={title}&u={url}"
|
||||
|
||||
|
||||
def twitter_hastags(content):
|
||||
tags = getattr(content, 'tags', [])
|
||||
hashtags = ','.join((tag.slug for tag in tags))
|
||||
return '' if not hashtags else '&hashtags=%s' % hashtags
|
||||
@create_link
|
||||
def create_link_diaspora(title, url, content):
|
||||
return f"https://sharetodiaspora.github.io/?title={title}&url={url}"
|
||||
|
||||
|
||||
def twitter_via(content):
|
||||
twitter_username = content.settings.get('TWITTER_USERNAME', '')
|
||||
return '' if not twitter_username else '&via=%s' % twitter_username
|
||||
@create_link
|
||||
def create_link_facebook(title, url, content):
|
||||
return f"https://www.facebook.com/sharer/sharer.php?u={url}"
|
||||
|
||||
|
||||
def share_post(content):
|
||||
@create_link
|
||||
def create_link_twitter(title, url, content):
|
||||
twitter_username = content.settings.get("TWITTER_USERNAME", "")
|
||||
via = f"&via={twitter_username}" if twitter_username else ""
|
||||
|
||||
tags = getattr(content, "tags", [])
|
||||
tags = ",".join([tag.slug for tag in tags])
|
||||
hashtags = f"&hashtags={tags}" if tags else ""
|
||||
|
||||
return f"https://twitter.com/intent/tweet?text={title}&url={url}{via}{hashtags}"
|
||||
|
||||
|
||||
@create_link
|
||||
def create_link_reddit(title, url, content):
|
||||
return f"https://www.reddit.com/submit?url={url}&title={title}"
|
||||
|
||||
|
||||
@create_link
|
||||
def create_link_linkedin(title, url, content):
|
||||
summary = quote(
|
||||
BeautifulSoup(content.summary, "html.parser").get_text().strip().encode("utf-8")
|
||||
)
|
||||
|
||||
return (
|
||||
f"https://www.linkedin.com/shareArticle?"
|
||||
f"mini=true&url={url}&title={title}&"
|
||||
f"summary={summary}&source={url}"
|
||||
)
|
||||
|
||||
|
||||
def create_share_links(content):
|
||||
if isinstance(content, contents.Static):
|
||||
return
|
||||
|
||||
title = article_title(content)
|
||||
url = article_url(content)
|
||||
summary = article_summary(content)
|
||||
hastags = twitter_hastags(content)
|
||||
via = twitter_via(content)
|
||||
main_title = BeautifulSoup(content.title, "html.parser").get_text().strip()
|
||||
|
||||
mail_link = 'mailto:?subject=%s&body=%s' % (title, url)
|
||||
diaspora_link = 'https://sharetodiaspora.github.io/?title=%s&url=%s' % (
|
||||
title, url)
|
||||
facebook_link = 'https://www.facebook.com/sharer/sharer.php?u=%s' % url
|
||||
twitter_link = 'https://twitter.com/intent/tweet?text=%s&url=%s%s%s' % (
|
||||
title, url, via, hastags)
|
||||
hackernews_link = 'https://news.ycombinator.com/submitlink?t=%s&u=%s' % (
|
||||
title, url)
|
||||
linkedin_link = 'https://www.linkedin.com/shareArticle?mini=true&url=%s&title=%s&summary=%s&source=%s' % ( # noqa
|
||||
url, title, summary, url
|
||||
)
|
||||
reddit_link = 'https://www.reddit.com/submit?url=%s&title=%s' % (
|
||||
url, title)
|
||||
try:
|
||||
sub_title = (
|
||||
" " + BeautifulSoup(content.subtitle, "html.parser").get_text().strip()
|
||||
)
|
||||
except AttributeError:
|
||||
sub_title = ""
|
||||
|
||||
content.share_post = {
|
||||
'diaspora': diaspora_link,
|
||||
'twitter': twitter_link,
|
||||
'facebook': facebook_link,
|
||||
'linkedin': linkedin_link,
|
||||
'hacker-news': hackernews_link,
|
||||
'email': mail_link,
|
||||
'reddit': reddit_link,
|
||||
}
|
||||
title = quote(f"{main_title}{sub_title}".encode("utf-8"))
|
||||
|
||||
site_url = content.settings["SITEURL"]
|
||||
url = quote(f"{site_url}/{content.url}".encode("utf-8"))
|
||||
|
||||
content.share_post = {}
|
||||
for func in _create_link_functions:
|
||||
key = func.__name__.replace("create_link_", "").replace("_", "-")
|
||||
content.share_post[key] = func(title, url, content)
|
||||
|
||||
|
||||
def run_plugin(generators):
|
||||
for generator in generators:
|
||||
if isinstance(generator, ArticlesGenerator):
|
||||
for article in generator.articles:
|
||||
share_post(article)
|
||||
create_share_links(article)
|
||||
for translation in article.translations:
|
||||
share_post(translation)
|
||||
create_share_links(translation)
|
||||
elif isinstance(generator, PagesGenerator):
|
||||
for page in generator.pages:
|
||||
share_post(page)
|
||||
create_share_links(page)
|
||||
|
||||
|
||||
def register():
|
||||
try:
|
||||
signals.all_generators_finalized.connect(run_plugin)
|
||||
except AttributeError:
|
||||
# NOTE: This results in #314 so shouldn't really be relied on
|
||||
# https://github.com/getpelican/pelican-plugins/issues/314
|
||||
signals.content_object_init.connect(share_post)
|
||||
signals.all_generators_finalized.connect(run_plugin)
|
||||
|
|
|
|||
8
pelican/plugins/share_post/test_data/article.md
Normal file
8
pelican/plugins/share_post/test_data/article.md
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
Title: Test post
|
||||
Date: 2021-02-01 13:00:00
|
||||
Category: test
|
||||
Tags: foo, bar, foobar
|
||||
Summary: I have a lot to test
|
||||
Series: test_series
|
||||
|
||||
Content
|
||||
65
pelican/plugins/share_post/test_share_post.py
Normal file
65
pelican/plugins/share_post/test_share_post.py
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
import os
|
||||
|
||||
from share_post import run_plugin
|
||||
|
||||
from pelican.generators import ArticlesGenerator
|
||||
from pelican.tests.support import get_context, get_settings
|
||||
|
||||
from . import share_post
|
||||
|
||||
|
||||
def test_share_post(tmp_folder):
|
||||
base_path = os.path.dirname(os.path.abspath(__file__))
|
||||
test_data_path = os.path.join(base_path, "test_data")
|
||||
|
||||
share_post.register()
|
||||
|
||||
settings = get_settings()
|
||||
context = get_context(settings)
|
||||
|
||||
generator = ArticlesGenerator(
|
||||
context=context,
|
||||
settings=settings,
|
||||
path=test_data_path,
|
||||
theme=settings["THEME"],
|
||||
output_path=tmp_folder,
|
||||
)
|
||||
generator.generate_context()
|
||||
|
||||
run_plugin([generator])
|
||||
|
||||
share_links = generator.articles[0].share_post
|
||||
|
||||
assert (
|
||||
share_links["diaspora"]
|
||||
== "https://sharetodiaspora.github.io/?title=Test%20post&url=/test-post.html"
|
||||
)
|
||||
|
||||
assert share_links["twitter"] == (
|
||||
"https://twitter.com/intent/tweet?text=Test%20post"
|
||||
"&url=/test-post.html&hashtags=foo,bar,foobar"
|
||||
)
|
||||
|
||||
assert (
|
||||
share_links["facebook"]
|
||||
== "https://www.facebook.com/sharer/sharer.php?u=/test-post.html"
|
||||
)
|
||||
assert share_links["linkedin"] == (
|
||||
"https://www.linkedin.com/shareArticle?"
|
||||
"mini=true&url=/test-post.html&title=Test%20post&"
|
||||
"summary=I%20have%20a%20lot%20to%20test&source=/test-post.html"
|
||||
)
|
||||
|
||||
assert (
|
||||
share_links["hacker-news"]
|
||||
== "https://news.ycombinator.com/submitlink?t=Test%20post&u=/test-post.html"
|
||||
)
|
||||
|
||||
assert (
|
||||
share_links["email"] == "mailto:?subject=Test%20post&body=/test-post.html"
|
||||
)
|
||||
|
||||
assert (
|
||||
share_links["reddit"]
|
||||
== "https://www.reddit.com/submit?url=/test-post.html&title=Test%20post"
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue