acmcommits 0.0.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.
- data/.gitignore +12 -0
- data/.travis.yml +20 -0
- data/CHANGELOG +99 -0
- data/CONTRIBUTING +11 -0
- data/Gemfile +4 -0
- data/LICENSE +165 -0
- data/README.md +74 -0
- data/Rakefile +69 -0
- data/acmcommits.gemspec +39 -0
- data/bin/lolcommits +309 -0
- data/features/bugs.feature +58 -0
- data/features/lolcommits.feature +147 -0
- data/features/plugins.feature +34 -0
- data/features/step_definitions/lolcommits_steps.rb +98 -0
- data/features/support/env.rb +94 -0
- data/lib/core_ext/class.rb +7 -0
- data/lib/lolcommits/capture_fake.rb +10 -0
- data/lib/lolcommits/capture_linux.rb +28 -0
- data/lib/lolcommits/capture_mac.rb +19 -0
- data/lib/lolcommits/capture_windows.rb +18 -0
- data/lib/lolcommits/capturer.rb +13 -0
- data/lib/lolcommits/configuration.rb +160 -0
- data/lib/lolcommits/git_info.rb +27 -0
- data/lib/lolcommits/plugin.rb +40 -0
- data/lib/lolcommits/plugins/lolsrv.rb +73 -0
- data/lib/lolcommits/plugins/loltext.rb +79 -0
- data/lib/lolcommits/plugins/statsd.rb +25 -0
- data/lib/lolcommits/runner.rb +97 -0
- data/lib/lolcommits/version.rb +3 -0
- data/lib/lolcommits.rb +27 -0
- data/test/images/test_image.jpg +0 -0
- data/test/test_lolcommits.rb +49 -0
- data/vendor/ext/CommandCam/COPYING +674 -0
- data/vendor/ext/CommandCam/CommandCam.exe +0 -0
- data/vendor/ext/CommandCam/LICENSE +16 -0
- data/vendor/ext/imagesnap/ReadMeOrDont.rtf +117 -0
- data/vendor/ext/imagesnap/imagesnap +0 -0
- data/vendor/fonts/Impact.ttf +0 -0
- metadata +228 -0
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'aruba/cucumber'
|
2
|
+
require 'methadone/cucumber'
|
3
|
+
require 'open3'
|
4
|
+
require 'test/unit/assertions'
|
5
|
+
include Test::Unit::Assertions
|
6
|
+
require 'faker'
|
7
|
+
require 'lolcommits/configuration'
|
8
|
+
include Lolcommits
|
9
|
+
|
10
|
+
ENV['PATH'] = "#{File.expand_path(File.dirname(__FILE__) + '/../../bin')}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
|
11
|
+
LIB_DIR = File.join(File.expand_path(File.dirname(__FILE__)),'..','..','lib')
|
12
|
+
|
13
|
+
Before do
|
14
|
+
# Using "announce" causes massive warnings on 1.9.2
|
15
|
+
@puts = true
|
16
|
+
@aruba_timeout_seconds = 20
|
17
|
+
|
18
|
+
@original_rubylib = ENV['RUBYLIB']
|
19
|
+
ENV['RUBYLIB'] = LIB_DIR + File::PATH_SEPARATOR + ENV['RUBYLIB'].to_s
|
20
|
+
|
21
|
+
@original_fakecapture = ENV['LOLCOMMITS_FAKECAPTURE']
|
22
|
+
ENV['LOLCOMMITS_FAKECAPTURE'] = "1"
|
23
|
+
|
24
|
+
# @original_loldir = ENV['LOLCOMMITS_DIR']
|
25
|
+
# ENV['LOLCOMMITS_DIR'] = File.expand_path( File.join(current_dir, ".lolcommits") )
|
26
|
+
|
27
|
+
@original_home = ENV['HOME']
|
28
|
+
ENV['HOME'] = File.expand_path( current_dir )
|
29
|
+
|
30
|
+
ENV['LAUNCHY_DRY_RUN'] = 'true'
|
31
|
+
end
|
32
|
+
|
33
|
+
After do
|
34
|
+
ENV['RUBYLIB'] = @original_rubylib
|
35
|
+
ENV['LOLCOMMITS_FAKECAPTURE'] = @original_fakecapture
|
36
|
+
# ENV['LOLCOMMITS_DIR'] = @original_loldir
|
37
|
+
ENV['HOME'] = @original_home
|
38
|
+
ENV['LAUNCHY_DRY_RUN'] = nil
|
39
|
+
end
|
40
|
+
|
41
|
+
Before('@fake-interactive-rebase') do
|
42
|
+
# in order to fake an interactive rebase,
|
43
|
+
# we replace the editor with a script that simply squashes a few random commits
|
44
|
+
@original_git_editor = ENV['GIT_EDITOR']
|
45
|
+
# ENV['GIT_EDITOR'] = "sed -i -e 'n;s/pick/squash/g'" #every other commit
|
46
|
+
ENV['GIT_EDITOR'] = "sed -i -e '3,5 s/pick/squash/g'" #lines 3-5
|
47
|
+
end
|
48
|
+
|
49
|
+
After('@fake-interactive-rebase') do
|
50
|
+
ENV['GIT_EDITOR'] = @original_git_editor
|
51
|
+
end
|
52
|
+
|
53
|
+
Before('@slow_process') do
|
54
|
+
@aruba_io_wait_seconds = 5
|
55
|
+
@aruba_timeout_seconds = 60
|
56
|
+
end
|
57
|
+
|
58
|
+
# adjust the path so tests dont see a global imagemagick install
|
59
|
+
Before('@fake-no-imagemagick') do
|
60
|
+
|
61
|
+
# make a new subdir that still contains git and mplayer
|
62
|
+
tmpbindir = File.expand_path(File.join @dirs, "bin")
|
63
|
+
FileUtils.mkdir_p tmpbindir
|
64
|
+
["git","mplayer"].each do |cmd|
|
65
|
+
whichcmd = Lolcommits::Configuration.command_which(cmd)
|
66
|
+
unless whichcmd.nil?
|
67
|
+
FileUtils.ln_s whichcmd, File.join(tmpbindir, File.basename(whichcmd))
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# use a modified version of Configuration::command_which to detect where IM is installed
|
72
|
+
# and remove that from the path
|
73
|
+
cmd = 'mogrify'
|
74
|
+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
75
|
+
newpaths = ENV['PATH'].split(File::PATH_SEPARATOR).reject do |path|
|
76
|
+
found_cmd = false
|
77
|
+
exts.each { |ext|
|
78
|
+
exe = "#{path}/#{cmd}#{ext}"
|
79
|
+
found_cmd = true if File.executable? exe
|
80
|
+
}
|
81
|
+
found_cmd
|
82
|
+
end
|
83
|
+
|
84
|
+
# add the temporary directory with git in it back into the path
|
85
|
+
newpaths << tmpbindir
|
86
|
+
|
87
|
+
@original_path = ENV['PATH']
|
88
|
+
ENV['PATH'] = newpaths.join(File::PATH_SEPARATOR)
|
89
|
+
puts ENV['PATH']
|
90
|
+
end
|
91
|
+
|
92
|
+
After('@fake-no-imagemagick') do
|
93
|
+
ENV['PATH'] = @original_path
|
94
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Lolcommits
|
2
|
+
class CaptureLinux < Capturer
|
3
|
+
def capture
|
4
|
+
debug "LinuxCapturer: making tmp directory"
|
5
|
+
tmpdir = Dir.mktmpdir
|
6
|
+
|
7
|
+
# There's no way to give a capture delay in mplayer, but a number of frame
|
8
|
+
# I've found that 6 is a good value for me.
|
9
|
+
frames = if capture_delay != 0 then capture_delay else 6 end
|
10
|
+
|
11
|
+
debug "LinuxCapturer: calling out to mplayer to capture image"
|
12
|
+
# mplayer's output is ugly and useless, let's throw it away
|
13
|
+
_, r, _ = Open3.popen3("mplayer -vo jpeg:outdir=#{tmpdir} -frames #{frames} tv://")
|
14
|
+
# looks like we still need to read the output for something to happen
|
15
|
+
r.read
|
16
|
+
|
17
|
+
# the below SHOULD tell FileUtils actions to post their output if we are in debug mode
|
18
|
+
include FileUtils::Verbose if logger.level == 0
|
19
|
+
|
20
|
+
debug "LinuxCapturer: calling out to mplayer to capture image"
|
21
|
+
FileUtils.mv(tmpdir + "/%08d.jpg" % frames, snapshot_location)
|
22
|
+
debug "LinuxCapturer: cleaning up"
|
23
|
+
FileUtils.rm_rf( tmpdir )
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Lolcommits
|
2
|
+
class CaptureMac < Capturer
|
3
|
+
def capture_device_string
|
4
|
+
@capture_device.nil? ? nil : "-d \"#{@capture_device}\""
|
5
|
+
end
|
6
|
+
|
7
|
+
def capture
|
8
|
+
call_str = "#{imagesnap_bin} -q \"#{snapshot_location}\" -w #{capture_delay} #{capture_device_string}"
|
9
|
+
debug "Capturer: making system call for #{call_str}"
|
10
|
+
system(call_str)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def imagesnap_bin
|
16
|
+
File.join(Configuration::LOLCOMMITS_ROOT, "vendor", "ext", "imagesnap", "imagesnap")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Lolcommits
|
2
|
+
class CaptureWindows < Capturer
|
3
|
+
def capture
|
4
|
+
commandcam_exe = File.join Configuration::LOLCOMMITS_ROOT, "vendor", "ext", "CommandCam", "CommandCam.exe"
|
5
|
+
# DirectShow takes a while to show... at least for me anyway
|
6
|
+
delaycmd = " /delay 3000"
|
7
|
+
if capture_delay > 0
|
8
|
+
# CommandCam delay is in milliseconds
|
9
|
+
delaycmd = " /delay #{capture_delay * 1000}"
|
10
|
+
end
|
11
|
+
_, r, _ = Open3.popen3("#{commandcam_exe} /filename #{snapshot_location}#{delaycmd}")
|
12
|
+
# looks like we still need to read the output for something to happen
|
13
|
+
r.read
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Lolcommits
|
2
|
+
class Capturer
|
3
|
+
include Methadone::CLILogging
|
4
|
+
attr_accessor :capture_device, :capture_delay, :snapshot_location, :font
|
5
|
+
|
6
|
+
def initialize(attributes = Hash.new)
|
7
|
+
attributes.each do |attr, val|
|
8
|
+
self.send("#{attr}=", val)
|
9
|
+
end
|
10
|
+
debug "Capturer: initializing new instance " + self.to_s
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
module Lolcommits
|
2
|
+
class Configuration
|
3
|
+
LOLBASEDIR = ENV['LOLCOMMITS_DIR'] || File.join(ENV['HOME'], '.lolcommits')
|
4
|
+
LOLCOMMITS_ROOT = File.join(File.dirname(__FILE__), '../..')
|
5
|
+
attr_writer :loldir
|
6
|
+
|
7
|
+
def initialize(attributes={})
|
8
|
+
attributes.each do |attr, val|
|
9
|
+
self.send("#{attr}=", val)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.platform
|
14
|
+
if is_fakecapture?
|
15
|
+
'Fake'
|
16
|
+
elsif is_mac?
|
17
|
+
'Mac'
|
18
|
+
elsif is_linux?
|
19
|
+
'Linux'
|
20
|
+
elsif is_windows?
|
21
|
+
'Windows'
|
22
|
+
else
|
23
|
+
raise "Unknown / Unsupported Platform."
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def user_configuration
|
28
|
+
if File.exists?(user_configuration_file)
|
29
|
+
YAML.load(File.open(user_configuration_file))
|
30
|
+
else
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def user_configuration_file
|
36
|
+
"#{self.loldir}/config.yml"
|
37
|
+
end
|
38
|
+
|
39
|
+
def loldir
|
40
|
+
return @loldir if @loldir
|
41
|
+
|
42
|
+
basename ||= File.basename(Git.open('.').dir.to_s).sub(/^\./, 'dot')
|
43
|
+
basename.sub!(/ /, '-')
|
44
|
+
|
45
|
+
@loldir = Configuration.loldir_for(basename)
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.loldir_for(basename)
|
49
|
+
loldir = File.join(LOLBASEDIR, basename)
|
50
|
+
|
51
|
+
if not File.directory? loldir
|
52
|
+
FileUtils.mkdir_p loldir
|
53
|
+
end
|
54
|
+
loldir
|
55
|
+
end
|
56
|
+
|
57
|
+
def most_recent
|
58
|
+
Dir.glob(File.join self.loldir, "*").max_by {|f| File.mtime(f)}
|
59
|
+
end
|
60
|
+
|
61
|
+
def raw_image
|
62
|
+
File.join self.loldir, "tmp_snapshot.jpg"
|
63
|
+
end
|
64
|
+
|
65
|
+
def main_image(commit_sha)
|
66
|
+
File.join self.loldir, "#{commit_sha}.jpg"
|
67
|
+
end
|
68
|
+
|
69
|
+
def puts_plugins
|
70
|
+
names = Lolcommits::PLUGINS.collect {|p| p.new(nil).name }
|
71
|
+
puts "Available plugins: #{names.join(', ')}"
|
72
|
+
end
|
73
|
+
|
74
|
+
def do_configure!(plugin, forced_options=nil)
|
75
|
+
if plugin.nil? || plugin.strip == ''
|
76
|
+
puts_plugins
|
77
|
+
print "Name of plugin to configure: "
|
78
|
+
plugin = STDIN.gets.strip
|
79
|
+
end
|
80
|
+
|
81
|
+
plugins = Lolcommits::PLUGINS.inject(Hash.new) do |acc, val|
|
82
|
+
p = val.new(nil)
|
83
|
+
acc.merge(p.name => p)
|
84
|
+
end
|
85
|
+
|
86
|
+
plugin_object = plugins[plugin]
|
87
|
+
|
88
|
+
if plugin_object.nil?
|
89
|
+
puts "Unable to find plugin: #{plugin}"
|
90
|
+
return
|
91
|
+
end
|
92
|
+
|
93
|
+
if forced_options.nil?
|
94
|
+
options = plugin_object.options.inject(Hash.new) do |acc, option|
|
95
|
+
print "#{option}: "
|
96
|
+
val = STDIN.gets.strip
|
97
|
+
val = true if val == 'true'
|
98
|
+
val = false if val == 'false'
|
99
|
+
|
100
|
+
acc.merge(option => val)
|
101
|
+
end
|
102
|
+
else
|
103
|
+
options = forced_options
|
104
|
+
end
|
105
|
+
|
106
|
+
config = self.user_configuration || Hash.new
|
107
|
+
config[plugin] = options
|
108
|
+
File.open(self.user_configuration_file, 'w') do |f|
|
109
|
+
f.write(config.to_yaml)
|
110
|
+
end
|
111
|
+
|
112
|
+
puts "#{config.to_yaml}\n"
|
113
|
+
puts "Successfully Configured"
|
114
|
+
end
|
115
|
+
|
116
|
+
def self.is_mac?
|
117
|
+
RUBY_PLATFORM.to_s.downcase.include?("darwin")
|
118
|
+
end
|
119
|
+
|
120
|
+
def self.is_linux?
|
121
|
+
RUBY_PLATFORM.to_s.downcase.include?("linux")
|
122
|
+
end
|
123
|
+
|
124
|
+
def self.is_windows?
|
125
|
+
!! RUBY_PLATFORM.match(/(win|w)32/)
|
126
|
+
end
|
127
|
+
|
128
|
+
def self.is_fakecapture?
|
129
|
+
(ENV['LOLCOMMITS_FAKECAPTURE'] == '1' || false)
|
130
|
+
end
|
131
|
+
|
132
|
+
def self.valid_imagemagick_installed?
|
133
|
+
return false unless self.command_which('identify')
|
134
|
+
return false unless self.command_which('mogrify')
|
135
|
+
# you'd expect the below to work on its own, but it only handles old versions
|
136
|
+
# and will throw an exception if IM is not installed in PATH
|
137
|
+
MiniMagick::valid_version_installed?
|
138
|
+
end
|
139
|
+
|
140
|
+
def self.git_config_color_always?
|
141
|
+
`git config color.ui`.chomp =~ /always/
|
142
|
+
end
|
143
|
+
|
144
|
+
# Cross-platform way of finding an executable in the $PATH.
|
145
|
+
# idea taken from http://bit.ly/qDaTbY
|
146
|
+
#
|
147
|
+
# which('ruby') #=> /usr/bin/ruby
|
148
|
+
def self.command_which(cmd)
|
149
|
+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
150
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
151
|
+
exts.each { |ext|
|
152
|
+
exe = "#{path}/#{cmd}#{ext}"
|
153
|
+
return exe if File.executable? exe
|
154
|
+
}
|
155
|
+
end
|
156
|
+
return nil
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Lolcommits
|
2
|
+
class GitInfo
|
3
|
+
include Methadone::CLILogging
|
4
|
+
attr_accessor :sha, :message, :repo_internal_path, :repo
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
debug "GitInfo: attempting to read local repository"
|
8
|
+
g = Git.open('.')
|
9
|
+
debug "GitInfo: reading commits logs"
|
10
|
+
commit = g.log.first
|
11
|
+
debug "GitInfo: most recent commit is '#{commit}'"
|
12
|
+
|
13
|
+
self.message = commit.message.split("\n").first
|
14
|
+
self.sha = commit.sha[0..10]
|
15
|
+
self.repo_internal_path = g.repo.path
|
16
|
+
regex = /.*[:\/](\w*).git/
|
17
|
+
match = g.remote.url.match regex if g.remote.url
|
18
|
+
self.repo = match[1] if match
|
19
|
+
|
20
|
+
debug "GitInfo: parsed the following values from commit:"
|
21
|
+
debug "GitInfo: \t#{self.message}"
|
22
|
+
debug "GitInfo: \t#{self.sha}"
|
23
|
+
debug "GitInfo: \t#{self.repo_internal_path}"
|
24
|
+
debug "GitInfo: \t#{self.repo}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Lolcommits
|
2
|
+
class Plugin
|
3
|
+
include Methadone::CLILogging
|
4
|
+
attr_accessor :default, :name, :runner, :options
|
5
|
+
|
6
|
+
def configuration
|
7
|
+
config = runner.config.user_configuration
|
8
|
+
return Hash.new if config.nil?
|
9
|
+
config[self.name] || Hash.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(runner)
|
13
|
+
self.runner = runner
|
14
|
+
self.options = ['enabled']
|
15
|
+
|
16
|
+
plugdebug "Initializing"
|
17
|
+
end
|
18
|
+
|
19
|
+
def is_enabled?
|
20
|
+
enabled_config = configuration['enabled']
|
21
|
+
return self.default if enabled_config.nil? || enabled_config == ''
|
22
|
+
return enabled_config
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
def execute
|
27
|
+
if is_enabled?
|
28
|
+
plugdebug "I am enabled, about to run"
|
29
|
+
run
|
30
|
+
else
|
31
|
+
plugdebug "Disabled, doing nothing for execution"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# uniform debug logging output for plugins
|
36
|
+
def plugdebug(msg)
|
37
|
+
debug("Plugin: #{self.class.to_s}: " + msg)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require "rest_client"
|
2
|
+
require "pp"
|
3
|
+
require "json"
|
4
|
+
require "logger"
|
5
|
+
|
6
|
+
module Lolcommits
|
7
|
+
|
8
|
+
class Lolsrv < Plugin
|
9
|
+
|
10
|
+
SERVER = 'server'
|
11
|
+
|
12
|
+
def initialize(runner)
|
13
|
+
super
|
14
|
+
self.name = 'lolsrv'
|
15
|
+
self.default = false
|
16
|
+
self.options << SERVER
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
def run
|
21
|
+
|
22
|
+
log_file = File.new(self.runner.config.loldir + "/lolsrv.log", "a+")
|
23
|
+
@logger = Logger.new(log_file)
|
24
|
+
|
25
|
+
if configuration[SERVER].nil?
|
26
|
+
puts "Missing server configuration. Use lolcommits --config -p lolsrv"
|
27
|
+
return
|
28
|
+
end
|
29
|
+
|
30
|
+
fork do
|
31
|
+
sync()
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def sync
|
36
|
+
existing = get_existing_lols
|
37
|
+
unless existing.nil?
|
38
|
+
Dir.glob(self.runner.config.loldir + "/*.jpg") do |item|
|
39
|
+
next if item == '.' or item == '..'
|
40
|
+
# do work on real items
|
41
|
+
sha = File.basename(item, '.*')
|
42
|
+
unless existing.include?(sha) || sha == 'tmp_snapshot'
|
43
|
+
upload(item, sha)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def get_existing_lols
|
50
|
+
begin
|
51
|
+
lols = JSON.parse(
|
52
|
+
RestClient.get(configuration[SERVER] + '/commits'))
|
53
|
+
lols.map { |lol| lol["sha"] }
|
54
|
+
rescue => error
|
55
|
+
@logger.info "Existing commits could not be retrieved with Error " + error.message
|
56
|
+
@logger.info error.backtrace
|
57
|
+
return nil
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def upload(file, sha)
|
62
|
+
begin
|
63
|
+
RestClient.post(
|
64
|
+
configuration[SERVER] + '/upload',
|
65
|
+
:lol => File.new(file),
|
66
|
+
:sha => sha)
|
67
|
+
rescue => error
|
68
|
+
@logger.info "Upload of LOL "+ sha + " failed with Error " + error.message
|
69
|
+
return
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Lolcommits
|
2
|
+
class Loltext < Plugin
|
3
|
+
|
4
|
+
def initialize(runner)
|
5
|
+
super
|
6
|
+
|
7
|
+
@font_location = runner ? runner.font : nil
|
8
|
+
|
9
|
+
self.name = 'loltext'
|
10
|
+
self.default = true
|
11
|
+
end
|
12
|
+
|
13
|
+
def run
|
14
|
+
mm_run
|
15
|
+
end
|
16
|
+
|
17
|
+
# use minimagick wrapper
|
18
|
+
def mm_run
|
19
|
+
font_location = @font_location || File.join(Configuration::LOLCOMMITS_ROOT, "vendor", "fonts", "Impact.ttf")
|
20
|
+
|
21
|
+
plugdebug "Annotating image via MiniMagick"
|
22
|
+
image = MiniMagick::Image.open(self.runner.main_image)
|
23
|
+
image.combine_options do |c|
|
24
|
+
c.gravity 'SouthWest'
|
25
|
+
c.fill 'white'
|
26
|
+
c.stroke 'black'
|
27
|
+
c.strokewidth '2'
|
28
|
+
c.pointsize '48'
|
29
|
+
c.interline_spacing '-9'
|
30
|
+
c.font font_location
|
31
|
+
c.annotate '0', clean_msg(self.runner.message)
|
32
|
+
end
|
33
|
+
|
34
|
+
image.combine_options do |c|
|
35
|
+
c.gravity 'NorthEast'
|
36
|
+
c.fill 'white'
|
37
|
+
c.stroke 'black'
|
38
|
+
c.strokewidth '2'
|
39
|
+
c.pointsize '32'
|
40
|
+
c.font font_location
|
41
|
+
c.annotate '0', self.runner.sha
|
42
|
+
end
|
43
|
+
|
44
|
+
plugdebug "Writing changed file to #{self.runner.main_image}"
|
45
|
+
image.write self.runner.main_image
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
# do whatever is required to commit message to get it clean and ready for imagemagick
|
51
|
+
def clean_msg(text)
|
52
|
+
wrapped_text = word_wrap text
|
53
|
+
escape_quotes wrapped_text
|
54
|
+
text = scrub_profanity text
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
#search the commit for profanity and if it exists remove the commit
|
59
|
+
def scrub_profanity(text)
|
60
|
+
profanity = ['fuck', 'bitch', 'cunt', 'hate', 'pissed', 'balls', 'screw', 'ACM',
|
61
|
+
'ass']
|
62
|
+
text.each do |word|
|
63
|
+
text = ' ' if profanity.include? word
|
64
|
+
end
|
65
|
+
end
|
66
|
+
# conversion for quotation marks to avoid shell interpretation
|
67
|
+
# does not seem to be a safe way to escape cross-platform?
|
68
|
+
def escape_quotes(text)
|
69
|
+
text.gsub(/"/, "''")
|
70
|
+
end
|
71
|
+
|
72
|
+
# convenience method for word wrapping
|
73
|
+
# based on https://github.com/cmdrkeene/memegen/blob/master/lib/meme_generator.rb
|
74
|
+
def word_wrap(text, col = 27)
|
75
|
+
wrapped = text.gsub(/(.{1,#{col + 4}})(\s+|\Z)/, "\\1\n")
|
76
|
+
wrapped.chomp!
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "statsd"
|
2
|
+
|
3
|
+
#
|
4
|
+
# This is just to keep some usage statistics on lolcommits.
|
5
|
+
#
|
6
|
+
|
7
|
+
module Lolcommits
|
8
|
+
class StatsD < Plugin
|
9
|
+
def initialize(runner)
|
10
|
+
super
|
11
|
+
|
12
|
+
self.name = 'statsd'
|
13
|
+
self.default = true
|
14
|
+
end
|
15
|
+
|
16
|
+
def run
|
17
|
+
$statsd = Statsd.new('23.20.178.143')
|
18
|
+
if Configuration.is_fakecapture?
|
19
|
+
$statsd.increment 'app.lolcommits.fakecaptures'
|
20
|
+
else
|
21
|
+
$statsd.increment 'app.lolcommits.captures'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|