omnibot 0.0.11 → 0.0.12

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -4,6 +4,8 @@ OmniBot
4
4
  Simple XMPP bot for server monitoring.
5
5
  Works with AMQP for sending messages at server side.
6
6
  Sends notifications to a user via XMPP.
7
+ Checks e-mail and extracts attachments to a specified
8
+ directory.
7
9
 
8
10
  Dependencies
9
11
  ------------
@@ -12,6 +14,8 @@ Dependencies
12
14
  * amqp
13
15
  * xmpp4r
14
16
  * eventmachine
17
+ * mail
18
+ * sqlite3
15
19
 
16
20
  Installation
17
21
  ------------
@@ -28,4 +32,4 @@ Send messages to omnibot by AMQP by running:
28
32
  Support
29
33
  -------
30
34
 
31
- Tested on Mac OS X 10.6 with Ruby 1.8
35
+ Tested with ruby 1.8.6 and 1.9.2, rabbitmq as an AMQP server, at OS X 10.6 and Debian Linux.
data/examples/config.yaml CHANGED
@@ -4,7 +4,7 @@ config:
4
4
  notifyjid: owner@example.com
5
5
  notifyresource: Adium.*
6
6
  periodiccommands: [ 'vnstat' ]
7
- logpath: '/tmp/omnibot.log'
7
+ #logpath: '/tmp/omnibot.log'
8
8
  mails:
9
9
  - user: foobar@example.com
10
10
  password: secret
data/lib/omnibot.rb CHANGED
@@ -7,6 +7,7 @@ require 'xmpp4r'
7
7
  require 'xmpp4r/client'
8
8
  require 'xmpp4r/roster'
9
9
  require 'mail'
10
+ require 'sqlite3'
10
11
  require 'socket'
11
12
  require 'date'
12
13
  require 'tmpdir'
@@ -4,6 +4,7 @@ module OmniBot
4
4
  class AMQPConsumer
5
5
 
6
6
  attr_accessor :handlers
7
+ attr_accessor :db
7
8
 
8
9
  def send_message message
9
10
  begin
@@ -39,7 +40,7 @@ module OmniBot
39
40
  handler.start
40
41
  end
41
42
 
42
- rescue Object => e
43
+ rescue => e
43
44
  OmniLog::error "Sending message error: #{e.message}\ntrace:\n#{Helpers::backtrace e}\nExiting..."
44
45
  AMQP.stop{ EM.stop }
45
46
  end
@@ -9,22 +9,32 @@ module OmniBot
9
9
  raise 'No config file found, checked command line and ~/.omnibot.yaml'
10
10
  end
11
11
 
12
+ def ensure_omnidir
13
+ path = ENV['HOME']+'/.omnibot'
14
+ FileUtils.mkdir path unless File.directory? path unless File.directory? path
15
+ path
16
+ end
17
+
12
18
  def get_log_path config
13
19
  return config['logpath'] unless (config['logpath'] or '').empty?
14
- return '/var/log/omnibot.log' if File.directory? '/var/log/'
15
- return 'omnibot.log'
20
+ ensure_omnidir + '/omnibot.log'
16
21
  end
17
22
 
18
- def get_store config
19
- store_path = config['storepath']
20
- unless File.directory? store_path
21
- store_path = ENV['HOME']+'/.omnibot'
22
- FileUtils.mkdir store_path unless File.directory? store_path
23
+ def get_db
24
+ db = SQLite3::Database.new(ensure_omnidir + '/omnibot.sqlite3')
25
+ if db.execute("select * from sqlite_master where type='table' and name='received_messages'").empty?
26
+ db.execute <<-SQL
27
+ create table received_messages (
28
+ account TEXT,
29
+ message TEXT,
30
+ date TEXT
31
+ );
32
+ SQL
23
33
  end
24
- store_path + '/omnibot.store'
34
+ db
25
35
  end
26
36
 
27
- def provide_handlers config
37
+ def provide_handlers config, db
28
38
  periodic_commands = ([config['periodiccommands']].flatten or [])
