jekyll-recker 1.12.0 → 2.2.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: f0acecf9f429bcd83a0cbe8204e046bee16c5a30de1e458b4080db7502e3a831
4
- data.tar.gz: 2b579e98cd7b81c71f063652a45b791708825b58d6ba83d2146ab2f321b0ce2e
3
+ metadata.gz: ea539028f1189e2337f3303c646c14a6c479c9a8bc4345e095b4807c6cbc78f0
4
+ data.tar.gz: 54890ff14bc9a52cecf154b1af2f44b64a4536a19c270e7bc741bb5f8be1436f
5
5
  SHA512:
6
- metadata.gz: a8b792c90336432c126993937c45dafcb88b1741bfbe2f0eafb32f8c6cc7607d402c442a782409b69a52664cbffe886cf8be39efff0890c15a2f96d84c5f83a9
7
- data.tar.gz: 14da6696ecf19dc25ea9d02a7ef1904c7e975f8137f0a41ee333da524ff1d242391673a2d6c31d81a77a0ce11d45aed03677b7173e24dae6a91716255f146689
6
+ metadata.gz: f7907b88a8fdf1ceb6cdc8f57042b6cc1424ff09a243f50b6790953ab591b625489e656f5ac35e63f3b2760b6ec5d5e659e0fd6ee19de3d7b3b0ef839d0cc924
7
+ data.tar.gz: 31a39ca124631df4a59216b7734d7f6e33419a3ebfcc717d54a6a53334c5eea44be3db6c4eca1cdecf3d361f417bb58ab1af3bb26a71f4b169b054fefb351daa
@@ -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
 
@@ -3,9 +3,9 @@
3
3
  module JekyllRecker
4
4
  # Commands
5
5
  module Commands
6
- # Share
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|
@@ -0,0 +1,21 @@
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
+ end
21
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JekyllRecker
4
+ # Entry
5
+ class Entry
6
+ def initialize(doc)
7
+ @doc = doc
8
+ end
9
+
10
+ def content
11
+ @doc.content
12
+ end
13
+
14
+ def date
15
+ @date ||= ::Date.parse(@doc.date.strftime('%Y-%m-%d'))
16
+ end
17
+
18
+ def words
19
+ content.split.map do |token|
20
+ token.gsub!(/[^0-9a-z ]/i, '')
21
+ token.downcase
22
+ end
23
+ end
24
+
25
+ def word_count
26
+ @word_count ||= words.size
27
+ end
28
+ end
29
+ 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,153 +1,112 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'mini_magick'
4
- require 'fastimage'
3
+ require 'bundler'
5
4
 
6
5
  module JekyllRecker
6
+ # Generators Module
7
7
  module Generators
8
- # Image Resize Generator
9
- class ImageResize < Jekyll::Generator
10
- include Mixins::Logging
8
+ # Base Generator Functions
9
+ module Base
10
+ include Date
11
+ include Logging
12
+ include Math
11
13
 
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
-
48
- # Stats Module
49
- #
50
- # Functions for stats generators.
51
- # @abstract
52
- module Stats
53
- include Mixins::Logging
54
- include Jekyll::Filters
55
-
56
- def key
57
- self.class.const_get(:KEY)
58
- end
59
-
60
- def generate(site)
61
- @site = site
62
- logger.info "crunching stats.#{key}"
63
- @site.data['stats'] ||= {}
64
- @site.data['stats'][key] = crunch
14
+ def production?
15
+ ENV['JEKYLL_ENV'] == 'production'
65
16
  end
66
17
 
67
- def crunch
68
- raise NotImplementedError, '#crunch not implemented!'
18
+ def word_counts
19
+ @word_counts ||= bodies.map(&:split).map(&:size)
69
20
  end
70
21
 
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
22
+ def words
23
+ bodies.map(&:split).flatten
78
24
  end
79
25
 
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 }
26
+ def bodies
27
+ entries.collect(&:content)
86
28
  end
87
29
 
88
30
  def entries
89
- @site.posts.docs.select(&:published?)
31
+ @site.posts.docs.select(&:published?).sort_by(&:date).reverse
90
32
  end
91
- end
92
-
93
- # Post Count Generator
94
- class PostCount < Jekyll::Generator
95
- include Stats
96
-
97
- KEY = 'posts'
98
33
 
99
- def crunch
100
- entries.count
34
+ def dates
35
+ entries.collect(&:date).map { |t| ::Date.new(t.year, t.month, t.day) }
101
36
  end
102
37
  end
103
38
 
104
- # Word Count Generator
105
- class Words < Jekyll::Generator
106
- include Stats
39
+ # Stats Generator
40
+ class Stats < Jekyll::Generator
41
+ include Base
42
+ include Graphs
107
43
 
108
- KEY = 'words'
44
+ def generate(site)
45
+ @site = site
46
+ logger.info 'calculating statistics'
47
+ @site.data['stats'] = data
48
+ if production?
49
+ logger.info 'production detected. skipping graphs'
50
+ else
51
+ require 'gruff'
52
+ logger.info 'generating graphs'
53
+ generate_graphs(entries, swear_results, graphs_dir)
54
+ end
55
+ end
109
56
 
110
- def crunch
111
- total_counts = entries.collect(&:content).map { |c| number_of_words(c) }
57
+ def data
112
58
  {
113
- 'average' => average(total_counts),
114
- 'total' => total(total_counts)
59
+ 'total_words' => total(word_counts),
60
+ 'average_words' => average(word_counts),
61
+ 'total_posts' => entries.size,
62
+ 'consecutive_posts' => calculate_streaks(dates).first['days'],
63
+ 'swears' => {
64
+ 'total' => swear_results.map(&:last).reduce(0, :+),
65
+ 'words' => swear_results
66
+ }
115
67
  }
