catfriend 0.11 → 0.12

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.
@@ -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