jekyll-recker 1.10.0 → 1.16.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: 9e61434d17d1a940324300e971e46521b5775f0831090a0f0f7ff7a7d6779bdb
4
- data.tar.gz: bfa3635b5fb0e128347216e4855904252b172147172ef4e3176d348947d3fbbf
3
+ metadata.gz: 5134c19a248e628a2709daf01227163084bfb2dfd81e8d7c828324dddbd13e2d
4
+ data.tar.gz: 9710e3c11ea62dda0707dedd0c9771fd8f802682f36140ef4e59af07a6f7aaa9
5
5
  SHA512:
6
- metadata.gz: '094e0465155a843d4e3955700ca6244dff42b88a3d6b28860371ed0ab6a4e970f1c7b97b1d1750b9bfbb06ac51ee691b308420ad49b1e6da84393253d872f7f9'
7
- data.tar.gz: 7a944d6f918a52b903715ab6034704ee244d59fffc2a0d929983cbb4427e165387d55c508b3e62d8b9d641cc45bf94e23ac450ff75b625aa9748cea905144595
6
+ metadata.gz: 7767ff61b4b0ec54f646b207b4742f7f5b1a94d684d78bfa4f9a00ff0920f097c3e3a28106b847bddcebc0105eb9b65794c0adb9cc8e15f3235bac769454d7c7
7
+ data.tar.gz: f45942a90efd38657dc4b8fe81073c20b19a6ed2c22eb6e4b46e48c00807f458b429dd28e45a888f4836f728ad8e56251cc56f45c5a2108496e135275a75088e
@@ -1,5 +1,10 @@
1
1
  <nav>
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>
4
- <span class="float-right hide-on-mobile">{{ page.slug }}</span>
2
+ <a href="{{ site.baseurl }}/" class="{% if page.active == 'index' %}active{% endif %} lowercase">
3
+ 🏠 Home
4
+ </a>
5
+ <a href="{{ site.baseurl }}/stats.html" class="{% if page.active == 'stats' %}active{% endif %} lowercase">
6
+ 🖩 Stats
7
+ </a>
8
+ <a class="lowercase" href="{{ site.baseurl }}/feed.xml">🛰️ RSS</a>
9
+ <a class="lowercase" href="https://cookbook.reckerfamily.com">👨‍🍳 Cookbook</a>
5
10
  </nav>
@@ -0,0 +1,121 @@
1
+ ---
2
+ ---
3
+ @import "https://fonts.googleapis.com/css?family=Inconsolata|Open+Sans&display=swap";
4
+
5
+ // color
6
+ $color-accent: #008083;
7
+ $color-black: #444;
8
+ $color-passive: #6f7370;
9
+
10
+ // font
11
+ $font-regular: Open Sans, sans-serif;
12
+ $font-regular-color: $color-black;
13
+ $font-regular-size: 20px;
14
+ $font-caption-size: 18px;
15
+ $font-code: monospace;
16
+ $font-code-size: 18px;
17
+
18
+ .float {
19
+ &-right {
20
+ float: right;
21
+ }
22
+
23
+ &-left {
24
+ float: left;
25
+ }
26
+ }
27
+
28
+ .lowercase {
29
+ text-transform: lowercase;
30
+ }
31
+
32
+ @media (max-width: 600px) {
33
+ .hide-on-mobile {
34
+ display: none;
35
+ }
36
+ }
37
+
38
+ .clearfix::after {
39
+ content: "";
40
+ clear: both;
41
+ display: block;
42
+ }
43
+
44
+ body {
45
+
46
+ -webkit-font-smoothing: antialiased;
47
+ -moz-osx-font-smoothing: grayscale;
48
+
49
+ color: $font-regular-color;
50
+ font-family: $font-regular;
51
+ font-size: $font-regular-size;
52
+ margin: 40px auto;
53
+ max-width: 800px;
54
+ line-height: 1.6;
55
+ padding: 0 10px;
56
+
57
+ header {
58
+ h1 {
59
+ margin-bottom: 9px;
60
+ }
61
+ }
62
+
63
+ nav {
64
+ a {
65
+ margin-right: 10px
66
+ }
67
+
68
+ span {
69
+ color: $color-passive;
70
+ }
71
+ }
72
+
73
+ a {
74
+ color: $color-accent;
75
+ text-decoration: none;
76
+
77
+ &.active {
78
+ color: $color-black;
79
+ }
80
+ }
81
+
82
+ h1, h2, h3 {
83
+ line-height: 1.2
84
+ }
85
+
86
+ p {
87
+ margin-top: 9px;
88
+ }
89
+
90
+ ul {
91
+ list-style-type: none;
92
+ margin: 0;
93
+ padding: 0;
94
+ }
95
+
96
+ figure {
97
+ img {
98
+ display: block;
99
+ margin-left: auto;
100
+ margin-right: auto;
101
+ vertical-align: top;
102
+ height: auto;
103
+ max-width: 100%;
104
+ }
105
+ }
106
+
107
+ figcaption {
108
+ color: $color-passive;
109
+ font-size: $font-caption-size;
110
+ text-align: center;
111
+ }
112
+
113
+ blockquote {
114
+ color: $color-passive;
115
+ }
116
+
117
+ code, pre, pre span {
118
+ font-family: $font-code;
119
+ font-size: $font-code-size;
120
+ }
121
+ }
@@ -6,8 +6,6 @@ require 'jekyll'
6
6
  #
