watobo 0.9.9.pre1 → 0.9.9.pre2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +1 -1
- data/lib/watobo/core/interceptor.rb +6 -2
- data/lib/watobo/gui/main_window.rb +2 -0
- data/lib/watobo/gui/page_tree.rb +10 -3
- data/lib/watobo.rb +1 -1
- data/plugins/crawler/gui/auth_frame.rb +22 -12
- data/plugins/crawler/gui/crawler_gui.rb +30 -15
- data/plugins/crawler/lib/engine.rb +68 -36
- data/plugins/crawler/lib/grabber.rb +11 -7
- metadata +2 -3
- data/.yardopts +0 -24
data/CHANGELOG
CHANGED
@@ -136,8 +136,11 @@ module Watobo
|
|
136
136
|
puts "*[I] #{request.url}"
|
137
137
|
|
138
138
|
rescue => bang
|
139
|
-
|
140
|
-
|
139
|
+
# puts "!!! Error reading client request "
|
140
|
+
# puts bang
|
141
|
+
# puts bang.backtrace
|
142
|
+
# puts request
|
143
|
+
# puts request
|
141
144
|
Thread.current.exit
|
142
145
|
#break
|
143
146
|
end
|
@@ -586,6 +589,7 @@ module Watobo
|
|
586
589
|
session = socket
|
587
590
|
# puts "* read header ..."
|
588
591
|
Watobo::HTTP.read_header(socket) do |line|
|
592
|
+
# puts line
|
589
593
|
request.push line
|
590
594
|
end
|
591
595
|
|
data/lib/watobo/gui/page_tree.rb
CHANGED
@@ -19,7 +19,7 @@
|
|
19
19
|
# along with WATOBO; if not, write to the Free Software
|
20
20
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
21
21
|
# .
|
22
|
-
#require 'qcustomize.rb'
|
22
|
+
#require 'qcustomize.rb'
|
23
23
|
|
24
24
|
module Watobo
|
25
25
|
module Gui
|
@@ -200,8 +200,11 @@ module Watobo
|
|
200
200
|
end
|
201
201
|
|
202
202
|
form_name_item = nil
|
203
|
-
name = "
|
204
|
-
|
203
|
+
name = "undefined"
|
204
|
+
unless form.name.nil?
|
205
|
+
name = form.name unless form.name.empty?
|
206
|
+
end
|
207
|
+
form_name_item = self.appendItem(form_item, name, nil, nil)
|
205
208
|
|
206
209
|
unless form_name_item.nil?
|
207
210
|
self.setItemData(form_name_item, form)
|
@@ -210,6 +213,10 @@ module Watobo
|
|
210
213
|
self.setItemData(form_field_item, ff)
|
211
214
|
|
212
215
|
end
|
216
|
+
form.buttons.each do |fb|
|
217
|
+
form_field_item = self.appendItem(form_name_item, fb.name, nil, nil)
|
218
|
+
self.setItemData(form_field_item, fb)
|
219
|
+
end
|
213
220
|
end
|
214
221
|
|
215
222
|
unless form_item.nil?
|
data/lib/watobo.rb
CHANGED
@@ -34,7 +34,7 @@ module Watobo
|
|
34
34
|
|
35
35
|
def update_fields
|
36
36
|
self.getNumRows.times do |i|
|
37
|
-
self.getItemData(i,0).value = self.getItemText(i,
|
37
|
+
self.getItemData(i,0).value = self.getItemText(i,2)
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
@@ -61,8 +61,11 @@ module Watobo
|
|
61
61
|
self.setItemData(lastRowIndex, 0, field)
|
62
62
|
self.setItemText(lastRowIndex, 0, field.name)
|
63
63
|
self.getItem(lastRowIndex, 0).justify = FXTableItem::LEFT
|
64
|
-
self.setItemText(lastRowIndex, 1, field.
|
64
|
+
self.setItemText(lastRowIndex, 1, field.type)
|
65
|
+
puts field.methods.sort
|
65
66
|
self.getItem(lastRowIndex, 1).justify = FXTableItem::LEFT
|
67
|
+
self.setItemText(lastRowIndex, 2, field.value)
|
68
|
+
self.getItem(lastRowIndex, 2).justify = FXTableItem::LEFT
|
66
69
|
|
67
70
|
end
|
68
71
|
private
|
@@ -71,7 +74,7 @@ module Watobo
|
|
71
74
|
begin
|
72
75
|
row = item.row
|
73
76
|
self.selectRow(row, false)
|
74
|
-
self.startInput(row,
|
77
|
+
self.startInput(row,2)
|
75
78
|
rescue => bang
|
76
79
|
puts bang
|
77
80
|
end
|
@@ -87,14 +90,16 @@ module Watobo
|
|
87
90
|
|
88
91
|
def initTable
|
89
92
|
self.clearItems()
|
90
|
-
self.setTableSize(0,
|
93
|
+
self.setTableSize(0, 3)
|
91
94
|
|
92
|
-
self.setColumnText( 0, "
|
93
|
-
self.setColumnText( 1, "
|
95
|
+
self.setColumnText( 0, "Name" )
|
96
|
+
self.setColumnText( 1, "Type" )
|
97
|
+
self.setColumnText( 2, "Value" )
|
94
98
|
|
95
99
|
self.rowHeader.width = 0
|
96
100
|
self.setColumnWidth(0, 100)
|
97
101
|
self.setColumnWidth(1, 100)
|
102
|
+
self.setColumnWidth(2, 100)
|
98
103
|
end
|
99
104
|
end
|
100
105
|
|
@@ -205,23 +210,25 @@ module Watobo
|
|
205
210
|
|
206
211
|
page = nil
|
207
212
|
url = nil
|
213
|
+
|
214
|
+
if @form_auth_url_txt.text.empty?
|
208
215
|
unless Watobo::Plugin::Crawler.start_url.nil?
|
209
216
|
uri = Watobo::Plugin::Crawler.start_url
|
217
|
+
end
|
210
218
|
else
|
211
|
-
|
219
|
+
url = @form_auth_url_txt.text unless @form_auth_url_txt.text.empty?
|
212
220
|
uri = URI.parse(url)
|
213
221
|
end
|
214
222
|
|
215
|
-
notify(:log, "GET PAGE << #{
|
223
|
+
notify(:log, "GET PAGE << #{uri.to_s}")
|
216
224
|
@agent, page = @crawler.get_page(uri)
|
217
225
|
notify(:log, "PAGE LOADED")
|
218
226
|
@page_tree.page = page
|
219
227
|
rescue => bang
|
220
|
-
notify(:log, "could not get page #{
|
221
|
-
puts "Could not get page for #{
|
222
|
-
puts url.class
|
228
|
+
notify(:log, "could not get page #{uri.to_s}")
|
229
|
+
puts "Could not get page for #{uri.to_s}"
|
223
230
|
puts bang
|
224
|
-
puts bang.backtrace
|
231
|
+
puts bang.backtrace if $DEBUG
|
225
232
|
end
|
226
233
|
true
|
227
234
|
}
|
@@ -233,6 +240,9 @@ module Watobo
|
|
233
240
|
form.fields.each do |field|
|
234
241
|
@form_fields_table.add_field field
|
235
242
|
end
|
243
|
+
form.buttons.each do |field|
|
244
|
+
@form_fields_table.add_field field
|
245
|
+
end
|
236
246
|
}
|
237
247
|
|
238
248
|
end
|
@@ -23,18 +23,23 @@ module Watobo
|
|
23
23
|
module Plugin
|
24
24
|
module Crawler
|
25
25
|
def self.start_url
|
26
|
-
@start_url
|
26
|
+
@start_url ||= nil
|
27
27
|
end
|
28
28
|
|
29
29
|
def self.start_url=(url)
|
30
|
-
|
31
|
-
|
30
|
+
# puts "Set Start-URL to #{url}"
|
31
|
+
# puts url.class
|
32
32
|
begin
|
33
|
-
|
33
|
+
@start_url ||= nil
|
34
|
+
@start_url = url
|
35
|
+
|
36
|
+
@start_url = URI.parse(url) unless url.respond_to? :host
|
37
|
+
|
34
38
|
rescue => bang
|
35
|
-
|
39
|
+
puts bang
|
40
|
+
@start_url = nil
|
36
41
|
end
|
37
|
-
|
42
|
+
|
38
43
|
@start_url
|
39
44
|
end
|
40
45
|
|
@@ -82,16 +87,19 @@ module Watobo
|
|
82
87
|
@start_button.disable
|
83
88
|
|
84
89
|
@url_txt.connect(SEL_COMMAND){ |sender, sel, item|
|
85
|
-
|
90
|
+
if url_valid?
|
91
|
+
# @start_button.setFocus()
|
92
|
+
Watobo::Plugin::Crawler.start_url = start_url
|
93
|
+
end
|
86
94
|
}
|
87
95
|
|
88
96
|
@url_txt.connect(SEL_CHANGED){
|
89
97
|
if url_valid?
|
90
|
-
|
98
|
+
|
91
99
|
@start_button.enable
|
92
100
|
else
|
93
101
|
@start_button.disable
|
94
|
-
|
102
|
+
# Watobo::Plugin::Crawler.start_url = nil
|
95
103
|
end
|
96
104
|
}
|
97
105
|
|
@@ -178,14 +186,21 @@ module Watobo
|
|
178
186
|
auth = @settings_tabbook.auth.to_h
|
179
187
|
# puts auth.to_yaml
|
180
188
|
case auth[:auth_type]
|
189
|
+
when :basic
|
190
|
+
auth[:auth_uri] = start_url
|
181
191
|
when :form
|
182
192
|
if auth.has_key? :form
|
183
|
-
|
184
|
-
|
185
|
-
|
193
|
+
begin
|
194
|
+
if auth[:form].buttons.length > 0
|
195
|
+
auth[:form].click_button
|
196
|
+
#@crawler.send_form(form).
|
197
|
+
elsif auth[:form].respond_to? :submit
|
186
198
|
puts "Submitting Form"
|
187
199
|
p = auth[:form].submit()
|
188
|
-
puts p.class
|
200
|
+
#puts p.class
|
201
|
+
end
|
202
|
+
rescue => bang
|
203
|
+
puts bang
|
189
204
|
end
|
190
205
|
end
|
191
206
|
end
|
@@ -214,8 +229,8 @@ module Watobo
|
|
214
229
|
|
215
230
|
def url_valid?
|
216
231
|
begin
|
217
|
-
return false unless @url_txt.text =~ /^https?:\/\//
|
218
|
-
url = URI.parse(@url_txt.text)
|
232
|
+
return false unless @url_txt.text.strip =~ /^https?:\/\//
|
233
|
+
url = URI.parse(@url_txt.text.strip)
|
219
234
|
# puts url.host.class
|
220
235
|
return true unless url.host.nil?
|
221
236
|
return false
|
@@ -22,25 +22,38 @@
|
|
22
22
|
module Watobo
|
23
23
|
module Crawler
|
24
24
|
|
25
|
-
#CRAWL_NONE = 0x00
|
26
|
-
# CRAWL_RUNNING = 0x01
|
27
|
-
# CRAWL_PAUSED = 0x02
|
28
|
-
|
29
25
|
class Agent < Mechanize
|
30
26
|
|
31
27
|
def initialize(opts)
|
32
28
|
super()
|
33
29
|
|
34
|
-
|
35
|
-
self.set_proxy( opts[:proxy_host], opts[:proxy_port] )
|
36
|
-
end
|
30
|
+
|
37
31
|
self.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
38
32
|
self.ignore_bad_chunking = true
|
33
|
+
self.keep_alive = false
|
34
|
+
|
39
35
|
self.user_agent = opts[:user_agent] if opts.has_key?(:user_agent)
|
36
|
+
|
37
|
+
if opts.has_key? :username and opts.has_key? :password
|
38
|
+
unless opts[:username].empty? and opts[:password].empty?
|
39
|
+
|
40
|
+
user = opts[:username]
|
41
|
+
pw = opts[:password]
|
42
|
+
uri = opts[:auth_uri]
|
43
|
+
#puts "Got Credentials for #{uri}: #{user} / #{pw}"
|
44
|
+
self.add_auth(uri, user , pw )
|
45
|
+
# TODO: remove this workaround for a Mechanize Bug (#243)
|
46
|
+
p = self.get uri
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
if ( opts.has_key? :proxy_host ) && ( opts.has_key? :proxy_port )
|
51
|
+
self.set_proxy( opts[:proxy_host], opts[:proxy_port] )
|
52
|
+
end
|
40
53
|
|
41
54
|
if opts.has_key? :pre_connect_hook
|
42
55
|
self.pre_connect_hooks << opts[:pre_connect_hook] if opts[:pre_connect_hook].respond_to? :call
|
43
|
-
end
|
56
|
+
end
|
44
57
|
|
45
58
|
unless opts[:cookie_jar].nil?
|
46
59
|
clean_jar = Mechanize::CookieJar.new
|
@@ -52,21 +65,6 @@ module Watobo
|
|
52
65
|
|
53
66
|
end
|
54
67
|
|
55
|
-
def initialize_UNUSED(opts)
|
56
|
-
super { |a|
|
57
|
-
|
58
|
-
if ( opts.has_key? :proxy_host ) && ( opts.has_key? :proxy_port )
|
59
|
-
a.set_proxy( opts[:proxy_host], opts[:proxy_port] )
|
60
|
-
end
|
61
|
-
a.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
62
|
-
a.ignore_bad_chunking = true
|
63
|
-
a.user_agent = opts[:user_agent] if opts.has_key?(:user_agent)
|
64
|
-
|
65
|
-
if opts.has_key? :pre_connect_hook
|
66
|
-
a.pre_connect_hooks << opts[:pre_connect_hook] if opts[:pre_connect_hook].respond_to? :call
|
67
|
-
end
|
68
|
-
}
|
69
|
-
end
|
70
68
|
end
|
71
69
|
|
72
70
|
class Engine
|
@@ -107,6 +105,8 @@ module Watobo
|
|
107
105
|
|
108
106
|
def initialize(opts={})
|
109
107
|
@event_dispatcher_listeners = Hash.new
|
108
|
+
@status_lock = Mutex.new
|
109
|
+
|
110
110
|
@opts = {
|
111
111
|
:submit_forms => true,
|
112
112
|
:max_depth => 5,
|
@@ -125,6 +125,7 @@ module Watobo
|
|
125
125
|
:root_path => "", # regex
|
126
126
|
:username => "",
|
127
127
|
:password => "",
|
128
|
+
:auth_uri => nil,
|
128
129
|
:auth_domain => "", # for ntlm auth
|
129
130
|
:cookie_jar => nil
|
130
131
|
}
|
@@ -149,25 +150,33 @@ module Watobo
|
|
149
150
|
end
|
150
151
|
|
151
152
|
def pause
|
152
|
-
|
153
|
+
false
|
153
154
|
end
|
154
155
|
|
155
156
|
def cancel
|
156
|
-
|
157
|
-
|
157
|
+
puts "[CRAWLER] - CANCEL!!"
|
158
|
+
@status_lock.synchronize do
|
159
|
+
@engine_status = CRAWL_NONE
|
160
|
+
end
|
158
161
|
@grabber_threads.each do |gt|
|
162
|
+
puts "Killing Thread #{gt}"
|
159
163
|
gt.kill
|
164
|
+
gt.raise "CANCEL"
|
160
165
|
end
|
161
166
|
@grabber_threads.each{|t| t.join }
|
167
|
+
|
168
|
+
@link_queue.clear
|
169
|
+
@page_queue.clear
|
162
170
|
@grabber_threads.clear
|
163
171
|
@link_keys.clear
|
164
172
|
@link_counts.clear
|
165
173
|
|
166
174
|
@form_keys.clear
|
167
175
|
@form_counts.clear
|
168
|
-
@engine_status = CRAWL_NONE
|
169
|
-
notify( :update_status, current_status )
|
170
176
|
|
177
|
+
notify( :update_status, current_status )
|
178
|
+
puts "CANCELED - CANCELED"
|
179
|
+
# exit
|
171
180
|
end
|
172
181
|
|
173
182
|
def run(url, opts={})
|
@@ -192,19 +201,23 @@ module Watobo
|
|
192
201
|
|
193
202
|
@link_queue.enq LinkBag.new(start_link, 0)
|
194
203
|
|
195
|
-
puts "[Crawler]
|
196
|
-
|
197
|
-
|
204
|
+
puts "[Crawler] Engine Settings:"
|
205
|
+
@opts.each do |k,v|
|
206
|
+
puts "#{k}: #{v}"
|
207
|
+
end
|
208
|
+
puts "---"
|
209
|
+
notify(:log, "Crawling #{url} started ..." )
|
198
210
|
|
199
211
|
@opts[:max_threads].times do |i|
|
200
212
|
g = Grabber.new(@link_queue, @page_queue, @opts )
|
201
213
|
@grabber_threads << g.run
|
202
214
|
end
|
203
215
|
|
204
|
-
|
205
|
-
@engine_status = CRAWL_RUNNING
|
216
|
+
@engine_status = CRAWL_RUNNING
|
206
217
|
|
218
|
+
loop do
|
207
219
|
pagebag = @page_queue.deq
|
220
|
+
|
208
221
|
process_links(pagebag)
|
209
222
|
|
210
223
|
process_forms(pagebag)
|
@@ -212,14 +225,17 @@ puts "[Crawler] engine starting ..."
|
|
212
225
|
|
213
226
|
puts "Links/Pages: #{@link_queue.size}/#{@page_queue.size}"
|
214
227
|
notify( :update_status, current_status )
|
215
|
-
|
228
|
+
# if @link_queue.empty? and @page_queue.empty?
|
229
|
+
if @page_queue.empty?
|
230
|
+
# if page_queue is empty wait for all grabber threads finishing the link_queue
|
216
231
|
until @link_queue.num_waiting == @grabber_threads.length
|
217
232
|
Thread.pass
|
218
233
|
end
|
234
|
+
# when the link_queue is finished check the page_queue. Crawling is finished if page_queue is empty too.
|
219
235
|
if @page_queue.empty?
|
220
236
|
@grabber_threads.each { |t| t.kill }
|
221
237
|
puts "Finished Crawling"
|
222
|
-
@engine_status = CRAWL_NONE
|
238
|
+
@status_lock.synchronize{ @engine_status = CRAWL_NONE }
|
223
239
|
notify(:log, "Crawling finished")
|
224
240
|
notify( :update_status, current_status )
|
225
241
|
break
|
@@ -314,17 +330,20 @@ end
|
|
314
330
|
|
315
331
|
fp = "#{form.action}"
|
316
332
|
fp << form.method
|
333
|
+
if form.request_data =~ /=/
|
317
334
|
data = form.request_data.split("&").sort.join("&")
|
318
335
|
if o[:clear_values]
|
319
336
|
fp << data.gsub(/=[^&]*/,'=')
|
320
337
|
else
|
321
338
|
fp << data
|
322
339
|
end
|
340
|
+
end
|
323
341
|
fkey = Digest::MD5.hexdigest fp
|
324
342
|
fkey
|
325
343
|
end
|
326
344
|
|
327
345
|
def send_form(form, depth)
|
346
|
+
return false if @engine_status == CRAWL_NONE
|
328
347
|
cfk = form_key(form, :clear_values => true)
|
329
348
|
@form_counts[cfk] ||= 0
|
330
349
|
@form_counts[cfk] += 1
|
@@ -335,7 +354,12 @@ end
|
|
335
354
|
@form_keys[fk] = nil
|
336
355
|
begin
|
337
356
|
if @form_counts[cfk] < @opts[:max_repeat]
|
357
|
+
if form.buttons.length > 0
|
358
|
+
p = form.click_button
|
359
|
+
else
|
338
360
|
p = form.submit()
|
361
|
+
end
|
362
|
+
puts p.class
|
339
363
|
@page_queue.enq PageBag.new(p, depth+1)
|
340
364
|
else
|
341
365
|
puts "! MAX REPEAT !\nSkipped Form #{form.action}"
|
@@ -348,6 +372,7 @@ end
|
|
348
372
|
|
349
373
|
def send_form?(form)
|
350
374
|
# puts "SEND FORM?"
|
375
|
+
return false unless engine_running?
|
351
376
|
return false unless @opts[:submit_forms] == true
|
352
377
|
# puts "> submit_forms"
|
353
378
|
return false unless allowed? form.action
|
@@ -416,7 +441,7 @@ end
|
|
416
441
|
# need to handle different link objects, Mechanize::Page::Link and URIs
|
417
442
|
uri = nil
|
418
443
|
uri = link.uri if link.respond_to? :uri
|
419
|
-
uri = URI.parse(link)
|
444
|
+
uri = URI.parse(link) if link.is_a? String
|
420
445
|
uri = link if link.is_a? URI::HTTP
|
421
446
|
|
422
447
|
return false if uri.nil?
|
@@ -450,6 +475,13 @@ end
|
|
450
475
|
Digest::MD5.hexdigest key
|
451
476
|
end
|
452
477
|
|
478
|
+
def engine_running?
|
479
|
+
@status_lock.synchronize do
|
480
|
+
return false if @engine_status == CRAWL_NONE
|
481
|
+
return true
|
482
|
+
end
|
483
|
+
end
|
484
|
+
|
453
485
|
def link_is_followed?(link)
|
454
486
|
|
455
487
|
return true if @link_keys.has_key? link_key(link)
|
@@ -46,7 +46,7 @@ module Watobo
|
|
46
46
|
return nil if page.nil?
|
47
47
|
return PageBag.new( page, linkbag.depth+1 )
|
48
48
|
rescue => bang
|
49
|
-
puts bang
|
49
|
+
puts bang #if $DEBUG
|
50
50
|
puts bang.backtrace if $DEBUG
|
51
51
|
end
|
52
52
|
return nil
|
@@ -54,15 +54,18 @@ module Watobo
|
|
54
54
|
|
55
55
|
def run
|
56
56
|
Thread.new(@link_queue, @page_queue){ |lq, pq|
|
57
|
-
|
58
|
-
|
59
|
-
link, referer, depth = lq.deq
|
57
|
+
loop do
|
58
|
+
begin
|
59
|
+
#link, referer, depth = lq.deq
|
60
|
+
link = lq.deq
|
61
|
+
next if link.depth > @opts[:max_depth]
|
60
62
|
page = get_page(link)
|
61
63
|
pq << page unless page.nil?
|
64
|
+
|
65
|
+
rescue => bang
|
66
|
+
puts bang
|
67
|
+
puts bang.backtrace
|
62
68
|
end
|
63
|
-
rescue => bang
|
64
|
-
puts bang
|
65
|
-
puts bang.backtrace
|
66
69
|
end
|
67
70
|
}
|
68
71
|
end
|
@@ -73,6 +76,7 @@ module Watobo
|
|
73
76
|
@opts = opts
|
74
77
|
begin
|
75
78
|
@agent = Crawler::Agent.new(@opts)
|
79
|
+
|
76
80
|
rescue => bang
|
77
81
|
puts bang
|
78
82
|
puts bang.backtrace
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: watobo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.9.
|
4
|
+
version: 0.9.9.pre2
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-06
|
12
|
+
date: 2012-07-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: mechanize
|
@@ -331,7 +331,6 @@ files:
|
|
331
331
|
- icons/Yellow Ball_24x24.ico
|
332
332
|
- README
|
333
333
|
- CHANGELOG
|
334
|
-
- .yardopts
|
335
334
|
- bin/watobo_gui.rb
|
336
335
|
- bin/watobo
|
337
336
|
homepage: http://watobo.sourceforge.net
|
data/.yardopts
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
# .
|
2
|
-
# .yardopts
|
3
|
-
#
|
4
|
-
# Copyright 2012 by siberas, http://www.siberas.de
|
5
|
-
#
|
6
|
-
# This file is part of WATOBO (Web Application Tool Box)
|
7
|
-
# http://watobo.sourceforge.com
|
8
|
-
#
|
9
|
-
# WATOBO is free software; you can redistribute it and/or modify
|
10
|
-
# it under the terms of the GNU General Public License as published by
|
11
|
-
# the Free Software Foundation version 2 of the License.
|
12
|
-
#
|
13
|
-
# WATOBO is distributed in the hope that it will be useful,
|
14
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
-
# GNU General Public License for more details.
|
17
|
-
#
|
18
|
-
# You should have received a copy of the GNU General Public License
|
19
|
-
# along with WATOBO; if not, write to the Free Software
|
20
|
-
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
21
|
-
# .
|
22
|
-
--no-private
|
23
|
-
*.xxx
|
24
|
-
- CHANGELOG
|