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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- M2E4MTk5Nzc3YTU1MjFjNmUyYzdlZjBjOTU4ZTgwOWIwZTBlMTBhYQ==
4
+ M2M4NjlmOTY0ZTUxNWRlY2JlOTUwNjY1ZDgyNGY5OTQ0YmZlNjE2YQ==
5
5
  data.tar.gz: !binary |-
6
- ZmEwYTMyNjE4ZGY5YzljYzM2OWY3M2ZmZTBjZWY0MTY5Y2E0YzhlNw==
6
+ ZWE4OThiYjczOTM0MGY3YTVkN2Y4ZmFkZWQwMDI3YjEwM2M4YjQxZA==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- YjFmMzgwZTZjZWY5ZTNmNjI0ZDdiOTVlYjhhNmM1ZjUxN2FjYmZhYTY2MzU5
10
- OTBmMTM5MDgwZmVmNTNhZGIwMTZjMDA0MDc5MGZmYzc4MGRiZjk1YTMxMmU5
11
- NmFiOWQwNzllMTBlMWU2MWQ0NTAxNWNhZGNlMTg2ZmU2NTFiNDU=
9
+ ZGUwMmJhNDQ2ODJlNjM0Y2UxYTRlODlmZjY4ZWZiMzNlYmFhYTE5OTg1Njhh
10
+ MGQxOWQ0YmQzZjAzNmU2YTBiNzM3ODRjMzMwYjI0NmE4OGJlYWIxMzFlNzhl
11
+ NDVkMzhlODAxNWEyMTA5OGU5ZWM1MGIxYTJjMmU3ZTEzZjc4OTE=
12
12
  data.tar.gz: !binary |-
13
- ZmJiMTRjODRjMzgwOTBmZTA5ZmFhM2MzMTYwODY3ZWU1NTA1Yjk2ZDA4Yzdk
14
- ZGJkMmE1NjQwZTFkZDdjMmM2NjJkODg4YTk1NDU3ZDE0NjI3MmQ3YzRkMjNl
15
- MWZlZGEwNTU1YzhhNTc2NmQ5YzhhZWEyN2M3ZTNlZGI4NzJhNzA=
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
- if `uname`.strip == 'Darwin'
7
- if `sw_vers -productVersion`.strip >= '10.8'
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.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.4.2)
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. [DEFAULT: ~/.imap_notifier]") do |c|
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. [Default: #{$imap_server}]") do |s|
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. [Default: #{$imap_server.split('.').pop(2).join('.')}]") do |d|
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. [Default: ENV['USER']]") do |d|
41
- opts[:domain] = d.gsub('@','')
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', "Max mail mentioned before grouping them together. [Default: #{MAX_MAIL}]") do |m|
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
 
@@ -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"
@@ -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
- if @debug
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
- imap.examine("#{f}")
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.login(@user, @password)
29
+ @imap = nil
65
30
  rescue Exception => err
66
- p "Class: #{err.class}",
67
- "Message: #{err.message}",
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("User connected to #{@domain}!", "USER: #{@user}")
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
@@ -1,21 +1,33 @@
1
1
  class IMAP_Notifier
2
2
  def config(opts={})
3
- file = File.expand_path("~#{opts[:user]}/.imap_notifier")
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] || ENV['USER']}@#{@domain}"
5
+ @user = "#{opts[:user]}@#{@domain}"
16
6
  @password = opts[:password] || get_password
17
- @folders = Hash[(opts[:folders] || ['INBOX']).map{ |f| [f,Array.new] }]
7
+ @folders = mbox_conf opts[:folders] || ['INBOX']
18
8
  @debug = opts[:debug] || false
19
- @max_mail = opts[:max] || MAX_MAIL
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(title, body)
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
- include TerminalNotifier
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(title,body)
7
- notify(body, :title => title)
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
@@ -1,3 +1,3 @@
1
1
  class IMAP_Notifier
2
- VERSION='0.2.2'
2
+ VERSION='0.2.3'
3
3
  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 = '/tmp/imap_notifier.err'
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.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-20 00:00:00.000000000 Z
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: '0'
116
+ version: 1.9.2
117
117
  required_rubygems_version: !ruby/object:Gem::Requirement
118
118
  requirements:
119
119
  - - ! '>='