29
39
 
30
40
  mails = ([config['mails']].flatten or [])
@@ -42,7 +52,7 @@ module OmniBot
42
52
  end +
43
53
  mail_triggers.map do |trigger|
44
54
  mail = mails.find { |m| m['user'] == trigger['for'] }
45
- MailChecker.new mail, trigger
55
+ MailChecker.new mail, trigger, db
46
56
  end
47
57
  end
48
58
 
@@ -56,8 +66,10 @@ module OmniBot
56
66
  OmniLog::log = Logger.new(log_path)
57
67
  OmniLog::log.level = Logger::DEBUG
58
68
 
69
+ db = get_db
59
70
  consumer = AMQPConsumer.new config
60
- consumer.handlers = provide_handlers(config)
71
+ consumer.db = db
72
+ consumer.handlers = provide_handlers(config, db)
61
73
  consumer.start
62
74
 
63
75
  OmniLog::log.close
@@ -7,7 +7,7 @@ module OmniBot
7
7
  @jabber_messenger.call "#{banner} command #{command} failed with an error #{$?}:\n" + body
8
8
  end
9
9
  if body.strip != ''
10
- @jabber_messenger.call "#{banner} command #{command_str} succeeded with:\n" + body
10
+ @jabber_messenger.call "#{banner} command #{command} succeeded with:\n" + body
11
11
  end
12
12
  end
13
13
 
@@ -5,7 +5,6 @@ module OmniBot
5
5
  include LoggedCommand
6
6
 
7
7
  def on_first_timer
8
- OmniLog::debug "Okay, it's near of midnight"
9
8
  on_periodic_timer
10
9
  @timer_provider.add_periodic_timer(3600) { on_periodic_timer }
11
10
  end
@@ -18,27 +17,47 @@ module OmniBot
18
17
  end
19
18
 
20
19
  def match_conditions m
21
- %w{ subject from to cc date}.any? { |condition| match_condition m, condition }
20
+ @conditions.empty? || %w{ subject from to cc date}.any? { |condition| match_condition m, condition }
22
21
  end
23
22
 
24
23
  def on_periodic_timer
25
- OmniLog::info "Checking mail #{@mail_config['address']}"
26
- Mail.all.each do |m|
27
- OmniLog::info " look at message from #{m.from} about #{m.subject}"
28
- handle_message(m) if match_conditions m
24
+ begin
25
+ OmniLog::info "Checking mail #{@address}"
26
+ is_new_mail = false
27
+ Mail.all.each do |m|
28
+ rows = @db.execute "select message from received_messages where account=? and message=?", @address, m.message_id
29
+
30
+ if rows.empty?
31
+ is_new_mail = true
32
+ OmniLog::info "New message from #{m.from} about #{m.subject}; id #{m.message_id}"
33
+ if match_conditions m
34
+ handle_message(m)
35
+ end
36
+ @db.execute "insert into received_messages values(?, ?, ?)", @address, m.message_id, m.date.to_s
37
+ end
38
+ end
39
+ OmniLog::info "No new mail" unless is_new_mail
40
+ rescue => e
41
+ OmniLog::error "MailChecker error: #{e.message}\ntrace:\n#{Helpers::backtrace e}"
29
42
  end
30
43
  end
31
44
 
32
45
  def handle_message m
33
46
  OmniLog::info "Matched " + m.inspect.to_s
34
- attached = m.attachments.find { |a| a.mime_type =~ /application\/x-zip.*/ }
47
+ attached = m.attachments.find { |a| a.mime_type =~ /application\/(zip|x-zip|rar|x-rar).*/ }
35
48
  if attached
36
49
  Dir.mktmpdir('omniatt') do |tmpdir|
37
50
  filename = tmpdir + '/' + attached.filename
38
51
  OmniLog::info "Writing attachment to #{filename}"
39
52
  File.open(filename,'w') { |f| f.write attached.read }
40
53
  Dir.chdir(@unpack_to) do
