jekyll-recker 0.3.0 → 0.4.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 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