jekyll-recker 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 02b03a8725b047a9fa8eec504729b06027478be280ba31889b078ee695381727
4
- data.tar.gz: e3ba4f4e2a08837835dcc250dd20549428758c8fc863b1cb22f5f9dcf14ba1ae
3
+ metadata.gz: 27007112ff63186d2d55ea50ea4318817aab091824c2657401c8f6b51d0cd7a2
4
+ data.tar.gz: 7cd0e1169baa77572ff3cead226a6a7b03f0e74849bba8e3b362c1eeba39a579
5
5
  SHA512:
6
- metadata.gz: fedf073810e2531159624d42312db8f36329f47ea2051104964fd29fde0f434a51b6556ef619c69eebdf15045827f0bcffc96e03706490a56ea5473dcc4f1aab
7
- data.tar.gz: 68f3ea26ee215eca663f16b315c615056d17bcce983a496735b72965fd367c07311d9c77a88adeba0b8a97c1357df20f935fb684043d2476cfcc446126b1afee
6
+ metadata.gz: 47d59369933cd797ab422071c43f5a62c8619791511931a2c5f4a5aa16539cda1c9fe80f9bee37f57fe877d43a83a027d869b0434a99a5282f48af8f97f99dea
7
+ data.tar.gz: 70ec0f5d69e913b6810b4c5ca57568710d4854285126e51f6a4431b5e53f3f2e893a6e90e58501cba3f4fdc0b509e411901bc8ecdc6789d43dcc01e23534dcfc
data/README.org CHANGED
@@ -41,6 +41,82 @@ bundle exec jekyll serve
41
41
 
42
42
  ** Commands
43
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
+
44
120
  *** =tweet=
45
121
 
46
122
  The =tweet= command tweets a link to the latest published jekyll blog
@@ -71,6 +147,23 @@ Run =bundle exec jekyll tweet= to let it rip!
71
147
 
72
148
  [[assets/images/example-tweet.png]]
73
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
+
74
167
  ** Generators
75
168
 
76
169
  *** =stats=
Binary file
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Jekyll
2
4
  module Recker
3
5
  module Commands
@@ -8,14 +10,15 @@ module Jekyll
8
10
  prog.command(:tweet) do |c|
9
11
  c.syntax 'tweet'
10
12
  c.description 'tweet latest post'
11
- c.action do |args, options|
12
- client = Jekyll::Recker::Twitter.new
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'])
13
16
  Recker.info 'discovering credentials'
14
17
  client.discover_credentials!
15
18
  Recker.info "tweeting #{client.latest.data['title']}"
16
19
  client.post_latest!
17
- rescue => e
18
- abort_with e.message
20
+ rescue ReckerError => e
21
+ Recker.abort_with e.message
19
22
  end
20
23
  end
21
24
  end
@@ -29,8 +32,16 @@ module Jekyll
29
32
  prog.command(:slack) do |c|
30
33
  c.syntax 'slack'
31
34
  c.description 'slack latest post'
32
- c.action do |args, options|
33
- Recker.info 'normally I would slack here'
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
34
45
  end
35
46
  end
36
47
  end
@@ -24,6 +24,10 @@ module Jekyll
24
24
  @site.read
25
25
  @site
26
26
  end
27
+
28
+ def self.latest_post
29
+ @latest_post ||= site.posts.docs.last
30
+ end
27
31
  end
28
32
  end
29
33
  end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module Recker
5
+ # ReckerError
6
+ class ReckerError < StandardError; end
7
+ end
8
+ end
@@ -1,7 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Jekyll
4
+ # Recker
4
5
  module Recker
6
+ def self.debug(msg)
7
+ Jekyll.logger.debug("jekyll-recker: #{msg}")
8
+ end
9
+
5
10
  def self.info(msg)
6
11
  Jekyll.logger.info("jekyll-recker: #{msg}")
