emn 0.0.2 → 0.0.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,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fba0a6081b5f82515a2a108a97ffe1de70af9a83
4
- data.tar.gz: 3ea0c86c34254dc7606f8289f1d46019a146477c
3
+ metadata.gz: 7859ee37dc3e8c7bd5a616c4e206070ab4efe8db
4
+ data.tar.gz: 7a85adb9dfce6b2f027e89e7275b021f3b66476a
5
5
  SHA512:
6
- metadata.gz: b5c1af56493896170c053558afc23e60f8f813f0629326239106080f158af2c84d20f5246415ffccfee58a5e23aca3dda0007095b5d80c43278aba2850ae033f
7
- data.tar.gz: 035cd4c92f83fb0d0d94c911e46454b06a9e274090ff34c07c1f5c4952fd1e5c22534d55a30181cd5f5d99232735661dde6772fa88dc6f1dbeb51baefdaed0ce
6
+ metadata.gz: bfed3767c44236dd8dd19155cdd2f430069efd5894fd841fa0d7e77b8f632a2aa86fd0f6168d19d1162f04e560880a8f1780466ca04c8aca0745d112abdb3a50
7
+ data.tar.gz: cf20b5003a66f1e2e318edaa28a76d8be759d0a916edf999110ac775e996149b63102a92a53b37f67a1409cf13702ef657ad44cf7502cd2105c1d9c8da7ba500
data/bin/emn CHANGED
@@ -4,4 +4,4 @@ require 'emn'
4
4
 
5
5
  emn = EMN.new
6
6
  emn.parse_options
