arrow 1.0.7

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 (198) hide show
  1. data/ChangeLog +1590 -0
  2. data/LICENSE +28 -0
  3. data/README +75 -0
  4. data/Rakefile +366 -0
  5. data/Rakefile.local +63 -0
  6. data/data/arrow/applets/TEMPLATE.rb.tpl +53 -0
  7. data/data/arrow/applets/args.rb +50 -0
  8. data/data/arrow/applets/config.rb +55 -0
  9. data/data/arrow/applets/error.rb +63 -0
  10. data/data/arrow/applets/files.rb +46 -0
  11. data/data/arrow/applets/inspect.rb +46 -0
  12. data/data/arrow/applets/nosuchapplet.rb +31 -0
  13. data/data/arrow/applets/status.rb +92 -0
  14. data/data/arrow/applets/test.rb +133 -0
  15. data/data/arrow/applets/tutorial/counter.rb +96 -0
  16. data/data/arrow/applets/tutorial/dingus.rb +67 -0
  17. data/data/arrow/applets/tutorial/hello.rb +34 -0
  18. data/data/arrow/applets/tutorial/hello2.rb +73 -0
  19. data/data/arrow/applets/tutorial/imgtext.rb +90 -0
  20. data/data/arrow/applets/tutorial/imgtext2.rb +286 -0
  21. data/data/arrow/applets/tutorial/index.rb +36 -0
  22. data/data/arrow/applets/tutorial/logo.rb +98 -0
  23. data/data/arrow/applets/tutorial/memcache.rb +61 -0
  24. data/data/arrow/applets/tutorial/missing.rb +37 -0
  25. data/data/arrow/applets/tutorial/protected.rb +100 -0
  26. data/data/arrow/applets/tutorial/redirector.rb +52 -0
  27. data/data/arrow/applets/tutorial/rndimages.rb +159 -0
  28. data/data/arrow/applets/tutorial/sharenotes.rb +83 -0
  29. data/data/arrow/applets/tutorial/subclassed-hello.rb +32 -0
  30. data/data/arrow/applets/tutorial/superhello.rb +72 -0
  31. data/data/arrow/applets/tutorial/timeclock.rb +78 -0
  32. data/data/arrow/applets/view-applet.rb +123 -0
  33. data/data/arrow/applets/view-template.rb +85 -0
  34. data/data/arrow/applets/wiki.rb +274 -0
  35. data/data/arrow/templates/TEMPLATE.tmpl.tpl +36 -0
  36. data/data/arrow/templates/applet-status.tmpl +153 -0
  37. data/data/arrow/templates/args-display.tmpl +120 -0
  38. data/data/arrow/templates/config/display-table.tmpl +36 -0
  39. data/data/arrow/templates/config/display.tmpl +36 -0
  40. data/data/arrow/templates/counter-deleted.tmpl +33 -0
  41. data/data/arrow/templates/counter.tmpl +59 -0
  42. data/data/arrow/templates/dingus.tmpl +55 -0
  43. data/data/arrow/templates/enumtable.tmpl +8 -0
  44. data/data/arrow/templates/error-display.tmpl +92 -0
  45. data/data/arrow/templates/filemap.tmpl +89 -0
  46. data/data/arrow/templates/hello-world-src.tmpl +34 -0
  47. data/data/arrow/templates/hello-world.tmpl +60 -0
  48. data/data/arrow/templates/imgtext/fontlist.tmpl +46 -0
  49. data/data/arrow/templates/imgtext/form.tmpl +70 -0
  50. data/data/arrow/templates/imgtext/reload-error.tmpl +40 -0
  51. data/data/arrow/templates/imgtext/reload.tmpl +55 -0
  52. data/data/arrow/templates/inspect/display.tmpl +80 -0
  53. data/data/arrow/templates/loginform.tmpl +64 -0
  54. data/data/arrow/templates/logout.tmpl +32 -0
  55. data/data/arrow/templates/memcache/display.tmpl +41 -0
  56. data/data/arrow/templates/navbar.incl +27 -0
  57. data/data/arrow/templates/nosuchapplet.tmpl +32 -0
  58. data/data/arrow/templates/printsource.tmpl +35 -0
  59. data/data/arrow/templates/protected.tmpl +36 -0
  60. data/data/arrow/templates/rndimages.tmpl +38 -0
  61. data/data/arrow/templates/service-response.tmpl +13 -0
  62. data/data/arrow/templates/sharenotes/display.tmpl +38 -0
  63. data/data/arrow/templates/status.tmpl +120 -0
  64. data/data/arrow/templates/templateviewer.tmpl +43 -0
  65. data/data/arrow/templates/test/harness.tmpl +57 -0
  66. data/data/arrow/templates/test/list.tmpl +48 -0
  67. data/data/arrow/templates/test/problem.tmpl +42 -0
  68. data/data/arrow/templates/tutorial/index.tmpl +37 -0
  69. data/data/arrow/templates/tutorial/missingapplet.tmpl +29 -0
  70. data/data/arrow/templates/view-applet-nosuch.tmpl +32 -0
  71. data/data/arrow/templates/view-applet.tmpl +40 -0
  72. data/data/arrow/templates/view-template.tmpl +83 -0
  73. data/data/arrow/templates/wiki/formerror.tmpl +47 -0
  74. data/data/arrow/templates/wiki/markup_help.incl +6 -0
  75. data/data/arrow/templates/wiki/new.tmpl +56 -0
  76. data/data/arrow/templates/wiki/new_system.tmpl +122 -0
  77. data/data/arrow/templates/wiki/sectionlist.tmpl +43 -0
  78. data/data/arrow/templates/wiki/show.tmpl +34 -0
  79. data/docs/manual/layouts/default.page +43 -0
  80. data/docs/manual/lib/api-filter.rb +81 -0
  81. data/docs/manual/lib/editorial-filter.rb +64 -0
  82. data/docs/manual/lib/examples-filter.rb +244 -0
  83. data/docs/manual/lib/links-filter.rb +117 -0
  84. data/lib/apache/fakerequest.rb +448 -0
  85. data/lib/apache/logger.rb +33 -0
  86. data/lib/arrow.rb +51 -0
  87. data/lib/arrow/acceptparam.rb +207 -0
  88. data/lib/arrow/applet.rb +725 -0
  89. data/lib/arrow/appletmixins.rb +218 -0
  90. data/lib/arrow/appletregistry.rb +590 -0
  91. data/lib/arrow/applettestcase.rb +503 -0
  92. data/lib/arrow/broker.rb +255 -0
  93. data/lib/arrow/cache.rb +176 -0
  94. data/lib/arrow/config-loaders/yaml.rb +75 -0
  95. data/lib/arrow/config.rb +615 -0
  96. data/lib/arrow/constants.rb +24 -0
  97. data/lib/arrow/cookie.rb +359 -0
  98. data/lib/arrow/cookieset.rb +108 -0
  99. data/lib/arrow/dispatcher.rb +368 -0
  100. data/lib/arrow/dispatcherloader.rb +50 -0
  101. data/lib/arrow/exceptions.rb +61 -0
  102. data/lib/arrow/fallbackhandler.rb +48 -0
  103. data/lib/arrow/formvalidator.rb +631 -0
  104. data/lib/arrow/htmltokenizer.rb +343 -0
  105. data/lib/arrow/logger.rb +488 -0
  106. data/lib/arrow/logger/apacheoutputter.rb +69 -0
  107. data/lib/arrow/logger/arrayoutputter.rb +63 -0
  108. data/lib/arrow/logger/coloroutputter.rb +111 -0
  109. data/lib/arrow/logger/fileoutputter.rb +96 -0
  110. data/lib/arrow/logger/htmloutputter.rb +54 -0
  111. data/lib/arrow/logger/outputter.rb +123 -0
  112. data/lib/arrow/mixins.rb +425 -0
  113. data/lib/arrow/monkeypatches.rb +94 -0
  114. data/lib/arrow/object.rb +117 -0
  115. data/lib/arrow/path.rb +196 -0
  116. data/lib/arrow/service.rb +447 -0
  117. data/lib/arrow/session.rb +289 -0
  118. data/lib/arrow/session/dbstore.rb +100 -0
  119. data/lib/arrow/session/filelock.rb +160 -0
  120. data/lib/arrow/session/filestore.rb +132 -0
  121. data/lib/arrow/session/id.rb +98 -0
  122. data/lib/arrow/session/lock.rb +253 -0
  123. data/lib/arrow/session/md5id.rb +42 -0
  124. data/lib/arrow/session/nulllock.rb +42 -0
  125. data/lib/arrow/session/posixlock.rb +166 -0
  126. data/lib/arrow/session/sha1id.rb +54 -0
  127. data/lib/arrow/session/store.rb +366 -0
  128. data/lib/arrow/session/usertrackid.rb +52 -0
  129. data/lib/arrow/spechelpers.rb +73 -0
  130. data/lib/arrow/template.rb +713 -0
  131. data/lib/arrow/template/attr.rb +31 -0
  132. data/lib/arrow/template/call.rb +31 -0
  133. data/lib/arrow/template/comment.rb +33 -0
  134. data/lib/arrow/template/container.rb +118 -0
  135. data/lib/arrow/template/else.rb +41 -0
  136. data/lib/arrow/template/elsif.rb +44 -0
  137. data/lib/arrow/template/escape.rb +53 -0
  138. data/lib/arrow/template/export.rb +87 -0
  139. data/lib/arrow/template/for.rb +145 -0
  140. data/lib/arrow/template/if.rb +78 -0
  141. data/lib/arrow/template/import.rb +119 -0
  142. data/lib/arrow/template/include.rb +206 -0
  143. data/lib/arrow/template/iterator.rb +208 -0
  144. data/lib/arrow/template/nodes.rb +734 -0
  145. data/lib/arrow/template/parser.rb +571 -0
  146. data/lib/arrow/template/prettyprint.rb +53 -0
  147. data/lib/arrow/template/render.rb +191 -0
  148. data/lib/arrow/template/selectlist.rb +94 -0
  149. data/lib/arrow/template/set.rb +87 -0
  150. data/lib/arrow/template/timedelta.rb +81 -0
  151. data/lib/arrow/template/unless.rb +78 -0
  152. data/lib/arrow/template/urlencode.rb +51 -0
  153. data/lib/arrow/template/yield.rb +139 -0
  154. data/lib/arrow/templatefactory.rb +125 -0
  155. data/lib/arrow/testcase.rb +567 -0
  156. data/lib/arrow/transaction.rb +608 -0
  157. data/rake/191_compat.rb +26 -0
  158. data/rake/dependencies.rb +76 -0
  159. data/rake/documentation.rb +114 -0
  160. data/rake/helpers.rb +502 -0
  161. data/rake/hg.rb +282 -0
  162. data/rake/manual.rb +787 -0
  163. data/rake/packaging.rb +129 -0
  164. data/rake/publishing.rb +278 -0
  165. data/rake/style.rb +62 -0
  166. data/rake/svn.rb +668 -0
  167. data/rake/testing.rb +187 -0
  168. data/rake/verifytask.rb +64 -0
  169. data/spec/arrow/acceptparam_spec.rb +157 -0
  170. data/spec/arrow/applet_spec.rb +575 -0
  171. data/spec/arrow/appletmixins_spec.rb +409 -0
  172. data/spec/arrow/appletregistry_spec.rb +294 -0
  173. data/spec/arrow/broker_spec.rb +153 -0
  174. data/spec/arrow/config_spec.rb +224 -0
  175. data/spec/arrow/cookieset_spec.rb +164 -0
  176. data/spec/arrow/dispatcher_spec.rb +137 -0
  177. data/spec/arrow/dispatcherloader_spec.rb +65 -0
  178. data/spec/arrow/formvalidator_spec.rb +781 -0
  179. data/spec/arrow/logger_spec.rb +346 -0
  180. data/spec/arrow/mixins_spec.rb +120 -0
  181. data/spec/arrow/service_spec.rb +645 -0
  182. data/spec/arrow/session_spec.rb +121 -0
  183. data/spec/arrow/template/iterator_spec.rb +222 -0
  184. data/spec/arrow/templatefactory_spec.rb +185 -0
  185. data/spec/arrow/transaction_spec.rb +319 -0
  186. data/spec/arrow_spec.rb +37 -0
  187. data/spec/lib/appletmatchers.rb +281 -0
  188. data/spec/lib/constants.rb +77 -0
  189. data/spec/lib/helpers.rb +41 -0
  190. data/spec/lib/matchers.rb +44 -0
  191. data/tests/cookie.tests.rb +310 -0
  192. data/tests/path.tests.rb +157 -0
  193. data/tests/session.tests.rb +111 -0
  194. data/tests/session_id.tests.rb +82 -0
  195. data/tests/session_lock.tests.rb +191 -0
  196. data/tests/session_store.tests.rb +53 -0
  197. data/tests/template.tests.rb +1360 -0
  198. metadata +339 -0
