jekyll-recker 1.2.1 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +105 -0
- data/_includes/figure.html +14 -0
- data/_includes/footer.html +10 -1
- data/_includes/head.html +21 -0
- data/_includes/nav.html +3 -6
- data/_includes/pager.html +13 -0
- data/_layouts/home.html +13 -9
- data/_layouts/page.html +13 -8
- data/_layouts/post.html +20 -28
- data/lib/jekyll-recker.rb +14 -13
- data/lib/jekyll_recker/commands.rb +35 -0
- data/lib/{jekyll-recker → jekyll_recker}/configuration.rb +6 -0
- data/lib/{jekyll-recker → jekyll_recker}/error.rb +0 -0
- data/lib/jekyll_recker/facebook.rb +97 -0
- data/lib/jekyll_recker/filters.rb +15 -0
- data/lib/{jekyll-recker/stats.rb → jekyll_recker/generators.rb} +42 -39
- data/lib/{jekyll-recker → jekyll_recker}/logger.rb +0 -0
- data/lib/jekyll_recker/mixins.rb +29 -0
- data/lib/{jekyll-recker → jekyll_recker}/shell.rb +0 -0
- data/lib/{jekyll-recker → jekyll_recker}/slack.rb +10 -1
- data/lib/{jekyll-recker → jekyll_recker}/tags.rb +1 -1
- data/lib/{jekyll-recker → jekyll_recker}/twitter.rb +10 -2
- data/lib/{jekyll-recker → jekyll_recker}/version.rb +1 -1
- data/lib/{jekyll-recker → jekyll_recker}/words.rb +0 -0
- metadata +104 -35
- data/README.org +0 -204
- data/_layouts/default.html +0 -14
- data/assets/jekyll-recker.scss +0 -110
- data/lib/jekyll-recker/commands.rb +0 -12
- data/lib/jekyll-recker/commands/share.rb +0 -25
- data/lib/jekyll-recker/commands/slack.rb +0 -30
- data/lib/jekyll-recker/commands/tweet.rb +0 -31
- data/lib/jekyll-recker/generators.rb +0 -17
- data/lib/jekyll-recker/mixins.rb +0 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e0cc3d6cafa2518fb5819ad8cc4a6db7ecf88e214b0e998468f521d0ec19a37
|
4
|
+
data.tar.gz: e623e1c53b62d3ccf0a55ac572ef0fc4257e03cdf7faf543baa1f5ce7d0a40ed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b45d3daae8d8af21c963a412d8430dce81bafaff270a35ca94444b01e74a7d4bd25e422a3ac9afb958bb3693cd7359d4bab70a07776d1da7c3637a38d633eed7
|
7
|
+
data.tar.gz: 4f6aadcd49f0b0d71232ab67c361d3aac1e5a91887272d39e826e3300afa8e0cf872b2154f6e5371dda74a5fd8ea9ac928bd7a2acc6b98357be2e87b75d25903
|
data/README.md
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
# jekyll-recker
|
2
|
+
|
3
|
+
The Greatest Jekyll Plugin in the World. For a live example, check
|
4
|
+
out [my personal website].
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add `jekyll-recker` to the `jekyll_plugins` group in your `Gemfile`.
|
9
|
+
|
10
|
+
group :jekyll_plugins do
|
11
|
+
gem 'jekyll-recker'
|
12
|
+
end
|
13
|
+
|
14
|
+
Then add the plugin to jekyll site's `config.yml` file.
|
15
|
+
|
16
|
+
pugins:
|
17
|
+
- jekyll-recker
|
18
|
+
|
19
|
+
If you'd like to make your site look like mine too, set the theme in
|
20
|
+
`config.yml` too.
|
21
|
+
|
22
|
+
theme: jekyll-recker
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
|
26
|
+
### Share
|
27
|
+
|
28
|
+
Use the `share` jekyll command to post a link to your latest published
|
29
|
+
blog post to any or all of the configured Shares.
|
30
|
+
|
31
|
+
# TODO: example of `be jekyll share`
|
32
|
+
|
33
|
+
Perform a test run with the `--dry` flag.
|
34
|
+
|
35
|
+
# TODO: example of `be jekyll share --dry`
|
36
|
+
|
37
|
+
Send to all configured shares, or just pick one of them.
|
38
|
+
|
39
|
+
$ jekyll share slack
|
40
|
+
$ jekyll share twitter
|
41
|
+
|
42
|
+
#### Slack
|
43
|
+
|
44
|
+
Send the latest published post to a slack channel.
|
45
|
+
|
46
|
+
![example slack]
|
47
|
+
|
48
|
+
Configure the slack share in `_config.yml`.
|
49
|
+
|
50
|
+
recker:
|
51
|
+
slack:
|
52
|
+
myteam:
|
53
|
+
channel: '#blogs'
|
54
|
+
username: 'blogbot'
|
55
|
+
emoji: ':robot:'
|
56
|
+
webhook_cmd: cat ~/.secrets/slack-webhook.txt
|
57
|
+
|
58
|
+
Use the `webhook_cmd` option to shell out to `gpg` or another CLI
|
59
|
+
password manager. Alternatively, you can supply the private incoming
|
60
|
+
webhook using an environment variable.
|
61
|
+
|
62
|
+
export SLACK_MYTEAM_WEBHOOK="https://.../" # SLACK_ + MyTeam.upcase + _WEBHOOK
|
63
|
+
|
64
|
+
Multiple teams are supported as well.
|
65
|
+
|
66
|
+
recker:
|
67
|
+
slack:
|
68
|
+
MyTeamA:
|
69
|
+
channel: '#blogs'
|
70
|
+
username: 'blogbot'
|
71
|
+
emoji: ':robot:'
|
72
|
+
MyTeamB:
|
73
|
+
channel: '#blogs'
|
74
|
+
username: 'blogbot'
|
75
|
+
emoji: ':robot:'
|
76
|
+
MyTeamC:
|
77
|
+
channel: '#blogs'
|
78
|
+
username: 'blogbot'
|
79
|
+
emoji: ':robot:'
|
80
|
+
|
81
|
+
#### Twitter
|
82
|
+
|
83
|
+
Send a tweet with a link to the latest published post.
|
84
|
+
|
85
|
+
![example tweet]
|
86
|
+
|
87
|
+
Configure the tweet share in `_config.yml`.
|
88
|
+
|
89
|
+
recker:
|
90
|
+
twitter:
|
91
|
+
access_token_secret_cmd: pass twitter/reckerbot/access-token-secret
|
92
|
+
access_token_cmd: pass twitter/reckerbot/access-token
|
93
|
+
consumer_api_key_cmd: pass twitter/reckerbot/consumer-api-key
|
94
|
+
consumer_api_secret_cmd: pass twitter/reckerbot/consumer-api-secret-key
|
95
|
+
|
96
|
+
Alternatively, ensure these environment variables are set.
|
97
|
+
|
98
|
+
export TWITTER_ACCESS_TOKEN_SECRET="..."
|
99
|
+
export TWITTER_ACCESS_TOKEN="..."
|
100
|
+
export TWITTER_CONSUMER_API_KEY="..."
|
101
|
+
export TWITTER_CONSUMER_API_SECRET="..."
|
102
|
+
|
103
|
+
[example slack]: screenshots/example-slack.png
|
104
|
+
[example tweet]: screenshots/example-tweet.png
|
105
|
+
[my personal website]: https://www.alexrecker.com
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<figure>
|
2
|
+
{%- if include.url %}
|
3
|
+
<a href="{{ include.url }}">
|
4
|
+
{%- endif %}
|
5
|
+
<img alt="{{ alt | default: include.filename }}" src="{{ site.baseurl }}assets/images/{{ include.filename }}"/>
|
6
|
+
{%- if include.url %}
|
7
|
+
</a>
|
8
|
+
{%- endif %}
|
9
|
+
{%- if include.caption %}
|
10
|
+
<figcaption>
|
11
|
+
<p>{{ include.caption }}</p>
|
12
|
+
</figcaption>
|
13
|
+
{%- endif %}
|
14
|
+
</figure>
|
data/_includes/footer.html
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
<footer>
|
2
|
-
|
2
|
+
<nav>
|
3
|
+
find me on:  
|
4
|
+
<a href="mailto:{{ site.email }}">email</a>
|
5
|
+
<a href="https://www.github.com/{{ site.github_username }}">github</a>
|
6
|
+
<a href="https://www.twitter.com/{{ site.twitter_username }}">twitter</a>
|
7
|
+
<a href="{{ site.basurl }}/assets/public.gpg.asc">gpg</a>
|
8
|
+
<a href="https://www.linkedin.com/in/{{ site.linkedin_username }}">linkedin</a>
|
9
|
+
<a href="https://www.facebook.com/{{ site.facebook_username }}">facebook</a>
|
10
|
+
</nav>
|
11
|
+
built with <a href="https://jekyllrb.com/">jekyll</a> using <a href="https://www.github.com/arecker/jekyll-recker/">jekyll-recker</a> v{% recker_version %}
|
3
12
|
<br/>
|
4
13
|
<small>© copyright {{ 'now' | date: '%Y' }}, {{ site.author }}</small>
|
5
14
|
</footer>
|
data/_includes/head.html
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
{%- capture title %}{{ include.title | default: page.title }}{%- endcapture %}
|
2
|
+
{%- capture description %}{{ include.description | default: site.description }}{%- endcapture %}
|
3
|
+
{%- capture image %}{{ include.image | default: page.image }}{%- endcapture %}
|
4
|
+
<head>
|
5
|
+
<meta charset="UTF-8"/>
|
6
|
+
<title>{{ title }} | {{ description }}</title>
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
8
|
+
<meta name="twitter:card" content="summary" />
|
9
|
+
<meta name="twitter:site" content="@{{ site.twitter_username }}" />
|
10
|
+
<meta name="twitter:title" content="{{ include.title }}" />
|
11
|
+
<meta name="twitter:description" content="{{ include.description }}" />
|
12
|
+
<meta property="og:url" content="{{ site.url }}{{ page.url }}" />
|
13
|
+
<meta property="og:type" content="article" />
|
14
|
+
<meta property="og:title" content="{{ title }}"/>
|
15
|
+
<meta property="og:description" content="{{ description }}" />
|
16
|
+
{%- if image %}
|
17
|
+
<meta name="twitter:image" content="{{ site.url }}{{ site.base_url }}/assets/images/{{ image }}"/>
|
18
|
+
<meta property="og:image" content="{{ site.url }}{{ site.base_url }}/assets/images/{{ image }}"/>
|
19
|
+
{%- endif %}
|
20
|
+
<link href="{{ site.baseurl }}/assets/jekyll-recker.css" rel="stylesheet"/>
|
21
|
+
</head>
|
data/_includes/nav.html
CHANGED
@@ -1,8 +1,5 @@
|
|
1
1
|
<nav>
|
2
|
-
<a href="{{ site.baseurl }}/" class="{% if page.active == 'index' %}active{% endif %}">index</a>
|
3
|
-
<a href="{
|
4
|
-
<a href="{% link stats.org %}" class="{% if page.active == 'stats' %}active{% endif %}">stats</a>
|
5
|
-
<a href="{% link projects.html %}" class="{% if page.active == 'projects' %}active{% endif %}">projects</a>
|
6
|
-
<a href="{% link contact.html %}" class="{% if page.active == 'contact' %}active{% endif %}">contact</a>
|
2
|
+
<a href="{{ site.baseurl }}/" class="{% if page.active == 'index' %}active{% endif %}">index.html</a>
|
3
|
+
<a href="{{ site.basurl }}/feed.xml">feed.xml</a>
|
7
4
|
<span class="float-right hide-on-mobile">{{ page.slug }}</span>
|
8
|
-
</nav>
|
5
|
+
</nav>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<nav class="clearfix">
|
2
|
+
{%- if page.next -%}
|
3
|
+
<a href="{{ page.next.url }}">
|
4
|
+
⟵ {{ page.next.slug }}
|
5
|
+
</a>
|
6
|
+
{%- endif -%}
|
7
|
+
{%- if page.previous -%}
|
8
|
+
<a class="float-right" href="{{ page.previous.url }}">
|
9
|
+
{{ page.previous.slug }} ⟶
|
10
|
+
</a>
|
11
|
+
{%- endif -%}
|
12
|
+
</nav>
|
13
|
+
|
data/_layouts/home.html
CHANGED
@@ -1,9 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
1
|
+
<!doctype html>
|
2
|
+
<html lang="en">
|
3
|
+
{% include head.html title=site.title %}
|
4
|
+
<body>
|
5
|
+
{% include header.html title=site.title subtitle=site.description %}
|
6
|
+
<hr/>
|
7
|
+
{% include nav.html %}
|
8
|
+
<hr/>
|
9
|
+
{{ content }}
|
10
|
+
<hr/>
|
11
|
+
{% include footer.html %}
|
12
|
+
</body>
|
13
|
+
</html>
|
data/_layouts/page.html
CHANGED
@@ -1,8 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
1
|
+
<!doctype html>
|
2
|
+
<html lang="en">
|
3
|
+
{% include head.html title=site.title %}
|
4
|
+
<body>
|
5
|
+
{% include header.html title=page.title subtitle=page.description %}
|
6
|
+
<hr/>
|
7
|
+
{% include nav.html %}
|
8
|
+
<hr/>
|
9
|
+
{{ content }}
|
10
|
+
<hr/>
|
11
|
+
{% include footer.html %}
|
12
|
+
</body>
|
13
|
+
</html>
|
data/_layouts/post.html
CHANGED
@@ -1,28 +1,20 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
{%
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
<
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
{
|
16
|
-
{
|
17
|
-
<
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
</a>
|
22
|
-
{%- endif -%}
|
23
|
-
{%- if page.previous -%}
|
24
|
-
<a class="float-right" href="{{ page.previous.url }}">
|
25
|
-
{{ page.previous.slug }} ⟶
|
26
|
-
</a>
|
27
|
-
</nav>
|
28
|
-
{%- endif -%}
|
1
|
+
{%- capture datestring %}{{ page.date | uyd_date }}{% endcapture %}
|
2
|
+
<!doctype html>
|
3
|
+
<html lang="en">
|
4
|
+
{% include head.html title=datestring description=page.title %}
|
5
|
+
<body>
|
6
|
+
{% include header.html title=datestring subtitle=page.title %}
|
7
|
+
<hr/>
|
8
|
+
{% include nav.html %}
|
9
|
+
<hr/>
|
10
|
+
{%- if page.image -%}
|
11
|
+
<br/>
|
12
|
+
{% include figure.html filename=page.image %}
|
13
|
+
<br/>
|
14
|
+
{%- endif -%}
|
15
|
+
{{ content }}
|
16
|
+
{% include pager.html %}
|
17
|
+
<hr/>
|
18
|
+
{% include footer.html %}
|
19
|
+
</body>
|
20
|
+
</html>
|
data/lib/jekyll-recker.rb
CHANGED
@@ -5,19 +5,20 @@ require 'jekyll'
|
|
5
5
|
module Jekyll
|
6
6
|
# Recker
|
7
7
|
module Recker
|
8
|
-
require '
|
9
|
-
require '
|
8
|
+
require 'jekyll_recker/logger.rb'
|
9
|
+
require 'jekyll_recker/mixins.rb'
|
10
10
|
|
11
|
-
require '
|
12
|
-
require '
|
13
|
-
require '
|
14
|
-
require '
|
15
|
-
require '
|
16
|
-
require '
|
17
|
-
require '
|
18
|
-
require '
|
19
|
-
require '
|
20
|
-
require '
|
21
|
-
require '
|
11
|
+
require 'jekyll_recker/commands.rb'
|
12
|
+
require 'jekyll_recker/configuration.rb'
|
13
|
+
require 'jekyll_recker/error.rb'
|
14
|
+
require 'jekyll_recker/facebook.rb'
|
15
|
+
require 'jekyll_recker/filters.rb'
|
16
|
+
require 'jekyll_recker/generators.rb'
|
17
|
+
require 'jekyll_recker/shell.rb'
|
18
|
+
require 'jekyll_recker/slack.rb'
|
19
|
+
require 'jekyll_recker/tags.rb'
|
20
|
+
require 'jekyll_recker/twitter.rb'
|
21
|
+
require 'jekyll_recker/version.rb'
|
22
|
+
require 'jekyll_recker/words.rb'
|
22
23
|
end
|
23
24
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jekyll
|
4
|
+
module Recker
|
5
|
+
# Commands
|
6
|
+
module Commands
|
7
|
+
# Share
|
8
|
+
class Share < Jekyll::Command
|
9
|
+
include Mixins::Logging
|
10
|
+
|
11
|
+
def self.init_with_program(prog)
|
12
|
+
prog.command(:share) do |c|
|
13
|
+
c.syntax 'share'
|
14
|
+
c.description 'Share latest post with each configured backend'
|
15
|
+
c.option 'dry', '-d', '--dry', 'perform dry run'
|
16
|
+
c.action { |args, opts| action(args, opts) }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.action(args, options)
|
21
|
+
if args.empty? || args.include?('slack')
|
22
|
+
Recker::Slack.share(dry: options['dry'])
|
23
|
+
elsif args.empty? || args.include?('twitter')
|
24
|
+
Recker::Twitter.share(dry: options['dry'])
|
25
|
+
# elsif args.empty? || args.include?('facebook')
|
26
|
+
# Recker::Facebook.share(dry: options['dry'])
|
27
|
+
end
|
28
|
+
rescue ReckerError => e
|
29
|
+
logger.error e.message
|
30
|
+
exit 1
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Jekyll
|
2
4
|
module Recker
|
3
5
|
# Configuration
|
@@ -10,6 +12,10 @@ module Jekyll
|
|
10
12
|
jekyll.fetch('recker', {})
|
11
13
|
end
|
12
14
|
|
15
|
+
def self.facebook
|
16
|
+
recker.fetch('facebook', {})
|
17
|
+
end
|
18
|
+
|
13
19
|
def self.twitter
|
14
20
|
recker.fetch('twitter', {})
|
15
21
|
end
|
File without changes
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'koala'
|
4
|
+
|
5
|
+
module Jekyll
|
6
|
+
module Recker
|
7
|
+
# Facebook Client
|
8
|
+
class Facebook
|
9
|
+
include Mixins::Logging
|
10
|
+
|
11
|
+
def self.share(dry: false)
|
12
|
+
client = new(dry: dry)
|
13
|
+
logger.info 'discovering credentials'
|
14
|
+
client.discover_credentials!
|
15
|
+
logger.info "sharing #{client.latest.data['title']}"
|
16
|
+
client.post_latest!
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(dry: false)
|
20
|
+
@dry = dry
|
21
|
+
end
|
22
|
+
|
23
|
+
def discover_credentials!
|
24
|
+
@creds = extract_from_env || extract_from_config
|
25
|
+
raise ReckerError, 'cannot find facebook credentials!' if @creds.nil?
|
26
|
+
|
27
|
+
set_credentials!
|
28
|
+
end
|
29
|
+
|
30
|
+
def post_latest!
|
31
|
+
if @dry
|
32
|
+
logger.info('posting in dry mode, printing message')
|
33
|
+
logger.info("BEGIN POST\n#{post_body.strip}\nEND POST")
|
34
|
+
else
|
35
|
+
@graph.put_connections("me", "feed", message: "I am writing on my wall!")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def latest
|
40
|
+
Configuration.latest_post
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def post_body
|
46
|
+
url = File.join Configuration.jekyll['url'], latest.url
|
47
|
+
<<~POST
|
48
|
+
#{latest.data['date'].strftime('%A, %B %-d %Y')}
|
49
|
+
#{latest.data['title']}
|
50
|
+
#{url}
|
51
|
+
POST
|
52
|
+
end
|
53
|
+
|
54
|
+
def set_credentials!
|
55
|
+
Koala.configure do |config|
|
56
|
+
config.access_token = @creds['access_token']
|
57
|
+
# config.app_access_token = @creds['app_access_token']
|
58
|
+
config.app_id = @creds['app_id']
|
59
|
+
config.app_secret = @creds['app_secret']
|
60
|
+
end
|
61
|
+
@client = Koala::Facebook::API.new(@creds['access_token'])
|
62
|
+
end
|
63
|
+
|
64
|
+
def extract_from_env
|
65
|
+
values = cred_fieldnames.map { |k| ENV["FACEBOOK_#{k.upcase}"] }
|
66
|
+
|
67
|
+
return nil if values.any? { |v| v.nil? || v.empty? }
|
68
|
+
|
69
|
+
Hash[cred_fieldnames.zip(values)]
|
70
|
+
end
|
71
|
+
|
72
|
+
def extract_from_config
|
73
|
+
values = cred_fieldnames.map do |k|
|
74
|
+
cmd = Configuration.facebook.fetch("#{k}_cmd", '').strip
|
75
|
+
if cmd.empty?
|
76
|
+
nil
|
77
|
+
else
|
78
|
+
Recker.shell(Configuration.facebook["#{k}_cmd"]).strip
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
return nil if values.any? { |v| v.nil? || v.empty? }
|
83
|
+
|
84
|
+
Hash[cred_fieldnames.zip(values)]
|
85
|
+
end
|
86
|
+
|
87
|
+
def cred_fieldnames
|
88
|
+
# app_access_token
|
89
|
+
%w[
|
90
|
+
access_token
|
91
|
+
app_id
|
92
|
+
app_secret
|
93
|
+
]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|