raw 0.49.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 (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,16 @@
1
+ module Raw
2
+
3
+ # Compress HTML markup.
4
+
5
+ class SqueezeFilter
6
+
7
+ # Remove new lines. Typically used in live mode before the
8
+ # TemplateFilter.
9
+
10
+ def apply(source)
11
+ source.gsub(/^(\s*)/m, "").gsub(/\n/, "").gsub(/\t/, " ").squeeze(" ")
12
+ end
13
+
14
+ end
15
+
16
+ end
@@ -0,0 +1,74 @@
1
+ module Raw
2
+
3
+ # Performs static includes. Typically you should include this
4
+ # compiler as the first stage of the compile pipeline.
5
+ #
6
+ # This compiler is extremely helpful, typically you would want
7
+ # to use static includes in many many cases.
8
+
9
+ class StaticIncludeFilter
10
+
11
+ # Statically include sub-template files.
12
+ # The target file is included at compile time.
13
+ # If the given path is relative, the template_root stack of
14
+ # the controller is traversed. If an absolute path is provided,
15
+ # templates are searched only in Template.root
16
+ #
17
+ # gmosx: must be xformed before the <?r pi.
18
+ #
19
+ # === Example
20
+ # <?include href="root/myfile.sx" ?>
21
+
22
+ def apply(text)
23
+ resolve_include(text)
24
+ end
25
+
26
+ def resolve_include_filename(href)
27
+ found = false
28
+
29
+ if href[0] == ?/
30
+ # Absolute path, search only in the application template
31
+ # root.
32
+
33
+ href = href[1, 999999] # hack!!
34
+ template_dir_stack = [ Template.root_dir ]
35
+ else
36
+ template_dir_stack = Controller.current.ann(:self, :template_dir_stack)
37
+ end
38
+
39
+ for dir in template_dir_stack
40
+ if File.exist?(filename = "#{dir}/#{href}")
41
+ found = true
42
+ break
43
+ end
44
+
45
+ if File.exist?(filename = "#{dir}/#{href}.inc")
46
+ found = true
47
+ break
48
+ end
49
+ end
50
+
51
+ raise "Cannot statically include '#{href}'" unless found
52
+
53
+ return filename
54
+ end
55
+
56
+ def resolve_include(text)
57
+ return text.gsub(/<\?include href=["|'](.*?)["|'](.*)\?>/) do |match|
58
+ filename = resolve_include_filename($1)
59
+
60
+ c = Context.current.application.compiler
61
+ c.templates = c.templates.push(filename).uniq
62
+ itext = File.read(filename)
63
+
64
+ itext.gsub!(/<\?xml.*\?>/, '')
65
+
66
+ # Recursively resolve to handle sub-includes.
67
+
68
+ resolve_include(itext)
69
+ end
70
+ end
71
+
72
+ end
73
+
74
+ end
@@ -0,0 +1,121 @@
1
+ module Raw
2
+
3
+ # Nitro Template.
4
+
5
+ class Template
6
+
7
+ # The default template dir.
8
+
9
+ setting :root_dir, :default => File.expand_path("template"), :doc => "The default template dir"
10
+
11
+ # Strip xml comments from templates?
12
+
13
+ setting :strip_xml_comments, :default => false, :doc => "Strip xml comments from templates?"
14
+
15
+ end
16
+
17
+ # The basic Nitro Template filter.
18
+
19
+ class TemplateFilter
20
+
21
+ # Set some pretty safe delimiters for templates.
22
+
23
+ START_DELIM = "%{"
24
+ END_DELIM = "}\n"
25
+
26
+ # Convert a template to actual Ruby code, ready to be
27
+ # evaluated.
28
+ #
29
+ # [+source+]
30
+ # The template source as a String.
31
+ #
32
+ # [+buffer+]
33
+ # The variable to act as a buffer where the ruby code
34
+ # for this template will be generated. Passed as a
35
+ # String.
36
+
37
+ def apply(source, buffer = "@out")
38
+ source = source.dup
39
+
40
+ # Strip the xml header! (interracts with the following gsub!)
41
+
42
+ source.gsub!(/<\?xml.*\?>/, "")
43
+
44
+ # Transform include instructions <include href="xxx" />
45
+ # must be transformed before the processing instructions.
46
+ # Useful to include fragments cached on disk
47
+ #--
48
+ # gmosx, FIXME: NOT TESTED! test and add caching.
49
+ # add load_statically_included fixes.
50
+ #++
51
+
52
+ source.gsub!(/<include\s+href=["'](.*?)["']\s+\/>/, %[<?r File.read("\#{@dispatcher.root}/\\1") ?>])
53
+
54
+ # xform render/inject instructions <render href="xxx" />
55
+ # must be transformed before the processinc instructions.
56
+
57
+ source.gsub!(/<(?:render|inject)\s+href=["'](.*?)["']\s+\/>/, %[<?r render "\\1" ?>])
58
+
59
+ # Transform the processing instructions, use <?r as a marker.
60
+
61
+ source.gsub!(/<\?r\s+(.*?)\s+\?>/m) do |code|
62
+ "#{END_DELIM}#{$1.squeeze(' ').chomp}\n#{buffer} << #{START_DELIM}"
63
+ end
64
+
65
+ # Transform alternative code tags (very useful in xsl
66
+ # stylesheets).
67
+
68
+ source.gsub!(/<ruby>(.*?)<\/ruby>/m) do |code|
69
+ "#{END_DELIM}#{$1.squeeze(' ').chomp}\n#{buffer} << #{START_DELIM}"
70
+ end
71
+
72
+ # Also handle erb/asp/jsp style tags. Those tags *cannot*
73
+ # be used with an xslt stylesheet.
74
+ #
75
+ # Example:
76
+ #
77
+ # <% 10.times do %>
78
+ # Hello<br />
79
+ # <% end %>
80
+
81
+ source.gsub!(/<%(.*?)%>/m) do |code|
82
+ "#{END_DELIM}#{$1.squeeze(' ').chomp}\n#{buffer} << #{START_DELIM}"
83
+ end
84
+
85
+ # Alterative versions of interpolation (very useful in xsl
86
+ # stylesheets).
87
+ #
88
+ # Example:
89
+ #
90
+ # Here is #\my_val\
91
+
92
+ source.gsub!(/\#\\(.*?)\\/, '#{\1}')
93
+
94
+ # Alternative for entities (useful in xsl stylesheets).
95
+ #
96
+ # Examples:
97
+ #
98
+ # %nbsp;, %rquo;
99
+
100
+ source.gsub!(/%(#\d+|\w+);/, '&\1;')
101
+
102
+ # Compile time ruby code. This code is evaluated when
103
+ # compiling the template and the result injected directly
104
+ # into the result. Usefull for example to prevaluate
105
+ # localization. Just use the #[] marker instead of #{}.
106
+ #
107
+ # Example:
108
+ #
109
+ # This script was compiled at #[Time.now]
110
+
111
+ source.gsub!(/\#\[(.*?)\]/) do |match|
112
+ eval($1)
113
+ end
114
+
115
+ return "#{buffer} << #{START_DELIM}#{source}#{END_DELIM}"
116
+ end
117
+
118
+
119
+ end
120
+
121
+ end
@@ -0,0 +1,96 @@
1
+ module Raw
2
+
3
+ # Autoreload classes and templates. Mainly useful while
4
+ # debugging. Should be turned off in production servers to
5
+ # avoid the severe performance penalty.
6
+
7
+ class Reloader
8
+
9
+ def initialize(application)
10
+ @application = application
11
+ @mtimes = Hash.new(Time.now)
12
+ end
13
+
14
+ # Start the monitor thread. This thread monitors code and
15
+ # template files.
16
+ #--
17
+ # gmosx: the thread accesses the reloader variables through the
18
+ # closure.
19
+ #++
20
+
21
+ def start(interval)
22
+ @interval = interval
23
+ @thread = Thread.new do
24
+ begin
25
+ loop do
26
+ sleep(@interval)
27
+
28
+ dirty = false
29
+
30
+ # Check code files.
31
+
32
+ for feature in $LOADED_FEATURES
33
+ for path in $LOAD_PATH
34
+ file = File.join(path, feature)
35
+ if File.exist?(file) and is_dirty?(file)
36
+ begin
37
+ dirty = true
38
+ load(feature)
39
+ rescue Exception => ex
40
+ Logger.info ex.inspect
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ # Check template files.
47
+
48
+ for template in @application.compiler.templates
49
+ if is_dirty? template
50
+ dirty = true
51
+ break
52
+ end
53
+ end
54
+
55
+ reload_controllers() if dirty
56
+ end # loop
57
+ rescue => ex
58
+ Logger.info ex
59
+ end
60
+ end
61
+ end
62
+
63
+ # Stop the monitor thread.
64
+
65
+ def stop
66
+ @thread.exit
67
+ end
68
+
69
+ # Is a file modified on disk?
70
+
71
+ def is_dirty?(file)
72
+ if (mtime = File.stat(file).mtime) > @mtimes[file]
73
+ Logger.debug "File '#{file}' is modified" if $DBG
74
+ @mtimes[file] = mtime
75
+ return true
76
+ else
77
+ return false
78
+ end
79
+ end
80
+
81
+ # When a template is modified, remove all generated methods
82
+ # from the controllers.
83
+
84
+ def reload_controllers
85
+ controllers = @application.dispatcher.controllers.values
86
+
87
+ for c in controllers
88
+ for m in c.instance_methods.grep(/(___control$)|(___view$)/)
89
+ c.send(:remove_method, m) rescue nil
90
+ end
91
+ end
92
+ end
93
+
94
+ end
95
+
96
+ end
@@ -0,0 +1,154 @@
1
+ require "facets/core/kernel/assign_with"
2
+
3
+ require "raw/cgi"
4
+ require "raw/context/request"
5
+ require "raw/context/response"
6
+ require "raw/context/global"
7
+ require "raw/context/session"
8
+
9
+ require "raw/util/attr"
10
+
11
+ module Raw
12
+
13
+ # Encapsulates an HTTP processing cycle context. Integrates the
14
+ # HTTP Request and the HTTP Response with Session, Global and
15
+ # Local variable stores.
16
+ #
17
+ # The Context object can be accessed by the context, request or
18
+ # response aliases. You can use the alias that makes sense
19
+ # every time. This means inside an action request, response and
20
+ # context all point to the same object.
21
+
22
+ class Context
23
+ include Request
24
+ include Response
25
+
26
+ # The application of this context. Contains configuration
27
+ # parameters.
28
+
29
+ attr_accessor :application
30
+
31
+ # The session contains variables that stay alive
32
+ # for the full user session. Session variables
33
+ # should be generally avoided. This variable
34
+ # becomes populated ONLY if needed.
35
+
36
+ attr_reader :session
37
+
38
+ # The rendering level. An action may include sub-actions,
39
+ # each time the action is called, the level is increased,
40
+ # when the action returns the level decreases. The first
41
+ # action, called top level action has a level of 1.
42
+
43
+ attr_accessor :level
44
+
45
+ # The resource representation format for this request.
46
+
47
+ attr_accessor :format
48
+
49
+ # The output buffer accumulates the generated output.
50
+
51
+ attr_accessor :output_buffer
52
+
53
+ def initialize(application)
54
+ @level = 0
55
+ @application = application
56
+ @post_params = {}
57
+ @get_params = {}
58
+ @response_headers = {}
59
+ @output_buffer = ""
60
+ @status = Http::STATUS_OK
61
+
62
+ # Store this instance in a thread local variable for easy
63
+ # access.
64
+
65
+ Thread.current[:CURRENT_CONTEXT] = self
66
+ end
67
+
68
+ # Don't sync session. This method may be needed in low level
69
+ # hacks with the session code. For example if you updade an
70
+ # entity (managed) object that is cached in the session, you
71
+ # may dissable the syncing to avoid resetting the old value
72
+ # after the sync.
73
+
74
+ def no_sync!
75
+ @no_sync = true
76
+ end
77
+
78
+ # Close the context, should be called at the end of the HTTP
79
+ # request handling code.
80
+
81
+ def close
82
+ if @session
83
+ # Ugly hack: need to use AOP instead
84
+ if @session.has_key?(:FLASH)
85
+ @session[:FLASH].clean
86
+ end
87
+
88
+ # INVESTIGATE: is this needed?
89
+ @session.sync unless @no_sync
90
+ end
91
+ end
92
+ alias_method :finish, :close
93
+
94
+ # Access the dispactcher
95
+
96
+ def dispatcher
97
+ @application.dispatcher
98
+ end
99
+
100
+ # Lazy lookup of the session to avoid costly cookie
101
+ # lookup when not needed.
102
+
103
+ def session
104
+ @session || @session = Session.lookup(self)
105
+ end
106
+
107
+ # Access global variables. In a distributed server scenario,
108
+ # these variables can reside outside of the process.
109
+
110
+ def global
111
+ return Global
112
+ end
113
+
114
+ # Automagically populate an object from request parameters.
115
+ # This is a truly dangerous method.
116
+ #
117
+ # === Options
118
+ #
119
+ # * name
120
+ # * force_boolean
121
+ #
122
+ # === Example
123
+ #
124
+ # request.fill(User.new)
125
+ #
126
+ # This method is deprecated, Prefer to use the following form:
127
+ #
128
+ # User.new.assign_with(request)
129
+
130
+ def fill(obj, options = {})
131
+ AttributeUtils.populate_object(obj, params, options)
132
+ end
133
+ alias_method :populate, :fill
134
+ alias_method :assign, :fill
135
+
136
+ # Is the current action the top level action? The level
137
+ # of the top action is 1.
138
+
139
+ def is_top_level?
140
+ @level == 1
141
+ end
142
+ alias_method :top?, :is_top_level?
143
+ alias_method :is_top?, :is_top_level?
144
+ alias_method :top_level?, :is_top_level?
145
+
146
+ # Returns the context for the current thread.
147
+
148
+ def self.current
149
+ Thread.current[:CURRENT_CONTEXT]
150
+ end
151
+
152
+ end
153
+
154
+ end