fbomb 1.0.0 → 2.0.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 +15 -0
- data/Gemfile +31 -0
- data/Gemfile.lock +93 -0
- data/README.md +130 -0
- data/Rakefile +41 -9
- data/bin/fbomb +226 -31
- data/fbomb.gemspec +51 -8
- data/images/planet/1dEzGbz.jpg +0 -0
- data/images/planet/3aASzbv.jpg +0 -0
- data/images/planet/BCfEwgl.jpg +0 -0
- data/images/planet/EPbgqjy.jpg +0 -0
- data/images/planet/FoiDgwc.jpg +0 -0
- data/images/planet/HJiUPV2.jpg +0 -0
- data/images/planet/KOcvGjw.jpg +0 -0
- data/images/planet/L5n5lPK.jpg +0 -0
- data/images/planet/MaGKipv.jpg +0 -0
- data/images/planet/QVRALtz.jpg +0 -0
- data/images/planet/W3fWkTZ.jpg +0 -0
- data/images/planet/about.md +1 -0
- data/images/planet/nWqdkF7.jpg +0 -0
- data/images/planet/w41sv1T.jpg +0 -0
- data/images/planet/xySa4GD.jpg +0 -0
- data/images/planet/yzw8pOQ.jpg +0 -0
- data/lib/fbomb.rb +99 -19
- data/lib/fbomb/campfire.rb +39 -11
- data/lib/fbomb/command.rb +52 -15
- data/lib/fbomb/commands/builtin.rb +720 -9
- data/lib/fbomb/commands/system.rb +52 -10
- data/lib/fbomb/flowdock.rb +307 -0
- data/lib/fbomb/util.rb +65 -0
- data/lib/fbomb/uuid.rb +312 -0
- data/notes/ara.txt +54 -0
- metadata +229 -113
- data/README +0 -20
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NDhkZDQ4ZGYyMGNkOWFhOTRiZmI0NjUyYzYxNWRhMjZlOTE1NjQzMA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MGIzOTkyM2NmM2EyZTZmOGIyYTA4MDZjNzQ2ZWYyNzZhODFjMmM5MA==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
OTI0MGQ2MWExNWY3ZGY5MmRhYTg2YTRiN2EwNDgzOTkzM2UxYzFiM2ZkMWQw
|
10
|
+
OTRkNzEwMzRjZjI1NjcxZTAwOGFkOWRhMDRmNGM2MjU5NTczYjhhOTE5Yzk5
|
11
|
+
YzJiNTlkNTg3MGI4MzdiODE3NzNlNGNlNDU0ZTlmZGM4NjI1MjI=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MTQ2NjM0MTI0Yjg5NzFmMmIyNTliMDYwNWU1MDRiZTEwYTM0NTUxNWFmNWY4
|
14
|
+
M2MwMGMzNDliOWY4YTQ5YzU5OGUwNmI4NDM3N2UzMmZlOTkzZTg1YTIwZjQx
|
15
|
+
MzI3YmY2ZWQzODVhYjQ3NWIzZGE1NDZkMGVlYzVkOGI1ODkwZjc=
|
data/Gemfile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
|
4
|
+
gem(*["flowdock", ">= 0.4.0"])
|
5
|
+
|
6
|
+
gem(*["eventmachine", ">= 1.0.3"])
|
7
|
+
|
8
|
+
gem(*["em-http-request", ">= 1.1.2"])
|
9
|
+
|
10
|
+
gem(*["json", ">= 1.8.1"])
|
11
|
+
|
12
|
+
gem(*["coerce", ">= 0.0.6"])
|
13
|
+
|
14
|
+
gem(*["fukung", ">= 1.1.0"])
|
15
|
+
|
16
|
+
gem(*["main", ">= 4.7.6"])
|
17
|
+
|
18
|
+
gem(*["nokogiri", ">= 1.5.0"])
|
19
|
+
|
20
|
+
gem(*["google-search", ">= 1.0.2"])
|
21
|
+
|
22
|
+
gem(*["unidecode", ">= 1.0.0"])
|
23
|
+
|
24
|
+
gem(*["systemu", ">= 2.3.0"])
|
25
|
+
|
26
|
+
gem(*["pry", ">= 0.9.6.2"])
|
27
|
+
|
28
|
+
gem(*["mechanize", ">= 2.7.3"])
|
29
|
+
|
30
|
+
gem(*["mime-types", ">= 1.16"])
|
31
|
+
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
addressable (2.3.6)
|
5
|
+
arrayfields (4.9.2)
|
6
|
+
chronic (0.10.2)
|
7
|
+
coderay (1.1.0)
|
8
|
+
coerce (0.0.6)
|
9
|
+
chronic (>= 0.6.2)
|
10
|
+
cookiejar (0.3.2)
|
11
|
+
domain_name (0.5.18)
|
12
|
+
unf (>= 0.0.5, < 1.0.0)
|
13
|
+
em-http-request (1.1.2)
|
14
|
+
addressable (>= 2.3.4)
|
15
|
+
cookiejar
|
16
|
+
em-socksify (>= 0.3)
|
17
|
+
eventmachine (>= 1.0.3)
|
18
|
+
http_parser.rb (>= 0.6.0)
|
19
|
+
em-socksify (0.3.0)
|
20
|
+
eventmachine (>= 1.0.0.beta.4)
|
21
|
+
eventmachine (1.0.3)
|
22
|
+
fattr (2.2.2)
|
23
|
+
flowdock (0.4.0)
|
24
|
+
httparty (~> 0.7)
|
25
|
+
multi_json
|
26
|
+
fukung (1.1.0)
|
27
|
+
launchy
|
28
|
+
google-search (1.0.3)
|
29
|
+
json
|
30
|
+
http-cookie (1.0.2)
|
31
|
+
domain_name (~> 0.5)
|
32
|
+
http_parser.rb (0.6.0)
|
33
|
+
httparty (0.13.1)
|
34
|
+
json (~> 1.8)
|
35
|
+
multi_xml (>= 0.5.2)
|
36
|
+
json (1.8.1)
|
37
|
+
launchy (2.4.2)
|
38
|
+
addressable (~> 2.3)
|
39
|
+
main (6.0.0)
|
40
|
+
arrayfields (>= 4.7.4)
|
41
|
+
chronic (>= 0.6.2)
|
42
|
+
fattr (>= 2.2.0)
|
43
|
+
map (>= 5.1.0)
|
44
|
+
map (6.5.3)
|
45
|
+
mechanize (2.7.3)
|
46
|
+
domain_name (~> 0.5, >= 0.5.1)
|
47
|
+
http-cookie (~> 1.0)
|
48
|
+
mime-types (~> 2.0)
|
49
|
+
net-http-digest_auth (~> 1.1, >= 1.1.1)
|
50
|
+
net-http-persistent (~> 2.5, >= 2.5.2)
|
51
|
+
nokogiri (~> 1.4)
|
52
|
+
ntlm-http (~> 0.1, >= 0.1.1)
|
53
|
+
webrobots (>= 0.0.9, < 0.2)
|
54
|
+
method_source (0.8.2)
|
55
|
+
mime-types (2.2)
|
56
|
+
mini_portile (0.5.3)
|
57
|
+
multi_json (1.10.0)
|
58
|
+
multi_xml (0.5.5)
|
59
|
+
net-http-digest_auth (1.4)
|
60
|
+
net-http-persistent (2.9.4)
|
61
|
+
nokogiri (1.6.1)
|
62
|
+
mini_portile (~> 0.5.0)
|
63
|
+
ntlm-http (0.1.1)
|
64
|
+
pry (0.9.12.6)
|
65
|
+
coderay (~> 1.0)
|
66
|
+
method_source (~> 0.8)
|
67
|
+
slop (~> 3.4)
|
68
|
+
slop (3.5.0)
|
69
|
+
systemu (2.6.4)
|
70
|
+
unf (0.1.4)
|
71
|
+
unf_ext
|
72
|
+
unf_ext (0.0.6)
|
73
|
+
unidecode (1.0.0)
|
74
|
+
webrobots (0.1.1)
|
75
|
+
|
76
|
+
PLATFORMS
|
77
|
+
ruby
|
78
|
+
|
79
|
+
DEPENDENCIES
|
80
|
+
coerce (>= 0.0.6)
|
81
|
+
em-http-request (>= 1.1.2)
|
82
|
+
eventmachine (>= 1.0.3)
|
83
|
+
flowdock (>= 0.4.0)
|
84
|
+
fukung (>= 1.1.0)
|
85
|
+
google-search (>= 1.0.2)
|
86
|
+
json (>= 1.8.1)
|
87
|
+
main (>= 4.7.6)
|
88
|
+
mechanize (>= 2.7.3)
|
89
|
+
mime-types (>= 1.16)
|
90
|
+
nokogiri (>= 1.5.0)
|
91
|
+
pry (>= 0.9.6.2)
|
92
|
+
systemu (>= 2.3.0)
|
93
|
+
unidecode (>= 1.0.0)
|
data/README.md
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
NAME
|
2
|
+
====
|
3
|
+
fbomb
|
4
|
+
|
5
|
+
SYNOPSIS
|
6
|
+
========
|
7
|
+
fbomb is the dangerous, easily customizable flowdock robot
|
8
|
+
|
9
|
+
TL;DR;
|
10
|
+
======
|
11
|
+
```bash
|
12
|
+
|
13
|
+
~> ./bin/fbomb setup
|
14
|
+
|
15
|
+
# edit your config
|
16
|
+
|
17
|
+
~> ./bin/fbomb start
|
18
|
+
|
19
|
+
# now a daemon is running in your flowz, try typing .help in the flow!
|
20
|
+
|
21
|
+
```
|
22
|
+
|
23
|
+
DESCRIPTION
|
24
|
+
===========
|
25
|
+
|
26
|
+
after setting the appropriate api tokens and config you'll have a robot
|
27
|
+
running in your flow that does all sorts of irritating stuff. to find out
|
28
|
+
what he does just type _.help_
|
29
|
+
|
30
|
+

