From 5c70b46572f903eb09e8ab8972e7ce4123088272 Mon Sep 17 00:00:00 2001 From: Talha Mansoor Date: Mon, 20 Jan 2014 23:21:56 +0500 Subject: [PATCH 01/16] Add plugin to add share URLs to article --- README.md | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++ __init__.py | 1 + share_post.py | 58 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+) create mode 100644 README.md create mode 100644 __init__.py create mode 100644 share_post.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..9646ef5 --- /dev/null +++ b/README.md @@ -0,0 +1,65 @@ +Share Post +========== + +A Pelican plugin to create share URLs of article + +Copyright (c) Talha Mansoor + +Author | Talha Mansoor +----------------|----- +Author Email | talha131@gmail.com +Author Homepage | http://onCrashReboot.com +Github Account | https://github.com/talha131 + +Why do you need it? +=================== + +Almost all website have share widgets to let readers share posts on social +networks. Most of these widgets are used by vendors for online tracking. These +widgets are also visual which quite often become a distraction and negatively +affect readers attention. + +`share_post` creates old school URLs for some popular sites which your theme +can use. These links do not have the ability to track the users. They can also +be unobtrusive depending on how Pelican theme uses them. + +Requirements +============ + +`share_post` requires BeautifulSoup + +```bash +pip install beautifulsoup4 +``` + +How to Use +========== + +`share_post` adds a dictionary attribute to `article` which can be accessed via +`article.share_post`. Keys of the dictionary are as follows, + +1. `facebook` +1. `google-plus` +1. `email` +1. `twitter` + +Template Example +================ + +```python +{% if article.share_post and article.status != 'draft' %} +
+

+ Share on: + Twitter + ❄ + Facebook + ❄ + Google+ + ❄ + Email +

