doodle 0.0.10 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/CREDITS +22 -0
  2. data/{ChangeLog → History.txt} +22 -3
  3. data/License.txt +20 -0
  4. data/Manifest.txt +61 -0
  5. data/README.txt +166 -0
  6. data/Rakefile +4 -0
  7. data/config/hoe.rb +77 -0
  8. data/config/requirements.rb +15 -0
  9. data/examples/doodle-errors.rb +25 -0
  10. data/examples/event-location.rb +3 -7
  11. data/examples/example-01.rb +1 -1
  12. data/examples/example-01.rdoc +3 -3
  13. data/examples/example-02.rb +15 -4
  14. data/examples/example-02.rdoc +17 -5
  15. data/examples/mail-datatypes.rb +104 -0
  16. data/examples/mail.rb +85 -0
  17. data/examples/parent.rb +40 -0
  18. data/examples/profile-options.rb +67 -0
  19. data/examples/smtp_tls.rb +65 -0
  20. data/examples/test-datatypes.rb +55 -0
  21. data/examples/yaml-example.rb +40 -0
  22. data/examples/yaml-example2.rb +42 -0
  23. data/lib/doodle.rb +364 -301
  24. data/lib/doodle/datatypes.rb +148 -0
  25. data/lib/doodle/rfc822.rb +31 -0
  26. data/lib/doodle/utils.rb +13 -0
  27. data/lib/doodle/version.rb +9 -0
  28. data/log/debug.log +0 -0
  29. data/script/console +10 -0
  30. data/script/destroy +14 -0
  31. data/script/generate +14 -0
  32. data/script/txt2html +82 -0
  33. data/setup.rb +1585 -0
  34. data/spec/arg_order_spec.rb +5 -5
  35. data/spec/attributes_spec.rb +66 -24
  36. data/spec/bugs_spec.rb +109 -6
  37. data/spec/class_spec.rb +7 -4
  38. data/spec/class_validation_spec.rb +46 -0
  39. data/spec/class_var_spec.rb +76 -0
  40. data/spec/collector_spec.rb +16 -30
  41. data/spec/conversion_spec.rb +8 -3
  42. data/spec/defaults_spec.rb +4 -4
  43. data/spec/doodle_context_spec.rb +3 -4
  44. data/spec/doodle_spec.rb +25 -15
  45. data/spec/extra_args_spec.rb +1 -1
  46. data/spec/factory_spec.rb +3 -3
  47. data/spec/init_spec.rb +11 -11
  48. data/spec/new_doodle_spec.rb +19 -0
  49. data/spec/required_spec.rb +1 -1
  50. data/spec/serialization_spec.rb +3 -6
  51. data/spec/singleton_spec.rb +5 -5
  52. data/spec/spec.opts +1 -0
  53. data/spec/spec_helper.rb +44 -0
  54. data/spec/superclass_spec.rb +6 -5
  55. data/spec/validation2_spec.rb +248 -0
  56. data/spec/validation_spec.rb +26 -37
  57. data/tasks/deployment.rake +34 -0
  58. data/tasks/environment.rake +7 -0
  59. data/tasks/rspec.rake +21 -0
  60. data/tasks/website.rake +17 -0
  61. metadata +76 -20
  62. data/COPYING +0 -18
  63. data/README +0 -57
  64. data/examples/event.rb +0 -39
  65. data/examples/example-03.rb +0 -45
  66. data/examples/example-03.rdoc +0 -55
  67. data/lib/semantic.cache +0 -8
@@ -2,7 +2,7 @@ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
2
  require 'date'
3
3
  require 'doodle'
4
4
 
5
- class DateRange < Doodle::Base
5
+ class DateRange < Doodle
6
6
  has :start_date do
7
7
  default { Date.today }
8
8
  end
@@ -2,7 +2,7 @@ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
2
  require 'date'
3
3
  require 'doodle'
4
4
 
5
- class DateRange < Doodle::Base
5
+ class DateRange < Doodle
6
6
  has :start_date do
7
7
  default { Date.today }
8
8
  end
@@ -12,6 +12,6 @@ class DateRange < Doodle::Base
12
12
  end
13
13
 
14
14
  dr = DateRange.new
15
- dr.start_date # => #<Date: 4909137/2,0,2299161>
16
- dr.end_date # => #<Date: 4909137/2,0,2299161>
15
+ dr.start_date # => #<Date: 4909159/2,0,2299161>
16
+ dr.end_date # => #<Date: 4909159/2,0,2299161>
17
17
 
@@ -1,8 +1,9 @@
1
1
  $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
2
  require 'date'
3
3
  require 'doodle'
4
+ require 'doodle/utils' # for try
4
5
 
