dohruby 0.2.1 → 0.3

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 (154) hide show
  1. data/CHANGELOG +8 -0
  2. data/bin/config.rb +61 -0
  3. data/bin/create_database.rb +13 -6
  4. data/bin/gendata.rb +37 -0
  5. data/bin/migrate.rb +66 -0
  6. data/bin/{rcov-preprocess-files.rb → rcov_preprocess_files.rb} +1 -1
  7. data/bin/run_tests.rb +15 -5
  8. data/bin/update_rdoc.rb +28 -0
  9. data/dohapp_home +0 -0
  10. data/lib/doh/app/activate_database.rb +5 -12
  11. data/lib/doh/app/activate_logger.rb +29 -13
  12. data/lib/doh/app/config.rb +18 -0
  13. data/lib/doh/app/home.rb +3 -8
  14. data/lib/doh/app/init_runnable.rb +39 -8
  15. data/lib/doh/app/init_script.rb +19 -0
  16. data/lib/doh/app/init_unit_test.rb +4 -1
  17. data/lib/doh/app_no_stdio.rb +1 -1
  18. data/lib/doh/boot/app.rb +2 -0
  19. data/lib/doh/boot/app_pwd.rb +2 -0
  20. data/lib/doh/boot/find_dohruby.rb +5 -0
  21. data/lib/doh/boot/find_dohruby_18.rb +37 -0
  22. data/lib/doh/boot/find_dohruby_19.rb +58 -0
  23. data/lib/doh/boot/init_runnable.rb +2 -0
  24. data/lib/doh/boot/options.rb +2 -0
  25. data/lib/doh/core/array.rb +10 -0
  26. data/lib/doh/core/bigdecimal.rb +15 -0
  27. data/lib/doh/core/date.rb +73 -0
  28. data/lib/doh/core/deep_dup.rb +12 -0
  29. data/lib/doh/core/hash.rb +21 -0
  30. data/lib/doh/core/object.rb +6 -0
  31. data/lib/doh/core/require_local.rb +5 -0
  32. data/lib/doh/core/socket.rb +25 -0
  33. data/lib/doh/core/string.rb +34 -4
  34. data/lib/doh/core.rb +4 -1
  35. data/lib/doh/data/basic.rb +24 -19
  36. data/lib/doh/data/bulk.rb +28 -88
  37. data/lib/doh/data/catalog.rb +44 -0
  38. data/lib/doh/data/human.rb +50 -42
  39. data/lib/doh/data/make_global.rb +3 -0
  40. data/lib/doh/data/require_datagen.rb +2 -1
  41. data/lib/doh/home.rb +16 -0
  42. data/lib/doh/logger/email_acceptor.rb +6 -3
  43. data/lib/doh/logger/event.rb +19 -6
  44. data/lib/doh/logger/formatter.rb +22 -16
  45. data/lib/doh/logger/interface.rb +13 -0
  46. data/lib/doh/logger/iostream_acceptor.rb +3 -2
  47. data/lib/doh/logger/null_interface.rb +1 -0
  48. data/lib/doh/logger/proxy.rb +53 -0
  49. data/lib/doh/logger/socket_acceptor.rb +53 -0
  50. data/lib/doh/logger/socket_viewer.rb +64 -0
  51. data/lib/doh/logger/standard_interface.rb +46 -17
  52. data/lib/doh/logger/util.rb +18 -0
  53. data/lib/doh/logger.rb +2 -1
  54. data/lib/doh/logger_configure.rb +1 -1
  55. data/lib/doh/merb/db_session.rb +136 -0
  56. data/lib/doh/merb/form_helpers.rb +16 -0
  57. data/lib/doh/merb/login.rb +27 -12
  58. data/lib/doh/merb/merb_dohsession.rb +4 -0
  59. data/lib/doh/merb/notify_on_exception.rb +1 -1
  60. data/lib/doh/merb/session.rb +7 -0
  61. data/lib/doh/merb/source_ip.rb +10 -0
  62. data/lib/doh/merb.rb +0 -1
  63. data/lib/doh/mysql/abstract_row.rb +81 -0
  64. data/lib/doh/mysql/cache_connector.rb +11 -8
  65. data/lib/doh/mysql/connector_instance.rb +32 -5
  66. data/lib/doh/mysql/connector_util.rb +1 -0
  67. data/lib/doh/mysql/convert.rb +18 -0
  68. data/lib/doh/mysql/database_creator.rb +18 -5
  69. data/lib/doh/mysql/db_date.rb +2 -2
  70. data/lib/doh/mysql/default_type_guesser.rb +21 -4
  71. data/lib/doh/mysql/error.rb +3 -2
  72. data/lib/doh/mysql/handle.rb +144 -18
  73. data/lib/doh/mysql/hash_row.rb +13 -0
  74. data/lib/doh/mysql/load_sql.rb +1 -0
  75. data/lib/doh/mysql/metadata_util.rb +60 -19
  76. data/lib/doh/mysql/migrate.rb +122 -0
  77. data/lib/doh/mysql/migrate_check.rb +139 -0
  78. data/lib/doh/mysql/parse.rb +2 -0
  79. data/lib/doh/mysql/readonly_row.rb +11 -48
  80. data/lib/doh/mysql/require_dbtypes.rb +8 -0
  81. data/lib/doh/mysql/smart_row.rb +156 -0
  82. data/lib/doh/mysql/to_sql.rb +12 -0
  83. data/lib/doh/mysql/typed_row_builder.rb +4 -3
  84. data/lib/doh/mysql/types.rb +33 -0
  85. data/lib/doh/mysql/unquoted.rb +8 -0
  86. data/lib/doh/mysql/version.rb +102 -0
  87. data/lib/doh/mysql/virtual.rb +17 -0
  88. data/lib/doh/mysql/writable_row.rb +58 -0
  89. data/lib/doh/mysql.rb +2 -1
  90. data/lib/doh/paypal/paypal.rb +20 -0
  91. data/lib/doh/paypal/pdt.rb +14 -0
  92. data/lib/doh/paypal.rb +1 -0
  93. data/lib/doh/rails/form_helpers.rb +53 -0
  94. data/lib/doh/rails/login.rb +143 -0
  95. data/lib/doh/test/error_acceptor.rb +1 -1
  96. data/lib/doh/test/run_tests.rb +48 -43
  97. data/lib/doh/test/setup_once.rb +15 -0
  98. data/lib/doh/test/test_result.rb +7 -0
  99. data/lib/doh/unit_test.rb +6 -0
  100. data/lib/doh/util/banking_workday.rb +16 -12
  101. data/lib/doh/util/class_basename.rb +10 -0
  102. data/lib/doh/util/current_date.rb +18 -41
  103. data/lib/doh/util/doh_socket.rb +56 -0
  104. data/lib/doh/util/email.rb +18 -0
  105. data/lib/doh/util/file_edit.rb +64 -0
  106. data/lib/doh/util/http_helper.rb +107 -0
  107. data/lib/doh/util/internal_ip.rb +1 -1
  108. data/lib/doh/util/jsval.rb +13 -0
  109. data/lib/doh/util/post_hash.rb +14 -0
  110. data/lib/doh/util/xml_util.rb +48 -0
  111. data/test/core/tc_array.rb +12 -0
  112. data/test/core/tc_date.rb +53 -0
  113. data/test/core/tc_deep_dup.rb +69 -0
  114. data/test/core/tc_hash.rb +28 -0
  115. data/test/core/tc_socket.rb +30 -0
  116. data/test/core/tc_string.rb +15 -22
  117. data/test/local_tests.rb +3 -0
  118. data/test/local_tests_including_slow.rb +4 -0
  119. data/test/logger/tc_acceptor.rb +23 -6
  120. data/test/logger/tc_event.rb +1 -1
  121. data/test/logger/tc_formatter.rb +3 -2
  122. data/test/logger/tc_socket_viewer_acceptor.rb +48 -0
  123. data/test/mysql/001_down.sql +1 -0
  124. data/test/mysql/001_up.sql +4 -0
  125. data/test/mysql/002_down.sql +1 -0
  126. data/test/mysql/002_up.sql +1 -0
  127. data/test/mysql/tc_connector_instance.rb +8 -8
  128. data/test/mysql/tc_convert.rb +45 -0
  129. data/test/mysql/tc_handle.rb +94 -2
  130. data/test/mysql/tc_metadata_util.rb +50 -0
  131. data/test/mysql/tc_migrate.rb +50 -0
  132. data/test/mysql/tc_parse.rb +3 -1
  133. data/test/mysql/tc_readonly_row.rb +14 -10
  134. data/test/mysql/tc_smart_row.rb +22 -0
  135. data/test/mysql/tc_to_sql.rb +20 -0
  136. data/test/mysql/tc_types.rb +32 -0
  137. data/test/mysql/tc_unquoted.rb +1 -0
  138. data/test/mysql/tc_writable_row.rb +22 -0
  139. data/test/ts_core.rb +4 -0
  140. data/test/ts_logger.rb +4 -0
  141. data/test/ts_mysql.rb +6 -0
  142. data/test/ts_util.rb +6 -0
  143. data/test/util/slow_doh_socket.rb +102 -0
  144. data/test/util/tc_banking_workday.rb +18 -0
  145. data/test/util/tc_file_edit.rb +54 -0
  146. data/test/util/tc_jsval.rb +12 -0
  147. data/test/util/tc_to_display.rb +14 -0
  148. data/test/util/tc_xml_util.rb +17 -0
  149. metadata +130 -39
  150. data/README +0 -4
  151. data/lib/doh/merb/post_hash.rb +0 -26
  152. data/lib/doh/mysql/db_null.rb +0 -24
  153. data/lib/doh/mysql/hash_util.rb +0 -56
  154. data/test/mysql/tc_hash_util.rb +0 -23