7
- emn.send!
7
+ emn.process!
data/lib/emn/config.rb ADDED
@@ -0,0 +1,40 @@
1
+ class EMN
2
+ class Config
3
+ def initialize(config="~/.emn", seen="~/.emn_seen")
4
+ @config_file = config
5
+ @seen_file = seen
6
+
7
+ load_config
8
+ end
9
+
10
+ def logger
11
+ if OPTIONS[:debug] || OPTIONS[:verbose]
12
+ return @logger ||= Logger.new(STDOUT)
13
+ else
14
+ return @logger ||= Logger.new(nil)
15
+ end
16
+ end
17
+
18
+ def seen
19
+ YAML.load(File.read(File.expand_path(@seen_file)))
20
+ rescue
21
+ {}
22
+ end
23
+
24
+ def save_seen!(seen)
25
+ return if OPTIONS[:debug]
26
+
27
+ File.open(File.expand_path(@seen_file), "w") do |file|
28
+ file.puts seen.to_yaml
29
+ end
30
+ end
31
+
32
+ def [](key)
33
+ @config[key]
34
+ end
35
+
36
+ def load_config
37
+ @config = YAML.load(File.read(File.expand_path(@config_file)))
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,48 @@
1
+ class EMN
2
+ class EveAPI
3
+ attr_reader :config, :logger
4
+
5
+ def initialize(config)
6
+ @config = config
7
+ @logger = config.logger
8
+ end
9
+
10
+ def api
11
+ unless EAAL.cache.is_a?(EAAL::Cache::FileCache)
12
+ EAAL.cache = EAAL::Cache::FileCache.new
13
+ end
14
+
15
+ @api ||= EAAL::API.new(
16
+ config[:eve][:key_id],
17
+ config[:eve][:verification_code]
18
+ )
19
+ end
20
+
21
+ def planets(char)
22
+ api.scope = "char"
23
+ api.PlanetaryColonies("characterID" => char.characterID).colonies.sort_by{|c| c.planetID}
24
+ end
25
+
26
+ def planet_pins(char, planet)
27
+ api.scope = "char"
28
+ api.PlanetaryPins("characterID" => char.characterID, "planetID" => planet.planetID).pins.sort_by do |pin|
29
+ pin.pinID
30
+ end.map do |pin|
31
+ pin.expiryTime = Time.parse("%s UTC" % pin.expiryTime)
32
+ pin.lastLaunchTime = Time.parse("%s UTC" % pin.lastLaunchTime)
33
+ pin.installTime = Time.parse("%s UTC" % pin.installTime)
34
+ pin
35
+ end
36
+ end
37
+
38
+ def mails(char)
39
+ api.scope = "char"
40
+ api.MailMessages("characterID" => char.characterID).messages.sort_by{|m| m.messageID}
41
+ end
42
+
43
+ def characters
44
+ api.scope = "account"
45
+ api.Characters.characters
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,64 @@
1
+ class EMN
2
+ class Monitor
3
+ class Mail
4
+ attr_reader :config, :logger, :api
5
+
6
+ def initialize(config)
7
+ @config = config
8
+ @logger = config.logger
9
+ @api = EveAPI.new(config)
10
+ end
11
+
12
+ def seen
13
+ @seen ||= {:mail => config.seen.fetch(:mail, {})}
14
+ end
15
+
16
+ def notifications
17
+ notifications = {
18
+ :template => "templates/mail.erb",
19
+ :subject => "Eve Mail",
20
+ :seen => config.seen,
21
+ :data => {}
22
+ }
23
+
24
+ api.characters.each do |toon|
25
+ logger.debug("Checking character %s" % toon.name)
26
+
27
+ messages = api.mails(toon)
28
+
29
+ logger.debug("Found %d messages for %s" % [messages.size, toon.name])
30
+
31
+ messages.each do |mail|
32
+ logger.debug("Processing email %s: from: %s subject: %s" % [mail.messageID, mail.senderName, mail.title])
33
+
34
+ seen[:mail][toon.name] ||= "0"
35
+
36
+ if seen[:mail][toon.name] < mail.messageID
37
+ seen[:mail][toon.name] = mail.messageID
38
+
39
+ if mail.senderName == toon.name
40
+ logger.debug("Skipping mail %s as it's from the character" % mail.messageID)
41
+ next
42
+ end
43
+
44
+ logger.debug("Adding email %s: %s to the queue" % [mail.messageID, mail.title])
45
+
46
+ notifications[:data][toon.name] ||= []
47
+ notifications[:data][toon.name] << {
48
+ :id => mail.messageID,
49
+ :from => mail.senderName,
50
+ :date => mail.sentDate,
51
+ :subject => mail.title
52
+ }
53
+ else
54
+ logger.debug("Skipping email %s: it's been seen before (%s)" % [mail.messageID, seen[:mail][toon.name]])
55
+ end
56
+ end
57
+ end
58
+
59
+ notifications[:seen] = seen
60
+ notifications
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,98 @@
1
+ require 'time'
2
+
3
+ class EMN
4
+ class Monitor
5
+ class Pi
6
+ attr_reader :config, :logger, :api
7
+
8
+ def initialize(config)
9
+ @config = config
10
+ @logger = config.logger
11
+ @api = EveAPI.new(config)
12
+ end
13
+
14
+ def seen
15
+ @seen ||= {:planets => config.seen.fetch(:planets, {})}
16
+ end
17
+
18
+ def seconds_to_human(seconds)
19
+ if seconds < 0
20
+ past = true
21
+ seconds = seconds.abs
22
+ end
23
+
24
+ days = seconds.to_i / 86400
25
+ seconds -= 86400 * days
26
+
27
+ hours = seconds.to_i / 3600
28
+ seconds -= 3600 * hours
29
+
30
+ minutes = seconds.to_i / 60
31
+ seconds -= 60 * minutes
32
+
33
+ time = if days > 1
34
+ "%d days %d hours %d minutes" % [days, hours, minutes]
35
+ elsif days == 1
36
+ "%d day %d hours %d minutes" % [days, hours, minutes]
37
+ elsif hours > 0
38
+ "%d hours %d minutes" % [hours, minutes]
39
+ elsif minutes > 0
40
+ "%d minutes" % [minutes]
41
+ else
42
+ "%d seconds" % [seconds]
43
+ end
44
+
45
+ past ? "%s ago" % time : time
46
+ end
47
+
48
+ def pins
49
+ api.characters.each do |toon|
50
+ logger.debug("Processing toon %s" % toon.name)
51
+ api.planets(toon).each do |planet|
52
+ logger.debug("Processing planet %s" % planet.planetName)
53
+ api.planet_pins(toon, planet).sort_by{|p| p.planetName}.each do |pin|
54
+ yield(toon, planet, pin)
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ def notifications
61
+ notifications = {
62
+ :template => "templates/pi.erb",
63
+ :subject => "Eve PI",
64
+ :data => {}
65
+ }
66
+
67
+ pins do |toon, planet, pin|
68
+ next if pin.expiryTime.year == 1
69
+
70
+ time_till_expire = pin.expiryTime - Time.now.utc
71
+ logger.debug("%s expires in %s / %s (%s)" % [planet.planetName, time_till_expire, seconds_to_human(time_till_expire), pin.expiryTime])
72
+
73
+ seen[:planets][toon.name] ||= {}
74
+
75
+ if (time_till_expire < 600) && (time_till_expire > -86400)
76
+ if seen[:planets][toon.name][planet.planetName]
77
+ next
78
+ else
79
+ seen[:planets][toon.name][planet.planetName] = true
80
+ end
81
+
82
+ notifications[:data][toon.name] ||= []
83
+ notifications[:data][toon.name] << {
84
+ :name => planet.planetName,
85
+ :time_till_expire => seconds_to_human(time_till_expire),
86
+ :expire_time => pin.expiryTime
87
+ }
88
+ else
89
+ seen[:planets][toon.name].delete(planet.planetName)
90
+ end
91
+ end
92
+
93
+ notifications[:seen] = seen
94
+ notifications
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,38 @@
1
+ require 'pushover'
2
+
3
+ class EMN
4
+ class Notifier
5
+ class Pushover
6
+ attr_reader :config, :logger, :debug
7
+
8
+ def initialize(config, debug=false)
9
+ @config = config
10
+ @logger = config.logger
11
+ @debug = debug
12
+ end
13
+
14
+ def api
15
+ ::Pushover.user = config[:pushover][:user_token]
16
+ ::Pushover.token = config[:pushover][:app_token]
17
+ ::Pushover
18
+ end
19
+
20
+ def publish(message, subject)
21
+ if debug
22
+ logger.debug("Would have published the message: ")
23
+ puts message
24
+ return true
25
+ else
26
+ responce = api.notification(:html => 1, :title => subject, :message => message)
27
+
28
+ if responce.code == 200
29
+ return true
30
+ else
31
+ STDERR.puts("Failed to notify pushover: %s" % responce.inspect)
32
+ return false
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
data/lib/emn/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class EMN
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
data/lib/emn.rb CHANGED
@@ -1,10 +1,15 @@
1
1
  require 'eaal'