@@ -0,0 +1,286 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # The FancyImageText class, a derivative of Arrow::Applet. It
4
+ # is an applet which generates an image of a string of TrueType text.
5
+ #
6
+ # == VCS Id
7
+ #
8
+ # $Id$
9
+ #
10
+ # == Authors
11
+ #
12
+ # * Michael Granger <ged@FaerieMUD.org>
13
+ #
14
+ # Thanks to Mahlon Smith <mahlon@martini.nu> for ideas for refinement,
15
+ # suggestions.
16
+ #
17
+
18
+ require 'GD'
19
+ require 'ft2'
20
+ require 'arrow/applet'
21
+
22
+ ### It is an applet which generates an image from one or more characters of text.
23
+ class FancyImageText < Arrow::Applet
24
+
25
+ # Default settings
26
+ DefaultFont = 'TektonPro-Regular'
27
+ DefaultFont.untaint
28
+ DefaultFontDir = "/Library/WebServer/Fonts"
29
+ DefaultFontDir.untaint
30
+
31
+ DefaultFontSize = 36
32
+ DefaultText = 'TrueType Font Mangler'
33
+
34
+ # Colors
35
+ DefaultForegroundColor = "#000000"
36
+ DefaultBackgroundColor = "#ffffff"
37
+
38
+ # Safety constraints
39
+ MaxPointSize = 180
40
+ MinPointSize = 5
41
+ MaxTextLength = 1024
42
+
43
+ # URLs of the form: /ttf/<fontname>/<size>/<caption>.<fmt>
44
+ # Stolen shamelessly from Mahlon.
45
+ FileName = %r{(.*)\.(png|jpg)}i
46
+
47
+ # Applet signature
48
+ Signature = {
49
+ :name => "imagetext",
50
+ :description => "Generates an image from one or more characters of text.",
51
+ :maintainer => "ged@FaerieMUD.org",
52
+ :default_action => 'fontlist',
53
+ :templates => {
54
+ :form => 'imgtext/form.tmpl',
55
+ :fontlist => 'imgtext/fontlist.tmpl',
56
+ :reload => 'imgtext/reload.tmpl',
57
+ :reload_error => 'imgtext/reload-error.tmpl',
58
+ },
59
+ :vargs => {
60
+ :__default__ => {
61
+ :required => [],
62
+ :optional => [:imgtext, :fontsize, :fontface],
63
+ :constraints => {
64
+ :imgtext => /^[\x20-\x7e-]+$/,
65
+ :fontsize => /^\d+$/,
66
+ :fontface => /^\S+$/,
67
+ },
68
+ },
69
+ }
70
+ }
71
+
72
+
73
+ ### Load some stuff when the applet is created.
74
+ def initialize( *args ) # :nodoc:
75
+ super
76
+
77
+ if @config.respond_to?( :imgtext )
78
+ bkgnd = @config.imgtext.background
79
+ fgnd = @config.imgtext.foreground
80
+ @fontdir = @config.imgtext.fontdir
81
+ @defaultfont = @config.imgtext.defaultfont
82
+ end
83
+
84
+ bkgnd ||= DefaultBackgroundColor
85
+ fgnd ||= DefaultForegroundColor
86
+ @fontdir ||= DefaultFontDir
87
+ @defaultfont ||= DefaultFont
88
+
89
+ @background= GD::Image.trueColorAlpha( bkgnd, GD::AlphaTransparent )
90
+ @foreground = GD::Image.trueColorAlpha( fgnd, GD::AlphaOpaque )
91
+ @fonts = load_fonts( @fontdir )
92
+
93
+ self.log.debug "Loaded %d fonts" % @fonts.length
94
+ end
95
+
96
+
97
+ ######
98
+ public
99
+ ######
100
+
101
+ attr_reader :fontdir, :background, :foreground, :fonts
102
+
103
+ ### The action to run when the specified action method doesn't exist. This
104
+ ### is used to make the URL a bit shorter -- the action name becomes the
105
+ ### font name in effect.
106
+ def action_missing_action( txn, *args )
107
+
108
+ # Fetch the REST arguments and build the image for them
109
+ fontname, size, imgname = *args
110
+ caption, fmt = $1, $2 if FileName.match( imgname )
111
+ img = make_image( txn, fontname, size, caption ) or return false
112
+
113
+ self.log.debug "Made %s image with font: %s, size: %d, caption: %p" %
114
+ [ fmt, fontname, size, caption ]
115
+
116
+ # Render the image according to what extension the URI had
117
+ case fmt
118
+ when /png/
119
+ txn.content_type = 'image/png'
120
+ return img.pngStr
121
+
122
+ when /jpg/
123
+ txn.content_type = 'image/jpeg'
124
+ return img.jpegStr( -1 )
125
+
126
+ else
127
+ self.log.error "Unsupported image extension %p" % fmt
128
+ return false
129
+ end
130
+ end
131
+
132
+
133
+ ### Display a list of the available fonts.
134
+ def fontlist_action( txn, *rest )
135
+ templ = self.load_template( :fontlist )
136
+ templ.txn = txn
137
+ templ.app = self
138
+ templ.fonts = @fonts
139
+
140
+ return templ
141
+ end
142
+
143
+
144
+ ### Reload the fonts and display what changed.
145
+ def reload_action( txn, *args )
146
+ self.log.debug "Doing reload of fonts for child %d" % [ Process.pid ]
147
+
148
+ newfonts = tmpl = nil
149
+
150
+ # Try to reload the fonts, replacing the currently-loaded ones and
151
+ # showing the differences if it succeeds, and showing the error and
152
+ # keeping the old ones if it fails.
153
+ begin
154
+ newfonts = load_fonts( @fontdir )
155
+ rescue Exception => err
156
+ self.log.error "Caught exception while attempting to reload fonts: %s\n\t%s" %
157
+ [ err.message, err.backtrace.join("\n\t") ]
158
+ tmpl = self.load_template( :reload_error )
159
+ tmpl.exception = err
160
+ else
161
+ tmpl = self.load_template( :reload )
162
+ tmpl.newfonts = newfonts.reject {|name,font| @fonts.key?(name)}
163
+ tmpl.removedfonts = @fonts.reject {|name,font| newfonts.key?(name)}
164
+ @fonts = newfonts
165
+ end
166
+
167
+ tmpl.txn = txn
168
+ tmpl.applet = self
169
+
170
+ return tmpl
171
+ end
172
+
173
+
174
+ #########
175
+ protected
176
+ #########
177
+
178
+ ### Load Hashes full of font info for each of the readable fonts in the
179
+ ### given +dir+ and return them in a Hash keyed by the font name.
180
+ def load_fonts( dir )
181
+ count = 0
182
+ fonts = {}
183
+
184
+ Dir["#{dir}/*.{otf,ttf}"].each {|file|
185
+ file.untaint
186
+ next unless File.file?( file ) && File.readable?( file )
187
+ face = nil
188
+
189
+ count += 1
190
+ begin
191
+ face = FT2::Face.load( file ) or
192
+ raise ".load returned nil"
193
+ rescue Exception => err
194
+ self.log.debug "While loading #{file}: %s" % err.message
195
+ next
196
+ end
197
+
198
+ fonts[ face.name ] = {
199
+ :file => file,
200
+ :family => face.family,
201
+ :style => face.style,
202
+ :bold => face.bold?,
203
+ :italic => face.italic?,
204
+ }
205
+ }
206
+
207
+ self.log.debug "Mapped %d of %d font files" %
208
+ [ fonts.keys.nitems, count ]
209
+ return fonts
210
+ end
211
+
212
+
213
+ ### Create a GD::Image object from the given +txn+ and +rest+-style
214
+ ### arguments.
215
+ def make_image( txn, fontname, size, caption )
216
+
217
+ # Arguments are read from either the query args or the REST-style
218
+ # parameters, preferring the latter.
219
+
220
+ # Fetch the text and normalize it
221
+ text = $1 if /([\x20-\x7f]+)/.match( caption )
222
+ text ||= txn.vargs[:imgtext]
223
+ text ||= DefaultText
224
+ text = text[0, MaxTextLength] if text.length > MaxTextLength
225
+ self.log.debug "Set text to %p" % text
226
+
227
+ # Get the face name the same way
228
+ face = $1 if /(\S+)/.match( fontname )
229
+ face ||= txn.vargs[:fontface]
230
+ face ||= @defaultfont
231
+ self.log.debug "Set face to %p" % face
232
+
233
+ # Get the pointsize the same way
234
+ pointsize = Integer($1) if /(\d+)/.match( size )
235
+ pointsize ||= Integer( txn.vargs[:fontsize] ) rescue nil
236
+ pointsize = DefaultFontSize if pointsize.nil? || pointsize.zero?
237
+ pointsize = MaxPointSize if pointsize > MaxPointSize
238
+ pointsize = MinPointSize if pointsize < MinPointSize
239
+ self.log.debug "Set pointsize to %p" % pointsize
240
+
241
+ # Calculate the size of the image based on the size of the rendered text
242
+ raise "No such font '#{face}'" unless @fonts.key?( face )
243
+ font = @fonts[ face ][:file]
244
+ self.log.debug "Font file is %p" % font
245
+ err, brect = GD::Image.stringFT( @foreground, font, pointsize, 0, 0, 0, text )
246
+ raise "Failed to calculate bounding-box for #{font}: #{err}" if err
247
+ self.log.debug "Bounding rect: %p" % [ brect ]
248
+
249
+ # Calculate the image size from the bounding rectangle with a 5-pixel
250
+ # border.
251
+ width = brect[2] - brect[6] + 10
252
+ height = brect[3] - brect[7] + 10
253
+ self.log.debug "Width: %d, height: %d" % [ width, height ]
254
+
255
+ # Make the image and colors
256
+ img = GD::Image.newTrueColor( width, height )
257
+ self.log.debug "Created image object: %p" % [ img ]
258
+
259
+ # If the GD library has been patched to support alpha-channel PNGs, turn
260
+ # that on.
261
+ if img.respond_to? :saveAlpha
262
+ self.log.debug "Using saveAlpha"
263
+ img.saveAlpha = true
264
+ img.alphaBlending = false
265
+
266
+ # Otherwise just muddle through as best we can with immediate compositing
267
+ else
268
+ self.log.debug "Using alphaBlending"
269
+ img.alphaBlending = true
270
+ img.transparent( @background )
271
+ end
272
+
273
+ # Fill the image with the background and draw the text and a border with
274
+ # the foreground color.
275
+ self.log.debug "Filling background"
276
+ img.fill( 1, 1, @background )
277
+ self.log.debug "Drawing string"
278
+ img.stringFT( @foreground, font, pointsize, 0, 5 - brect[6], 5 - brect[7], text )
279
+ self.log.debug "Filled and set string."
280
+
281
+ return img
282
+ end
283
+
284
+ end # class FancyImageText
285
+
286
+
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # The ArrowTutorial class, a derivative of Arrow::Applet. It
4
+ # is the applet which loads and displays the tutorial (or will eventually).
5
+ #
6
+ # == VCS Id
7
+ #
8
+ # $Id$
9
+ #
10
+ # == Authors
11
+ #
12
+ # * Michael Granger <ged@FaerieMUD.org>
13
+ #
14
+
15
+ require 'arrow/applet'
16
+
17
+
18
+ ### Blah
19
+ class ArrowTutorial < Arrow::Applet
20
+
21
+
22
+ # Applet signature
23
+ Signature = {
24
+ :name => "Arrow Tutorial",
25
+ :description => "The tutorial applet.",
26
+ :maintainer => "ged@FaerieMUD.org",
27
+ :default_action => 'index',
28
+ :templates => {
29
+ :index => 'index.tmpl',
30
+ },
31
+ }
32
+
33
+
34
+ end # class ArrowTutorial
35
+
36
+
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # The LogoGenerator class, a derivative of Arrow::Applet. It
4
+ # generates a blank logo of a given size and format.
5
+ #
6
+ # == VCS Id
7
+ #
8
+ # $Id$
9
+ #
10
+ # == Authors
11
+ #
12
+ # * Michael Granger <ged@FaerieMUD.org>
13
+ #
14
+
15
+ require 'arrow/applet'
16
+ require 'GD'
17
+
18
+ ### It generates a blank logo of a given size and format.
19
+ class LogoGenerator < Arrow::Applet
20
+
21
+
22
+ # Applet signature
23
+ Signature = {
24
+ :name => "Logo Generator",
25
+ :description => "Generate a blank logo of a given size and format.",
26
+ :maintainer => "ged@FaerieMUD.org",
27
+ :default_action => 'display',
28
+ :vargs => {
29
+ :display => {
30
+ :optional => [:height, :width, :format],
31
+ :constraints => {
32
+ :height => /^\d+$/,
33
+ :width => /^\d+$/,
34
+ :format => /^(png|jpe?g|gif)$/,
35
+ },
36
+ },
37
+ }
38
+ }
39
+
40
+
41
+ def initialize( *args )
42
+ super
43
+
44
+ @defaultLogoWidth = 60
45
+ @defaultLogoHeight = 60
46
+ @defaultLogoImageFormat = :png
47
+
48
+ @background= GD::Image.trueColorAlpha( "#ffffff", GD::AlphaTransparent )
49
+ @foreground = GD::Image.trueColorAlpha( "#000000", GD::AlphaOpaque )
50
+ end
51
+
52
+
53
+ ######
54
+ public
55
+ ######
56
+
57
+ def display_action( txn, *args )
58
+ width = txn.vargs[ :width ] || @defaultLogoWidth
59
+ height = txn.vargs[ :height ] || @defaultLogoHeight
60
+ format = txn.vargs[ :format ] || @defaultLogoImageFormat
61
+ self.log.debug "height = %d, width = %d, format = %p" %
62
+ [ height, width, format ]
63
+
64
+ img = GD::Image.newTrueColor( width, height )
65
+ self.log.debug "Created image"
66
+
67
+ if img.respond_to? :saveAlpha
68
+ self.log.debug "Using saveAlpha"
69
+ img.saveAlpha = true
70
+ img.alphaBlending = false
71
+
72
+ # Otherwise just muddle through as best we can with immediate compositing
73
+ else
74
+ self.log.debug "Using alphaBlending"
75
+ img.alphaBlending = true
76
+ img.transparent( background )
77
+ end
78
+
79
+ img.fill( 1, 1, @background )
80
+ self.log.debug "Filled it with %p" % @background
81
+ img.rectangle( 0, 0, width - 1, height - 1, @foreground )
82
+ self.log.debug "Drew bounding rectangle"
83
+ img.line( 0, 0, width - 1, height - 1, @foreground )
84
+ self.log.debug "Draw first crosshatch"
85
+ img.line( 0, height - 1, width - 1, 0, @foreground )
86
+ self.log.debug "Draw second crosshatch"
87
+
88
+ imgdata = img.pngStr
89
+ self.log.debug "Extracted image data (%d bytes)" % imgdata.length
90
+ txn.request.content_type = "image/png"
91
+
92
+ return imgdata
93
+ end
94
+
95
+
96
+ end # class LogoGenerator
97
+
98
+
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # The MemCache class, a derivative of Arrow::Applet. This is a web interface to MemCached.
4
+ #
5
+ # == VCS Id
6
+ #
7
+ # $Id$
8
+ #
9
+ # == Authors
10
+ #
11
+ # * Michael Granger <ged@FaerieMUD.org>
12
+ #
13
+
14
+ require 'arrow/applet'
15
+ require 'memcache'
16
+
17
+ ### This is a web interface to MemCached.
18
+ class MemCacheApplet < Arrow::Applet
19
+
20
+
21
+ # Applet signature
22
+ Signature = {
23
+ :name => "memcache",
24
+ :description => "This is a web interface to MemCached.",
25
+ :maintainer => "ged@FaerieMUD.org",
26
+ :default_action => 'display',
27
+ :templates => {
28
+ :display => 'memcache/display.tmpl',
29
+ },
30
+ }
31
+
32
+ DefaultServers = [ 'localhost:11211' ]
33
+
34
+ def initialize( *args )
35
+ super
36
+
37
+ servers = DefaultServers
38
+ if @config.respond_to?( :memcache )
39
+ servers.replace( @config.memcache.servers )
40
+ end
41
+
42
+ @memcache = MemCache.new( *servers )
43
+ end
44
+
45
+
46
+ ######
47
+ public
48
+ ######
49
+
50
+ def display_action( txn, *args )
51
+ templ = self.load_template( :display )
52
+ templ.txn = txn
53
+ templ.memcache = @memcache
54
+
55
+ return templ
56
+ end
57
+
58
+
59
+ end # class MemCache
60
+
61
+