@@ -1,82 +1,87 @@
1
1
  require 'doh/test/configure_logging'
2
- require 'doh/core/dir'
3
2
  require 'doh/app/activate_database'
4
3
  require 'doh/mysql/database_creator'
5
4
  require 'test/unit'
6
- require 'test/unit/collector/dir'
7
- require 'test/unit/ui/console/testrunner'
5
+ if RUBY_VERSION.to_d < 1.9
6
+ require 'test/unit/collector/dir'
7
+ require 'test/unit/ui/console/testrunner'
8
+ end
8
9
  require 'doh/test/clear_on_teardown'
10
+ require 'doh/test/setup_once'
9
11
  require 'doh/data/require_datagen'
12
+ require 'doh/test/test_result'
10
13
 
11
14
  module DohTest
12
15
 
13
- def self.find_tests(directory, match, files_found)
14
- Dir.glob(File.join(directory, match)).each {|filename| files_found.push(filename)}
15
- Dir.directories(directory).each {|subdir| find_tests(File.join(directory, subdir), match, files_found)}
16
- end
17
-
18
16
  def self.init_test_database
19
- dbname = DohApp::config['primary_database']
20
- DohDb::DatabaseCreator.new.create_database_copy('doh_test_' + dbname, dbname, true)
21
- end
22
-
23
- def self.init_live_database
24
- DohDb::connector_instance.reset
25
- DohDb::connector_instance.database = DohApp::config['primary_database']
17
+ if DohApp::config['database_type'] == 'mysql'
18
+ dbname = DohApp::config['primary_database']
19
+ DohDb::DatabaseCreator.new.create_database_copy('doh_test_' + dbname, dbname, true)
20
+ end
26
21
  end