2
2
  require 'yaml'
3
- require 'pushover'
4
3
  require 'optparse'
5
4
  require 'pp'
6
5
  require 'logger'
7
6
  require 'emn/version'
7
+ require 'emn/config'
8
+ require 'emn/eve_api'
9
+ require 'emn/monitor/mail'
10
+ require 'emn/monitor/pi'
11
+ require 'emn/notifier/pushover'
12
+ require 'tilt/erb'
8
13
 
9
14
  class EMN
10
15
  OPTIONS = {
@@ -12,17 +17,9 @@ class EMN
12
17
  :debug => false,
13
18
  :config => File.expand_path("~/.emn"),
14
19
  :seen => File.expand_path("~/.emn_seen"),
15
- :logger => nil
20
+ :checkers => []
16
21
  }
17
22
 
18
- def logger
19
- if OPTIONS[:debug] || OPTIONS[:verbose]
20
- return Logger.new(STDOUT)
21
- else
22
- return Logger.new(nil)
23
- end
24
- end
25
-
26
23
  def parse_options
27
24
  opt = OptionParser.new
28
25
 
@@ -45,149 +42,58 @@ class EMN
45
42
  OPTIONS[:seen] = File.expand_path(v)
46
43
  end
47
44
 
45
+ opt.on("--pi", "Check PI extractor cycles") do
46
+ OPTIONS[:checkers] << EMN::Monitor::Pi
47
+ end
48
+
49
+ opt.on("--mail", "Check for new emails") do
50
+ OPTIONS[:checkers] << EMN::Monitor::Mail
51
+ end
52
+
48
53
  opt.separator ""