7
7
  # The greatest jekyll plugin in the world
8
8
  module JekyllRecker
9
- autoload :Configuration, 'jekyll_recker/configuration.rb'
10
- autoload :Error, 'jekyll_recker/error.rb'
11
9
  autoload :Mixins, 'jekyll_recker/mixins.rb'
12
10
  autoload :Shell, 'jekyll_recker/shell.rb'
13
11
  autoload :Social, 'jekyll_recker/social.rb'
@@ -3,7 +3,7 @@
3
3
  module JekyllRecker
4
4
  # Commands
5
5
  module Commands
6
- # Share
6
+ # Share Command
7
7
  class Share < Jekyll::Command
8
8
  include Mixins::Logging
9
9
 
@@ -17,8 +17,11 @@ module JekyllRecker
17
17
  end
18
18
 
19
19
  def self.action(args, options)
20
- JekyllRecker::Social.action(args, options)
21
- rescue ::JekyllRecker::Error => e
20
+ site = Jekyll::Site.new(configuration_from_options(options))
21
+ site.reset
22
+ site.read
23
+ Social.action(site, args, options)
24
+ rescue StandardError => e
22
25
  logger.error e.message
23
26
  exit 1
24
27
  end
@@ -1,7 +1,50 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'fastimage'
4
+ require 'mini_magick'
5
+
3
6
  module JekyllRecker
4
7
  module Generators
8
+ # Image Resize Generator
9
+ class ImageResize < Jekyll::Generator
10
+ include Mixins::Logging
11
+
12
+ def generate(site)
13
+ @site = site
14
+ logger.info 'checking images'
15
+ resizeable_images.each do |f, d|
16
+ logger.info "resizing #{f} to fit #{d}"
17
+ image = MiniMagick::Image.new(f)
18
+ image.resize d
19
+ end
20
+ end
21
+
22
+ def image?(file)
23
+ ['.jpg', 'jpeg', '.png', '.svg'].include? File.extname(file)
24
+ end
25
+
26
+ def too_big?(width, height)
27
+ width > 800 || height > 800
28
+ end
29
+
30
+ def images
31
+ @site.static_files.collect(&:path).select { |f| image?(f) }
32
+ end
33
+
34
+ def resizeable_images
35
+ with_sizes = images.map { |f| [f, FastImage.size(f)].flatten }
36
+ with_sizes.select! { |f| too_big?(f[1], f[2]) }
37
+ with_sizes.map do |f, w, h|
38
+ dimensions = if w > h
39
+ '800x600'
40
+ else
41
+ '600x800'
42
+ end
43
+ [f, dimensions]
44
+ end
45
+ end
46
+ end
47
+
5
48
  # Stats Module
6
49
  #
7
50
  # Functions for stats generators.
@@ -106,5 +149,67 @@ module JekyllRecker
106
149
  entries.collect(&:date).map { |t| Date.new(t.year, t.month, t.day) }.sort.reverse
107
150
  end
108
151
  end
