jekyll-recker 1.15.0 → 2.3.1
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 +0 -2
- data/lib/jekyll_recker/generators.rb +85 -153
- data/lib/jekyll_recker/graphs.rb +88 -0
- data/lib/jekyll_recker/logging.rb +20 -0
- data/lib/jekyll_recker/math.rb +23 -0
- data/lib/jekyll_recker/site.rb +70 -0
- data/lib/jekyll_recker/social.rb +21 -21
- 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: 0eae22b002ade0f4221755d4de3893fe42e802da54705d41887b7cc6def3f4a8
|
4
|
+
data.tar.gz: b76f167177035a42fb196ee51c3ca44b55ce945e11f72dd49c53340bb47b786d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 032c96a18fb0a1e9d83e5cf2ce84e801b8573aaa7e8eac01093cb166f74d7e751b6e72bbec8af0be0ac2d5a1d502560b9651585be4a4ea52e1f13c8e5377b23d
|
7
|
+
data.tar.gz: 78dd6d4ac429dc0c3edfe28fb4ef64f1ed05c678d0b82aa566f0fcdd1dce4c45351cd8334425ef68a528f1af625b0104b552204f309f18cc2b0f262e1423db30
|
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
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,190 +1,122 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'mini_magick'
|
4
|
-
require 'fastimage'
|
5
|
-
|
6
3
|
module JekyllRecker
|
4
|
+
# Generators Module
|
7
5
|
module Generators
|
8
|
-
#
|
9
|
-
|
10
|
-
include
|
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
|
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
|
6
|
+
# Base Generator
|
7
|
+
module Base
|
8
|
+
include Date
|
9
|
+
include Logging
|
10
|
+
include Math
|
46
11
|
end
|
47
12
|
|
48
|
-
# Stats
|
49
|
-
|
50
|
-
|
51
|
-
# @abstract
|
52
|
-
module Stats
|
53
|
-
include Mixins::Logging
|
54
|
-
include Jekyll::Filters
|
13
|
+
# Stats Generator
|
14
|
+
class Stats < Jekyll::Generator
|
15
|
+
include Base
|
55
16
|
|
56
|
-
|
57
|
-
self.class.const_get(:KEY)
|
58
|
-
end
|
17
|
+
attr_reader :site
|
59
18
|
|
60
19
|
def generate(site)
|
61
|
-
@site = site
|
62
|
-
|
63
|
-
@site.
|
64
|
-
|
20
|
+
@site = Site.new(site)
|
21
|
+
generate_stats!
|
22
|
+
if @site.production?
|
23
|
+
info 'production detected. skipping graphs'
|
24
|
+
else
|
25
|
+
info 'generating graphs'
|
26
|
+
Graphs.generate_graphs(@site)
|
27
|
+
end
|
65
28
|
end
|
66
29
|
|
67
|
-
def
|
68
|
-
|
30
|
+
def generate_stats!
|
31
|
+
info 'calculating statistics'
|
32
|
+
site.data['stats'] = {
|
33
|
+
'total_words' => total(site.word_counts),
|
34
|
+
'average_words' => average(site.word_counts),
|
35
|
+
'total_posts' => site.entries.size,
|
36
|
+
'consecutive_posts' => calculate_streaks(site.dates).first['days'],
|
37
|
+
'swears' => calculate_swears
|
38
|
+
}
|
69
39
|
end
|
70
40
|
|
71
|
-
|
72
|
-
#
|
73
|
-
# @param [Array<Numeric>] numlist list of numbers to be averaged.
|
74
|
-
# @return [Numeric] rounded, calculated average of numlist.
|
75
|
-
def average(numlist)
|
76
|
-
calc = numlist.inject { |sum, el| sum + el }.to_f / numlist.size
|
77
|
-
calc.round
|
78
|
-
end
|
41
|
+
private
|
79
42
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
def total(numlist)
|
85
|
-
numlist.inject(0) { |sum, x| sum + x }
|
43
|
+
def calculate_swears
|
44
|
+
results = Hash[count_swears]
|
45
|
+
results['total'] = total(results.values)
|
46
|
+
results
|
86
47
|
end
|
87
48
|
|
88
|
-
def
|
89
|
-
|
49
|
+
def count_swears
|
50
|
+
occurences(swears, site.words).reject { |_k, v| v.zero? }.sort_by { |_k, v| -v }
|
90
51
|
end
|
91
|
-
end
|
92
|
-
|
93
|
-
# Post Count Generator
|
94
|
-
class PostCount < Jekyll::Generator
|
95
|
-
include Stats
|
96
52
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
53
|
+
def swears
|
54
|
+
%w[
|
55
|
+
ass
|
56
|
+
asshole
|
57
|
+
booger
|
58
|
+
crap
|
59
|
+
damn
|
60
|
+
fart
|
61
|
+
fuck
|
62
|
+
hell
|
63
|
+
jackass
|
64
|
+
piss
|
65
|
+
poop
|
66
|
+
shit
|
67
|
+
]
|
101
68
|
end
|
102
69
|
end
|
103
70
|
|
104
|
-
#
|
105
|
-
class
|
106
|
-
include
|
107
|
-
|
108
|
-
KEY = 'words'
|
109
|
-
|
110
|
-
def crunch
|
111
|
-
total_counts = entries.collect(&:content).map { |c| number_of_words(c) }
|
112
|
-
{
|
113
|
-
'average' => average(total_counts),
|
114
|
-
'total' => total(total_counts)
|
115
|
-
}
|
116
|
-
end
|
117
|
-
end
|
71
|
+
# Image Resize Generator
|
72
|
+
class ImageResize < Jekyll::Generator
|
73
|
+
include Base
|
118
74
|
|
119
|
-
|
120
|
-
class Streaks < Jekyll::Generator
|
121
|
-
include Stats
|
75
|
+
attr_reader :site
|
122
76
|
|
123
|
-
|
77
|
+
def generate(site)
|
78
|
+
@site = Site.new(site)
|
124
79
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
'start' => dates[0],
|
130
|
-
'end' => dates[1]
|
131
|
-
}
|
132
|
-
end.first
|
133
|
-
end
|
80
|
+
if @site.production?
|
81
|
+
info 'production detected, skipping images'
|
82
|
+
return
|
83
|
+
end
|
134
84
|
|
135
|
-
|
85
|
+
load_deps!
|
136
86
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
first, last = dates.minmax
|
143
|
-
_streaks << [(last - first).to_i, [first, last]]
|
87
|
+
info 'checking images'
|
88
|
+
resizeable_images.each do |f, d|
|
89
|
+
info "resizing #{f} to fit #{d}"
|
90
|
+
image = MiniMagick::Image.new(f)
|
91
|
+
image.resize d
|
144
92
|
end
|
145
|
-
_streaks
|
146
93
|
end
|
147
94
|
|
148
|
-
def
|
149
|
-
|
95
|
+
def too_big?(width, height)
|
96
|
+
width > 800 || height > 800
|
150
97
|
end
|
151
|
-
end
|
152
|
-
|
153
|
-
# Swear Count Generator
|
154
|
-
class Swears < Jekyll::Generator
|
155
|
-
include Stats
|
156
|
-
|
157
|
-
KEY = 'swears'
|
158
98
|
|
159
|
-
def
|
160
|
-
|
161
|
-
|
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 }
|
99
|
+
def load_deps!
|
100
|
+
require 'fastimage'
|
101
|
+
require 'mini_magick'
|
169
102
|
end
|
170
103
|
|
171
|
-
|
104
|
+
def graph?(file)
|
105
|
+
file.include?('/graphs/')
|
106
|
+
end
|
172
107
|
|
173
|
-
def
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
'poop',
|
186
|
-
'shit',
|
187
|
-
]
|
108
|
+
def resizeable_images
|
109
|
+
without_graphs = site.images.reject { |i| graph?(i) }
|
110
|
+
with_sizes = without_graphs.map { |f| [f, FastImage.size(f)].flatten }
|
111
|
+
with_sizes.select! { |f| too_big?(f[1], f[2]) }
|
112
|
+
with_sizes.map do |f, w, h|
|
113
|
+
dimensions = if w > h
|
114
|
+
'800x600'
|
115
|
+
else
|
116
|
+
'600x800'
|
117
|
+
end
|
118
|
+
[f, dimensions]
|
119
|
+
end
|
188
120
|
end
|
189
121
|
end
|
190
122
|
end
|
@@ -0,0 +1,88 @@
|
|
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
|
+
attr_reader :results
|
70
|
+
|
71
|
+
def initialize(site)
|
72
|
+
@results = site.data['stats']['swears'].clone
|
73
|
+
@results.delete('total')
|
74
|
+
@graphs_dir = site.graphs_dir
|
75
|
+
end
|
76
|
+
|
77
|
+
def write
|
78
|
+
g = ::Gruff::Pie.new('800x600')
|
79
|
+
g.theme = Gruff::Themes::PASTEL
|
80
|
+
g.hide_legend = false
|
81
|
+
g.legend_at_bottom = true
|
82
|
+
g.minimum_value = 0
|
83
|
+
results.each { |w, n| g.data w, n }
|
84
|
+
g.write(graphs_join('swears.png'))
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|