imap_notifier 0.2.2 → 0.2.3
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 +8 -8
- data/Gemfile +5 -8
- data/Gemfile.lock +3 -2
- data/bin/imap_notifier +8 -7
- data/imap_notifier.gemspec +1 -0
- data/lib/imap_notifier/base.rb +45 -51
- data/lib/imap_notifier/config.rb +26 -14
- data/lib/imap_notifier/growler.rb +6 -3
- data/lib/imap_notifier/notifier.rb +7 -3
- data/lib/imap_notifier/version.rb +1 -1
- data/lib/imap_notifier.rb +1 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
M2M4NjlmOTY0ZTUxNWRlY2JlOTUwNjY1ZDgyNGY5OTQ0YmZlNjE2YQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZWE4OThiYjczOTM0MGY3YTVkN2Y4ZmFkZWQwMDI3YjEwM2M4YjQxZA==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZGUwMmJhNDQ2ODJlNjM0Y2UxYTRlODlmZjY4ZWZiMzNlYmFhYTE5OTg1Njhh
|
10
|
+
MGQxOWQ0YmQzZjAzNmU2YTBiNzM3ODRjMzMwYjI0NmE4OGJlYWIxMzFlNzhl
|
11
|
+
NDVkMzhlODAxNWEyMTA5OGU5ZWM1MGIxYTJjMmU3ZTEzZjc4OTE=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NmVkNTA3YzlmMDU5Y2IyOGJhMmQ4Y2EzOWY0MjI0N2NhMGY3N2Q3YzE2OTk2
|
14
|
+
NzVhNDViZTU5Y2ViZjdjNjllMDdmZThmMGM4YjYwMTM2YzRlZDlhMmIzZDE3
|
15
|
+
MzEyZGNiZDMzMmNiZjYwN2VkN2Q1OTM4MGU5M2FkZjlmOTNmODY=
|
data/Gemfile
CHANGED
@@ -3,14 +3,11 @@ source 'https://rubygems.org'
|
|
3
3
|
# Specify your gem's dependencies in imap_notifier.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
gem 'terminal-notifier'
|
9
|
-
else
|
10
|
-
gem 'ruby-growl'
|
11
|
-
end
|
12
|
-
else
|
13
|
-
raise "You must be running Mac OS X for imap_notifier to work!"
|
6
|
+
def is_mnt_lion?
|
7
|
+
@lion ||= (RUBY_PLATFORM.match /(\d+)\.\d+\.\d+$/)[0].to_i >= 12
|
14
8
|
end
|
15
9
|
|
10
|
+
gem 'terminal-notifier', :require => is_mnt_lion?
|
11
|
+
gem 'ruby-growl', :require => is_mnt_lion?
|
12
|
+
|
16
13
|
gem 'highline'
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
imap_notifier (0.2.
|
4
|
+
imap_notifier (0.2.3)
|
5
5
|
highline
|
6
6
|
ruby-growl
|
7
7
|
terminal-notifier
|
@@ -16,7 +16,7 @@ GEM
|
|
16
16
|
ruby-growl (4.0)
|
17
17
|
uuid (~> 2.3, >= 2.3.5)
|
18
18
|
systemu (2.5.2)
|
19
|
-
terminal-notifier (1.
|
19
|
+
terminal-notifier (1.5.1)
|
20
20
|
uuid (2.3.7)
|
21
21
|
macaddr (~> 1.0)
|
22
22
|
|
@@ -28,4 +28,5 @@ DEPENDENCIES
|
|
28
28
|
highline
|
29
29
|
imap_notifier!
|
30
30
|
rake
|
31
|
+
ruby-growl
|
31
32
|
terminal-notifier
|
data/bin/imap_notifier
CHANGED
@@ -24,29 +24,30 @@ opt_parser = OptionParser.new do |opt|
|
|
24
24
|
opts[:debug] = true
|
25
25
|
end
|
26
26
|
|
27
|
-
opt.on('-f', '--file FILE', "Read configuration file
|
27
|
+
opt.on('-f', '--file FILE', "Read configuration file.\t[DEFAULT: ~/.imap_notifier]") do |c|
|
28
28
|
opts[:config] = c
|
29
29
|
end
|
30
30
|
|
31
|
-
opt.on('-s','--server STR', "Specify imap server
|
31
|
+
opt.on('-s','--server STR', "Specify imap server.\t[Default: #{$imap_server}]") do |s|
|
32
32
|
$imap_server = s
|
33
33
|
end
|
34
34
|
|
35
35
|
opt.on('-d','--domain STR',
|
36
|
-
"Specify email domain
|
37
|
-
opts[:domain] = d.gsub('
|
36
|
+
"Specify email domain.\t[Default: #{$imap_server.split('.').pop(2).join('.')}]") do |d|
|
37
|
+
opts[:domain] = d.gsub(/.+\@/,'')
|
38
38
|
end
|
39
39
|
|
40
|
-
opt.on('-u','--user STR', "Specify user login
|
41
|
-
opts[:
|
40
|
+
opt.on('-u','--user STR', "Specify user login.\t[Default: ENV['USER']]") do |u|
|
41
|
+
opts[:user] = u
|
42
42
|
end
|
43
43
|
|
44
|
-
opt.on('-m','--max INT', "
|
44
|
+
opt.on('-m','--max INT', "Group notify on N or more mails. [Default: #{MAX_MAIL}]") do |m|
|
45
45
|
opts[:max] = m.to_i
|
46
46
|
end
|
47
47
|
|
48
48
|
opt.on('-k', '--kill', "Kill currently running #{opt.program_name} process with SIGINT") do
|
49
49
|
IMAP_Notifier.kill_process
|
50
|
+
exit
|
50
51
|
end
|
51
52
|
end
|
52
53
|
|
data/imap_notifier.gemspec
CHANGED
@@ -20,6 +20,7 @@ If you're running Max OSX > 10.8, terminal-notifier is required, otherwise ruby-
|
|
20
20
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
21
|
spec.require_paths = ["lib"]
|
22
22
|
|
23
|
+
spec.required_ruby_version = '>= 1.9.2'
|
23
24
|
spec.add_development_dependency "bundler", "~> 1.3"
|
24
25
|
spec.add_development_dependency "rake"
|
25
26
|
spec.add_dependency "highline"
|
data/lib/imap_notifier/base.rb
CHANGED
@@ -5,8 +5,6 @@ class IMAP_Notifier
|
|
5
5
|
Process.kill("SIGINT", pid)
|
6
6
|
rescue Errno::ESRCH, Errno::ENOENT => e
|
7
7
|
puts "#{e.message} - Exiting..."
|
8
|
-
ensure
|
9
|
-
exit
|
10
8
|
end
|
11
9
|
|
12
10
|
def initialize(opts={})
|
@@ -15,69 +13,52 @@ class IMAP_Notifier
|
|
15
13
|
|
16
14
|
pid = fork do
|
17
15
|
$stderr.reopen(ERRFILE, 'w')
|
18
|
-
|
19
|
-
$stdout.reopen(DEBUGFILE, 'w')
|
20
|
-
@notifier.alert("DEBUG MODE ENABLED", "DEBUG LOGFILE: #{DEBUGFILE}")
|
21
|
-
end
|
22
|
-
at_exit { File.delete(PIDFILE) if File.exists?(PIDFILE) }
|
16
|
+
at_exit { self.stop }
|
23
17
|
run
|
24
18
|
end
|
25
19
|
File.open(PIDFILE, 'w') { |f| f.write pid }
|
26
20
|
end
|
27
21
|
|
28
|
-
def imap
|
29
|
-
@imap ||= _imap
|
30
|
-
end
|
31
|
-
|
32
22
|
def run
|
33
23
|
begin
|
34
24
|
@folders.each do |f, ids|
|
35
|
-
|
36
|
-
|
37
|
-
p "Mailbox: #{f}" if @debug
|
38
|
-
unseen = imap.search(["UNSEEN"])
|
39
|
-
ungrowled = unseen - ids
|
40
|
-
ungrowled_count = ungrowled.length
|
41
|
-
p "All unseen mail ids: #{unseen}",
|
42
|
-
"All ungrowled mail ids: #{ungrowled}",
|
43
|
-
"Ungrowled count: #{ungrowled_count}" if @debug
|
44
|
-
|
45
|
-
if ungrowled_count > @max_mail
|
46
|
-
p "New Mail in #{f}!",
|
47
|
-
"New: #{ungrowled_count}\nTotal: #{unseen.length}" if @debug
|
48
|
-
@notifier.alert("New Mail in #{f}!", "New: #{ungrowled_count}")
|
49
|
-
else
|
50
|
-
ungrowled.each do |msg_id|
|
51
|
-
msg = imap.fetch(msg_id, "ENVELOPE")[0].attr["ENVELOPE"]
|
52
|
-
next if ids.include?(msg.message_id)
|
53
|
-
p "Growled about #{msg.message_id}" if @debug
|
54
|
-
@notifier.alert("Mail from #{msg.sender.first.mailbox}", "#{msg.subject}")
|
55
|
-
end
|
56
|
-
end
|
57
|
-
@folders[f] = unseen
|
25
|
+
alert_folder(f, ids)
|
58
26
|
end
|
59
27
|
sleep SLEEP
|
60
|
-
rescue Interrupt
|
61
|
-
@notifier.alert("Goodbye!", '')
|
62
|
-
raise
|
63
28
|
rescue EOFError
|
64
|
-
imap
|
29
|
+
@imap = nil
|
65
30
|
rescue Exception => err
|
66
|
-
|
67
|
-
|
68
|
-
"See #{ERRFILE} for more info." if @debug
|
69
|
-
@notifier.alert(err.class, err.message)
|
70
|
-
|
71
|
-
warn Time.now
|
72
|
-
warn @user
|
73
|
-
warn $imap_server
|
74
|
-
warn err.class
|
75
|
-
warn err.message
|
76
|
-
err.backtrace.map{ |e| warn e }
|
77
|
-
raise
|
31
|
+
say_goodbye(err.class.to_s) || handle_exception(err)
|
32
|
+
exit
|
78
33
|
end while true
|
79
34
|
end
|
80
35
|
|
36
|
+
def alert_folder(f, ids)
|
37
|
+
imap.examine(f)
|
38
|
+
unseen = imap.search(["UNSEEN"])
|
39
|
+
unalerted = unseen - ids
|
40
|
+
|
41
|
+
if unalerted.length > @max_mail
|
42
|
+
@notifier.alert("#{f}: #{unalerted.length} new mails", :group => f)
|
43
|
+
else
|
44
|
+
unalerted.each do |msg_id|
|
45
|
+
msg = imap.fetch(msg_id, "ENVELOPE")[0].attr["ENVELOPE"]
|
46
|
+
next if ids.include?(msg.message_id)
|
47
|
+
@notifier.alert("#{f} #{msg.subject}", :title => "Mail from #{msg.sender.first.mailbox}", :group => msg_id)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
@folders[f] = unseen
|
51
|
+
end
|
52
|
+
|
53
|
+
def imap
|
54
|
+
@imap ||= _imap
|
55
|
+
end
|
56
|
+
|
57
|
+
def stop
|
58
|
+
IMAP_Notifier::Alert.remove
|
59
|
+
File.delete(PIDFILE) if File.exists?(PIDFILE)
|
60
|
+
end
|
61
|
+
|
81
62
|
private
|
82
63
|
def get_password(prompt="Enter Password: ")
|
83
64
|
ask(prompt) { |q| q.echo = false }
|
@@ -86,7 +67,20 @@ class IMAP_Notifier
|
|
86
67
|
def _imap
|
87
68
|
imap = Net::IMAP.new($imap_server, { :port => 993, :ssl => true } )
|
88
69
|
imap.login(@user, @password)
|
89
|
-
@notifier.alert("
|
70
|
+
@notifier.alert("#{@user} connected!", :group => @domain)
|
90
71
|
return imap
|
91
72
|
end
|
73
|
+
|
74
|
+
def say_goodbye(klass)
|
75
|
+
return if !(klass.eql? "Interrupt")
|
76
|
+
@notifier.alert("Goodbye!", :group => @domain)
|
77
|
+
File.delete(ERRFILE) if File.exists?(ERRFILE)
|
78
|
+
end
|
79
|
+
|
80
|
+
def handle_exception(err)
|
81
|
+
@notifier.alert(err.message, :title => err.class, :open => "file://#{ERRFILE}")
|
82
|
+
warn("#{Time.now} - #{@user}")
|
83
|
+
warn("#{err.class}: #{err.message}")
|
84
|
+
err.backtrace.map{ |e| warn e }
|
85
|
+
end
|
92
86
|
end
|
data/lib/imap_notifier/config.rb
CHANGED
@@ -1,21 +1,33 @@
|
|
1
1
|
class IMAP_Notifier
|
2
2
|
def config(opts={})
|
3
|
-
|
4
|
-
if File.exists? file
|
5
|
-
m = sprintf("%o", File.stat(file).mode).split('').last(3).join().to_i
|
6
|
-
if m != 600
|
7
|
-
warn "#{file} must have permissions 0644, not #{m}"
|
8
|
-
exit 1
|
9
|
-
end
|
10
|
-
YAML.load(File.open(file)).each do |k,v|
|
11
|
-
opts[k.to_sym] ||= v
|
12
|
-
end
|
13
|
-
end
|
3
|
+
read_conf opts
|
14
4
|
@domain = opts[:domain] || $imap_server.split('.').pop(2).join('.')
|
15
|
-
@user = "#{opts[:user]
|
5
|
+
@user = "#{opts[:user]}@#{@domain}"
|
16
6
|
@password = opts[:password] || get_password
|
17
|
-
@folders =
|
7
|
+
@folders = mbox_conf opts[:folders] || ['INBOX']
|
18
8
|
@debug = opts[:debug] || false
|
19
|
-
@max_mail = opts[:max]
|
9
|
+
@max_mail = opts[:max] || MAX_MAIL
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
def mbox_conf ary
|
14
|
+
Hash[ary.map{ |f| [f,Array.new] }]
|
15
|
+
end
|
16
|
+
|
17
|
+
def read_conf opts
|
18
|
+
file = File.expand_path("~/.imap_notifier")
|
19
|
+
return if ! File.exists? file
|
20
|
+
ensure_perms file
|
21
|
+
YAML.load(File.open(file)).each do |k,v|
|
22
|
+
opts[k.to_sym] ||= v
|
23
|
+
end
|
24
|
+
opts[:user] ||= ENV['USER']
|
25
|
+
end
|
26
|
+
|
27
|
+
def ensure_perms file
|
28
|
+
m = sprintf("%o", File.stat(file).mode).split('').last(3).join().to_i
|
29
|
+
return if m.eql? 600
|
30
|
+
warn "#{file} permissions should be set to 600 #{m}"
|
31
|
+
exit 1
|
20
32
|
end
|
21
33
|
end
|
@@ -1,13 +1,16 @@
|
|
1
1
|
require 'ruby-growl'
|
2
2
|
|
3
3
|
class IMAP_Notifier::Alert < Growl
|
4
|
+
def self.remove
|
5
|
+
end
|
6
|
+
|
4
7
|
def initialize
|
5
8
|
super("localhost", ::IMAP_Notifier::VERSION)
|
6
9
|
end
|
7
10
|
|
8
|
-
def alert(
|
11
|
+
def alert(body, opts={})
|
12
|
+
opts[:title] ||= self.class.name
|
9
13
|
add_notification ::IMAP_Notifier::VERSION
|
10
|
-
notify ::IMAP_Notifier::VERSION, title, body
|
14
|
+
notify ::IMAP_Notifier::VERSION, opts[:title], body
|
11
15
|
end
|
12
|
-
|
13
16
|
end
|
@@ -1,9 +1,13 @@
|
|
1
1
|
require 'terminal-notifier'
|
2
2
|
|
3
3
|
class IMAP_Notifier::Alert
|
4
|
-
|
4
|
+
def self.remove
|
5
|
+
return if (msgs = TerminalNotifier.list).nil?
|
6
|
+
msgs.map{ |a| TerminalNotifier.remove a[:group] }
|
7
|
+
end
|
5
8
|
|
6
|
-
def alert(
|
7
|
-
|
9
|
+
def alert(body, opts={})
|
10
|
+
opts[:title] ||= self.class.name
|
11
|
+
TerminalNotifier.notify(body, opts.merge({:sender => 'com.apple.Mail'}))
|
8
12
|
end
|
9
13
|
end
|
data/lib/imap_notifier.rb
CHANGED
@@ -6,11 +6,10 @@ require 'imap_notifier/version'
|
|
6
6
|
require 'imap_notifier/config'
|
7
7
|
require 'imap_notifier/base'
|
8
8
|
|
9
|
-
|
10
9
|
MAX_MAIL = 5 # Max new mails mentioned before they
|
11
10
|
# are grouped together
|
12
11
|
SLEEP = 30
|
13
|
-
ERRFILE = '/
|
12
|
+
ERRFILE = File.expand_path('~/Desktop/imap_notifier.log')
|
14
13
|
DEBUGFILE = '/tmp/imap_notifier.debug'
|
15
14
|
PIDFILE = '/tmp/imap_notifier.pid'
|
16
15
|
$imap_server = "imap.gmail.com" # could be anything with tweaks
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: imap_notifier
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Campbell
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-09-
|
11
|
+
date: 2013-09-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -113,7 +113,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
113
113
|
requirements:
|
114
114
|
- - ! '>='
|
115
115
|
- !ruby/object:Gem::Version
|
116
|
-
version:
|
116
|
+
version: 1.9.2
|
117
117
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
118
|
requirements:
|
119
119
|
- - ! '>='
|