+
+{% endif %} +``` + diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..428e32a --- /dev/null +++ b/__init__.py @@ -0,0 +1 @@ +from .share_post import * diff --git a/share_post.py b/share_post.py new file mode 100644 index 0000000..f4fc7c3 --- /dev/null +++ b/share_post.py @@ -0,0 +1,58 @@ +""" +Share Post +========== + +This plugin adds share URL to article. These links are textual which means no +online tracking of your readers. +""" + +from bs4 import BeautifulSoup +try: + from urllib.parse import quote +except ImportError: + from urllib import quote +from pelican import signals, contents + + +def article_title(content): + main_title = BeautifulSoup(content.title, 'html.parser').prettify().strip() + sub_title = '' + if hasattr(content, 'subtitle'): + sub_title = BeautifulSoup(content.subtitle, 'html.parser').prettify().strip() + return quote(('%s %s' % (main_title, sub_title)).encode('utf-8')) + + +def article_url(content): + site_url = content.settings['SITEURL'] + return quote(('%s/%s' % (site_url, content.url)).encode('utf-8')) + + +def article_summary(content): + return quote(content.summary.encode('utf-8')) + + +def share_post(content): + if isinstance(content, contents.Static): + return + title = article_title(content) + url = article_url(content) + summary = article_summary(content) + + tweet = '%s %s' % (title, url) + facebook_link = 'http://www.facebook.com/sharer/sharer.php?s=100' \ + '&p[url]=%s&p[images][0]=&p[title]=%s&p[summary]=%s' \ + % (url, title, summary) + gplus_link = 'https://plus.google.com/share?url=%s' % url + twitter_link = 'http://twitter.com/home?status=%s' % tweet + mail_link = 'mailto:?subject=%s&body=%s' % (title, url) + + share_links = {'twitter': twitter_link, + 'facebook': facebook_link, + 'google-plus': gplus_link, + 'email': mail_link + } + content.share_post = share_links + + +def register(): + signals.content_object_init.connect(share_post) From 9052e10aa71a4c9d91e13aebf0bbda71459aa4b3 Mon Sep 17 00:00:00 2001 From: Kernc Date: Mon, 22 Dec 2014 23:31:41 +0100 Subject: [PATCH 02/16] Fix share_post plugin Firstly, the implemented services only accept unmarked text, so `get_text()` instead of `prettify()` is called. Secondly, `&` is properly escaped ampersand in href URLs. --- share_post.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/share_post.py b/share_post.py index f4fc7c3..16f20dc 100644 --- a/share_post.py +++ b/share_post.py @@ -15,11 +15,11 @@ from pelican import signals, contents def article_title(content): - main_title = BeautifulSoup(content.title, 'html.parser').prettify().strip() + main_title = BeautifulSoup(content.title, 'html.parser').get_text().strip() sub_title = '' if hasattr(content, 'subtitle'): - sub_title = BeautifulSoup(content.subtitle, 'html.parser').prettify().strip() - return quote(('%s %s' % (main_title, sub_title)).encode('utf-8')) + sub_title = ' ' + BeautifulSoup(content.subtitle, 'html.parser').get_text().strip() + return quote(('%s%s' % (main_title, sub_title)).encode('utf-8')) def article_url(content): @@ -28,7 +28,7 @@ def article_url(content): def article_summary(content): - return quote(content.summary.encode('utf-8')) + return quote(BeautifulSoup(content.summary, 'html.parser').get_text().strip().encode('utf-8')) def share_post(content): @@ -38,13 +38,11 @@ def share_post(content): url = article_url(content) summary = article_summary(content) - tweet = '%s %s' % (title, url) - facebook_link = 'http://www.facebook.com/sharer/sharer.php?s=100' \ - '&p[url]=%s&p[images][0]=&p[title]=%s&p[summary]=%s' \ - % (url, title, summary) + tweet = quote(('%s %s' % (title, url)).encode('utf-8')) + facebook_link = 'http://www.facebook.com/sharer/sharer.php?s=100&p%%5Burl%%5D=%s' % url gplus_link = 'https://plus.google.com/share?url=%s' % url twitter_link = 'http://twitter.com/home?status=%s' % tweet - mail_link = 'mailto:?subject=%s&body=%s' % (title, url) + mail_link = 'mailto:?subject=%s&body=%s' % (title, url) share_links = {'twitter': twitter_link, 'facebook': facebook_link, From f510f7f9e62e70bde36ce45e1a26703b181b9d82 Mon Sep 17 00:00:00 2001 From: Giel van Schijndel Date: Sat, 3 Jan 2015 22:23:58 +0100 Subject: [PATCH 03/16] share_post: prevent double-quoting in Twitter URL Both parameters being concatenated have already been quoted: don't do that twice. Do make sure to quote the separating space though. --- share_post.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share_post.py b/share_post.py index 16f20dc..db99d5a 100644 --- a/share_post.py +++ b/share_post.py @@ -38,7 +38,7 @@ def share_post(content): url = article_url(content) summary = article_summary(content) - tweet = quote(('%s %s' % (title, url)).encode('utf-8')) + tweet = ('%s%s%s' % (title, quote(' '), url)).encode('utf-8') facebook_link = 'http://www.facebook.com/sharer/sharer.php?s=100&p%%5Burl%%5D=%s' % url gplus_link = 'https://plus.google.com/share?url=%s' % url twitter_link = 'http://twitter.com/home?status=%s' % tweet From bf5a1ecc6b9563e67c6dd06834f9d8292c6a32af Mon Sep 17 00:00:00 2001 From: Giel van Schijndel Date: Sat, 3 Jan 2015 22:24:53 +0100 Subject: [PATCH 04/16] share_post: add share-to-Diaspora* support This uses the sharetodiaspora.github.io HTML5 posting app, necessary due to Diaspora*'s multi-homed nature. --- README.md | 2 ++ share_post.py | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9646ef5..0edd3e2 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,8 @@ Template Example

Share on: + Diaspora* + ❄ TwitterFacebook diff --git a/share_post.py b/share_post.py index db99d5a..b8c1b6a 100644 --- a/share_post.py +++ b/share_post.py @@ -39,12 +39,15 @@ def share_post(content): summary = article_summary(content) tweet = ('%s%s%s' % (title, quote(' '), url)).encode('utf-8') + diaspora_link = 'https://sharetodiaspora.github.io/?title=%s&url=%s' % (title, url) facebook_link = 'http://www.facebook.com/sharer/sharer.php?s=100&p%%5Burl%%5D=%s' % url gplus_link = 'https://plus.google.com/share?url=%s' % url twitter_link = 'http://twitter.com/home?status=%s' % tweet mail_link = 'mailto:?subject=%s&body=%s' % (title, url) - share_links = {'twitter': twitter_link, + share_links = { + 'diaspora': diaspora_link, + 'twitter': twitter_link, 'facebook': facebook_link, 'google-plus': gplus_link, 'email': mail_link From d9a96f1b9b5a80e4490e3f9909ac196a2831ed49 Mon Sep 17 00:00:00 2001 From: "niccolasmendoza@gmail.com" Date: Fri, 12 Jun 2015 17:00:33 -0300 Subject: [PATCH 05/16] add share-to-linkedin support --- share_post.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/share_post.py b/share_post.py index b8c1b6a..a54d454 100644 --- a/share_post.py +++ b/share_post.py @@ -43,6 +43,10 @@ def share_post(content): facebook_link = 'http://www.facebook.com/sharer/sharer.php?s=100&p%%5Burl%%5D=%s' % url gplus_link = 'https://plus.google.com/share?url=%s' % url twitter_link = 'http://twitter.com/home?status=%s' % tweet + linkedin_link = 'https://www.linkedin.com/shareArticle?mini=true&url=%s&title=%s&summary=%s&source=%s' % ( + url, title, summary, url + ) + mail_link = 'mailto:?subject=%s&body=%s' % (title, url) share_links = { @@ -50,6 +54,7 @@ def share_post(content): 'twitter': twitter_link, 'facebook': facebook_link, 'google-plus': gplus_link, + 'linkedin': linkedin_link, 'email': mail_link } content.share_post = share_links @@ -57,3 +62,5 @@ def share_post(content): def register(): signals.content_object_init.connect(share_post) + + From 5f6b44a97358192138b936f60ad14c14dfb26429 Mon Sep 17 00:00:00 2001 From: Kernc Date: Sun, 1 Feb 2015 02:54:16 +0100 Subject: [PATCH 06/16] share_post: Don't read summary as it's not used anywhere Related to issue #314. --- share_post.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/share_post.py b/share_post.py index a54d454..a4edc2e 100644 --- a/share_post.py +++ b/share_post.py @@ -27,16 +27,11 @@ def article_url(content): return quote(('%s/%s' % (site_url, content.url)).encode('utf-8')) -def article_summary(content): - return quote(BeautifulSoup(content.summary, 'html.parser').get_text().strip().encode('utf-8')) - - def share_post(content): if isinstance(content, contents.Static): return title = article_title(content) url = article_url(content) - summary = article_summary(content) tweet = ('%s%s%s' % (title, quote(' '), url)).encode('utf-8') diaspora_link = 'https://sharetodiaspora.github.io/?title=%s&url=%s' % (title, url) From c4351fe4532b8216e5e6b8ba9cd99d94cdf0968f Mon Sep 17 00:00:00 2001 From: David Marquis Date: Sun, 13 Sep 2015 13:12:42 -0400 Subject: [PATCH 07/16] Revert "share_post: Don't read summary as it's not used anywhere" This reverts commit 7c097d6699cff6aef0a08336cf5914f64e2bf2bd. Closes #549 --- share_post.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/share_post.py b/share_post.py index a4edc2e..a54d454 100644 --- a/share_post.py +++ b/share_post.py @@ -27,11 +27,16 @@ def article_url(content): return quote(('%s/%s' % (site_url, content.url)).encode('utf-8')) +def article_summary(content): + return quote(BeautifulSoup(content.summary, 'html.parser').get_text().strip().encode('utf-8')) + + def share_post(content): if isinstance(content, contents.Static): return title = article_title(content) url = article_url(content) + summary = article_summary(content) tweet = ('%s%s%s' % (title, quote(' '), url)).encode('utf-8') diaspora_link = 'https://sharetodiaspora.github.io/?title=%s&url=%s' % (title, url) From 82095658644487bc5487226aa775958701aa4bcb Mon Sep 17 00:00:00 2001 From: Kernc Date: Mon, 9 Nov 2015 00:09:00 +0100 Subject: [PATCH 08/16] share_post: fire on all_generators_finalized so that links resolve Fixes #577. Closes #598. Ref: * https://github.com/getpelican/pelican-plugins/issues/577 * https://github.com/getpelican/pelican-plugins/pull/556#issuecomment-140250725 --- share_post.py | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/share_post.py b/share_post.py index a54d454..e1b975e 100644 --- a/share_post.py +++ b/share_post.py @@ -12,6 +12,7 @@ try: except ImportError: from urllib import quote from pelican import signals, contents +from pelican.generators import ArticlesGenerator, PagesGenerator def article_title(content): @@ -40,7 +41,7 @@ def share_post(content): tweet = ('%s%s%s' % (title, quote(' '), url)).encode('utf-8') diaspora_link = 'https://sharetodiaspora.github.io/?title=%s&url=%s' % (title, url) - facebook_link = 'http://www.facebook.com/sharer/sharer.php?s=100&p%%5Burl%%5D=%s' % url + facebook_link = 'http://www.facebook.com/sharer/sharer.php?u=%s' % url gplus_link = 'https://plus.google.com/share?url=%s' % url twitter_link = 'http://twitter.com/home?status=%s' % tweet linkedin_link = 'https://www.linkedin.com/shareArticle?mini=true&url=%s&title=%s&summary=%s&source=%s' % ( @@ -54,13 +55,27 @@ def share_post(content): 'twitter': twitter_link, 'facebook': facebook_link, 'google-plus': gplus_link, - 'linkedin': linkedin_link, + 'linkedin': linkedin_link, 'email': mail_link } content.share_post = share_links +def run_plugin(generators): + for generator in generators: + if isinstance(generator, ArticlesGenerator): + for article in generator.articles: + share_post(article) + elif isinstance(generator, PagesGenerator): + for page in generator.pages: + share_post(page) + + def register(): - signals.content_object_init.connect(share_post) - + 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) From 1409e56e1d8259efe15b145db2c9fc1b907834d0 Mon Sep 17 00:00:00 2001 From: Gustavo Furtado Date: Wed, 7 Jun 2017 18:55:41 -0300 Subject: [PATCH 09/16] Update twitter sharing link to 'twitter.com/intent' --- share_post.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/share_post.py b/share_post.py index e1b975e..3e9299f 100644 --- a/share_post.py +++ b/share_post.py @@ -39,11 +39,10 @@ def share_post(content): url = article_url(content) summary = article_summary(content) - tweet = ('%s%s%s' % (title, quote(' '), url)).encode('utf-8') diaspora_link = 'https://sharetodiaspora.github.io/?title=%s&url=%s' % (title, url) facebook_link = 'http://www.facebook.com/sharer/sharer.php?u=%s' % url gplus_link = 'https://plus.google.com/share?url=%s' % url - twitter_link = 'http://twitter.com/home?status=%s' % tweet + twitter_link = 'https://twitter.com/intent/tweet?text=%s&url=%s' % (title, url) linkedin_link = 'https://www.linkedin.com/shareArticle?mini=true&url=%s&title=%s&summary=%s&source=%s' % ( url, title, summary, url ) @@ -78,4 +77,3 @@ def register(): # 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) - From 64f726aa66d3d8bbfe550c0996efc02d028e35af Mon Sep 17 00:00:00 2001 From: Jonathan DEKHTIAR Date: Mon, 23 Oct 2017 15:47:34 +0200 Subject: [PATCH 10/16] Documentation Updated --- README.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0edd3e2..351555c 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,9 @@ Author Email | talha131@gmail.com Author Homepage | http://onCrashReboot.com Github Account | https://github.com/talha131 +## Contributors: +* [Jonathan DEKHTIAR](https://github.com/DEKHTIARJonathan) - contact@jonathandekhtiar.eu + Why do you need it? =================== @@ -39,9 +42,12 @@ How to Use `article.share_post`. Keys of the dictionary are as follows, 1. `facebook` -1. `google-plus` -1. `email` -1. `twitter` +2. `google-plus` +3. `email` +4. `twitter` +5. `diaspora` +6. `linkedin` +7. `hacker-news` Template Example ================ @@ -59,6 +65,10 @@ Template Example ❄ Google+ ❄ + LinkedIn + ❄ + HackerNews + ❄ Email

From 5b64414f7943d6cf29ed9109acbdf89b6a4a7ab3 Mon Sep 17 00:00:00 2001 From: Jonathan DEKHTIAR Date: Mon, 23 Oct 2017 15:48:18 +0200 Subject: [PATCH 11/16] Share with Hacker News Added + Code Refactored --- share_post.py | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/share_post.py b/share_post.py index 3e9299f..3b8546d 100644 --- a/share_post.py +++ b/share_post.py @@ -35,29 +35,30 @@ def article_summary(content): def share_post(content): if isinstance(content, contents.Static): return - title = article_title(content) - url = article_url(content) + + title = article_title(content) + url = article_url(content) summary = article_summary(content) - diaspora_link = 'https://sharetodiaspora.github.io/?title=%s&url=%s' % (title, url) - facebook_link = 'http://www.facebook.com/sharer/sharer.php?u=%s' % url - gplus_link = 'https://plus.google.com/share?url=%s' % url - twitter_link = 'https://twitter.com/intent/tweet?text=%s&url=%s' % (title, url) - linkedin_link = 'https://www.linkedin.com/shareArticle?mini=true&url=%s&title=%s&summary=%s&source=%s' % ( + mail_link = 'mailto:?subject=%s&body=%s' % (title, url) + diaspora_link = 'https://sharetodiaspora.github.io/?title=%s&url=%s' % (title, url) + facebook_link = 'http://www.facebook.com/sharer/sharer.php?u=%s' % url + gplus_link = 'https://plus.google.com/share?url=%s' % url + twitter_link = 'https://twitter.com/intent/tweet?text=%s&url=%s' % (title, url) + 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' % ( url, title, summary, url ) - mail_link = 'mailto:?subject=%s&body=%s' % (title, url) - - share_links = { - 'diaspora': diaspora_link, - 'twitter': twitter_link, - 'facebook': facebook_link, - 'google-plus': gplus_link, - 'linkedin': linkedin_link, - 'email': mail_link - } - content.share_post = share_links + content.share_post = { + 'diaspora' : diaspora_link, + 'twitter' : twitter_link, + 'facebook' : facebook_link, + 'google-plus': gplus_link, + 'linkedin' : linkedin_link, + 'hacker-news': hackernews_link, + 'email' : mail_link + } def run_plugin(generators): From de3397633cf9d4ed7c02441b066f5852fcced6ed Mon Sep 17 00:00:00 2001 From: Paolo Melchiorre Date: Fri, 14 Sep 2018 15:33:17 +0200 Subject: [PATCH 12/16] Improve translations and facebook/twitter links --- share_post.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/share_post.py b/share_post.py index 3b8546d..28d0582 100644 --- a/share_post.py +++ b/share_post.py @@ -32,6 +32,20 @@ def article_summary(content): return quote(BeautifulSoup(content.summary, 'html.parser').get_text().strip().encode('utf-8')) +def twitter_hastags(content): + tags = getattr(content, 'tags', []) + category = getattr(content, 'category', '') + if category: + tags.append(category) + hashtags = ','.join((tag.slug for tag in tags)) + return '' if not hashtags else '&hashtags=%s' % hashtags + + +def twitter_via(content): + twitter_username = content.settings.get('TWITTER_USERNAME', '') + return '' if not twitter_username else '&via=%s' % twitter_username + + def share_post(content): if isinstance(content, contents.Static): return @@ -39,12 +53,14 @@ def share_post(content): title = article_title(content) url = article_url(content) summary = article_summary(content) + hastags = twitter_hastags(content) + via = twitter_via(content) mail_link = 'mailto:?subject=%s&body=%s' % (title, url) diaspora_link = 'https://sharetodiaspora.github.io/?title=%s&url=%s' % (title, url) - facebook_link = 'http://www.facebook.com/sharer/sharer.php?u=%s' % url + facebook_link = 'https://www.facebook.com/sharer/sharer.php?u=%s' % url gplus_link = 'https://plus.google.com/share?url=%s' % url - twitter_link = 'https://twitter.com/intent/tweet?text=%s&url=%s' % (title, 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' % ( url, title, summary, url @@ -66,6 +82,8 @@ def run_plugin(generators): if isinstance(generator, ArticlesGenerator): for article in generator.articles: share_post(article) + for translation in article.translations: + share_post(translation) elif isinstance(generator, PagesGenerator): for page in generator.pages: share_post(page) From 13e2184d82077c60d9cb460978bdf3d177b6c249 Mon Sep 17 00:00:00 2001 From: Patrick <4002194+askpatrickw@users.noreply.github.com> Date: Tue, 16 Apr 2019 09:42:15 -0700 Subject: [PATCH 13/16] share_post: Remove Google Plus (#1108) * Remove Google Plus --- README.md | 13 +++++-------- share_post.py | 2 -- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 351555c..e2ccd82 100644 --- a/README.md +++ b/README.md @@ -42,12 +42,11 @@ How to Use `article.share_post`. Keys of the dictionary are as follows, 1. `facebook` -2. `google-plus` -3. `email` -4. `twitter` -5. `diaspora` -6. `linkedin` -7. `hacker-news` +1. `email` +1. `twitter` +1. `diaspora` +1. `linkedin` +1. `hacker-news` Template Example ================ @@ -63,8 +62,6 @@ Template Example ❄ Facebook ❄ - Google+ - ❄ LinkedInHackerNews diff --git a/share_post.py b/share_post.py index 28d0582..960e4b3 100644 --- a/share_post.py +++ b/share_post.py @@ -59,7 +59,6 @@ def share_post(content): 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 - gplus_link = 'https://plus.google.com/share?url=%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' % ( @@ -70,7 +69,6 @@ def share_post(content): 'diaspora' : diaspora_link, 'twitter' : twitter_link, 'facebook' : facebook_link, - 'google-plus': gplus_link, 'linkedin' : linkedin_link, 'hacker-news': hackernews_link, 'email' : mail_link From d1c511e0384e79b153c37b438ba357b24cb4db73 Mon Sep 17 00:00:00 2001 From: Paolo Melchiorre Date: Wed, 17 Apr 2019 08:46:36 +0200 Subject: [PATCH 14/16] Fix #1121 Add reddit to share post plugin --- README.md | 57 ++++++++++++++++++++++++++------------------------- __init__.py | 2 +- share_post.py | 48 +++++++++++++++++++++++-------------------- 3 files changed, 56 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index e2ccd82..c1651b3 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ -Share Post -========== +# Share Post A Pelican plugin to create share URLs of article +# Author + Copyright (c) Talha Mansoor Author | Talha Mansoor @@ -11,11 +12,12 @@ Author Email | talha131@gmail.com Author Homepage | http://onCrashReboot.com Github Account | https://github.com/talha131 -## Contributors: -* [Jonathan DEKHTIAR](https://github.com/DEKHTIARJonathan) - contact@jonathandekhtiar.eu +### Contributors -Why do you need it? -=================== +* [Jonathan DEKHTIAR](https://github.com/DEKHTIARJonathan) - contact@jonathandekhtiar.eu +* [Paolo Melchiorre](https://github.com/pauloxnet) - [www.paulox.net](https://www.paulox.net/) + +## Why do you need it? Almost all website have share widgets to let readers share posts on social networks. Most of these widgets are used by vendors for online tracking. These @@ -26,8 +28,7 @@ affect readers attention. can use. These links do not have the ability to track the users. They can also be unobtrusive depending on how Pelican theme uses them. -Requirements -============ +## Requirements `share_post` requires BeautifulSoup @@ -35,8 +36,7 @@ Requirements pip install beautifulsoup4 ``` -How to Use -========== +## How to Use `share_post` adds a dictionary attribute to `article` which can be accessed via `article.share_post`. Keys of the dictionary are as follows, @@ -47,28 +47,29 @@ How to Use 1. `diaspora` 1. `linkedin` 1. `hacker-news` +1. `reddit` -Template Example -================ +## Template Example -```python +```html {% if article.share_post and article.status != 'draft' %}
-

