jekyll-recker 1.16.0 → 2.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: 5134c19a248e628a2709daf01227163084bfb2dfd81e8d7c828324dddbd13e2d
4
- data.tar.gz: 9710e3c11ea62dda0707dedd0c9771fd8f802682f36140ef4e59af07a6f7aaa9
3
+ metadata.gz: 7f3c029100fd9fc95b7f7b065e17bbb5cd2baf321fd0b3f93aeac96505e816d6
4
+ data.tar.gz: f66cd31401dd09fd965f34372c117dd26ab582cb8d761d5a00fa1a41352c3e31
5
5
  SHA512:
6
- metadata.gz: 7767ff61b4b0ec54f646b207b4742f7f5b1a94d684d78bfa4f9a00ff0920f097c3e3a28106b847bddcebc0105eb9b65794c0adb9cc8e15f3235bac769454d7c7
7
- data.tar.gz: f45942a90efd38657dc4b8fe81073c20b19a6ed2c22eb6e4b46e48c00807f458b429dd28e45a888f4836f728ad8e56251cc56f45c5a2108496e135275a75088e
6
+ metadata.gz: 2171c0a55cb2e419ae0c120880fef8e11fd4d01b554327f2adca939f8a92c5c0e0b37934acf58d64bbf276688cc7785aa4c06b46db5a224be721b71a0a3d4805
7
+ data.tar.gz: f07aadca9f824b3c22bcbca26c208fe29e1ffa6fee993984263456f951d861d58ec2697aed963a9bbd7924c3d8b6282ef2f6857f335ab8a343b3486fef039e88
@@ -6,8 +6,13 @@ require 'jekyll'
6
6
  #
7
7
  # The greatest jekyll plugin in the world
8
8
  module JekyllRecker
9
- autoload :Mixins, 'jekyll_recker/mixins.rb'
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 Mixins::Logging
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 %d %Y')
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
- # Image Resize Generator
9
- class ImageResize < Jekyll::Generator
10
- include Mixins::Logging
6
+ # Base Generator
7
+ module Base
8
+ include Date
9
+ include Logging
10
+ include Math
11
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
12
+ attr_reader :site
21
13
 
22
- def image?(file)
23
- ['.jpg', 'jpeg', '.png', '.svg'].include? File.extname(file)
14
+ def name
15
+ self.class.name.split('::').last.downcase
24
16
  end
25
17
 
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) }
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 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
29
+ def data_file_target
30
+ File.join site.data_dir, "#{name}.json"
45
31
  end
46
32
  end
47
33
 
48
- # Stats Module
49
- #
50
- # Functions for stats generators.
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
- def key
57
- self.class.const_get(:KEY)
58
- end
38
+ attr_reader :site
59
39
 
60
- def generate(site)
61
- @site = site
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 crunch
68
- raise NotImplementedError, '#crunch not implemented!'
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
- # Calculates the average of a list of numbers.
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
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
- # Calculates the total of a list of numbers.
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 entries
89
- @site.posts.docs.select(&:published?)
66
+ def swears
67
+ site.recker_config.fetch('swears', [])
90
68
  end
91
69
  end
92
70
 
93
- # Post Count Generator
94
- class PostCount < Jekyll::Generator
95
- include Stats
96
-
97
- KEY = 'posts'
71
+ # Graphs Generator
72
+ class Graphs < Jekyll::Generator
73
+ include Base
98
74
 
99
75
  def crunch
100
- entries.count
76
+ JekyllRecker::Graphs.generate_graphs(site)
77
+ nil
101
78
  end
102
79
  end
103
80
 
104
- # Word Count Generator
105
- class Words < Jekyll::Generator
106
- include Stats
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
- 'average' => average(total_counts),
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
- # Streak Count Generator
120
- class Streaks < Jekyll::Generator
121
- include Stats
122
-
123
- KEY = 'days'
92
+ # Image Resize Generator
93
+ class ImageResize < Jekyll::Generator
94
+ include Base
124
95
 
125
96
  def crunch
126
- streaks.take(1).map do |count, dates|
127
- {
128
- 'days' => count,
129
- 'start' => dates[0],
130
- 'end' => dates[1]
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
- _streaks
104
+ nil
146
105
  end
147
106
 
148
- def entry_dates
149
- entries.collect(&:date).map { |t| Date.new(t.year, t.month, t.day) }.sort.reverse
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
- 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 }
111
+ def load_deps!
112
+ require 'fastimage'
113
+ require 'mini_magick'
169
114
  end
170
115
 
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
- ]
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 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
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