catfriend 0.11 → 0.12

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,12 +1,13 @@
1
1
  require 'catfriend/server'
2
2
  require 'catfriend/notify'
3
+ require 'catfriend/thread'
3
4
 
4
5
  module Catfriend
5
6
 
6
7
  # This class represents a thread capable of checking and creating
7
8
  # notifications for a single mailbox on a single IMAP server.
8
9
  class ImapServer
9
- include ThreadMixin
10
+ include Thread
10
11
  include AccessorsFromHash
11
12
 
12
13
  # Create new IMAP server with optional full configuration hash.
@@ -30,8 +31,6 @@ class ImapServer
30
31
  if not @password
31
32
  raise ConfigError, "imap password not set"
32
33
  end
33
-
34
- @id = @host unless @id
35
34
  end
36
35
 
37
36
  # The id is a token which represents this server when displaying
@@ -50,20 +49,21 @@ class ImapServer
50
49
  # succeeds.
51
50
  def run
52
51
  begin
53
- connect
54
- # :body => nil means summary only
55
52
  @notification =
56
53
  Libnotify.new :body => nil,
57
54
  :timeout => Catfriend.notification_timeout
55
+ @message_count = connect
56
+ notify_message @message_count
57
+ # :body => nil means summary only
58
58
  rescue OpenSSL::SSL::SSLError
59
59
  error "try providing ssl certificate"
60
60
  rescue Net::IMAP::NoResponseError
61
61
  error "no response to connect, try ssl"
62
62
  else
63
- @message_count = @imap.fetch('*', 'UID').first.seqno
64
- notify_message @message_count
65
-
66
- loop { check_loop }
63
+ loop {
64
+ check_loop
65
+ break if stopped?
66
+ }
67
67
  end
68
68
  end
69
69
 
@@ -72,26 +72,34 @@ class ImapServer
72
72
  # on an unrecoverable error.
73
73
  def check_loop
74
74
  @imap.idle do |r|
75
+ # puts "#{id}: #{r}" # debug code
75
76
  next if r.instance_of? Net::IMAP::ContinuationRequest
76
77
 
77
78
  if r.instance_of? Net::IMAP::UntaggedResponse
78
- if r.name == 'EXISTS'
79
+ case r.name
80
+ when 'EXISTS'
79
81
  # some servers send this even when the message count
80
82
  # hasn't increased so suspiciously double-check
81
- if r.data > @message_count
83
+ if r.data != @message_count
84
+ notify_message(r.data) if r.data > @message_count
82
85
  @message_count = r.data
83
- notify_message @message_count
84
86
  end
85
- elsif r.name == 'EXPUNGE'
87
+ when 'EXPUNGE'
86
88
  @message_count -= 1
87
89
  end
88
90
  end
89
91
  end
90
92
 
91
- notify_message "error - server cancelled idle"
93
+ # puts "idle loop over" # debug code
94
+ rescue Net::IMAP::Error, IOError
95
+ # reconnect and carry on
96
+ reconnect unless stopped?
92
97
  rescue => e
93
- # todo: see if we have to re-open socket
94
- notify_message "error - #{e.message}"
98
+ unless stopped?
99
+ # todo: see if we have to re-open socket
100
+ notify_message "error - #{e.message}"
101
+ puts e.backtrace.join "\n"
102
+ end
95
103
  end
96
104
 
97
105
  def notify_message message
@@ -104,7 +112,7 @@ class ImapServer
104
112
  super
105
113
  end
106
114
 
107
- # Connect to the configured IMAP server.
115
+ # Connect to the configured IMAP server and return message count.
108
116
  def connect
109
117
  args = nil
110
118
  if not @no_ssl
@@ -117,11 +125,21 @@ class ImapServer
117
125
  @imap = Net::IMAP.new(@host, args)
118
126
  @imap.login(@user, @password)
119
127
  @imap.select(@mailbox || "INBOX")
128
+ return @imap.fetch('*', 'UID').first.seqno
129
+ end
130
+
131
+ def reconnect
132
+ # todo: log an error unless this completes within a short time
133
+ # puts "#{id}: reconnecting" # debug code
134
+ new_count = connect
135
+ notify_message(new_count) if new_count != @message_count
136
+ @message_count = new_count
120
137
  end
121
138
 
122
139
  def disconnect ; @imap.disconnect ; end
123
140
 
124
- private :connect, :disconnect, :check_loop, :run, :error, :notify_message
141
+ private :connect, :disconnect, :reconnect,
142
+ :check_loop, :run, :error, :notify_message
125
143
  attr_writer :host, :password, :id, :user, :no_ssl, :cert_file, :mailbox
126
144
  end
127
145
 
@@ -4,18 +4,6 @@ def self.notification_timeout
4
4
  @@notification_timeout
5
5
  end
6
6
 
7
- # Mixin this module and define "run" for a simple runnable/joinable thread
8
- module ThreadMixin
9
- # Call to start a thread running via the start method.
10
- def start ; @thread = Thread.new { run } ; end
11
-
12
- # Join thread if it has started.
13
- def join ; @thread.join if @thread ; end
14
-
15
- # Kill thread if it has started.
16
- def kill ; @thread.kill if @thread ; end
17
- end
18
-
19
7
  # Mixin to provide #configure which allows all instance variables with write
20
8
  # accessors declared to be set from a hash.
21
9
  module AccessorsFromHash
@@ -32,4 +20,4 @@ end
32
20
  # This class is used to signal the user made an error in their configuration.
33
21
  class ConfigError < Exception ; end
34
22
 
35
- end # end module
23
+ end # end Catfriend module
@@ -0,0 +1,29 @@
1
+ module Catfriend
2
+
3
+ # Mixin this module and define "run" for a simple runnable/joinable thread
4
+ module Thread
5
+ # Call to start a thread running via the start method.
6
+ def start ; @thread = ::Thread.new { run } ; end
7
+
8
+ # Test whether thread is currently stopped or closing down.
9
+ def stopped? ; @thread.nil? ; end
10
+
11
+ # Join thread if it has started.
12
+ def join
13
+ unless stopped?
14
+ @thread.join
15
+ @thread = nil
16
+ end
17
+ end
18
+
19
+
20
+ # Kill thread if it has started.
21
+ def kill
22
+ unless stopped?
23
+ @thread.kill
24
+ @thread = nil
25
+ end
26
+ end
27
+ end
28
+
29
+ end # end Catfriend module
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: catfriend
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.11'
4
+ version: '0.12'
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-01 00:00:00.000000000 Z
12
+ date: 2012-01-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: libnotify
16
- requirement: &10589720 !ruby/object:Gem::Requirement
16
+ requirement: &10675900 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '0.6'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *10589720
24
+ version_requirements: *10675900
25
25
  description: E-mail checker with libnotify desktop notifications.
26
26
  email:
27
27
  - catfriend@chilon.net
@@ -35,6 +35,7 @@ files:
35
35
  - lib/catfriend/server.rb
36
36
  - lib/catfriend/notify.rb
37
37
  - lib/catfriend/filetokenstack.rb
38
+ - lib/catfriend/thread.rb
38
39
  - lib/catfriend/imap.rb
39
40
  - bin/catfriend
40
41
  homepage: https://github.com/nuisanceofcats/catfriend