49
54
  opt.separator "http://github.com/ripienaar/emn"
50
55
 
51
56
  opt.parse!
52
57
 
53
- logger.info("emn %s starting with config %s and seen file %s" % [ EMN::VERSION, OPTIONS[:config], OPTIONS[:seen]])
54
- end
55
-
56
- def config
57
- @config ||= YAML.load(File.read(File.expand_path(OPTIONS[:config])))
58
+ if OPTIONS[:checkers].empty?
59
+ abort("Please specify either --mail, --pi or both")
60
+ end
58
61
  end
59
62
 
60
- def seen
61
- @seen ||= YAML.load(File.read(File.expand_path(OPTIONS[:seen])))
62
- rescue
63
- @seen = {}
63
+ def logger
64
+ config.logger
64
65
  end
65
66
 
66
- def save_seen!
67
- return if OPTIONS[:debug]
68
-
69
- File.open(File.expand_path(OPTIONS[:seen]), "w") do |file|
70
- file.puts seen.to_yaml
71
- end
67
+ def config
68
+ @config ||= EMN::Config.new(OPTIONS[:config], OPTIONS[:seen])
72
69
  end
73
70
 
74
71
  def pushover
75
- Pushover.user = config[:pushover][:user_token]
76
- Pushover.token = config[:pushover][:app_token]
77
- Pushover
72
+ @pushover_api ||= Notifier::Pushover.new(config, OPTIONS[:debug])
78
73
  end
79
74
 
80
75
  def eve_api
81
- unless EAAL.cache.is_a?(EAAL::Cache::FileCache)
82
- EAAL.cache = EAAL::Cache::FileCache.new
83
- end
84
-
85
- @eve_api ||= EAAL::API.new(
86
- config[:eve][:key_id],
87
- config[:eve][:verification_code]
88
- )
76
+ @eve_api ||= EveAPI.new(config)
89
77
  end
90
78
 
91
- def mails(char)
92
- eve_api.scope = "char"
93
- eve_api.MailMessages("characterID" => char.characterID).messages.sort_by{|m| m.messageID}
94
- end
95
-
96
- def characters
97
- eve_api.scope = "account"
98
- eve_api.Characters.characters
99
- end
100
-
101
- def check_mail
102
- notifications = {}
103
-
104
- characters.each do |toon|
105
- logger.debug("Checking character %s" % toon.name)
106
-
107
- messages = mails(toon)
79
+ def process!
80
+ OPTIONS[:checkers].each do |klass|
81
+ checker = klass.new(config)
82
+ logger.debug("Processing %s" % checker.class)
108
83
 
109
- logger.debug("Found %d messages for %s" % [messages.size, toon.name])
84
+ notifications = checker.notifications
110
85
 
111
- messages.each do |mail|
112
- logger.debug("Processing email %s: from: %s subject: %s" % [mail.messageID, mail.senderName, mail.title])
86
+ unless notifications[:data].empty?
87
+ template_file = File.expand_path(File.join(File.dirname(__FILE__), "..", notifications[:template]))
88
+ logger.debug("Sending notifications using template %s" % template_file)
113
89
 
114
- seen[toon.name] ||= "0"
90
+ template = Tilt::ERBTemplate.new(template_file)
91
+ output = template.render(:data => notifications[:data], :config => config)
115
92
 
116
- if seen[toon.name] < mail.messageID
117
- seen[toon.name] = mail.messageID
118
-
119
- if mail.senderName == toon.name
120
- logger.debug("Skipping mail %s as it's from the character" % mail.messageID)
121
- next
122
- end
123
-
124
- logger.debug("Adding email %s: %s to the queue" % [mail.messageID, mail.title])
125
-
126
- notifications[toon.name] ||= []
127
- notifications[toon.name] << {
128
- :from => mail.senderName,
129
- :date => mail.sentDate,
130
- :subject => mail.title
131
- }
132
- else
133
- logger.debug("Skipping email %s: it's been seen before (%s)" % [mail.messageID, seen[toon.name]])
93
+ if pushover.publish(output, notifications[:subject])
94
+ config.save_seen!(config.seen.merge(notifications[:seen]))
134
95
  end
