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,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