27
22
 
28
- def self.execute_test_files(files, method_filter = nil)
23
+ def self.execute_test_files(files, method_filter = nil, growl_notify = nil)
24
+ if RUBY_VERSION.to_d < 1.9
29
25
  collector = Test::Unit::Collector::Dir.new
30
26
  collector.filter = [proc {|tstobj| !tstobj.method_name.index(method_filter).nil?}] if method_filter
31
27
  suite = collector.collect(*files)
32
28
  results = Test::Unit::UI::Console::TestRunner.run(suite)
29
+
30
+ dohlog.literal do
31
+ results.errors.each do |error|
32
+ dohlog.debug("got #{error.to_s}")
33
+ end
34
+ results.failures.each do |failure|
35
+ dohlog.debug("got #{failure.to_s}")
36
+ end
37
+ end
38
+
39
+ if growl_notify
40
+ if !results.passed?
41
+ `growlnotify -n run_tests_failed -m 'some tests failed' -p 1`
42
+ else
43
+ `growlnotify -n run_tests_passed -m 'all tests passed' -p -2`
44
+ end
45
+ end
33
46
  exit(1) unless results.passed?
34
47
  DohTest::check_for_unhandled_errors
48
+ else
49
+ files.each {|onefile| require onefile}
50
+ end
35
51
  end