5
- class DateRange < Doodle::Base
6
+ class DateRange < Doodle
6
7
  has :start_date, :kind => Date do
7
8
  default { Date.today }
8
9
  from String do |s|
@@ -25,6 +26,8 @@ class DateRange < Doodle::Base
25
26
  m = /(\d{4}-\d{2}-\d{2})\s*(?:to|-|\s)\s*(\d{4}-\d{2}-\d{2})/.match(s)
26
27
  if m
27
28
  self.new(*m.captures)
29
+ else
30
+ raise Exception, "Cannot parse date: '#{s}'"
28
31
  end
29
32
  end
30
33
  end
@@ -57,6 +60,14 @@ dr = DateRange.from '2007-01-01 2007-12-31'
57
60
  dr.start_date # =>
58
61
  dr.end_date # =>
59
62
 
60
- dr = DateRange '2008-01-01', '2007-12-31'
61
- dr.start_date # =>
62
- dr.end_date # =>
63
+ p try {
64
+ dr = DateRange.from 'Hello World'
65
+ dr.start_date # =>
66
+ dr.end_date # =>
67
+ }
68
+
69
+ p try {
70
+ dr = DateRange '2008-01-01', '2007-12-31'
71
+ dr.start_date # =>
72
+ dr.end_date # =>
73
+ }
@@ -1,8 +1,9 @@
1
1
  $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
2
  require 'date'
3
3
  require 'doodle'
4
+ require 'doodle/utils' # for try
4
5
 
5
- class DateRange < Doodle::Base
6
+ class DateRange < Doodle
6
7
  has :start_date, :kind => Date do
7
8
  default { Date.today }
8
9
  from String do |s|
@@ -25,6 +26,8 @@ class DateRange < Doodle::Base
25
26
  m = /(\d{4}-\d{2}-\d{2})\s*(?:to|-|\s)\s*(\d{4}-\d{2}-\d{2})/.match(s)
26
27
  if m
27
28
  self.new(*m.captures)
29
+ else
30
+ raise Exception, "Cannot parse date: '#{s}'"
28
31
  end
29
32
  end
30
33
  end
@@ -57,7 +60,16 @@ dr = DateRange.from '2007-01-01 2007-12-31'
57
60
  dr.start_date # => #<Date: 4908203/2,0,2299161>
58
61
  dr.end_date # => #<Date: 4908931/2,0,2299161>
59
62
 