- Share on: - Diaspora* - ❄ - Twitter - ❄ - Facebook - ❄ - LinkedIn - ❄ - HackerNews - ❄ - Email -

+

+ Share on: + Diaspora* + ❄ + Twitter + ❄ + Facebook + ❄ + LinkedIn + ❄ + HackerNews + ❄ + Email + ❄ + Reddit +

{% endif %} ``` - diff --git a/__init__.py b/__init__.py index 428e32a..4185ce8 100644 --- a/__init__.py +++ b/__init__.py @@ -1 +1 @@ -from .share_post import * +from .share_post import * # noqa diff --git a/share_post.py b/share_post.py index 960e4b3..d2a3c64 100644 --- a/share_post.py +++ b/share_post.py @@ -1,25 +1,26 @@ """ -Share Post -========== +Share Post plugin. This plugin adds share URL to article. These links are textual which means no online tracking of your readers. """ 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 -from pelican import signals, contents -from pelican.generators import ArticlesGenerator, PagesGenerator 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() + sub_title = ' ' + BeautifulSoup(content.subtitle, 'html.parser').get_text().strip() # noqa return quote(('%s%s' % (main_title, sub_title)).encode('utf-8')) @@ -29,14 +30,11 @@ def article_url(content): def article_summary(content): - return quote(BeautifulSoup(content.summary, 'html.parser').get_text().strip().encode('utf-8')) + return quote(BeautifulSoup(content.summary, 'html.parser').get_text().strip().encode('utf-8')) # noqa def twitter_hastags(content): tags = getattr(content, 'tags', []) - category = getattr(content, 'category', '') - if category: - tags.append(category) hashtags = ','.join((tag.slug for tag in tags)) return '' if not hashtags else '&hashtags=%s' % hashtags @@ -50,28 +48,34 @@ def share_post(content): if isinstance(content, contents.Static): return - title = article_title(content) - url = article_url(content) + title = article_title(content) + url = article_url(content) summary = article_summary(content) hastags = twitter_hastags(content) via = twitter_via(content) - 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' % ( + 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) content.share_post = { - 'diaspora' : diaspora_link, - 'twitter' : twitter_link, - 'facebook' : facebook_link, - 'linkedin' : linkedin_link, + 'diaspora': diaspora_link, + 'twitter': twitter_link, + 'facebook': facebook_link, + 'linkedin': linkedin_link, 'hacker-news': hackernews_link, - 'email' : mail_link + 'email': mail_link, + 'reddit': reddit_link, } From 32c4488fb7ab32084b903b91de79d869913f4ca0 Mon Sep 17 00:00:00 2001 From: Leonardo Giordani Date: Fri, 12 Mar 2021 08:33:32 +0000 Subject: [PATCH 15/16] Convert to namespace plugin filesystem layout --- __init__.py => pelican/plugins/share_post/__init__.py | 0 share_post.py => pelican/plugins/share_post/share_post.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename __init__.py => pelican/plugins/share_post/__init__.py (100%) rename share_post.py => pelican/plugins/share_post/share_post.py (100%) diff --git a/__init__.py b/pelican/plugins/share_post/__init__.py similarity index 100% rename from __init__.py rename to pelican/plugins/share_post/__init__.py diff --git a/share_post.py b/pelican/plugins/share_post/share_post.py similarity index 100% rename from share_post.py rename to pelican/plugins/share_post/share_post.py From 5b7dbc440c343b19816751b68e147249b567bf04 Mon Sep 17 00:00:00 2001 From: Leonardo Giordani Date: Fri, 12 Mar 2021 16:34:46 +0000 Subject: [PATCH 16/16] Modernize code and add a test --- .editorconfig | 15 ++ .github/workflows/main.yml | 104 ++++++++++++ .gitignore | 1 + .pre-commit-config.yaml | 31 ++++ CONTRIBUTING.md | 9 ++ README.md | 105 ++++++------ RELEASE.md | 3 + pelican/plugins/share_post/conftest.py | 9 ++ pelican/plugins/share_post/share_post.py | 149 ++++++++++-------- .../plugins/share_post/test_data/article.md | 8 + pelican/plugins/share_post/test_share_post.py | 65 ++++++++ pyproject.toml | 73 +++++++++ tasks.py | 79 ++++++++++ tox.ini | 3 + 14 files changed, 545 insertions(+), 109 deletions(-) create mode 100644 .editorconfig create mode 100644 .github/workflows/main.yml create mode 100644 .gitignore create mode 100644 .pre-commit-config.yaml create mode 100644 CONTRIBUTING.md create mode 100644 RELEASE.md create mode 100644 pelican/plugins/share_post/conftest.py create mode 100644 pelican/plugins/share_post/test_data/article.md create mode 100644 pelican/plugins/share_post/test_share_post.py create mode 100644 pyproject.toml create mode 100644 tasks.py create mode 100644 tox.ini diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..862c1e1 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.py] +max_line_length = 88 + +[*.yml] +indent_size = 2 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..c5b40b3 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,104 @@ +name: build + +on: [push, pull_request] + +env: + PYTEST_ADDOPTS: "--color=yes" + +jobs: + test: + name: Test - ${{ matrix.python-version }} + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [3.6, 3.7, 3.8, 3.9] + + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Set up Pip cache + uses: actions/cache@v2 + 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@v2 + 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 + + + lint: + name: Lint + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: "3.x" + - name: Set Poetry cache + uses: actions/cache@v2 + 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 + + + deploy: + name: Deploy + environment: Deployment + needs: [test, lint] + runs-on: ubuntu-latest + if: ${{ github.ref=='refs/heads/main' && github.event_name!='pull_request' }} + + steps: + - uses: actions/checkout@v2 + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: "3.x" + - 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)" + - name: Publish + if: ${{ steps.check_release.outputs.release=='' }} + 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 githubrelease + poetry publish -u __token__ -p $PYPI_PASSWORD diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c04bc49 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +poetry.lock diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..3338bab --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,31 @@ +# See https://pre-commit.com/hooks.html for info on hooks +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v3.4.0 + hooks: + - id: check-added-large-files + - id: check-ast + - id: check-case-conflict + - id: check-toml + - id: check-yaml + - id: debug-statements + - id: detect-private-key + - id: end-of-file-fixer + - id: trailing-whitespace + + - repo: https://github.com/psf/black + rev: 19.10b0 + hooks: + - id: black + + - repo: https://gitlab.com/pycqa/flake8 + rev: 3.9.0 + hooks: + - id: flake8 + args: [--max-line-length=88] + language_version: python3.7 + + - repo: https://github.com/PyCQA/isort + rev: 5.7.0 + hooks: + - id: isort diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..f96daf4 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,9 @@ +Contributing +============ + +Contributions are welcome and much appreciated. Every little bit helps. You can contribute by improving the documentation, adding missing features, and fixing bugs. You can also help out by reviewing and commenting on [existing issues][]. + +To start contributing to this plugin, review the [Contributing to Pelican][] documentation, beginning with the **Contributing Code** section. + +[existing issues]: https://github.com/pelican-plugins/share-post/issues +[Contributing to Pelican]: https://docs.getpelican.com/en/latest/contribute.html diff --git a/README.md b/README.md index c1651b3..926e737 100644 --- a/README.md +++ b/README.md @@ -1,75 +1,86 @@ -# Share Post +# Share Post: A Plugin for Pelican -A Pelican plugin to create share URLs of article +[![Build Status](https://img.shields.io/github/workflow/status/pelican-plugins/share-post/build)](https://github.com/pelican-plugins/share-post/actions) +[![PyPI Version](https://img.shields.io/pypi/v/pelican-share-post)](https://pypi.org/project/pelican-share-post/) +![License](https://img.shields.io/pypi/l/pelican-share-post?color=blue) -# Author +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. -Copyright (c) Talha Mansoor +Many web sites have share widgets to let readers share posts on social networks. Most of these widgets are used by vendors for online tracking. These widgets can also be visually-distracting and negatively affect readers’ attention. -Author | Talha Mansoor -----------------|----- -Author Email | talha131@gmail.com -Author Homepage | http://onCrashReboot.com -Github Account | https://github.com/talha131 +Share Post creates old-school URLs for some popular sites which your theme can use. These links do not have the ability to track site visitors. They can also be unobtrusive depending on how Pelican theme uses them. -### Contributors -* [Jonathan DEKHTIAR](https://github.com/DEKHTIARJonathan) - contact@jonathandekhtiar.eu -* [Paolo Melchiorre](https://github.com/pauloxnet) - [www.paulox.net](https://www.paulox.net/) +Installation +------------ -## Why do you need it? +This plugin can be installed via: -Almost all website have share widgets to let readers share posts on social -networks. Most of these widgets are used by vendors for online tracking. These -widgets are also visual which quite often become a distraction and negatively -affect readers attention. + python -m pip install pelican-share-post -`share_post` creates old school URLs for some popular sites which your theme -can use. These links do not have the ability to track the users. They can also -be unobtrusive depending on how Pelican theme uses them. +Usage +----- -## Requirements +This plugin adds to each Pelican article a dictionary of URLs that, when followed, allows the reader to easily share the article via specific channels. When activated, the plugin adds the attribute `share_post` to each article with the following format: -`share_post` requires BeautifulSoup - -```bash -pip install beautifulsoup4 +``` python +article.share_post = { + "facebook": "", + "email": "", + "twitter": "", + "diaspora": "", + "linkedin": "", + "hacker-news": "", + "reddit": "", +} ``` -## How to Use +You can then access those variables in your template. For example: -`share_post` adds a dictionary attribute to `article` which can be accessed via -`article.share_post`. Keys of the dictionary are as follows, - -1. `facebook` -1. `email` -1. `twitter` -1. `diaspora` -1. `linkedin` -1. `hacker-news` -1. `reddit` - -## Template Example - -```html +``` html+jinja {% if article.share_post and article.status != 'draft' %}

