jah 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +7 -0
- data/LICENSE +20 -0
- data/README.md +115 -0
- data/Rakefile +75 -0
- data/VERSION +1 -0
- data/bin/jah +9 -0
- data/jah.gemspec +89 -0
- data/lib/jah/agent.rb +128 -0
- data/lib/jah/agents/dump.rb +5 -0
- data/lib/jah/agents/post.rb +18 -0
- data/lib/jah/agents/xmpp.rb +194 -0
- data/lib/jah/cli.rb +124 -0
- data/lib/jah/collector.rb +12 -0
- data/lib/jah/collectors/cpu.rb +35 -0
- data/lib/jah/collectors/disk.rb +14 -0
- data/lib/jah/collectors/mem.rb +51 -0
- data/lib/jah/collectors/net.rb +27 -0
- data/lib/jah/collectors/prok.rb +88 -0
- data/lib/jah/collectors/services.rb +13 -0
- data/lib/jah/collectors/who.rb +20 -0
- data/lib/jah/command.rb +23 -0
- data/lib/jah/commands/admin.rb +40 -0
- data/lib/jah/commands/extra.rb +14 -0
- data/lib/jah/commands/pub.rb +34 -0
- data/lib/jah/commands/status.rb +61 -0
- data/lib/jah/god.rb +24 -0
- data/lib/jah/install.rb +336 -0
- data/lib/jah.rb +26 -0
- data/lib/jah.yaml.template +26 -0
- data/lib/locales/en_us.yml +2 -0
- data/lib/locales/pt_br.yml +2 -0
- data/lib/locales/pt_br_gostosa.yml +10 -0
- data/lib/locales/pt_br_mano.yml +10 -0
- data/lib/locales/pt_br_mineiro.yml +10 -0
- data/spec/console +12 -0
- data/spec/jah_spec.rb +7 -0
- data/spec/spec_helper.rb +9 -0
- metadata +123 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Marcos Piccinini
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
# ![Jah](http://fireho.com/system/jahlogo.png)
|
2
|
+
|
3
|
+
Talk to your machines. Like a god.
|
4
|
+
|
5
|
+
## Install
|
6
|
+
|
7
|
+
Just run it for the first time to create a config file.
|
8
|
+
Use `jah install` to force the wizard again.
|
9
|
+
|
10
|
+
Gems needed for XMPP mode:
|
11
|
+
|
12
|
+
* EventMachine (gem install eventmachine)
|
13
|
+
* Blather (gem install blather)
|
14
|
+
|
15
|
+
|
16
|
+
Jah will try to find a `jah.yaml` file on ~/.jah or /etc.
|
17
|
+
|
18
|
+
|
19
|
+
## Modes
|
20
|
+
|
21
|
+
### XMPP
|
22
|
+
|
23
|
+
Chat with your server with your favorite XMPP client (pidgin, adium..)
|
24
|
+
Receive reports and failures realtime!
|
25
|
+
Send commands and
|
26
|
+
|
27
|
+
|
28
|
+
### POST
|
29
|
+
|
30
|
+
The old school way. Set up a Jah Web Server, and give Jah it`s address.
|
31
|
+
Jah will periodically post info. You can send commands through SSH.
|
32
|
+
|
33
|
+
|
34
|
+
### DUMP
|
35
|
+
|
36
|
+
AkA: Security freak. Jah just writes to tmp/ or whatever a dump file,
|
37
|
+
Jah Web securely connects (scp) and downloads the data to parse.
|
38
|
+
|
39
|
+
|
40
|
+
## Use God?
|
41
|
+
|
42
|
+
|
43
|
+
## XMPP Bot
|
44
|
+
|
45
|
+
|
46
|
+
Execute sh commands:
|
47
|
+
|
48
|
+
pwd
|
49
|
+
$> /home/jah
|
50
|
+
|
51
|
+
|
52
|
+
Executing ruby statements:
|
53
|
+
|
54
|
+
! 2 + 2
|
55
|
+
=> 4
|
56
|
+
|
57
|
+
! def foo; "hi"; end
|
58
|
+
! foo
|
59
|
+
=> "hi"
|
60
|
+
|
61
|
+
|
62
|
+
Execute Jah commands:
|
63
|
+
|
64
|
+
cpu?
|
65
|
+
msweet: 0.14, 0.25, 0.14
|
66
|
+
|
67
|
+
mem?
|
68
|
+
msweet: 53%
|
69
|
+
|
70
|
+
net?
|
71
|
+
7 connections
|
72
|
+
[ips...]
|
73
|
+
|
74
|
+
ok?
|
75
|
+
[Personalized cool phrase...]
|
76
|
+
|
77
|
+
|
78
|
+
Group session:
|
79
|
+
|
80
|
+
me: ok?
|
81
|
+
msweet: I'm fine, thanks..
|
82
|
+
ssaint: Kinda busy right now..
|
83
|
+
naomi: I need you! Now!
|
84
|
+
|
85
|
+
|
86
|
+
Execute God statements:
|
87
|
+
|
88
|
+
Start, stop, restart, monitor and unmonitor words on the beginning
|
89
|
+
of a phrase will make Jah add a "god" on the front of it, making it
|
90
|
+
trivial to work with your services:
|
91
|
+
|
92
|
+
|
93
|
+
start nginx
|
94
|
+
restart nanites
|
95
|
+
unmonitor postgresql
|
96
|
+
|
97
|
+
|
98
|
+
More to come...
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
## Note on Patches/Pull Requests
|
103
|
+
|
104
|
+
* Fork the project.
|
105
|
+
* Make your feature addition or bug fix.
|
106
|
+
* Add tests for it. This is important so I don't break it in a
|
107
|
+
future version unintentionally.
|
108
|
+
* Commit, do not mess with rakefile, version, or history.
|
109
|
+
(if you want to have your own version, that is fine but
|
110
|
+
bump version in a commit by itself I can ignore when I pull)
|
111
|
+
* Send me a pull request. Bonus points for topic branches.
|
112
|
+
|
113
|
+
## Copyright
|
114
|
+
|
115
|
+
Copyright (c) 2009 Marcos Piccinini. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "jah"
|
8
|
+
gem.summary = "be omnipresent..."
|
9
|
+
gem.description = "talk to your machines"
|
10
|
+
gem.email = "x@nofxx.com"
|
11
|
+
gem.homepage = "http://github.com/nofxx/jah"
|
12
|
+
gem.authors = ["Marcos Piccinini"]
|
13
|
+
gem.add_dependency "blather"
|
14
|
+
gem.add_dependency "i18n"
|
15
|
+
gem.add_development_dependency "rspec"
|
16
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
17
|
+
end
|
18
|
+
rescue LoadError
|
19
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'spec/rake/spectask'
|
23
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
24
|
+
spec.libs << 'lib' << 'spec'
|
25
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
26
|
+
end
|
27
|
+
|
28
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
29
|
+
spec.libs << 'lib' << 'spec'
|
30
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
31
|
+
spec.rcov = true
|
32
|
+
end
|
33
|
+
|
34
|
+
task :spec => :check_dependencies
|
35
|
+
task :default => :spec
|
36
|
+
|
37
|
+
begin
|
38
|
+
require 'reek/rake_task'
|
39
|
+
Reek::RakeTask.new do |t|
|
40
|
+
t.fail_on_error = true
|
41
|
+
t.verbose = false
|
42
|
+
t.source_files = 'lib/**/*.rb'
|
43
|
+
end
|
44
|
+
rescue LoadError
|
45
|
+
task :reek do
|
46
|
+
abort "Reek is not available. In order to run reek, you must: sudo gem install reek"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
begin
|
51
|
+
require 'roodi'
|
52
|
+
require 'roodi_task'
|
53
|
+
RoodiTask.new do |t|
|
54
|
+
t.verbose = false
|
55
|
+
end
|
56
|
+
rescue LoadError
|
57
|
+
task :roodi do
|
58
|
+
abort "Roodi is not available. In order to run roodi, you must: sudo gem install roodi"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
require 'rake/rdoctask'
|
64
|
+
Rake::RDocTask.new do |rdoc|
|
65
|
+
if File.exist?('VERSION')
|
66
|
+
version = File.read('VERSION')
|
67
|
+
else
|
68
|
+
version = ""
|
69
|
+
end
|
70
|
+
|
71
|
+
rdoc.rdoc_dir = 'rdoc'
|
72
|
+
rdoc.title = "jah #{version}"
|
73
|
+
rdoc.rdoc_files.include('README*')
|
74
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
75
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.3
|
data/bin/jah
ADDED
data/jah.gemspec
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{jah}
|
8
|
+
s.version = "0.0.3"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Marcos Piccinini"]
|
12
|
+
s.date = %q{2009-09-29}
|
13
|
+
s.default_executable = %q{jah}
|
14
|
+
s.description = %q{talk to your machines}
|
15
|
+
s.email = %q{x@nofxx.com}
|
16
|
+
s.executables = ["jah"]
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"LICENSE",
|
19
|
+
"README.md"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
".document",
|
23
|
+
".gitignore",
|
24
|
+
"LICENSE",
|
25
|
+
"README.md",
|
26
|
+
"Rakefile",
|
27
|
+
"VERSION",
|
28
|
+
"bin/jah",
|
29
|
+
"jah.gemspec",
|
30
|
+
"lib/jah.rb",
|
31
|
+
"lib/jah.yaml.template",
|
32
|
+
"lib/jah/agent.rb",
|
33
|
+
"lib/jah/agents/dump.rb",
|
34
|
+
"lib/jah/agents/post.rb",
|
35
|
+
"lib/jah/agents/xmpp.rb",
|
36
|
+
"lib/jah/cli.rb",
|
37
|
+
"lib/jah/collector.rb",
|
38
|
+
"lib/jah/collectors/cpu.rb",
|
39
|
+
"lib/jah/collectors/disk.rb",
|
40
|
+
"lib/jah/collectors/mem.rb",
|
41
|
+
"lib/jah/collectors/net.rb",
|
42
|
+
"lib/jah/collectors/prok.rb",
|
43
|
+
"lib/jah/collectors/services.rb",
|
44
|
+
"lib/jah/collectors/who.rb",
|
45
|
+
"lib/jah/command.rb",
|
46
|
+
"lib/jah/commands/admin.rb",
|
47
|
+
"lib/jah/commands/extra.rb",
|
48
|
+
"lib/jah/commands/pub.rb",
|
49
|
+
"lib/jah/commands/status.rb",
|
50
|
+
"lib/jah/god.rb",
|
51
|
+
"lib/jah/install.rb",
|
52
|
+
"lib/locales/en_us.yml",
|
53
|
+
"lib/locales/pt_br.yml",
|
54
|
+
"lib/locales/pt_br_gostosa.yml",
|
55
|
+
"lib/locales/pt_br_mano.yml",
|
56
|
+
"lib/locales/pt_br_mineiro.yml",
|
57
|
+
"spec/console",
|
58
|
+
"spec/jah_spec.rb",
|
59
|
+
"spec/spec_helper.rb"
|
60
|
+
]
|
61
|
+
s.homepage = %q{http://github.com/nofxx/jah}
|
62
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
63
|
+
s.require_paths = ["lib"]
|
64
|
+
s.rubygems_version = %q{1.3.5}
|
65
|
+
s.summary = %q{be omnipresent...}
|
66
|
+
s.test_files = [
|
67
|
+
"spec/jah_spec.rb",
|
68
|
+
"spec/spec_helper.rb"
|
69
|
+
]
|
70
|
+
|
71
|
+
if s.respond_to? :specification_version then
|
72
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
73
|
+
s.specification_version = 3
|
74
|
+
|
75
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
76
|
+
s.add_runtime_dependency(%q<blather>, [">= 0"])
|
77
|
+
s.add_runtime_dependency(%q<i18n>, [">= 0"])
|
78
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
79
|
+
else
|
80
|
+
s.add_dependency(%q<blather>, [">= 0"])
|
81
|
+
s.add_dependency(%q<i18n>, [">= 0"])
|
82
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
83
|
+
end
|
84
|
+
else
|
85
|
+
s.add_dependency(%q<blather>, [">= 0"])
|
86
|
+
s.add_dependency(%q<i18n>, [">= 0"])
|
87
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
88
|
+
end
|
89
|
+
end
|
data/lib/jah/agent.rb
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'net/https'
|
3
|
+
require 'net/http'
|
4
|
+
require 'zlib'
|
5
|
+
require 'stringio'
|
6
|
+
# require 'eventmachine'
|
7
|
+
|
8
|
+
module Jah
|
9
|
+
class Agent
|
10
|
+
PID_FILE = File.join("/tmp", "jah.pid")
|
11
|
+
autoload :XmppAgent, "jah/agents/xmpp"
|
12
|
+
autoload :PostAgent, "jah/agents/xmpp"
|
13
|
+
autoload :DumpAgent, "jah/agents/xmpp"
|
14
|
+
|
15
|
+
def initialize(options=nil)#, config)
|
16
|
+
if Jah.daemon?
|
17
|
+
puts "Jah starting in background.."
|
18
|
+
fork do
|
19
|
+
daemonize
|
20
|
+
run_agent_run
|
21
|
+
end
|
22
|
+
exit
|
23
|
+
end
|
24
|
+
run_agent_run
|
25
|
+
end
|
26
|
+
|
27
|
+
def pid_file
|
28
|
+
@pidfile ||= PID_FILE
|
29
|
+
end
|
30
|
+
|
31
|
+
def run_agent_run
|
32
|
+
case Jah.mode # @mode
|
33
|
+
when "xmpp" then XmppAgent.new.run
|
34
|
+
when "post" then PostAgent.new.run
|
35
|
+
else
|
36
|
+
DumpAgent.new
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.start
|
41
|
+
new
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.stop
|
45
|
+
if File.exists?(PID_FILE)
|
46
|
+
pid = File.read(PID_FILE)
|
47
|
+
puts "Stopping #{pid}"
|
48
|
+
`kill #{pid}`
|
49
|
+
else
|
50
|
+
puts "Jah not running..."
|
51
|
+
exit
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.restart
|
56
|
+
stop
|
57
|
+
start
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.install
|
61
|
+
Install.new
|
62
|
+
end
|
63
|
+
|
64
|
+
def daemonize
|
65
|
+
begin
|
66
|
+
File.open(pid_file, File::CREAT|File::EXCL|File::WRONLY) do |pid|
|
67
|
+
pid.puts $$
|
68
|
+
end
|
69
|
+
at_exit do
|
70
|
+
begin
|
71
|
+
File.unlink(pid_file)
|
72
|
+
rescue
|
73
|
+
Log.error "Unable to unlink pid file: #{$!.message}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
rescue
|
77
|
+
pid = File.read(pid_file).strip.to_i rescue "unknown"
|
78
|
+
running = true
|
79
|
+
begin
|
80
|
+
Process.kill(0, pid)
|
81
|
+
if stat = File.stat(pid_file)
|
82
|
+
if mtime = stat.mtime
|
83
|
+
if Time.now - mtime > 25 * 60 # assume process is hung after 25m
|
84
|
+
Log.info "Trying to KILL an old process..."
|
85
|
+
Process.kill("KILL", pid)
|
86
|
+
running = false
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
rescue Errno::ESRCH
|
91
|
+
running = false
|
92
|
+
rescue
|
93
|
+
# do nothing, we didn't have permission to check the running process
|
94
|
+
end
|
95
|
+
if running
|
96
|
+
if pid == "unknown"
|
97
|
+
Log.warn "Could not create or read PID file. " +
|
98
|
+
"You may need to the path to the config directory. " +
|
99
|
+
"See: http://scoutapp.com/help#data_file"
|
100
|
+
else
|
101
|
+
Log.warn "Process #{pid} was already running"
|
102
|
+
end
|
103
|
+
exit
|
104
|
+
else
|
105
|
+
Log.info "Stale PID file found. Clearing it and reloading..."
|
106
|
+
File.unlink(pid_file) rescue nil
|
107
|
+
retry
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
self
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
# def do_something!
|
117
|
+
# if @mode == :online
|
118
|
+
# puts "online"
|
119
|
+
# post(@config[:server], nil, format_out)
|
120
|
+
# else
|
121
|
+
# puts "Writing log.."
|
122
|
+
# f = open("/tmp/jah.txt", "a")
|
123
|
+
# f.write(format_out)
|
124
|
+
# f.close
|
125
|
+
# end
|
126
|
+
# end
|
127
|
+
|
128
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
|
2
|
+
module Jah
|
3
|
+
class PostAgent
|
4
|
+
|
5
|
+
|
6
|
+
def post(url, error, body, headers = Hash.new, &response_handler)
|
7
|
+
return unless url
|
8
|
+
request(url, response_handler, error) do |connection|
|
9
|
+
post = Net::HTTP::Post.new( url.path +
|
10
|
+
(url.query ? ('?' + url.query) : ''),
|
11
|
+
HTTP_HEADERS.merge(headers) )
|
12
|
+
post.body = body
|
13
|
+
connection.request(post)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,194 @@
|
|
1
|
+
require "eventmachine"#autoload :Client,
|
2
|
+
require "blather/client/client"
|
3
|
+
|
4
|
+
module Jah
|
5
|
+
# include Blather::DSL
|
6
|
+
class XmppAgent
|
7
|
+
ROSTER = []
|
8
|
+
attr_reader :client
|
9
|
+
|
10
|
+
|
11
|
+
def initialize #(jid, key, server, port=5222, debug=false, report=0)
|
12
|
+
Blather.logger.level = Logger::DEBUG if Jah.debug
|
13
|
+
@report = Jah.report
|
14
|
+
@client = Blather::Client.setup Jah.jid, Jah.key, Jah.server, Jah.port
|
15
|
+
setup
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
def process_message(to, msg, type = :chat)
|
20
|
+
if comm = Jah::Command.find(msg)
|
21
|
+
puts "Commmand => #{comm} | #{msg}"
|
22
|
+
args = msg.split(" ")
|
23
|
+
body = comm[2].send(comm[0], *args[1..-1])
|
24
|
+
else
|
25
|
+
keywords = %w{ start stop restart monitor unmonitor }
|
26
|
+
kind = :god if msg =~ /#{keywords.join("|")}/
|
27
|
+
kind ||= msg =~ /^\!/ ? :ruby : :sh
|
28
|
+
body = case kind
|
29
|
+
when :ruby
|
30
|
+
puts "Executing ruby command => #{msg}"
|
31
|
+
"=> #{execute_ruby(msg)}"
|
32
|
+
when :sh
|
33
|
+
puts "Executing *sh command => #{msg}"
|
34
|
+
"$> #{execute_sh(msg)}"
|
35
|
+
when :god
|
36
|
+
puts "Executing god command => #{msg}"
|
37
|
+
"G> #{execute_sh('god ' + msg)}"
|
38
|
+
else "dunno what to do...."
|
39
|
+
end
|
40
|
+
end
|
41
|
+
#beautify(body)
|
42
|
+
[ Blather::Stanza::Message.new(to, body, type)]
|
43
|
+
rescue => e
|
44
|
+
"Something is wrong.. #{e}\n#{e.backtrace.join("\n")}"
|
45
|
+
end
|
46
|
+
|
47
|
+
# Naive.... to be improved
|
48
|
+
def execute_ruby(code)
|
49
|
+
keywords = / class | module | def | do | while | for /
|
50
|
+
if code =~ keywords
|
51
|
+
return "Unmatched ends" if code.scan(keywords).length != code.scan(/end(\s|$)/).length
|
52
|
+
end
|
53
|
+
return "Unmatched.." if code.scan(/\{|\(|\[/).length != code.scan(/\}|\)|\]/).length
|
54
|
+
return "Unmatched quotes.." if code.scan(/\"|\'/).length % 2 != 0
|
55
|
+
begin
|
56
|
+
eval(code[1..-1]) || "nil"
|
57
|
+
rescue => e
|
58
|
+
"Fail => #{e}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def execute_sh(code)
|
63
|
+
return I18n.t(:no_sudo) if code =~ /sudo/
|
64
|
+
res = `#{code}`.chomp
|
65
|
+
ex = $?.exitstatus
|
66
|
+
if ex != 0
|
67
|
+
res << I18n.t(:exit_code, :ex => ex.to_s)
|
68
|
+
else
|
69
|
+
res = "\n" + res unless res.split("\n").length < 2
|
70
|
+
end
|
71
|
+
res
|
72
|
+
end
|
73
|
+
|
74
|
+
#TODO: need to write raw....
|
75
|
+
def beautify(txt)
|
76
|
+
#txt.gsub!(/\*(.*)\*/, "<span style=\"font-weight: bold;\">\\1</span>")
|
77
|
+
#txt.gsub!(/\/(.*)\//, "<em>\\1</em>") # Italic
|
78
|
+
#txt.gsub!(/\_(.*)\_/, "<span style=\"font-decoration: underline;\">\\1</span>")
|
79
|
+
#txt.gsub!(/\-(.*)\-/, "<span style=\"font-decoration: line-through;\">\\1</span>")
|
80
|
+
# <span style="font-size: large;">ok?</span>
|
81
|
+
# <span style="color: #FF0000;">ok?</span>
|
82
|
+
txt
|
83
|
+
end
|
84
|
+
|
85
|
+
# [:iq, :query, :roster, :disco_info, :disco_items, :message, :presence,
|
86
|
+
# :status, :subscription, :pubsub_node, :pubsub_affiliations,
|
87
|
+
# :pubsub_create, :pubsub_event, :pubsub_items, :pubsub_publish,
|
88
|
+
# :pubsub_retract, :pubsub_subscribe, :pubsub_subscription,
|
89
|
+
# :pubsub_subscriptions, :pubsub_unsubscribe, :pubsub_owner,
|
90
|
+
# :pubsub_delete, :pubsub_purge]
|
91
|
+
|
92
|
+
|
93
|
+
def setup
|
94
|
+
# return if client && client.setup?
|
95
|
+
client.register_handler(:ready) do
|
96
|
+
puts "Connected!"
|
97
|
+
ROSTER << [client.roster.items.keys, Jah.groups].flatten.uniq
|
98
|
+
ROSTER.flatten!
|
99
|
+
ROSTER.select { |j| j =~ /\@conference\./ }.each do |c|
|
100
|
+
presence = Blather::Stanza::Presence.new
|
101
|
+
presence.to = "#{c}/#{Jah.hostname}"
|
102
|
+
client.write presence
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
client.register_handler :subscription, :request? do |s|
|
107
|
+
if ROSTER.include?(s.from.stripped.to_s)
|
108
|
+
puts "[REQUEST] Approve #{s}"
|
109
|
+
client.write s.approve!
|
110
|
+
else
|
111
|
+
puts "[REQUEST] Refuse #{s}"
|
112
|
+
client.write s.refuse!
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# client.register_handler :message, :chat?, :body => 'exit' do |m|
|
117
|
+
# client.write Blather::Stanza::Message.new(m.from, 'Exiting...')
|
118
|
+
# client.close
|
119
|
+
# end
|
120
|
+
#client.register_handler :roster, [],
|
121
|
+
#client.register_handler :message, :error?, :body do |m|
|
122
|
+
#client.register_handler :message, :headline?, :body do |m|
|
123
|
+
#client.register_handler :message, :normal?, :body do |m|
|
124
|
+
|
125
|
+
client.register_handler :pubsub_event, :items do |m|
|
126
|
+
puts "[PUBSUB] => #{m.inspect}"
|
127
|
+
client.write m.body
|
128
|
+
end
|
129
|
+
|
130
|
+
client.register_handler :message, :groupchat? do |m|
|
131
|
+
if m.body =~ /^!|^>|^\\/ && m.to_s !~ /x.*:delay/ #delay.nil?
|
132
|
+
puts "[GROUP] => #{m.inspect}"
|
133
|
+
for msg in process_message(m.from.stripped, m.body, :groupchat)
|
134
|
+
client.write msg
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
client.register_handler :message, :chat?, :body do |m|
|
140
|
+
if ROSTER.include?(m.from.stripped.to_s)
|
141
|
+
puts "[PVT] => #{m.inspect}"
|
142
|
+
for msg in process_message(m.from, m.body)
|
143
|
+
client.write msg
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
def run
|
152
|
+
puts "Starting Jah Client...#{client.jid.stripped}"
|
153
|
+
trap(:INT) { EM.stop }
|
154
|
+
trap(:TERM) { EM.stop }
|
155
|
+
|
156
|
+
EM.run do
|
157
|
+
client.run
|
158
|
+
if @report != 0
|
159
|
+
puts "will report..."
|
160
|
+
EM.add_periodic_timer(@report) do
|
161
|
+
puts " I'm ok.. "
|
162
|
+
client.write Blather::Stanza::Message.new(
|
163
|
+
"nofxx@Jah.host.com", Jah::Collector.quick_results)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
|
177
|
+
# # when_ready do
|
178
|
+
# # roster.grouped.each do |group, items|
|
179
|
+
# # puts "#{'*'*3} #{group || 'Ungrouped'} #{'*'*3}"
|
180
|
+
# # items.each { |item| puts "- #{item.name} (#{item.jid})" }
|
181
|
+
# # puts
|
182
|
+
# # end
|
183
|
+
# # shutdown
|
184
|
+
# # end
|
185
|
+
|
186
|
+
# # message :chat?, :body do |m|
|
187
|
+
# # begin
|
188
|
+
# # say m.from, eval(m.body)
|
189
|
+
# # rescue => e
|
190
|
+
# # say m.from, e.inspect
|
191
|
+
# # end
|
192
|
+
|
193
|
+
|
194
|
+
# end
|