36
52
 
37
- def self.run_tests_directory(directory, include_production_tests, method_filter = nil)
53
+ def self.run_tests_directory(directory, include_production_tests, include_slow_tests, method_filter = nil, growl_notify = nil)
54
+ result = false
38
55
  if include_production_tests
39
56
  letters = 'pq'
40
- run_integration_tests = false
41
57
  else
42
58
  letters = 'dp'
43
- run_integration_tests = true
44
59
  end
60
+ letters += 's' if include_slow_tests
45
61
 
46
- files = []; DohTest::find_tests(directory, "*.dt[#{letters}].rb", files)
62
+ files = Dir.glob(File.join(directory, '**', "*.dt[#{letters}].rb"))
47
63
  unless files.empty?
48
64
  init_test_database
49
- execute_test_files(files, method_filter)
50
- end
51
-
52
- return unless run_integration_tests
53
- files = []; DohTest::find_tests(directory, "*.dti.rb", files)
54
- unless files.empty?
55
- init_live_database
56
- execute_test_files(files)
65
+ execute_test_files(files, method_filter, growl_notify)
66
+ result = true
57
67
  end
68
+ result
58
69
  end
59
70
 
60
- def self.run_tests_file(filename, method_filter = nil)
61
- if filename.ends_with('.dti.rb')
62
- init_live_database
63
- else
64
- init_test_database
65
- end
66
- execute_test_files([filename], method_filter)
71
+ def self.run_tests_file(filename, method_filter = nil, growl_notify = nil)
72
+ init_test_database
73
+ execute_test_files([filename], method_filter, growl_notify)
74
+ true
67
75
  end
68
76
 
69
- def self.run_tests(what_to_run, include_production_tests, method_filter = nil)
77
+ def self.run_tests(what_to_run, include_production_tests, include_slow_tests, method_filter = nil, growl_notify = nil)
70
78
  DohApp::activate_database
71
79
  DohData::require_datagen
72
- what_to_run.each do |elem|
73
- if File.directory?(elem)
74
- run_tests_directory(elem, include_production_tests, method_filter)
75
- else
76
- run_tests_file(elem, method_filter)
77
- end
80
+ if File.directory?(what_to_run)
81
+ run_tests_directory(what_to_run, include_production_tests, include_slow_tests, method_filter, growl_notify)
82
+ else
83
+ run_tests_file(what_to_run, method_filter, growl_notify)
78
84
  end
79
- 0
80
85
  end
81
86
 
82
87
  end
@@ -0,0 +1,15 @@
1
+ module Test
2
+ module Unit
3
+ class TestCase
4
+ def setup
5
+ unless @setup_once
6
+ @setup_once = true
7
+ setup_once
8
+ end
9
+ end
10
+
11
+ def setup_once
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ module Test
2
+ module Unit
3
+ class TestResult
4
+ attr_reader(:failures, :errors)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ # this is intended for simple unit test files, particularly those for dohruby itself
2
+ # for a more powerful test setup, use bin/run_tests.rb
3
+
4
+ require 'doh/test/configure_logging'
5
+ at_exit { DohTest::check_for_unhandled_errors }
6
+ require 'test/unit'
@@ -1,20 +1,24 @@
1
1
  require 'doh/core/date'
2
2
 
3
3
  class Date