152
+
153
+ # Swear Count Generator
154
+ class Swears < Jekyll::Generator
155
+ include Stats
156
+
157
+ KEY = 'swears'
158
+
159
+ def crunch
160
+ results = Hash.new(0)
161
+ entries.collect(&:content).map(&:split).each do |words|
162
+ words = words.map(&:downcase)
163
+ swears.each do |swear|
164
+ count = words.count(swear)
165
+ results[swear] += count
166
+ end
167
+ end
168
+ results.reject { |_k, v| v.zero? }.sort_by { |_k, v| -v }
169
+ end
170
+
171
+ private
172
+
173
+ def swears
174
+ [
175
+ 'ass',
176
+ 'asshole',
177
+ 'booger',
178
+ 'crap',
179
+ 'damn',
180
+ 'fart',
181
+ 'fuck',
182
+ 'hell',
183
+ 'jackass',
184
+ 'piss',
185
+ 'poop',
186
+ 'shit',
187
+ ]
188
+ end
189
+ end
190
+
191
+ # Memory Size Generator
192
+ class Memory < Jekyll::Generator
193
+ include Stats
194
+
195
+ KEY = 'memory'
196
+
197
+ def crunch
198
+ results = Hash.new(0)
199
+ entries.each do |entry|
200
+ results['chars'] += entry.content.size
201
+ results['spaces'] += entry.content.count(' ')
202
+ results['size'] += entry.content.bytes.to_a.length
203
+ end
204
+ results['size'] = bytes_to_megabytes(results['size'])
205
+ results
206
+ end
207
+
208
+ private
209
+
210
+ def bytes_to_megabytes(bytes)
211
+ (bytes / (1024.0 * 1024.0)).to_f.round(4)
212
+ end
213
+ end
109
214
  end
110
215
  end
@@ -4,25 +4,6 @@ require 'logger'
4
4
 
5
5
  module JekyllRecker
6
6
  module Mixins
7
- # Introspection
8
- #
9
- # Adds functions which let the class see things about itself.
10
- module Introspection
11
- def self.included(base)
12
- base.extend(self)
13
- end
14
-
15
- # Get the class instance
16
- def class_name
17
- self.class.name.split('::').last
18
- end
19
-
20
- # Get a list of all classes which inherit from this class
21
- def descendants
22
- ObjectSpace.each_object(Class).select { |klass| klass < self }
23
- end
24
- end
25
-
26
7
  # Logging
27
8
  module Logging
28
9
  def self.included(base)
@@ -5,9 +5,6 @@ require 'open3'
5
5
  module JekyllRecker
6
6
  # Shell
7
7
  module Shell
8
- # ShellCommandFailed
9
- class ShellCommandFailed < JekyllRecker::Error; end
10
-
11
8
  def self.run(cmd)
12
9
  out, err, status = Open3.capture3(cmd)
13
10
  return out if status.success?
@@ -22,7 +19,7 @@ module JekyllRecker
22
19
  #{err}
23
20
  ERROR
24
21
 
25
- raise ShellCommandFailed, msg
22
+ raise msg
26
23
  end
27
24
  end
28
25
  end
@@ -5,21 +5,21 @@ require 'twitter'
5
5
 
6
6
  module JekyllRecker
7
7
  module Social
8
- def self.action(args, options)
8
+ def self.action(site, args, options)
9
9
  args += %w[slack twitter] if args.empty?
10
- Slack.share(dry: options['dry']) if args.include?('slack')
11
- Twitter.share(dry: options['dry']) if args.include?('twitter')
10
+ Slack.share(site, dry: options['dry']) if args.include?('slack')
11
+ Twitter.share(site, dry: options['dry']) if args.include?('twitter')
12
12
  end
13
+
13
14
  # Backend
14
15
  #
15
16
  # Backend base class for social sharing backends.
16
17
  # @abstract
17
18
  class Share
18
- include Mixins::Introspection
19
19
  include Mixins::Logging
20
20
 
21
- def self.share(dry: false)
22
- backend = new(dry: dry)
21
+ def self.share(site, dry: false)
22
+ backend = new(site, dry: dry)
23
23
  logger.info "#{backend.name} - building configuration"
24
24
  backend.configure!
25
25
 
@@ -27,7 +27,8 @@ module JekyllRecker
27
27
  backend.post!
28
28
  end
29
29
 
30
- def initialize(dry: false)
30
+ def initialize(site, dry: false)
31
+ @site = site
31
32
  @dry = dry
32
33
  end
33
34
 
@@ -36,25 +37,25 @@ module JekyllRecker
36
37
  end
37
38
 
38
39
  def config
39
- @config ||= JekyllRecker::Configuration.recker.fetch(config_key)
40
+ @site.config.fetch('recker', {}).fetch(config_key, {})
40
41
  end
41
42
 
42
43
  def config_key
43
- class_name.downcase
44
+ self.class.const_get(:KEY)
44
45
  end
45
- alias name config_key
46
+ alias name :config_key
46
47
 
47
48
  def post_body
48
- url = File.join Configuration.jekyll['url'], latest.url
49
+ url = File.join @site.config['url'], latest.url
49
50
  <<~BODY
50
- #{latest.data['date'].strftime('%A, %B %-d %Y')}
51
- #{latest.data['title']}
52
- #{url}
53
- BODY
51
+ #{latest.data['date'].strftime('%A, %B %-d %Y')}
52
+ #{latest.data['title']}
53
+ #{url}
54
+ BODY
54
55
  end
