ig3tool 0.1.0 → 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.
Files changed (60) hide show
  1. data/bin/ig3tool +17 -21
  2. data/lib/actions/bib.rb +295 -0
  3. data/lib/actions/bitching.rb +19 -0
  4. data/lib/actions/cultuur.rb +3 -0
  5. data/lib/actions/interne.rb +98 -0
  6. data/lib/actions/kaching.rb +90 -0
  7. data/lib/actions/people.rb +178 -0
  8. data/lib/actions/printing.rb +125 -0
  9. data/lib/actions/product.rb +154 -0
  10. data/lib/bib.rb +94 -0
  11. data/lib/billing.rb +112 -0
  12. data/lib/bitching.rb +49 -0
  13. data/lib/config.rb +19 -0
  14. data/lib/glade/cola_light_small.png +0 -0
  15. data/lib/glade/cola_light_xsmall.png +0 -0
  16. data/lib/glade/cola_small.png +0 -0
  17. data/lib/glade/cola_xsmall.png +0 -0
  18. data/lib/glade/doos_small.png +0 -0
  19. data/lib/glade/doos_xsmall.png +0 -0
  20. data/lib/glade/icons/cola_light_small.png +0 -0
  21. data/lib/glade/icons/cola_light_xsmall.png +0 -0
  22. data/lib/glade/icons/cola_small.png +0 -0
  23. data/lib/glade/icons/cola_xsmall.png +0 -0
  24. data/lib/glade/icons/doos_small.png +0 -0
  25. data/lib/glade/icons/doos_xsmall.png +0 -0
  26. data/lib/glade/icons/piggy_small.png +0 -0
  27. data/lib/glade/icons/piggy_xsmall.png +0 -0
  28. data/lib/glade/money_small.png +0 -0
  29. data/lib/glade/money_xsmall.png +0 -0
  30. data/lib/glade/newinterne.glade +504 -0
  31. data/lib/glade/piggy_small.png +0 -0
  32. data/lib/glade/piggy_xsmall.png +0 -0
  33. data/lib/glade/sales.glade +89 -87
  34. data/lib/horrible_hack.rb +15 -0
  35. data/lib/interne.rb +111 -0
  36. data/lib/ldap.rb +104 -0
  37. data/lib/log.rb +25 -0
  38. data/lib/membership.rb +32 -0
  39. data/lib/mymd5.rb +95 -0
  40. data/lib/people.rb +143 -0
  41. data/lib/printing.rb +238 -0
  42. data/lib/request.rb +14 -0
  43. data/lib/sales.rb +158 -0
  44. data/lib/ui/automaatwindow.rb +2 -2
  45. data/lib/ui/bibliotheekwindow.rb +16 -17
  46. data/lib/ui/bibwindow.rb +15 -15
  47. data/lib/ui/gladehelper.rb +20 -6
  48. data/lib/ui/internewindow.rb +12 -9
  49. data/lib/ui/loginwindow.rb +2 -4
  50. data/lib/ui/memberswindow.rb +9 -9
  51. data/lib/ui/newinterne.rb +258 -0
  52. data/lib/ui/peoplewindow.rb +14 -16
  53. data/lib/ui/printenwindow.rb +11 -11
  54. data/lib/ui/printingwindow.rb +19 -20
  55. data/lib/ui/productswindow.rb +27 -15
  56. data/lib/ui/saleswindow.rb +21 -8
  57. data/lib/ui/toolwindow.rb +5 -3
  58. data/lib/utils.rb +106 -0
  59. data/lib/web.rb +98 -0
  60. metadata +48 -3
data/bin/ig3tool CHANGED
@@ -12,13 +12,7 @@ require "lib/util"
12
12
 
13
13
  module Ig3tool
14
14
 