7
12
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'open3'
4
+
5
+ module Jekyll
6
+ # Recker
7
+ module Recker
8
+ # ShellCommandFailed
9
+ class ShellCommandFailed < ReckerError; end
10
+
11
+ def self.shell(cmd)
12
+ Recker.debug("running shell command \`#{cmd}\`")
13
+ out, err, status = Open3.capture3(cmd)
14
+ return out if status.success?
15
+
16
+ msg = <<~ERROR
17
+ the command \`#{cmd}\` failed!
18
+ --- exit
19
+ #{status}
20
+ --- stdout
21
+ #{out}
22
+ --- stderr
23
+ #{err}
24
+ ERROR
25
+
26
+ raise ShellCommandFailed, msg
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'slack-notifier'
4
+
5
+ module Jekyll
6
+ # Recker
7
+ module Recker
8
+ # Slack
9
+ class Slack
10
+ def self.each_in_config(dry: false)
11
+ Configuration.slack.map do |key, body|
12
+ yield new(key, body, dry: dry)
13
+ end
14
+ end
15
+
16
+ attr_reader :key
17
+
18
+ def initialize(config_key, config_body, dry: false)
19
+ @key = config_key
20
+ @data = config_body
21
+ @webhook = nil
22
+ @dry = dry
23
+ end
24
+
25
+ def discover_webhook!
26
+ @webhook = ENV["SLACK_#{@key.upcase}_WEBHOOK"] || extract_from_config
27
+ raise ReckerError, 'cannot find slack credentials!' if @webhook.nil?
28
+ end
29
+
30
+ def latest
31
+ @latest ||= Configuration.latest_post
32
+ end
33
+
34
+ def post_latest!
35
+ if @dry
36
+ Recker.info('postign in dry mode, printing message')
37
+ Recker.info("BEGIN MESSAGE\n#{message_body.strip}\nEND MESSAGE")
38
+ else
39
+ ::Slack::Notifier.new(
40
+ @webhook.strip,
41
+ channel: @data.fetch('channel'),
42
+ username: @data.fetch('username'),
43
+ icon_emoji: @data.fetch('emoji')
44
+ ).post(text: message_body)
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ def message_body
51
+ url = File.join Configuration.jekyll['url'], latest.url
52
+ body = <<~MSG
53
+ #{latest.data['date'].strftime('%A, %B %-d %Y')}
54
+ #{latest.data['title']}
55
+ #{url}
56
+ MSG
57
+ ::Slack::Notifier::Util::LinkFormatter.format(body)
58
+ end
59
+
60
+ def extract_from_config
61
+ cmd = @data['webhook_cmd']
62
+ return nil if cmd.nil?
63
+
64
+ Recker.shell(cmd)
65
+ end
66
+ end
67
+ end
68
+ end
@@ -1,28 +1,33 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'twitter'
3
4
 
4
5
  module Jekyll
5
6
  module Recker
6
7
  # Twitter Client
7
8
  class Twitter
8
- class CannotFindCreds < StandardError
9
- def initialize(msg = 'could not find twitter credentials')
10
- super
11
- end
9
+ def initialize(dry: false)
10
+ @dry = dry
12
11
  end
13
12
 
14
13
  def discover_credentials!
15
14
  @creds = extract_from_env || extract_from_config
16
- raise CannotFindCreds if @creds.nil?
15
+ raise ReckerError, 'cannot find twitter credentials!' if @creds.nil?
16
+
17
17
  set_credentials!
18
18
  end
19
19
 
20
20
  def post_latest!
21
- @client.update(tweet_body)
21
+ if @dry
22
+ Recker.info('tweeting in dry mode, printing message')
23
+ Recker.info("BEGIN TWEET\n#{tweet_body.strip}\nEND TWEET")
24
+ else
25
+ @client.update(tweet_body)
26
+ end
22
27
  end
23
28
 
24
29
  def latest
25
- @latest ||= Configuration.site.posts.docs.last
30
+ Configuration.latest_post
26
31
  end
27
32
 
28
33
  private
@@ -47,12 +52,20 @@ module Jekyll
47
52
 
48
53
  def extract_from_env
49
54
  values = cred_fieldnames.map { |k| ENV[k.upcase] }
50
- Hash[cred_fieldnames.zip(values)] unless values.any? { |v| v.nil? || v.empty? }
55
+
56
+ return nil if values.any? { |v| v.nil? || v.empty? }
57
+
58
+ Hash[cred_fieldnames.zip(values)]
51
59
  end
52
60
 
53
61
  def extract_from_config
54
- values = cred_fieldnames.map { |k| shell(Configuration.twitter["#{k}_cmd"]) }
55
- Hash[cred_fieldnames.zip(values)] unless values.any? { |v| v.nil? || v.empty? }
62
+ values = cred_fieldnames.map do |k|
63
+ Recker.shell(Configuration.twitter["#{k}_cmd"])
64
+ end
65
+
66
+ return nil if values.any? { |v| v.nil? || v.empty? }
67
+
68
+ Hash[cred_fieldnames.zip(values)]
56
69
  end
57
70
 
58
71
  def shell(cmd)
@@ -60,11 +73,11 @@ module Jekyll
60
73
  end
61
74
 
62
75
  def cred_fieldnames
63
- [
64
- 'access_token_secret',
65
- 'access_token',
66
- 'consumer_api_key',
67
- 'consumer_api_secret'
76
+ %w[
77
+ access_token_secret
78
+ access_token
79
+ consumer_api_key
80
+ consumer_api_secret
68
81
  ]
69
82
  end
70
83
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Jekyll
4
4
  module Recker
5
- VERSION = '0.3.0'
5
+ VERSION = '0.4.0'
6
6
  end
7
7
  end
data/lib/jekyll-recker.rb CHANGED
@@ -1,12 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'jekyll'
4
+
3
5
  module Jekyll
4
6
  # Recker
5
7
  module Recker
6
8
  require 'jekyll-recker/commands.rb'
7
9
  require 'jekyll-recker/configuration.rb'
10
+ require 'jekyll-recker/error.rb'
8
11
  require 'jekyll-recker/generators.rb'
9
12
  require 'jekyll-recker/log.rb'
13
+ require 'jekyll-recker/shell.rb'
14
+ require 'jekyll-recker/slack.rb'
10
15
  require 'jekyll-recker/stats.rb'
11
16
  require 'jekyll-recker/tags.rb'
12
17
  require 'jekyll-recker/twitter.rb'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-recker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Recker
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '3.8'
27
+ - !ruby/object:Gem::Dependency
28
+ name: slack-notifier
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: twitter
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -84,26 +98,20 @@ files:
84
98
  - _layouts/page.html
85
99
  - _layouts/post.html
86
100
  - _sass/jekyll-recker.sass
101
+ - assets/images/example-slack.png
87
102
  - assets/images/example-stats.png
88
103
  - assets/images/example-tweet.png
89
104
  - assets/images/me.jpg
90
105
  - assets/images/words.png
91
106
  - assets/jekyll-recker.scss
92
- - lib/blog.rb
93
- - lib/blog/cli.rb
94
- - lib/blog/config.rb
95
- - lib/blog/entry.rb
96
- - lib/blog/git.rb
97
- - lib/blog/jekyll.rb
98
- - lib/blog/journal.rb
99
- - lib/blog/log.rb
100
- - lib/blog/slack.rb
101
- - lib/blog/words.rb
102
107
  - lib/jekyll-recker.rb
103
108
  - lib/jekyll-recker/commands.rb
104
109
  - lib/jekyll-recker/configuration.rb
110
+ - lib/jekyll-recker/error.rb
105
111
  - lib/jekyll-recker/generators.rb
106
112
  - lib/jekyll-recker/log.rb
113
+ - lib/jekyll-recker/shell.rb
114
+ - lib/jekyll-recker/slack.rb
107
115
  - lib/jekyll-recker/stats.rb
108
116
  - lib/jekyll-recker/tags.rb
109
117
  - lib/jekyll-recker/twitter.rb
data/lib/blog/cli.rb DELETED
@@ -1,102 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'commander'
4
- require 'fileutils'
5
-
6
- module Blog
7
- # CLI
8
- class CLI
9
- include Commander::Methods
10
-
11
- def logger
12
- Blog::Log.logger
13
- end
14
-
15
- def config_path
16
- @config_path ||= File.expand_path '~/.blog.yml'
17
- end
18
-
19
- def config
20
- Blog::Config.load_from_file(config_path)
21
- end
22
-
23
- def journal
24
- @journal ||= Blog::Journal.from_file(config.journal_path)
25
- end
26
-
27
- def latest
28
- @latest ||= journal.public_entries.first
29
- end
30
-
31
- def build
32
- logger.info "deleting #{config.site_dir.pretty_path}"
33
- FileUtils.rm_rf(config.site_dir)
34
- logger.info "parsing #{config.journal_path.pretty_path}"
35
- journal = Blog::Journal.from_file(config.journal_path)
36
- logger.info "writing #{journal.public_entries.count.pretty} public entries"
37
- journal.write_public_entries! config.posts_dir
38
- logger.info "building jekyll"
39
- Blog::Jekyll.build(config)
40
- end
41
-
42
- def commit
43
- git = Blog::Git.new(config.blog_repo)
44
- git.run!
45
- end
46
-
47
- def slack
48
- logger.info "fetched latest entry: #{latest.excerpt}"
49
- config.slacks.each do |info|
50
- Blog::Slacky.post(latest, `#{info['webhook_cmd']}`, info)
51
- end
52
- end
53
-
54
- def run
55
- program :name, 'blog'
56
- program :version, 'v0.0.0'
57
- program :description, 'script to generate and publish my blog'
58
-
59
- default_command :all
60
-
61
- global_option '--config FILE', String, 'path to blog.yml' do |file|
62
- @config_path = file
63
- end
64
-
65
- command :build do |c|
66
- c.syntax = 'build'
67
- c.description = 'build jekyll site'
68
- c.action do |_args, _options|
69
- build
70
- end
71
- end
72
-
73
- command :commit do |c|
74
- c.syntax = 'commit'
75
- c.description = 'commit and push new post'
76
- c.action do |_args, _options|
77
- commit
78
- end
79
- end
80
-
81
- command :slack do |c|
82
- c.syntax = 'slack'
83
- c.description = 'send slack notifications'
84
- c.action do |_args, _options|
85
- slack
86
- end
87
- end
88
-
89
- command :all do |c|
90
- c.syntax = 'all'
91
- c.description = 'build, commit, and slack'
92
- c.action do |_args, _options|
93
- build
94
- commit
95
- slack
96
- end
97
- end
98
-
99
- run!
100
- end
101
- end
102
- end
data/lib/blog/config.rb DELETED
@@ -1,67 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler'
4
- require 'yaml'
5
-
6
- module Blog
7
- # Config
8
- class Config
9
- attr_reader :data
10
-
11
- def self.load_from_file(config_path = File.expand_path('~/.blog.yml'))
12
- new(YAML.load_file(config_path) || {})
13
- end
14
-
15
- def initialize(data)
16
- @data = data
17
- end
18
-
19
- def journal_path
20
- File.join blog_repo, 'journal.org'
21
- end
22
-
23
- def posts_dir
24
- File.join blog_repo, '_posts'
25
- end
26
-
27
- def site_dir
28
- File.join(File.expand_path(blog_repo), '_site')
29
- end
30
-
31
- def blog_repo
32
- Bundler.root.to_s
33
- end
34
-
35
- def stats_path
36
- File.join blog_repo, '_data/stats.json'
37
- end
38
-
39
- def log_level
40
- @data.fetch('log_level', 'INFO').upcase
41
- end
42
-
43
- def twitter_creds
44
- twitter = @data.fetch('twitter')
45
- creds = {}
46
- [
47
- 'access_token_secret',
48
- 'access_token',
49
- 'consumer_api_key',
50
- 'consumer_api_secret'
51
- ].each do |key|
52
- creds[key] = `#{twitter.fetch(key + '_cmd')}`.strip
53
- end
54
- creds
55
- end
56
-
57
- def slacks
58
- @data.fetch('slacks', [])
59
- end
60
-
61
- private
62
-
63
- def missing_fields
64
- required_keys.reject { |k| @data.key? k }
65
- end
66
- end
67
- end
data/lib/blog/entry.rb DELETED
@@ -1,68 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'date'
4
- require 'org-ruby'
5
-
6
- module Blog
7
- # Entry
8
- class Entry
9
- def initialize(headline)
10
- @headline = headline
11
- end
12
-
13
- def title
14
- date.strftime('%A, %B %-e %Y')
15
- end
16
-
17
- def subtitle
18
- @subtitle ||= @headline.headline_text.split(' ').drop(2).join(' ')
19
- end
20
-
21
- alias excerpt subtitle
22
-
23
- def tags
24
- @tags ||= @headline.tags
25
- end
26
-
27
- def date
28
- @date ||= Date.strptime(
29
- @headline.headline_text.split(' ').take(2).join(' '),
30
- '%Y-%m-%d %A'
31
- )
32
- end
33
-
34
- def date_slug
35
- date.strftime('%Y-%m-%d')
36
- end
37
-
38
- def public?
39
- !tags.include? 'private'
40
- end
41
-
42
- def filename
43
- "#{date_slug}-#{date_slug}.html.html"
44
- end
45
-
46
- def permalink
47
- "https://www.alexrecker.com/#{date_slug}.html"
48
- end
49
-
50
- def body_text
51
- @headline.body_lines.drop(1).collect(&:output_text).join(' ')
52
- end
53
-
54
- def body_html
55
- Orgmode::Parser.new(body_text).to_html
56
- end
57
-
58
- def to_html
59
- <<~HTML
60
- ---
61
- title: #{title}
62
- excerpt: #{excerpt}
63
- ---
64
- #{body_html}
65
- HTML
66
- end
67
- end
68
- end
data/lib/blog/git.rb DELETED
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'git'
4
-
5
- module Blog
6
- # Git
7
- class Git
8
- attr_reader :client
9
-
10
- def initialize(path)
11
- @client = ::Git.open(path)
12
- @logger = Blog::Log.logger
13
- end
14
-
15
- def run!
16
- commit!
17
- end
18
-
19
- def commit!
20
- commit = '[auto] Automatic Publish'
21
- @logger.info "writing commit: #{commit}"
22
- @client.add
23
- @client.commit(commit)
24
- @logger.info 'pushing commit'
25
- @client.push
26
- end
27
- end
28
- end
data/lib/blog/jekyll.rb DELETED
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'jekyll'
4
-
5
- module Blog
6
- module Jekyll
7
- def self.build(config)
8
- conf = ::Jekyll.configuration(
9
- {
10
- 'source' => config.blog_repo,
11
- 'destination' => config.site_dir
12
- }
13
- )
14
- ::Jekyll::Site.new(conf).process
15
- end
16
- end
17
- end
data/lib/blog/journal.rb DELETED
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'org-ruby'
4
-
5
- module Blog
6
- # Journal
7
- class Journal
8
- def self.from_file(path)
9
- new(Orgmode::Parser.load(path))
10
- end
11
-
12
- def logger
13
- Blog::Log.logger
14
- end
15
-
16
- def initialize(parser)
17
- @parser = parser
18
- end
19
-
20
- def public_entries
21
- @public_entries ||= all_entries.select(&:public?).sort_by(&:date).reverse
22
- end
23
-
24
- def private_entries
25
- @private_entries ||= all_entries.reject(&:public?).sort_by(&:date).reverse
26
- end
27
-
28
- def write_public_entries!(dir)
29
- public_entries.each do |entry|
30
- target = File.join(dir, entry.filename)
31
- logger.debug "writing #{entry.title} to #{target.pretty_path}"
32
- File.open(target, 'w+') { |f| f.write(entry.to_html) }
33
- end
34
- end
35
-
36
- def all_entries
37
- entry_headlines.map { |h| Entry.new(h) }
38
- end
39
-
40
- private
41
-
42
- def entry_headlines
43
- @parser.headlines.select { |h| h.level == 3 }
44
- end
45
- end
46
- end
data/lib/blog/log.rb DELETED
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'logger'
4
-
5
- module Blog
6
- # Log
7
- module Log
8
- def self.logger
9
- @logger ||= default_logger
10
- end
11
-
12
- def self.default_logger
13
- logger = Logger.new(STDOUT)
14
- logger.level = Logger::INFO
15
- logger.formatter = proc do |severity, _datetime, _progname, msg|
16
- "blog: #{msg}\n"
17
- end
18
- logger
19
- end
20
-
21
- def self.level=(setting)
22
- @logger.level = case setting.upcase
23
- when 'DEBUG'
24
- Logger::DEBUG
25
- else
26
- Logger::INFO
27
- end
28
- end
29
- end
30
- end
data/lib/blog/slack.rb DELETED
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'slack-notifier'
4
-
5
- module Blog
6
- # Slack
7
- module Slacky
8
- def self.post(entry, url, info)
9
- notifier = ::Slack::Notifier.new(
10
- url.strip,
11
- channel: info['channel'],
12
- username: info['username'],
13
- icon_emoji: ':reckerbot:'
14
- )
15
- message = "#{entry.title} - #{entry.excerpt}\n#{entry.permalink}"
16
- Slack::Notifier::Util::LinkFormatter.format(message)
17
- notifier.post text: message
18
- end
19
- end
20
- end
data/lib/blog/words.rb DELETED
@@ -1,80 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Blog
4
- # Words
5
- module Words
6
- def self.array_to_and_list(array)
7
- case array.length
8
- when 0
9
- ''
10
- when 1
11
- array.first
12
- when 2
13
- "#{array.first} and #{array.last}"
14
- else
15
- array[0...-1].join(', ') + ", and #{array.last}"
16
- end
17
- end
18
-
19
- def self.and_list_to_array(str)
20
- str = str.gsub(' and ', ', ')
21
- str.split(',').map(&:strip).reject(&:empty?)
22
- end
23
-
24
- def self.prettify_number(number)
25
- number.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
26
- end
27
-
28
- def self.prettify_path(path, home = nil)
29
- home ||= File.expand_path('~/')
30
- path.sub(home, '~')
31
- end
32
-
33
- def self.to_word_list(str)
34
- str.split(' ')
35
- end
36
-
37
- def self.to_weighted_list(arr)
38
- arr.uniq.map do |word|
39
- [word, arr.count(word)]
40
- end
41
- end
42
- end
43
- end
44
-
45
- # Array extensions
46
- class Array
47
- def to_and_list
48
- Blog::Words.array_to_and_list(self)
49
- end
50
-
51
- def to_weighted_list
52
- Blog::Words.to_weighted_list(self)
53
- end
54
- end
55
-
56
- # Integer extensions
57
- class Integer
58
- def pretty
59
- Blog::Words.prettify_number(self)
60
- end
61
- end
62
-
63
- # String extensions
64
- class String
65
- def words
66
- Blog::Words.to_word_list(self)
67
- end
68
-
69
- def word_count
70
- Blog::Words.to_word_list(self).count
71
- end
72
-
73
- def pretty_path(home = nil)
74
- Blog::Words.prettify_path(self, home)
75
- end
76
-
77
- def to_and_array
78
- Blog::Words.and_list_to_array(self)
79
- end
80
- end
data/lib/blog.rb DELETED
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Blog
4
- module Blog
5
- require_relative 'blog/cli'
6
- require_relative 'blog/config'
7
- require_relative 'blog/entry'
8
- require_relative 'blog/git'
9
- require_relative 'blog/jekyll'
10
- require_relative 'blog/journal'
11
- require_relative 'blog/log'
12
- require_relative 'blog/slack'
13
- require_relative 'blog/words'
14
- end