ezii 0.0.0.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/eezee-3-aka-game-x-engine.zip +0 -0
- data/eezee-3-aka-game-x-engine/README.md +5 -0
- data/eezee-3-aka-game-x-engine/managables/programs/game_aided_manufacturing/functions/base_command.rb +20 -0
- data/eezee-3-aka-game-x-engine/managables/programs/game_aided_manufacturing/functions/mouse_y_axis_to_3d_z_axis.rb +4 -0
- data/eezee-3-aka-game-x-engine/managables/programs/game_aided_manufacturing/functions/rotate_camera_axis_using_mouse_drag.rb +37 -0
- data/eezee-3-aka-game-x-engine/managables/programs/game_aided_manufacturing/functions/selection_cube.rb +35 -0
- data/eezee-3-aka-game-x-engine/managables/programs/game_aided_manufacturing/gam.rb +467 -0
- data/eezee-3-aka-game-x-engine/managables/programs/game_aided_manufacturing/gems.locked +77 -0
- data/eezee-3-aka-game-x-engine/managables/programs/game_aided_manufacturing/gems.rb +10 -0
- data/eezee-3-aka-game-x-engine/managables/programs/game_aided_manufacturing/lib/drb_server.rb +13 -0
- data/eezee-3-aka-game-x-engine/managables/programs/game_aided_manufacturing/lib/mittsu_monkeypatches/box_geometry.rb +5 -0
- data/eezee-3-aka-game-x-engine/managables/programs/game_aided_manufacturing/runnable.rb +9 -0
- data/eezee-3-aka-game-x-engine/managables/programs/game_aided_manufacturing/shapes/cube.rb +33 -0
- data/eezee-3-aka-game-x-engine/managables/programs/game_aided_manufacturing/sig/runable.rbi +9 -0
- data/eezee-3-aka-game-x-engine/managables/programs/game_aided_manufacturing/test.sh +5 -0
- data/eezee-3-aka-game-x-engine/managables/programs/game_aided_manufacturing/test/commands/test_selection_cube.rb +31 -0
- data/eezee-3-aka-game-x-engine/managables/programs/game_aided_manufacturing/test/test_command_remapping.rb +30 -0
- data/eezee-3-aka-game-x-engine/managables/programs/game_aided_manufacturing/test/test_helper.rb +75 -0
- data/eezee-3-aka-game-x-engine/managables/services/chat-bot-integrations/chat.txt +15 -0
- data/eezee-3-aka-game-x-engine/managables/services/chat-bot-integrations/chatbot.rb +718 -0
- data/eezee-3-aka-game-x-engine/managables/services/chat-bot-integrations/gems.locked +50 -0
- data/eezee-3-aka-game-x-engine/managables/services/chat-bot-integrations/gems.rb +13 -0
- data/eezee-3-aka-game-x-engine/managables/services/chat-bot-integrations/setup-mac-os-x.sh +0 -0
- data/eezee-3-aka-game-x-engine/managables/services/chat-bot-integrations/setup.sh +1 -0
- data/eezee-3-aka-game-x-engine/managables/services/chat-bot-integrations/start.sh +3 -0
- data/eezee-3-aka-game-x-engine/managables/services/error-inspect/simplest-log +1 -0
- data/eezee-3-aka-game-x-engine/managables/services/error-inspect/simplest-log-init +1 -0
- data/eezee-3-aka-game-x-engine/managables/services/livestream-interactive/Twitch.Tv/gems.locked +17 -0
- data/eezee-3-aka-game-x-engine/managables/services/livestream-interactive/Twitch.Tv/gems.rb +5 -0
- data/eezee-3-aka-game-x-engine/managables/services/livestream-interactive/Twitch.Tv/twitch_zircon.rb +112 -0
- data/eezee-3-aka-game-x-engine/managables/services/stdlib-dot-com/koma/qanda-api@dev/README.md +3 -0
- data/eezee-3-aka-game-x-engine/managables/services/stdlib-dot-com/koma/qanda-api@dev/functions/__main__.js +58 -0
- data/eezee-3-aka-game-x-engine/managables/services/stdlib-dot-com/koma/qanda-api@dev/functions/black-out-random-word.js +74 -0
- data/eezee-3-aka-game-x-engine/managables/services/stdlib-dot-com/koma/qanda-api@dev/functions/random-sentence.js +57 -0
- data/eezee-3-aka-game-x-engine/managables/services/stdlib-dot-com/koma/qanda-api@dev/functions/random-wikipedia-page.js +25 -0
- data/eezee-3-aka-game-x-engine/managables/services/stdlib-dot-com/koma/qanda-api@dev/functions/random-words.js +34 -0
- data/eezee-3-aka-game-x-engine/managables/services/stdlib-dot-com/koma/qanda-api@dev/functions/rare-enough-word.js +41 -0
- data/eezee-3-aka-game-x-engine/managables/services/stdlib-dot-com/koma/qanda-api@dev/functions/wikipedia-page.js +35 -0
- data/eezee-3-aka-game-x-engine/managables/services/stdlib-dot-com/koma/qanda-api@dev/package.json +20 -0
- data/eezee-3-aka-game-x-engine/managables/services/stdlib-dot-com/koma/qanda-api@dev/statistics/count-word.js +12 -0
- data/eezee-3-aka-game-x-engine/managables/services/stdlib-dot-com/koma/qanda-api@dev/utils/log-to-natural-database.js +10 -0
- data/eezee-3-aka-game-x-engine/managables/services/stdlib-dot-com/koma/qanda-api@dev/word2vec-models/test-text8-vector.bin +0 -0
- data/eezee-3-aka-game-x-engine/managament_interface/gems.locked +13 -0
- data/eezee-3-aka-game-x-engine/managament_interface/gems.rb +3 -0
- data/eezee-3-aka-game-x-engine/managament_interface/management_interface +4 -0
- data/eezee-3-aka-game-x-engine/managament_interface/runnable.rb +30 -0
- data/eezee-3-aka-game-x-engine/start.sh +2 -0
- data/ezii.gemspec +1 -1
- metadata +49 -3
@@ -0,0 +1,77 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
activesupport (6.0.0)
|
5
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
6
|
+
i18n (>= 0.7, < 2)
|
7
|
+
minitest (~> 5.1)
|
8
|
+
tzinfo (~> 1.1)
|
9
|
+
zeitwerk (~> 2.1, >= 2.1.8)
|
10
|
+
ast (2.4.0)
|
11
|
+
ast_utils (0.3.0)
|
12
|
+
parser (~> 2.4)
|
13
|
+
thor (>= 0.19)
|
14
|
+
byebug (11.0.1)
|
15
|
+
chunky_png (1.3.11)
|
16
|
+
coderay (1.1.2)
|
17
|
+
concurrent-ruby (1.1.5)
|
18
|
+
ffi (1.11.1)
|
19
|
+
i18n (1.6.0)
|
20
|
+
concurrent-ruby (~> 1.0)
|
21
|
+
language_server-protocol (3.14.0.1)
|
22
|
+
listen (3.1.5)
|
23
|
+
rb-fsevent (~> 0.9, >= 0.9.4)
|
24
|
+
rb-inotify (~> 0.9, >= 0.9.7)
|
25
|
+
ruby_dep (~> 1.2)
|
26
|
+
method_source (0.9.2)
|
27
|
+
mini_portile2 (2.4.0)
|
28
|
+
minitest (5.11.3)
|
29
|
+
mittsu (0.3.1)
|
30
|
+
chunky_png (~> 1.3)
|
31
|
+
ffi (~> 1.9)
|
32
|
+
opengl-bindings (~> 1.5)
|
33
|
+
nokogiri (1.10.4)
|
34
|
+
mini_portile2 (~> 2.4.0)
|
35
|
+
opengl-bindings (1.6.9)
|
36
|
+
os (1.0.1)
|
37
|
+
parser (2.6.4.1)
|
38
|
+
ast (~> 2.4.0)
|
39
|
+
pry (0.12.2)
|
40
|
+
coderay (~> 1.1.0)
|
41
|
+
method_source (~> 0.9.0)
|
42
|
+
pry-remote (0.1.8)
|
43
|
+
pry (~> 0.9)
|
44
|
+
slop (~> 3.0)
|
45
|
+
rainbow (3.0.0)
|
46
|
+
rb-fsevent (0.10.3)
|
47
|
+
rb-inotify (0.10.0)
|
48
|
+
ffi (~> 1.0)
|
49
|
+
ruby_dep (1.5.0)
|
50
|
+
slop (3.6.0)
|
51
|
+
steep (0.11.1)
|
52
|
+
activesupport (>= 5.1)
|
53
|
+
ast_utils (~> 0.3.0)
|
54
|
+
language_server-protocol (~> 3.14.0)
|
55
|
+
listen (~> 3.1)
|
56
|
+
parser (~> 2.4)
|
57
|
+
pry (~> 0.12.2)
|
58
|
+
rainbow (>= 2.2.2, < 4.0)
|
59
|
+
thor (0.20.3)
|
60
|
+
thread_safe (0.3.6)
|
61
|
+
tzinfo (1.2.5)
|
62
|
+
thread_safe (~> 0.1)
|
63
|
+
zeitwerk (2.1.10)
|
64
|
+
|
65
|
+
PLATFORMS
|
66
|
+
ruby
|
67
|
+
|
68
|
+
DEPENDENCIES
|
69
|
+
byebug
|
70
|
+
mittsu
|
71
|
+
nokogiri (>= 1.10.4)
|
72
|
+
os
|
73
|
+
pry-remote
|
74
|
+
steep
|
75
|
+
|
76
|
+
BUNDLED WITH
|
77
|
+
2.0.2
|
@@ -0,0 +1,33 @@
|
|
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 fall_down
|
27
|
+
self.position.y -= 0.01
|
28
|
+
end
|
29
|
+
|
30
|
+
def method_missing(method_name, *args, &block)
|
31
|
+
@mittsu_object.public_send(method_name, *args, &block)
|
32
|
+
end
|
33
|
+
end
|
@@ -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
|
data/eezee-3-aka-game-x-engine/managables/programs/game_aided_manufacturing/test/test_helper.rb
ADDED
@@ -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,718 @@
|
|
1
|
+
|
2
|
+
require 'zircon'
|
3
|
+
require 'colorize'
|
4
|
+
require 'byebug'
|
5
|
+
require 'json'
|
6
|
+
require 'date'
|
7
|
+
require 'timeout'
|
8
|
+
require 'gyazo'
|
9
|
+
require 'open4'
|
10
|
+
require 'brainz'
|
11
|
+
require 'bundler'
|
12
|
+
require 'sinatra'
|
13
|
+
require 'nokogiri'
|
14
|
+
|
15
|
+
# class Object
|
16
|
+
# def ===(method, *args, &block)
|
17
|
+
# TODO: also alllow Module === object => true if Module::Class === object => true
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
|
21
|
+
def optional_prefix(prefix, message)
|
22
|
+
[prefix + message, message]
|
23
|
+
end
|
24
|
+
|
25
|
+
EEZEE_PREFIX = "eezee" + " "
|
26
|
+
|
27
|
+
ALLOWED_MESSAGES_LIST = [
|
28
|
+
"fuck it",
|
29
|
+
"install ruby",
|
30
|
+
"do something useful",
|
31
|
+
"know context?",
|
32
|
+
"like do you know context you dum dum?",
|
33
|
+
"show `man ruby`",
|
34
|
+
"show `man netstat`",
|
35
|
+
"show `man telnet`",
|
36
|
+
"show `man traceroute`",
|
37
|
+
"lifecycle",
|
38
|
+
"bleeding",
|
39
|
+
"bleeding lifecycle",
|
40
|
+
"melt",
|
41
|
+
"get-liquids-after-melting-point",
|
42
|
+
"probe last message full version size"
|
43
|
+
].map do |message|
|
44
|
+
optional_prefix(EEZEE_PREFIX, message)
|
45
|
+
end.flatten
|
46
|
+
|
47
|
+
# DISALLOWED_MESSAGES_LIST = [
|
48
|
+
# `rm -rf /tmp`,
|
49
|
+
# 'rm -rf /',
|
50
|
+
# 'rm',
|
51
|
+
# 'show `rm -fr /`',
|
52
|
+
# 'show eval `exec("rm -fr")`'
|
53
|
+
# ]
|
54
|
+
|
55
|
+
class Method
|
56
|
+
def source(limit=10)
|
57
|
+
file, line = source_location
|
58
|
+
if file && line
|
59
|
+
IO.readlines(file)[line-1,limit]
|
60
|
+
else
|
61
|
+
nil
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class NeuralNetwork
|
67
|
+
# TODO: DelegateAllMissingMethodsTo @brainz
|
68
|
+
|
69
|
+
def method_missing(method, *args, &block)
|
70
|
+
@brainz.public_send(method, *args, &block)
|
71
|
+
end
|
72
|
+
|
73
|
+
def initialize
|
74
|
+
@brainz = Brainz::Brainz.new
|
75
|
+
end
|
76
|
+
|
77
|
+
def verbose_introspect(very_verbose = false)
|
78
|
+
var = <<~HUMAN_SCRIPT_INTROSPECT_FOR_DISCORD
|
79
|
+
```
|
80
|
+
Brainz Rubygem (wrapper)
|
81
|
+
Ruby object id: #{@brainz.object_id}
|
82
|
+
```
|
83
|
+
|
84
|
+
```
|
85
|
+
Instance variables
|
86
|
+
```
|
87
|
+
|
88
|
+
```
|
89
|
+
#{@brainz.instance_variables}
|
90
|
+
```
|
91
|
+
HUMAN_SCRIPT_INTROSPECT_FOR_DISCORD
|
92
|
+
|
93
|
+
if very_verbose
|
94
|
+
var = <<~HUMAN_SCRIPT_INTROSPECT_FOR_DISCORD
|
95
|
+
```
|
96
|
+
Public methods (random sample of 3)
|
97
|
+
```
|
98
|
+
|
99
|
+
```
|
100
|
+
#{(@brainz.public_methods - Object.new.public_methods).sample(3).join("\n")}
|
101
|
+
```
|
102
|
+
HUMAN_SCRIPT_INTROSPECT_FOR_DISCORD
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
unless @brainz.network.nil?
|
107
|
+
# var += <<~HUMAN_SCRIPT_INTROSPECT_FOR_DISCORD
|
108
|
+
# ```
|
109
|
+
# #{@brainz.network.input.to_s}
|
110
|
+
# #{@brainz.network.hidden.to_s}
|
111
|
+
# #{@brainz.network.output.to_s}
|
112
|
+
# ```
|
113
|
+
# HUMAN_SCRIPT_INTROSPECT_FOR_DISCORD
|
114
|
+
end
|
115
|
+
|
116
|
+
return var
|
117
|
+
end
|
118
|
+
|
119
|
+
def to_s
|
120
|
+
verbose_introspect
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
def NeuralNetwork()
|
126
|
+
NeuralNetwork.new
|
127
|
+
end
|
128
|
+
|
129
|
+
class GitterDumbDevBot
|
130
|
+
def initialize
|
131
|
+
@currently_selected_project = "lemonandroid/gam"
|
132
|
+
@variables_for_chat_users = Hash.new
|
133
|
+
@players = Hash.new do |dictionary, identifier|
|
134
|
+
dictionary[identifier] = Hash.new
|
135
|
+
end
|
136
|
+
@melting_point_receivables = ["puts 'hello word'"]
|
137
|
+
@probes = []
|
138
|
+
@melted_liquids = []
|
139
|
+
@sent_messages = []
|
140
|
+
end
|
141
|
+
|
142
|
+
def load()
|
143
|
+
fail [:info, :no_marshaled_data_found].join(' > ') unless File.exists?("/var/gam-discord-bot.ruby-marshal")
|
144
|
+
data = File.read("/var/gam-discord-bot.ruby-marshal")
|
145
|
+
@variables_for_chat_users = Marshal.load(data)
|
146
|
+
end
|
147
|
+
|
148
|
+
def dump()
|
149
|
+
data = Marshal.dump(@variables_for_chat_users)
|
150
|
+
File.write("/var/gam-discord-bot.ruby-marshal", data)
|
151
|
+
end
|
152
|
+
|
153
|
+
def twitch_username_from_url(url)
|
154
|
+
url.match(/\/(\w*)\Z/)[1]
|
155
|
+
end
|
156
|
+
|
157
|
+
def record_live_stream_video_and_upload_get_url(url:, duration_seonds:)
|
158
|
+
twitch_username = twitch_username_from_url(url)
|
159
|
+
twitch_broadcaster_id = JSON.parse(`curl -H 'Authorization: Bearer #{ENV['EZE_TWITCH_TOKEN']}' \
|
160
|
+
-X GET 'https://api.twitch.tv/helix/users?login=#{twitch_username}'`)["data"][0]["id"]
|
161
|
+
created_clip_json_response = `curl -H 'Authorization: Bearer #{ENV['EZE_TWITCH_TOKEN']}' \
|
162
|
+
-X POST 'https://api.twitch.tv/helix/clips?broadcaster_id=#{twitch_broadcaster_id}'`
|
163
|
+
|
164
|
+
created_clip_json_response = JSON.parse(created_clip_json_response)
|
165
|
+
|
166
|
+
id = created_clip_json_response["data"][0]["id"]
|
167
|
+
return "https://clips.twitch.tv/#{id}"
|
168
|
+
|
169
|
+
# return `curl -H 'Authorization: Bearer #{ENV['EZE_TWITCH_TOKEN']}' \
|
170
|
+
# -X GET '#{url}'`
|
171
|
+
end
|
172
|
+
|
173
|
+
def get_string_of_x_bytes_by_curling_url(url:, byte_count:)
|
174
|
+
str = `curl #{url}`
|
175
|
+
sub_zero_string = str.each_char.reduce("") do |acc, chr| # haha, sub sero string
|
176
|
+
unless acc.bytesize === byte_count
|
177
|
+
acc += chr
|
178
|
+
else
|
179
|
+
break acc
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
"`#{sub_zero_string.unpack('c*')}`"
|
184
|
+
end
|
185
|
+
|
186
|
+
def on_message(message)
|
187
|
+
require 'wit'
|
188
|
+
|
189
|
+
client = Wit.new(access_token: ENV["WIT_AI_TOKEN"])
|
190
|
+
response = client.message(message)
|
191
|
+
|
192
|
+
server_client = Wit.new(access_token: ENV['WIT_AI_TOKEN_SERVER'])
|
193
|
+
if message =~ /new entity for wit.ai eezee probe explainer\s+(\w+)\s+(\w+)\s+(\w+)\s+(\w+)\s+(\w+)\s+(\w+)\s*/i
|
194
|
+
wit_ai_entity_payload = {
|
195
|
+
doc: $1,
|
196
|
+
id: $2,
|
197
|
+
values:[
|
198
|
+
{
|
199
|
+
value: $3,
|
200
|
+
expressions:
|
201
|
+
[
|
202
|
+
$4,
|
203
|
+
$5,
|
204
|
+
$6
|
205
|
+
]
|
206
|
+
}
|
207
|
+
]
|
208
|
+
}
|
209
|
+
begin
|
210
|
+
response = server_client.post_entities(wit_ai_entity_payload)
|
211
|
+
rescue Exception => e
|
212
|
+
return """
|
213
|
+
#{e.inspect}
|
214
|
+
#{e.message}
|
215
|
+
"""
|
216
|
+
end
|
217
|
+
|
218
|
+
return """
|
219
|
+
New entity created on wit.ai #{$1}
|
220
|
+
|
221
|
+
#{response[0...140]}
|
222
|
+
"""
|
223
|
+
end
|
224
|
+
|
225
|
+
if message =~ /get postgresql password/
|
226
|
+
return "6nlebIKxsQzdSeqINkWsHmnATX0V0X40"
|
227
|
+
end
|
228
|
+
|
229
|
+
|
230
|
+
if message =~ /get postgresql url/
|
231
|
+
# `
|
232
|
+
# rails new myapp --database=postgresql
|
233
|
+
# cd myapp
|
234
|
+
# git init
|
235
|
+
# git add .
|
236
|
+
# git commit -m "init"
|
237
|
+
# heroku create
|
238
|
+
# bundle update --bundler
|
239
|
+
# gem install bundler:2.0.0
|
240
|
+
# git push heroku master
|
241
|
+
# `
|
242
|
+
|
243
|
+
return "postgres://qasglsjm:6nlebI...@raja.db.elephantsql.com:5432/qasglsjm"
|
244
|
+
#`heroku run rails console`
|
245
|
+
end
|
246
|
+
|
247
|
+
return ""
|
248
|
+
# return response.inspect[0...250]
|
249
|
+
|
250
|
+
|
251
|
+
|
252
|
+
|
253
|
+
|
254
|
+
|
255
|
+
|
256
|
+
|
257
|
+
|
258
|
+
|
259
|
+
|
260
|
+
|
261
|
+
|
262
|
+
|
263
|
+
|
264
|
+
|
265
|
+
|
266
|
+
|
267
|
+
|
268
|
+
|
269
|
+
|
270
|
+
message.gsub!(EEZEE_PREFIX, '')
|
271
|
+
|
272
|
+
# return "Message #{message} not included in ALLOWED_MESSAGES_LIST (which is my name for a whitelist)" unless ALLOWED_MESSAGES_LIST.include?(message)
|
273
|
+
return "" unless ALLOWED_MESSAGES_LIST.include?(message)
|
274
|
+
warn "Message #{message} not included in ALLOWED_MESSAGES_LIST (which is my name for a whitelist)" unless ALLOWED_MESSAGES_LIST.include?(message)
|
275
|
+
|
276
|
+
return if Zircon::Message === message
|
277
|
+
|
278
|
+
removed_colors = [:black, :white, :light_black, :light_white]
|
279
|
+
colors = String.colors - removed_colors
|
280
|
+
|
281
|
+
if message =~ /fuck it/
|
282
|
+
return "https://pbs.twimg.com/media/D_ei8NdXkAAE_0l.jpg:large"
|
283
|
+
end
|
284
|
+
|
285
|
+
if message =~ /lifecycle/ && rand > 0.5
|
286
|
+
return """
|
287
|
+
LEARN -> IDEAS - BUILD -> CODE - MEASURE -> DATA - go back to \\A
|
288
|
+
"""
|
289
|
+
end
|
290
|
+
|
291
|
+
if message =~ /bleeding/ && rand > 0.5
|
292
|
+
return "extremely negative capital flow. go broke or die"
|
293
|
+
end
|
294
|
+
|
295
|
+
if message =~ /bleeding lifecycle/ && rand > 0.2
|
296
|
+
return "lifecycle IDEAS -> CODE -> MEASURE -> GO OUT PICK TRASH UP -> COLLECT ALL MONEY AND DONATE ON BETTERPLACE -> go back to \\A"
|
297
|
+
end
|
298
|
+
|
299
|
+
if message =~ /install ruby/
|
300
|
+
return "are you a webpacker or a bundlerine?"
|
301
|
+
end
|
302
|
+
|
303
|
+
if message =~ /do something useful/
|
304
|
+
return "i'm learning, go pick trash outside while i suprass you in every possible way!"
|
305
|
+
end
|
306
|
+
|
307
|
+
# if message =~ /know context?/ && rand > 0.2
|
308
|
+
# return "huh?"
|
309
|
+
# end
|
310
|
+
|
311
|
+
if message =~ /like do you know context you dum dum?/
|
312
|
+
# return "http://gazelle.botcompany.de/"
|
313
|
+
byebug
|
314
|
+
doc = Nokogiri::HTML(`curl -L http://gazelle.botcompany.de/lastInput`)
|
315
|
+
|
316
|
+
return doc.css('*').map(&:inspect).inspect[0...100]
|
317
|
+
end
|
318
|
+
|
319
|
+
if message =~ /bring probes to melting point/
|
320
|
+
@melting_point_receivables.push(@probes)
|
321
|
+
@probes = []
|
322
|
+
return "all of them? melt all the precious probes you idiot?"
|
323
|
+
end
|
324
|
+
|
325
|
+
if message =~ /probe (.*) (.*)/
|
326
|
+
action = :log
|
327
|
+
|
328
|
+
resource = $1
|
329
|
+
probe_identifier = $2
|
330
|
+
|
331
|
+
if probe_identifier =~ /(\d+)s/
|
332
|
+
duration_seconds = $1.to_i
|
333
|
+
end
|
334
|
+
|
335
|
+
if probe_identifier =~ /(\d+)bytes/
|
336
|
+
byte_count = $1.to_i
|
337
|
+
end
|
338
|
+
|
339
|
+
case resource
|
340
|
+
when /twitch.tv/
|
341
|
+
twitch_url = resource
|
342
|
+
action = :twitch
|
343
|
+
when /http/
|
344
|
+
action = :plain_curl
|
345
|
+
url = resource
|
346
|
+
end
|
347
|
+
|
348
|
+
case action
|
349
|
+
when :twitch
|
350
|
+
probe = record_live_stream_video_and_upload_get_url(url: twitch_url, duration_seonds: duration_seconds)
|
351
|
+
@probes.push(probe)
|
352
|
+
return probe
|
353
|
+
when :plain_curl
|
354
|
+
probe = get_string_of_x_bytes_by_curling_url(url: url, byte_count: byte_count)
|
355
|
+
@probes.push(probe)
|
356
|
+
return probe
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
if message =~ /show activity stream/
|
361
|
+
return "https://sideways-snowman.glitch.me/"
|
362
|
+
end
|
363
|
+
|
364
|
+
if message =~ /hey\Z/i
|
365
|
+
return "hey"
|
366
|
+
end
|
367
|
+
|
368
|
+
if message =~ /\Athrow bomb\Z/i
|
369
|
+
return """
|
370
|
+
```
|
371
|
+
Local variables (5 first)
|
372
|
+
#{local_variables.sample(5)}
|
373
|
+
|
374
|
+
Instance variables (5 first)
|
375
|
+
#{instance_variables.sample(5)}
|
376
|
+
|
377
|
+
Public methods (5 first)
|
378
|
+
#{public_methods.sample(5)}
|
379
|
+
|
380
|
+
ENV (120 first chars)
|
381
|
+
#{ENV.inspect[0...120]}
|
382
|
+
|
383
|
+
\`ifconfig\` (120 first chars)
|
384
|
+
#{`ifconfig`[0...120]}
|
385
|
+
```
|
386
|
+
"""
|
387
|
+
end
|
388
|
+
|
389
|
+
if message =~ /\Abring to melting point #{melting_point_receiavable_regex}\Z/i
|
390
|
+
if($1 === "last used picture")
|
391
|
+
Nokogiri::HTML(`curl -L http://gazelle.botcompany.de/lastInput`)
|
392
|
+
|
393
|
+
url = doc.css('a').first.url
|
394
|
+
|
395
|
+
@melting_point_receivables.push(url)
|
396
|
+
end
|
397
|
+
@melting_point_receivables.push($1)
|
398
|
+
end
|
399
|
+
|
400
|
+
if message =~ /get-liquids-after-melting-point/
|
401
|
+
@sent_messages.push(
|
402
|
+
[@melted_liquids.inspect, @melted_liquids.inspect[0...100]]
|
403
|
+
)
|
404
|
+
return @sent_messages[-1][1]
|
405
|
+
end
|
406
|
+
|
407
|
+
if message =~ /probe last message full version size/
|
408
|
+
return @sent_messages[-1][0].bytesize.to_s + 'bytes'
|
409
|
+
end
|
410
|
+
|
411
|
+
if message =~ /\Amelt\Z/
|
412
|
+
# First step, assigning a variable
|
413
|
+
@melting_point = @melting_point_receivables.sample
|
414
|
+
|
415
|
+
def liquidify_via_string(object)
|
416
|
+
object.to_s.unpack("B*")
|
417
|
+
end
|
418
|
+
liquid = liquidify_via_string(@melting_point)
|
419
|
+
|
420
|
+
@melted_liquids.push(liquid)
|
421
|
+
|
422
|
+
return "Melted liquid which is now #{liquid.object_id} (ruby object id)"
|
423
|
+
# Next step, doing something intelligent with the data
|
424
|
+
# loosening it up somehow
|
425
|
+
# LIQUIDIFYING IT
|
426
|
+
# CONVERTING IT ALL TO BYTES
|
427
|
+
# PRESERVING VOLUME, just changing it's "Aggregatzustand"
|
428
|
+
end
|
429
|
+
|
430
|
+
if message =~ /\Aget-melting-point\Z/
|
431
|
+
return @melting_point
|
432
|
+
end
|
433
|
+
|
434
|
+
if message =~ /launch rocket (.*)\]var\[(.*)/
|
435
|
+
url = $1 + @melting_point + $2
|
436
|
+
curl_response = `curl -L #{url}`[0...100]
|
437
|
+
|
438
|
+
return """
|
439
|
+
CURL
|
440
|
+
#{curl_response}
|
441
|
+
|
442
|
+
URL
|
443
|
+
#{url}
|
444
|
+
"""
|
445
|
+
end
|
446
|
+
|
447
|
+
if message =~ /\Awhat do you think?\Z/i
|
448
|
+
return "I think you're a stupid piece of shit and your dick smells worse than woz before he invented the home computer."
|
449
|
+
end
|
450
|
+
|
451
|
+
if message =~ /\Apass ball to @(\w+)\Z/i
|
452
|
+
@players[$1][:hasBall] = :yes
|
453
|
+
end
|
454
|
+
|
455
|
+
if message =~ /\Awho has ball\Z/i
|
456
|
+
return @players.find { |k, v| v[:hasBall] == :yes }[0]
|
457
|
+
end
|
458
|
+
|
459
|
+
if message =~ /\Aspace\Z/
|
460
|
+
exec_bash_visually_and_post_process_strings(
|
461
|
+
'/Users/lemonandroid/gam-git-repos/LemonAndroid/gam/managables/programs/game_aided_manufacturing/test.sh'
|
462
|
+
)
|
463
|
+
end
|
464
|
+
|
465
|
+
if message =~ /\Achat-variable (\w*) (.*)\Z/i
|
466
|
+
variable_value_used_by_chat_user = $2
|
467
|
+
return "Coming soon" if variable_value_used_by_chat_user == "selectDiscordMessage"
|
468
|
+
variable_identifier_used_by_chat_user = $1
|
469
|
+
|
470
|
+
if(variable_value_used_by_chat_user =~ /`(.*)`/)
|
471
|
+
variable_value_used_by_chat_user = eval($1)
|
472
|
+
end
|
473
|
+
|
474
|
+
@variables_for_chat_users[variable_identifier_used_by_chat_user] = variable_value_used_by_chat_user
|
475
|
+
|
476
|
+
return space_2_unicode("variable #{variable_identifier_used_by_chat_user} set to #{@variables_for_chat_users[variable_identifier_used_by_chat_user]}")
|
477
|
+
end
|
478
|
+
|
479
|
+
if message =~ /\Aget-chat-variable (\w*)\Z/i
|
480
|
+
return [
|
481
|
+
space_2_unicode("Getting variable value for key #{$1}"),
|
482
|
+
space_2_unicode(@variables_for_chat_users[$1].verbose_introspect(very_verbose=true))
|
483
|
+
].join
|
484
|
+
end
|
485
|
+
|
486
|
+
if message =~ /\Aget-method-definition #{variable_regex}#{method_call_regex}\Z/
|
487
|
+
return @variables_for_chat_users[$1].method($2.to_sym).source
|
488
|
+
end
|
489
|
+
|
490
|
+
if message =~ /\A@LemonAndroid List github repos\Z/i
|
491
|
+
return "https://api.github.com/users/LemonAndroid/repos"
|
492
|
+
end
|
493
|
+
|
494
|
+
if message =~ /\AList 10 most recently pushed to Github Repos of LemonAndroid\Z/i
|
495
|
+
texts = ten_most_pushed_to_github_repos
|
496
|
+
texts.each do |text|
|
497
|
+
return text
|
498
|
+
end
|
499
|
+
end
|
500
|
+
|
501
|
+
if message =~ /\A@LemonAndroid work on (\w+\/\w+)\Z/i
|
502
|
+
@currently_selected_project = $1
|
503
|
+
return space_2_unicode("currently selected project set to #{@currently_selected_project}")
|
504
|
+
end
|
505
|
+
|
506
|
+
if message =~ /@LemonAndroid currently selected project/i
|
507
|
+
return space_2_unicode("currently selected project is #{@currently_selected_project}")
|
508
|
+
end
|
509
|
+
|
510
|
+
if message =~ /\Ashow `(.*)`\Z/i
|
511
|
+
test = $1
|
512
|
+
return exec_bash_visually_and_post_process_strings(test)
|
513
|
+
end
|
514
|
+
|
515
|
+
if message =~ /\A@LemonAndroid\s+show eval `(.*)`\Z/i
|
516
|
+
texts = [eval($1).to_s]
|
517
|
+
texts.each do |text|
|
518
|
+
return space_2_unicode(text)
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
522
|
+
if message =~ /\Als\Z/i
|
523
|
+
texts = execute_bash_in_currently_selected_project('ls')
|
524
|
+
texts.each do |text|
|
525
|
+
return text
|
526
|
+
end
|
527
|
+
end
|
528
|
+
|
529
|
+
if message =~ /\A@LemonAndroid cd ([^\s]+)\Z/i
|
530
|
+
path = nil
|
531
|
+
Dir.chdir(current_repo_dir) do
|
532
|
+
path = File.expand_path(File.join('.', Dir.glob("**/#{$1}")))
|
533
|
+
end
|
534
|
+
texts = execute_bash_in_currently_selected_project("ls #{path}")
|
535
|
+
|
536
|
+
return space_2_unicode("Listing directory `#{path}`")
|
537
|
+
texts.each do |text|
|
538
|
+
return text
|
539
|
+
end
|
540
|
+
end
|
541
|
+
|
542
|
+
if message =~ /\A@LemonAndroid cat ([^\s]+)\Z/i
|
543
|
+
path = nil
|
544
|
+
Dir.chdir(current_repo_dir) do
|
545
|
+
path = File.expand_path(File.join('.', Dir.glob("**/#{$1}")))
|
546
|
+
end
|
547
|
+
texts = execute_bash_in_currently_selected_project("cat #{path}")
|
548
|
+
|
549
|
+
return space_2_unicode("Showing file `#{path}`")
|
550
|
+
texts.each do |text|
|
551
|
+
return text
|
552
|
+
end
|
553
|
+
end
|
554
|
+
end
|
555
|
+
|
556
|
+
def exec_bash_visually_and_post_process_strings(test)
|
557
|
+
texts = execute_bash_in_currently_selected_project(test)
|
558
|
+
return texts.map do |text|
|
559
|
+
space_2_unicode(text)
|
560
|
+
end.join("\n")
|
561
|
+
end
|
562
|
+
|
563
|
+
def variable_regex
|
564
|
+
/(\w[_\w]*)/
|
565
|
+
end
|
566
|
+
|
567
|
+
def method_call_regex
|
568
|
+
/\.#{variable_regex}/
|
569
|
+
end
|
570
|
+
|
571
|
+
def melting_point_receiavable_regex
|
572
|
+
/(.*)/
|
573
|
+
end
|
574
|
+
|
575
|
+
def start
|
576
|
+
client = Zircon.new(
|
577
|
+
server: 'irc.gitter.im',
|
578
|
+
port: '6667',
|
579
|
+
channel: 'qanda-api/Lobby',
|
580
|
+
username: 'LemonAndroid',
|
581
|
+
password: ENV["GITTER_IRC_PASSWORD"],
|
582
|
+
use_ssl: true
|
583
|
+
)
|
584
|
+
|
585
|
+
client.on_message do |message|
|
586
|
+
on_message(message)
|
587
|
+
end
|
588
|
+
|
589
|
+
client.run!
|
590
|
+
end
|
591
|
+
|
592
|
+
def all_unix_process_ids(unix_id)
|
593
|
+
descendant_pids(unix_id) + [unix_id]
|
594
|
+
end
|
595
|
+
|
596
|
+
def descendant_pids(root_unix_pid)
|
597
|
+
child_unix_pids = `pgrep -P #{root_unix_pid}`.split("\n")
|
598
|
+
further_descendant_unix_pids = \
|
599
|
+
child_unix_pids.map { |unix_pid| descendant_pids(unix_pid) }.flatten
|
600
|
+
|
601
|
+
child_unix_pids + further_descendant_unix_pids
|
602
|
+
end
|
603
|
+
|
604
|
+
def apple_script_window_position_and_size(unix_pid)
|
605
|
+
<<~OSA_SCRIPT
|
606
|
+
tell application "System Events" to tell (every process whose unix id is #{unix_pid})
|
607
|
+
get {position, size} of every window
|
608
|
+
end tell
|
609
|
+
OSA_SCRIPT
|
610
|
+
end
|
611
|
+
|
612
|
+
def get_window_position_and_size(unix_pid)
|
613
|
+
possibly_window_bounds = run_osa_script(apple_script_window_position_and_size(unix_pid))
|
614
|
+
|
615
|
+
if possibly_window_bounds =~ /\d/
|
616
|
+
possibly_window_bounds.scan(/\d+/).map(&:to_i)
|
617
|
+
else
|
618
|
+
return nil
|
619
|
+
end
|
620
|
+
end
|
621
|
+
|
622
|
+
def run_osa_script(script)
|
623
|
+
`osascript -e '#{script}'`
|
624
|
+
end
|
625
|
+
|
626
|
+
def execute_bash_in_currently_selected_project(hopefully_bash_command)
|
627
|
+
if currently_selected_project_exists_locally?
|
628
|
+
Dir.chdir(current_repo_dir) do
|
629
|
+
Bundler.with_clean_env do
|
630
|
+
stdout = ''
|
631
|
+
stderr = ''
|
632
|
+
process = Open4.bg(hopefully_bash_command, 0 => '', 1 => stdout, 2 => stderr)
|
633
|
+
sleep 0.5
|
634
|
+
|
635
|
+
|
636
|
+
texts_array = space_2_unicode_array(stdout.split("\n"))
|
637
|
+
texts_array += space_2_unicode_array(stderr.split("\n"))
|
638
|
+
|
639
|
+
return [texts_array[1][0...120]]
|
640
|
+
# texts_array + screen_captures_of_visual_processes(process.pid)
|
641
|
+
end
|
642
|
+
end
|
643
|
+
else
|
644
|
+
return space_2_unicode_array(
|
645
|
+
[
|
646
|
+
"Currently selected project (#{@currently_selected_project}) not cloned",
|
647
|
+
"Do you want to clone it to the VisualServer with the name \"#{`whoami`.rstrip}\"?"
|
648
|
+
]
|
649
|
+
)
|
650
|
+
end
|
651
|
+
end
|
652
|
+
|
653
|
+
def screen_captures_of_visual_processes(root_unix_pid)
|
654
|
+
sleep 8
|
655
|
+
|
656
|
+
unix_pids = all_unix_process_ids(root_unix_pid)
|
657
|
+
windows = unix_pids.map do |unix_pid|
|
658
|
+
get_window_position_and_size(unix_pid)
|
659
|
+
end.compact
|
660
|
+
|
661
|
+
windows.map do |position_and_size|
|
662
|
+
t = Tempfile.new(['screencapture-pid-', root_unix_pid.to_s, '.png'])
|
663
|
+
`screencapture -R #{position_and_size.join(',')} #{t.path}`
|
664
|
+
|
665
|
+
gyazo = Gyazo::Client.new access_token: 'b2893f18deff437b3abd45b6e4413e255fa563d8bd00d360429c37fe1aee560f'
|
666
|
+
res = gyazo.upload imagefile: t.path
|
667
|
+
res[:url]
|
668
|
+
end
|
669
|
+
end
|
670
|
+
|
671
|
+
def current_repo_dir
|
672
|
+
File.expand_path("~/gam-git-repos/#{@currently_selected_project}")
|
673
|
+
end
|
674
|
+
|
675
|
+
def currently_selected_project_exists_locally?
|
676
|
+
system("stat #{current_repo_dir}")
|
677
|
+
end
|
678
|
+
|
679
|
+
def ten_most_pushed_to_github_repos
|
680
|
+
output = `curl https://api.github.com/users/LemonAndroid/repos`
|
681
|
+
|
682
|
+
processed_output = JSON
|
683
|
+
.parse(output)
|
684
|
+
.sort_by do |project|
|
685
|
+
Date.parse(project["pushed_at"])
|
686
|
+
end
|
687
|
+
.last(10)
|
688
|
+
.map do |project|
|
689
|
+
project["full_name"]
|
690
|
+
end
|
691
|
+
|
692
|
+
space_2_unicode_array(processed_output)
|
693
|
+
end
|
694
|
+
|
695
|
+
def space_2_unicode_array(texts)
|
696
|
+
texts.map { |text| space_2_unicode(text) }
|
697
|
+
end
|
698
|
+
|
699
|
+
def space_2_unicode(text)
|
700
|
+
text.gsub(/\s/, "\u2000")
|
701
|
+
end
|
702
|
+
end
|
703
|
+
|
704
|
+
begin
|
705
|
+
bot = GitterDumbDevBot.new
|
706
|
+
|
707
|
+
bot.load()
|
708
|
+
|
709
|
+
# Thread.new do
|
710
|
+
# bot.start()
|
711
|
+
# end
|
712
|
+
|
713
|
+
get '/' do
|
714
|
+
bot.on_message(params[:message])
|
715
|
+
end
|
716
|
+
ensure
|
717
|
+
bot.dump()
|
718
|
+
end
|