60
- dr = DateRange '2008-01-01', '2007-12-31'
61
- dr.start_date # =>
62
- dr.end_date # =>
63
- # ~> -:60: #<DateRange:0xb7a52640 @end_date=#<Date: 4908931/2,0,2299161>, @start_date=#<Date: 4908933/2,0,2299161>> must have end_date >= start_date (Doodle::ValidationError)
63
+ p try {
64
+ dr = DateRange.from 'Hello World'
65
+ dr.start_date # =>
66
+ dr.end_date # =>
67
+ }
68
+
69
+ p try {
70
+ dr = DateRange '2008-01-01', '2007-12-31'
71
+ dr.start_date # =>
72
+ dr.end_date # =>
73
+ }
74
+ # >> #<Doodle::ConversionError: Cannot parse date: 'Hello World'>
75
+ # >> #<Doodle::ValidationError: DateRange must have end_date >= start_date>
@@ -0,0 +1,104 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $:.unshift(File.join(File.dirname(__FILE__), '.'))
3
+
4
+ require 'doodle'
5
+ require 'doodle/datatypes'
6
+ require 'net/smtp'
7
+ require 'time'
8
+ require 'datatypes'
9
+ require 'smtp_tls'
10
+
11
+ # note: translated from Florian Frank's example in dslkit [http://dslkit.rubyforge.org/]
12
+
13
+ class Mail < Doodle
14
+ doodle do
15
+ string :mail_server, :default => ENV['MAILSERVER'] || 'mail'
16
+ string :body
17
+ email :from do
18
+ default do
19
+ if ENV['USER']
20
+ ENV['USER'] + '@' + mail_server
21
+ else
22
+ 'from@example.com'
23
+ end
24
+ end
25
+ end
26
+ email :to
27
+ string :subject, :default => 'Test Email'
28
+ date :date do
29
+ default { Time.now.rfc2822 }
30
+ end
31
+ string :message_id do
32
+ default do
33
+ key = [ ENV['HOSTNAME'] || 'localhost', $$ , Time.now ].join
34
+ (::Digest::MD5.new << key).to_s
35
+ end
36
+ end
37
+ string :msg do
38
+ default do
39
+ [
40
+ "From: #{from}",
41
+ "To: #{to}",
42
+ "Subject: #{subject}",
43
+ "Date: #{date}",
44
+ "Message-Id: <#{message_id}@#{mail_server}>",
45
+ '',
46
+ body
47
+ ] * "\n"
48
+ end
49
+ end
50
+ end
51
+
52
+ def send_message
53
+ if true
54
+ puts msg
55
+ else
56
+ ::Net::SMTP.start(mail_server, 25) do |smtp|
57
+ smtp.send_message msg, from, to
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ require 'highline/import'
64
+ def prompt_for_password
65
+ ask("Enter your password: ") { |q| q.echo = '*' }
66
+ end
67
+
68
+ class GMail < Mail
69
+ has :mail_server, :default => 'smtp.gmail.com'
70
+ has :port, :default => 587
71
+ has :username, :default => 'sean.ohalpin@gmail.com'
72
+ has :password, :default => 'sesame'
73
+ # has :password do
74
+ # init do
75
+ # prompt_for_password
76
+ # end
77
+ # end
78
+ has :host, :default => 'localhost.localdomain'
79
+ has :message_format, :default => 'plain'
80
+
81
+ def send_message
82
+ puts msg
83
+ return
84
+ ::Net::SMTP.start(mail_server,
85
+ port,
86
+ host,
87
+ username,
88
+ password,
89
+ message_format) do |smtp|
90
+ smtp.send_message(msg, from, to)
91
+ end
92
+ end
93
+ end
94
+
95
+ GMail do
96
+ subject subject + ': Hi!'
97
+ to 'sean.ohalpin@gmail.com'
98
+ body <<BODY
99
+ Hi,
100
+
101
+ this is a test email from Ruby.
102
+
103
+ BODY
104
+ end.send_message
@@ -0,0 +1,85 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $:.unshift(File.join(File.dirname(__FILE__), '.'))
3
+ require 'doodle'
4
+ require 'doodle/rfc822'
5
+ require 'net/smtp'
6
+ require 'time'
7
+
8
+ # note: translated from Florian Frank's example in dslkit [http://dslkit.rubyforge.org/]
9
+
10
+ class Mail < Doodle
11
+ has :mail_server, :default => ENV['MAILSERVER'] || 'mail'
12
+ has :body, :kind => String
13
+
14
+ has :from, :kind => String do
15
+ default do
16
+ if ENV['USER']
17
+ ENV['USER'] + '@' + mail_server
18
+ else
19
+ 'from@example.com'
20
+ end
21
+ end
22
+ must 'be valid email address' do |s|
23
+ s =~ RFC822::EmailAddress
24
+ end
25
+ end
26
+
27
+ has :to, :kind => String do
28
+ must 'be valid email address' do |s|
29
+ s =~ RFC822::EmailAddress
30
+ end
31
+ end
32
+ has :subject, :default => 'Test Email'
33
+ has :date do
34
+ default { Time.now.rfc2822 }
35
+ end
36
+ has :message_id do
37
+ default do
38
+ key = [ ENV['HOSTNAME'] || 'localhost', $$ , Time.now ].join
39
+ (::Digest::MD5.new << key).to_s
40
+ end
41
+ end
42
+ has :msg, :kind => String do
43
+ default do
44
+ [
45
+ "From: #{from}",
46
+ "To: #{to}",
47
+ "Subject: #{subject}",
48
+ "Date: #{date}",
49
+ "Message-Id: <#{message_id}@#{mail_server}>",
50
+ '',
51
+ body
52
+ ] * "\n"
53
+ end
54
+ end
55
+
56
+ def send
57
+ if true
58
+ puts msg
59
+ else
60
+ ::Net::SMTP.start(mail_server, 25) do |smtp|
61
+ smtp.send_message msg, from, to
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ def mail(&block)
68
+ Mail.new(&block)
69
+ end
70
+
71
+ def prompt
72
+ return 'someone@example.com'
73
+ STDOUT.print "Send to? "
74
+ STDOUT.flush
75
+ STDIN.gets.strip
76
+ end
77
+
78
+ m = Mail do
79
+ subject subject + ': Hi!'
80
+ if rcpt = prompt
81
+ to rcpt
82
+ end
83
+ body "Hello, world!\n"
84
+ end
85
+ m.send
@@ -0,0 +1,40 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require 'doodle'
3
+ require 'yaml'
4
+
5
+ class Child < Doodle
6
+ has :name
7
+ has :dad do
8
+ # I'm treating block arguments and Proc object (proc/lambda) arguments
9
+ # to :init differently:
10
+ # - a proc/lamba is treated as a literal argument, i.e. the
11
+ # - value is set to a Proc
12
+ # - a block argument, on the other hand, is instance
13
+ # - evaluated during initialization
14
+ # - consequences
15
+ # - can only be done in init block
16
+ # - somewhat subtle difference (from programmer's point of
17
+ # - view) between a proc and a block
18
+
19
+ # Also note re: Doodle.parent - its value is only valid
20
+ # during initialization - this is a way to capture that
21
+ # value for ues later
22
+
23
+ init do
24
+ parent
25
+ end
26
+ end
27
+ end
28
+
29
+ class Parent < Child
30
+ has :children, :collect => Child
31
+ end
32
+
33
+ parent = Parent 'Conn' do
34
+ child 'Sean'
35
+ end
36
+
37
+ puts parent.to_yaml
38
+
39
+
40
+
@@ -0,0 +1,67 @@
1
+ require 'lib/doodle'
2
+
3
+ module CommandLine
4
+ class Base < Doodle::Base
5
+ has :name
6
+ singleton_class do
7
+ has :doc
8
+ end
9
+ def to_s
10
+ name
11
+ end
12
+ end
13
+ class Command < Base
14
+ end
15
+ class KeyValue < Base
16
+ # specify order (should I need to do this?)
17
+ has :name
18
+ has :value
19
+ def to_s
20
+ %[--#{name}="#{value}"]
21
+ end
22
+ end
23
+ class Flag < Base
24
+ def to_s
25
+ %[--#{name}]
26
+ end
27
+ end
28
+ end
29
+
30
+ module Zenity
31
+ include CommandLine
32
+ class Entry < Flag
33
+ # specifying name here has effect of re-ordering positional args
34
+ doc "Display text entry dialogue"
35
+ has :name, :default => :entry
36
+ end
37
+ class Text < KeyValue
38
+ doc "Set the dialogue text"
39
+ has :name, :default => :text
40
+ end
41
+ class EntryText < KeyValue
42
+ doc "Set the entry text"
43
+ has :name, :default => 'entry-text'
44
+ end
45
+ class HideText < KeyValue
46
+ doc "Hide the entry text"
47
+ has :name, :default => 'hide-text'
48
+ end
49
+ end
50
+
51
+ include Zenity
52
+
53
+ 1.upto(100) do
54
+ cmd = [
55
+ Command.new("zenity"),
56
+ Entry.new(),
57
+ # KeyValue.new("text", "Enter name:"),
58
+ # KeyValue.new(:name => "text", :value => "Enter name:"),
59
+ # Text.new(:value => "Enter name:"),
60
+ Text.new(:value => "Enter name:"),
61
+ EntryText.new(:value => "Enter text"),
62
+ ].join(' ')
63
+ #puts cmd
64
+ end
65
+ #result = `#{cmd}`
66
+ #puts "result=#{result}"
67
+
@@ -0,0 +1,65 @@
1
+ require "openssl"
2
+ require "net/smtp"
3
+
4
+ Net::SMTP.class_eval do
5
+ private
6
+ def do_start(helodomain, user, secret, authtype)
7
+ raise IOError, 'SMTP session already started' if @started
8
+ check_auth_args user, secret, authtype if user or secret
9
+
10
+ sock = timeout(@open_timeout) { TCPSocket.open(@address, @port) }
11
+ @socket = Net::InternetMessageIO.new(sock)
12
+ @socket.read_timeout = 60 #@read_timeout
13
+
14
+ check_response(critical { recv_response() })
15
+ do_helo(helodomain)
16
+
17
+ if starttls
18
+ raise 'openssl library not installed' unless defined?(OpenSSL)
19
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
20
+ ssl.sync_close = true
21
+ ssl.connect
22
+ @socket = Net::InternetMessageIO.new(ssl)
23
+ @socket.read_timeout = 60 #@read_timeout
24
+ do_helo(helodomain)
25
+ end
26
+
27
+ authenticate user, secret, authtype if user
28
+ @started = true
29
+ ensure
30
+ unless @started
31
+ # authentication failed, cancel connection.
32
+ @socket.close if not @started and @socket and not @socket.closed?
33
+ @socket = nil
34
+ end
35
+ end
36
+
37
+ def do_helo(helodomain)
38
+ begin
39
+ if @esmtp
40
+ ehlo helodomain
41
+ else
42
+ helo helodomain
43
+ end
44
+ rescue Net::ProtocolError
45
+ if @esmtp
46
+ @esmtp = false
47
+ @error_occured = false
48
+ retry
49
+ end
50
+ raise
51
+ end
52
+ end
53
+
54
+ def starttls
55
+ getok('STARTTLS') rescue return false
56
+ return true
57
+ end
58
+
59
+ def quit
60
+ begin
61
+ getok('QUIT')
62
+ rescue EOFError
63
+ end
64
+ end
65
+ end