ezii 0.0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/ezii-client/Gemfile +6 -0
- data/ezii-client/Gemfile.lock +32 -0
- data/ezii-client/Procfile +2 -0
- data/ezii-client/README.md +16 -0
- data/ezii-client/chat.txt +1446 -0
- data/ezii-client/config.ru +1 -0
- data/ezii-client/fake.rb +5 -0
- data/ezii-client/managables/programs/game_aided_manufacturing/functions/base_command.rb +26 -0
- data/ezii-client/managables/programs/game_aided_manufacturing/functions/mouse_y_axis_to_3d_z_axis.rb +4 -0
- data/ezii-client/managables/programs/game_aided_manufacturing/functions/record_audio_and_send_to_wit.rb +18 -0
- data/ezii-client/managables/programs/game_aided_manufacturing/functions/rotate_camera_axis_using_mouse_drag.rb +37 -0
- data/ezii-client/managables/programs/game_aided_manufacturing/functions/selection_cube.rb +35 -0
- data/ezii-client/managables/programs/game_aided_manufacturing/gam.rb +388 -0
- data/ezii-client/managables/programs/game_aided_manufacturing/gems.locked +75 -0
- data/ezii-client/managables/programs/game_aided_manufacturing/gems.rb +10 -0
- data/ezii-client/managables/programs/game_aided_manufacturing/lib/drb_server.rb +13 -0
- data/ezii-client/managables/programs/game_aided_manufacturing/lib/mittsu_monkeypatches/box_geometry.rb +5 -0
- data/ezii-client/managables/programs/game_aided_manufacturing/runnable.rb +20 -0
- data/ezii-client/managables/programs/game_aided_manufacturing/shapes/cube.rb +29 -0
- data/ezii-client/managables/programs/game_aided_manufacturing/sig/runable.rbi +9 -0
- data/ezii-client/managables/programs/game_aided_manufacturing/test.sh +5 -0
- data/ezii-client/managables/programs/game_aided_manufacturing/test/commands/test_move_cube.rb +18 -0
- data/ezii-client/managables/programs/game_aided_manufacturing/test/commands/test_selection_cube.rb +31 -0
- data/ezii-client/managables/programs/game_aided_manufacturing/test/test_command_remapping.rb +30 -0
- data/ezii-client/managables/programs/game_aided_manufacturing/test/test_helper.rb +75 -0
- data/ezii-client/managables/services/chat-bot-integrations/chat.txt +15 -0
- data/ezii-client/managables/services/chat-bot-integrations/gems.locked +66 -0
- data/ezii-client/managables/services/chat-bot-integrations/gems.rb +18 -0
- data/ezii-client/managables/services/chat-bot-integrations/gitter_zircon.rb +644 -0
- data/ezii-client/managables/services/chat-bot-integrations/regexes.rb +240 -0
- data/ezii-client/managables/services/chat-bot-integrations/setup-mac-os-x.sh +0 -0
- data/ezii-client/managables/services/chat-bot-integrations/setup.sh +1 -0
- data/ezii-client/managables/services/chat-bot-integrations/start.sh +3 -0
- data/ezii-client/managables/services/error-inspect/simplest-log +1 -0
- data/ezii-client/managables/services/error-inspect/simplest-log-init +1 -0
- data/ezii-client/managables/services/livestream-interactive/Twitch.Tv/ascii_nebuchadnezzar +9 -0
- data/ezii-client/managables/services/livestream-interactive/Twitch.Tv/chat.txt +1 -0
- data/ezii-client/managables/services/livestream-interactive/Twitch.Tv/twitch_zircon.rb +61 -0
- data/ezii-client/managables/services/livestream-interactive/Twitch.Tv/zion_fleet.rb +198 -0
- data/ezii-client/managables/services/livestream-interactive/chat.txt +40 -0
- data/ezii-client/managables/services/stdlib-dot-com/koma/qanda-api@dev/README.md +3 -0
- data/ezii-client/managables/services/stdlib-dot-com/koma/qanda-api@dev/functions/__main__.js +58 -0
- data/ezii-client/managables/services/stdlib-dot-com/koma/qanda-api@dev/functions/black-out-random-word.js +74 -0
- data/ezii-client/managables/services/stdlib-dot-com/koma/qanda-api@dev/functions/random-sentence.js +57 -0
- data/ezii-client/managables/services/stdlib-dot-com/koma/qanda-api@dev/functions/random-wikipedia-page.js +25 -0
- data/ezii-client/managables/services/stdlib-dot-com/koma/qanda-api@dev/functions/random-words.js +34 -0
- data/ezii-client/managables/services/stdlib-dot-com/koma/qanda-api@dev/functions/rare-enough-word.js +41 -0
- data/ezii-client/managables/services/stdlib-dot-com/koma/qanda-api@dev/functions/wikipedia-page.js +35 -0
- data/ezii-client/managables/services/stdlib-dot-com/koma/qanda-api@dev/package.json +20 -0
- data/ezii-client/managables/services/stdlib-dot-com/koma/qanda-api@dev/statistics/count-word.js +12 -0
- data/ezii-client/managables/services/stdlib-dot-com/koma/qanda-api@dev/utils/log-to-natural-database.js +10 -0
- data/ezii-client/managables/services/stdlib-dot-com/koma/qanda-api@dev/word2vec-models/test-text8-vector.bin +0 -0
- data/ezii-client/managament_interface/gems.locked +13 -0
- data/ezii-client/managament_interface/gems.rb +3 -0
- data/ezii-client/managament_interface/management_interface +4 -0
- data/ezii-client/managament_interface/runnable.rb +30 -0
- data/ezii-client/rocknrolla +1 -0
- data/ezii-client/start.sh +2 -0
- data/ezii-client/test.wav +0 -0
- data/ezii-misc/detect-intent-from-git-patch.rb +46 -0
- data/ezii-server/Gemfile +23 -0
- data/ezii-server/Gemfile.lock +84 -0
- data/ezii-server/README.md +13 -0
- data/ezii-server/config.ru +2 -0
- data/ezii-server/eezee.rb +1243 -0
- data/ezii-server/httpsprojecteulernetproblem=155.png +0 -0
- data/ezii-server/httpsprojecteulernetproblem=205.png +0 -0
- data/ezii-server/httpsprojecteulernetproblem=228.png +0 -0
- data/ezii-server/httpsprojecteulernetproblem=262.png +0 -0
- data/ezii-server/httpsprojecteulernetproblem=3.png +0 -0
- data/ezii-server/httpsprojecteulernetproblem=333.png +0 -0
- data/ezii-server/httpsprojecteulernetproblem=334.png +0 -0
- data/ezii-server/httpsprojecteulernetproblem=337.png +0 -0
- data/ezii-server/httpsprojecteulernetproblem=426.png +0 -0
- data/ezii-server/httpsprojecteulernetproblem=442.png +0 -0
- data/ezii-server/httpsprojecteulernetproblem=449.png +0 -0
- data/ezii-server/httpsprojecteulernetproblem=497.png +0 -0
- data/ezii-server/httpsprojecteulernetproblem=51.png +0 -0
- data/ezii-server/httpsprojecteulernetproblem=514.png +0 -0
- data/ezii-server/httpsprojecteulernetproblem=520.png +0 -0
- data/ezii-server/httpsprojecteulernetproblem=571.png +0 -0
- data/ezii-server/httpsprojecteulernetproblem=587.png +0 -0
- data/ezii-server/httpsprojecteulernetproblem=588.png +0 -0
- data/ezii-server/httpsprojecteulernetproblem=599.png +0 -0
- data/ezii-server/httpsprojecteulernetproblem=72.png +0 -0
- data/ezii-server/httpsprojecteulernetproblem=93.png +0 -0
- data/ezii-server/regexes +258 -0
- data/ezii-server/sample.wav +0 -0
- data/ezii.gemspec +13 -0
- metadata +132 -0
@@ -0,0 +1,75 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
activesupport (5.2.3)
|
5
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
6
|
+
i18n (>= 0.7, < 2)
|
7
|
+
minitest (~> 5.1)
|
8
|
+
tzinfo (~> 1.1)
|
9
|
+
ast (2.4.0)
|
10
|
+
ast_utils (0.3.0)
|
11
|
+
parser (~> 2.4)
|
12
|
+
thor (>= 0.19)
|
13
|
+
byebug (11.0.1)
|
14
|
+
chunky_png (1.3.11)
|
15
|
+
coderay (1.1.2)
|
16
|
+
concurrent-ruby (1.1.5)
|
17
|
+
ffi (1.11.1)
|
18
|
+
i18n (1.6.0)
|
19
|
+
concurrent-ruby (~> 1.0)
|
20
|
+
language_server-protocol (3.14.0.1)
|
21
|
+
listen (3.1.5)
|
22
|
+
rb-fsevent (~> 0.9, >= 0.9.4)
|
23
|
+
rb-inotify (~> 0.9, >= 0.9.7)
|
24
|
+
ruby_dep (~> 1.2)
|
25
|
+
method_source (0.9.2)
|
26
|
+
minitest (5.11.3)
|
27
|
+
mittsu (0.3.0)
|
28
|
+
chunky_png (~> 1.3)
|
29
|
+
ffi (~> 1.9)
|
30
|
+
opengl-bindings (~> 1.5)
|
31
|
+
opengl-bindings (1.6.9)
|
32
|
+
os (1.0.1)
|
33
|
+
parser (2.6.3.0)
|
34
|
+
ast (~> 2.4.0)
|
35
|
+
pry (0.12.2)
|
36
|
+
coderay (~> 1.1.0)
|
37
|
+
method_source (~> 0.9.0)
|
38
|
+
pry-remote (0.1.8)
|
39
|
+
pry (~> 0.9)
|
40
|
+
slop (~> 3.0)
|
41
|
+
rainbow (2.2.2)
|
42
|
+
rake
|
43
|
+
rake (12.3.2)
|
44
|
+
rb-fsevent (0.10.3)
|
45
|
+
rb-inotify (0.10.0)
|
46
|
+
ffi (~> 1.0)
|
47
|
+
ruby_dep (1.5.0)
|
48
|
+
slop (3.6.0)
|
49
|
+
steep (0.11.0)
|
50
|
+
activesupport (~> 5.1)
|
51
|
+
ast_utils (~> 0.3.0)
|
52
|
+
language_server-protocol (~> 3.14.0)
|
53
|
+
listen (~> 3.1)
|
54
|
+
parser (~> 2.4)
|
55
|
+
pry (~> 0.12.2)
|
56
|
+
rainbow (~> 2.2.2, < 4.0)
|
57
|
+
thor (0.20.3)
|
58
|
+
thread_safe (0.3.6)
|
59
|
+
tzinfo (1.2.5)
|
60
|
+
thread_safe (~> 0.1)
|
61
|
+
wit (6.0.0)
|
62
|
+
|
63
|
+
PLATFORMS
|
64
|
+
ruby
|
65
|
+
|
66
|
+
DEPENDENCIES
|
67
|
+
byebug
|
68
|
+
mittsu
|
69
|
+
os
|
70
|
+
pry-remote
|
71
|
+
steep
|
72
|
+
wit
|
73
|
+
|
74
|
+
BUNDLED WITH
|
75
|
+
2.0.2
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative 'gam'
|
2
|
+
require_relative 'lib/drb_server.rb'
|
3
|
+
|
4
|
+
|
5
|
+
gam = Gam.new
|
6
|
+
|
7
|
+
|
8
|
+
WIT = Wit.new(access_token: ENV['WIT_AI_TOKEN_SERVER'])
|
9
|
+
|
10
|
+
|
11
|
+
Thread.new do
|
12
|
+
if WIT.get_entity('intent').grep(/.*move.*cube.*/)
|
13
|
+
gam.move_cube(:any, [rand(), rand(), rand()])
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
DrbServer.new(gam).start
|
19
|
+
|
20
|
+
gam.start
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative '../lib/mittsu_monkeypatches/box_geometry.rb'
|
2
|
+
|
3
|
+
class Cube
|
4
|
+
attr_accessor :color, :mittsu_object, :size_vector
|
5
|
+
|
6
|
+
def initialize(color: 0x0000ff, size_vector: Mittsu::Vector3.new(1.0, 1.0, 1.0))
|
7
|
+
# value assignment (phase 1)
|
8
|
+
|
9
|
+
self.color = color
|
10
|
+
self.size_vector = size_vector
|
11
|
+
|
12
|
+
# computing based on values (phase 2)
|
13
|
+
self.create_mittsu_object
|
14
|
+
|
15
|
+
# event distribution (phase 3)
|
16
|
+
::Gam::CUBES.push(self)
|
17
|
+
end
|
18
|
+
|
19
|
+
def create_mittsu_object
|
20
|
+
@mittsu_object = Mittsu::Mesh.new(
|
21
|
+
Mittsu::BoxGeometry.new(self.size_vector.x, self.size_vector.y, self.size_vector.z),
|
22
|
+
Mittsu::MeshBasicMaterial.new(color: self.color)
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
def method_missing(method_name, *args, &block)
|
27
|
+
@mittsu_object.public_send(method_name, *args, &block)
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative '../test_helper.rb'
|
2
|
+
require 'byebug'
|
3
|
+
|
4
|
+
module SystemTests
|
5
|
+
class TestSelectionCube < AbstractSystemTest
|
6
|
+
def test_move_any_cube_somehow
|
7
|
+
open_gam_window do |console_stdin, console_stdout|
|
8
|
+
cubes_before = drb_interface.cubes
|
9
|
+
|
10
|
+
assert_equal cubes_after, cubes_before
|
11
|
+
drb_interface.move_cube(:any, *[rand(), rand(), rand()])
|
12
|
+
cubes_after = drb_interface.cubes
|
13
|
+
|
14
|
+
refute_equal cubes_after, cubes_before
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/ezii-client/managables/programs/game_aided_manufacturing/test/commands/test_selection_cube.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require_relative '../test_helper.rb'
|
2
|
+
require 'byebug'
|
3
|
+
|
4
|
+
module SystemTests
|
5
|
+
class TestSelectionCube < AbstractSystemTest
|
6
|
+
def test_gets_mouse_down_position
|
7
|
+
open_gam_window do |console_stdin, console_stdout|
|
8
|
+
drb_interface.execute_command(drb_interface.functions[1])
|
9
|
+
drag_mouse_from_to_in_gam_window([100, 100], [150, 150])
|
10
|
+
scroll_out_in_gam_window(-10)
|
11
|
+
sleep 1
|
12
|
+
drb_interface.execute_command(drb_interface.functions[1])
|
13
|
+
drag_mouse_from_to_in_gam_window([100, 100], [150, 150])
|
14
|
+
sleep 0.5
|
15
|
+
@output = get_2_last_created_cubes_volume(drb_interface)
|
16
|
+
end
|
17
|
+
|
18
|
+
assert @output.first < @output.last, "Firstly created cube is smaller"
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_2_last_created_cubes_volume(drb_interface)
|
22
|
+
firstly_created_cube = drb_interface.cubes[0]
|
23
|
+
secondly_created_cube = drb_interface.cubes[1]
|
24
|
+
|
25
|
+
firstly_created_cube_volume = firstly_created_cube.geometry.volume
|
26
|
+
secondly_created_cube_volume = secondly_created_cube.geometry.volume
|
27
|
+
|
28
|
+
return [firstly_created_cube_volume, secondly_created_cube_volume]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require_relative 'test_helper.rb'
|
2
|
+
require 'byebug'
|
3
|
+
|
4
|
+
module SystemTests
|
5
|
+
class TestCommandRemapping < AbstractSystemTest
|
6
|
+
def test_command_remapping
|
7
|
+
open_gam_window do |console_stdin, console_stdout|
|
8
|
+
send_keypress_to_gam_window("y")
|
9
|
+
|
10
|
+
puts console_stdout.gets
|
11
|
+
puts console_stdout.gets
|
12
|
+
puts console_stdout.gets
|
13
|
+
|
14
|
+
console_stdin.puts("1")
|
15
|
+
|
16
|
+
puts console_stdout.gets
|
17
|
+
|
18
|
+
console_stdin.puts("z")
|
19
|
+
|
20
|
+
send_keypress_to_gam_window("z")
|
21
|
+
|
22
|
+
sleep 1
|
23
|
+
|
24
|
+
@output = drb_interface.played_commands.last.class.name
|
25
|
+
end
|
26
|
+
|
27
|
+
assert_match "SelectionCube", @output
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require "minitest/autorun"
|
2
|
+
require_relative '../gam'
|
3
|
+
require_relative '../functions/selection_cube'
|
4
|
+
require 'os'
|
5
|
+
require 'open3'
|
6
|
+
require 'drb/drb'
|
7
|
+
|
8
|
+
|
9
|
+
DRb.start_service
|
10
|
+
|
11
|
+
module SystemTests
|
12
|
+
class AbstractSystemTest < Minitest::Test
|
13
|
+
SERVER_URI="druby://localhost:65000"
|
14
|
+
|
15
|
+
def drb_interface
|
16
|
+
@drb_interface ||= DRbObject.new_with_uri(SERVER_URI)
|
17
|
+
end
|
18
|
+
|
19
|
+
def send_keypress_to_gam_window(key)
|
20
|
+
apple_script("keystroke \"#{key}\"")
|
21
|
+
end
|
22
|
+
|
23
|
+
def drag_mouse_from_to_in_gam_window(from, to)
|
24
|
+
apple_script("set position of window 1 to {0, 0}")
|
25
|
+
|
26
|
+
cliclick_drag_start(*from)
|
27
|
+
cliclick_drag_end(*to)
|
28
|
+
end
|
29
|
+
|
30
|
+
def scroll_out_in_gam_window(factor)
|
31
|
+
`cliclick sp:#{factor},0,0`
|
32
|
+
end
|
33
|
+
|
34
|
+
def cliclick_drag_start(x,y)
|
35
|
+
`cliclick dd:#{x},#{y}`
|
36
|
+
end
|
37
|
+
|
38
|
+
def cliclick_drag_end(x,y)
|
39
|
+
`cliclick du:#{x},#{y}`
|
40
|
+
end
|
41
|
+
|
42
|
+
def apple_script(script)
|
43
|
+
if OS.mac?
|
44
|
+
`osascript -e 'tell application "System Events" to tell (every process whose unix id is #{@gam_pid})
|
45
|
+
set frontmost to true
|
46
|
+
|
47
|
+
#{script}
|
48
|
+
end tell'`
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def open_gam_window(&block)
|
53
|
+
outer_self = self
|
54
|
+
Open3.popen3("ruby runnable.rb") do |stdin, stdout, stderr, thread|
|
55
|
+
Thread.new {
|
56
|
+
open('/var/log/gam.stderr', 'a') { |f|
|
57
|
+
begin
|
58
|
+
while line = stderr.gets
|
59
|
+
f << line
|
60
|
+
end
|
61
|
+
rescue IOError
|
62
|
+
end
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
@gam_pid = thread.pid
|
67
|
+
sleep 2
|
68
|
+
|
69
|
+
outer_self.instance_exec(stdin, stdout, &block)
|
70
|
+
|
71
|
+
Process.kill('KILL', @gam_pid)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
|
2
|
+
Gitter
|
3
|
+
Version:
|
4
|
+
Created
|
5
|
+
irc.gitter.im
|
6
|
+
CHANTYPES=#
|
7
|
+
- Message of the Day -
|
8
|
+
- Welcome To Gitter IRC!
|
9
|
+
- Info at https://irc.gitter.im
|
10
|
+
- Code at https://gitlab.com/gitlab-org/gitter/irc-bridge
|
11
|
+
End of /MOTD command.
|
12
|
+
|
13
|
+
#qanda-api/Lobby
|
14
|
+
*
|
15
|
+
#qanda-api/Lobby
|
@@ -0,0 +1,66 @@
|
|
1
|
+
GIT
|
2
|
+
remote: https://github.com/icetiger-tec/zircon.git
|
3
|
+
revision: b40496d72d8fa8590375a85c5684deb45c3fcd70
|
4
|
+
specs:
|
5
|
+
zircon (0.0.8)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
addressable (2.6.0)
|
11
|
+
public_suffix (>= 2.0.2, < 4.0)
|
12
|
+
brainz (0.2.0)
|
13
|
+
bugsnag (6.11.1)
|
14
|
+
concurrent-ruby (~> 1.0)
|
15
|
+
bugsnag-api (2.0.2)
|
16
|
+
sawyer (~> 0.8.1)
|
17
|
+
byebug (11.0.1)
|
18
|
+
colorize (0.8.1)
|
19
|
+
concurrent-ruby (1.1.5)
|
20
|
+
faraday (0.15.4)
|
21
|
+
multipart-post (>= 1.2, < 3)
|
22
|
+
gyazo (3.0.1)
|
23
|
+
faraday
|
24
|
+
mime-types
|
25
|
+
multipart-post
|
26
|
+
mime-types (3.2.2)
|
27
|
+
mime-types-data (~> 3.2015)
|
28
|
+
mime-types-data (3.2019.0331)
|
29
|
+
mini_portile2 (2.4.0)
|
30
|
+
multipart-post (2.1.1)
|
31
|
+
mustermann (1.0.3)
|
32
|
+
nokogiri (1.10.3)
|
33
|
+
mini_portile2 (~> 2.4.0)
|
34
|
+
open4 (1.3.4)
|
35
|
+
public_suffix (3.1.1)
|
36
|
+
rack (2.0.7)
|
37
|
+
rack-protection (2.0.5)
|
38
|
+
rack
|
39
|
+
sawyer (0.8.2)
|
40
|
+
addressable (>= 2.3.5)
|
41
|
+
faraday (> 0.8, < 2.0)
|
42
|
+
sinatra (2.0.5)
|
43
|
+
mustermann (~> 1.0)
|
44
|
+
rack (~> 2.0)
|
45
|
+
rack-protection (= 2.0.5)
|
46
|
+
tilt (~> 2.0)
|
47
|
+
tilt (2.0.9)
|
48
|
+
|
49
|
+
PLATFORMS
|
50
|
+
ruby
|
51
|
+
|
52
|
+
DEPENDENCIES
|
53
|
+
brainz
|
54
|
+
bugsnag
|
55
|
+
bugsnag-api
|
56
|
+
bundler
|
57
|
+
byebug
|
58
|
+
colorize
|
59
|
+
gyazo
|
60
|
+
nokogiri
|
61
|
+
open4
|
62
|
+
sinatra
|
63
|
+
zircon!
|
64
|
+
|
65
|
+
BUNDLED WITH
|
66
|
+
2.1.0.pre.1
|
@@ -0,0 +1,18 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
gem 'zircon', github: 'icetiger-tec/zircon'
|
4
|
+
gem 'colorize'
|
5
|
+
gem 'byebug'
|
6
|
+
gem 'gyazo'
|
7
|
+
gem 'open4'
|
8
|
+
|
9
|
+
gem 'brainz'
|
10
|
+
gem 'bundler'
|
11
|
+
|
12
|
+
gem 'sinatra'
|
13
|
+
|
14
|
+
gem 'nokogiri'
|
15
|
+
|
16
|
+
gem 'bugsnag'
|
17
|
+
|
18
|
+
gem 'bugsnag-api'
|
@@ -0,0 +1,644 @@
|
|
1
|
+
# LemonAndroidToday at 6:56 PM
|
2
|
+
# grep last message RBENV
|
3
|
+
# pass ball to @notify.me
|
4
|
+
# eezee probe twitter.com/lemonandroid 5
|
5
|
+
# eezee probe "bundle exec rails new"
|
6
|
+
# reset-eezee-probe
|
7
|
+
# eezee probe "bundle exec rails new"
|
8
|
+
# eezee probe "cd last-project"
|
9
|
+
# eezee probe "bundle exec rails scaffold melts name:string type:string"
|
10
|
+
# eezee probe "upload current-project"
|
11
|
+
# bring to melting point eezee probe
|
12
|
+
# melt by using wit.ai into "melt-rails-app" liquid
|
13
|
+
# melting-point-show-liquids
|
14
|
+
# cast "melt-rails-app-batch-0" from "melt-rails-app" lliquid
|
15
|
+
# show melt-rails-app-batch-0 :3000
|
16
|
+
# launch rocket "ask common stackoverflow questions" carry melt-rails-app-batch-0 > controllers folder
|
17
|
+
# what do you think @stefan reich?
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
require 'zircon'
|
22
|
+
require 'colorize'
|
23
|
+
require 'byebug'
|
24
|
+
require 'json'
|
25
|
+
require 'date'
|
26
|
+
require 'timeout'
|
27
|
+
require 'gyazo'
|
28
|
+
require 'open4'
|
29
|
+
require 'brainz'
|
30
|
+
require 'bundler'
|
31
|
+
require 'sinatra'
|
32
|
+
require 'nokogiri'
|
33
|
+
require 'sinatra'
|
34
|
+
require 'bugsnag'
|
35
|
+
require 'bugsnag/api'
|
36
|
+
|
37
|
+
Bugsnag.configure do |config|
|
38
|
+
config.api_key = "3bda845ddbc9ddabefbdabb3a8cda431"
|
39
|
+
end
|
40
|
+
|
41
|
+
set :raise_errors, true
|
42
|
+
|
43
|
+
use Bugsnag::Rack
|
44
|
+
|
45
|
+
# class Object
|
46
|
+
# def ===(method, *args, &block)
|
47
|
+
# TODO: also alllow Module === object => true if Module::Class === object => true
|
48
|
+
# end
|
49
|
+
# end
|
50
|
+
|
51
|
+
def optional_prefix(prefix, message)
|
52
|
+
[prefix + message, message]
|
53
|
+
end
|
54
|
+
|
55
|
+
EEZEE_PREFIX = "eezee" + " "
|
56
|
+
|
57
|
+
ALLOWED_MESSAGES_LIST = [
|
58
|
+
"show `say i am so easy you can do whatever you like with me`",
|
59
|
+
"hey",
|
60
|
+
"show `whoami`",
|
61
|
+
"show `ifconfig`",
|
62
|
+
"chat-variable bot0 `NeuralNetwork()`",
|
63
|
+
"get-chat-variable bot0",
|
64
|
+
"What do you think?",
|
65
|
+
"get-method-definition bot0.num_hidden",
|
66
|
+
"chat-variable bot0brainz selectDiscordMessage",
|
67
|
+
"throw bomb",
|
68
|
+
"pass ball to @user",
|
69
|
+
"who has ball",
|
70
|
+
"space",
|
71
|
+
"launch rocket google.com?q=]var[",
|
72
|
+
"launch rocket http://www.gigablast.com/search?c=main&format=json&q=]var[",
|
73
|
+
"launch rocket http://agi.blue/]var[",
|
74
|
+
"show activity stream",
|
75
|
+
"bring to melting point https://css-tricks.com/wp-content/uploads/2018/10/align-items.svg",
|
76
|
+
"melt",
|
77
|
+
"get-melting-point",
|
78
|
+
"bring to melting point last used picture",
|
79
|
+
"probe https://www.twitch.tv/jamiepinelive 10s",
|
80
|
+
"probe https://www.twitch.tv/sudokid 5s",
|
81
|
+
"probe https://www.twitch.tv/dowright 5s",
|
82
|
+
"probe https://github.com/facebook/relay/commit/377ca939b5f5b46d57e11d4a1dfa7c4aecf5666b 50bytes",
|
83
|
+
"probe https://github.com/facebook/relay/commit/377ca939b5f5b46d57e11d4a1dfa7c4aecf5666b 150bytes",
|
84
|
+
"bring probes to melting point",
|
85
|
+
"throw bugsnag bomb"
|
86
|
+
].map do |message|
|
87
|
+
optional_prefix(EEZEE_PREFIX, message)
|
88
|
+
end.flatten
|
89
|
+
|
90
|
+
# DISALLOWED_MESSAGES_LIST = [
|
91
|
+
# `rm -rf /tmp`,
|
92
|
+
# 'rm -rf /',
|
93
|
+
# 'rm',
|
94
|
+
# 'show `rm -fr /`',
|
95
|
+
# 'show eval `exec("rm -fr")`'
|
96
|
+
# ]
|
97
|
+
|
98
|
+
class Method
|
99
|
+
def source(limit=10)
|
100
|
+
file, line = source_location
|
101
|
+
if file && line
|
102
|
+
IO.readlines(file)[line-1,limit]
|
103
|
+
else
|
104
|
+
nil
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
class NeuralNetwork
|
110
|
+
# TODO: DelegateAllMissingMethodsTo @brainz
|
111
|
+
|
112
|
+
def method_missing(method, *args, &block)
|
113
|
+
@brainz.public_send(method, *args, &block)
|
114
|
+
end
|
115
|
+
|
116
|
+
def initialize
|
117
|
+
@brainz = Brainz::Brainz.new
|
118
|
+
end
|
119
|
+
|
120
|
+
def verbose_introspect(very_verbose = false)
|
121
|
+
var = <<~HUMAN_SCRIPT_INTROSPECT_FOR_DISCORD
|
122
|
+
```
|
123
|
+
Brainz Rubygem (wrapper)
|
124
|
+
Ruby object id: #{@brainz.object_id}
|
125
|
+
```
|
126
|
+
|
127
|
+
```
|
128
|
+
Instance variables
|
129
|
+
```
|
130
|
+
|
131
|
+
```
|
132
|
+
#{@brainz.instance_variables}
|
133
|
+
```
|
134
|
+
HUMAN_SCRIPT_INTROSPECT_FOR_DISCORD
|
135
|
+
|
136
|
+
if very_verbose
|
137
|
+
var = <<~HUMAN_SCRIPT_INTROSPECT_FOR_DISCORD
|
138
|
+
```
|
139
|
+
Public methods (random sample of 3)
|
140
|
+
```
|
141
|
+
|
142
|
+
```
|
143
|
+
#{(@brainz.public_methods - Object.new.public_methods).sample(3).join("\n")}
|
144
|
+
```
|
145
|
+
HUMAN_SCRIPT_INTROSPECT_FOR_DISCORD
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
unless @brainz.network.nil?
|
150
|
+
# var += <<~HUMAN_SCRIPT_INTROSPECT_FOR_DISCORD
|
151
|
+
# ```
|
152
|
+
# #{@brainz.network.input.to_s}
|
153
|
+
# #{@brainz.network.hidden.to_s}
|
154
|
+
# #{@brainz.network.output.to_s}
|
155
|
+
# ```
|
156
|
+
# HUMAN_SCRIPT_INTROSPECT_FOR_DISCORD
|
157
|
+
end
|
158
|
+
|
159
|
+
return var
|
160
|
+
end
|
161
|
+
|
162
|
+
def to_s
|
163
|
+
verbose_introspect
|
164
|
+
end
|
165
|
+
|
166
|
+
def num_hidden
|
167
|
+
puts 'wau'
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
def NeuralNetwork()
|
173
|
+
NeuralNetwork.new
|
174
|
+
end
|
175
|
+
|
176
|
+
class GitterDumbDevBot
|
177
|
+
def initialize
|
178
|
+
@currently_selected_project = "lemonandroid/gam"
|
179
|
+
@variables_for_chat_users = Hash.new
|
180
|
+
@players = Hash.new do |dictionary, identifier|
|
181
|
+
dictionary[identifier] = Hash.new
|
182
|
+
end
|
183
|
+
@melting_point_receivables = []
|
184
|
+
@probes = []
|
185
|
+
end
|
186
|
+
|
187
|
+
def load()
|
188
|
+
fail [:info, :no_marshaled_data_found].join(' > ') unless File.exists?("/var/gam-discord-bot.ruby-marshal")
|
189
|
+
data = File.read("/var/gam-discord-bot.ruby-marshal")
|
190
|
+
@variables_for_chat_users = Marshal.load(data)
|
191
|
+
end
|
192
|
+
|
193
|
+
def dump()
|
194
|
+
data = Marshal.dump(@variables_for_chat_users)
|
195
|
+
File.write("/var/gam-discord-bot.ruby-marshal", data)
|
196
|
+
end
|
197
|
+
|
198
|
+
def twitch_username_from_url(url)
|
199
|
+
url.match(/\/(\w*)\Z/)[1]
|
200
|
+
end
|
201
|
+
|
202
|
+
def record_live_stream_video_and_upload_get_url(url:, duration_seonds:)
|
203
|
+
twitch_username = twitch_username_from_url(url)
|
204
|
+
twitch_broadcaster_id = JSON.parse(`curl -H 'Authorization: Bearer #{ENV['EZE_TWITCH_TOKEN']}' \
|
205
|
+
-X GET 'https://api.twitch.tv/helix/users?login=#{twitch_username}'`)["data"][0]["id"]
|
206
|
+
created_clip_json_response = `curl -H 'Authorization: Bearer #{ENV['EZE_TWITCH_TOKEN']}' \
|
207
|
+
-X POST 'https://api.twitch.tv/helix/clips?broadcaster_id=#{twitch_broadcaster_id}'`
|
208
|
+
|
209
|
+
created_clip_json_response = JSON.parse(created_clip_json_response)
|
210
|
+
|
211
|
+
id = created_clip_json_response["data"][0]["id"]
|
212
|
+
return "https://clips.twitch.tv/#{id}"
|
213
|
+
|
214
|
+
# return `curl -H 'Authorization: Bearer #{ENV['EZE_TWITCH_TOKEN']}' \
|
215
|
+
# -X GET '#{url}'`
|
216
|
+
end
|
217
|
+
|
218
|
+
def get_string_of_x_bytes_by_curling_url(url:, byte_count:)
|
219
|
+
str = `curl #{url}`
|
220
|
+
sub_zero_string = str.each_char.reduce("") do |acc, chr| # haha, sub sero string
|
221
|
+
unless acc.bytesize === byte_count
|
222
|
+
acc += chr
|
223
|
+
else
|
224
|
+
break acc
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
"`#{sub_zero_string.unpack('c*')}`"
|
229
|
+
end
|
230
|
+
|
231
|
+
def on_message(message)
|
232
|
+
message.gsub!(EEZEE_PREFIX, '')
|
233
|
+
|
234
|
+
# return "Message #{message} not included in ALLOWED_MESSAGES_LIST (which is my name for a whitelist)" unless ALLOWED_MESSAGES_LIST.include?(message)
|
235
|
+
return "" unless ALLOWED_MESSAGES_LIST.include?(message)
|
236
|
+
warn "Message #{message} not included in ALLOWED_MESSAGES_LIST (which is my name for a whitelist)" unless ALLOWED_MESSAGES_LIST.include?(message)
|
237
|
+
|
238
|
+
return if Zircon::Message === message
|
239
|
+
|
240
|
+
removed_colors = [:black, :white, :light_black, :light_white]
|
241
|
+
colors = String.colors - removed_colors
|
242
|
+
|
243
|
+
if message =~ /bring probes to melting point/
|
244
|
+
@melting_point_receivables.push(@probes)
|
245
|
+
@probes = []
|
246
|
+
return "all of them? melt all the precious probes you idiot?"
|
247
|
+
end
|
248
|
+
|
249
|
+
if message =~ /probe (.*) (.*)/
|
250
|
+
action = :log
|
251
|
+
|
252
|
+
resource = $1
|
253
|
+
probe_identifier = $2
|
254
|
+
|
255
|
+
if probe_identifier =~ /(\d+)s/
|
256
|
+
duration_seconds = $1.to_i
|
257
|
+
end
|
258
|
+
|
259
|
+
if probe_identifier =~ /(\d+)bytes/
|
260
|
+
byte_count = $1.to_i
|
261
|
+
end
|
262
|
+
|
263
|
+
case resource
|
264
|
+
when /twitch.tv/
|
265
|
+
twitch_url = resource
|
266
|
+
action = :twitch
|
267
|
+
when /http/
|
268
|
+
action = :plain_curl
|
269
|
+
url = resource
|
270
|
+
end
|
271
|
+
|
272
|
+
case action
|
273
|
+
when :twitch
|
274
|
+
probe = record_live_stream_video_and_upload_get_url(url: twitch_url, duration_seonds: duration_seconds)
|
275
|
+
@probes.push(probe)
|
276
|
+
return probe
|
277
|
+
when :plain_curl
|
278
|
+
probe = get_string_of_x_bytes_by_curling_url(url: url, byte_count: byte_count)
|
279
|
+
@probes.push(probe)
|
280
|
+
return probe
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
if message =~ /show activity stream/
|
285
|
+
return "https://sideways-snowman.glitch.me/"
|
286
|
+
end
|
287
|
+
|
288
|
+
if message =~ /hey\Z/i
|
289
|
+
return "hey"
|
290
|
+
end
|
291
|
+
|
292
|
+
if message =~ /\Athrow (?:(.*)\s)?bomb\Z/i
|
293
|
+
if $1 == "bugsnag"
|
294
|
+
Bugsnag::Api.configure do |config|
|
295
|
+
config.auth_token = ENV["BUGSNAG_TOKEN"]
|
296
|
+
end
|
297
|
+
organizations = Bugsnag::Api.organizations
|
298
|
+
|
299
|
+
organization = organizations.first
|
300
|
+
|
301
|
+
projects = Bugsnag::Api.projects(organization[:id])
|
302
|
+
|
303
|
+
|
304
|
+
errors = Bugsnag::Api.errors(projects[0][:id], nil)
|
305
|
+
|
306
|
+
return errors.inspect[0...500]
|
307
|
+
end
|
308
|
+
|
309
|
+
return """
|
310
|
+
```
|
311
|
+
Local variables (5 first)
|
312
|
+
#{local_variables.sample(5)}
|
313
|
+
|
314
|
+
Instance variables (5 first)
|
315
|
+
#{instance_variables.sample(5)}
|
316
|
+
|
317
|
+
Public methods (5 first)
|
318
|
+
#{public_methods.sample(5)}
|
319
|
+
|
320
|
+
ENV (120 first chars)
|
321
|
+
#{ENV.inspect[0...120]}
|
322
|
+
|
323
|
+
\`ifconfig\` (120 first chars)
|
324
|
+
#{`ifconfig`[0...120]}
|
325
|
+
```
|
326
|
+
"""
|
327
|
+
end
|
328
|
+
|
329
|
+
if message =~ /\Abring to melting point #{melting_point_receiavable_regex}\Z/i
|
330
|
+
if($1 === "last used picture")
|
331
|
+
Nokogiri::HTML(`curl -L http://gazelle.botcompany.de/lastInput`)
|
332
|
+
|
333
|
+
url = doc.css('a').first.url
|
334
|
+
|
335
|
+
@melting_point_receivables.push(url)
|
336
|
+
end
|
337
|
+
@melting_point_receivables.push($1)
|
338
|
+
end
|
339
|
+
|
340
|
+
if message =~ /\Amelt\Z/
|
341
|
+
# First step, assigning a variable
|
342
|
+
@melting_point = @melting_point_receivables.sample
|
343
|
+
|
344
|
+
def liqudify(raw_data_object)
|
345
|
+
# https://stackoverflow.com/a/24076936/4132642
|
346
|
+
i_ptr_int = raw_data_object.object_id << 1
|
347
|
+
# https://stackoverflow.com/questions/47757960/how-to-get-value-at-a-memory-address-in-linux-shell
|
348
|
+
|
349
|
+
end
|
350
|
+
liqudify(@melting_point)
|
351
|
+
|
352
|
+
# Next step, doing something intelligent with the data
|
353
|
+
# loosening it up somehow
|
354
|
+
# LIQUIDIFYING IT
|
355
|
+
# CONVERTING IT ALL TO BYTES
|
356
|
+
# PRESERVING VOLUME, just changing it's "Aggregatzustand"
|
357
|
+
end
|
358
|
+
|
359
|
+
if message =~ /\Aget-melting-point\Z/
|
360
|
+
return @melting_point
|
361
|
+
end
|
362
|
+
|
363
|
+
if message =~ /launch rocket (.*)\]var\[(.*)/
|
364
|
+
url = $1 + @melting_point + $2
|
365
|
+
curl_response = `curl -L #{url}`[0...100]
|
366
|
+
|
367
|
+
return """
|
368
|
+
CURL
|
369
|
+
#{curl_response}
|
370
|
+
|
371
|
+
URL
|
372
|
+
#{url}
|
373
|
+
"""
|
374
|
+
end
|
375
|
+
|
376
|
+
if message =~ /\Awhat do you think?\Z/i
|
377
|
+
return "I think you're a stupid piece of shit and your dick smells worse than woz before he invented the home computer."
|
378
|
+
end
|
379
|
+
|
380
|
+
if message =~ /\Apass ball to @(\w+)\Z/i
|
381
|
+
@players[$1][:hasBall] = :yes
|
382
|
+
end
|
383
|
+
|
384
|
+
if message =~ /\Awho has ball\Z/i
|
385
|
+
return @players.find { |k, v| v[:hasBall] == :yes }[0]
|
386
|
+
end
|
387
|
+
|
388
|
+
if message =~ /\Aspace\Z/
|
389
|
+
exec_bash_visually_and_post_process_strings(
|
390
|
+
'/Users/lemonandroid/gam-git-repos/LemonAndroid/gam/managables/programs/game_aided_manufacturing/test.sh'
|
391
|
+
)
|
392
|
+
end
|
393
|
+
|
394
|
+
if message =~ /\Achat-variable (\w*) (.*)\Z/i
|
395
|
+
variable_value_used_by_chat_user = $2
|
396
|
+
return "Coming soon" if variable_value_used_by_chat_user == "selectDiscordMessage"
|
397
|
+
variable_identifier_used_by_chat_user = $1
|
398
|
+
|
399
|
+
if(variable_value_used_by_chat_user =~ /`(.*)`/)
|
400
|
+
variable_value_used_by_chat_user = eval($1)
|
401
|
+
end
|
402
|
+
|
403
|
+
@variables_for_chat_users[variable_identifier_used_by_chat_user] = variable_value_used_by_chat_user
|
404
|
+
|
405
|
+
return space_2_unicode("variable #{variable_identifier_used_by_chat_user} set to #{@variables_for_chat_users[variable_identifier_used_by_chat_user]}")
|
406
|
+
end
|
407
|
+
|
408
|
+
if message =~ /\Aget-chat-variable (\w*)\Z/i
|
409
|
+
return [
|
410
|
+
space_2_unicode("Getting variable value for key #{$1}"),
|
411
|
+
space_2_unicode(@variables_for_chat_users[$1].verbose_introspect(very_verbose=true))
|
412
|
+
].join
|
413
|
+
end
|
414
|
+
|
415
|
+
if message =~ /\Aget-method-definition #{variable_regex}#{method_call_regex}\Z/
|
416
|
+
return @variables_for_chat_users[$1].method($2.to_sym).source
|
417
|
+
end
|
418
|
+
|
419
|
+
if message =~ /\A@LemonAndroid List github repos\Z/i
|
420
|
+
return "https://api.github.com/users/LemonAndroid/repos"
|
421
|
+
end
|
422
|
+
|
423
|
+
if message =~ /\AList 10 most recently pushed to Github Repos of LemonAndroid\Z/i
|
424
|
+
texts = ten_most_pushed_to_github_repos
|
425
|
+
texts.each do |text|
|
426
|
+
return text
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
if message =~ /\A@LemonAndroid work on (\w+\/\w+)\Z/i
|
431
|
+
@currently_selected_project = $1
|
432
|
+
return space_2_unicode("currently selected project set to #{@currently_selected_project}")
|
433
|
+
end
|
434
|
+
|
435
|
+
if message =~ /@LemonAndroid currently selected project/i
|
436
|
+
return space_2_unicode("currently selected project is #{@currently_selected_project}")
|
437
|
+
end
|
438
|
+
|
439
|
+
if message =~ /\Ashow `(.*)`\Z/i
|
440
|
+
test = $1
|
441
|
+
exec_bash_visually_and_post_process_strings
|
442
|
+
end
|
443
|
+
|
444
|
+
if message =~ /\A@LemonAndroid\s+show eval `(.*)`\Z/i
|
445
|
+
texts = [eval($1).to_s]
|
446
|
+
texts.each do |text|
|
447
|
+
return space_2_unicode(text)
|
448
|
+
end
|
449
|
+
end
|
450
|
+
|
451
|
+
if message =~ /\Als\Z/i
|
452
|
+
texts = execute_bash_in_currently_selected_project('ls')
|
453
|
+
texts.each do |text|
|
454
|
+
return text
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
if message =~ /\A@LemonAndroid cd ([^\s]+)\Z/i
|
459
|
+
path = nil
|
460
|
+
Dir.chdir(current_repo_dir) do
|
461
|
+
path = File.expand_path(File.join('.', Dir.glob("**/#{$1}")))
|
462
|
+
end
|
463
|
+
texts = execute_bash_in_currently_selected_project("ls #{path}")
|
464
|
+
|
465
|
+
return space_2_unicode("Listing directory `#{path}`")
|
466
|
+
texts.each do |text|
|
467
|
+
return text
|
468
|
+
end
|
469
|
+
end
|
470
|
+
|
471
|
+
if message =~ /\A@LemonAndroid cat ([^\s]+)\Z/i
|
472
|
+
path = nil
|
473
|
+
Dir.chdir(current_repo_dir) do
|
474
|
+
path = File.expand_path(File.join('.', Dir.glob("**/#{$1}")))
|
475
|
+
end
|
476
|
+
texts = execute_bash_in_currently_selected_project("cat #{path}")
|
477
|
+
|
478
|
+
return space_2_unicode("Showing file `#{path}`")
|
479
|
+
texts.each do |text|
|
480
|
+
return text
|
481
|
+
end
|
482
|
+
end
|
483
|
+
end
|
484
|
+
|
485
|
+
def exec_bash_visually_and_post_process_strings(test)
|
486
|
+
texts = execute_bash_in_currently_selected_project(test)
|
487
|
+
return texts.map do |text|
|
488
|
+
space_2_unicode(text)
|
489
|
+
end.join("\n")
|
490
|
+
end
|
491
|
+
|
492
|
+
def variable_regex
|
493
|
+
/(\w[_\w]*)/
|
494
|
+
end
|
495
|
+
|
496
|
+
def method_call_regex
|
497
|
+
/\.#{variable_regex}/
|
498
|
+
end
|
499
|
+
|
500
|
+
def melting_point_receiavable_regex
|
501
|
+
/(.*)/
|
502
|
+
end
|
503
|
+
|
504
|
+
def start
|
505
|
+
client = Zircon.new(
|
506
|
+
server: 'irc.gitter.im',
|
507
|
+
port: '6667',
|
508
|
+
channel: 'qanda-api/Lobby',
|
509
|
+
username: 'LemonAndroid',
|
510
|
+
password: ENV["GITTER_IRC_PASSWORD"],
|
511
|
+
use_ssl: true
|
512
|
+
)
|
513
|
+
|
514
|
+
client.on_message do |message|
|
515
|
+
on_message(message)
|
516
|
+
end
|
517
|
+
|
518
|
+
client.run!
|
519
|
+
end
|
520
|
+
|
521
|
+
def all_unix_process_ids(unix_id)
|
522
|
+
descendant_pids(unix_id) + [unix_id]
|
523
|
+
end
|
524
|
+
|
525
|
+
def descendant_pids(root_unix_pid)
|
526
|
+
child_unix_pids = `pgrep -P #{root_unix_pid}`.split("\n")
|
527
|
+
further_descendant_unix_pids = \
|
528
|
+
child_unix_pids.map { |unix_pid| descendant_pids(unix_pid) }.flatten
|
529
|
+
|
530
|
+
child_unix_pids + further_descendant_unix_pids
|
531
|
+
end
|
532
|
+
|
533
|
+
def apple_script_window_position_and_size(unix_pid)
|
534
|
+
<<~OSA_SCRIPT
|
535
|
+
tell application "System Events" to tell (every process whose unix id is #{unix_pid})
|
536
|
+
get {position, size} of every window
|
537
|
+
end tell
|
538
|
+
OSA_SCRIPT
|
539
|
+
end
|
540
|
+
|
541
|
+
def get_window_position_and_size(unix_pid)
|
542
|
+
possibly_window_bounds = run_osa_script(apple_script_window_position_and_size(unix_pid))
|
543
|
+
|
544
|
+
if possibly_window_bounds =~ /\d/
|
545
|
+
possibly_window_bounds.scan(/\d+/).map(&:to_i)
|
546
|
+
else
|
547
|
+
return nil
|
548
|
+
end
|
549
|
+
end
|
550
|
+
|
551
|
+
def run_osa_script(script)
|
552
|
+
`osascript -e '#{script}'`
|
553
|
+
end
|
554
|
+
|
555
|
+
def execute_bash_in_currently_selected_project(hopefully_bash_command)
|
556
|
+
if currently_selected_project_exists_locally?
|
557
|
+
Dir.chdir(current_repo_dir) do
|
558
|
+
Bundler.with_clean_env do
|
559
|
+
stdout = ''
|
560
|
+
stderr = ''
|
561
|
+
process = Open4.bg(hopefully_bash_command, 0 => '', 1 => stdout, 2 => stderr)
|
562
|
+
sleep 1
|
563
|
+
|
564
|
+
texts_array = space_2_unicode_array(stdout.split("\n"))
|
565
|
+
texts_array += space_2_unicode_array(stderr.split("\n"))
|
566
|
+
texts_array + screen_captures_of_visual_processes(process.pid)
|
567
|
+
end
|
568
|
+
end
|
569
|
+
else
|
570
|
+
return space_2_unicode_array(
|
571
|
+
[
|
572
|
+
"Currently selected project (#{@currently_selected_project}) not cloned",
|
573
|
+
"Do you want to clone it to the VisualServer with the name \"#{`whoami`.rstrip}\"?"
|
574
|
+
]
|
575
|
+
)
|
576
|
+
end
|
577
|
+
end
|
578
|
+
|
579
|
+
def screen_captures_of_visual_processes(root_unix_pid)
|
580
|
+
sleep 8
|
581
|
+
|
582
|
+
unix_pids = all_unix_process_ids(root_unix_pid)
|
583
|
+
windows = unix_pids.map do |unix_pid|
|
584
|
+
get_window_position_and_size(unix_pid)
|
585
|
+
end.compact
|
586
|
+
|
587
|
+
windows.map do |position_and_size|
|
588
|
+
t = Tempfile.new(['screencapture-pid-', root_unix_pid.to_s, '.png'])
|
589
|
+
`screencapture -R #{position_and_size.join(',')} #{t.path}`
|
590
|
+
|
591
|
+
gyazo = Gyazo::Client.new access_token: 'b2893f18deff437b3abd45b6e4413e255fa563d8bd00d360429c37fe1aee560f'
|
592
|
+
res = gyazo.upload imagefile: t.path
|
593
|
+
res[:url]
|
594
|
+
end
|
595
|
+
end
|
596
|
+
|
597
|
+
def current_repo_dir
|
598
|
+
File.expand_path("~/gam-git-repos/#{@currently_selected_project}")
|
599
|
+
end
|
600
|
+
|
601
|
+
def currently_selected_project_exists_locally?
|
602
|
+
system("stat #{current_repo_dir}")
|
603
|
+
end
|
604
|
+
|
605
|
+
def ten_most_pushed_to_github_repos
|
606
|
+
output = `curl https://api.github.com/users/LemonAndroid/repos`
|
607
|
+
|
608
|
+
processed_output = JSON
|
609
|
+
.parse(output)
|
610
|
+
.sort_by do |project|
|
611
|
+
Date.parse(project["pushed_at"])
|
612
|
+
end
|
613
|
+
.last(10)
|
614
|
+
.map do |project|
|
615
|
+
project["full_name"]
|
616
|
+
end
|
617
|
+
|
618
|
+
space_2_unicode_array(processed_output)
|
619
|
+
end
|
620
|
+
|
621
|
+
def space_2_unicode_array(texts)
|
622
|
+
texts.map { |text| space_2_unicode(text) }
|
623
|
+
end
|
624
|
+
|
625
|
+
def space_2_unicode(text)
|
626
|
+
text.gsub(/\s/, "\u2000")
|
627
|
+
end
|
628
|
+
end
|
629
|
+
|
630
|
+
begin
|
631
|
+
bot = GitterDumbDevBot.new
|
632
|
+
|
633
|
+
bot.load()
|
634
|
+
|
635
|
+
# Thread.new do
|
636
|
+
# bot.start()
|
637
|
+
# end
|
638
|
+
|
639
|
+
get '/' do
|
640
|
+
bot.on_message(params[:message])
|
641
|
+
end
|
642
|
+
ensure
|
643
|
+
bot.dump()
|
644
|
+
end
|