forked from zdavatz/bbmb
/
polling_manager.rb
155 lines (153 loc) · 4.34 KB
/
polling_manager.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/usr/bin/env ruby
# Util::PollingManager -- bbmb.ch -- 14.09.2006 -- hwyss@ywesee.com
require 'bbmb'
require 'bbmb/util/mail'
require 'fileutils'
require 'net/ftp'
require 'net/pop'
require 'tmpdir'
require 'uri'
require 'yaml'
module BBMB
module Util
class FileMission
attr_accessor :backup_dir, :delete, :directory, :glob_pattern
def file_paths
path = File.expand_path(@glob_pattern || '*', @directory)
res = Dir.glob(path).collect { |entry|
File.expand_path(entry, @directory)
}.compact
res
end
def poll(&block)
@directory = File.expand_path(@directory, BBMB.config.bbmb_dir) unless File.directory?(@directory) &&
File.absolute_path(@directory) == @directory
file_paths.each { |path|
poll_path(path, &block)
}
end
def poll_path(path, &block)
@backup_dir = BBMB.config.backup_dir if BBMB.config.respond_to?(:backup_dir)
@backup_dir ||= Dir.tmpdir
File.open(path) { |io|
block.call(File.basename(path), io)
}
rescue StandardError => err
BBMB::Util::Mail.notify_error(err)
ensure
if(@backup_dir)
if File.absolute_path(@backup_dir) == @backup_dir
dir = @backup_dir
else
dir = File.expand_path(@backup_dir, BBMB.config.bbmb_dir)
end
FileUtils.mkdir_p(dir)
FileUtils.cp(path, dir)
end
if(@delete)
FileUtils.rm(path)
end
end
end
class PopMission
attr_accessor :host, :port, :user, :pass, :content_type
@@ptrn = /name=(?:(?:(?<quote>['"])(?:=\?.+?\?[QB]\?)?(?<file>.*?)(\?=)?(?<!\\)\k<quote>)|(?:(?<file>.+?)(?:;|$)))/i
def poll(&block)
@backup_dir = BBMB.config.backup_dir if BBMB.config.respond_to?(:backup_dir)
@backup_dir ||= Dir.tmpdir
options = {
:address => @host,
:port => @port,
:user_name => @user,
:password => @pass,
:enable_ssl => true
}
::Mail.defaults do retriever_method :pop3, options end
all_mails = ::Mail.delivery_method.is_a?(::Mail::TestMailer) ? ::Mail::TestMailer.deliveries : ::Mail.all
all_mails.each do |mail|
begin
poll_message(mail, &block)
ensure
time = Time.now
name = sprintf("%s.%s.%s", @user, time.strftime("%Y%m%d%H%M%S"), time.usec)
FileUtils.mkdir_p(@backup_dir)
path = File.join(@backup_dir, name)
File.open(path, 'w') { |fh| fh.puts(mail) }
mail.mark_for_delete = true
# mail.delete # Not necessary with gem mail, as delete_after_find is set to true by default
end
end
end
def poll_message(message, &block)
if(message.multipart?)
message.parts.each do |part|
poll_message(part, &block)
end
elsif(/text\/xml/.match(message.content_type))
filtered_transaction(message.decoded, sprintf('pop3:%s@%s:%s', @user, @host, @port), &block)
elsif message.attachment?
block.call(message.filename, message.decoded)
end
end
end
class FtpMission
attr_accessor :backup_dir, :delete, :pattern, :directory
def initialize(*args)
super
@backup_dir = BBMB.config.backup_dir if BBMB.config.respond_to?(:backup_dir)
@backup_dir ||= Dir.tmpdir
@regexp = Regexp.new('.*')
end
def poll(&block)
FileUtils.mkdir_p(@backup_dir)
@regexp = Regexp.new(@pattern || '.*')
uri = URI.parse(@directory)
locals = []
Net::FTP.open(uri.host) do |ftp|
ftp.login uri.user, uri.password
ftp.chdir uri.path
ftp.nlst.each do |file|
if(local = poll_remote ftp, file)
locals.push local
end
end
end
locals.each do |path|
poll_file path, &block
end
end
def poll_file(path, &block)
File.open(path) { |io|
block.call(File.basename(path), io)
}
rescue StandardError => err
BBMB::Util::Mail.notify_error(err)
end
def poll_remote(ftp, file)
if(@regexp.match file)
local = File.join(@backup_dir, file)
ftp.get file, local
ftp.delete file if @delete
local
end
end
def regexp
end
end
class PollingManager
def load_sources(&block)
file = File.open(BBMB.config.polling_file)
YAML.load_documents(file) { |mission|
block.call(mission)
}
ensure
file.close if(file)
end
def poll_sources(&block)
load_sources { |source|
source.poll(&block)
}
end
end
end
end