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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 953321eea46a43a48fac8c20a579022e91792c7d9fa4b8ce40321fa3b4012445
4
- data.tar.gz: d45e2cd815c91e5f342d064cfd669f115232145ddd310c6bd067f839c22e35f1
3
+ metadata.gz: 0eae22b002ade0f4221755d4de3893fe42e802da54705d41887b7cc6def3f4a8
4
+ data.tar.gz: b76f167177035a42fb196ee51c3ca44b55ce945e11f72dd49c53340bb47b786d
5
5
  SHA512:
6
- metadata.gz: 2dc67f5ddb86b95f8123e45565d2e0fbcf2dad9c8724be6f1a4b3fb0de2470d4e4f673b964bc36218e9b42a5b5e622252bfa40ddbbe9fb7c796cd44621a50818
7
- data.tar.gz: 97be3ae1fe99ca231cee9fc69e0488dbf1c1800547a73add34bc12e71bb7c1d42da23b17b0417341ec4241c193ffec5e8f07cf8598a60bd56e884bcf4954b36d
6
+ metadata.gz: 032c96a18fb0a1e9d83e5cf2ce84e801b8573aaa7e8eac01093cb166f74d7e751b6e72bbec8af0be0ac2d5a1d502560b9651585be4a4ea52e1f13c8e5377b23d
7
+ data.tar.gz: 78dd6d4ac429dc0c3edfe28fb4ef64f1ed05c678d0b82aa566f0fcdd1dce4c45351cd8334425ef68a528f1af625b0104b552204f309f18cc2b0f262e1423db30
@@ -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
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
- # 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
6
+ # Base Generator
7
+ module Base
8
+ include Date
9
+ include Logging
10
+ include Math
46
11
  end
47
12
 
48
- # Stats Module
49
- #
50
- # Functions for stats generators.
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
- def key
57
- self.class.const_get(:KEY)
58
- end
17
+ attr_reader :site
59
18
 
60
19
  def generate(site)
61
- @site = site
62
- logger.info "crunching stats.#{key}"
63
- @site.data['stats'] ||= {}
64
- @site.data['stats'][key] = crunch
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 crunch
68
- raise NotImplementedError, '#crunch not implemented!'
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
- # 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
78
- end
41
+ private
79
42
 
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 }
43
+ def calculate_swears
44
+ results = Hash[count_swears]
45
+ results['total'] = total(results.values)
46
+ results
86
47
  end
87
48
 
88
- def entries
89
- @site.posts.docs.select(&:published?)
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
- KEY = 'posts'
98
-
99
- def crunch
100
- entries.count
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
- # Word Count Generator
105
- class Words < Jekyll::Generator
106
- include Stats
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
- # Streak Count Generator
120
- class Streaks < Jekyll::Generator
121
- include Stats
75
+ attr_reader :site
122
76
 
123
- KEY = 'days'
77
+ def generate(site)
78
+ @site = Site.new(site)
124
79
 
125
- 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
80
+ if @site.production?
81
+ info 'production detected, skipping images'
82
+ return
83
+ end
134
84
 
135
- private
85
+ load_deps!
136
86
 
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]]
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 entry_dates
149
- entries.collect(&:date).map { |t| Date.new(t.year, t.month, t.day) }.sort.reverse
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 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 }
99
+ def load_deps!
100
+ require 'fastimage'
101
+ require 'mini_magick'
169
102
  end
170
103
 
171
- private
104
+ def graph?(file)
105
+ file.include?('/graphs/')
106
+ end
172
107
 
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
- ]
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