|
31
|
+
|
32
|
+
there are two sets of built-in commands, system commands
|
33
|
+
|
34
|
+
https://github.com/ahoward/fbomb/blob/master/lib/fbomb/commands/system.rb
|
35
|
+
|
36
|
+
and a bunch of canned ones, most of which actually work ;-)
|
37
|
+
|
38
|
+
https://github.com/ahoward/fbomb/blob/master/lib/fbomb/commands/builtin.rb
|
39
|
+
|
40
|
+
the dsl for adding commands is super, super simple, you just
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
|
44
|
+
command(:my_command_name) do
|
45
|
+
call do |*args|
|
46
|
+
|
47
|
+
speak 'stuff'
|
48
|
+
|
49
|
+
paste 'stuff'
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
```
|
55
|
+
|
56
|
+
commands can be loaded from a file by putting something like this in your
|
57
|
+
config
|
58
|
+
|
59
|
+
```yaml
|
60
|
+
|
61
|
+
commands:
|
62
|
+
|
63
|
+
- system
|
64
|
+
- builtin
|
65
|
+
- ~/.fbomb/commands.rb
|
66
|
+
|
67
|
+
```
|
68
|
+
|
69
|
+
the interpolation of these paths is the only sane one
|
70
|
+
|
71
|
+
- realtive to the libdir of the fbomb gem if bare (not starting with ~ or ./ or /)
|
72
|
+
- otherwise an expanded path in the fs
|
73
|
+
- otherwise a url (yep, it evaluates code from a url - sweet huh?)
|
74
|
+
|
75
|
+
in the config above you'll notice the '~/.fbomb' path. by default fbomb keeps
|
76
|
+
all it's state in '~/.fbomb' including it's logs, pid files, config, etc.
|
77
|
+
this is therefore a great place to keep commands on your server. if you gem
|
78
|
+
install fbomb it's the dot directory, and nothing more, you'd probably want in
|
79
|
+
your repo.
|
80
|
+
|
81
|
+
in dojo4's we have command to list our people and txt message them. here is a
|
82
|
+
litle example of that custom command(s)
|
83
|
+
|
84
|
+
https://gist.github.com/ahoward/d31fc57067a15c0387bf
|
85
|
+
|
86
|
+
the fbomb tool can be installed with
|
87
|
+
|
88
|
+
```bash
|
89
|
+
|
90
|
+
~> gem install fbomb
|
91
|
+
|
92
|
+
```
|
93
|
+
|
94
|
+
and the cli is super well behaved, like all main.rb scripts
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
TIPS
|
99
|
+
====
|
100
|
+
|
101
|
+
```bash
|
102
|
+
|
103
|
+
# run in debug mode to emulate via stdin/stdout based controls
|
104
|
+
|
105
|
+
~> FBOMB_DEBUG=42 fbomb run
|
106
|
+
|
107
|
+
```
|
108
|
+
|
109
|
+
```bash
|
110
|
+
|
111
|
+
# start an iteractive shell in a live flow!
|
112
|
+
|
113
|
+
~> fbomb shell
|
114
|
+
|
115
|
+
```
|
116
|
+
|
117
|
+
```cron
|
118
|
+
|
119
|
+
# use cron to drop shit in your flow
|
120
|
+
|
121
|
+
* 12 * * * * fbomb speak 'time for stand-up bitches!' --tag stand-up
|
122
|
+
|
123
|
+
```
|
124
|
+
|
125
|
+
|
126
|
+
DOCS
|
127
|
+
====
|
128
|
+
RFTC @
|
129
|
+
- https://github.com/ahoward/fbomb/tree/master/lib
|
130
|
+
- https://github.com/ahoward/fbomb/blob/master/bin/fbomb
|
data/Rakefile
CHANGED
@@ -3,6 +3,9 @@ This.author = "Ara T. Howard"
|
|
3
3
|
This.email = "ara.t.howard@gmail.com"
|
4
4
|
This.homepage = "https://github.com/ahoward/#{ This.lib }"
|
5
5
|
|
6
|
+
task :license do
|
7
|
+
open('LICENSE', 'w'){|fd| fd.puts "Ruby"}
|
8
|
+
end
|
6
9
|
|
7
10
|
task :default do
|
8
11
|
puts((Rake::Task.tasks.map{|task| task.name.gsub(/::/,':')} - ['default']).sort)
|
@@ -29,7 +32,7 @@ def run_tests!(which = nil)
|
|
29
32
|
|
30
33
|
test_rbs.each_with_index do |test_rb, index|
|
31
34
|
testno = index + 1
|
32
|
-
command = "#{ This.ruby } -I ./lib -I ./test/lib #{ test_rb }"
|
35
|
+
command = "#{ This.ruby } -w -I ./lib -I ./test/lib #{ test_rb }"
|
33
36
|
|
34
37
|
puts
|
35
38
|
say(div, :color => :cyan, :bold => true)
|
@@ -60,7 +63,7 @@ end
|
|
60
63
|
task :gemspec do
|
61
64
|
ignore_extensions = ['git', 'svn', 'tmp', /sw./, 'bak', 'gem']
|
62
65
|
ignore_directories = ['pkg']
|
63
|
-
ignore_files = ['test/log'
|
66
|
+
ignore_files = ['test/log']
|
64
67
|
|
65
68
|
shiteless =
|
66
69
|
lambda do |list|
|
@@ -87,9 +90,10 @@ task :gemspec do
|
|
87
90
|
files = shiteless[Dir::glob("**/**")]
|
88
91
|
executables = shiteless[Dir::glob("bin/*")].map{|exe| File.basename(exe)}
|
89
92
|
#has_rdoc = true #File.exist?('doc')
|
90
|
-
test_files =
|
93
|
+
test_files = "test/#{ lib }.rb" if File.file?("test/#{ lib }.rb")
|
91
94
|
summary = object.respond_to?(:summary) ? object.summary : "summary: #{ lib } kicks the ass"
|
92
95
|
description = object.respond_to?(:description) ? object.description : "description: #{ lib } kicks the ass"
|
96
|
+
license = object.respond_to?(:license) ? object.license : "Ruby"
|
93
97
|
|
94
98
|
if This.extensions.nil?
|
95
99
|
This.extensions = []
|
@@ -100,7 +104,6 @@ task :gemspec do
|
|
100
104
|
end
|
101
105
|
extensions = [extensions].flatten.compact
|
102
106
|
|
103
|
-
# TODO
|
104
107
|
if This.dependencies.nil?
|
105
108
|
dependencies = []
|
106
109
|
else
|
@@ -127,6 +130,7 @@ task :gemspec do
|
|
127
130
|
spec.platform = Gem::Platform::RUBY
|
128
131
|
spec.summary = <%= lib.inspect %>
|
129
132
|
spec.description = <%= description.inspect %>
|
133
|
+
spec.license = <%= license.inspect %>
|
130
134
|
|
131
135
|
spec.files =\n<%= files.sort.pretty_inspect %>
|
132
136
|
spec.executables = <%= executables.inspect %>
|
@@ -167,6 +171,36 @@ task :gem => [:clean, :gemspec] do
|
|
167
171
|
This.gem = File.join(This.pkgdir, File.basename(gem))
|
168
172
|
end
|
169
173
|
|
174
|
+
task :gemfile do
|
175
|
+
if This.dependencies.nil?
|
176
|
+
dependencies = []
|
177
|
+
else
|
178
|
+
case This.dependencies
|
179
|
+
when Hash
|
180
|
+
dependencies = This.dependencies.values
|
181
|
+
when Array
|
182
|
+
dependencies = This.dependencies
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
template =
|
187
|
+
if test(?e, 'gemfile.erb')
|
188
|
+
Template{ IO.read('gemfile.erb') }
|
189
|
+
else
|
190
|
+
Template {
|
191
|
+
<<-__
|
192
|
+
source 'https://rubygems.org'
|
193
|
+
|
194
|
+
<% dependencies.each do |lib_version| %>
|
195
|
+
gem(*<%= Array(lib_version).flatten.inspect %>)
|
196
|
+
<% end %>
|
197
|
+
__
|
198
|
+
}
|
199
|
+
end
|
200
|
+
|
201
|
+
IO.binwrite('Gemfile', template)
|
202
|
+
end
|
203
|
+
|
170
204
|
task :readme do
|
171
205
|
samples = ''
|
172
206
|
prompt = '~ > '
|
@@ -188,8 +222,8 @@ task :readme do
|
|
188
222
|
end
|
189
223
|
|
190
224
|
template =
|
191
|
-
if test(?e, '
|
192
|
-
Template{ IO.read('
|
225
|
+
if test(?e, 'README.erb')
|
226
|
+
Template{ IO.read('README.erb') }
|
193
227
|
else
|
194
228
|
Template {
|
195
229
|
<<-__
|
@@ -275,9 +309,7 @@ BEGIN {
|
|
275
309
|
unless version
|
276
310
|
require "./lib/#{ This.lib }"
|
277
311
|
This.name = lib.capitalize
|
278
|
-
|
279
|
-
abort("no module exported for #{ This.name }") unless const
|
280
|
-
This.object = eval(const)
|
312
|
+
This.object = eval(This.name)
|
281
313
|
version = This.object.send(:version)
|
282
314
|
end
|
283
315
|
This.version = version
|
data/bin/fbomb
CHANGED
@@ -4,76 +4,230 @@ Main {
|
|
4
4
|
##
|
5
5
|
#
|
6
6
|
edit_config_file! <<-__
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
flowdock:
|
8
|
+
organizaion: YOUR_ORGANIZATION
|
9
|
+
flow: YOUR_FLOW
|
10
|
+
token: YOUR_PERSONAL_AS_OPPOSED_TO_FLOW_BASED_TOKEN
|
11
|
+
|
12
|
+
flowdock:
|
13
|
+
organizaion: YOUR_ORGANIZATION
|
14
|
+
flow: YOUR_FLOW
|
15
|
+
token: TOP_LEVEL_TOKEN_FOUND_HERE # http://cl.ly/VU6j/Screen%20Shot%202014-05-12%20at%2012.36.39%20PM.png
|
16
|
+
|
17
|
+
options:
|
18
|
+
client:
|
19
|
+
api_token: FLOW_LEVEL_API_TOKEN_FOUND_HERE # http://cl.ly/VTKt/Screen%20Shot%202014-05-12%20at%2012.37.35%20PM.png
|
20
|
+
source: arbitrary-application-name-without-spaces
|
21
|
+
external_user_name: arbitrary-roboto-name-without-spaces
|
22
|
+
from:
|
23
|
+
name: Robot First Last Name
|
24
|
+
email: robot's email (must have access!)
|
11
25
|
|
12
26
|
commands:
|
13
27
|
- system
|
14
28
|
- builtin
|
15
29
|
__
|
16
30
|
|
31
|
+
|
32
|
+
option('--force', '-f')
|
33
|
+
|
17
34
|
##
|
18
35
|
#
|
19
36
|
def run
|
20
37
|
load_commands!
|
38
|
+
load_flow!
|
39
|
+
run_command! if argv.first =~ %r|^#{ Regexp.escape(FBomb.leader) }| unless argv.empty?
|
21
40
|
end
|
22
41
|
|
23
42
|
def load_commands!
|
24
|
-
|
25
|
-
|
43
|
+
FBomb::Command.load(config[:commands])
|
44
|
+
end
|
45
|
+
|
46
|
+
def load_flow!
|
47
|
+
organizaion, flow, token =
|
48
|
+
Map.for(config[:flowdock]).slice(:organizaion, :flow, :token).values
|
49
|
+
|
50
|
+
options = config.get(:flowdock, :options)
|
51
|
+
|
52
|
+
@flowdock = FBomb::Flowdock.new(organizaion, flow, token, options)
|
53
|
+
|
54
|
+
@flow = @flowdock.flow
|
55
|
+
|
56
|
+
FBomb::Command.flow = @flow
|
26
57
|
end
|
27
58
|
|
28
59
|
def run_command!
|
29
|
-
path, args = argv
|
60
|
+
path, *args = argv
|
30
61
|
commands = FBomb::Command.table
|
31
62
|
command = commands[path] or abort("no such command #{ path }")
|
63
|
+
#FBomb::Command.flow = nil unless params['force'].given?
|
64
|
+
stdin = read_standard_input()
|
65
|
+
(args << stdin.chomp) if stdin
|
32
66
|
command.call(*args)
|
33
67
|
exit
|
34
68
|
end
|
35
69
|
|
70
|
+
def read_standard_input
|
71
|
+
require 'io/wait'
|
72
|
+
input = nil
|
73
|
+
return input unless STDIN.ready?
|
74
|
+
loop do
|
75
|
+
begin
|
76
|
+
buf = STDIN.readpartial(8192)
|
77
|
+
input ||= ''
|
78
|
+
input << buf
|
79
|
+
rescue EOFError
|
80
|
+
break
|
81
|
+
end
|
82
|
+
end
|
83
|
+
input
|
84
|
+
end
|
85
|
+
|
36
86
|
##
|
37
87
|
#
|
88
|
+
mode(:shell) do
|
89
|
+
def run
|
90
|
+
load_commands!
|
91
|
+
load_flow!
|
92
|
+
|
93
|
+
require 'irb'
|
94
|
+
|
95
|
+
$FUCKING_HACK = IRB.method(:load_modules)
|
96
|
+
$FLOWDOCK = @flowdock
|
97
|
+
|
98
|
+
def IRB.load_modules
|
99
|
+
$FUCKING_HACK.call()
|
100
|
+
|
101
|
+
prompt = "#{ $FLOWDOCK.organization }/#{ $FLOWDOCK.flow }"
|
102
|
+
|
103
|
+
IRB.conf[:PROMPT][:RO] = {
|
104
|
+
:PROMPT_I=>"#{ prompt }:%03n:%i> ",
|
105
|
+
:PROMPT_N=>"#{ prompt }:%03n:%i> ",
|
106
|
+
:PROMPT_S=>"#{ prompt }:%03n:%i%l ",
|
107
|
+
:PROMPT_C=>"#{ prompt }:%03n:%i* ",
|
108
|
+
:RETURN=>"=> %s\n"
|
109
|
+
}
|
110
|
+
|
111
|
+
IRB.conf[:PROMPT_MODE] = :RO
|
112
|
+
IRB.conf[:AUTO_INDENT] = true
|
113
|
+
end
|
114
|
+
|
115
|
+
Kernel.module_eval do
|
116
|
+
def flowdock
|
117
|
+
$FLOWDOCK
|
118
|
+
end
|
119
|
+
|
120
|
+
def flow
|
121
|
+
flowdock.flow
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
ARGV.clear
|
126
|
+
|
127
|
+
::IRB.start
|
128
|
+
end
|
129
|
+
|
130
|
+
def method_missing(method, *args, &block)
|
131
|
+
ivar = "@#{ method }"
|
132
|
+
super unless instance_variable_defined?(ivar)
|
133
|
+
instance_variable_get(ivar)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
##
|
138
|
+
#
|
139
|
+
mode(:stop) do
|
140
|
+
def run
|
141
|
+
pid = IO.read(File.join(dotdir, 'pid')).to_i
|
142
|
+
Process.kill(-9, pid)
|
143
|
+
rescue
|
144
|
+
nil
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
mode(:pid) do
|
149
|
+
def run
|
150
|
+
pid = IO.read(File.join(dotdir, 'pid')).to_i
|
151
|
+
puts pid
|
152
|
+
rescue
|
153
|
+
nil
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
mode(:speak) do
|
158
|
+
option('--tag=tag', '-t')
|
159
|
+
|
160
|
+
def run
|
161
|
+
speak!
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
mode(:paste) do
|
166
|
+
option('--tag=tag', '-t')
|
167
|
+
|
168
|
+
def run
|
169
|
+
paste!
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
38
173
|
mode(:run) do
|
174
|
+
option('--daemon', '-d')
|
175
|
+
|
39
176
|
def run
|
177
|
+
if params['daemon'].given?
|
178
|
+
DATA.flock(File::LOCK_EX|File::LOCK_NB) or exit!(42)
|
179
|
+
Dir.chdir('/tmp')
|
180
|
+
exit! if fork
|
181
|
+
exit! if fork
|
182
|
+
open(File.join(dotdir, 'pid'), 'w'){|fd| fd.write($$)}
|
183
|
+
open('/dev/null', 'w+') do |fd|
|
184
|
+
STDOUT.reopen(fd)
|
185
|
+
STDERR.reopen(fd)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
40
189
|
load_commands!
|
190
|
+
load_flow!
|
41
191
|
drop_fbombs!
|
42
192
|
end
|
43
193
|
|
44
194
|
def drop_fbombs!
|
45
|
-
|
46
|
-
campfire = FBomb::Campfire.new(domain, :token => token)
|
47
|
-
room = campfire.room_for(room)
|
48
|
-
room.join
|
49
|
-
at_exit{ room.leave }
|
50
|
-
room.speak("fbomb in da house...")
|
51
|
-
id = room.id
|
195
|
+
at_exit{ @flow.leave }
|
52
196
|
|
53
|
-
|
54
|
-
url = URI.parse("http://#{ token }:x@streaming.campfirenow.com//room/#{ id }/live.json")
|
197
|
+
@flow.speak("fbomb (beta) in da house...")
|
55
198
|
|
56
199
|
trap('INT'){ exit }
|
57
200
|
|
201
|
+
=begin
|
202
|
+
{"event"=>"activity.user", "tags"=>[], "uuid"=>nil, "persist"=>false, "id"=>194342, "flow"=>"c6dbc029-2173-4fb6-a423-32293c373106", "content"=>{"last_activity"=>1399656686378}, "sent"=>1399657205286, "app"=>nil, "attachments"=>[], "user"=>"76002"}
|
203
|
+
=end
|
58
204
|
loop do
|
59
205
|
logging_errors do
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
206
|
+
@flow.stream do |flow|
|
207
|
+
#p :flow => flow
|
208
|
+
next unless flow[:event] == 'message'
|
209
|
+
|
210
|
+
content = flow[:content].to_s
|
211
|
+
tokens = content.scan(%r/[^\s]+/)
|
212
|
+
arg, *args = tokens
|
213
|
+
|
214
|
+
if arg =~ %r|^\s*#{ Regexp.escape(FBomb.leader) }|
|
215
|
+
key = arg.strip
|
216
|
+
command = FBomb::Command.table[key]
|
217
|
+
|
218
|
+
if command
|
219
|
+
user = @flow.user_for(flow[:user])
|
220
|
+
#p :user => user
|
221
|
+
FBomb::Command.user = user
|
222
|
+
begin
|
223
|
+
logging_errors do
|
224
|
+
logger.info("#{ key } #{ args.join(' ') }")
|
225
|
+
command.call(*args)
|
75
226
|
end
|
227
|
+
ensure
|
228
|
+
FBomb::Command.user = nil
|
76
229
|
end
|
230
|
+
end
|
77
231
|
end
|
78
232
|
end
|
79
233
|
|
@@ -102,6 +256,34 @@ Main {
|
|
102
256
|
logger.error("#{ m }(#{ c })\n#{ b }")
|
103
257
|
end
|
104
258
|
end
|
259
|
+
|
260
|
+
def speak_or_paste!(which)
|
261
|
+
load_commands!
|
262
|
+
load_flow!
|
263
|
+
|
264
|
+
tags =
|
265
|
+
if params['tag'] and params['tag'].given?
|
266
|
+
Coerce.list_of_strings(params['tag'].value)
|
267
|
+
else
|
268
|
+
[]
|
269
|
+
end
|
270
|
+
|
271
|
+
content = ARGV.join(' ')
|
272
|
+
|
273
|
+
if content.strip == '-'
|
274
|
+
content = STDIN.read
|
275
|
+
end
|
276
|
+
|
277
|
+
@flow.send(which, content, :tags => tags)
|
278
|
+
end
|
279
|
+
|
280
|
+
def speak!
|
281
|
+
speak_or_paste!(:speak)
|
282
|
+
end
|
283
|
+
|
284
|
+
def paste!
|
285
|
+
speak_or_paste!(:paste)
|
286
|
+
end
|
105
287
|
}
|
106
288
|
|
107
289
|
BEGIN{
|
@@ -110,4 +292,17 @@ BEGIN{
|
|
110
292
|
libdir = File.join(srcdir, 'lib')
|
111
293
|
lib = File.join(libdir, 'fbomb.rb')
|
112
294
|
require(test(?s, lib) ? lib : 'fbomb')
|
295
|
+
|
296
|
+
|
297
|
+
class Map
|
298
|
+
def slice(*keys)
|
299
|
+
keys = keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
|
300
|
+
hash = self.class.new
|
301
|
+
keys.each { |k| hash[k] = self[k] if has_key?(k) }
|
302
|
+
hash
|
303
|
+
end
|
304
|
+
end
|
113
305
|
}
|
306
|
+
|
307
|
+
|
308
|
+
__END__
|