raw 0.49.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (148) hide show
  1. data/doc/CONTRIBUTORS +106 -0
  2. data/doc/LICENSE +32 -0
  3. data/doc/coding_conventions.txt +11 -0
  4. data/lib/raw.rb +42 -0
  5. data/lib/raw/adapter.rb +113 -0
  6. data/lib/raw/adapter/cgi.rb +41 -0
  7. data/lib/raw/adapter/fastcgi.rb +48 -0
  8. data/lib/raw/adapter/mongrel.rb +146 -0
  9. data/lib/raw/adapter/script.rb +94 -0
  10. data/lib/raw/adapter/webrick.rb +144 -0
  11. data/lib/raw/adapter/webrick/vcr.rb +91 -0
  12. data/lib/raw/cgi.rb +323 -0
  13. data/lib/raw/cgi/cookie.rb +47 -0
  14. data/lib/raw/cgi/http.rb +62 -0
  15. data/lib/raw/compiler.rb +138 -0
  16. data/lib/raw/compiler/filter/cleanup.rb +21 -0
  17. data/lib/raw/compiler/filter/elements.rb +166 -0
  18. data/lib/raw/compiler/filter/elements/element.rb +210 -0
  19. data/lib/raw/compiler/filter/localization.rb +23 -0
  20. data/lib/raw/compiler/filter/markup.rb +32 -0
  21. data/lib/raw/compiler/filter/morph.rb +123 -0
  22. data/lib/raw/compiler/filter/morph/each.rb +34 -0
  23. data/lib/raw/compiler/filter/morph/for.rb +11 -0
  24. data/lib/raw/compiler/filter/morph/if.rb +26 -0
  25. data/lib/raw/compiler/filter/morph/selected_if.rb +43 -0
  26. data/lib/raw/compiler/filter/morph/standard.rb +55 -0
  27. data/lib/raw/compiler/filter/morph/times.rb +27 -0
  28. data/lib/raw/compiler/filter/script.rb +116 -0
  29. data/lib/raw/compiler/filter/squeeze.rb +16 -0
  30. data/lib/raw/compiler/filter/static_include.rb +74 -0
  31. data/lib/raw/compiler/filter/template.rb +121 -0
  32. data/lib/raw/compiler/reloader.rb +96 -0
  33. data/lib/raw/context.rb +154 -0
  34. data/lib/raw/context/flash.rb +157 -0
  35. data/lib/raw/context/global.rb +88 -0
  36. data/lib/raw/context/request.rb +338 -0
  37. data/lib/raw/context/response.rb +57 -0
  38. data/lib/raw/context/session.rb +198 -0
  39. data/lib/raw/context/session/drb.rb +11 -0
  40. data/lib/raw/context/session/file.rb +15 -0
  41. data/lib/raw/context/session/memcached.rb +13 -0
  42. data/lib/raw/context/session/memory.rb +12 -0
  43. data/lib/raw/context/session/og.rb +15 -0
  44. data/lib/raw/context/session/pstore.rb +13 -0
  45. data/lib/raw/control.rb +18 -0
  46. data/lib/raw/control/attribute.rb +91 -0
  47. data/lib/raw/control/attribute/checkbox.rb +25 -0
  48. data/lib/raw/control/attribute/datetime.rb +21 -0
  49. data/lib/raw/control/attribute/file.rb +20 -0
  50. data/lib/raw/control/attribute/fixnum.rb +26 -0
  51. data/lib/raw/control/attribute/float.rb +26 -0
  52. data/lib/raw/control/attribute/options.rb +38 -0
  53. data/lib/raw/control/attribute/password.rb +16 -0
  54. data/lib/raw/control/attribute/text.rb +16 -0
  55. data/lib/raw/control/attribute/textarea.rb +16 -0
  56. data/lib/raw/control/none.rb +16 -0
  57. data/lib/raw/control/relation.rb +59 -0
  58. data/lib/raw/control/relation/belongs_to.rb +0 -0
  59. data/lib/raw/control/relation/has_many.rb +97 -0
  60. data/lib/raw/control/relation/joins_many.rb +0 -0
  61. data/lib/raw/control/relation/many_to_many.rb +0 -0
  62. data/lib/raw/control/relation/refers_to.rb +29 -0
  63. data/lib/raw/controller.rb +37 -0
  64. data/lib/raw/controller/publishable.rb +160 -0
  65. data/lib/raw/dispatcher.rb +209 -0
  66. data/lib/raw/dispatcher/format.rb +108 -0
  67. data/lib/raw/dispatcher/format/atom.rb +31 -0
  68. data/lib/raw/dispatcher/format/css.rb +0 -0
  69. data/lib/raw/dispatcher/format/html.rb +42 -0
  70. data/lib/raw/dispatcher/format/json.rb +31 -0
  71. data/lib/raw/dispatcher/format/rss.rb +33 -0
  72. data/lib/raw/dispatcher/format/xoxo.rb +31 -0
  73. data/lib/raw/dispatcher/mounter.rb +60 -0
  74. data/lib/raw/dispatcher/router.rb +111 -0
  75. data/lib/raw/errors.rb +19 -0
  76. data/lib/raw/helper.rb +86 -0
  77. data/lib/raw/helper/benchmark.rb +23 -0
  78. data/lib/raw/helper/buffer.rb +60 -0
  79. data/lib/raw/helper/cookie.rb +32 -0
  80. data/lib/raw/helper/debug.rb +28 -0
  81. data/lib/raw/helper/default.rb +16 -0
  82. data/lib/raw/helper/feed.rb +451 -0
  83. data/lib/raw/helper/form.rb +284 -0
  84. data/lib/raw/helper/javascript.rb +59 -0
  85. data/lib/raw/helper/layout.rb +40 -0
  86. data/lib/raw/helper/navigation.rb +87 -0
  87. data/lib/raw/helper/pager.rb +305 -0
  88. data/lib/raw/helper/table.rb +247 -0
  89. data/lib/raw/helper/xhtml.rb +218 -0
  90. data/lib/raw/helper/xml.rb +125 -0
  91. data/lib/raw/mixin/magick.rb +35 -0
  92. data/lib/raw/mixin/sweeper.rb +71 -0
  93. data/lib/raw/mixin/thumbnails.rb +1 -0
  94. data/lib/raw/mixin/webfile.rb +165 -0
  95. data/lib/raw/render.rb +271 -0
  96. data/lib/raw/render/builder.rb +26 -0
  97. data/lib/raw/render/caching.rb +81 -0
  98. data/lib/raw/render/call.rb +43 -0
  99. data/lib/raw/render/send_file.rb +46 -0
  100. data/lib/raw/render/stream.rb +39 -0
  101. data/lib/raw/scaffold.rb +13 -0
  102. data/lib/raw/scaffold/controller.rb +25 -0
  103. data/lib/raw/scaffold/model.rb +157 -0
  104. data/lib/raw/test.rb +5 -0
  105. data/lib/raw/test/assertions.rb +169 -0
  106. data/lib/raw/test/context.rb +55 -0
  107. data/lib/raw/test/testcase.rb +79 -0
  108. data/lib/raw/util/attr.rb +128 -0
  109. data/lib/raw/util/encode_uri.rb +149 -0
  110. data/lib/raw/util/html_filter.rb +538 -0
  111. data/lib/raw/util/markup.rb +130 -0
  112. data/test/glue/tc_webfile.rb +1 -0
  113. data/test/nitro/CONFIG.rb +3 -0
  114. data/test/nitro/adapter/raw_post1.bin +9 -0
  115. data/test/nitro/adapter/tc_webrick.rb +16 -0
  116. data/test/nitro/cgi/tc_cookie.rb +14 -0
  117. data/test/nitro/cgi/tc_request.rb +61 -0
  118. data/test/nitro/compiler/tc_client_morpher.rb +47 -0
  119. data/test/nitro/compiler/tc_compiler.rb +25 -0
  120. data/test/nitro/dispatcher/tc_mounter.rb +47 -0
  121. data/test/nitro/helper/tc_feed.rb +135 -0
  122. data/test/nitro/helper/tc_navbar.rb +74 -0
  123. data/test/nitro/helper/tc_pager.rb +35 -0
  124. data/test/nitro/helper/tc_table.rb +68 -0
  125. data/test/nitro/helper/tc_xhtml.rb +19 -0
  126. data/test/nitro/tc_caching.rb +19 -0
  127. data/test/nitro/tc_cgi.rb +222 -0
  128. data/test/nitro/tc_context.rb +17 -0
  129. data/test/nitro/tc_controller.rb +103 -0
  130. data/test/nitro/tc_controller_aspect.rb +32 -0
  131. data/test/nitro/tc_controller_params.rb +885 -0
  132. data/test/nitro/tc_dispatcher.rb +109 -0
  133. data/test/nitro/tc_element.rb +85 -0
  134. data/test/nitro/tc_flash.rb +59 -0
  135. data/test/nitro/tc_helper.rb +47 -0
  136. data/test/nitro/tc_render.rb +119 -0
  137. data/test/nitro/tc_router.rb +61 -0
  138. data/test/nitro/tc_server.rb +35 -0
  139. data/test/nitro/tc_session.rb +66 -0
  140. data/test/nitro/tc_template.rb +71 -0
  141. data/test/nitro/util/tc_encode_url.rb +87 -0
  142. data/test/nitro/util/tc_markup.rb +31 -0
  143. data/test/public/blog/another/very_litle/index.xhtml +1 -0
  144. data/test/public/blog/inc1.xhtml +2 -0
  145. data/test/public/blog/inc2.xhtml +1 -0
  146. data/test/public/blog/list.xhtml +9 -0
  147. data/test/public/dummy_mailer/registration.xhtml +5 -0
  148. metadata +244 -0