Share on: - Diaspora* + Diaspora* ❄ - Twitter + Twitter ❄ - Facebook + Facebook ❄ - LinkedIn + LinkedIn ❄ - HackerNews + HackerNews ❄ - Email + Email ❄ - Reddit + Reddit

{% endif %} ``` + +Contributing +------------ + +Contributions are welcome and much appreciated. Every little bit helps. You can contribute by improving the documentation, adding missing features, and fixing bugs. You can also help out by reviewing and commenting on [existing issues][]. + +To start contributing to this plugin, review the [Contributing to Pelican][] documentation, beginning with the **Contributing Code** section. + +[existing issues]: https://github.com/pelican-plugins/share-post/issues +[Contributing to Pelican]: https://docs.getpelican.com/en/latest/contribute.html + + +Contributors +------------ + +* [Talha Mansoor](https://www.oncrashreboot.com) - talha131@gmail.com +* [Jonathan DEKHTIAR](https://github.com/DEKHTIARJonathan) - contact@jonathandekhtiar.eu +* [Justin Mayer](https://justinmayer.com) +* [Leonardo Giordani](https://www.thedigitalcatonline.com) + + +License +------- + +This project is licensed under the MIT license. diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 0000000..9b81d15 --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,3 @@ +Release type: major + +Initial release as namespace plugin diff --git a/pelican/plugins/share_post/conftest.py b/pelican/plugins/share_post/conftest.py new file mode 100644 index 0000000..57affce --- /dev/null +++ b/pelican/plugins/share_post/conftest.py @@ -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 diff --git a/pelican/plugins/share_post/share_post.py b/pelican/plugins/share_post/share_post.py index d2a3c64..f30b088 100644 --- a/pelican/plugins/share_post/share_post.py +++ b/pelican/plugins/share_post/share_post.py @@ -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 + +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) diff --git a/pelican/plugins/share_post/test_data/article.md b/pelican/plugins/share_post/test_data/article.md new file mode 100644 index 0000000..8c302b2 --- /dev/null +++ b/pelican/plugins/share_post/test_data/article.md @@ -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 diff --git a/pelican/plugins/share_post/test_share_post.py b/pelican/plugins/share_post/test_share_post.py new file mode 100644 index 0000000..a35fc59 --- /dev/null +++ b/pelican/plugins/share_post/test_share_post.py @@ -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" + ) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..4a11803 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,73 @@ +[tool.poetry] +name = "pelican-share-post" +version = "0.0.0" +description = "A Pelican plugin to create share URLs of article" +authors = ["Talha Mansoor "] +license = "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", + "Operating System :: OS Independent", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Software Development :: Libraries :: Python Modules", +] + +[tool.poetry.urls] +"Funding" = "https://donate.getpelican.com/" +"Issue Tracker" = "https://github.com/pelican-plugins/share-post/issues" + +[tool.poetry.dependencies] +python = "^3.6" +pelican = "^4.5" +markdown = {version = "^3.2.2", optional = true} +beautifulsoup4 = "^4.9.3" + +[tool.poetry.dev-dependencies] +black = {version = "^19.10b0", allow-prereleases = true} +flake8 = "^3.9" +flake8-black = "^0.2.0" +invoke = "^1.3" +isort = "^5.4" +livereload = "^2.6" +markdown = "^3.2.2" +pytest = "^6.0" +pytest-cov = "^2.8" +pytest-pythonpath = "^0.7.3" +pytest-sugar = "^0.9.4" +Werkzeug = "^1.0" + +[tool.poetry.extras] +markdown = ["markdown"] + +[tool.autopub] +project-name = "Share Post" +git-username = "botpub" +git-email = "botpub@autopub.rocks" +append-github-contributor = true + +[tool.isort] +# Maintain compatibility with Black +profile = "black" +multi_line_output = 3 + +# Sort imports within their section independent of the import type +force_sort_within_sections = true + +# Designate "pelican" as separate import section +known_pelican = "pelican" +sections = "FUTURE,STDLIB,THIRDPARTY,PELICAN,FIRSTPARTY,LOCALFOLDER" + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" diff --git a/tasks.py b/tasks.py new file mode 100644 index 0000000..0377b73 --- /dev/null +++ b/tasks.py @@ -0,0 +1,79 @@ +import os +from pathlib import Path +from shutil import which + +from invoke import task + +PKG_NAME = "share_post" +PKG_PATH = Path(f"pelican/plugins/{PKG_NAME}") +ACTIVE_VENV = os.environ.get("VIRTUAL_ENV", None) +VENV_HOME = Path(os.environ.get("WORKON_HOME", "~/.local/share/virtualenvs")) +VENV_PATH = Path(ACTIVE_VENV) if ACTIVE_VENV else (VENV_HOME / PKG_NAME) +VENV = str(VENV_PATH.expanduser()) + +TOOLS = ["poetry", "pre-commit"] +POETRY = which("poetry") if which("poetry") else (VENV / Path("bin") / "poetry") +PRECOMMIT = ( + which("pre-commit") if which("pre-commit") else (VENV / Path("bin") / "pre-commit") +) + + +@task +def tests(c): + """Run the test suite""" + c.run(f"{VENV}/bin/pytest", pty=True) + + +@task +def black(c, check=False, diff=False): + """Run Black auto-formatter, optionally with --check or --diff""" + check_flag, diff_flag = "", "" + if check: + check_flag = "--check" + if diff: + diff_flag = "--diff" + c.run(f"{VENV}/bin/black {check_flag} {diff_flag} {PKG_PATH} tasks.py") + + +@task +def isort(c, check=False, diff=False): + check_flag, diff_flag = "", "" + if check: + check_flag = "-c" + if diff: + diff_flag = "--diff" + c.run(f"{VENV}/bin/isort {check_flag} {diff_flag} .") + + +@task +def flake8(c): + c.run(f"{VENV}/bin/flake8 {PKG_PATH} tasks.py") + + +@task +def lint(c): + isort(c, check=True) + black(c, check=True) + flake8(c) + + +@task +def tools(c): + """Install tools in the virtual environment if not already on PATH""" + for tool in TOOLS: + if not which(tool): + c.run(f"{VENV}/bin/pip install {tool}") + + +@task +def precommit(c): + """Install pre-commit hooks to .git/hooks/pre-commit""" + c.run(f"{PRECOMMIT} install") + + +@task +def setup(c): + c.run(f"{VENV}/bin/pip install -U pip") + tools(c) + c.run(f"{POETRY} install") + precommit(c) diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..abbd0dc --- /dev/null +++ b/tox.ini @@ -0,0 +1,3 @@ +[flake8] +max-line-length = 88 +ignore = E203, W503