jekyll-recker 1.16.0 → 2.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 +4 -4
- data/lib/jekyll-recker.rb +6 -1
- data/lib/jekyll_recker/commands.rb +2 -2
- data/lib/jekyll_recker/date.rb +25 -0
- data/lib/jekyll_recker/entry.rb +44 -0
- data/lib/jekyll_recker/filters.rb +1 -3
- data/lib/jekyll_recker/generators.rb +80 -161
- data/lib/jekyll_recker/graphs.rb +92 -0
- data/lib/jekyll_recker/logging.rb +20 -0
- data/lib/jekyll_recker/math.rb +23 -0
- data/lib/jekyll_recker/site.rb +75 -0
- data/lib/jekyll_recker/social.rb +35 -28
- data/lib/jekyll_recker/tags.rb +5 -4
- data/lib/jekyll_recker/version.rb +1 -1
- metadata +9 -156
- data/LICENSE +0 -674
- data/README.md +0 -105
- data/_includes/figure.html +0 -14
- data/_includes/footer.html +0 -14
- data/_includes/head.html +0 -21
- data/_includes/header.html +0 -4
- data/_includes/nav.html +0 -10
- data/_includes/pager.html +0 -13
- data/_layouts/home.html +0 -13
- data/_layouts/page.html +0 -13
- data/_layouts/post.html +0 -20
- data/assets/jekyll-recker.scss +0 -121
- data/lib/jekyll_recker/mixins.rb +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f3c029100fd9fc95b7f7b065e17bbb5cd2baf321fd0b3f93aeac96505e816d6
|
4
|
+
data.tar.gz: f66cd31401dd09fd965f34372c117dd26ab582cb8d761d5a00fa1a41352c3e31
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2171c0a55cb2e419ae0c120880fef8e11fd4d01b554327f2adca939f8a92c5c0e0b37934acf58d64bbf276688cc7785aa4c06b46db5a224be721b71a0a3d4805
|
7
|
+
data.tar.gz: f07aadca9f824b3c22bcbca26c208fe29e1ffa6fee993984263456f951d861d58ec2697aed963a9bbd7924c3d8b6282ef2f6857f335ab8a343b3486fef039e88
|
data/lib/jekyll-recker.rb
CHANGED
@@ -6,8 +6,13 @@ require 'jekyll'
|
|
6
6
|
#
|
7
7
|
# The greatest jekyll plugin in the world
|
8
8
|
module JekyllRecker
|
9
|
-
autoload :
|
9
|
+
autoload :Date, 'jekyll_recker/date.rb'
|
10
|
+
autoload :Entry, 'jekyll_recker/entry.rb'
|
11
|
+
autoload :Graphs, 'jekyll_recker/graphs.rb'
|
12
|
+
autoload :Logging, 'jekyll_recker/logging.rb'
|
13
|
+
autoload :Math, 'jekyll_recker/math.rb'
|
10
14
|
autoload :Shell, 'jekyll_recker/shell.rb'
|
15
|
+
autoload :Site, 'jekyll_recker/site.rb'
|
11
16
|
autoload :Social, 'jekyll_recker/social.rb'
|
12
17
|
autoload :VERSION, 'jekyll_recker/version.rb'
|
13
18
|
|
@@ -5,7 +5,7 @@ module JekyllRecker
|
|
5
5
|
module Commands
|
6
6
|
# Share Command
|
7
7
|
class Share < Jekyll::Command
|
8
|
-
include
|
8
|
+
include Logging
|
9
9
|
|
10
10
|
def self.init_with_program(prog)
|
11
11
|
prog.command(:share) do |c|
|
@@ -17,7 +17,7 @@ module JekyllRecker
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def self.action(args, options)
|
20
|
-
site = Jekyll::Site.new(configuration_from_options(options))
|
20
|
+
site = ::Jekyll::Site.new(configuration_from_options(options))
|
21
21
|
site.reset
|
22
22
|
site.read
|
23
23
|
Social.action(site, args, options)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JekyllRecker
|
4
|
+
# Date Module
|
5
|
+
module Date
|
6
|
+
def slice_by_consecutive(dates)
|
7
|
+
dates.slice_when { |p, c| c != p - 1 && c != p + 1 }.to_a
|
8
|
+
end
|
9
|
+
|
10
|
+
def calculate_streaks(dates)
|
11
|
+
slice_by_consecutive(dates).map do |pair|
|
12
|
+
first, last = pair.minmax
|
13
|
+
{
|
14
|
+
'days' => (last - first).to_i,
|
15
|
+
'start' => first,
|
16
|
+
'end' => last
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def time_to_date(time)
|
22
|
+
::Date.parse(time.strftime('%Y-%m-%d'))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JekyllRecker
|
4
|
+
# Entry
|
5
|
+
class Entry
|
6
|
+
include Date
|
7
|
+
include Filters
|
8
|
+
|
9
|
+
def initialize(doc)
|
10
|
+
@doc = doc
|
11
|
+
end
|
12
|
+
|
13
|
+
def content
|
14
|
+
@doc.content
|
15
|
+
end
|
16
|
+
|
17
|
+
def date
|
18
|
+
@date ||= time_to_date(@doc.date)
|
19
|
+
end
|
20
|
+
|
21
|
+
def title
|
22
|
+
uyd_date(date)
|
23
|
+
end
|
24
|
+
|
25
|
+
def subtitle
|
26
|
+
@doc.data['title']
|
27
|
+
end
|
28
|
+
|
29
|
+
def url
|
30
|
+
@doc.url
|
31
|
+
end
|
32
|
+
|
33
|
+
def words
|
34
|
+
content.split.map do |token|
|
35
|
+
token.gsub!(/[^0-9a-z ']/i, '')
|
36
|
+
token.downcase
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def word_count
|
41
|
+
@word_count ||= words.size
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -3,12 +3,10 @@
|
|
3
3
|
module JekyllRecker
|
4
4
|
# Filters
|
5
5
|
module Filters
|
6
|
-
# Converts a date object to standard Uhh Yeah Dude format.
|
7
6
|
def uyd_date(date)
|
8
|
-
date.strftime('%A, %B
|
7
|
+
date.strftime('%A, %B %-d %Y')
|
9
8
|
end
|
10
9
|
|
11
|
-
# Adds commas to a number
|
12
10
|
def pretty(num)
|
13
11
|
num.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
|
14
12
|
end
|
@@ -1,214 +1,133 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'fastimage'
|
4
|
-
require 'mini_magick'
|
5
|
-
|
6
3
|
module JekyllRecker
|
4
|
+
# Generators Module
|
7
5
|
module Generators
|
8
|
-
#
|
9
|
-
|
10
|
-
include
|
6
|
+
# Base Generator
|
7
|
+
module Base
|
8
|
+
include Date
|
9
|
+
include Logging
|
10
|
+
include Math
|
11
11
|
|
12
|
-
|
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
|
12
|
+
attr_reader :site
|
21
13
|
|
22
|
-
def
|
23
|
-
|
14
|
+
def name
|
15
|
+
self.class.name.split('::').last.downcase
|
24
16
|
end
|
25
17
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
18
|
+
def generate(site)
|
19
|
+
@site = Site.new(site)
|
20
|
+
if @site.production?
|
21
|
+
info "skipping #{name} generator"
|
22
|
+
else
|
23
|
+
info "running #{name} generator"
|
24
|
+
data = crunch
|
25
|
+
File.open(data_file_target, 'w') { |f| f.write(JSON.pretty_generate(data)) } unless data.nil?
|
26
|
+
end
|
32
27
|
end
|
33
28
|
|
34
|
-
def
|
35
|
-
|
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
|
29
|
+
def data_file_target
|
30
|
+
File.join site.data_dir, "#{name}.json"
|
45
31
|
end
|
46
32
|
end
|
47
33
|
|
48
|
-
# Stats
|
49
|
-
|
50
|
-
|
51
|
-
# @abstract
|
52
|
-
module Stats
|
53
|
-
include Mixins::Logging
|
54
|
-
include Jekyll::Filters
|
34
|
+
# Stats Generator
|
35
|
+
class Stats < Jekyll::Generator
|
36
|
+
include Base
|
55
37
|
|
56
|
-
|
57
|
-
self.class.const_get(:KEY)
|
58
|
-
end
|
38
|
+
attr_reader :site
|
59
39
|
|
60
|
-
def
|
61
|
-
|
62
|
-
logger.info "crunching stats.#{key}"
|
63
|
-
@site.data['stats'] ||= {}
|
64
|
-
@site.data['stats'][key] = crunch
|
40
|
+
def crunch
|
41
|
+
generate_stats
|
65
42
|
end
|
66
43
|
|
67
|
-
def
|
68
|
-
|
44
|
+
def generate_stats
|
45
|
+
{
|
46
|
+
'total_words' => total(site.word_counts),
|
47
|
+
'average_words' => average(site.word_counts),
|
48
|
+
'total_posts' => site.entries.size,
|
49
|
+
'consecutive_posts' => calculate_streaks(site.dates).first['days'],
|
50
|
+
'swears' => calculate_swears
|
51
|
+
}
|
69
52
|
end
|
70
53
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
calc.round
|
54
|
+
private
|
55
|
+
|
56
|
+
def calculate_swears
|
57
|
+
results = Hash[count_swears]
|
58
|
+
results['total'] = total(results.values)
|
59
|
+
results
|
78
60
|
end
|
79
61
|
|
80
|
-
|
81
|
-
|
82
|
-
# @param [Array<Numeric>] numlist list of numbers to be totaled.
|
83
|
-
# @return [Numeric] calculated total of numlist.
|
84
|
-
def total(numlist)
|
85
|
-
numlist.inject(0) { |sum, x| sum + x }
|
62
|
+
def count_swears
|
63
|
+
occurences(swears, site.words).reject { |_k, v| v.zero? }.sort_by { |_k, v| -v }
|
86
64
|
end
|
87
65
|
|
88
|
-
def
|
89
|
-
|
66
|
+
def swears
|
67
|
+
site.recker_config.fetch('swears', [])
|
90
68
|
end
|
91
69
|
end
|
92
70
|
|
93
|
-
#
|
94
|
-
class
|
95
|
-
include
|
96
|
-
|
97
|
-
KEY = 'posts'
|
71
|
+
# Graphs Generator
|
72
|
+
class Graphs < Jekyll::Generator
|
73
|
+
include Base
|
98
74
|
|
99
75
|
def crunch
|
100
|
-
|
76
|
+
JekyllRecker::Graphs.generate_graphs(site)
|
77
|
+
nil
|
101
78
|
end
|
102
79
|
end
|
103
80
|
|
104
|
-
#
|
105
|
-
class
|
106
|
-
include
|
107
|
-
|
108
|
-
KEY = 'words'
|
81
|
+
# Git Generator
|
82
|
+
class Git < Jekyll::Generator
|
83
|
+
include Base
|
109
84
|
|
110
85
|
def crunch
|
111
|
-
total_counts = entries.collect(&:content).map { |c| number_of_words(c) }
|
112
86
|
{
|
113
|
-
'
|
114
|
-
'total' => total(total_counts)
|
87
|
+
'commit_count' => Shell.run('git rev-list --count master').chomp
|
115
88
|
}
|
116
89
|
end
|
117
90
|
end
|
118
91
|
|
119
|
-
#
|
120
|
-
class
|
121
|
-
include
|
122
|
-
|
123
|
-
KEY = 'days'
|
92
|
+
# Image Resize Generator
|
93
|
+
class ImageResize < Jekyll::Generator
|
94
|
+
include Base
|
124
95
|
|
125
96
|
def crunch
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
end.first
|
133
|
-
end
|
134
|
-
|
135
|
-
private
|
136
|
-
|
137
|
-
def streaks
|
138
|
-
_streaks = []
|
139
|
-
entry_dates.slice_when do |prev, curr|
|
140
|
-
curr != prev - 1
|
141
|
-
end.each do |dates|
|
142
|
-
first, last = dates.minmax
|
143
|
-
_streaks << [(last - first).to_i, [first, last]]
|
97
|
+
load_deps!
|
98
|
+
info 'checking images'
|
99
|
+
resizeable_images.each do |f, d|
|
100
|
+
info "resizing #{f} to fit #{d}"
|
101
|
+
image = MiniMagick::Image.new(f)
|
102
|
+
image.resize d
|
144
103
|
end
|
145
|
-
|
104
|
+
nil
|
146
105
|
end
|
147
106
|
|
148
|
-
def
|
149
|
-
|
107
|
+
def too_big?(width, height)
|
108
|
+
width > 800 || height > 800
|
150
109
|
end
|
151
|
-
end
|
152
|
-
|
153
|
-
# Swear Count Generator
|
154
|
-
class Swears < Jekyll::Generator
|
155
|
-
include Stats
|
156
110
|
|
157
|
-
|
158
|
-
|
159
|
-
|
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 }
|
111
|
+
def load_deps!
|
112
|
+
require 'fastimage'
|
113
|
+
require 'mini_magick'
|
169
114
|
end
|
170
115
|
|
171
|
-
|
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
|
-
]
|
116
|
+
def images_without_graphs
|
117
|
+
site.images.reject { |i| i.include?('/graphs/') }
|
188
118
|
end
|
189
|
-
end
|
190
|
-
|
191
|
-
# Memory Size Generator
|
192
|
-
class Memory < Jekyll::Generator
|
193
|
-
include Stats
|
194
|
-
|
195
|
-
KEY = 'memory'
|
196
119
|
|
197
|
-
def
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
120
|
+
def resizeable_images
|
121
|
+
with_sizes = images_without_graphs.map { |f| [f, FastImage.size(f)].flatten }
|
122
|
+
with_sizes.select! { |f| too_big?(f[1], f[2]) }
|
123
|
+
with_sizes.map do |f, w, h|
|
124
|
+
dimensions = if w > h
|
125
|
+
'800x600'
|
126
|
+
else
|
127
|
+
'600x800'
|
128
|
+
end
|
129
|
+
[f, dimensions]
|
203
130
|
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
131
|
end
|
213
132
|
end
|
214
133
|
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler'
|
4
|
+
|
5
|
+
module JekyllRecker
|
6
|
+
# Graphs module
|
7
|
+
module Graphs
|
8
|
+
def self.generate_graphs(site)
|
9
|
+
require 'gruff'
|
10
|
+
WordCount.new(site).write
|
11
|
+
Swears.new(site).write
|
12
|
+
end
|
13
|
+
|
14
|
+
# Base Graph
|
15
|
+
module Base
|
16
|
+
attr_reader :site
|
17
|
+
|
18
|
+
def graphs_join(path)
|
19
|
+
File.join Bundler.root, @graphs_dir, path
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Word Count Graph
|
24
|
+
class WordCount
|
25
|
+
include Base
|
26
|
+
|
27
|
+
def initialize(site)
|
28
|
+
@site = site
|
29
|
+
@graphs_dir = site.graphs_dir
|
30
|
+
end
|
31
|
+
|
32
|
+
def posts
|
33
|
+
site.entries[0..6].reverse
|
34
|
+
end
|
35
|
+
|
36
|
+
def word_counts
|
37
|
+
site.word_counts[0..6].reverse
|
38
|
+
end
|
39
|
+
|
40
|
+
def title
|
41
|
+
format = '%m/%d/%y'
|
42
|
+
first = posts.first.date.strftime(format)
|
43
|
+
last = posts.last.date.strftime(format)
|
44
|
+
"Word Count: #{first} - #{last}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def labels
|
48
|
+
Hash[posts.each_with_index.map { |p, i| [i, p.date.strftime('%a')] }]
|
49
|
+
end
|
50
|
+
|
51
|
+
def write
|
52
|
+
g = ::Gruff::Line.new('800x600')
|
53
|
+
g.theme = Gruff::Themes::PASTEL
|
54
|
+
g.hide_legend = true
|
55
|
+
g.labels = labels
|
56
|
+
g.data :words, word_counts
|
57
|
+
g.title = title
|
58
|
+
g.x_axis_label = 'Day'
|
59
|
+
g.y_axis_label = 'Word Count'
|
60
|
+
g.minimum_value = 0
|
61
|
+
g.write(graphs_join('words.png'))
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Swears Chart
|
66
|
+
class Swears
|
67
|
+
include Base
|
68
|
+
|
69
|
+
def initialize(site)
|
70
|
+
@data_dir = site.data_dir
|
71
|
+
@graphs_dir = site.graphs_dir
|
72
|
+
end
|
73
|
+
|
74
|
+
def results
|
75
|
+
path = File.join(@data_dir, 'stats.json')
|
76
|
+
data = JSON.parse(File.read(path))['swears']
|
77
|
+
data.delete('total')
|
78
|
+
data
|
79
|
+
end
|
80
|
+
|
81
|
+
def write
|
82
|
+
g = ::Gruff::Pie.new('800x600')
|
83
|
+
g.theme = Gruff::Themes::PASTEL
|
84
|
+
g.hide_legend = false
|
85
|
+
g.legend_at_bottom = true
|
86
|
+
g.minimum_value = 0
|
87
|
+
results.each { |w, n| g.data w, n }
|
88
|
+
g.write(graphs_join('swears.png'))
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|