15
- $global = {
16
- 'client' => '',
17
- 'amazon_loaded' => false
18
- }
19
-
20
15
  CONFIG = {
21
-
22
16
  'amazon-associates-id' => 'webservices-20',
23
17
  # You need an Amazon dev token (Lookup ISBN feature)
24
18
  'amazon-dev-token' => 'D2CCFZZMOO6ZB9'
@@ -33,29 +27,19 @@ module Ig3tool
33
27
 
34
28
  host = ENV['IG3TOOL_HOST'] || "igwe.vub.ac.be"
35
29
  port = ENV['IG3TOOL_PORT'] || 2007
36
- $global['client'] = Ig3tool::Client.new(host, port)
30
+ $client = Ig3tool::Client.new(host, port)
37
31
  Gtk::init
38
32
 
39
- def error_dialog (parent, exception)
40
- dialog = Gtk::MessageDialog.new \
41
- parent,
42
- Gtk::Dialog::MODAL | Gtk::Dialog::DESTROY_WITH_PARENT,
43
- Gtk::MessageDialog::WARNING,
44
- Gtk::MessageDialog::BUTTONS_CLOSE,
45
- exception.to_s
46
- dialog.run
47
- dialog.destroy
48
- end
49
33
  begin
50
- if $global['client'].validate
34
+ if $client.validate
51
35
  ToolWindow.new(@klasses)
52
36
  else
53
- LoginWindow.new($global['client']) do
37
+ LoginWindow.new($client) do
54
38
  ToolWindow.new(@klasses)
55
39
  end
56
40
  end
57
41
  rescue Exception => e
58
- LoginWindow.new($global['client']) do
42
+ LoginWindow.new($client) do
59
43
  ToolWindow.new(@klasses)
60
44
  end
61
45
  end
@@ -71,6 +55,18 @@ module Ig3tool
71
55
  retry
72
56
  end
73
57
  end
58
+
59
+
60
+ def error_dialog (parent, exception)
61
+ dialog = Gtk::MessageDialog.new \
62
+ parent,
63
+ Gtk::Dialog::MODAL | Gtk::Dialog::DESTROY_WITH_PARENT,
64
+ Gtk::MessageDialog::WARNING,
65
+ Gtk::MessageDialog::BUTTONS_CLOSE,
66
+ exception.to_s
67
+ dialog.run
68
+ dialog.destroy
69
+ end
74
70
 
75
71
 
76
72
  @klasses = []
@@ -105,7 +101,7 @@ require "ui/automaatwindow"
105
101
  require "ui/peoplewindow"
106
102
  require "ui/saleswindow"
107
103
  require "ui/printingwindow.rb"
108
- require "ui/internewindow.rb"
104
+ require "ui/newinterne.rb"
109
105
  require "ui/productswindow.rb"
110
106
  require "ui/loginwindow.rb"
111
107
 
@@ -0,0 +1,295 @@
1
+ module Ig3tool
2
+ class Actions
3
+
4
+ # Geeft alle secties terug die in de bib te vinden zijn.
5
+ def self.bib_sections(params)
6
+ BibSection.find(:all, :order => "name")
7
+ end
8
+
9
+ # Geeft een lijst van boeken terug.
10
+ # Geen params -> alle boeken
11
+ # ALL UPPERCASE -> alle boeken in die sectie
12
+ # else -> zoek in titels en auteurs
13
+ def self.bib_books(params)
14
+ p = params[:from_uri].first
15
+ if p.nil? || p.empty? then
16
+ BibBook.find(:all, :order => "title")
17
+ elsif p =~ /^(\d|X){10,}/ # Indien hij begint met X of een digit -> ISBN
18
+ BibBook.find(_isbn(p))
19
+ elsif p == p.upcase # Indien in uppercase -> Section
20
+ BibSection.find(p).books
21
+ else
22
+ p = '%' + p + '%'
23
+ BibBook.find(:all, :order => "title", :conditions => [ "title like ? or author like ?", p, p ])
24
+ end
25
+ end
26
+
27
+ # Geeft alle info over een boek terug
28
+ # Verwacht een ISBN
29
+ def self.bib_info(params)
30
+ raise Needed, "barcode" if params[:given_uri] != 1
31
+ isbn = _isbn(params[:from_uri].first) or raise InvalidISBN, "Invalid isbn number"
32
+ BibBook.find_by_isbn isbn # Return een boek
33
+ end
34
+
35
+ # Geeft alle uitgeleende boeken terug
36
+ # Verwacht geen parameters
37
+ def self.bib_loans(params)
38
+ if params[:given_uri] == 1
39
+ memberid = params[:from_uri].first
40
+ BibLoan.find_by_member_id(memberid)
41
+ else
42
+ BibLoan.find(:all, :order => "return_date ASC")
43
+ end
44
+ end
45
+
46
+ # Kijkt of een bepaald boek url[0] beschikbaar is
47
+ def self.bib_availableinfo(params)
48
+ raise Needed, "barcode" if params[:given_uri] != 1
49
+ isbn = _isbn(params[:from_uri].first)
50
+ _available(isbn,true)
51
+ end
52
+
53
+ # Kijkt of een bepaald boek url[0] beschikbaar is
54
+ def self.bib_available(params)
55
+ raise Needed, "barcode" if params[:given_uri] != 1
56
+ isbn = _isbn(params[:from_uri].first) or raise InvalidISBN, "Invalid isbn number"
57
+ _available(isbn)
58
+ end
59
+
60
+ # Vernietigt de lening van het gegeven 'isbn' en 'member'
61
+ def self.bib_return!(params)
62
+ isbn = _isbn(params["isbn"]) or raise InvalidISBN, "Invalid isbn number"
63
+ member = params["member"] or raise Needed, "membership"
64
+ name = Membership.find(member).username
65
+ book = BibBook.find(isbn)
66
+ l = BibLoan.find(:all, :conditions =>
67
+ [ "member_id = ? and isbn = ?", member, isbn ])
68
+ if l.empty?
69
+ raise NotFound, "Book #{isbn} not loaned by #{name}" if loan.nil?
70
+ else
71
+ Logger::log :bib, :return, "%s returned %s (%s)" %
72
+ [ name, isbn, book.title ]
73
+
74
+ l.first.destroy
75
+ "OK"
76
+ end
77
+ rescue ActiveRecord::RecordNotFound
78
+ raise NotAMember, params['member']
79
+ end
80
+
81
+ def self.bib_lookup(params)
82
+ raise Needed, "search value" if params[:given_uri] == 0
83
+ raise Needed, "even number of values" if params[:given_uri] % 2 == 1
84
+
85
+ valid_keys = %w(title author publisher year section copies isbn)
86
+ h = params[:from_uri].to_h
87
+ h["isbn"] = _isbn(h["isbn"]) unless h["isbn"].nil?
88
+ BibBook.hash_lookup(h, valid_keys)
89
+ end
90
+
91
+ # Maakt een lening aan voor het gegeven 'isbn' voor 'member' met 'warranty'.
92
+ # Standaard datum van teruggave is nu+3 weken,
93
+ # standaard garantie is "debugger ? 0 : 5"
94
+ def self.bib_loan!(params)
95
+ isbn = _isbn(params["isbn"]) or raise InvalidISBN, "Invalid isbn number"
96
+ book = BibBook.find(isbn)
97
+
98
+ raise BookNotAvaible, "All copies loaned out!" unless book.available?
99
+
100
+ member = Membership.find params["member"]
101
+ raise NotAMember, params["member"] if member.nil?
102
+
103
+ warranty = params["warranty"] || (member.debugger? ? 0 : 5)
104
+ loan_date = Time.now
105
+ return_date = Time.now + 3.weeks
106
+
107
+ BibLoan.create(:isbn => book.isbn,
108
+ :member_id => member.barcode,
109
+ :warranty => warranty,
110
+ :loan_date => loan_date,
111
+ :return_date => return_date)
112
+
113
+ Logger::log :bib, :loan, "%s loaned %s (%s)." %
114
+ [ member.person.username, isbn, book.title ]
115
+
116
+ "OK"
117
+ end
118
+
119
+ # Verleng een lening voor het gegeven 'isbn' voor 'member'.
120
+ def self.bib_extend!(params)
121
+ isbn = _isbn(params["isbn"]) or raise InvalidISBN, "Invalid isbn number"
122
+
123
+ member = Membership.find params["member"]
124
+ raise NotAMember, params["member"] if member.nil?
125
+
126
+ book = BibBook.find(isbn)
127
+ loan = BibLoan.find_by_isbn_and_member_id(book.isbn, member.barcode)
128
+ return_date = Time.parse(loan.return_date) + 3.weeks
129
+ #return_date = Time.now + 3.weeks
130
+ #
131
+ loan.return_date = return_date
132
+ loan.save!
133
+
134
+ Logger::log :bib, :loan, "%s extended %s (%s)." %
135
+ [ member.person.username, isbn, book.title ]
136
+
137
+ loan # Return Loan
138
+ end
139
+
140
+ # Een boek aanmaken. Verwacht "isbn", "title", "author", "publisher", "year".
141
+ # Mogelijkheid om "copies" ook bij te zetten, default 1.
142
+ # Returnt het ISBN van het nieuwe boek.
143
+ def self.bib_add!(params)
144
+ notfound = []
145
+ [:isbn, :title, :author, :publisher, :year].each do |k|
146
+ notfound << k if params[k.to_s].nil?
147
+ end
148
+
149
+ raise Needed, notfound unless notfound.empty?
150
+ isbn = _isbn(params["isbn"]) or raise InvalidISBN, "Invalid isbn number"
151
+
152
+ b = BibBook.find_by_isbn(isbn)
153
+
154
+ unless b.nil?
155
+ b.title = params["title"]
156
+ b.author = params["author"]
157
+ b.publisher = params["publisher"]
158
+ b.year = params["year"]
159
+ b.section = params["section"]
160
+ b.copies = params["copies"] || 1
161
+ b.save # DB Save
162
+
163
+ Logger::log :bib, :update, "Book %s (%s) updated." %
164
+ [ params["isbn"], params["title"] ]
165
+
166
+ else
167
+ b = BibBook.new(:isbn => isbn,
168
+ :title => params["title"],
169
+ :author => params["author"],
170
+ :publisher => params["publisher"],
171
+ :year => params["year"],
172
+ :section => params["section"],
173
+ :copies => params["copies"] || 1)
174
+
175
+ b.save!
176
+
177
+ Logger::log :bib, :add, "Book %s (%s) created." %
178
+ [ isbn, params["title"] ]
179
+ end
180
+
181
+ b.isbn
182
+
183
+ rescue ActiveRecord::RecordInvalid
184
+ raise BibSectionNotFound, "the ig3tool imps want you to select a section..."
185
+ end
186
+
187
+ # Een boek verwijderen, verwacht het ISBN nummer in :isbn.
188
+ def self.bib_remove!(params)
189
+ isbn = _isbn(params["isbn"]) or raise InvalidISBN, "Invalid isbn number"
190
+ book = BibBook.find(isbn)
191
+ raise BookNotAvaible, "Book is loaned" unless book.loans.empty?
192
+
193
+ book.destroy
194
+
195
+ Logger::log :bib, :remove, "Book %d removed." % params["isbn"]
196
+
197
+ "OK"
198
+ rescue ActiveRecord::RecordNotFound
199
+ raise NotFound, "book"
200
+ end
201
+
202
+ private
203
+ # Kijk of een bepaald boek nog beschikbaar is
204
+ def self._available(isbn,extra_info = false)
205
+ begin
206
+ begin
207
+ b = BibBook.find(isbn)
208
+ rescue ActiveRecord::RecordNotFound
209
+ b = BibBook.find(_isbn(isbn))
210
+ end
211
+
212
+
213
+ if extra_info
214
+ { "copies" => b.copies, "loans" => b.loans.length }
215
+ else
216
+ b.available?
217
+ end
218
+ rescue ActiveRecord::RecordNotFound
219
+ raise NotFound, "the ig3tool imps found no such book..."
220
+ end
221
+
222
+ end
223
+
224
+ # Controleert op de geldigheid van een isbn nummer
225
+ # isbn nummers die beginnen met IG0 zijn gevrijwaard van de controle
226
+ # en dienen voor zelfgemaakte barcode
227
+ def self._isbn (code, strong_check = false)
228
+ code = code.to_s.gsub(/\W/, '')
229
+ raise Needed, "ISBN" if code.nil? or code.empty?
230
+
231
+ if !strong_check and code =~ /^IG0/ # Indien zelfgemaakte barcode
232
+ return code
233
+
234
+ # indien oude isbn (10 cijfers)
235
+ elsif code.length == 10
236
+ code = code.gsub(/[^0-9Xx]+/, '').tr('x', 'X')
237
+
238
+ sum = 0
239
+ 9.times {|i| sum += code[i].chr.to_i * (10 - i) }
240
+ sum += if code =~ /X$/ then 10 else code[9].chr.to_i end
241
+
242
+ # geldige barcode, converten naar 13
243
+ if sum % 11 == 0
244
+ return BibBook._isbn13(code)
245
+ end
246
+
247
+ # indien nieuwe isbn (13 cijfers - jan 2007)
248
+ elsif code.length == 13
249
+ sum = 0
250
+ multiply = 1
251
+ 0.upto(11){|i|
252
+ sum += code[i].chr.to_i * multiply
253
+ if multiply == 1 then multiply = 3 else multiply = 1 end
254
+ }
255
+
256
+ return code if code[12].chr.to_i == (10 - (sum % 10))
257
+ end
258
+
259
+ # geen geldig isbn
260
+ return nil
261
+ end
262
+
263
+ # XXX move naar util.rb?
264
+ # Convert ISBN10 naar ISBN13
265
+ def self._isbn13(code)
266
+ raise InvalidISBN if code.length != 10
267
+ code.chop!
268
+ code = "978" + code
269
+
270
+ sum = 0
271
+ code.split(//).each_with_index do |c, i|
272
+ sum += c.to_i * ( i % 2 == 0 ? 1 : 3 )
273
+ end
274
+
275
+ rem = sum % 10
276
+ check = (rem == 0) ? 0 : 10 - rem
277
+
278
+ code = code + check.to_s
279
+ end
280
+
281
+ # Convert ISBN13 naar ISBN10
282
+ def self._isbn10(code)
283
+ raise InvalidISBN if code.length != 13
284
+ code = code[3..11]
285
+
286
+ sum = 0
287
+ 9.times {|i| sum += code[i].chr.to_i * (10 - i) }
288
+
289
+ check = 11 - sum % 11
290
+ check = 0 if sum == 0
291
+ check = 'X' if check == 10
292
+ code = code + check.to_s
293
+ end
294
+ end
295
+ end
@@ -0,0 +1,19 @@
1
+ require 'bitching'
2
+
3
+ module Ig3tool
4
+ class Actions
5
+
6
+ def self.wannabe!(params)
7
+ username = params["username"] or raise Needed, "username"
8
+ password = params["password"] or raise Needed, "password"
9
+ Bitch.wannabe(username, password)
10
+ end
11
+
12
+ def self.register!(params)
13
+ username = params["username"] or raise Needed, "username"
14
+ password = params["password"] or raise Needed, "password"
15
+ Bitch.wannabe(username, password)
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ module Ig3tool
2
+ # :)
3
+ end
@@ -0,0 +1,98 @@
1
+ require 'people'
2
+ require 'interne'
3
+
4
+ module Ig3tool
5
+ class Actions
6
+
7
+ def self.internes(params)
8
+ internes = {}
9
+ Interne.find(:all) \
10
+ .sort { |a,b| a.person.username <=> b.person.username } \
11
+ .each { |i| internes[i.person.username] = i.saldo }
12
+ internes
13
+ end
14
+
15
+ # Verwacht een 'username' in de URL
16
+ # Geeft saldo terug
17
+ def self.interne(params)
18
+ raise NeedDebugger unless params[:given_uri] == 1
19
+ name = params[:from_uri].first
20
+ _interne(name).saldo
21
+ end
22
+
23
+ # Toon de InterneTransactions
24
+ # Geen debugger-username -> Alles
25
+ # Debugger-username -> Donor + Recipient
26
+ def self.interne_log(params)
27
+ # XXX TODO
28
+ # Change from LogEntry to InterneTransaction
29
+ # MAAR:
30
+ # eerst nog zorgen dat alle transacties ivm interne (dus ook scribblen enzo) ook weergegeven worden
31
+ # voorlopig dus via LogEntry zodat je meer info hebt
32
+ name, max_lines = params[:from_uri]
33
+ max_lines = 500 if max_lines.nil?
34
+
35
+ if name
36
+ name = "%#{name}%"
37
+ LogEntry.find(:all, :conditions => ["system = 'interne' and
38
+ subsystem = 'transfer' and
39
+ message like ?", name],
40
+ :order => "timestamp DESC",
41
+ :limit => max_lines)
42
+ else
43
+ LogEntry.find(:all, :order => "timestamp DESC",
44
+ :limit => max_lines)
45
+ end
46
+ end
47
+
48
+ # Verwacht in 'from','to' usernames
49
+ # Verwacht in 'saldo' een getal
50
+ # Geeft saldo terug.
51
+ def self.interne_transfer!(params)
52
+ from = params['from'] or raise Needed, "source interne"
53
+ to = params['to'] or raise Needed, "target interne"
54
+ amount = params['amount'].to_i or raise Needed, "amount"
55
+
56
+ if amount < 0 then
57
+ amount *= -1
58
+ from, to = to, from
59
+ end
60
+
61
+ raise IG3Error, "Having fun playing with yourself?" if from == to
62
+ raise IG3Error, "No sense in transferring 0 credits.." if amount == 0
63
+
64
+ case
65
+ when from == "kas" # geld UIT de kassa
66
+ Logger::log :interne, :withdraw, '%s withdrew %.2f from kas' % [to, amount.to_f / 100]
67
+ _with_interne(to) { |s| s - amount }
68
+
69
+ when to == "kas" # geld IN de kassa
70
+ Logger::log :interne, :deposit, '%s deposited %.2f in kas' % [from, amount.to_f / 100]
71
+ _with_interne(from) { |s| s + amount }
72
+
73
+ else
74
+ Logger::log :interne, :transfer, '%s transferred %.2f to %s' % [from, amount.to_f / 100, to]
75
+ Interne.transaction do
76
+ _with_interne(to) { |s| s + amount }
77
+ _with_interne(from) { |s| s - amount }
78
+ end
79
+ end
80
+ end
81
+
82
+ private
83
+
84
+ def self._interne(name)
85
+ d = Person.find(name)
86
+ raise NotADebugger, name.to_s unless d.debugger?
87
+ d.interne
88
+ end
89
+
90
+ def self._with_interne(name)
91
+ i = _interne(name)
92
+ i.saldo = yield i.saldo
93
+ i.save
94
+ i.saldo
95
+ end
96
+
97
+ end
98
+ end