lolcommits 0.13.1 → 0.14.0
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 +5 -5
- data/.rubocop.yml +1 -0
- data/.rubocop_todo.yml +3 -3
- data/CHANGELOG.md +18 -7
- data/Gemfile +2 -0
- data/README.md +101 -76
- data/Rakefile +3 -1
- data/bin/console +1 -0
- data/bin/lolcommits +37 -32
- data/config/cucumber.yml +1 -1
- data/features/bugs.feature +2 -2
- data/features/lolcommits.feature +42 -17
- data/features/step_definitions/lolcommits_steps.rb +7 -3
- data/lib/lolcommits/animated_gif.rb +77 -0
- data/lib/lolcommits/backends/git_info.rb +15 -11
- data/lib/lolcommits/backends/installation_git.rb +4 -3
- data/lib/lolcommits/backends/installation_mercurial.rb +1 -1
- data/lib/lolcommits/backends/mercurial_info.rb +13 -9
- data/lib/lolcommits/capturer.rb +14 -6
- data/lib/lolcommits/capturer/capture_cygwin.rb +3 -14
- data/lib/lolcommits/capturer/capture_fake.rb +8 -2
- data/lib/lolcommits/capturer/capture_linux.rb +11 -10
- data/lib/lolcommits/capturer/capture_linux_video.rb +15 -0
- data/lib/lolcommits/capturer/capture_mac.rb +6 -11
- data/lib/lolcommits/capturer/capture_mac_video.rb +23 -0
- data/lib/lolcommits/capturer/capture_windows.rb +14 -9
- data/lib/lolcommits/capturer/capture_windows_video.rb +46 -0
- data/lib/lolcommits/cli/fatals.rb +1 -1
- data/lib/lolcommits/cli/launcher.rb +1 -1
- data/lib/lolcommits/cli/timelapse_gif.rb +28 -12
- data/lib/lolcommits/configuration.rb +4 -26
- data/lib/lolcommits/platform.rb +4 -4
- data/lib/lolcommits/plugin/base.rb +2 -2
- data/lib/lolcommits/plugin/configuration_helper.rb +1 -1
- data/lib/lolcommits/runner.rb +138 -69
- data/lib/lolcommits/version.rb +2 -2
- data/lolcommits.gemspec +4 -2
- data/test/assets/test_image.jpg +0 -0
- data/test/assets/test_video.mp4 +0 -0
- metadata +12 -9
- data/lib/lolcommits/capturer/capture_linux_animated.rb +0 -74
- data/lib/lolcommits/capturer/capture_mac_animated.rb +0 -75
- data/lib/lolcommits/capturer/capture_windows_animated.rb +0 -110
data/lib/lolcommits/version.rb
CHANGED
data/lolcommits.gemspec
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
lib = File.expand_path('lib', __dir__)
|
2
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
5
|
require 'lolcommits/version'
|
@@ -44,13 +46,13 @@ Gem::Specification.new do |s|
|
|
44
46
|
s.add_runtime_dependency('git', '~> 1.5.0')
|
45
47
|
|
46
48
|
# included plugins
|
47
|
-
s.add_runtime_dependency('lolcommits-loltext', '~> 0.
|
49
|
+
s.add_runtime_dependency('lolcommits-loltext', '~> 0.2.3')
|
48
50
|
|
49
51
|
# development & test gems
|
50
52
|
s.add_development_dependency('aruba')
|
51
53
|
s.add_development_dependency('rake')
|
52
54
|
s.add_development_dependency('rdoc')
|
53
|
-
s.add_development_dependency('pry')
|
55
|
+
s.add_development_dependency('pry-remote')
|
54
56
|
s.add_development_dependency('rubocop')
|
55
57
|
s.add_development_dependency('minitest')
|
56
58
|
s.add_development_dependency('simplecov')
|
Binary file
|
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lolcommits
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew Rothenberg
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2019-
|
12
|
+
date: 2019-05-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: methadone
|
@@ -101,14 +101,14 @@ dependencies:
|
|
101
101
|
requirements:
|
102
102
|
- - "~>"
|
103
103
|
- !ruby/object:Gem::Version
|
104
|
-
version: 0.
|
104
|
+
version: 0.2.3
|
105
105
|
type: :runtime
|
106
106
|
prerelease: false
|
107
107
|
version_requirements: !ruby/object:Gem::Requirement
|
108
108
|
requirements:
|
109
109
|
- - "~>"
|
110
110
|
- !ruby/object:Gem::Version
|
111
|
-
version: 0.
|
111
|
+
version: 0.2.3
|
112
112
|
- !ruby/object:Gem::Dependency
|
113
113
|
name: aruba
|
114
114
|
requirement: !ruby/object:Gem::Requirement
|
@@ -152,7 +152,7 @@ dependencies:
|
|
152
152
|
- !ruby/object:Gem::Version
|
153
153
|
version: '0'
|
154
154
|
- !ruby/object:Gem::Dependency
|
155
|
-
name: pry
|
155
|
+
name: pry-remote
|
156
156
|
requirement: !ruby/object:Gem::Requirement
|
157
157
|
requirements:
|
158
158
|
- - ">="
|
@@ -260,6 +260,7 @@ files:
|
|
260
260
|
- lib/core_ext/mercurial-ruby/command.rb
|
261
261
|
- lib/core_ext/mercurial-ruby/shell.rb
|
262
262
|
- lib/lolcommits.rb
|
263
|
+
- lib/lolcommits/animated_gif.rb
|
263
264
|
- lib/lolcommits/backends/git_info.rb
|
264
265
|
- lib/lolcommits/backends/installation_git.rb
|
265
266
|
- lib/lolcommits/backends/installation_mercurial.rb
|
@@ -268,11 +269,11 @@ files:
|
|
268
269
|
- lib/lolcommits/capturer/capture_cygwin.rb
|
269
270
|
- lib/lolcommits/capturer/capture_fake.rb
|
270
271
|
- lib/lolcommits/capturer/capture_linux.rb
|
271
|
-
- lib/lolcommits/capturer/
|
272
|
+
- lib/lolcommits/capturer/capture_linux_video.rb
|
272
273
|
- lib/lolcommits/capturer/capture_mac.rb
|
273
|
-
- lib/lolcommits/capturer/
|
274
|
+
- lib/lolcommits/capturer/capture_mac_video.rb
|
274
275
|
- lib/lolcommits/capturer/capture_windows.rb
|
275
|
-
- lib/lolcommits/capturer/
|
276
|
+
- lib/lolcommits/capturer/capture_windows_video.rb
|
276
277
|
- lib/lolcommits/cli.rb
|
277
278
|
- lib/lolcommits/cli/fatals.rb
|
278
279
|
- lib/lolcommits/cli/launcher.rb
|
@@ -291,6 +292,8 @@ files:
|
|
291
292
|
- lib/lolcommits/vcs_info.rb
|
292
293
|
- lib/lolcommits/version.rb
|
293
294
|
- lolcommits.gemspec
|
295
|
+
- test/assets/test_image.jpg
|
296
|
+
- test/assets/test_video.mp4
|
294
297
|
- test/images/test_image.jpg
|
295
298
|
- test/permissions_test.rb
|
296
299
|
- test/test_helper.rb
|
@@ -327,7 +330,7 @@ requirements:
|
|
327
330
|
- imagemagick
|
328
331
|
- a webcam
|
329
332
|
rubyforge_project:
|
330
|
-
rubygems_version: 2.
|
333
|
+
rubygems_version: 2.7.7
|
331
334
|
signing_key:
|
332
335
|
specification_version: 4
|
333
336
|
summary: Capture webcam image on git commit for lulz.
|
@@ -1,74 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Lolcommits
|
4
|
-
class CaptureLinuxAnimated < Capturer
|
5
|
-
def capture
|
6
|
-
# make a fresh frames directory
|
7
|
-
FileUtils.rm_rf(frames_location)
|
8
|
-
FileUtils.mkdir_p(frames_location)
|
9
|
-
|
10
|
-
# capture the raw video with ffmpeg video4linux2
|
11
|
-
system_call "ffmpeg -v quiet -y -f video4linux2 -video_size 320x240 -i #{capture_device_string} -t #{capture_duration} \"#{video_location}\" > /dev/null"
|
12
|
-
return unless File.exist?(video_location)
|
13
|
-
|
14
|
-
# convert raw video to png frames with ffmpeg
|
15
|
-
system_call "ffmpeg #{capture_delay_string} -v quiet -i \"#{video_location}\" -t #{animated_duration} \"#{frames_location}/%09d.png\" > /dev/null"
|
16
|
-
|
17
|
-
# use fps to set delay and number of frames to skip (for lower filesized gifs)
|
18
|
-
fps = video_fps(video_location)
|
19
|
-
skip = frame_skip(fps)
|
20
|
-
delay = frame_delay(fps, skip)
|
21
|
-
debug "Capturer: anaimated gif choosing every #{skip} frames with a frame delay of #{delay} (video fps: #{fps})"
|
22
|
-
|
23
|
-
# create the looping animated gif from frames (picks nth frame with seq,
|
24
|
-
# quotes output and concats to a single line with tr)
|
25
|
-
seq_command = "seq -f \"\\\"#{frames_location}/%09g.png\\\"\" 1 #{skip} #{Dir["#{frames_location}/*"].length} | tr '\\n' ' '"
|
26
|
-
seq_frame_files = system_call(seq_command, true)
|
27
|
-
# convert to animated gif with delay and gif optimisation
|
28
|
-
system_call "convert -layers OptimizeTransparency -delay #{delay} -loop 0 #{seq_frame_files} -coalesce \"#{snapshot_location}\""
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
def system_call(call_str, capture_output = false)
|
34
|
-
debug "Capturer: making system call for \n #{call_str}"
|
35
|
-
capture_output ? `#{call_str}` : system(call_str)
|
36
|
-
end
|
37
|
-
|
38
|
-
def frame_delay(fps, skip)
|
39
|
-
# calculate frame delay
|
40
|
-
delay = ((100.0 * skip) / fps.to_f).to_i
|
41
|
-
delay < 6 ? 6 : delay # hard limit for IE browsers
|
42
|
-
end
|
43
|
-
|
44
|
-
def video_fps(file)
|
45
|
-
# inspect fps of the captured video file (default to 29.97)
|
46
|
-
fps = system_call("ffmpeg -i \"#{file}\" 2>&1 | sed -n \"s/.*, \\(.*\\) fp.*/\\1/p\"", true)
|
47
|
-
fps.to_i < 1 ? 29.97 : fps.to_f
|
48
|
-
end
|
49
|
-
|
50
|
-
def frame_skip(fps)
|
51
|
-
# of frames to skip depends on movie fps
|
52
|
-
case fps
|
53
|
-
when 0..15
|
54
|
-
2
|
55
|
-
when 16..28
|
56
|
-
3
|
57
|
-
else
|
58
|
-
4
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def capture_device_string
|
63
|
-
capture_device || '/dev/video0'
|
64
|
-
end
|
65
|
-
|
66
|
-
def capture_delay_string
|
67
|
-
" -ss #{capture_delay}" if capture_delay.to_i > 0
|
68
|
-
end
|
69
|
-
|
70
|
-
def capture_duration
|
71
|
-
animated_duration.to_i + capture_delay.to_i
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
@@ -1,75 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Lolcommits
|
4
|
-
class CaptureMacAnimated < Capturer
|
5
|
-
def capture
|
6
|
-
# make a fresh frames directory
|
7
|
-
FileUtils.rm_rf(frames_location)
|
8
|
-
FileUtils.mkdir_p(frames_location)
|
9
|
-
|
10
|
-
# capture the raw video with videosnap
|
11
|
-
system_call "#{executable_path} -s 240 #{capture_device_string}#{capture_delay_string}-t #{animated_duration} --no-audio \"#{video_location}\" > /dev/null"
|
12
|
-
return unless File.exist?(video_location)
|
13
|
-
|
14
|
-
# get fps for ffmpeg output stream configuration
|
15
|
-
fps = video_fps(video_location)
|
16
|
-
# convert raw video to png frames with ffmpeg
|
17
|
-
system_call "ffmpeg -v quiet -i \"#{video_location}\" -t #{animated_duration} -r #{fps} \"#{frames_location}/%09d.png\""
|
18
|
-
|
19
|
-
# use fps to set delay and number of frames to skip (for lower filesized gifs)
|
20
|
-
skip = frame_skip(fps)
|
21
|
-
delay = frame_delay(fps, skip)
|
22
|
-
debug "Capturer: animated gif choosing every #{skip} frames with a frame delay of #{delay} (video fps: #{fps})"
|
23
|
-
|
24
|
-
# create the looping animated gif from frames (picks nth frame with seq,
|
25
|
-
# quotes output and concats to a single line with tr)
|
26
|
-
seq_command = "seq -f \"\\\"#{frames_location}/%09g.png\\\"\" 1 #{skip} #{Dir["#{frames_location}/*"].length} | tr '\\n' ' '"
|
27
|
-
seq_frame_files = system_call(seq_command, true)
|
28
|
-
# convert to animated gif with delay and gif optimisation
|
29
|
-
system_call "convert -layers OptimizeTransparency -delay #{delay} -loop 0 #{seq_frame_files} -coalesce \"#{snapshot_location}\" > /dev/null"
|
30
|
-
end
|
31
|
-
|
32
|
-
def executable_path
|
33
|
-
File.join(Configuration::LOLCOMMITS_ROOT, 'vendor', 'ext', 'videosnap', 'videosnap')
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def system_call(call_str, capture_output = false)
|
39
|
-
debug "Capturer: making system call for \n #{call_str}"
|
40
|
-
capture_output ? `#{call_str}` : system(call_str)
|
41
|
-
end
|
42
|
-
|
43
|
-
def frame_delay(fps, skip)
|
44
|
-
# calculate frame delay
|
45
|
-
delay = ((100.0 * skip) / fps.to_f).to_i
|
46
|
-
delay < 6 ? 6 : delay # hard limit for IE browsers
|
47
|
-
end
|
48
|
-
|
49
|
-
def video_fps(file)
|
50
|
-
# inspect fps of the captured video file (default to 29.97)
|
51
|
-
fps = system_call("ffmpeg -i \"#{file}\" 2>&1 | sed -n \"s/.*, \\(.*\\) fp.*/\\1/p\"", true)
|
52
|
-
fps.to_i < 1 ? 29.97 : fps.to_f
|
53
|
-
end
|
54
|
-
|
55
|
-
def frame_skip(fps)
|
56
|
-
# of frames to skip depends on movie fps
|
57
|
-
case fps
|
58
|
-
when 0..15
|
59
|
-
2
|
60
|
-
when 16..28
|
61
|
-
3
|
62
|
-
else
|
63
|
-
4
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def capture_device_string
|
68
|
-
"-d \"#{capture_device}\" " if capture_device
|
69
|
-
end
|
70
|
-
|
71
|
-
def capture_delay_string
|
72
|
-
"-w \"#{capture_delay}\" " if capture_delay.to_i > 0
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
@@ -1,110 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Lolcommits
|
4
|
-
class CaptureWindowsAnimated < Capturer
|
5
|
-
def capture
|
6
|
-
# make a fresh frames directory
|
7
|
-
FileUtils.rm_rf(frames_location)
|
8
|
-
FileUtils.mkdir_p(frames_location)
|
9
|
-
|
10
|
-
# abort capture if we don't have a device name
|
11
|
-
return unless capture_device_string
|
12
|
-
|
13
|
-
# capture raw video with ffmpeg dshow
|
14
|
-
system_call "ffmpeg -v quiet -y -f dshow -i video=\"#{capture_device_string}\" -video_size 320x240 -t #{capture_duration} \"#{video_location}\" > NUL"
|
15
|
-
|
16
|
-
return unless File.exist?(video_location)
|
17
|
-
|
18
|
-
# convert raw video to png frames with ffmpeg
|
19
|
-
system_call "ffmpeg #{capture_delay_string} -v quiet -i \"#{video_location}\" -t #{animated_duration} \"#{frames_location}/%09d.png\" > NUL"
|
20
|
-
|
21
|
-
# use fps to set delay and number of frames to skip (for lower filesized gifs)
|
22
|
-
fps = video_fps(video_location)
|
23
|
-
skip = frame_skip(fps)
|
24
|
-
delay = frame_delay(fps, skip)
|
25
|
-
debug "Capturer: animated gif choosing every #{skip} frames with a frame delay of #{delay} (video fps: #{fps})"
|
26
|
-
|
27
|
-
# create the looping animated gif from frames (delete frame files except every #{skip} frame)
|
28
|
-
Dir["#{frames_location}/*.png"].each do |frame_filename|
|
29
|
-
basename = File.basename(frame_filename)
|
30
|
-
frame_number = basename.split('.').first.to_i
|
31
|
-
File.delete(frame_filename) if frame_number % skip != 0
|
32
|
-
end
|
33
|
-
|
34
|
-
# convert to animated gif with delay and gif optimisation
|
35
|
-
system_call "convert -layers OptimizeTransparency -delay #{delay} -loop 0 \"#{frames_location}/*.png\" -coalesce \"#{snapshot_location}\""
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
def ffpmeg_list_devices_cmd
|
41
|
-
'ffmpeg -list_devices true -f dshow -i dummy 2>&1'
|
42
|
-
end
|
43
|
-
|
44
|
-
# inspired by this code from @rdp http://tinyurl.com/y7t276bh
|
45
|
-
def device_names
|
46
|
-
@device_names ||= begin
|
47
|
-
names = []
|
48
|
-
cmd_output = ''
|
49
|
-
count = 0
|
50
|
-
while cmd_output.empty? || !cmd_output.split('DirectShow')[2]
|
51
|
-
cmd_output = system_call(ffpmeg_list_devices_cmd, true)
|
52
|
-
count += 1
|
53
|
-
raise 'failed to find a video capture device with ffmpeg -list_devices' if count == 5
|
54
|
-
|
55
|
-
sleep 0.1
|
56
|
-
end
|
57
|
-
cmd_output.gsub!("\r\n", "\n")
|
58
|
-
video = cmd_output.split('DirectShow')[1]
|
59
|
-
|
60
|
-
video.lines.map do |line|
|
61
|
-
names << Regexp.last_match(1) if line =~ /"(.+)"\n/
|
62
|
-
end
|
63
|
-
|
64
|
-
debug "Capturer: found #{names.length} video devices: #{names.join(', ')}"
|
65
|
-
names
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def system_call(call_str, capture_output = false)
|
70
|
-
debug "Capturer: making system call for \n #{call_str}"
|
71
|
-
capture_output ? `#{call_str}` : system(call_str)
|
72
|
-
end
|
73
|
-
|
74
|
-
def frame_delay(fps, skip)
|
75
|
-
# calculate frame delay
|
76
|
-
delay = ((100.0 * skip) / fps.to_f).to_i
|
77
|
-
delay < 6 ? 6 : delay # hard limit for IE browsers
|
78
|
-
end
|
79
|
-
|
80
|
-
def video_fps(file)
|
81
|
-
# inspect fps of the captured video file (default to 29.97)
|
82
|
-
fps = system_call("ffmpeg -i \"#{file}\" 2>&1 | sed -n \"s/.*, \\(.*\\) fp.*/\\1/p\"", true)
|
83
|
-
fps.to_i < 1 ? 29.97 : fps.to_f
|
84
|
-
end
|
85
|
-
|
86
|
-
def frame_skip(fps)
|
87
|
-
# of frames to skip depends on movie fps
|
88
|
-
case fps
|
89
|
-
when 0..15
|
90
|
-
2
|
91
|
-
when 16..28
|
92
|
-
3
|
93
|
-
else
|
94
|
-
4
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
def capture_device_string
|
99
|
-
capture_device || device_names.first
|
100
|
-
end
|
101
|
-
|
102
|
-
def capture_delay_string
|
103
|
-
" -ss #{capture_delay}" if capture_delay.to_i > 0
|
104
|
-
end
|
105
|
-
|
106
|
-
def capture_duration
|
107
|
-
animated_duration.to_i + capture_delay.to_i
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|