xmlconv 1.0.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.
- data/.gemtest +0 -0
- data/History.txt +6 -0
- data/LICENSE +339 -0
- data/README.txt +29 -0
- data/Rakefile +37 -0
- data/bin/admin +68 -0
- data/bin/xmlconvd +38 -0
- data/data/grammar/i2.grammar +73 -0
- data/lib/xmlconv/config.rb +61 -0
- data/lib/xmlconv/custom/lookandfeel.rb +50 -0
- data/lib/xmlconv/i2/address.rb +35 -0
- data/lib/xmlconv/i2/date.rb +41 -0
- data/lib/xmlconv/i2/document.rb +27 -0
- data/lib/xmlconv/i2/header.rb +32 -0
- data/lib/xmlconv/i2/order.rb +61 -0
- data/lib/xmlconv/i2/parser.rb +23 -0
- data/lib/xmlconv/i2/position.rb +45 -0
- data/lib/xmlconv/i2/record.rb +11 -0
- data/lib/xmlconv/model/address.rb +20 -0
- data/lib/xmlconv/model/agreement.rb +10 -0
- data/lib/xmlconv/model/bdd.rb +37 -0
- data/lib/xmlconv/model/bsr.rb +16 -0
- data/lib/xmlconv/model/delivery.rb +15 -0
- data/lib/xmlconv/model/delivery_item.rb +24 -0
- data/lib/xmlconv/model/document.rb +25 -0
- data/lib/xmlconv/model/freetext_container.rb +26 -0
- data/lib/xmlconv/model/id_container.rb +22 -0
- data/lib/xmlconv/model/invoice.rb +18 -0
- data/lib/xmlconv/model/invoice_item.rb +11 -0
- data/lib/xmlconv/model/item.rb +19 -0
- data/lib/xmlconv/model/item_container.rb +15 -0
- data/lib/xmlconv/model/name.rb +27 -0
- data/lib/xmlconv/model/part_info.rb +10 -0
- data/lib/xmlconv/model/part_info_container.rb +15 -0
- data/lib/xmlconv/model/party.rb +20 -0
- data/lib/xmlconv/model/party_container.rb +20 -0
- data/lib/xmlconv/model/price.rb +10 -0
- data/lib/xmlconv/model/price_container.rb +18 -0
- data/lib/xmlconv/model/transaction.rb +28 -0
- data/lib/xmlconv/state/global.rb +28 -0
- data/lib/xmlconv/state/global_predefine.rb +11 -0
- data/lib/xmlconv/state/login.rb +39 -0
- data/lib/xmlconv/state/transaction.rb +13 -0
- data/lib/xmlconv/state/transactions.rb +130 -0
- data/lib/xmlconv/util/application.rb +142 -0
- data/lib/xmlconv/util/autoload.rb +35 -0
- data/lib/xmlconv/util/destination.rb +249 -0
- data/lib/xmlconv/util/invoicer.rb +71 -0
- data/lib/xmlconv/util/known_user.rb +16 -0
- data/lib/xmlconv/util/mail.rb +31 -0
- data/lib/xmlconv/util/polling_manager.rb +198 -0
- data/lib/xmlconv/util/session.rb +23 -0
- data/lib/xmlconv/util/transaction.rb +133 -0
- data/lib/xmlconv/util/validator.rb +20 -0
- data/lib/xmlconv/view/foot.rb +27 -0
- data/lib/xmlconv/view/head.rb +13 -0
- data/lib/xmlconv/view/login.rb +36 -0
- data/lib/xmlconv/view/navigation.rb +30 -0
- data/lib/xmlconv/view/navigationlink.rb +21 -0
- data/lib/xmlconv/view/pager.rb +73 -0
- data/lib/xmlconv/view/preformatted.rb +54 -0
- data/lib/xmlconv/view/template.rb +17 -0
- data/lib/xmlconv/view/transaction.rb +42 -0
- data/lib/xmlconv/view/transactions.rb +90 -0
- data/lib/xmlconv.rb +3 -0
- data/test/config.rb +12 -0
- data/test/mock.rb +149 -0
- data/test/suite.rb +16 -0
- data/test/test_i2/address.rb +88 -0
- data/test/test_i2/date.rb +50 -0
- data/test/test_i2/document.rb +62 -0
- data/test/test_i2/header.rb +39 -0
- data/test/test_i2/order.rb +94 -0
- data/test/test_i2/parser.rb +312 -0
- data/test/test_i2/position.rb +65 -0
- data/test/test_model/address.rb +35 -0
- data/test/test_model/agreement.rb +22 -0
- data/test/test_model/bdd.rb +55 -0
- data/test/test_model/bsr.rb +38 -0
- data/test/test_model/delivery.rb +79 -0
- data/test/test_model/delivery_item.rb +52 -0
- data/test/test_model/freetext_container.rb +45 -0
- data/test/test_model/invoice.rb +65 -0
- data/test/test_model/invoice_item.rb +41 -0
- data/test/test_model/name.rb +57 -0
- data/test/test_model/part_info.rb +24 -0
- data/test/test_model/party.rb +96 -0
- data/test/test_model/price.rb +24 -0
- data/test/test_util/application.rb +168 -0
- data/test/test_util/destination.rb +415 -0
- data/test/test_util/invoicer.rb +42 -0
- data/test/test_util/polling_manager.rb +299 -0
- data/test/test_util/transaction.rb +130 -0
- metadata +178 -0
@@ -0,0 +1,249 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Destination -- xmlconv2 -- 08.06.2004 -- hwyss@ywesee.com
|
3
|
+
|
4
|
+
require 'fileutils'
|
5
|
+
require 'uri'
|
6
|
+
require 'odba'
|
7
|
+
require 'net/http'
|
8
|
+
require 'net/ftp'
|
9
|
+
require 'tempfile'
|
10
|
+
|
11
|
+
module XmlConv
|
12
|
+
module Util
|
13
|
+
class Destination
|
14
|
+
include ODBA::Persistable
|
15
|
+
attr_accessor :path, :status
|
16
|
+
attr_reader :uri
|
17
|
+
STATUS_COMPARABLE = {
|
18
|
+
:pending_pickup => 10,
|
19
|
+
:picked_up => 20,
|
20
|
+
:bbmb_ok => 20,
|
21
|
+
:http_ok => 20,
|
22
|
+
:ftp_ok => 20,
|
23
|
+
:sftp_ok => 20,
|
24
|
+
:mail_ok => 20,
|
25
|
+
}
|
26
|
+
def Destination.book(str, tmp=nil)
|
27
|
+
uri = URI.parse(str)
|
28
|
+
tmp = URI.parse(tmp) if tmp
|
29
|
+
case uri.scheme.to_s.downcase
|
30
|
+
when 'http'
|
31
|
+
DestinationHttp.new(uri)
|
32
|
+
when 'ftp'
|
33
|
+
DestinationFtp.new(uri, tmp)
|
34
|
+
when 'sftp'
|
35
|
+
DestinationSftp.new(uri)
|
36
|
+
when 'mailto'
|
37
|
+
DestinationMail.new(uri)
|
38
|
+
else
|
39
|
+
DestinationDir.new(uri)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
def initialize
|
43
|
+
@status = :open
|
44
|
+
end
|
45
|
+
def deliver(delivery)
|
46
|
+
raise 'Abstract Method deliver called in Destination'
|
47
|
+
end
|
48
|
+
def update_status
|
49
|
+
end
|
50
|
+
def status_comparable
|
51
|
+
self::class::STATUS_COMPARABLE[@status].to_i
|
52
|
+
end
|
53
|
+
def sanitize(str)
|
54
|
+
str.to_s.gsub(/[^a-zA-Z0-9 _.]/, '').gsub(' ', '+')
|
55
|
+
end
|
56
|
+
def forget_credentials!
|
57
|
+
end
|
58
|
+
end
|
59
|
+
class DestinationDir < Destination
|
60
|
+
attr_reader :filename
|
61
|
+
def initialize(uri = URI.parse('/'))
|
62
|
+
@path = uri.path
|
63
|
+
super()
|
64
|
+
end
|
65
|
+
def deliver(delivery)
|
66
|
+
do_deliver(delivery)
|
67
|
+
@status = :pending_pickup
|
68
|
+
odba_store
|
69
|
+
end
|
70
|
+
def do_deliver(delivery)
|
71
|
+
if(delivery.is_a?(Array))
|
72
|
+
delivery.each { |part| do_deliver(part) }
|
73
|
+
else
|
74
|
+
FileUtils.mkdir_p(@path)
|
75
|
+
@filename = delivery.filename
|
76
|
+
path = File.expand_path(sanitize(@filename), @path)
|
77
|
+
File.open(path, 'w') { |fh| fh << delivery.to_s }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
def update_status
|
81
|
+
if(@status == :pending_pickup \
|
82
|
+
&& !File.exist?(File.expand_path(sanitize(@filename), @path)))
|
83
|
+
@status = :picked_up
|
84
|
+
odba_store
|
85
|
+
end
|
86
|
+
end
|
87
|
+
def uri
|
88
|
+
URI.parse("file:#{File.expand_path(sanitize(@filename), @path)}")
|
89
|
+
end
|
90
|
+
end
|
91
|
+
class RemoteDestination < Destination
|
92
|
+
attr_accessor :transport
|
93
|
+
def deliver(delivery)
|
94
|
+
do_deliver(delivery)
|
95
|
+
ensure
|
96
|
+
forget_credentials!
|
97
|
+
end
|
98
|
+
def forget_credentials!
|
99
|
+
@uri = URI::HTTP.new(@uri.scheme, nil, @uri.host, @uri.port,
|
100
|
+
@uri.registry, @uri.path, @uri.opaque, @uri.query, @uri.fragment)
|
101
|
+
end
|
102
|
+
def host
|
103
|
+
@uri.host
|
104
|
+
end
|
105
|
+
def host=(str)
|
106
|
+
@uri.host = str
|
107
|
+
end
|
108
|
+
def path
|
109
|
+
@uri.path if(@uri)
|
110
|
+
end
|
111
|
+
def path=(str)
|
112
|
+
@uri.path = str if(@uri)
|
113
|
+
end
|
114
|
+
def uri=(uri)
|
115
|
+
if(uri.is_a?(String))
|
116
|
+
@uri = URI.parse(uri)
|
117
|
+
else
|
118
|
+
@uri = uri
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
class DestinationFtp < RemoteDestination
|
123
|
+
def initialize(uri = URI.parse('ftp:/'), tmp = nil)
|
124
|
+
super()
|
125
|
+
@tmp = tmp
|
126
|
+
@uri = uri
|
127
|
+
@transport = Net::FTP
|
128
|
+
end
|
129
|
+
def do_deliver(delivery)
|
130
|
+
@transport.open(@uri.host, @uri.user, @uri.password) { |conn|
|
131
|
+
conn.chdir(@uri.path)
|
132
|
+
deliver_to_connection(conn, delivery)
|
133
|
+
}
|
134
|
+
end
|
135
|
+
def deliver_to_connection(connection, delivery, idx=nil)
|
136
|
+
if(delivery.is_a?(Array))
|
137
|
+
delivery.each_with_index { |part, idx|
|
138
|
+
deliver_to_connection(connection, part, idx)
|
139
|
+
}
|
140
|
+
else
|
141
|
+
fh = Tempfile.new('xmlconv')
|
142
|
+
fh.puts(delivery)
|
143
|
+
fh.flush
|
144
|
+
target = delivery.filename
|
145
|
+
if(idx)
|
146
|
+
target = sprintf("%03i_%s", idx, target)
|
147
|
+
end
|
148
|
+
if(@tmp)
|
149
|
+
tmp = File.join(@tmp.path, target)
|
150
|
+
connection.puttextfile(fh.path, tmp)
|
151
|
+
connection.rename(tmp, target)
|
152
|
+
else
|
153
|
+
connection.puttextfile(fh.path, target)
|
154
|
+
end
|
155
|
+
fh.close!
|
156
|
+
@status = :ftp_ok
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
class DestinationHttp < RemoteDestination
|
161
|
+
HTTP_HEADERS = {
|
162
|
+
'content-type' => 'text/xml',
|
163
|
+
}
|
164
|
+
def initialize(uri = URI.parse('http:/'))
|
165
|
+
super()
|
166
|
+
@uri = uri
|
167
|
+
@transport = Net::HTTP
|
168
|
+
end
|
169
|
+
def do_deliver(delivery)
|
170
|
+
if(delivery.is_a?(Array))
|
171
|
+
worst_status = ''
|
172
|
+
delivery.each { |part|
|
173
|
+
do_deliver(part)
|
174
|
+
## bogostatus: assume that the more information in the string,
|
175
|
+
## the worse the status is (ok < not found)
|
176
|
+
## rationale: DTSTTCPW
|
177
|
+
if(@status.to_s > worst_status.to_s)
|
178
|
+
worst_status = @status
|
179
|
+
end
|
180
|
+
}
|
181
|
+
@status = worst_status
|
182
|
+
else
|
183
|
+
@transport.start(@uri.host, @uri.port) { |http|
|
184
|
+
request = Net::HTTP::Post.new(@uri.path, HTTP_HEADERS)
|
185
|
+
if(@uri.user || @uri.password)
|
186
|
+
request.basic_auth(@uri.user, @uri.password)
|
187
|
+
end
|
188
|
+
response = http.request(request, delivery.to_s)
|
189
|
+
status_str = response.message.downcase.gsub(/\s+/, "_")
|
190
|
+
@status = "http_#{status_str}".intern
|
191
|
+
}
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
class DestinationMail < Destination
|
196
|
+
def initialize(uri = URI.parse('mailto:noone@nowhere.org'))
|
197
|
+
@uri = uri
|
198
|
+
super()
|
199
|
+
end
|
200
|
+
def deliver(delivery)
|
201
|
+
recipients = [@uri.to].compact
|
202
|
+
recipients.uniq!
|
203
|
+
return if(recipients.empty?)
|
204
|
+
subject = 'XmlConv - Delivery'
|
205
|
+
mail = TMail::Mail.new
|
206
|
+
mail.set_content_type('text', 'plain', 'charset'=>'ISO-8859-1')
|
207
|
+
mail.body = delivery.to_s
|
208
|
+
mail.from = XmlConv::CONFIG.mail_from
|
209
|
+
mail.to = recipients
|
210
|
+
mail.subject = subject
|
211
|
+
mail.date = Time.now
|
212
|
+
mail['User-Agent'] = 'XmlConv::Util::Destination'
|
213
|
+
Net::SMTP.start(XmlConv::CONFIG.mail_host) { |smtp|
|
214
|
+
smtp.sendmail(mail.encoded, XmlConv::CONFIG.mail_from, recipients)
|
215
|
+
}
|
216
|
+
@status = :mail_ok
|
217
|
+
odba_store
|
218
|
+
end
|
219
|
+
end
|
220
|
+
class DestinationSftp < RemoteDestination
|
221
|
+
def initialize(uri = URI.parse('sftp:/'))
|
222
|
+
require 'net/sftp'
|
223
|
+
super()
|
224
|
+
@uri = uri
|
225
|
+
@transport = Net::SFTP
|
226
|
+
end
|
227
|
+
def do_deliver(delivery)
|
228
|
+
@transport.start(@uri.host, @uri.user,
|
229
|
+
:user_known_hosts_file => CONFIG.ssh_known_hosts_file,
|
230
|
+
:keys => CONFIG.ssh_identities) { |conn|
|
231
|
+
deliver_to_connection(conn, delivery)
|
232
|
+
}
|
233
|
+
end
|
234
|
+
def deliver_to_connection(connection, delivery)
|
235
|
+
if(delivery.is_a?(Array))
|
236
|
+
delivery.each { |part|
|
237
|
+
deliver_to_connection(connection, part)
|
238
|
+
}
|
239
|
+
else
|
240
|
+
target = delivery.filename
|
241
|
+
connection.file.open(File.join(@uri.path, target), "w") do |fh|
|
242
|
+
fh.puts delivery
|
243
|
+
end
|
244
|
+
@status = :sftp_ok
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Util::Invoicer -- xmlconv2 -- 03.08.2006 -- hwyss@ywesee.com
|
3
|
+
|
4
|
+
require 'ydim/config'
|
5
|
+
require 'ydim/client'
|
6
|
+
|
7
|
+
module XmlConv
|
8
|
+
module Util
|
9
|
+
class Invoicer
|
10
|
+
class << self
|
11
|
+
def create_invoice(time_range, groups, date, currency='CHF')
|
12
|
+
time = Time.now
|
13
|
+
format = XmlConv::CONFIG.invoice_item_format
|
14
|
+
ydim_connect { |client|
|
15
|
+
ydim_inv = client.create_invoice(XmlConv::CONFIG.ydim_id)
|
16
|
+
ydim_inv.description = sprintf(XmlConv::CONFIG.invoice_format,
|
17
|
+
time_range.first.strftime("%d.%m.%Y"),
|
18
|
+
(time_range.last - 1).strftime("%d.%m.%Y"))
|
19
|
+
ydim_inv.date = date
|
20
|
+
ydim_inv.currency = currency
|
21
|
+
ydim_inv.payment_period = 30
|
22
|
+
default_rate = XmlConv::CONFIG.commission
|
23
|
+
item_data = groups.sort.collect { |group, bdds|
|
24
|
+
rate = XmlConv::CONFIG.group_commissions[group] || default_rate
|
25
|
+
amount = bdds.inject(0) { |memo, bdd| memo + bdd.invoiced_amount }
|
26
|
+
{
|
27
|
+
:price => (amount * rate) / 100.0,
|
28
|
+
:quantity => 1,
|
29
|
+
:text => sprintf(format, group.to_s, currency, amount, bdds.size),
|
30
|
+
:time => Time.local(date.year, date.month, date.day),
|
31
|
+
:unit => ("%3.2f%%" % rate).gsub(/0+%/, '%'),
|
32
|
+
}
|
33
|
+
}
|
34
|
+
client.add_items(ydim_inv.unique_id, item_data)
|
35
|
+
ydim_inv
|
36
|
+
}
|
37
|
+
end
|
38
|
+
def group_by_partner(transactions)
|
39
|
+
groups = {}
|
40
|
+
transactions.each { |transaction|
|
41
|
+
(groups[transaction.partner] ||= []).push(transaction.model)
|
42
|
+
}
|
43
|
+
groups
|
44
|
+
end
|
45
|
+
def run(time_range, transactions, date)
|
46
|
+
unless(transactions.empty?)
|
47
|
+
invoice = create_invoice(time_range, group_by_partner(transactions),
|
48
|
+
date)
|
49
|
+
send_invoice(invoice.unique_id)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
def send_invoice(invoice_id)
|
53
|
+
ydim_connect { |client| client.send_invoice(invoice_id) }
|
54
|
+
end
|
55
|
+
def ydim_connect(&block)
|
56
|
+
config = YDIM::Client::CONFIG
|
57
|
+
if(path = XmlConv::CONFIG.ydim_config)
|
58
|
+
config.load(path)
|
59
|
+
end
|
60
|
+
server = DRbObject.new(nil, config.server_url)
|
61
|
+
client = YDIM::Client.new(config)
|
62
|
+
key = OpenSSL::PKey::DSA.new(File.read(config.private_key))
|
63
|
+
client.login(server, key)
|
64
|
+
block.call(client)
|
65
|
+
ensure
|
66
|
+
client.logout if(client)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Util::KnownUser -- xmlconv2 -- 09.06.2004 -- hwyss@ywesee.com
|
3
|
+
|
4
|
+
require 'sbsm/user'
|
5
|
+
require 'xmlconv/state/transactions'
|
6
|
+
|
7
|
+
module XmlConv
|
8
|
+
module Util
|
9
|
+
class KnownUser < SBSM::KnownUser
|
10
|
+
HOME = State::Transactions
|
11
|
+
NAVIGATION = [
|
12
|
+
:home, :logout
|
13
|
+
]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Util::Mail -- XmlConv -- 23.04.2009 -- hwyss@ywesee.com
|
3
|
+
|
4
|
+
require 'net/smtp'
|
5
|
+
require 'tmail'
|
6
|
+
require 'xmlconv/config'
|
7
|
+
|
8
|
+
module XmlConv
|
9
|
+
module Util
|
10
|
+
module Mail
|
11
|
+
SMTP_HANDLER = Net::SMTP
|
12
|
+
def Mail.notify recipients, subject, body
|
13
|
+
recipients.flatten!
|
14
|
+
recipients.compact!
|
15
|
+
recipients.uniq!
|
16
|
+
return if(recipients.empty?)
|
17
|
+
mail = TMail::Mail.new
|
18
|
+
mail.set_content_type('text', 'plain', 'charset'=>'ISO-8859-1')
|
19
|
+
mail.body = body
|
20
|
+
mail.from = XmlConv::CONFIG.mail_from
|
21
|
+
mail.to = recipients
|
22
|
+
mail.subject = subject
|
23
|
+
mail.date = Time.now
|
24
|
+
mail['User-Agent'] = 'XmlConv::Util::Mail'
|
25
|
+
SMTP_HANDLER.start(XmlConv::CONFIG.mail_host) { |smtp|
|
26
|
+
smtp.sendmail(mail.encoded, XmlConv::CONFIG.mail_from, recipients)
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,198 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Util::PollingManager -- xmlconv2 -- 29.06.2004 -- hwyss@ywesee.com
|
3
|
+
|
4
|
+
require 'fileutils'
|
5
|
+
require 'uri'
|
6
|
+
require 'yaml'
|
7
|
+
require 'xmlconv/util/destination'
|
8
|
+
require 'xmlconv/util/mail'
|
9
|
+
require 'xmlconv/util/transaction'
|
10
|
+
require 'net/pop'
|
11
|
+
require 'rmail'
|
12
|
+
|
13
|
+
module XmlConv
|
14
|
+
module Util
|
15
|
+
class Mission
|
16
|
+
attr_accessor :reader, :writer, :destination, :error_recipients,
|
17
|
+
:debug_recipients, :backup_dir, :partner, :postprocs, :filter,
|
18
|
+
:tmp_destination, :arguments
|
19
|
+
def create_transaction
|
20
|
+
transaction = XmlConv::Util::Transaction.new
|
21
|
+
transaction.domain = @domain
|
22
|
+
transaction.partner = @partner
|
23
|
+
transaction.reader = @reader
|
24
|
+
transaction.writer = @writer
|
25
|
+
transaction.debug_recipients = @debug_recipients
|
26
|
+
transaction.error_recipients = @error_recipients
|
27
|
+
transaction.postprocs = @postprocs
|
28
|
+
transaction.destination = Destination.book(@destination, @tmp_destination)
|
29
|
+
transaction.arguments = [@arguments].flatten.compact
|
30
|
+
transaction
|
31
|
+
end
|
32
|
+
def filtered_transaction(src, origin, &block)
|
33
|
+
unless(@filter && Regexp.new(@filter).match(src))
|
34
|
+
transaction = create_transaction
|
35
|
+
transaction.input = src
|
36
|
+
transaction.origin = origin
|
37
|
+
block.call(transaction)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
class PollingMission < Mission
|
42
|
+
attr_accessor :directory, :glob_pattern
|
43
|
+
def file_paths
|
44
|
+
path = File.expand_path(@glob_pattern || '*', @directory)
|
45
|
+
Dir.glob(path).collect { |entry|
|
46
|
+
File.expand_path(entry, @directory)
|
47
|
+
}.compact
|
48
|
+
end
|
49
|
+
def poll
|
50
|
+
@directory = File.expand_path(@directory, CONFIG.project_root)
|
51
|
+
file_paths.each { |path|
|
52
|
+
begin
|
53
|
+
filtered_transaction(File.read(path), 'file:' << path) { |transaction|
|
54
|
+
yield transaction
|
55
|
+
}
|
56
|
+
rescue Exception => e
|
57
|
+
puts e
|
58
|
+
puts e.backtrace
|
59
|
+
ensure
|
60
|
+
FileUtils.mkdir_p(@backup_dir)
|
61
|
+
FileUtils.mv(path, @backup_dir)
|
62
|
+
end
|
63
|
+
}
|
64
|
+
end
|
65
|
+
end
|
66
|
+
class PopMission < Mission
|
67
|
+
attr_accessor :host, :port, :user, :pass, :content_type
|
68
|
+
def poll(&block)
|
69
|
+
Net::POP3.start(@host, @port || 110, @user, @pass) { |pop|
|
70
|
+
pop.each_mail { |mail|
|
71
|
+
source = mail.pop
|
72
|
+
begin
|
73
|
+
## work around a bug in RMail::Parser that cannot deal with
|
74
|
+
## RFC-2822-compliant CRLF..
|
75
|
+
source.gsub!(/\r\n/, "\n")
|
76
|
+
poll_message(RMail::Parser.read(source), &block)
|
77
|
+
ensure
|
78
|
+
time = Time.now
|
79
|
+
name = sprintf("%s.%s.%s", @user,
|
80
|
+
time.strftime("%Y%m%d%H%M%S"), time.usec)
|
81
|
+
FileUtils.mkdir_p(@backup_dir)
|
82
|
+
path = File.join(@backup_dir, name)
|
83
|
+
File.open(path, 'w') { |fh| fh.puts(source) }
|
84
|
+
mail.delete
|
85
|
+
end
|
86
|
+
}
|
87
|
+
}
|
88
|
+
end
|
89
|
+
def poll_message(message, &block)
|
90
|
+
if(message.multipart?)
|
91
|
+
message.each_part { |part|
|
92
|
+
poll_message(part, &block)
|
93
|
+
}
|
94
|
+
elsif(@content_type.match(message.header.content_type('text/plain')))
|
95
|
+
src = message.decode
|
96
|
+
filtered_transaction(src, sprintf('pop3:%s@%s:%s', @user, @host, @port),
|
97
|
+
&block)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
class FtpMission < Mission
|
102
|
+
attr_accessor :origin, :glob_pattern
|
103
|
+
def file_names(ftp)
|
104
|
+
pattern = @glob_pattern || '*'
|
105
|
+
ftp.nlst.select do |name| File.fnmatch pattern, name end
|
106
|
+
end
|
107
|
+
def poll(&block)
|
108
|
+
uri = URI.parse(@origin)
|
109
|
+
origin_dir = "ftp://#{uri.user}@#{uri.host}#{uri.path}"
|
110
|
+
require 'net/ftp'
|
111
|
+
Net::FTP.open(uri.host, uri.user, uri.password) do |ftp|
|
112
|
+
ftp.chdir uri.path
|
113
|
+
file_names(ftp).each do |name|
|
114
|
+
begin
|
115
|
+
origin = File.join origin_dir, name
|
116
|
+
FileUtils.mkdir_p(@backup_dir)
|
117
|
+
target = File.join(@backup_dir, name)
|
118
|
+
ftp.gettextfile name, target
|
119
|
+
filtered_transaction File.read(target), origin do |trans|
|
120
|
+
block.call trans
|
121
|
+
end
|
122
|
+
rescue Exception => e
|
123
|
+
puts e
|
124
|
+
puts e.backtrace
|
125
|
+
ensure
|
126
|
+
ftp.delete name
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
class SftpMission < Mission
|
133
|
+
attr_accessor :origin, :glob_pattern
|
134
|
+
def file_names(sftp, uri)
|
135
|
+
pattern = @glob_pattern || '*'
|
136
|
+
sftp.dir.entries(uri.path).collect do |entry|
|
137
|
+
name = entry.name
|
138
|
+
name if File.fnmatch pattern, name
|
139
|
+
end.compact
|
140
|
+
end
|
141
|
+
def poll(&block)
|
142
|
+
uri = URI.parse(@origin)
|
143
|
+
require 'net/sftp'
|
144
|
+
Net::SFTP.start(uri.host, uri.user,
|
145
|
+
:user_known_hosts_file => CONFIG.ssh_known_hosts_file,
|
146
|
+
:keys => CONFIG.ssh_identities) do |sftp|
|
147
|
+
file_names(sftp, uri).each do |name|
|
148
|
+
begin
|
149
|
+
path = File.join uri.path, name
|
150
|
+
origin = File.join @origin, name
|
151
|
+
source = sftp.file.open path do |fh| fh.read end
|
152
|
+
filtered_transaction source, origin do |trans|
|
153
|
+
block.call trans
|
154
|
+
end
|
155
|
+
rescue Exception => e
|
156
|
+
puts e
|
157
|
+
puts e.backtrace
|
158
|
+
ensure
|
159
|
+
FileUtils.mkdir_p(@backup_dir)
|
160
|
+
File.open File.join(@backup_dir, name), 'w' do |fh|
|
161
|
+
fh.puts source
|
162
|
+
end
|
163
|
+
sftp.remove! path
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
rescue NoMethodError
|
168
|
+
## prevent polling error notification for intermittent connection problems
|
169
|
+
end
|
170
|
+
end
|
171
|
+
class PollingManager
|
172
|
+
def initialize(system)
|
173
|
+
@system = system
|
174
|
+
end
|
175
|
+
def load_sources(&block)
|
176
|
+
file = File.open(CONFIG.polling_file)
|
177
|
+
YAML.load_documents(file) { |mission|
|
178
|
+
block.call(mission)
|
179
|
+
}
|
180
|
+
ensure
|
181
|
+
file.close if(file)
|
182
|
+
end
|
183
|
+
def poll_sources
|
184
|
+
load_sources { |source|
|
185
|
+
begin
|
186
|
+
source.poll { |transaction|
|
187
|
+
@system.execute(transaction)
|
188
|
+
}
|
189
|
+
rescue Exception => e
|
190
|
+
subject = 'XmlConv2 - Polling-Error'
|
191
|
+
body = [e.class, e.message].concat(e.backtrace).join("\n")
|
192
|
+
Util::Mail.notify source.error_recipients, subject, body
|
193
|
+
end
|
194
|
+
}
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Session -- xmlconv2 -- 09.06.2004 -- hwyss@ywesee.com
|
3
|
+
|
4
|
+
require 'sbsm/session'
|
5
|
+
require 'xmlconv/state/login'
|
6
|
+
require 'xmlconv/custom/lookandfeel'
|
7
|
+
require 'xmlconv/util/known_user'
|
8
|
+
|
9
|
+
module XmlConv
|
10
|
+
module Util
|
11
|
+
class Session < SBSM::Session
|
12
|
+
DEFAULT_LANGUAGE = 'de'
|
13
|
+
DEFAULT_STATE = State::Login
|
14
|
+
LOOKANDFEEL = Custom::Lookandfeel
|
15
|
+
def login
|
16
|
+
if((pass = user_input(:pass)) \
|
17
|
+
&& (pass == CONFIG.pass_hash))
|
18
|
+
@user = Util::KnownUser.new
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|