4
- # taken from http://www.federalreserve.gov/releases/k8/default.htm
5
- @@banking_holidays = [Date.new(2007, 1, 1), Date.new(2007, 1, 15), Date.new(2007, 2, 19), Date.new(2007, 5, 28), Date.new(2007, 7, 4), Date.new(2007, 9, 3), Date.new(2007, 10, 8), Date.new(2007, 11, 12), Date.new(2007, 11, 22), Date.new(2007, 12, 25),
6
- Date.new(2008, 1, 1), Date.new(2008, 1, 21), Date.new(2008, 2, 18), Date.new(2008, 5, 26), Date.new(2008, 7, 4), Date.new(2008, 9, 1), Date.new(2008, 10, 13), Date.new(2008, 11, 11), Date.new(2008, 11, 27), Date.new(2008, 12, 25),
7
- Date.new(2009, 1, 1), Date.new(2009, 1, 19), Date.new(2009, 2, 16), Date.new(2009, 5, 25), Date.new(2009, 7, 4), Date.new(2009, 9, 7), Date.new(2009, 10, 12), Date.new(2009, 11, 11), Date.new(2009, 11, 26), Date.new(2009, 12, 25),
8
- Date.new(2010, 1, 1), Date.new(2010, 1, 18), Date.new(2010, 2, 15), Date.new(2010, 5, 31), Date.new(2010, 7, 5), Date.new(2010, 9, 6), Date.new(2010, 10, 11), Date.new(2010, 11, 11), Date.new(2010, 11, 25), Date.new(2010, 12, 25),
9
- Date.new(2011, 1, 1), Date.new(2011, 1, 17), Date.new(2011, 2, 21), Date.new(2011, 5, 30), Date.new(2011, 7, 4), Date.new(2011, 9, 5), Date.new(2011, 10, 10), Date.new(2011, 11, 11), Date.new(2011, 11, 24), Date.new(2011, 12, 26),
10
- ]
11
-
12
- def banking_holiday?
13
- @@banking_holidays.include?(self)
4
+ # algoritm based on http://www.federalreserve.gov/releases/k8/default.htm and wikipedia pages about the individual holidays
5
+ def banking_workday?
6
+ return false if wday == 0 || wday == 6
7
+ !(case month
8
+ when 1 then (mday == 1) || ((wday == 1) && ((mday == 2) || (mday > 14 && mday < 22)))
9
+ when 2 then (wday == 1) && (mday > 14 && mday < 22)
10
+ when 5 then (wday == 1) && (mday > 24)
11
+ when 7 then (mday == 4) || ((mday == 5) && (wday == 1))
12
+ when 9 then (wday == 1) && (mday < 8)
13
+ when 10 then (wday == 1) && (mday > 7) && (mday < 15)
14
+ when 11 then (mday == 11) || ((mday == 12) && (wday == 1)) || ((wday == 4) && (mday > 21 && mday < 29))
15
+ when 12 then (mday == 25) || ((mday == 26) && (wday == 1))
16
+ else false
17
+ end)
14
18
  end
15
19
 
16
- def banking_workday?
17
- weekday? && !banking_holiday?
20
+ def banking_holiday?
21
+ weekday? && !banking_workday?
18
22
  end
19
23
 
20
24
  def forward_banking_workday(count = 1)
@@ -0,0 +1,10 @@
1
+ require 'doh/core/string'
2
+
3
+ module Doh
4
+
5
+ def self.class_basename(klass)
6
+ full_name = klass.to_s
7
+ full_name.rafter('::') || full_name
8
+ end
9
+
10
+ end
@@ -2,64 +2,41 @@ require 'doh/core/date'
2
2
 
3
3
  module Doh
4
4
 
5
- @@current_date = nil
6
- @@current_datetime = nil
5
+ @@current_date_objs = []
7
6
 
8
7
  def self.current_date(dflt = Date.today)
9
- @@current_date || (@@current_datetime && @@current_datetime.date_only) || dflt
8
+ return dflt if @@current_date_objs.empty?
9
+ @@current_date_objs.last.date_only
10
10
  end
11
11
 
12
- def self.set_current_date(date)
13
- @@current_date = date
12
+ def self.current_datetime(dflt = DateTime.zow)
13
+ return dflt if @@current_date_objs.empty?
14
+ cdo = @@current_date_objs.last
15
+ return cdo if cdo.respond_to?(:hour)
16
+ DateTime.new(cdo.year, cdo.month, cdo.day, dflt.hour, dflt.min, dflt.sec, dflt.zone)
14
17
  end
15
18
 
16
- def self.current_date_set?
17
- !@@current_date.nil?
19
+ def self.push_current_date(date_obj)
20
+ @@current_date_objs.push(date_obj)
18
21
  end