135
96
  end
136
97
  end
137
-
138
- notifications.empty? ? nil : notifications
139
- end
140
-
141
- def message_body(notifications)
142
- summary = ["<b>"]
143
- body = []
144
-
145
- notifications.keys.sort.each do |toon|
146
- summary << "%s: %d " % [toon, notifications[toon].size]
147
-
148
- body << "<b>%s</b>" % toon
149
- notifications[toon].reverse[0..config[:max_notifications] - 1].each do |notification|
150
- body << " %s: %s" % [notification[:from], notification[:subject]]
151
- end
152
-
153
- if notifications[toon].size > config[:max_notifications]
154
- body << " ... and %d more" % [notifications[toon].size - config[:max_notifications]]
155
- end
156
-
157
- body << ""
158
- end
159
-
160
- summary << "</b>"
161
-
162
- [summary, "", body].flatten.join("\n")
163
- end
164
-
165
- def publish(message)
166
- if OPTIONS[:debug]
167
- logger.debug("Would have published the message: ")
168
- puts message
169
- return true
170
- else
171
- responce = pushover.notification(:html => 1, :message => message)
172
-
173
- if responce.code == 200
174
- return true
175
- else
176
- STDERR.puts("Failed to notify pushover: %s" % responce.inspect)
177
- return false
178
- end
179
- end
180
- end
181
-
182
- def send!
183
- if notifications = check_mail
184
- logger.debug("Found mail for %d characters" % [notifications.keys.size])
185
-
186
- if publish(message_body(notifications))
187
- save_seen!
188
- end
189
- else
190
- logger.debug("No new mail found, not sending any messages")
191
- end
192
98
  end
193
99
  end
@@ -0,0 +1,22 @@
1
+ <b>
2
+ <%=
3
+ self[:data].keys.sort.map do |toon|
4
+ "%s: %s" % [toon, self[:data][toon].size]
5
+ end.join("\n")
6
+ %>
7
+ </b>
8
+
9
+ <% self[:data].keys.sort.map do |toon| %>
10
+ <b><%= toon %>:</b>
11
+ <%=
12
+ self[:data][toon].reverse[0..self[:config][:max_notifications] - 1].map do |notification|
13
+ " %s: %s" % [notification[:from], notification[:subject]]
14
+ end.join("\n")
15
+ %>
16
+ <%=
17
+ if self[:data][toon].size > self[:config][:max_notifications]
18
+ " ... and %d more" % [self[:data][toon].size - self[:config][:max_notifications]]
19
+ end
20
+ %>
21
+
22
+ <% end %>
data/templates/pi.erb ADDED
@@ -0,0 +1,6 @@
1
+ <% self[:data].keys.sort.each do |toon| %>
2
+ <b><%= toon %>:</b>
3
+ <% self[:data][toon].each do |planet| %>
4
+ <%= " %s: %s\n" % [planet[:name], planet[:time_till_expire]] %>
5
+ <% end %>
6
+ <% end %>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: emn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - R.I.Pienaar
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-29 00:00:00.000000000 Z
11
+ date: 2015-08-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: eaal
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: tilt
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  description: Get Pushover notification when your characters get mail
42
56
  email: rip@devco.net
43
57
  executables:
@@ -47,7 +61,14 @@ extra_rdoc_files: []
47
61
  files:
48
62
  - bin/emn
49
63
  - lib/emn.rb
64
+ - lib/emn/notifier/pushover.rb
50
65
  - lib/emn/version.rb
66
+ - lib/emn/eve_api.rb
67
+ - lib/emn/config.rb
68
+ - lib/emn/monitor/mail.rb
69
+ - lib/emn/monitor/pi.rb
70
+ - templates/mail.erb
71
+ - templates/pi.erb
51
72
  homepage: https://github.com/ripienaar/eve_mail_notifier
52
73
  licenses: []
53
74
  metadata: {}