lolcommits 0.9.2 → 0.9.3.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +6 -0
  3. data/CHANGELOG.md +243 -105
  4. data/CONTRIBUTING.md +2 -2
  5. data/README.md +10 -3
  6. data/bin/lolcommits +9 -16
  7. data/features/step_definitions/lolcommits_steps.rb +0 -1
  8. data/features/support/env.rb +0 -1
  9. data/features/support/path_helpers.rb +0 -1
  10. data/lib/core_ext/mini_magick/utilities.rb +0 -1
  11. data/lib/lolcommits.rb +16 -16
  12. data/lib/lolcommits/backends/git_info.rb +0 -1
  13. data/lib/lolcommits/backends/installation_git.rb +0 -1
  14. data/lib/lolcommits/backends/installation_mercurial.rb +0 -1
  15. data/lib/lolcommits/backends/mercurial_info.rb +0 -1
  16. data/lib/lolcommits/capturer.rb +0 -1
  17. data/lib/lolcommits/capturer/capture_cygwin.rb +0 -1
  18. data/lib/lolcommits/capturer/capture_fake.rb +0 -1
  19. data/lib/lolcommits/capturer/capture_linux.rb +0 -1
  20. data/lib/lolcommits/capturer/capture_linux_animated.rb +0 -1
  21. data/lib/lolcommits/capturer/capture_mac.rb +0 -1
  22. data/lib/lolcommits/capturer/capture_mac_animated.rb +0 -1
  23. data/lib/lolcommits/capturer/capture_windows.rb +0 -1
  24. data/lib/lolcommits/cli/fatals.rb +0 -8
  25. data/lib/lolcommits/cli/launcher.rb +0 -1
  26. data/lib/lolcommits/cli/process_runner.rb +0 -2
  27. data/lib/lolcommits/cli/timelapse_gif.rb +0 -1
  28. data/lib/lolcommits/configuration.rb +10 -7
  29. data/lib/lolcommits/gem_plugin.rb +46 -0
  30. data/lib/lolcommits/installation.rb +0 -1
  31. data/lib/lolcommits/platform.rb +0 -1
  32. data/lib/lolcommits/plugin/base.rb +110 -0
  33. data/lib/lolcommits/plugin/dot_com.rb +50 -0
  34. data/lib/lolcommits/plugin/lol_flowdock.rb +69 -0
  35. data/lib/lolcommits/plugin/lol_hipchat.rb +124 -0
  36. data/lib/lolcommits/plugin/lol_protonet.rb +68 -0
  37. data/lib/lolcommits/plugin/lol_slack.rb +68 -0
  38. data/lib/lolcommits/plugin/lol_tumblr.rb +129 -0
  39. data/lib/lolcommits/plugin/lol_twitter.rb +176 -0
  40. data/lib/lolcommits/plugin/lol_yammer.rb +84 -0
  41. data/lib/lolcommits/plugin/lolsrv.rb +58 -0
  42. data/lib/lolcommits/plugin/loltext.rb +190 -0
  43. data/lib/lolcommits/plugin/term_output.rb +55 -0
  44. data/lib/lolcommits/{plugins → plugin}/tranzlate.rb +14 -15
  45. data/lib/lolcommits/plugin/uploldz.rb +65 -0
  46. data/lib/lolcommits/plugin_manager.rb +48 -0
  47. data/lib/lolcommits/runner.rb +4 -5
  48. data/lib/lolcommits/test_helpers/fake_io.rb +20 -0
  49. data/lib/lolcommits/test_helpers/git_repo.rb +44 -0
  50. data/lib/lolcommits/vcs_info.rb +0 -1
  51. data/lib/lolcommits/version.rb +2 -2
  52. data/lolcommits.gemspec +2 -2
  53. data/test/lolcommits_test.rb +1 -2
  54. data/test/plugins_test.rb +7 -8
  55. metadata +22 -19
  56. data/lib/core_ext/class.rb +0 -8
  57. data/lib/lolcommits/plugin.rb +0 -123
  58. data/lib/lolcommits/plugins/dot_com.rb +0 -51
  59. data/lib/lolcommits/plugins/lol_flowdock.rb +0 -70
  60. data/lib/lolcommits/plugins/lol_hipchat.rb +0 -125
  61. data/lib/lolcommits/plugins/lol_protonet.rb +0 -69
  62. data/lib/lolcommits/plugins/lol_slack.rb +0 -69
  63. data/lib/lolcommits/plugins/lol_tumblr.rb +0 -129
  64. data/lib/lolcommits/plugins/lol_twitter.rb +0 -176
  65. data/lib/lolcommits/plugins/lol_yammer.rb +0 -85
  66. data/lib/lolcommits/plugins/lolsrv.rb +0 -58
  67. data/lib/lolcommits/plugins/loltext.rb +0 -184
  68. data/lib/lolcommits/plugins/term_output.rb +0 -54
  69. data/lib/lolcommits/plugins/uploldz.rb +0 -66