19
22
 
20
- def self.clear_current_date
21
- @@current_date = nil
22
- end
23
-
24
- def self.date_as(date, &block)
25
- save_date = @@current_date
26
- @@current_date = date
27
- begin
28
- retval = block.call
29
- rescue
30
- @@current_date = save_date
31
- raise
32
- end
33
- @@current_date = save_date
34
- retval
35
- end
36
-
37
- def self.current_datetime(dflt = DateTime.now)
38
- @@current_datetime || (@@current_date && DateTime.new(@@current_date.year, @@current_date.month, @@current_date.day, rand(12) + 2, rand(60), rand(60))) || dflt
39
- end
40
-
41
- def self.set_current_datetime(datetime)
42
- @@current_datetime = datetime
43
- end
44
-
45
- def self.current_datetime_set?
46
- !@@current_datetime.nil?
23
+ def self.pop_current_date
24
+ @@current_date_objs.pop
47
25
  end
48
26
 
49
- def self.clear_current_datetime
50
- @@current_datetime = nil
27
+ def self.clear_current_date
28
+ @@current_date_objs.clear
51
29
  end
52
30
 
53
- def self.datetime_as(datetime, &block)
54
- save_datetime = @@current_datetime
55
- @@current_datetime = datetime
31
+ def self.date_as(date_obj, &block)
32
+ push_current_date(date_obj)
56
33
  begin
57
34
  retval = block.call
58
35
  rescue
59
- @@current_datetime = save_datetime
60
36
  raise
37
+ ensure
38
+ pop_current_date
61
39
  end
62
- @@current_datetime = save_datetime
63
40
  retval
64
41
  end
65
42
 