41
- system("unzip -oq '#{filename}'")
54
+ if filename =~ /\.zip$/
55
+ system("unzip -oq '#{filename}'")
56
+ elsif filename =~ /\.rar$/
57
+ system("unrar x -y '#{filename}'")
58
+ else
59
+ raise "Wrong filetype"
60
+ end
42
61
  raise "Error extracting file #{filename} to #{@unpack_to}" if $? != 0
43
62
  end
44
63
 
@@ -66,13 +85,14 @@ module OmniBot
66
85
  attr_writer :timer_provider
67
86
  attr_writer :startup_pause
68
87
 
69
- def initialize mail_config, trigger_config
88
+ def initialize mail_config, trigger_config, db
70
89
  @startup_pause = 0
71
90
  @mail_config = mail_config
72
- @conditions = trigger_config['if']
91
+ @db = db
92
+ @conditions = (trigger_config['if'] or {})
73
93
  @unpack_to = trigger_config['unpack_to']
74
94
  @command_post = trigger_config['command_post']
75
- @send_to = trigger_config['send_to']
95
+ @address = trigger_config['for']
76
96
 
77
97
  mailhash = yaml_to_mailhash(mail_config)
78
98
  Mail.defaults do
@@ -84,7 +104,7 @@ module OmniBot
84
104
  end
85
105
 
86
106
  def to_s
87
- "Mail checker for #{@send_to}"
107
+ "Mail checker for #{@address}"
88
108
  end
89
109
 
90
110
  def start
@@ -6,14 +6,17 @@ module OmniBot
6
6
  include OmniBot::LoggedCommand
7
7
 
8
8
  def on_first_timer
9
- OmniLog::debug "Okay, it's near of midnight"
10
9
  on_periodic_timer
11
10
  @timer_provider.add_periodic_timer(24*3600) { on_periodic_timer }
12
11
  end
13
12
 
14
13
  def on_periodic_timer
15
- OmniLog::info "Reporting command #{@command}"
16
- jabber_logged_command 'Periodic command', @command
14
+ begin
15
+ OmniLog::info "Reporting command #{@command}"
16
+ jabber_logged_command 'Periodic command', @command
17
+ rescue => e
18
+ OmniLog::error "PeriodicCommand error: #{e.message}\ntrace:\n#{Helpers::backtrace e}"
19
+ end
17
20
  end
18
21
 
19
22
  public
@@ -1,3 +1,3 @@
1
1
  module OmniBot
2
- VERSION = '0.0.11'
2
+ VERSION = '0.0.12'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omnibot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.11
4
+ version: 0.0.12
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2011-10-28 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: xmpp4r
16
- requirement: &70163940523880 !ruby/object:Gem::Requirement
16
+ requirement: &70295142817300 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70163940523880
24
+ version_requirements: *70295142817300
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: eventmachine
27
- requirement: &70163940523040 !ruby/object:Gem::Requirement
27
+ requirement: &70295142815520 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70163940523040
35
+ version_requirements: *70295142815520
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: amqp
38
- requirement: &70163936528020 !ruby/object:Gem::Requirement
38
+ requirement: &70295142814260 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70163936528020
46
+ version_requirements: *70295142814260
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: mail
49
- requirement: &70163936526040 !ruby/object:Gem::Requirement
49
+ requirement: &70295142813420 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,7 +54,18 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70163936526040
57
+ version_requirements: *70295142813420
58
+ - !ruby/object:Gem::Dependency
59
+ name: sqlite3
60
+ requirement: &70295142812580 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: *70295142812580
58
69
  description: Works with AMQP for sending messages at server side.Sends notifications
59
70
  to an user via XMPP.Can monitor system by performing daily commands.
60
71
  email: theirix@gmail.com
@@ -99,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
110
  version: '0'
100
111
  segments:
101
112
  - 0
102
- hash: 2655669642277178237
113
+ hash: 1612202538999953127
103
114
  requirements:
104
115
  - AMQP-compatible server (for example, RabbitMQ)
105
116
  rubyforge_project: nowarning