@@ -1,58 +0,0 @@
1
- # -*- encoding : utf-8 -*-
2
- require 'rest_client'
3
- require 'pp'
4
- require 'json'
5
-
6
- module Lolcommits
7
- class Lolsrv < Plugin
8
- def initialize(runner)
9
- super
10
- options << 'server'
11
- end
12
-
13
- def run_postcapture
14
- return unless valid_configuration?
15
- fork { sync }
16
- end
17
-
18
- def configured?
19
- !configuration['enabled'].nil? && configuration['server']
20
- end
21
-
22
- def sync
23
- existing = existing_lols
24
- return unless existing.nil?
25
- Dir[runner.config.loldir + '/*.{jpg,gif}'].each do |item|
26
- sha = File.basename(item, '.*')
27
- upload(item, sha) unless existing.include?(sha) || sha == 'tmp_snapshot'
28
- end
29
- end
30
-
31
- def existing_lols
32
- lols = JSON.parse(RestClient.get(configuration['server'] + '/lols'))
33
- lols.map { |lol| lol['sha'] }
34
- rescue => e
35
- log_error(e, "ERROR: existing lols could not be retrieved #{e.class} - #{e.message}")
36
- return nil
37
- end
38
-
39
- def upload(file, sha)
40
- RestClient.post(configuration['server'] + '/uplol',
41
- lol: File.new(file),
42
- url: runner.vcs_info.url + sha,
43
- repo: runner.vcs_info.repo,
44
- date: File.ctime(file),
45
- sha: sha)
46
- rescue => e
47
- log_error(e, "ERROR: Upload of lol #{sha} FAILED #{e.class} - #{e.message}")
48
- end
49
-
50
- def self.name
51
- 'lolsrv'
52
- end
53
-
54
- def self.runner_order
55
- :postcapture
56
- end
57
- end
58
- end
@@ -1,184 +0,0 @@
1
- # -*- encoding : utf-8 -*-
2
- module Lolcommits
3
- class Loltext < Plugin
4
- DEFAULT_FONT_PATH = File.join(Configuration::LOLCOMMITS_ROOT, 'vendor', 'fonts', 'Impact.ttf')
5
-
6
- def self.name
7
- 'loltext'
8
- end
9
-
10
- # enabled by default (if no configuration exists)
11
- def enabled?
12
- !configured? || super
13
- end
14
-
15
- def run_postcapture
16
- debug 'Annotating image via MiniMagick'
17
- image = MiniMagick::Image.open(runner.main_image)
18
- if config_option(:overlay, :enabled)
19
- image.combine_options do |c|
20
- c.fill config_option(:overlay, :overlay_colors).sample
21
- c.colorize config_option(:overlay, :overlay_percent)
22
- end
23
- end
24
-
25
- annotate(image, :message, clean_msg(runner.message))
26
- annotate(image, :sha, runner.sha)
27
- debug "Writing changed file to #{runner.main_image}"
28
- image.write runner.main_image
29
- end
30
-
31
- def annotate(image, type, string)
32
- debug("annotating #{type} to image with #{string}")
33
-
34
- transformed_position = position_transform(config_option(type, :position))
35
- annotate_location = '0'
36
- if transformed_position == 'South'
37
- annotate_location = '+0+20' # Move South gravity off the edge of the image.
38
- end
39
-
40
- string.upcase! if config_option(type, :uppercase)
41
-
42
- image.combine_options do |c|
43
- c.strokewidth runner.capture_animated? ? '1' : '2'
44
- c.interline_spacing(-(config_option(type, :size) / 5))
45
- c.stroke config_option(type, :stroke_color)
46
- c.fill config_option(type, :color)
47
- c.gravity transformed_position
48
- c.pointsize runner.capture_animated? ? (config_option(type, :size) / 2) : config_option(type, :size)
49
- c.font config_option(type, :font)
50
- c.annotate annotate_location, string
51
- end
52
- end
53
-
54
- def configure_options!
55
- options = super
56
- # ask user to configure text options when enabling
57
- if options['enabled']
58
- puts '---------------------------------------------------------------'
59
- puts ' LolText options '
60
- puts ''
61
- puts ' * any blank options will use the (default)'
62
- puts ' * always use the full absolute path to fonts'
63
- puts ' * valid text positions are NE, NW, SE, SW, S, C (centered)'
64
- puts ' * colors can be hex #FC0 value or a string \'white\''
65
- puts ' - use `none` for no stroke color'
66
- puts ' * overlay fills your image with a random color'
67
- puts ' - set one or more overlay_colors with a comma seperator'
68
- puts ' - overlay_percent (0-100) sets the fill colorize strength'
69
- puts '---------------------------------------------------------------'
70
-
71
- options[:message] = configure_sub_options(:message)
72
- options[:sha] = configure_sub_options(:sha)
73
- options[:overlay] = configure_sub_options(:overlay)
74
- end
75
- options
76
- end
77
-
78
- # TODO: consider this type of configuration prompting in the base Plugin
79
- # class, working with hash of defaults
80
- def configure_sub_options(type)
81
- print "#{type}:\n"
82
- defaults = config_defaults[type]
83
-
84
- # sort option keys since different `Hash#keys` varys across Ruby versions
85
- defaults.keys.sort_by(&:to_s).reduce({}) do |acc, opt|
86
- # if we have an enabled key set to false, abort asking for any more options
87
- if acc.key?(:enabled) && acc[:enabled] != true
88
- acc
89
- else
90
- print " #{opt.to_s.tr('_', ' ')} (#{defaults[opt]}): "
91
- val = parse_user_input(STDIN.gets.chomp.strip)
92
- # handle array options (comma seperated string)
93
- if defaults[opt].is_a?(Array) && !val.nil?
94
- val = val.split(',').map(&:strip).delete_if(&:empty?)
95
- end
96
- acc.merge(opt => val)
97
- end
98
- end
99
- end
100
-
101
- def config_defaults
102
- {
103
- message: {
104
- color: 'white',
105
- font: DEFAULT_FONT_PATH,
106
- position: 'SW',
107
- size: 48,
108
- stroke_color: 'black',
109
- uppercase: false
110
- },
111
- sha: {
112
- color: 'white',
113
- font: DEFAULT_FONT_PATH,
114
- position: 'NE',
115
- size: 32,
116
- stroke_color: 'black',
117
- uppercase: false
118
- },
119
- overlay: {
120
- enabled: false,
121
- overlay_colors: [
122
- '#2e4970', '#674685', '#ca242f', '#1e7882', '#2884ae', '#4ba000',
123
- '#187296', '#7e231f', '#017d9f', '#e52d7b', '#0f5eaa', '#e40087',
124
- '#5566ac', '#ed8833', '#f8991c', '#408c93', '#ba9109'
125
- ],
126
- overlay_percent: 50
127
- }
128
- }
129
- end
130
-
131
- def config_option(type, option)
132
- default_option = config_defaults[type][option]
133
- if configuration[type]
134
- configuration[type][option] || default_option
135
- else
136
- default_option
137
- end
138
- end
139
-
140
- private
141
-
142
- # explode psuedo-names for text position
143
- def position_transform(position)
144
- case position
145
- when 'NE'
146
- 'NorthEast'
147
- when 'NW'
148
- 'NorthWest'
149
- when 'SE'
150
- 'SouthEast'
151
- when 'SW'
152
- 'SouthWest'
153
- when 'C'
154
- 'Center'
155
- when 'S'
156
- 'South'
157
- end
158
- end
159
-
160
- # do whatever is required to commit message to get it clean and ready for imagemagick
161
- def clean_msg(text)
162
- wrapped_text = word_wrap text
163
- escape_quotes wrapped_text
164
- escape_ats wrapped_text
165
- end
166
-
167
- # conversion for quotation marks to avoid shell interpretation
168
- # does not seem to be a safe way to escape cross-platform?
169
- def escape_quotes(text)
170
- text.gsub(/"/, "''")
171
- end
172
-
173
- def escape_ats(text)
174
- text.gsub(/@/, '\@')
175
- end
176
-
177
- # convenience method for word wrapping
178
- # based on https://github.com/cmdrkeene/memegen/blob/master/lib/meme_generator.rb
179
- def word_wrap(text, col = 27)
180
- wrapped = text.gsub(/(.{1,#{col + 4}})(\s+|\Z)/, "\\1\n")
181
- wrapped.chomp!
182
- end
183
- end
184
- end
@@ -1,54 +0,0 @@
1
- # -*- encoding : utf-8 -*-
2
- require 'base64'
3
-
4
- module Lolcommits
5
- class TermOutput < Plugin
6
- def run_postcapture
7
- if terminal_supported?
8
- if !runner.vcs_info || runner.vcs_info.repo.empty?
9
- debug 'repo is empty, skipping term output'
10
- else
11
- base64 = Base64.encode64(open(runner.main_image, &:read))
12
- puts "#{begin_escape}1337;File=inline=1:#{base64};alt=#{runner.message};#{end_escape}\n"
13
- end
14
- else
15
- debug 'Disabled, your terminal is not supported (requires iTerm2)'
16
- end
17
- end
18
-
19
- def self.name
20
- 'term_output'
21
- end
22
-
23
- def self.runner_order
24
- :postcapture
25
- end
26
-
27
- def configure_options!
28
- if terminal_supported?
29
- super
30
- else
31
- puts "Sorry, your terminal does not support the #{self.class.name} plugin (requires iTerm2)"
32
- end
33
- end
34
-
35
- private
36
-
37
- # escape sequences for tmux sessions differ
38
- def begin_escape
39
- tmux? ? "\033Ptmux;\033\033]" : "\033]"
40
- end
41
-
42
- def end_escape
43
- tmux? ? "\a\033\\" : "\a"
44
- end
45
-
46
- def tmux?
47
- !ENV['TMUX'].nil?
48
- end
49
-
50
- def terminal_supported?
51
- ENV['TERM_PROGRAM'] =~ /iTerm/
52
- end
53
- end
54
- end
@@ -1,66 +0,0 @@
1
- # -*- encoding : utf-8 -*-
2
- require 'rest_client'
3
- require 'base64'
4
-
5
- module Lolcommits
6
- class Uploldz < Plugin
7
- attr_accessor :endpoint
8
-
9
- def initialize(runner)
10
- super
11
- options.concat(
12
- %w(
13
- endpoint
14
- optional_key
15
- optional_http_auth_username
16
- optional_http_auth_password
17
- )
18
- )
19
- end
20
-
21
- def run_postcapture
22
- return unless valid_configuration?
23
-
24
- if !runner.vcs_info || runner.vcs_info.repo.empty?
25
- puts 'Repo is empty, skipping upload'
26
- else
27
- debug "Posting capture to #{configuration['endpoint']}"
28
- RestClient.post(
29
- configuration['endpoint'],
30
- {
31
- file: File.new(runner.main_image),
32
- message: runner.message,
33
- repo: runner.vcs_info.repo,
34
- author_name: runner.vcs_info.author_name,
35
- author_email: runner.vcs_info.author_email,
36
- sha: runner.sha,
37
- key: configuration['optional_key']
38
- },
39
- Authorization: authorization_header
40
- )
41
- end
42
- rescue => e
43
- log_error(e, "ERROR: RestClient POST FAILED #{e.class} - #{e.message}")
44
- end
45
-
46
- def configured?
47
- !configuration['enabled'].nil? && configuration['endpoint']
48
- end
49
-
50
- def authorization_header
51
- user = configuration['optional_http_auth_username']
52
- password = configuration['optional_http_auth_password']
53
- return unless user || password
54
-
55
- 'Basic ' + Base64.encode64("#{user}:#{password}").chomp
56
- end
57
-
58
- def self.name
59
- 'uploldz'
60
- end
61
-
62
- def self.runner_order
63
- :postcapture
64
- end
65
- end
66
- end