55
56
 
56
57
  def latest
57
- @latest ||= Configuration.latest_post
58
+ @latest ||= @site.posts.docs.last
58
59
  end
59
60
 
60
61
  def latest_title
@@ -74,12 +75,14 @@ module JekyllRecker
74
75
  #
75
76
  # Slack social sharing backend
76
77
  class Slack < Share
78
+ KEY = 'slack'
79
+
77
80
  def configure!
78
81
  @creds = {}
79
82
  workspaces.each do |key, data|
80
83
  webhook = ENV["SLACK_#{key.upcase}_WEBHOOK"] || extract_from_config(data)
81
84
  if webhook.nil?
82
- raise ReckerError, "cannot find slack webhook for #{key} workspace!"
85
+ raise "cannot find slack webhook for #{key} workspace!"
83
86
  end
84
87
 
85
88
  @creds[key] = webhook
@@ -121,9 +124,11 @@ module JekyllRecker
121
124
  #
122
125
  # Twitter social sharing backend
123
126
  class Twitter < Share
127
+ KEY = 'twitter'
128
+
124
129
  def configure!
125
130
  creds = extract_from_env || extract_from_config
126
- raise ReckerError, 'cannot find twitter credentials!' if creds.nil?
131
+ raise 'cannot find twitter credentials!' if creds.nil?
127
132
 
128
133
  @client = ::Twitter::REST::Client.new do |settings|
129
134
  settings.consumer_key = creds['consumer_api_key']
@@ -154,7 +159,7 @@ module JekyllRecker
154
159
 
155
160
  def extract_from_config
156
161
  values = cred_fieldnames.map do |k|
157
- Shell.run(Configuration.twitter["#{k}_cmd"]).strip
162
+ Shell.run(config["#{k}_cmd"]).strip
158
163
  end
159
164
 
160
165
  return nil if values.any? { |v| v.nil? || v.empty? }
@@ -163,11 +168,11 @@ module JekyllRecker
163
168
  end
164
169
 
165
170
  def cred_fieldnames
166
- [
167
- 'access_token_secret',
168
- 'access_token',
169
- 'consumer_api_key',
170
- 'consumer_api_secret'
171
+ %w[
172
+ access_token_secret
173
+ access_token
174
+ consumer_api_key
175
+ consumer_api_secret
171
176
  ]
172
177
  end
173
178
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JekyllRecker
4
- VERSION = '1.10.0'
4
+ VERSION = '1.16.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-recker
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.10.0
4
+ version: 1.16.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-07-10 00:00:00.000000000 Z
11
+ date: 2020-07-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bump
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: fastimage
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: jekyll
99
113
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +122,20 @@ dependencies:
108
122
  - - "~>"
109
123
  - !ruby/object:Gem::Version
110
124
  version: '3.8'
125
+ - !ruby/object:Gem::Dependency
126
+ name: mini_magick
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'
111
139
  - !ruby/object:Gem::Dependency
112
140
  name: slack-notifier
113
141
  requirement: !ruby/object:Gem::Requirement
@@ -154,10 +182,9 @@ files:
154
182
  - _layouts/home.html
155
183
  - _layouts/page.html
156
184
  - _layouts/post.html
185
+ - assets/jekyll-recker.scss
157
186
  - lib/jekyll-recker.rb
158
187
  - lib/jekyll_recker/commands.rb
159
- - lib/jekyll_recker/configuration.rb
160
- - lib/jekyll_recker/error.rb
161
188
  - lib/jekyll_recker/filters.rb
162
189
  - lib/jekyll_recker/generators.rb
163
190
  - lib/jekyll_recker/mixins.rb
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module JekyllRecker
4
- # Configuration
5
- module Configuration
6
- def self.jekyll
7
- @jekyll ||= Jekyll.configuration
8
- end
9
-
10
- def self.recker
11
- jekyll.fetch('recker', {})
12
- end
13
-
14
- def self.facebook
15
- recker.fetch('facebook', {})
16
- end
17
-
18
- def self.twitter
19
- recker.fetch('twitter', {})
20
- end
21
-
22
- def self.slack
23
- recker.fetch('slack', {})
24
- end
25
-
26
- def self.site
27
- @site = Jekyll::Site.new(jekyll)
28
- @site.reset
29
- @site.read
30
- @site
31
- end
32
-
33
- def self.latest_post
34
- @latest_post ||= site.posts.docs.last
35
- end
36
- end
37
- end
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module JekyllRecker
4
- # Error
5
- class Error < StandardError; end
6
- end