jekyll-recker 1.14.0 → 2.3.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: e9a5e5beecbe76dfb1a709044a22e681c1d2c17efbe295a169f83ece21b9f127
4
- data.tar.gz: 7f0eb9d447f94fad07235c91675dab1b333a03d8fe47c102fada49547cd455c6
3
+ metadata.gz: 7de0dd41444c7a9cec90c5dfc035b3544efc0096e2b36cab9131c50122ead0b7
4
+ data.tar.gz: ed2122a9180d19f534c5dded62a8abcef9b56a94aad951e63fcdd30b3cf6a22f
5
5
  SHA512:
6
- metadata.gz: ed6e9a3464edd7a9986abdd755d567b12c11c0eb587b9699168d7dd2492a33b0ec85eddb473520fafb21e4cfab11d4aae8e08bb2b2f36294ebd53215eb49c681
7
- data.tar.gz: caa4a564c65dcc69593f3f3ff8976f7de24b4c016fd7f68d14c1161ea9a9d67c247755071e09e3d5454d623f6e74ab53f393f9eaa8c501075bf8b77dff55c809
6
+ metadata.gz: 78c36674f14a242e76bc2c82ffa9410d70e0f5f1cc9da1bbd5a26c47a12609e583101b7876ed7d56ff8e1bb3da45cab7da207cf51d05b8651958a00acf276781
7
+ data.tar.gz: ba89a46a1c2c48a6484bbcfab4b3e62e34c344423c1707ccb6497c086bde93a127517b5bfbba10ba4f749cc6d78cffd6d30e048fa170a823e50c1bf7031d9cf4
@@ -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,152 +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
6
+ # Base Generator
7
+ module Base
8
+ include Date
9
+ include Logging
10
+ include Math
11
+ end
12
+
13
+ # Stats Generator
14
+ class Stats < Jekyll::Generator
15
+ include Base
16
+
17
+ attr_reader :site
11
18
 
12
19
  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
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)
19
27
  end
20
28
  end
21
29
 
22
- def image?(file)
23
- ['.jpg', 'jpeg', '.png', '.svg'].include? File.extname(file)
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
+ }
24
39
  end
25
40
 
26
- def too_big?(width, height)
27
- width > 800 || height > 800
41
+ private
42
+
43
+ def calculate_swears
44
+ results = Hash[count_swears]
45
+ results['total'] = total(results.values)
46
+ results
28
47
  end
29
48
 
30
- def images
31
- @site.static_files.collect(&:path).select { |f| image?(f) }
49
+ def count_swears
50
+ occurences(swears, site.words).reject { |_k, v| v.zero? }.sort_by { |_k, v| -v }
32
51
  end
33
52
 
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
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
+ ]
45
68
  end
46
69
  end
47
70
 
48
- # Stats Module
49
- #
50
- # Functions for stats generators.
51
- # @abstract
52
- module Stats
53
- include Mixins::Logging
54
- include Jekyll::Filters
71
+ # Image Resize Generator
72
+ class ImageResize < Jekyll::Generator
73
+ include Base
55
74
 
56
- def key
57
- self.class.const_get(:KEY)
58
- end
75
+ attr_reader :site
59
76
 
60
77
  def generate(site)
61
- @site = site
62
- logger.info "crunching stats.#{key}"
63
- @site.data['stats'] ||= {}
64
- @site.data['stats'][key] = crunch
65
- end
78
+ @site = Site.new(site)
66
79
 
67
- def crunch
68
- raise NotImplementedError, '#crunch not implemented!'
69
- end
70
-
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
80
+ if @site.production?
81
+ info 'production detected, skipping images'
82
+ return
83
+ end
79
84
 
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 }
86
- end
85
+ load_deps!
87
86
 
88
- def entries
89
- @site.posts.docs.select(&:published?)
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
92
+ end
90
93
  end
91
- end
92
-
93
- # Post Count Generator
94
- class PostCount < Jekyll::Generator
95
- include Stats
96
94
 
97
- KEY = 'posts'
98
-
99
- def crunch
100
- entries.count
95
+ def too_big?(width, height)
96
+ width > 800 || height > 800
101
97
  end
102
- end
103
98
 
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
- }
99
+ def load_deps!
100
+ require 'fastimage'
101
+ require 'mini_magick'
116
102
  end
117
- end
118
103
 
119
- # Streak Count Generator
120
- class Streaks < Jekyll::Generator
121
- include Stats
122
-
123
- KEY = 'days'
124
-
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
104
+ def graph?(file)
105
+ file.include?('/graphs/')
133
106
  end
134
107
 
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]]
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]
144
119
  end
145
- _streaks
146
- end
147
-
148
- def entry_dates
149
- entries.collect(&:date).map { |t| Date.new(t.year, t.month, t.day) }.sort.reverse
150
120
  end
151
121
  end
152
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