popper 0.1.8 → 0.2.0
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 +4 -4
- data/README.md +15 -12
- data/init_script/cent7/etc/systemd/system/popper.service +17 -0
- data/lib/popper.rb +4 -3
- data/lib/popper/action/base.rb +5 -14
- data/lib/popper/action/ghe.rb +4 -4
- data/lib/popper/action/git.rb +5 -5
- data/lib/popper/action/slack.rb +8 -8
- data/lib/popper/cli.rb +50 -6
- data/lib/popper/config.rb +11 -4
- data/lib/popper/init.rb +8 -6
- data/lib/popper/mail_account.rb +100 -0
- data/lib/popper/version.rb +1 -1
- metadata +4 -4
- data/lib/popper/pop.rb +0 -125
- data/lib/popper/sync.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4c3c075a3c44288b2c8f7ed3e5dd890ef946f2bd
|
4
|
+
data.tar.gz: b60b17cfa8c19e4fda90dd8d6ab9639072744fb6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 15c20311b6c773f3744f99c7909dbda33a3df4cca2dd2b49fac0af3196e65426494ff70ee18828ceca365af157dd492d174c315004bb4f0b9e280636cc6dd5b9
|
7
|
+
data.tar.gz: b8abc1581a23478b5806580dcce98660c9135d7da6e08bf90b21c1e198504019b666983d525f3c49a145714c06e42db7d581b8bdb556d6f3140c6a15d9b58437
|
data/README.md
CHANGED
@@ -13,26 +13,25 @@ To post a variety of services by analyzing the email
|
|
13
13
|
|
14
14
|
# usage
|
15
15
|
```
|
16
|
-
# create
|
16
|
+
# create /etc/popper.conf
|
17
17
|
$ popper init
|
18
18
|
|
19
19
|
# edit popper.conf
|
20
|
-
$ vi
|
20
|
+
$ vi /etc/popper.conf
|
21
21
|
|
22
|
-
#
|
23
|
-
|
24
|
-
$ popper prepop
|
22
|
+
# print config
|
23
|
+
$ popper print
|
25
24
|
|
26
|
-
$ popper
|
27
|
-
```
|
28
|
-
`crontab -l`
|
29
|
-
```
|
30
|
-
* * * * * /path/to/popper
|
25
|
+
$ popper --daemon --config /etc/popper.conf --log /var/log/popper.log --pidfile /var/run/popper/popper.pid
|
31
26
|
```
|
27
|
+
systmd service config: https://github.com/pyama86/popper/tree/master/init_script/cent7/etc/systemd/system/popper.service
|
32
28
|
|
33
29
|
# configure(toml)
|
34
30
|
## ~/popper/popper.conf
|
35
31
|
```
|
32
|
+
[global]
|
33
|
+
interval = 60 # fetch interbal default:60
|
34
|
+
|
36
35
|
[default.condition]
|
37
36
|
|
38
37
|
subject = ["^(?!.*Re:).+$"]
|
@@ -82,8 +81,12 @@ user = "example2@example.com"
|
|
82
81
|
```
|
83
82
|
|
84
83
|
# option
|
85
|
-
|
86
|
-
|
84
|
+
```
|
85
|
+
-c, [--config=CONFIG]
|
86
|
+
-l, [--log=LOG]
|
87
|
+
-d, [--daemon], [--no-daemon]
|
88
|
+
-p, [--pidfile=PIDFILE]
|
89
|
+
```
|
87
90
|
|
88
91
|
# author
|
89
92
|
* pyama
|
@@ -0,0 +1,17 @@
|
|
1
|
+
[Unit]
|
2
|
+
Description=Popper
|
3
|
+
Requires=network.target
|
4
|
+
After=network.target
|
5
|
+
|
6
|
+
[Service]
|
7
|
+
Type=forking
|
8
|
+
User=root
|
9
|
+
|
10
|
+
Restart=always
|
11
|
+
RestartSec=120
|
12
|
+
|
13
|
+
ExecStart=/usr/local/bin/popper --daemon --config /etc/popper.conf --log /var/log/popper.log --pidfile /var/run/popper/popper.pid
|
14
|
+
PIDFile=/var/run/popper/popper.pid
|
15
|
+
|
16
|
+
[Install]
|
17
|
+
WantedBy=multi-user.target
|
data/lib/popper.rb
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
require 'pp'
|
2
2
|
require "popper/version"
|
3
3
|
require "popper/cli"
|
4
|
-
require 'popper/
|
4
|
+
require 'popper/mail_account'
|
5
5
|
require "popper/config"
|
6
6
|
require "popper/action"
|
7
7
|
require "popper/init"
|
8
|
-
require "popper/sync"
|
9
8
|
|
10
9
|
module Popper
|
11
10
|
def self.init_logger(options, stdout=nil)
|
12
|
-
log_path = options[:log] ||
|
11
|
+
log_path = options[:log] || "/var/log/popper.log"
|
13
12
|
log_path = STDOUT if ENV["POPPER_TEST"] || stdout
|
14
13
|
@_logger = Logger.new(log_path)
|
14
|
+
rescue => e
|
15
|
+
puts e
|
15
16
|
end
|
16
17
|
|
17
18
|
def self.log
|
data/lib/popper/action/base.rb
CHANGED
@@ -2,14 +2,14 @@ module Popper::Action
|
|
2
2
|
class Base
|
3
3
|
@next_action = nil
|
4
4
|
@action = nil
|
5
|
-
@
|
5
|
+
@action_config = nil
|
6
6
|
|
7
7
|
def self.run(config, mail, params={})
|
8
|
-
|
8
|
+
@action_config = config.send(self.action) if config.respond_to?(self.action)
|
9
9
|
if action?
|
10
10
|
begin
|
11
11
|
Popper.log.info "run action #{self.action}"
|
12
|
-
params = task(
|
12
|
+
params = task(mail, params)
|
13
13
|
Popper.log.info "exit action #{self.action}"
|
14
14
|
rescue => e
|
15
15
|
Popper.log.warn e
|
@@ -34,17 +34,8 @@ module Popper::Action
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def self.action?
|
37
|
-
|
37
|
+
@action_config && check_params
|
38
38
|
end
|
39
|
-
|
40
|
-
def self.set_config(config)
|
41
|
-
@_config = config.send(self.action) if config.respond_to?(self.action)
|
42
|
-
end
|
43
|
-
|
44
|
-
def self.my_config
|
45
|
-
@_config
|
46
|
-
end
|
47
|
-
|
48
|
-
def self.check_params(config); end
|
39
|
+
def self.check_params; end
|
49
40
|
end
|
50
41
|
end
|
data/lib/popper/action/ghe.rb
CHANGED
@@ -5,14 +5,14 @@ module Popper::Action
|
|
5
5
|
def self.octkit
|
6
6
|
Octokit.reset!
|
7
7
|
Octokit.configure do |c|
|
8
|
-
c.web_endpoint =
|
9
|
-
c.api_endpoint = File.join(
|
8
|
+
c.web_endpoint = @action_config.url
|
9
|
+
c.api_endpoint = File.join(@action_config.url, "api/v3")
|
10
10
|
end
|
11
|
-
Octokit::Client.new(:access_token =>
|
11
|
+
Octokit::Client.new(:access_token => @action_config.token)
|
12
12
|
end
|
13
13
|
|
14
14
|
def self.check_params
|
15
|
-
|
15
|
+
@action_config.respond_to?(:url) && super
|
16
16
|
end
|
17
17
|
|
18
18
|
next_action(Slack)
|
data/lib/popper/action/git.rb
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
require 'octokit'
|
3
3
|
module Popper::Action
|
4
4
|
class Git < Base
|
5
|
-
def self.task(
|
5
|
+
def self.task(mail, params={})
|
6
6
|
url = octkit.create_issue(
|
7
|
-
|
7
|
+
@action_config.repo,
|
8
8
|
mail.subject,
|
9
9
|
mail.body
|
10
10
|
)
|
@@ -14,12 +14,12 @@ module Popper::Action
|
|
14
14
|
|
15
15
|
def self.octkit
|
16
16
|
Octokit.reset!
|
17
|
-
Octokit::Client.new(:access_token =>
|
17
|
+
Octokit::Client.new(:access_token => @action_config.token)
|
18
18
|
end
|
19
19
|
|
20
20
|
def self.check_params
|
21
|
-
|
22
|
-
|
21
|
+
@action_config.respond_to?(:repo) &&
|
22
|
+
@action_config.respond_to?(:token)
|
23
23
|
end
|
24
24
|
|
25
25
|
next_action(Ghe)
|
data/lib/popper/action/slack.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
require 'slack-notifier'
|
2
2
|
module Popper::Action
|
3
3
|
class Slack < Base
|
4
|
-
def self.task(
|
4
|
+
def self.task(mail, params={})
|
5
5
|
notifier = ::Slack::Notifier.new(
|
6
|
-
|
7
|
-
channel:
|
8
|
-
username:
|
6
|
+
@action_config.webhook_url,
|
7
|
+
channel: @action_config.channel,
|
8
|
+
username: @action_config.user || 'popper',
|
9
9
|
link_names: 1
|
10
10
|
)
|
11
11
|
|
@@ -15,8 +15,8 @@ module Popper::Action
|
|
15
15
|
color: "good"
|
16
16
|
}
|
17
17
|
|
18
|
-
body =
|
19
|
-
body += " #{
|
18
|
+
body = @action_config.message || "popper mail notification"
|
19
|
+
body += " #{@action_config.mentions.join(" ")}" if @action_config.mentions
|
20
20
|
%w(
|
21
21
|
git
|
22
22
|
ghe
|
@@ -28,8 +28,8 @@ module Popper::Action
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def self.check_params
|
31
|
-
|
32
|
-
|
31
|
+
@action_config.respond_to?(:channel) &&
|
32
|
+
@action_config.respond_to?(:webhook_url)
|
33
33
|
end
|
34
34
|
|
35
35
|
action(:slack)
|
data/lib/popper/cli.rb
CHANGED
@@ -5,22 +5,39 @@ module Popper
|
|
5
5
|
class CLI < Thor
|
6
6
|
class_option :config, type: :string, aliases: '-c'
|
7
7
|
class_option :log, type: :string, aliases: '-l'
|
8
|
+
class_option :daemon, type: :boolean, aliases: '-d'
|
9
|
+
class_option :pidfile, type: :string, aliases: '-p'
|
8
10
|
default_task :pop
|
9
11
|
desc "pop", "from pop3"
|
10
12
|
def pop
|
13
|
+
if(options[:daemon])
|
14
|
+
Popper.init_logger(options)
|
15
|
+
Process.daemon
|
16
|
+
open(options[:pidfile] || "/var/run/popper.pid" , 'w') {|f| f << Process.pid}
|
17
|
+
else
|
18
|
+
Popper.init_logger(options, true)
|
19
|
+
end
|
20
|
+
|
11
21
|
Popper.load_config(options)
|
12
|
-
|
13
|
-
Popper
|
22
|
+
|
23
|
+
accounts = Popper.configure.accounts.map {|account| MailAccount.new(account)}
|
24
|
+
while true
|
25
|
+
accounts.each(&:run)
|
26
|
+
sleep(60 || Popper.configure.global.interval)
|
27
|
+
end
|
28
|
+
|
14
29
|
rescue => e
|
15
30
|
Popper.log.fatal(e)
|
16
31
|
Popper.log.fatal(e.backtrace)
|
17
32
|
end
|
18
33
|
|
19
|
-
|
20
|
-
|
34
|
+
class_option :config, type: :string, aliases: '-c'
|
35
|
+
desc "print", "print configure"
|
36
|
+
def print
|
21
37
|
Popper.load_config(options)
|
22
|
-
Popper.
|
23
|
-
|
38
|
+
Popper.configure.accounts.each do |account|
|
39
|
+
print_config(account)
|
40
|
+
end
|
24
41
|
end
|
25
42
|
|
26
43
|
desc "init", "create home dir"
|
@@ -36,5 +53,32 @@ module Popper
|
|
36
53
|
def __print_version
|
37
54
|
puts "Popper version:#{Popper::VERSION}"
|
38
55
|
end
|
56
|
+
|
57
|
+
no_commands do
|
58
|
+
def print_config(config)
|
59
|
+
puts config.name
|
60
|
+
last_rule = nil
|
61
|
+
last_header = nil
|
62
|
+
|
63
|
+
config.rule_with_conditions_all? do |rule,mail_header,condition|
|
64
|
+
puts " "*1 + "rule[#{rule}]" if rule != last_rule
|
65
|
+
puts " "*2 + "actions" if rule != last_rule
|
66
|
+
|
67
|
+
config.action_by_rule(rule).each_pair do |action,params|
|
68
|
+
puts " "*3 + "#{action}"
|
69
|
+
params.each_pair do |k,v|
|
70
|
+
puts " "*4 + "#{k} #{v}"
|
71
|
+
end
|
72
|
+
end if rule != last_rule
|
73
|
+
|
74
|
+
puts " "*2 + "header[#{mail_header}]" if mail_header != last_header
|
75
|
+
puts " "*3 + "#{condition}"
|
76
|
+
|
77
|
+
last_rule = rule
|
78
|
+
last_header = mail_header
|
79
|
+
true
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
39
83
|
end
|
40
84
|
end
|
data/lib/popper/config.rb
CHANGED
@@ -3,15 +3,16 @@ require 'ostruct'
|
|
3
3
|
require 'logger'
|
4
4
|
module Popper
|
5
5
|
class Config
|
6
|
-
attr_reader :default, :accounts
|
6
|
+
attr_reader :global, :default, :accounts
|
7
7
|
def initialize(config_path)
|
8
8
|
raise "configure not fond #{config_path}" unless File.exist?(config_path)
|
9
9
|
|
10
10
|
config = TOML.load_file(config_path)
|
11
|
+
@global = AccountAttributes.new(config["global"]) if config["global"]
|
11
12
|
@default = AccountAttributes.new(config["default"]) if config["default"]
|
12
13
|
@accounts = []
|
13
14
|
|
14
|
-
config.select {|k,v| !%w(default).include?(k) }.each do |account|
|
15
|
+
config.select {|k,v| !%w(default global).include?(k) }.each do |account|
|
15
16
|
_account = AccountAttributes.new(account[1])
|
16
17
|
_account.name = account[0]
|
17
18
|
@accounts << _account
|
@@ -66,11 +67,17 @@ module Popper
|
|
66
67
|
end
|
67
68
|
end
|
68
69
|
|
69
|
-
|
70
|
+
def rule_with_conditions_all?(&block)
|
71
|
+
rules.to_h.keys.find do |rule|
|
72
|
+
condition_by_rule(rule).to_h.all? do |mail_header,conditions|
|
73
|
+
block.call(rule, mail_header, conditions)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
70
77
|
end
|
71
78
|
|
72
79
|
def self.load_config(options)
|
73
|
-
config_path = options[:config] ||
|
80
|
+
config_path = options[:config] || "/etc/popper.conf"
|
74
81
|
@_config = Config.new(config_path)
|
75
82
|
end
|
76
83
|
|
data/lib/popper/init.rb
CHANGED
@@ -1,18 +1,20 @@
|
|
1
1
|
module Popper
|
2
2
|
class Init
|
3
3
|
def self.run(options)
|
4
|
-
|
5
|
-
unless FileTest.exist?(
|
6
|
-
|
7
|
-
open("#{dirname}/popper.conf","w") do |e|
|
4
|
+
filename = options[:config] || "/etc/popper.conf"
|
5
|
+
unless FileTest.exist?(filename)
|
6
|
+
open(filename,"w") do |e|
|
8
7
|
e.puts sample_config
|
9
|
-
end
|
10
|
-
puts "create
|
8
|
+
end
|
9
|
+
puts "create sample config #{filename}"
|
11
10
|
end
|
12
11
|
end
|
13
12
|
|
14
13
|
def self.sample_config
|
15
14
|
<<-EOS
|
15
|
+
[global]
|
16
|
+
interval = 60 # fetch interbal default:60
|
17
|
+
|
16
18
|
[default.condition]
|
17
19
|
subject = ["^(?!.*Re:).+$"]
|
18
20
|
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'net/pop'
|
2
|
+
require 'mail'
|
3
|
+
require 'kconv'
|
4
|
+
|
5
|
+
module Popper
|
6
|
+
class MailAccount
|
7
|
+
def initialize(config)
|
8
|
+
@config = config
|
9
|
+
end
|
10
|
+
|
11
|
+
def run
|
12
|
+
session_start do |conn|
|
13
|
+
@current_uidl_list = conn.mails.map(&:uidl)
|
14
|
+
@complete_uidl_list = @current_uidl_list unless @complete_uidl_list
|
15
|
+
pop(conn)
|
16
|
+
end
|
17
|
+
rescue => e
|
18
|
+
Popper.log.warn e
|
19
|
+
end
|
20
|
+
|
21
|
+
def pop(conn)
|
22
|
+
done_uidls = []
|
23
|
+
error_uidls = []
|
24
|
+
|
25
|
+
Popper.log.info "start popper #{@config.name}"
|
26
|
+
|
27
|
+
process_uidl_list(conn).each do |m|
|
28
|
+
begin
|
29
|
+
mail = EncodeMail.new(m.mail)
|
30
|
+
Popper.log.info "check mail:#{mail.date.to_s} #{mail.subject}"
|
31
|
+
|
32
|
+
if rule = match_rule?(mail)
|
33
|
+
Popper.log.info "do action:#{mail.subject}"
|
34
|
+
Popper::Action::Git.run(@config.action_by_rule(rule), mail) if @config.action_by_rule(rule)
|
35
|
+
end
|
36
|
+
done_uidls << m.uidl
|
37
|
+
|
38
|
+
rescue Net::POPError => e
|
39
|
+
@complete_uidl_list += done_uidls
|
40
|
+
Popper.log.warn "pop err write uidl"
|
41
|
+
return
|
42
|
+
rescue => e
|
43
|
+
error_uidls << m.uidl
|
44
|
+
Popper.log.warn e
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
@complete_uidl_list = @current_uidl_list - error_uidls
|
49
|
+
Popper.log.info "success popper #{@config.name}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def session_start(&block)
|
53
|
+
pop = Net::POP3.new(@config.login.server, @config.login.port || 110)
|
54
|
+
pop.open_timeout = ENV['POP_TIMEOUT'] || 120
|
55
|
+
pop.read_timeout = ENV['POP_TIMEOUT'] || 120
|
56
|
+
pop.start(
|
57
|
+
@config.login.user,
|
58
|
+
@config.login.password
|
59
|
+
) do |pop|
|
60
|
+
Popper.log.info "connect server #{@config.name}"
|
61
|
+
block.call(pop)
|
62
|
+
Popper.log.info "disconnect server #{@config.name}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def process_uidl_list(conn)
|
67
|
+
uidl_list = @current_uidl_list - @complete_uidl_list
|
68
|
+
conn.mails.select {|_m|uidl_list.include?(_m.uidl)}
|
69
|
+
end
|
70
|
+
|
71
|
+
def match_rule?(mail)
|
72
|
+
@config.rule_with_conditions_all? do |rule, mail_header, conditions|
|
73
|
+
conditions.all? do |condition|
|
74
|
+
mail.respond_to?(mail_header) && mail.send(mail_header).to_s.match(/#{condition}/)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class ::Hash
|
82
|
+
def deep_merge(second)
|
83
|
+
merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : Array === v1 && Array === v2 ? v1 | v2 : [:undefined, nil, :nil].include?(v2) ? v1 : v2 }
|
84
|
+
self.merge(second.to_h, &merger)
|
85
|
+
end
|
86
|
+
|
87
|
+
def deep_merge!(second)
|
88
|
+
self.merge!(deep_merge(second))
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class EncodeMail < Mail::Message
|
93
|
+
def subject
|
94
|
+
Kconv.toutf8(self[:Subject].value) if self[:Subject]
|
95
|
+
end
|
96
|
+
|
97
|
+
def body
|
98
|
+
super.decoded.encode("UTF-8", self.charset)
|
99
|
+
end
|
100
|
+
end
|
data/lib/popper/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: popper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- pyama86
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-11-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -139,6 +139,7 @@ files:
|
|
139
139
|
- bin/console
|
140
140
|
- bin/setup
|
141
141
|
- exe/popper
|
142
|
+
- init_script/cent7/etc/systemd/system/popper.service
|
142
143
|
- lib/popper.rb
|
143
144
|
- lib/popper/action.rb
|
144
145
|
- lib/popper/action/base.rb
|
@@ -148,8 +149,7 @@ files:
|
|
148
149
|
- lib/popper/cli.rb
|
149
150
|
- lib/popper/config.rb
|
150
151
|
- lib/popper/init.rb
|
151
|
-
- lib/popper/
|
152
|
-
- lib/popper/sync.rb
|
152
|
+
- lib/popper/mail_account.rb
|
153
153
|
- lib/popper/version.rb
|
154
154
|
- popper.gemspec
|
155
155
|
homepage: http://ten-snapon.com
|
data/lib/popper/pop.rb
DELETED
@@ -1,125 +0,0 @@
|
|
1
|
-
require 'net/pop'
|
2
|
-
require 'mail'
|
3
|
-
require 'kconv'
|
4
|
-
module Popper
|
5
|
-
class Pop
|
6
|
-
def self.run
|
7
|
-
begin
|
8
|
-
Popper::Sync.synchronized do
|
9
|
-
Popper.configure.accounts.each do |account|
|
10
|
-
begin
|
11
|
-
pop(account)
|
12
|
-
rescue => e
|
13
|
-
Popper.log.warn e
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
rescue Locked
|
18
|
-
puts "There will be a running process"
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.pop(account)
|
23
|
-
done_uidls = []
|
24
|
-
error_uidls = []
|
25
|
-
Popper.log.info "start popper #{account.name}"
|
26
|
-
connection(account) do |pop|
|
27
|
-
current_uidls = pop.mails.map(&:uidl)
|
28
|
-
target_uidls = current_uidls - last_uidl(account.name)
|
29
|
-
pop.mails.select {|_m|target_uidls.include?(_m.uidl) }.each do |m|
|
30
|
-
begin
|
31
|
-
mail = EncodeMail.new(m.mail)
|
32
|
-
Popper.log.info "check mail:#{mail.date.to_s} #{mail.subject}"
|
33
|
-
if rule = matching?(account, mail)
|
34
|
-
Popper.log.info "do action:#{mail.subject}"
|
35
|
-
Popper::Action::Git.run(account.action_by_rule(rule), mail) if account.action_by_rule(rule)
|
36
|
-
end
|
37
|
-
done_uidls << m.uidl
|
38
|
-
rescue Net::POPError => e
|
39
|
-
last_uidl(account.name, last_uidl(account.name) + done_uidls)
|
40
|
-
raise e
|
41
|
-
rescue => e
|
42
|
-
error_uidls << m.uidl
|
43
|
-
Popper.log.warn e
|
44
|
-
end
|
45
|
-
end
|
46
|
-
# write cache
|
47
|
-
last_uidl(account.name, current_uidls - error_uidls)
|
48
|
-
Popper.log.info "success popper #{account.name}"
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def self.connection(account, &block)
|
53
|
-
pop = Net::POP3.new(account.login.server, account.login.port || 110)
|
54
|
-
pop.open_timeout = ENV['POP_TIMEOUT'] || 120
|
55
|
-
pop.read_timeout = ENV['POP_TIMEOUT'] || 120
|
56
|
-
pop.start(
|
57
|
-
account.login.user,
|
58
|
-
account.login.password
|
59
|
-
) do |pop|
|
60
|
-
Popper.log.info "connect server #{account.name}"
|
61
|
-
block.call(pop)
|
62
|
-
Popper.log.info "disconnect server #{account.name}"
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def self.matching?(account, mail)
|
67
|
-
account.rules.to_h.keys.find do |rule|
|
68
|
-
account.condition_by_rule(rule).to_h.all? do |header,conditions|
|
69
|
-
conditions.all? do |condition|
|
70
|
-
mail.respond_to?(header) && mail.send(header).to_s.match(/#{condition}/)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def self.last_uidl(account, uidl=nil)
|
77
|
-
path = File.join(Dir.home, "popper", ".#{account}.uidl")
|
78
|
-
@_uidl ||= {}
|
79
|
-
|
80
|
-
File.write(File.join(path), uidl.join("\n")) if uidl
|
81
|
-
|
82
|
-
@_uidl[account] ||= File.exist?(path) ? File.read(path).split(/\r?\n/) : []
|
83
|
-
@_uidl[account]
|
84
|
-
end
|
85
|
-
|
86
|
-
def self.prepop
|
87
|
-
Popper.configure.accounts.each do |account|
|
88
|
-
Popper.log.info "start prepop #{account.name}"
|
89
|
-
begin
|
90
|
-
connection(account) do |pop|
|
91
|
-
uidls = pop.mails.map(&:uidl)
|
92
|
-
last_uidl(
|
93
|
-
account.name,
|
94
|
-
uidls
|
95
|
-
)
|
96
|
-
Popper.log.info "success prepop #{account.name} mail count:#{uidls.count}"
|
97
|
-
end
|
98
|
-
rescue => e
|
99
|
-
Popper.log.warn e
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
class ::Hash
|
107
|
-
def deep_merge(second)
|
108
|
-
merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : Array === v1 && Array === v2 ? v1 | v2 : [:undefined, nil, :nil].include?(v2) ? v1 : v2 }
|
109
|
-
self.merge(second.to_h, &merger)
|
110
|
-
end
|
111
|
-
|
112
|
-
def deep_merge!(second)
|
113
|
-
self.merge!(deep_merge(second))
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
class EncodeMail < Mail::Message
|
118
|
-
def subject
|
119
|
-
Kconv.toutf8(self[:Subject].value) if self[:Subject]
|
120
|
-
end
|
121
|
-
|
122
|
-
def body
|
123
|
-
super.decoded.encode("UTF-8", self.charset)
|
124
|
-
end
|
125
|
-
end
|
data/lib/popper/sync.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
module Popper
|
2
|
-
class Locked < StandardError; end
|
3
|
-
class Sync
|
4
|
-
def self.synchronized
|
5
|
-
File.open(lockfile, 'w') do |_lockfile|
|
6
|
-
if _lockfile.flock(File::LOCK_EX|File::LOCK_NB)
|
7
|
-
yield
|
8
|
-
else
|
9
|
-
raise Locked
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.lockfile
|
15
|
-
File.join(Dir.home, "popper", "popper.lock")
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|