jekyll-recker 1.2.0 → 1.5.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 +11 -2
- data/_includes/head.html +21 -0
- data/_includes/nav.html +3 -5
- data/_includes/pager.html +13 -0
- data/_layouts/home.html +13 -9
- data/_layouts/page.html +13 -8
- data/_layouts/post.html +20 -21
- data/lib/jekyll-recker.rb +14 -12
- data/lib/jekyll_recker/commands.rb +74 -0
- data/lib/{jekyll-recker → jekyll_recker}/configuration.rb +2 -0
- data/lib/{jekyll-recker → jekyll_recker}/error.rb +0 -0
- data/lib/jekyll_recker/filters.rb +15 -0
- data/lib/{jekyll-recker/stats.rb → jekyll_recker/generators.rb} +40 -38
- data/lib/jekyll_recker/logger.rb +20 -0
- data/lib/jekyll_recker/mixins.rb +29 -0
- data/lib/{jekyll-recker → jekyll_recker}/shell.rb +0 -1
- data/lib/{jekyll-recker → jekyll_recker}/slack.rb +4 -2
- data/lib/{jekyll-recker → jekyll_recker}/tags.rb +1 -1
- data/lib/{jekyll-recker → jekyll_recker}/twitter.rb +4 -2
- data/lib/{jekyll-recker → jekyll_recker}/version.rb +1 -1
- data/lib/{jekyll-recker → jekyll_recker}/words.rb +0 -0
- metadata +89 -31
- data/README.org +0 -204
- data/_layouts/default.html +0 -14
- data/assets/jekyll-recker.scss +0 -106
- data/lib/jekyll-recker/commands.rb +0 -52
- data/lib/jekyll-recker/generators.rb +0 -15
- data/lib/jekyll-recker/log.rb +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: efd3587e247f83a9294d79e67abe0edf58dfe64aa413a18ee591bc2b5225687e
|
4
|
+
data.tar.gz: 28f7d50132af62ac1955dbc5657e54f1c4f67a996d34c79aded6add417a815c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: df34b7690acd0abd08d79271e3c262e7367c184968bb6db587e681f0a5df3b62e7d1f54bd6f346c684e77541cf1f8acb979e55f9a460a4acac786d59ba48db3c
|
7
|
+
data.tar.gz: 0f90b95a366cbffde52647320aca1152322f36eccc5f791dd393696f1414da630624bb2bdadf54f632f378b1d3cb55af61b0d59308c704952fc344914df8fa44
|
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 ACCESS_TOKEN_SECRET="..."
|
99
|
+
export ACCESS_TOKEN="..."
|
100
|
+
export CONSUMER_API_KEY="..."
|
101
|
+
export 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,7 +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 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>
|
6
4
|
<span class="float-right hide-on-mobile">{{ page.slug }}</span>
|
7
|
-
</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,21 +1,20 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
{%
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
</
|
20
|
-
</
|
21
|
-
{%- 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,17 +5,19 @@ require 'jekyll'
|
|
5
5
|
module Jekyll
|
6
6
|
# Recker
|
7
7
|
module Recker
|
8
|
-
require '
|
9
|
-
require '
|
10
|
-
|
11
|
-
require '
|
12
|
-
require '
|
13
|
-
require '
|
14
|
-
require '
|
15
|
-
require '
|
16
|
-
require '
|
17
|
-
require '
|
18
|
-
require '
|
19
|
-
require '
|
8
|
+
require 'jekyll_recker/logger.rb'
|
9
|
+
require 'jekyll_recker/mixins.rb'
|
10
|
+
|
11
|
+
require 'jekyll_recker/commands.rb'
|
12
|
+
require 'jekyll_recker/configuration.rb'
|
13
|
+
require 'jekyll_recker/error.rb'
|
14
|
+
require 'jekyll_recker/filters.rb'
|
15
|
+
require 'jekyll_recker/generators.rb'
|
16
|
+
require 'jekyll_recker/shell.rb'
|
17
|
+
require 'jekyll_recker/slack.rb'
|
18
|
+
require 'jekyll_recker/tags.rb'
|
19
|
+
require 'jekyll_recker/twitter.rb'
|
20
|
+
require 'jekyll_recker/version.rb'
|
21
|
+
require 'jekyll_recker/words.rb'
|
20
22
|
end
|
21
23
|
end
|
@@ -0,0 +1,74 @@
|
|
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 do |_args, _options|
|
17
|
+
logger.info 'normally I\'d share here'
|
18
|
+
rescue ReckerError => e
|
19
|
+
logger.abort_with e.message
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Slack
|
26
|
+
class Slack < Jekyll::Command
|
27
|
+
include Mixins::Logging
|
28
|
+
def self.init_with_program(prog)
|
29
|
+
prog.command(:slack) do |c|
|
30
|
+
c.syntax 'slack'
|
31
|
+
c.description 'slack latest post'
|
32
|
+
c.option 'dry', '-d', '--dry', 'print message instead of posting'
|
33
|
+
c.action { |args, opts| action(args, opts) }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.action(_args, options)
|
38
|
+
Recker::Slack.each_in_config(dry: options['dry']) do |client|
|
39
|
+
logger.info "#{client.key}: discovering webhook"
|
40
|
+
client.discover_webhook!
|
41
|
+
logger.info "#{client.key}: posting #{client.latest.data['title']}"
|
42
|
+
client.post_latest!
|
43
|
+
end
|
44
|
+
rescue ReckerError => e
|
45
|
+
logger.abort_with e.message
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Tweet
|
50
|
+
class Tweet < Jekyll::Command
|
51
|
+
include Mixins::Logging
|
52
|
+
|
53
|
+
def self.init_with_program(prog)
|
54
|
+
prog.command(:tweet) do |c|
|
55
|
+
c.syntax 'tweet'
|
56
|
+
c.description 'tweet latest post'
|
57
|
+
c.option 'dry', '-d', '--dry', 'print message instead of tweeting'
|
58
|
+
c.action { |args, opts| action(args, opts) }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.action(_args, options)
|
63
|
+
client = Jekyll::Recker::Twitter.new(dry: options['dry'])
|
64
|
+
logger.info 'discovering credentials'
|
65
|
+
client.discover_credentials!
|
66
|
+
logger.info "tweeting #{client.latest.data['title']}"
|
67
|
+
client.post_latest!
|
68
|
+
rescue ReckerError => e
|
69
|
+
logger.abort_with e.message
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
File without changes
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jekyll
|
4
|
+
module Recker
|
5
|
+
# Filters
|
6
|
+
module Filters
|
7
|
+
# Converts a date object to standard Uhh Yeah Dude format.
|
8
|
+
def uyd_date(date)
|
9
|
+
date.strftime('%A, %B %d %Y')
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
Liquid::Template.register_filter(Jekyll::Recker::Filters)
|
@@ -1,42 +1,44 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'date'
|
4
|
-
|
5
3
|
module Jekyll
|
6
4
|
module Recker
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
stats[cruncher.stats_key] = cruncher.crunch
|
15
|
-
end
|
16
|
-
stats
|
17
|
-
end
|
18
|
-
|
19
|
-
# Base Cruncher
|
20
|
-
class BaseCruncher
|
5
|
+
module Generators
|
6
|
+
# Stats Module
|
7
|
+
#
|
8
|
+
# Functions for stats generators.
|
9
|
+
# @abstract
|
10
|
+
module Stats
|
11
|
+
include Mixins::Logging
|
21
12
|
include Jekyll::Filters
|
22
13
|
|
23
|
-
def
|
24
|
-
|
14
|
+
def key
|
15
|
+
self.class.const_get(:KEY)
|
25
16
|
end
|
26
17
|
|
27
|
-
def
|
18
|
+
def generate(site)
|
28
19
|
@site = site
|
20
|
+
logger.info "crunching stats.#{key}"
|
21
|
+
@site.data['stats'] ||= {}
|
22
|
+
@site.data['stats'][key] = crunch
|
29
23
|
end
|
30
24
|
|
31
|
-
|
32
|
-
|
33
|
-
|
25
|
+
def crunch
|
26
|
+
raise NotImplementedError, '#crunch not implemented!'
|
27
|
+
end
|
34
28
|
|
29
|
+
# Calculates the average of a list of numbers.
|
30
|
+
#
|
31
|
+
# @param [Array<Numeric>] numlist list of numbers to be averaged.
|
32
|
+
# @return [Numeric] rounded, calculated average of numlist.
|
35
33
|
def average(numlist)
|
36
34
|
calc = numlist.inject { |sum, el| sum + el }.to_f / numlist.size
|
37
35
|
calc.round
|
38
36
|
end
|
39
37
|
|
38
|
+
# Calculates the total of a list of numbers.
|
39
|
+
#
|
40
|
+
# @param [Array<Numeric>] numlist list of numbers to be totaled.
|
41
|
+
# @return [Numeric] calculated total of numlist.
|
40
42
|
def total(numlist)
|
41
43
|
numlist.inject(0) { |sum, x| sum + x }
|
42
44
|
end
|
@@ -46,22 +48,22 @@ module Jekyll
|
|
46
48
|
end
|
47
49
|
end
|
48
50
|
|
49
|
-
#
|
50
|
-
class
|
51
|
-
|
52
|
-
|
53
|
-
|
51
|
+
# Post Count Generator
|
52
|
+
class PostCount < Jekyll::Generator
|
53
|
+
include Stats
|
54
|
+
|
55
|
+
KEY = 'posts'
|
54
56
|
|
55
57
|
def crunch
|
56
58
|
entries.count.pretty
|
57
59
|
end
|
58
60
|
end
|
59
61
|
|
60
|
-
#
|
61
|
-
class
|
62
|
-
|
63
|
-
|
64
|
-
|
62
|
+
# Word Count Generator
|
63
|
+
class Words < Jekyll::Generator
|
64
|
+
include Stats
|
65
|
+
|
66
|
+
KEY = 'words'
|
65
67
|
|
66
68
|
def crunch
|
67
69
|
total_counts = entries.collect(&:content).map { |c| number_of_words(c) }
|
@@ -72,11 +74,11 @@ module Jekyll
|
|
72
74
|
end
|
73
75
|
end
|
74
76
|
|
75
|
-
# Streak
|
76
|
-
class
|
77
|
-
|
78
|
-
|
79
|
-
|
77
|
+
# Streak Count Generator
|
78
|
+
class Streaks < Jekyll::Generator
|
79
|
+
include Stats
|
80
|
+
|
81
|
+
KEY = 'days'
|
80
82
|
|
81
83
|
def crunch
|
82
84
|
streaks.take(1).map do |count, dates|
|
@@ -95,7 +97,7 @@ module Jekyll
|
|
95
97
|
entry_dates.slice_when do |prev, curr|
|
96
98
|
curr != prev - 1
|
97
99
|
end.each do |dates|
|
98
|
-
first, last = dates.
|
100
|
+
first, last = dates.minmax
|
99
101
|
_streaks << [(last - first).to_i, [first, last]]
|
100
102
|
end
|
101
103
|
_streaks
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
module Jekyll
|
6
|
+
# Recker
|
7
|
+
module Recker
|
8
|
+
def self.logger
|
9
|
+
@logger ||= make_logger
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.make_logger
|
13
|
+
logger = Logger.new(STDOUT)
|
14
|
+
logger.formatter = proc do |_severity, _datetime, _progname, msg|
|
15
|
+
"jekyll-recker: #{msg}\n"
|
16
|
+
end
|
17
|
+
logger
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jekyll
|
4
|
+
module Recker
|
5
|
+
module Mixins
|
6
|
+
# Descendants
|
7
|
+
module Descendants
|
8
|
+
def self.included(base)
|
9
|
+
base.extend(self)
|
10
|
+
end
|
11
|
+
|
12
|
+
def descendants
|
13
|
+
ObjectSpace.each_object(Class).select { |klass| klass < self }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Logging
|
18
|
+
module Logging
|
19
|
+
def self.included(base)
|
20
|
+
base.extend(self)
|
21
|
+
end
|
22
|
+
|
23
|
+
def logger
|
24
|
+
Jekyll::Recker.logger
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -7,6 +7,8 @@ module Jekyll
|
|
7
7
|
module Recker
|
8
8
|
# Slack
|
9
9
|
class Slack
|
10
|
+
include Jekyll::Recker::Mixins::Logging
|
11
|
+
|
10
12
|
def self.each_in_config(dry: false)
|
11
13
|
Configuration.slack.map do |key, body|
|
12
14
|
yield new(key, body, dry: dry)
|
@@ -33,8 +35,8 @@ module Jekyll
|
|
33
35
|
|
34
36
|
def post_latest!
|
35
37
|
if @dry
|
36
|
-
|
37
|
-
|
38
|
+
logger.info('postign in dry mode, printing message')
|
39
|
+
logger.info("BEGIN MESSAGE\n#{message_body.strip}\nEND MESSAGE")
|
38
40
|
else
|
39
41
|
::Slack::Notifier.new(
|
40
42
|
@webhook.strip,
|
@@ -6,6 +6,8 @@ module Jekyll
|
|
6
6
|
module Recker
|
7
7
|
# Twitter Client
|
8
8
|
class Twitter
|
9
|
+
include Mixins::Logging
|
10
|
+
|
9
11
|
def initialize(dry: false)
|
10
12
|
@dry = dry
|
11
13
|
end
|
@@ -19,8 +21,8 @@ module Jekyll
|
|
19
21
|
|
20
22
|
def post_latest!
|
21
23
|
if @dry
|
22
|
-
|
23
|
-
|
24
|
+
logger.info('tweeting in dry mode, printing message')
|
25
|
+
logger.info("BEGIN TWEET\n#{tweet_body.strip}\nEND TWEET")
|
24
26
|
else
|
25
27
|
@client.update(tweet_body)
|
26
28
|
end
|
File without changes
|
metadata
CHANGED
@@ -1,37 +1,37 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll-recker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Recker
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-05-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: bump
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
20
|
-
type: :
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: pry
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
|
-
type: :
|
34
|
+
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
@@ -39,13 +39,13 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
|
-
type: :
|
48
|
+
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
@@ -53,7 +53,7 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: rubocop
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
@@ -80,6 +80,62 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: yard
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: jekyll
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3.8'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '3.8'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: slack-notifier
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: twitter
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
83
139
|
description:
|
84
140
|
email:
|
85
141
|
- alex@reckerfamily.com
|
@@ -88,29 +144,31 @@ extensions: []
|
|
88
144
|
extra_rdoc_files: []
|
89
145
|
files:
|
90
146
|
- LICENSE
|
91
|
-
- README.
|
147
|
+
- README.md
|
148
|
+
- _includes/figure.html
|
92
149
|
- _includes/footer.html
|
150
|
+
- _includes/head.html
|
93
151
|
- _includes/header.html
|
94
152
|
- _includes/nav.html
|
95
|
-
-
|
153
|
+
- _includes/pager.html
|
96
154
|
- _layouts/home.html
|
97
155
|
- _layouts/page.html
|
98
156
|
- _layouts/post.html
|
99
|
-
- assets/jekyll-recker.scss
|
100
157
|
- lib/jekyll-recker.rb
|
101
|
-
- lib/
|
102
|
-
- lib/
|
103
|
-
- lib/
|
104
|
-
- lib/
|
105
|
-
- lib/
|
106
|
-
- lib/
|
107
|
-
- lib/
|
108
|
-
- lib/
|
109
|
-
- lib/
|
110
|
-
- lib/
|
111
|
-
- lib/
|
112
|
-
- lib/
|
113
|
-
|
158
|
+
- lib/jekyll_recker/commands.rb
|
159
|
+
- lib/jekyll_recker/configuration.rb
|
160
|
+
- lib/jekyll_recker/error.rb
|
161
|
+
- lib/jekyll_recker/filters.rb
|
162
|
+
- lib/jekyll_recker/generators.rb
|
163
|
+
- lib/jekyll_recker/logger.rb
|
164
|
+
- lib/jekyll_recker/mixins.rb
|
165
|
+
- lib/jekyll_recker/shell.rb
|
166
|
+
- lib/jekyll_recker/slack.rb
|
167
|
+
- lib/jekyll_recker/tags.rb
|
168
|
+
- lib/jekyll_recker/twitter.rb
|
169
|
+
- lib/jekyll_recker/version.rb
|
170
|
+
- lib/jekyll_recker/words.rb
|
171
|
+
homepage: https://www.github.com/arecker/jekyll-recker/
|
114
172
|
licenses:
|
115
173
|
- GPLv3
|
116
174
|
metadata: {}
|
@@ -132,5 +190,5 @@ requirements: []
|
|
132
190
|
rubygems_version: 3.0.3
|
133
191
|
signing_key:
|
134
192
|
specification_version: 4
|
135
|
-
summary:
|
193
|
+
summary: The Greatest Jekyll Plugin in the World
|
136
194
|
test_files: []
|
data/README.org
DELETED
@@ -1,204 +0,0 @@
|
|
1
|
-
#+TITLE: jekyll-recker
|
2
|
-
#+SLUG: jekyll-recker.html
|
3
|
-
#+PERMALINK: jekyll-recker.html
|
4
|
-
#+STARTUP: showall
|
5
|
-
#+DESCRIPTION: my website's custom jekyll plugin
|
6
|
-
|
7
|
-
This is the jekyll plugin for my personal website.
|
8
|
-
|
9
|
-
** Installation
|
10
|
-
|
11
|
-
Add =jekyll-recker= to the =jekyll_plugins= group of your =Gemfile=.
|
12
|
-
|
13
|
-
#+BEGIN_SRC ruby
|
14
|
-
group :jekyll_plugins do
|
15
|
-
gem 'jekyll-recker'
|
16
|
-
end
|
17
|
-
#+END_SRC
|
18
|
-
|
19
|
-
Add =jekyll-recker= to the list of plugins in jekyll's =_config.yml=.
|
20
|
-
|
21
|
-
#+BEGIN_SRC yaml
|
22
|
-
# _config.yaml
|
23
|
-
plugins:
|
24
|
-
- jekyll-recker
|
25
|
-
#+END_SRC
|
26
|
-
|
27
|
-
Set the theme.
|
28
|
-
|
29
|
-
#+BEGIN_SRC yaml
|
30
|
-
theme: jekyll-recker
|
31
|
-
#+END_SRC
|
32
|
-
|
33
|
-
Install and enjoy.
|
34
|
-
|
35
|
-
#+BEGIN_SRC sh
|
36
|
-
bundle install
|
37
|
-
bundle exec jekyll serve
|
38
|
-
#+END_SRC
|
39
|
-
|
40
|
-
** Usage
|
41
|
-
|
42
|
-
*** Commands
|
43
|
-
|
44
|
-
**** =slack=
|
45
|
-
|
46
|
-
The =slack= command posts a slack message advertising the latest
|
47
|
-
published jekyll blog post using a private incoming webhook.
|
48
|
-
|
49
|
-
Configure _config.yml
|
50
|
-
|
51
|
-
#+BEGIN_SRC yaml
|
52
|
-
# _config.yml
|
53
|
-
recker:
|
54
|
-
slack:
|
55
|
-
MyTeam:
|
56
|
-
channel: '#blogs' # required!
|
57
|
-
username: 'blogbot' # required!
|
58
|
-
emoji: ':robot:' # required!
|
59
|
-
#+END_SRC
|
60
|
-
|
61
|
-
Multiple teams are supported too!
|
62
|
-
|
63
|
-
#+BEGIN_SRC yaml
|
64
|
-
# _config.yml
|
65
|
-
recker:
|
66
|
-
slack:
|
67
|
-
MyTeamA:
|
68
|
-
channel: '#blogs' # required!
|
69
|
-
username: 'blogbot' # required!
|
70
|
-
emoji: ':robot:' # required!
|
71
|
-
MyTeamB:
|
72
|
-
channel: '#blogs' # required!
|
73
|
-
username: 'blogbot' # required!
|
74
|
-
emoji: ':robot:' # required!
|
75
|
-
MyTeamC:
|
76
|
-
channel: '#blogs' # required!
|
77
|
-
username: 'blogbot' # required!
|
78
|
-
emoji: ':robot:' # required!
|
79
|
-
#+END_SRC
|
80
|
-
|
81
|
-
|
82
|
-
Supply the private webhook through an environment variable.
|
83
|
-
|
84
|
-
#+BEGIN_SRC sh
|
85
|
-
export SLACK_MYTEAM_WEBHOOK="https://..." # SLACK_ + <MyTeam.upcase> + _WEBHOOK
|
86
|
-
#+END_SRC
|
87
|
-
|
88
|
-
Alternatively, add the command with which to retrieve the webhook in
|
89
|
-
_config.yml
|
90
|
-
|
91
|
-
#+BEGIN_SRC yaml
|
92
|
-
# _config.yml
|
93
|
-
recker:
|
94
|
-
slack:
|
95
|
-
MyTeam:
|
96
|
-
webhook_cmd: cat secrets/my-teams-secret-webhook.txt
|
97
|
-
#+END_SRC
|
98
|
-
|
99
|
-
Run =bundle exec jekyll slack= to let it rip!
|
100
|
-
|
101
|
-
[[assets/images/example-slack.png]]
|
102
|
-
|
103
|
-
Using the =--dry= flag, you can preview the message post without
|
104
|
-
actually posting anything.
|
105
|
-
|
106
|
-
#+BEGIN_EXAMPLE
|
107
|
-
arecker@25732-arecker:~/src/blog$ be jekyll slack --dry
|
108
|
-
Configuration file: /Users/arecker/src/blog/_config.yml
|
109
|
-
jekyll-recker: reckerfamily: discovering webhook
|
110
|
-
Configuration file: /Users/arecker/src/blog/_config.yml
|
111
|
-
jekyll-recker: reckerfamily: posting drag racing, windshield wipers, and alex's painting tips
|
112
|
-
jekyll-recker: postign in dry mode, printing message
|
113
|
-
jekyll-recker: BEGIN MESSAGE
|
114
|
-
Sunday, March 15 2020
|
115
|
-
drag racing, windshield wipers, and alex's painting tips
|
116
|
-
https://www.alexrecker.com/2020-03-15.html
|
117
|
-
END MESSAGE
|
118
|
-
#+END_EXAMPLE
|
119
|
-
|
120
|
-
**** =tweet=
|
121
|
-
|
122
|
-
The =tweet= command tweets a link to the latest published jekyll blog
|
123
|
-
post.
|
124
|
-
|
125
|
-
Ensure the following environment variables are set,.
|
126
|
-
|
127
|
-
#+BEGIN_SRC sh
|
128
|
-
export ACCESS_TOKEN_SECRET="..."
|
129
|
-
export ACCESS_TOKEN="..."
|
130
|
-
export CONSUMER_API_KEY="..."
|
131
|
-
export CONSUMER_API_SECRET="..."
|
132
|
-
#+END_SRC
|
133
|
-
|
134
|
-
Alternatively, configure which commands to run to fetch the secrets.
|
135
|
-
|
136
|
-
#+BEGIN_SRC yaml
|
137
|
-
# _config.yml
|
138
|
-
recker:
|
139
|
-
twitter:
|
140
|
-
access_token_secret_cmd: cat secrets/access-token-secret
|
141
|
-
access_token_cmd: cat secrets/access-token
|
142
|
-
consumer_api_key_cmd: cat secrets/consumer-api-key
|
143
|
-
consumer_api_secret_cmd: cat secrets/consumer-api-secret-key
|
144
|
-
#+END_SRC
|
145
|
-
|
146
|
-
Run =bundle exec jekyll tweet= to let it rip!
|
147
|
-
|
148
|
-
[[assets/images/example-tweet.png]]
|
149
|
-
|
150
|
-
Using the =--dry= flag, you can test your configuration without
|
151
|
-
actually tweeting anything.
|
152
|
-
|
153
|
-
#+BEGIN_EXAMPLE
|
154
|
-
arecker@25732-arecker:~/src/blog$ be jekyll tweet --dry
|
155
|
-
jekyll-recker: discovering credentials
|
156
|
-
Configuration file: /Users/arecker/src/blog/_config.yml
|
157
|
-
Configuration file: /Users/arecker/src/blog/_config.yml
|
158
|
-
jekyll-recker: tweeting drag racing, windshield wipers, and alex's painting tips
|
159
|
-
jekyll-recker: tweeting in dry mode, printing message
|
160
|
-
jekyll-recker: BEGIN TWEET
|
161
|
-
Sunday, March 15 2020
|
162
|
-
drag racing, windshield wipers, and alex's painting tips
|
163
|
-
https://www.alexrecker.com/2020-03-15.html
|
164
|
-
END TWEET
|
165
|
-
#+END_EXAMPLE
|
166
|
-
|
167
|
-
*** Generators
|
168
|
-
|
169
|
-
**** =stats=
|
170
|
-
|
171
|
-
On build time, =jekyll-recker= calculates and stores the following
|
172
|
-
stats in the =site.data.stats= object
|
173
|
-
|
174
|
-
| Field Name | Field Description |
|
175
|
-
|-----------------+------------------------------------------------------|
|
176
|
-
| =posts= | The total number of published posts. |
|
177
|
-
| =words.total= | The total number of words from all published post. |
|
178
|
-
| =words.average= | The average number of words for each published post. |
|
179
|
-
| =days.days= | Current streak of daily, consecutive posts. |
|
180
|
-
| =days.start= | First day of current streak. |
|
181
|
-
| =days.end= | Last day of current streak. |
|
182
|
-
|
183
|
-
Use these variables to render your own page of neat writing statistics!
|
184
|
-
|
185
|
-
#+BEGIN_SRC html
|
186
|
-
<table>
|
187
|
-
<tr>
|
188
|
-
<th>Total Posts</th>
|
189
|
-
<th>Total Words</th>
|
190
|
-
<th>Average Words per Post</th>
|
191
|
-
<th>Current Streak</th>
|
192
|
-
<th>First day of current streak</th>
|
193
|
-
<th>Last day of current streak</th>
|
194
|
-
</tr>
|
195
|
-
<tr>
|
196
|
-
<td>{{ site.data.stats.posts }}</td>
|
197
|
-
<td>{{ site.data.stats.words.total }}</td>
|
198
|
-
<td>{{ site.data.stats.words.average }}</td>
|
199
|
-
<td>{{ site.data.stats.days.days }}</td>
|
200
|
-
<td>{{ site.data.stats.days.start }}</td>
|
201
|
-
<td>{{ site.data.stats.days.end }}</td>
|
202
|
-
</tr>
|
203
|
-
</table>
|
204
|
-
#+END_SRC
|
data/_layouts/default.html
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
<!doctype html>
|
2
|
-
<html lang="en">
|
3
|
-
<head>
|
4
|
-
<meta charset="UTF-8"/>
|
5
|
-
<title>{{ site.title }} | {{ page.title | default: site.description }}</title>
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
7
|
-
<link href="{{ site.baseurl }}/assets/jekyll-recker.css" rel="stylesheet"/>
|
8
|
-
</head>
|
9
|
-
<body>
|
10
|
-
{{ content }}
|
11
|
-
<hr/>
|
12
|
-
{% include footer.html %}
|
13
|
-
</body>
|
14
|
-
</html>
|
data/assets/jekyll-recker.scss
DELETED
@@ -1,106 +0,0 @@
|
|
1
|
-
---
|
2
|
-
---
|
3
|
-
// @import 'https://fonts.googleapis.com/css?family=Titillium+Web&display=swap';
|
4
|
-
@import 'https://fonts.googleapis.com/css?family=Open+Sans&display=swap';
|
5
|
-
@import 'https://fonts.googleapis.com/css?family=Inconsolata&display=swap';
|
6
|
-
|
7
|
-
.float-right {
|
8
|
-
float: right;
|
9
|
-
}
|
10
|
-
|
11
|
-
.clearfix::after {
|
12
|
-
content: "";
|
13
|
-
clear: both;
|
14
|
-
display: block;
|
15
|
-
}
|
16
|
-
|
17
|
-
@media screen and (max-width: 600px) {
|
18
|
-
.hide-on-mobile {
|
19
|
-
display: none;
|
20
|
-
}
|
21
|
-
}
|
22
|
-
|
23
|
-
ul.unstyled {
|
24
|
-
list-style-type: none;
|
25
|
-
margin: 0;
|
26
|
-
padding: 0;
|
27
|
-
}
|
28
|
-
|
29
|
-
body {
|
30
|
-
margin: 40px auto;
|
31
|
-
max-width: 800px;
|
32
|
-
line-height: 1.6;
|
33
|
-
font-size: 18px;
|
34
|
-
color: #444;
|
35
|
-
padding: 0 10px;
|
36
|
-
}
|
37
|
-
|
38
|
-
h1, h2, h3 {
|
39
|
-
line-height: 1.2;
|
40
|
-
}
|
41
|
-
|
42
|
-
header {
|
43
|
-
h1 {
|
44
|
-
margin-bottom: 9px;
|
45
|
-
}
|
46
|
-
|
47
|
-
p {
|
48
|
-
margin-top: 9px;
|
49
|
-
}
|
50
|
-
}
|
51
|
-
|
52
|
-
figure {
|
53
|
-
img {
|
54
|
-
display: block;
|
55
|
-
margin-left: auto;
|
56
|
-
margin-right: auto;
|
57
|
-
vertical-align: top;
|
58
|
-
height: auto;
|
59
|
-
max-width: 100%;
|
60
|
-
}
|
61
|
-
|
62
|
-
figcaption {
|
63
|
-
text-align: center;
|
64
|
-
}
|
65
|
-
}
|
66
|
-
|
67
|
-
nav {
|
68
|
-
a {
|
69
|
-
margin-right: 10px;
|
70
|
-
}
|
71
|
-
|
72
|
-
a.active {
|
73
|
-
color: black !important;
|
74
|
-
}
|
75
|
-
|
76
|
-
span {
|
77
|
-
color: #6f7370;
|
78
|
-
}
|
79
|
-
}
|
80
|
-
|
81
|
-
a {
|
82
|
-
text-decoration: none !important;
|
83
|
-
color: #008083 !important;
|
84
|
-
|
85
|
-
:hover {
|
86
|
-
text-decoration: underline !important;
|
87
|
-
}
|
88
|
-
|
89
|
-
:active {
|
90
|
-
color: #6f7370 !important;
|
91
|
-
}
|
92
|
-
}
|
93
|
-
|
94
|
-
* {
|
95
|
-
// font-family: 'Titillium Web', sans-serif !important;
|
96
|
-
font-family: 'Open Sans', 'sans-serif' !important;
|
97
|
-
}
|
98
|
-
|
99
|
-
code, pre, pre span {
|
100
|
-
font-family: Inconsolata, monospace !important;
|
101
|
-
}
|
102
|
-
|
103
|
-
pre, pre span {
|
104
|
-
font-size: 14px;
|
105
|
-
}
|
106
|
-
|
@@ -1,52 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Jekyll
|
4
|
-
module Recker
|
5
|
-
module Commands
|
6
|
-
# Tweet
|
7
|
-
class Tweet < Jekyll::Command
|
8
|
-
class << self
|
9
|
-
def init_with_program(prog)
|
10
|
-
prog.command(:tweet) do |c|
|
11
|
-
c.syntax 'tweet'
|
12
|
-
c.description 'tweet latest post'
|
13
|
-
c.option 'dry', '-d', '--dry', 'print message instead of tweeting'
|
14
|
-
c.action do |_args, options|
|
15
|
-
client = Jekyll::Recker::Twitter.new(dry: options['dry'])
|
16
|
-
Recker.info 'discovering credentials'
|
17
|
-
client.discover_credentials!
|
18
|
-
Recker.info "tweeting #{client.latest.data['title']}"
|
19
|
-
client.post_latest!
|
20
|
-
rescue ReckerError => e
|
21
|
-
Recker.abort_with e.message
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
# Slack
|
29
|
-
class Slack < Jekyll::Command
|
30
|
-
class << self
|
31
|
-
def init_with_program(prog)
|
32
|
-
prog.command(:slack) do |c|
|
33
|
-
c.syntax 'slack'
|
34
|
-
c.description 'slack latest post'
|
35
|
-
c.option 'dry', '-d', '--dry', 'print message instead of posting'
|
36
|
-
c.action do |_args, options|
|
37
|
-
Recker::Slack.each_in_config(dry: options['dry']) do |client|
|
38
|
-
Recker.info "#{client.key}: discovering webhook"
|
39
|
-
client.discover_webhook!
|
40
|
-
Recker.info "#{client.key}: posting #{client.latest.data['title']}"
|
41
|
-
client.post_latest!
|
42
|
-
end
|
43
|
-
rescue ReckerError => e
|
44
|
-
Recker.abort_with e.message
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Jekyll
|
4
|
-
module Recker
|
5
|
-
module Generators
|
6
|
-
# StatsGenerator
|
7
|
-
class StatsGenerator < Jekyll::Generator
|
8
|
-
def generate(site)
|
9
|
-
Recker.info 'generating site statistics'
|
10
|
-
site.data['stats'] = Stats.crunch(site)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
data/lib/jekyll-recker/log.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Jekyll
|
4
|
-
# Recker
|
5
|
-
module Recker
|
6
|
-
def self.debug(msg)
|
7
|
-
Jekyll.logger.debug("jekyll-recker: #{msg}")
|
8
|
-
end
|
9
|
-
|
10
|
-
def self.info(msg)
|
11
|
-
Jekyll.logger.info("jekyll-recker: #{msg}")
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.error(msg)
|
15
|
-
Jekyll.logger.error("jekyll-recker: #{msg}")
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.abort_with(msg)
|
19
|
-
Jekyll.logger.abort_with("jekyll-recker: #{msg}")
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|