@@ -0,0 +1,56 @@
1
+ require 'socket'
2
+
3
+ module Doh
4
+
5
+ class TimeoutError < RuntimeError
6
+ end
7
+
8
+ class DohSocket
9
+ @@socket_end_times = []
10
+ attr_accessor :timeout
11
+
12
+ def initialize(server, port)
13
+ @sock = TCPSocket.new(server, port)
14
+ @timeout = 300
15
+ end
16
+
17
+ def self.timeout_block(duration)
18
+ push_duration(duration)
19
+ begin
20
+ yield
21
+ ensure
22
+ pop_duration
23
+ end
24
+ end
25
+
26
+ def write(str)
27
+ @sock.write(str)
28
+ end
29
+
30
+ def timed_readln
31
+ received = ''
32
+ while (received =~ /$/) == received.size
33
+ if (!select([@sock], nil, nil, time_left))
34
+ raise TimeoutError.new('DohSocket timed_readln timed out')
35
+ end
36
+ received += @sock.recvfrom(65536)[0]
37
+ end
38
+ received
39
+ end
40
+
41
+ private
42
+ def self.push_duration(duration)
43
+ @@socket_end_times.push(Time.now + duration)
44
+ end
45
+
46
+ def self.pop_duration
47
+ @@socket_end_times.pop
48
+ end
49
+
50
+ def time_left
51
+ result = [@@socket_end_times, Time.now + @timeout].flatten.min - Time.now
52
+ result = 0.001 if result <= 0
53
+ result
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,18 @@
1
+ require 'net/smtp'
2
+ module DohEmail
3
+
4
+ @@mail_server = DohApp::config['mail_server'] || 'mail.' + DohApp::get_required_config_value('domain_name', 'mail_server or domain_name required for mail server')
5
+ @@from_address = DohApp::config['from_address'] || 'admin@' + DohApp::get_required_config_value('domain_name', 'from_address or domain_name required for notification email address')
6
+
7
+ def self.send_email(subject, body, recipients, from_address = @@from_address)
8
+ msg = "Subject:#{subject}\nFrom:#{from_address}\nTo:#{recipients.join(', ')}\nContent-Type: text/plain\n\n#{body}"
9
+ Net::SMTP.start(@@mail_server) do |smtp|
10
+ begin
11
+ smtp.send_message(msg, from_address, recipients)
12
+ rescue Exception => excpt
13
+ Doh::log.warn("got exception while sending email: #{excpt.inspect}")
14
+ end
15
+ end
16
+ end
17
+
18
+ end
@@ -0,0 +1,64 @@
1
+ require 'socket'
2
+
3
+ module Doh
4
+
5
+ class TimeoutError < RuntimeError
6
+ end
7
+
8
+ class FileEdit
9
+ def initialize(filename, &block)
10
+ @filename = filename
11
+ @file = File.new(filename, 'r').to_a
12
+ @file.each_with_index do |line, index|
13
+ @file[index] = @file[index][0..-2]
14
+ end
15
+ @index = 0
16
+
17
+ if block
18
+ yield(self)
19
+ save
20
+ end
21
+ end
22
+
23
+ def move_after(regexp)
24
+ @file.each_with_index do |line, index|
25
+ if line =~ regexp
26
+ @index = index + 1
27
+ end
28
+ end
29
+ end
30
+
31
+ def move_before(regexp)
32
+ move_after(regexp)
33
+ @index -= 1
34
+ end
35
+
36
+ def insert(*lines)
37
+ lines.each do |line|
38
+ @file.insert(@index, line)
39
+ @index += 1
40
+ end
41
+ end
42
+
43
+ def gsub(regexp, replacement)
44
+ @file.each_with_index do |line, index|
45
+ @file[index] = line.gsub(regexp, replacement)
46
+ end
47
+ end
48
+
49
+ def delete(numlines = 1)
50
+ numlines.times do
51
+ @file.delete_at(@index)
52
+ end
53
+ end
54
+
55
+ def save
56
+ outf = File.open(@filename, 'w+')
57
+ @file.each do |line|
58
+ outf << line << "\n"
59
+ end
60
+ outf.close
61
+ end
62
+ end
63
+
64
+ end
@@ -0,0 +1,107 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+ require 'uri'
4
+
5
+ module Doh
6
+
7
+ class HttpHelper
8
+ attr_reader :headers
9
+
10
+ def initialize(url)
11
+ @url = url
12
+ @headers = {}
13
+ init_sender
14
+ end
15
+
16
+ def post(data, get_body_only = true)
17
+ dohlog.debug("posting to url #@url")
18
+ response = if data.is_a?(Hash)
19
+ post_hash(data)
20
+ else
21
+ post_string(data)
22
+ end
23
+ check_for_errors(response)
24
+ return response.body.to_s if get_body_only
25
+ response
26
+ end
27
+
28
+ def get(get_body_only = true, allow_redirect = false, num_redirects = 0)
29
+ getstr = @parsed_url.path
30
+ getstr += '?' + @parsed_url.query unless @parsed_url.query.to_s.empty?
31
+ request = Net::HTTP::Get.new(getstr)
32
+ request.initialize_http_header(@headers)
33
+ response = @sender.start { |http| http.request(request) }
34
+ if response.is_a?(Net::HTTPRedirection) && allow_redirect
35
+ raise "too many redirects" if num_redirects > 20
36
+ @url = response['location']
37
+ init_sender
38
+ return get(get_body_only, true, num_redirects + 1)
39
+ end
40
+ return response.body.to_s if get_body_only
41
+ response
42
+ end
43
+
44
+ def xml
45
+ @headers['Content-Type'] = 'text/xml'
46
+ self
47
+ end
48
+
49
+ def soap_action(action)
50
+ @headers['SOAPAction'] = action
51
+ self
52
+ end
53
+
54
+ def nossl
55
+ @sender.use_ssl = false
56
+ @nossl = true
57
+ self
58
+ end
59
+
60
+ def timeout(seconds)
61
+ @sender.read_timeout = seconds
62
+ self
63
+ end
64
+
65
+ def hdr(name, value)
66
+ @headers[name] = value
67
+ self
68
+ end
69
+
70
+ #shortcut method
71
+ def self.load(url, use_ssl = true)
72
+ helper = HttpHelper.new(url)
73
+ helper.nossl if !use_ssl
74
+ helper.get
75
+ end
76
+ private
77
+ def init_sender
78
+ @parsed_url = URI.parse(@url)
79
+ @sender = Net::HTTP.new(@parsed_url.host, @parsed_url.port)
80
+ @sender.use_ssl = true unless @nossl || (['127.0.0.1', 'localhost'].include?(@parsed_url.host) && @parsed_url.port != 443)
81
+ @sender.verify_mode = OpenSSL::SSL::VERIFY_NONE
82
+ end
83
+
84
+ def post_hash(data)
85
+ request = Net::HTTP::Post.new(@parsed_url.path)
86
+ request.set_form_data(data)
87
+ request.initialize_http_header(@headers)
88
+ @sender.start { |http| http.request(request) }
89
+ end
90
+
91
+ def post_string(data)
92
+ @sender.post(@parsed_url.path, data, @headers)
93
+ end
94
+
95
+ def check_for_errors(response)
96
+ # TODO: do something useful here
97
+ # case response
98
+ # when Net::HTTPSuccess
99
+ # puts "success"
100
+ # puts response.body.to_s
101
+ # else
102
+ # puts response.error!
103
+ # end
104
+ end
105
+ end
106
+
107
+ end
@@ -3,7 +3,7 @@ require 'socket'
3
3
  module Doh