@@ -0,0 +1,57 @@
1
+ module Raw
2
+
3
+ # HTTP Response. This module is included in Context.
4
+
5
+ module Response
6
+
7
+ # The Response status.
8
+
9
+ attr_accessor :status
10
+
11
+ # The Response headers.
12
+
13
+ attr_accessor :response_headers
14
+
15
+ # The Response cookies.
16
+
17
+ attr_accessor :response_cookies
18
+
19
+ # Return the content type for this response.
20
+
21
+ def content_type
22
+ @response_headers["Content-Type"]
23
+ end
24
+
25
+ # Set the content type for this response.
26
+
27
+ def content_type=(ctype)
28
+ @response_headers["Content-Type"] = ctype
29
+ end
30
+
31
+ # Add a cookie to the response. Better use this
32
+ # method to avoid precreating the cookies array
33
+ # for every request.
34
+ #
35
+ # === Examples
36
+ #
37
+ # add_cookie('nsid', 'gmosx')
38
+ # add_cookie(Cookie.new('nsid', 'gmosx')
39
+
40
+ def add_cookie(cookie, value = nil)
41
+ if value
42
+ (@response_cookies ||= []) << Cookie.new(cookie, value)
43
+ else
44
+ (@response_cookies ||= []) << cookie
45
+ end
46
+ end
47
+ alias_method :send_cookie, :add_cookie
48
+
49
+ # Return the output buffer.
50
+
51
+ def body
52
+ @output_buffer
53
+ end
54
+
55
+ end
56
+
57
+ end
@@ -0,0 +1,198 @@
1
+ require "md5"
2
+
3
+ require "facets/core/class/cattr"
4
+ require "facets/more/synchash"
5
+ require "facets/more/times"
6
+ require "facets/more/expirable"
7
+ require "facets/more/settings"
8
+
9
+ require "raw/cgi/cookie"
10
+
11
+ module Raw
12
+
13
+ # A web application session.
14
+ #
15
+ # State is a neccessary evil but session variables
16
+ # should be avoided as much as possible. Session state
17
+ # is typically distributed to many servers so avoid
18
+ # storing complete objects in session variables, only
19
+ # store oids and small integer/strings.
20
+ #
21
+ # The session should be persistable to survive server
22
+ # shutdowns.
23
+ #
24
+ # The session can be considered as a Hash where key-value
25
+ # pairs are stored. Typically symbols are used as keys. By
26
+ # convention uppercase symbols are used for internal Nitro
27
+ # session variables (ie :FLASH, :USER, etc). User applications
28
+ # typically use lowercase symbols (ie :cart, :history, etc).
29
+ #
30
+ #--
31
+ # TODO: rehash of the session cookie
32
+ # TODO: store -> cache, reimplement helpers.
33
+ #++
34
+
35
+ class Session < Hash
36
+ include Expirable
37
+
38
+ # Session id salt.
39
+
40
+ setting :session_id_salt, :default => 'SALT', :doc => 'Session id salt'
41
+
42
+ # The name of the cookie that stores the session id.
43
+
44
+ setting :cookie_name, :default => 'nsid', :doc => 'The name of the cookie that stores the session id'
45
+
46
+ # useful with persistents sessions stores
47
+
48
+ setting :cookie_expires, :default => false, :doc => 'Set expires parameter of session cookie equal to the keepalive setting?'
49
+
50
+ # The session keepalive time. The session is eligable for
51
+ # garbage collection after this time passes.
52
+
53
+ setting :keepalive, :default => 30.minutes, :doc => 'The session keepalive time'
54
+
55
+ # The type of the session cache. The generalized caching
56
+ # system in Glue is used. The following options are available:
57
+ #
58
+ # * :memory [default]
59
+ # * :drb
60
+ # * :og
61
+ # * :file
62
+ # * :memcached
63
+
64
+ setting :cache_type, :default => :memory, :doc => 'The type of session cache'
65
+
66
+ # The address of the cache store.
67
+
68
+ setting :cache_address, :default => '127.0.0.1', :doc => 'The address of the cache store'
69
+
70
+ # The port of the cache store.
71
+
72
+ setting :cache_port, :default => 9069, :doc => 'The port of the cache store'
73
+
74
+ class << self
75
+
76
+ # The sessions cache (store).
77
+
78
+ attr_accessor :cache
79
+ alias_method :store, :cache
80
+
81
+ # Load the correct Session specialization according to the
82
+ # cache type.
83
+
84
+ def setup(type = Session.cache_type)
85
+ # gmosx: RDoc friendly.
86
+ require "raw/context/session/" + type.to_s
87
+ end
88
+
89
+ # Lookup the session in the cache by using the session
90
+ # cookie value as a key. If the session does not exist
91
+ # creates a new session, inserts it in the cache and
92
+ # appends a new session cookie in the response.
93
+
94
+ def lookup(context)
95
+ if session_id = context.cookies[Session.cookie_name]
96
+ session = Session.cache[session_id]
97
+ end
98
+
99
+ unless session
100
+ # Create new session.
101
+ session = Session.new(context)
102
+ cookie = Cookie.new(Session.cookie_name, session.session_id)
103
+ if Session.cookie_expires
104
+ cookie.expires = Time.now + Session.keepalive
105
+ end
106
+ context.add_cookie(cookie)
107
+ Session.cache[session.session_id] = session
108
+ else
109
+ # Access ('touch') the existing session.
110
+ session.touch!
111
+ end
112
+
113
+ return session
114
+ end
115
+
116
+ # The number of active (online) sessions.
117
+ # DON'T use yet!
118
+
119
+ def count
120
+ Session.cache.size
121
+ end
122
+
123
+ # Perform Session garbage collection. You may call this
124
+ # method from a cron job.
125
+
126
+ def garbage_collect
127
+ expired = []
128
+ for s in Session.cache.all
129
+ expired << s.session_id if s.expired?
130
+ end
131
+ for sid in expired
132
+ Session.cache.delete(sid)
133
+ end
134
+ end
135
+ alias_method :gc!, :garbage_collect
136
+
137
+ # Returns the current session from the context thread local
138
+ # variable.
139
+
140
+ def current
141
+ Context.current.session
142
+ end
143
+
144
+ end
145
+
146
+ # The unique id of this session.
147
+
148
+ attr_reader :session_id
149
+
150
+ # Create the session for the given context.
151
+ # If the hook method 'created' is defined it is called
152
+ # at the end. Typically used to initialize the session
153
+ # hash.
154
+
155
+ def initialize(context = nil)
156
+ @session_id = create_id
157
+ expires_after(Session.keepalive)
158
+ created if respond_to?(:created)
159
+ end
160
+
161
+ # Synchronize the session store, by
162
+ # restoring this session. Especially useful
163
+ # in distributed and/or multiprocess setups.
164
+
165
+ def sync
166
+ Session.cache[@session_id] = self
167
+ end
168
+ alias_method :restore, :sync
169
+
170
+ def touch!
171
+ expires_after(Session.keepalive)
172
+ end
173
+
174
+ protected
175
+
176
+ # Calculates a unique id.
177
+ #
178
+ # The session id must be unique, a monotonically
179
+ # increasing function like time is appropriate.
180
+ # Random may produce equal ids? add a prefix
181
+ # (SALT) to stop hackers from creating session_ids.
182
+ #--
183
+ # THINK: Is MD5 slow??? Allow for pluggable hashes.
184
+ #++
185
+
186
+ def create_id
187
+ now = Time.now
188
+ md5 = Digest::MD5.new
189
+ md5.update(now.to_s)
190
+ md5.update(now.usec.to_s)
191
+ md5.update(rand(0).to_s)
192
+ md5.update(Session.session_id_salt)
193
+ md5.hexdigest
194
+ end
195
+
196
+ end
197
+
198
+ end
@@ -0,0 +1,11 @@
1
+ require "glue/cache/drb"
2
+
3
+ require "raw/context/session"
4
+
5
+ module Raw
6
+
7
+ Logger.info "Using DRb sessions at #{Session.cache_address}:#{Session.cache_port}." if defined?(Logger) && $DBG
8
+
9
+ Session.cache = Glue::DrbCache.new(Session.cache_address, Session.cache_port)
10
+
11
+ end
@@ -0,0 +1,15 @@
1
+ require "glue/cache/file"
2
+
3
+ require "raw/context/session"
4
+
5
+ module Raw
6
+
7
+ # A Session manager that persists sessions on disk.
8
+
9
+ Logger.info "Using File sessions." if defined?(Logger) && $DBG
10
+
11
+ Session.cache = Glue::FileCache.new("session_#{Session.cookie_name}", Session.keepalive)
12
+
13
+ end
14
+
15
+ # * Guillaume Pierronnet <guillaume.pierronnet@gmail.com>
@@ -0,0 +1,13 @@
1
+ require "glue/cache/memcached"
2
+
3
+ require "raw/context/session"
4
+
5
+ module Raw
6
+
7
+ # A Session manager that persists sessions on disk.
8
+
9
+ Logger.debug "Using MemCached sessions." if defined?(Logger) && $DBG
10
+
11
+ Session.cache = Glue::MemCached.new("session_#{Session.cookie_name}", Session.keepalive)
12
+
13
+ end
@@ -0,0 +1,12 @@
1
+ require "glue/cache/memory"
2
+ require "glue/logger"
3
+
4
+ require "raw/context/session"
5
+
6
+ module Raw
7
+
8
+ Logger.info "Using Memory sessions." if defined?(Logger) && $DBG
9
+
10
+ Session.cache = Glue::MemoryCache.new
11
+
12
+ end
@@ -0,0 +1,15 @@
1
+ require "glue/cache/og"
2
+
3
+ require "raw/context/session"
4
+
5
+ module Raw
6
+
7
+ # A Session manager that persists sessions on an Og store.
8
+
9
+ Logger.debug "Using Og sessions." if defined?(Logger) && $DBG
10
+
11
+ Session.cache = OgCache.new("session_#{Session.cookie_name}", Session.keepalive)
12
+
13
+ end
14
+
15
+ # * Guillaume Pierronnet <guillaume.pierronnet@gmail.com>
@@ -0,0 +1,13 @@
1
+ require "glue/cache/pstore"
2
+
3
+ require "raw/context/session"
4
+
5
+ module Raw
6
+
7
+ # A Session manager that is using PStore to store state
8
+
9
+ Logger.info "Using PStore sessions." if defined?(Logger) && $DBG
10
+
11
+ Session.cache = Glue::PStoreCache.new(Session.keepalive)
12
+
13
+ end
@@ -0,0 +1,18 @@
1
+ require "raw/compiler/filter/elements/element"
2
+ require "raw/helper/xhtml"
3
+
4
+ module Raw
5
+
6
+ # A specialized kind of element used for implementing UI
7
+ # controls.
8
+ #--
9
+ # TODO: add support for the singleton pattern to avoid excessive
10
+ # memory usage.
11
+ #++
12
+
13
+ class Control < Element
14
+ # THINK: maybe include this in element too?
15
+ include XhtmlHelper
16
+ end
17
+
18
+ end
@@ -0,0 +1,91 @@
1
+ require "raw/control"
2
+
3
+ module Raw
4
+
5
+ # The base class for controls used to inspect object
6
+ # attributes.
7
+ #--
8
+ # TODO: find a better name.
9
+ #++
10
+
11
+ class AttributeControl < Control
12
+
13
+ # The attribute that this control renders.
14
+
15
+ attr_accessor :attribute
16
+
17
+ # The annotations used for rendering
18
+
19
+ attr_accessor :anno
20
+
21
+ # The value
22
+
23
+ attr_accessor :value
24
+ alias_method :values, :value
25
+
26
+ # === Input
27
+ #
28
+ # * object = the object to inspect
29
+ # * a = the attribute to inspect
30
+ # * options = additional options
31
+
32
+ def initialize(object, a, options)
33
+ @object = object
34
+ @attribute = a
35
+ @anno = @object.class.ann(@attribute)
36
+ @value = @object.send(@attribute)
37
+ @options = options
38
+ end
39
+
40
+ private
41
+
42
+ # Used as id attribute in HTML markup.
43
+ def control_id
44
+ "#{@attribute}_ctl"
45
+ end
46
+
47
+ # Emit the label for this control.
48
+ # The label is skipped if the control is created with the
49
+ # option :no_label set to true.
50
+
51
+ def emit_label
52
+ return "" if @options[:no_label]
53
+ title = @anno[:title] || @options[:label] || @attribute.to_s.humanize
54
+ %{<label for="#{control_id}">#{title}</label>}
55
+ end
56
+
57
+ # Emit the css style for this control.
58
+ # This mehtod takes into account the passed options (first)
59
+ # and then the attribute annotations.
60
+
61
+ def emit_style
62
+ unless style = (@options[:style] || @anno[:control_style])
63
+ if self.class.respond_to? :style
64
+ style = self.class.style
65
+ else
66
+ style = nil
67
+ end
68
+ end
69
+ style ? %{ style="#{style}"} : ''
70
+ end
71
+
72
+ # Add support to your controls for being disabled
73
+ # by including an emit_disabled on form items
74
+ # or testing for is_disabled? on more complex controls.
75
+
76
+ def emit_disabled
77
+ is_disabled? ? %{ disabled="disabled"} : ''
78
+ end
79
+
80
+ #--
81
+ # FIXME
82
+ #++
83
+
84
+ def is_disabled?
85
+ return false if @options[:all]
86
+ @options[:disable_controls] || @anno[:disable_control]
87
+ end
88
+
89
+ end
90
+
91
+ end