116
68
  end
117
- end
118
-
119
- # Streak Count Generator
120
- class Streaks < Jekyll::Generator
121
- include Stats
122
69
 
123
- KEY = 'days'
70
+ private
124
71
 
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
72
+ def swear_results
73
+ @swear_results ||= count_swears
133
74
  end
134
75
 
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]]
144
- end
145
- _streaks
76
+ def graphs_dir
77
+ recker = @site.config.fetch('recker', {})
78
+ recker.fetch('graphs', 'assets/images/graphs/')
146
79
  end
147
80
 
148
- def entry_dates
149
- entries.collect(&:date).map { |t| Date.new(t.year, t.month, t.day) }.sort.reverse
81
+ def count_swears
82
+ results = Hash.new(0)
83
+ bodies.map(&:split).each do |words|
84
+ words = words.map(&:downcase)
85
+ swears.each do |swear|
86
+ count = words.count(swear)
87
+ results[swear] += count
88
+ end
89
+ end
90
+ results.reject { |_k, v| v.zero? }.sort_by { |_k, v| -v }
91
+ end
92
+
93
+ def swears
94
+ %w[
95
+ ass
96
+ asshole
97
+ booger
98
+ crap
99
+ damn
100
+ fart
101
+ fuck
102
+ hell
103
+ jackass
104
+ piss
105
+ poop
106
+ shit
107
+ ]
150
108
  end
151
109
  end
110
+ require 'jekyll_recker/generators/image_resize.rb'
152
111
  end
153
112
  end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JekyllRecker
4
+ module Generators
5
+ # Image Resize Generator
6
+ class ImageResize < Jekyll::Generator
7
+ include Base
8
+
9
+ def generate(site)
10
+ @site = site
11
+ if production?
12
+ logger.info 'production detected, skipping images'
13
+ return
14
+ else
15
+ logger.info 'loading image resizing deps'
16
+ require 'fastimage'
17
+ require 'mini_magick'
18
+ end
19
+ logger.info 'checking images'
20
+ resizeable_images.each do |f, d|
21
+ logger.info "resizing #{f} to fit #{d}"
22
+ image = MiniMagick::Image.new(f)
23
+ image.resize d
24
+ end
25
+ end
26
+
27
+ def image?(file)
28
+ ['.jpg', 'jpeg', '.png', '.svg'].include? File.extname(file)
29
+ end
30
+
31
+ def too_big?(width, height)
32
+ width > 800 || height > 800
33
+ end
34
+
35
+ def graph?(file)
36
+ file.include?('/graphs/')
37
+ end
38
+
39
+ def images
40
+ @site.static_files.collect(&:path).select { |f| image?(f) }
41
+ end
42
+
43
+ def resizeable_images
44
+ without_graphs = images.reject { |i| graph?(i) }
45
+ with_sizes = without_graphs.map { |f| [f, FastImage.size(f)].flatten }
46
+ with_sizes.select! { |f| too_big?(f[1], f[2]) }
47
+ with_sizes.map do |f, w, h|
48
+ dimensions = if w > h
49
+ '800x600'
50
+ else
51
+ '600x800'
52
+ end
53
+ [f, dimensions]
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler'
4
+
5
+ module JekyllRecker
6
+ # Graphs module
7
+ module Graphs
8
+ def generate_graphs(posts, swears, graphs_dir)
9
+ WordCount.new(posts, graphs_dir).write
10
+ Swears.new(swears, graphs_dir).write
11
+ end
12
+
13
+ # Word Count Graph
14
+ class WordCount
15
+ def initialize(posts, graphs_dir)
16
+ @posts = posts[0..6].reverse
17
+ @graphs_dir = graphs_dir
18
+ end
19
+
20
+ def graphs_join(path)
21
+ File.join Bundler.root, @graphs_dir, path
22
+ end
23
+
24
+ def title
25
+ format = '%m/%d/%y'
26
+ first = @posts.first.date.strftime(format)
27
+ last = @posts.last.date.strftime(format)
28
+ "Word Count: #{first} - #{last}"
29
+ end
30
+
31
+ def labels
32
+ Hash[@posts.each_with_index.map { |p, i| [i, p.date.strftime('%a')] }]
33
+ end
34
+
35
+ # TODO: copied from jekyll
36
+ def number_of_words(input)
37
+ input.split.length
38
+ end
39
+
40
+ def write
41
+ g = Gruff::Line.new('800x600')
42
+ g.theme = Gruff::Themes::PASTEL
43
+ g.hide_legend = true
44
+ g.labels = labels
45
+ g.data :words, @posts.collect(&:content).map { |c| number_of_words(c) }
46
+ g.title = title
47
+ g.x_axis_label = 'Day'
48
+ g.y_axis_label = 'Word Count'
49
+ g.minimum_value = 0
50
+ g.write(graphs_join('words.png'))
51
+ end
52
+ end
53
+
54
+ # Swears Chart
55
+ class Swears
56
+ attr_reader :results
57
+
58
+ def initialize(results, graphs_dir)
59
+ @results = results
60
+ @graphs_dir = graphs_dir
61
+ end
62
+
63
+ # TODO: I SUCK
64
+ def graphs_join(path)
65
+ File.join Bundler.root, @graphs_dir, path
66
+ end
67
+
68
+ def write
69
+ g = Gruff::Pie.new('800x600')
70
+ g.theme = Gruff::Themes::PASTEL
71
+ g.hide_legend = false
72
+ g.legend_at_bottom = true
73
+ g.minimum_value = 0
74
+ results.each { |w, n| g.data w, n }
75
+ g.write(graphs_join('swears.png'))
76
+ end
77
+ end
78
+ end
79
+ end