4
4
 
5
5
  def self.internal_ip
6
- Socket.getaddrinfo(Socket.gethostname, nil, Socket::AF_INET, Socket::SOCK_STREAM)[0][3]
6
+ @@internal_ip ||= Socket.getaddrinfo(Socket.gethostname, nil, Socket::AF_INET, Socket::SOCK_STREAM)[0][3]
7
7
  end
8
8
 
9
9
  end
@@ -0,0 +1,13 @@
1
+ require 'date'
2
+
3
+ module Doh
4
+
5
+ def self.jsval(value)
6
+ if value.is_a?(Date)
7
+ "new Date(#{value.year},#{value.month-1},#{value.mday})"
8
+ else
9
+ value
10
+ end
11
+ end
12
+
13
+ end
@@ -0,0 +1,14 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+ require 'uri'
4
+ require 'doh/util/xml_util'
5
+ require 'doh/util/http_helper'
6
+
7
+ module Doh
8
+
9
+ def self.post_hash_as_xml(hash, base_node = nil, url = 'http://localhost:4000/')
10
+ helper = HttpHelper.new(url).xml
11
+ helper.post("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>#{hash_to_xml(hash, base_node)}")
12
+ end
13
+
14
+ end
@@ -0,0 +1,48 @@
1
+ require 'rexml/document'
2
+
3
+ module Doh
4
+
5
+ def self.hash_to_xml(hash, root_node_name = nil)
6
+ doc = REXML::Document.new
7
+ doc << REXML::XMLDecl.new
8
+ if root_node_name
9
+ doc = doc.add_element(root_node_name)
10
+ end
11
+ elem_to_xml(hash, doc)
12
+ doc.to_s
13
+ end
14
+
15
+ def self.elem_to_xml(elem, node)
16
+ elem.each_pair do |field, value|
17
+ if value.class == Hash
18
+ elem_to_xml(value, node.add_element(field))
19
+ else
20
+ node.add_element(field).add_text(value.to_s)
21
+ end
22
+ end
23
+ end
24
+
25
+ def self.xml_to_hash(xml)
26
+ doc = REXML::Document.new(xml)
27
+ doc.children.each do |child|
28
+ if child.respond_to?('name')
29
+ return elem_to_hash(child)
30
+ end
31
+ end
32
+ raise "unable to find root node in xml: #{xml.inspect}"
33
+ end
34
+
35
+ def self.elem_to_hash(elem)
36
+ return {} if !elem.is_a?(REXML::Element)
37
+ if elem.has_elements?
38
+ children_hash = {}
39
+ elem.children.each do |child|
40
+ children_hash.merge!(elem_to_hash(child))
41
+ end
42
+ {elem.name => children_hash}
43
+ else
44
+ {elem.name => elem.text}
45
+ end
46
+ end
47
+
48
+ end
@@ -0,0 +1,12 @@
1
+ require 'test/unit'
2
+ require 'doh/core/array'
3
+
4
+ module Doh
5
+
6
+ class TC_core_array < Test::Unit::TestCase
7
+ def test_build_hash
8
+ assert_equal({'a' => 1, 'b' => 2}, [['a', 1], ['b', 2]].build_hash { |elem| elem})
9
+ end
10
+ end
11
+
12
+ end