bbmb 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +5 -0
- data/LICENSE.txt +339 -0
- data/Manifest.txt +91 -0
- data/README.txt +25 -0
- data/Rakefile +28 -0
- data/bin/admin +71 -0
- data/bin/bbmbd +61 -0
- data/lib/bbmb.rb +9 -0
- data/lib/bbmb/config.rb +106 -0
- data/lib/bbmb/html/state/change_password.rb +50 -0
- data/lib/bbmb/html/state/current_order.rb +81 -0
- data/lib/bbmb/html/state/customer.rb +109 -0
- data/lib/bbmb/html/state/customers.rb +52 -0
- data/lib/bbmb/html/state/favorites.rb +19 -0
- data/lib/bbmb/html/state/favorites_result.rb +21 -0
- data/lib/bbmb/html/state/global.rb +62 -0
- data/lib/bbmb/html/state/history.rb +95 -0
- data/lib/bbmb/html/state/info.rb +23 -0
- data/lib/bbmb/html/state/json.rb +16 -0
- data/lib/bbmb/html/state/login.rb +76 -0
- data/lib/bbmb/html/state/order.rb +21 -0
- data/lib/bbmb/html/state/orders.rb +19 -0
- data/lib/bbmb/html/state/result.rb +64 -0
- data/lib/bbmb/html/state/show_pass.rb +16 -0
- data/lib/bbmb/html/state/viral/admin.rb +41 -0
- data/lib/bbmb/html/state/viral/customer.rb +143 -0
- data/lib/bbmb/html/util/known_user.rb +51 -0
- data/lib/bbmb/html/util/multilingual.rb +18 -0
- data/lib/bbmb/html/util/session.rb +52 -0
- data/lib/bbmb/html/util/validator.rb +55 -0
- data/lib/bbmb/html/view/backorder.rb +24 -0
- data/lib/bbmb/html/view/change_password.rb +42 -0
- data/lib/bbmb/html/view/copyleft.rb +41 -0
- data/lib/bbmb/html/view/current_order.rb +482 -0
- data/lib/bbmb/html/view/customer.rb +152 -0
- data/lib/bbmb/html/view/customers.rb +145 -0
- data/lib/bbmb/html/view/favorites.rb +162 -0
- data/lib/bbmb/html/view/favorites_result.rb +26 -0
- data/lib/bbmb/html/view/foot.rb +21 -0
- data/lib/bbmb/html/view/head.rb +32 -0
- data/lib/bbmb/html/view/history.rb +60 -0
- data/lib/bbmb/html/view/info.rb +33 -0
- data/lib/bbmb/html/view/json.rb +20 -0
- data/lib/bbmb/html/view/list_prices.rb +51 -0
- data/lib/bbmb/html/view/login.rb +46 -0
- data/lib/bbmb/html/view/multilingual.rb +17 -0
- data/lib/bbmb/html/view/navigation.rb +30 -0
- data/lib/bbmb/html/view/order.rb +123 -0
- data/lib/bbmb/html/view/orders.rb +50 -0
- data/lib/bbmb/html/view/result.rb +107 -0
- data/lib/bbmb/html/view/search.rb +28 -0
- data/lib/bbmb/html/view/show_pass.rb +60 -0
- data/lib/bbmb/html/view/template.rb +61 -0
- data/lib/bbmb/model/customer.rb +96 -0
- data/lib/bbmb/model/order.rb +255 -0
- data/lib/bbmb/model/product.rb +99 -0
- data/lib/bbmb/model/promotion.rb +52 -0
- data/lib/bbmb/model/quota.rb +27 -0
- data/lib/bbmb/model/subject.rb +46 -0
- data/lib/bbmb/persistence/none.rb +6 -0
- data/lib/bbmb/persistence/odba.rb +42 -0
- data/lib/bbmb/persistence/odba/model/customer.rb +47 -0
- data/lib/bbmb/persistence/odba/model/order.rb +50 -0
- data/lib/bbmb/persistence/odba/model/product.rb +26 -0
- data/lib/bbmb/persistence/odba/model/quota.rb +12 -0
- data/lib/bbmb/util/invoicer.rb +126 -0
- data/lib/bbmb/util/mail.rb +140 -0
- data/lib/bbmb/util/multilingual.rb +57 -0
- data/lib/bbmb/util/numbers.rb +67 -0
- data/lib/bbmb/util/password_generator.rb +44 -0
- data/lib/bbmb/util/polling_manager.rb +135 -0
- data/lib/bbmb/util/server.rb +159 -0
- data/lib/bbmb/util/target_dir.rb +36 -0
- data/lib/bbmb/util/transfer_dat.rb +34 -0
- data/lib/bbmb/util/updater.rb +27 -0
- data/test/data/ydim.yml +2 -0
- data/test/model/test_customer.rb +75 -0
- data/test/model/test_order.rb +426 -0
- data/test/model/test_product.rb +238 -0
- data/test/model/test_promotion.rb +40 -0
- data/test/stub/persistence.rb +57 -0
- data/test/suite.rb +12 -0
- data/test/test_bbmb.rb +18 -0
- data/test/util/test_invoicer.rb +189 -0
- data/test/util/test_mail.rb +359 -0
- data/test/util/test_money.rb +71 -0
- data/test/util/test_password_generator.rb +27 -0
- data/test/util/test_polling_manager.rb +312 -0
- data/test/util/test_server.rb +189 -0
- data/test/util/test_target_dir.rb +82 -0
- data/test/util/test_transfer_dat.rb +45 -0
- metadata +190 -0
@@ -0,0 +1,140 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Util::Mail -- bbmb.ch -- 27.09.2006 -- hwyss@ywesee.com
|
3
|
+
|
4
|
+
require 'bbmb/config'
|
5
|
+
require 'net/smtp'
|
6
|
+
require 'rmail'
|
7
|
+
require 'pp'
|
8
|
+
|
9
|
+
module BBMB
|
10
|
+
module Util
|
11
|
+
module Mail
|
12
|
+
def Mail.notify_confirmation_error(order)
|
13
|
+
config = BBMB.config
|
14
|
+
if to = config.confirm_error_to
|
15
|
+
header, message = setup
|
16
|
+
customer = order.customer
|
17
|
+
from = header.from = config.confirm_error_from
|
18
|
+
header.to = to
|
19
|
+
cc = header.cc = config.confirm_error_cc
|
20
|
+
header.subject = config.confirm_error_subject % customer.customer_id
|
21
|
+
message.body = config.confirm_error_body % customer.customer_id
|
22
|
+
Mail.sendmail message, from, to, cc
|
23
|
+
end
|
24
|
+
end
|
25
|
+
def Mail.notify_debug(subject, body)
|
26
|
+
header, message = setup
|
27
|
+
config = BBMB.config
|
28
|
+
from = header.from = config.mail_order_from
|
29
|
+
to = header.to = config.error_recipients
|
30
|
+
header.subject = sprintf "%s: %s", BBMB.config.name, subject
|
31
|
+
message.body = body
|
32
|
+
Mail.sendmail(message, from, to)
|
33
|
+
end
|
34
|
+
def Mail.notify_error(error)
|
35
|
+
header, message = setup
|
36
|
+
config = BBMB.config
|
37
|
+
from = header.from = config.mail_order_from
|
38
|
+
to = header.to = config.error_recipients
|
39
|
+
header.subject = sprintf "%s: %s", BBMB.config.name, error.message
|
40
|
+
message.body = [ error.class, error.message,
|
41
|
+
error.backtrace.pretty_inspect ].join("\n")
|
42
|
+
Mail.sendmail(message, from, to)
|
43
|
+
end
|
44
|
+
def Mail.notify_inject_error(order, opts={})
|
45
|
+
config = BBMB.config
|
46
|
+
if to = config.inject_error_to
|
47
|
+
customer = order.customer
|
48
|
+
header, message = setup
|
49
|
+
from = header.from = config.inject_error_from
|
50
|
+
header.to = to
|
51
|
+
cc = header.cc = config.inject_error_cc
|
52
|
+
header.subject = config.inject_error_subject % [
|
53
|
+
order.order_id,
|
54
|
+
opts[:customer_name] || customer.customer_id,
|
55
|
+
]
|
56
|
+
message.body = config.inject_error_body % [
|
57
|
+
opts[:customer_name] || customer.customer_id,
|
58
|
+
order.commit_time.strftime('%d.%m.%Y %H:%M:%S'),
|
59
|
+
customer.customer_id,
|
60
|
+
]
|
61
|
+
Mail.sendmail message, from, to, cc
|
62
|
+
end
|
63
|
+
end
|
64
|
+
def Mail.sendmail(message, from, to, cc=[])
|
65
|
+
config = BBMB.config
|
66
|
+
Net::SMTP.start(config.smtp_server, config.smtp_port, config.smtp_helo,
|
67
|
+
config.smtp_user, config.smtp_pass,
|
68
|
+
config.smtp_authtype) { |smtp|
|
69
|
+
smtp.sendmail(message.to_s, from, [to, cc].flatten.compact)
|
70
|
+
}
|
71
|
+
end
|
72
|
+
def Mail.send_confirmation(order)
|
73
|
+
config = BBMB.config
|
74
|
+
## there are two switches that determine whether a confirmation is sent out:
|
75
|
+
# application-wide: mail_confirm_reply_to must be configured
|
76
|
+
reply_to = config.mail_confirm_reply_to or return nil
|
77
|
+
# per-customer: order_confirmation must be checked
|
78
|
+
order.customer.order_confirmation or return nil
|
79
|
+
to = order.customer.email or return notify_confirmation_error(order)
|
80
|
+
body = config.mail_confirm_body or return nil
|
81
|
+
date = order.commit_time.strftime("%d.%m.%Y")
|
82
|
+
parts = []
|
83
|
+
config.mail_confirm_lines.collect do |line|
|
84
|
+
content = order.collect do |pos|
|
85
|
+
sprintf line, pos.quantity, pos.description, pos.price_qty, pos.total
|
86
|
+
end
|
87
|
+
parts.push date, content.join("\n"), order.total
|
88
|
+
if vtotal = order.total_incl_vat
|
89
|
+
parts.push vtotal
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
header, message = setup
|
94
|
+
from = header.from = config.mail_confirm_from
|
95
|
+
header.to = to
|
96
|
+
header.subject = config.mail_confirm_subject % order.order_id
|
97
|
+
header.add('Message-ID', sprintf('<%s@%s>', order.order_id,
|
98
|
+
from.tr('@', '.')))
|
99
|
+
header.add('Reply-To', reply_to)
|
100
|
+
message.body = sprintf body, *parts
|
101
|
+
|
102
|
+
Mail.sendmail(message, from, to, config.mail_confirm_cc)
|
103
|
+
end
|
104
|
+
def Mail.send_order(order)
|
105
|
+
header, message = setup
|
106
|
+
config = BBMB.config
|
107
|
+
from = header.from = config.mail_order_from
|
108
|
+
to = header.to = config.mail_order_to
|
109
|
+
cc = header.cc = config.mail_order_cc
|
110
|
+
header.subject = config.mail_order_subject % order.order_id
|
111
|
+
header.add('Message-ID', sprintf('<%s@%s>', order.order_id,
|
112
|
+
from.tr('@', '.')))
|
113
|
+
message.body = order.to_target_format
|
114
|
+
|
115
|
+
Mail.sendmail(message, from, to, cc)
|
116
|
+
end
|
117
|
+
def Mail.send_request(email, organisation, body)
|
118
|
+
header, message = setup
|
119
|
+
config = BBMB.config
|
120
|
+
from = header.from = config.mail_request_from
|
121
|
+
to = header.to = config.mail_request_to
|
122
|
+
cc = header.cc = config.mail_request_cc
|
123
|
+
header.subject = config.mail_request_subject % organisation
|
124
|
+
header.add('Reply-To', email)
|
125
|
+
message.body = body
|
126
|
+
Mail.sendmail(message, from, to, cc)
|
127
|
+
end
|
128
|
+
def Mail.setup
|
129
|
+
message = RMail::Message.new
|
130
|
+
header = message.header
|
131
|
+
header.add('Date', Time.now.rfc822)
|
132
|
+
header.add('Mime-Version', '1.0')
|
133
|
+
header.add('User-Agent', BBMB.config.name)
|
134
|
+
header.add('Content-Type', 'text/plain', nil, 'charset' => 'utf-8')
|
135
|
+
header.add('Content-Disposition', 'inline')
|
136
|
+
[header, message]
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Util::Multilingual -- de.oddb.org -- 04.09.2006 -- hwyss@ywesee.com
|
3
|
+
|
4
|
+
module BBMB
|
5
|
+
module Util
|
6
|
+
class Multilingual
|
7
|
+
include Comparable
|
8
|
+
attr_reader :canonical
|
9
|
+
attr_reader :synonyms
|
10
|
+
def initialize(canonical={})
|
11
|
+
@canonical = canonical
|
12
|
+
@synonyms = []
|
13
|
+
end
|
14
|
+
def all
|
15
|
+
@canonical.values.concat(@synonyms)
|
16
|
+
end
|
17
|
+
def default
|
18
|
+
@canonical.values.sort.first
|
19
|
+
end
|
20
|
+
def empty?
|
21
|
+
@canonical.empty?
|
22
|
+
end
|
23
|
+
def method_missing(meth, *args, &block)
|
24
|
+
case meth.to_s
|
25
|
+
when /^[a-z]{2}$/
|
26
|
+
@canonical[meth]
|
27
|
+
when /^([a-z]{2})=$/
|
28
|
+
key = $~[1].to_sym
|
29
|
+
if(value = args.first)
|
30
|
+
@canonical.store(key, value)
|
31
|
+
else
|
32
|
+
@canonical.delete(key)
|
33
|
+
end
|
34
|
+
else
|
35
|
+
super(meth, *args, &block)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
def to_s
|
39
|
+
default.to_s
|
40
|
+
end
|
41
|
+
def ==(other)
|
42
|
+
case other
|
43
|
+
when String
|
44
|
+
@canonical.values.any? { |val| val == other } \
|
45
|
+
|| @synonyms.any? { |val| val == other }
|
46
|
+
when Multilingual
|
47
|
+
@canonical == other.canonical && @synonyms == other.synonyms
|
48
|
+
else
|
49
|
+
false
|
50
|
+
end
|
51
|
+
end
|
52
|
+
def <=>(other)
|
53
|
+
all.sort <=> other.all.sort
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Util::Money -- bbmb.ch -- 14.09.2006 -- hwyss@ywesee.com
|
3
|
+
|
4
|
+
module BBMB
|
5
|
+
module Util
|
6
|
+
module Numbers
|
7
|
+
def Numbers.append_features(mod)
|
8
|
+
super
|
9
|
+
mod.module_eval {
|
10
|
+
class << self
|
11
|
+
def money_accessor(*keys)
|
12
|
+
keys.each { |key|
|
13
|
+
attr_reader key
|
14
|
+
define_method("#{key}=") { |value|
|
15
|
+
money = Util::Money.new(value) if(value.to_f > 0)
|
16
|
+
instance_variable_set("@#{key}", money)
|
17
|
+
}
|
18
|
+
}
|
19
|
+
end
|
20
|
+
def int_accessor(*keys)
|
21
|
+
keys.each { |key|
|
22
|
+
attr_reader key
|
23
|
+
define_method("#{key}=") { |value|
|
24
|
+
int = value.to_i if(value)
|
25
|
+
instance_variable_set("@#{key}", int)
|
26
|
+
}
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
class Money
|
34
|
+
attr_reader :credits
|
35
|
+
include Comparable
|
36
|
+
def initialize(amount)
|
37
|
+
@credits = (amount.to_f * 100).round
|
38
|
+
end
|
39
|
+
def to_f
|
40
|
+
@credits.to_f / 100
|
41
|
+
end
|
42
|
+
def to_s
|
43
|
+
sprintf("%1.2f", to_f)
|
44
|
+
end
|
45
|
+
def +(other)
|
46
|
+
Money.new(to_f + other.to_f)
|
47
|
+
end
|
48
|
+
def -(other)
|
49
|
+
Money.new(to_f - other.to_f)
|
50
|
+
end
|
51
|
+
def *(other)
|
52
|
+
Money.new(to_f * other.to_f)
|
53
|
+
end
|
54
|
+
def /(other)
|
55
|
+
Money.new(to_f / other.to_f)
|
56
|
+
end
|
57
|
+
def <=>(other)
|
58
|
+
case other
|
59
|
+
when Money
|
60
|
+
@credits <=> other.credits
|
61
|
+
else
|
62
|
+
to_f <=> other.to_f
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# PasswordGenerator -- bbmb -- 11.10.2002 -- hwyss@ywesee.com
|
3
|
+
|
4
|
+
module BBMB
|
5
|
+
module Util
|
6
|
+
class PasswordGenerator
|
7
|
+
SEQUENCE = [ :char, :char, :sym, :num ]
|
8
|
+
SIZE = {
|
9
|
+
:char => 2,
|
10
|
+
:num => 4,
|
11
|
+
:sym => 1,
|
12
|
+
}
|
13
|
+
POOL = {
|
14
|
+
:char => ("A".."Z").to_a + ("a".."z").to_a,
|
15
|
+
:num => ("0".."9").to_a,
|
16
|
+
:sym => %w{! @ * ?},
|
17
|
+
}
|
18
|
+
class << self
|
19
|
+
def generate(user)
|
20
|
+
pool = POOL.dup
|
21
|
+
char = [user.organisation, user.firstname, user.lastname].join
|
22
|
+
if(char.length >= 12)
|
23
|
+
pool[:char] = char.scan(/\w/)
|
24
|
+
end
|
25
|
+
pass = ""
|
26
|
+
random_sequence.each { |type|
|
27
|
+
SIZE[type].times {
|
28
|
+
pass << pool[type].at(rand(pool[type].size))
|
29
|
+
}
|
30
|
+
}
|
31
|
+
pass
|
32
|
+
end
|
33
|
+
def random_sequence
|
34
|
+
sequence = SEQUENCE.dup
|
35
|
+
random = []
|
36
|
+
while(sequence.length > 0)
|
37
|
+
random.push(sequence.delete_at(rand(sequence.size)))
|
38
|
+
end
|
39
|
+
random
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Util::PollingManager -- bbmb.ch -- 14.09.2006 -- hwyss@ywesee.com
|
3
|
+
|
4
|
+
require 'bbmb'
|
5
|
+
require 'bbmb/util/mail'
|
6
|
+
require 'fileutils'
|
7
|
+
require 'net/ftp'
|
8
|
+
require 'net/pop'
|
9
|
+
require 'tmpdir'
|
10
|
+
require 'uri'
|
11
|
+
require 'yaml'
|
12
|
+
|
13
|
+
module BBMB
|
14
|
+
module Util
|
15
|
+
class FileMission
|
16
|
+
attr_accessor :backup_dir, :delete, :directory, :glob_pattern
|
17
|
+
def file_paths
|
18
|
+
path = File.expand_path(@glob_pattern || '*', @directory)
|
19
|
+
Dir.glob(path).collect { |entry|
|
20
|
+
File.expand_path(entry, @directory)
|
21
|
+
}.compact
|
22
|
+
end
|
23
|
+
def poll(&block)
|
24
|
+
@directory = File.expand_path(@directory, BBMB.config.bbmb_dir)
|
25
|
+
file_paths.each { |path|
|
26
|
+
poll_path(path, &block)
|
27
|
+
}
|
28
|
+
end
|
29
|
+
def poll_path(path, &block)
|
30
|
+
File.open(path) { |io|
|
31
|
+
block.call(File.basename(path), io)
|
32
|
+
}
|
33
|
+
rescue StandardError => err
|
34
|
+
BBMB::Util::Mail.notify_error(err)
|
35
|
+
ensure
|
36
|
+
if(@backup_dir)
|
37
|
+
dir = File.expand_path(@backup_dir, BBMB.config.bbmb_dir)
|
38
|
+
FileUtils.mkdir_p(dir)
|
39
|
+
FileUtils.cp(path, dir)
|
40
|
+
end
|
41
|
+
if(@delete)
|
42
|
+
FileUtils.rm(path)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
class PopMission
|
47
|
+
attr_accessor :host, :port, :user, :pass, :delete
|
48
|
+
@@ptrn = /name=(?:(?:(?<quote>['"])(?:=\?.+?\?[QB]\?)?(?<file>.*?)(\?=)?(?<!\\)\k<quote>)|(?:(?<file>.+?)(?:;|$)))/i
|
49
|
+
def poll(&block)
|
50
|
+
Net::POP3.start(@host, @port || 110, @user, @pass) { |pop|
|
51
|
+
pop.each_mail { |mail|
|
52
|
+
poll_mail(mail, &block)
|
53
|
+
}
|
54
|
+
}
|
55
|
+
end
|
56
|
+
def poll_mail(mail, &block)
|
57
|
+
source = mail.pop
|
58
|
+
## work around a bug in RMail::Parser that cannot deal with
|
59
|
+
## RFC-2822-compliant CRLF..
|
60
|
+
source.gsub!(/\r\n/, "\n")
|
61
|
+
poll_message(RMail::Parser.read(source), &block)
|
62
|
+
mail.delete if(@delete)
|
63
|
+
rescue StandardError => err
|
64
|
+
BBMB::Util::Mail.notify_error(err)
|
65
|
+
end
|
66
|
+
def poll_message(message, &block)
|
67
|
+
if(message.multipart?)
|
68
|
+
message.each_part { |part|
|
69
|
+
poll_message(part, &block)
|
70
|
+
}
|
71
|
+
elsif(match = @@ptrn.match(message.header["Content-Type"]))
|
72
|
+
block.call(match["file"], message.decode)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
class FtpMission
|
77
|
+
attr_accessor :backup_dir, :delete, :pattern, :directory
|
78
|
+
def initialize(*args)
|
79
|
+
super
|
80
|
+
@regexp = Regexp.new('.*')
|
81
|
+
end
|
82
|
+
def poll(&block)
|
83
|
+
@backup_dir ||= Dir.tmpdir
|
84
|
+
FileUtils.mkdir_p(@backup_dir)
|
85
|
+
@regexp = Regexp.new(@pattern || '.*')
|
86
|
+
uri = URI.parse(@directory)
|
87
|
+
locals = []
|
88
|
+
Net::FTP.open(uri.host) do |ftp|
|
89
|
+
ftp.login uri.user, uri.password
|
90
|
+
ftp.chdir uri.path
|
91
|
+
ftp.nlst.each do |file|
|
92
|
+
if(local = poll_remote ftp, file)
|
93
|
+
locals.push local
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
locals.each do |path|
|
98
|
+
poll_file path, &block
|
99
|
+
end
|
100
|
+
end
|
101
|
+
def poll_file(path, &block)
|
102
|
+
File.open(path) { |io|
|
103
|
+
block.call(File.basename(path), io)
|
104
|
+
}
|
105
|
+
rescue StandardError => err
|
106
|
+
BBMB::Util::Mail.notify_error(err)
|
107
|
+
end
|
108
|
+
def poll_remote(ftp, file)
|
109
|
+
if(@regexp.match file)
|
110
|
+
local = File.join(@backup_dir, file)
|
111
|
+
ftp.get file, local
|
112
|
+
ftp.delete file if @delete
|
113
|
+
local
|
114
|
+
end
|
115
|
+
end
|
116
|
+
def regexp
|
117
|
+
end
|
118
|
+
end
|
119
|
+
class PollingManager
|
120
|
+
def load_sources(&block)
|
121
|
+
file = File.open(BBMB.config.polling_file)
|
122
|
+
YAML.load_documents(file) { |mission|
|
123
|
+
block.call(mission)
|
124
|
+
}
|
125
|
+
ensure
|
126
|
+
file.close if(file)
|
127
|
+
end
|
128
|
+
def poll_sources(&block)
|
129
|
+
load_sources { |source|
|
130
|
+
source.poll(&block)
|
131
|
+
}
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Util::Server -- de.bbmb.org -- 01.09.2006 -- hwyss@ywesee.com
|
3
|
+
|
4
|
+
require 'bbmb/config'
|
5
|
+
require 'bbmb/html/util/known_user'
|
6
|
+
require 'bbmb/html/util/session'
|
7
|
+
require 'bbmb/html/util/validator'
|
8
|
+
require 'bbmb/util/invoicer'
|
9
|
+
require 'bbmb/util/mail'
|
10
|
+
require 'bbmb/util/updater'
|
11
|
+
require 'date'
|
12
|
+
require 'sbsm/drbserver'
|
13
|
+
|
14
|
+
module BBMB
|
15
|
+
module Util
|
16
|
+
class Server < SBSM::DRbServer
|
17
|
+
ENABLE_ADMIN = true
|
18
|
+
SESSION = Html::Util::Session
|
19
|
+
VALIDATOR = Html::Util::Validator
|
20
|
+
attr_reader :updater
|
21
|
+
def inject_order(customer_id, products, infos, opts={})
|
22
|
+
customer = Model::Customer.find_by_customer_id(customer_id) \
|
23
|
+
|| Model::Customer.find_by_ean13(customer_id)
|
24
|
+
needed_create = false
|
25
|
+
unless customer
|
26
|
+
if idtype = opts[:create_missing_customer] && !customer_id.empty?
|
27
|
+
customer = Model::Customer.new(customer_id)
|
28
|
+
if idtype.to_s == 'ean13'
|
29
|
+
customer.ean13 = customer_id
|
30
|
+
end
|
31
|
+
BBMB.persistence.save(customer)
|
32
|
+
needed_create = true
|
33
|
+
else
|
34
|
+
raise "Unknown Customer #{customer_id}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
order = Model::Order.new(customer)
|
38
|
+
products.each { |info|
|
39
|
+
if(product = Model::Product.find_by_pcode(info[:pcode]) \
|
40
|
+
|| Model::Product.find_by_ean13(info[:ean13]) \
|
41
|
+
|| Model::Product.find_by_article_number(info[:article_number]))
|
42
|
+
order.add(info[:quantity], product)
|
43
|
+
[:article_number, :backorder].each do |key|
|
44
|
+
info.store key, product.send(key)
|
45
|
+
end
|
46
|
+
info.store :description, product.description.de
|
47
|
+
info[:deliverable] = info[:quantity]
|
48
|
+
else
|
49
|
+
info[:deliverable] = 0
|
50
|
+
end
|
51
|
+
}
|
52
|
+
infos.each { |key, value|
|
53
|
+
order.send("#{key}=", value)
|
54
|
+
}
|
55
|
+
customer.inject_order(order)
|
56
|
+
if opts[:deliver]
|
57
|
+
async do
|
58
|
+
send_order order, customer
|
59
|
+
end
|
60
|
+
end
|
61
|
+
if needed_create
|
62
|
+
BBMB::Util::Mail.notify_inject_error(order, opts)
|
63
|
+
end
|
64
|
+
{ :order_id => order.order_id, :products => products }
|
65
|
+
end
|
66
|
+
def invoice(range)
|
67
|
+
Invoicer.run(range)
|
68
|
+
rescue Exception => e
|
69
|
+
Mail.notify_error(e)
|
70
|
+
end
|
71
|
+
def login(email, pass)
|
72
|
+
session = BBMB.auth.login(email, pass, BBMB.config.auth_domain)
|
73
|
+
Html::Util::KnownUser.new(session)
|
74
|
+
end
|
75
|
+
def logout(session)
|
76
|
+
BBMB.auth.logout(session)
|
77
|
+
rescue DRb::DRbError, RangeError, NameError
|
78
|
+
end
|
79
|
+
def rename_user(old, new)
|
80
|
+
return if(old == new)
|
81
|
+
BBMB.auth.autosession(BBMB.config.auth_domain) { |session|
|
82
|
+
if(old.nil?)
|
83
|
+
session.create_entity(new)
|
84
|
+
else
|
85
|
+
session.rename(old, new)
|
86
|
+
end
|
87
|
+
}
|
88
|
+
end
|
89
|
+
def run_invoicer
|
90
|
+
@invoicer ||= Thread.new {
|
91
|
+
Thread.current.abort_on_exception = true
|
92
|
+
loop {
|
93
|
+
today = Date.today
|
94
|
+
day = today >> 1
|
95
|
+
start = Time.local(today.year, today.month)
|
96
|
+
now = Time.now
|
97
|
+
at = Time.local(day.year, day.month)
|
98
|
+
secs = at - now
|
99
|
+
BBMB.logger.debug("invoicer") {
|
100
|
+
"sleeping %.2f seconds" % secs
|
101
|
+
}
|
102
|
+
sleep(secs)
|
103
|
+
invoice(start...at)
|
104
|
+
}
|
105
|
+
}
|
106
|
+
end
|
107
|
+
def run_updater
|
108
|
+
@updater ||= Thread.new {
|
109
|
+
loop {
|
110
|
+
day = Date.today
|
111
|
+
now = Time.now
|
112
|
+
if(now.hour >= BBMB.config.update_hour)
|
113
|
+
day += 1
|
114
|
+
end
|
115
|
+
at = Time.local(day.year, day.month, day.day,
|
116
|
+
BBMB.config.update_hour)
|
117
|
+
secs = at - now
|
118
|
+
BBMB.logger.debug("updater") {
|
119
|
+
"sleeping %.2f seconds" % secs
|
120
|
+
}
|
121
|
+
sleep(secs)
|
122
|
+
update
|
123
|
+
}
|
124
|
+
}
|
125
|
+
end
|
126
|
+
def send_order order, customer
|
127
|
+
begin
|
128
|
+
Timeout.timeout(300) {
|
129
|
+
BBMB::Util::TargetDir.send_order(order)
|
130
|
+
}
|
131
|
+
rescue StandardError => err
|
132
|
+
err.message << " (Email: #{customer.email} - Customer-Id: #{customer.customer_id})"
|
133
|
+
BBMB::Util::Mail.notify_error(err)
|
134
|
+
end
|
135
|
+
begin
|
136
|
+
Timeout.timeout(300) {
|
137
|
+
BBMB::Util::Mail.send_order(order)
|
138
|
+
}
|
139
|
+
rescue StandardError => err
|
140
|
+
err.message << " (Email: #{customer.email} - Customer-Id: #{customer.customer_id})"
|
141
|
+
BBMB::Util::Mail.notify_error(err)
|
142
|
+
end
|
143
|
+
begin
|
144
|
+
Timeout.timeout(300) {
|
145
|
+
BBMB::Util::Mail.send_confirmation(order)
|
146
|
+
}
|
147
|
+
rescue StandardError => err
|
148
|
+
err.message << " (Email: #{customer.email} - Customer-Id: #{customer.customer_id})"
|
149
|
+
BBMB::Util::Mail.notify_error(err)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
def update
|
153
|
+
Updater.run
|
154
|
+
rescue Exception => e
|
155
|
+
Mail.notify_error(e)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|