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.
- data/ChangeLog +1590 -0
- data/LICENSE +28 -0
- data/README +75 -0
- data/Rakefile +366 -0
- data/Rakefile.local +63 -0
- data/data/arrow/applets/TEMPLATE.rb.tpl +53 -0
- data/data/arrow/applets/args.rb +50 -0
- data/data/arrow/applets/config.rb +55 -0
- data/data/arrow/applets/error.rb +63 -0
- data/data/arrow/applets/files.rb +46 -0
- data/data/arrow/applets/inspect.rb +46 -0
- data/data/arrow/applets/nosuchapplet.rb +31 -0
- data/data/arrow/applets/status.rb +92 -0
- data/data/arrow/applets/test.rb +133 -0
- data/data/arrow/applets/tutorial/counter.rb +96 -0
- data/data/arrow/applets/tutorial/dingus.rb +67 -0
- data/data/arrow/applets/tutorial/hello.rb +34 -0
- data/data/arrow/applets/tutorial/hello2.rb +73 -0
- data/data/arrow/applets/tutorial/imgtext.rb +90 -0
- data/data/arrow/applets/tutorial/imgtext2.rb +286 -0
- data/data/arrow/applets/tutorial/index.rb +36 -0
- data/data/arrow/applets/tutorial/logo.rb +98 -0
- data/data/arrow/applets/tutorial/memcache.rb +61 -0
- data/data/arrow/applets/tutorial/missing.rb +37 -0
- data/data/arrow/applets/tutorial/protected.rb +100 -0
- data/data/arrow/applets/tutorial/redirector.rb +52 -0
- data/data/arrow/applets/tutorial/rndimages.rb +159 -0
- data/data/arrow/applets/tutorial/sharenotes.rb +83 -0
- data/data/arrow/applets/tutorial/subclassed-hello.rb +32 -0
- data/data/arrow/applets/tutorial/superhello.rb +72 -0
- data/data/arrow/applets/tutorial/timeclock.rb +78 -0
- data/data/arrow/applets/view-applet.rb +123 -0
- data/data/arrow/applets/view-template.rb +85 -0
- data/data/arrow/applets/wiki.rb +274 -0
- data/data/arrow/templates/TEMPLATE.tmpl.tpl +36 -0
- data/data/arrow/templates/applet-status.tmpl +153 -0
- data/data/arrow/templates/args-display.tmpl +120 -0
- data/data/arrow/templates/config/display-table.tmpl +36 -0
- data/data/arrow/templates/config/display.tmpl +36 -0
- data/data/arrow/templates/counter-deleted.tmpl +33 -0
- data/data/arrow/templates/counter.tmpl +59 -0
- data/data/arrow/templates/dingus.tmpl +55 -0
- data/data/arrow/templates/enumtable.tmpl +8 -0
- data/data/arrow/templates/error-display.tmpl +92 -0
- data/data/arrow/templates/filemap.tmpl +89 -0
- data/data/arrow/templates/hello-world-src.tmpl +34 -0
- data/data/arrow/templates/hello-world.tmpl +60 -0
- data/data/arrow/templates/imgtext/fontlist.tmpl +46 -0
- data/data/arrow/templates/imgtext/form.tmpl +70 -0
- data/data/arrow/templates/imgtext/reload-error.tmpl +40 -0
- data/data/arrow/templates/imgtext/reload.tmpl +55 -0
- data/data/arrow/templates/inspect/display.tmpl +80 -0
- data/data/arrow/templates/loginform.tmpl +64 -0
- data/data/arrow/templates/logout.tmpl +32 -0
- data/data/arrow/templates/memcache/display.tmpl +41 -0
- data/data/arrow/templates/navbar.incl +27 -0
- data/data/arrow/templates/nosuchapplet.tmpl +32 -0
- data/data/arrow/templates/printsource.tmpl +35 -0
- data/data/arrow/templates/protected.tmpl +36 -0
- data/data/arrow/templates/rndimages.tmpl +38 -0
- data/data/arrow/templates/service-response.tmpl +13 -0
- data/data/arrow/templates/sharenotes/display.tmpl +38 -0
- data/data/arrow/templates/status.tmpl +120 -0
- data/data/arrow/templates/templateviewer.tmpl +43 -0
- data/data/arrow/templates/test/harness.tmpl +57 -0
- data/data/arrow/templates/test/list.tmpl +48 -0
- data/data/arrow/templates/test/problem.tmpl +42 -0
- data/data/arrow/templates/tutorial/index.tmpl +37 -0
- data/data/arrow/templates/tutorial/missingapplet.tmpl +29 -0
- data/data/arrow/templates/view-applet-nosuch.tmpl +32 -0
- data/data/arrow/templates/view-applet.tmpl +40 -0
- data/data/arrow/templates/view-template.tmpl +83 -0
- data/data/arrow/templates/wiki/formerror.tmpl +47 -0
- data/data/arrow/templates/wiki/markup_help.incl +6 -0
- data/data/arrow/templates/wiki/new.tmpl +56 -0
- data/data/arrow/templates/wiki/new_system.tmpl +122 -0
- data/data/arrow/templates/wiki/sectionlist.tmpl +43 -0
- data/data/arrow/templates/wiki/show.tmpl +34 -0
- data/docs/manual/layouts/default.page +43 -0
- data/docs/manual/lib/api-filter.rb +81 -0
- data/docs/manual/lib/editorial-filter.rb +64 -0
- data/docs/manual/lib/examples-filter.rb +244 -0
- data/docs/manual/lib/links-filter.rb +117 -0
- data/lib/apache/fakerequest.rb +448 -0
- data/lib/apache/logger.rb +33 -0
- data/lib/arrow.rb +51 -0
- data/lib/arrow/acceptparam.rb +207 -0
- data/lib/arrow/applet.rb +725 -0
- data/lib/arrow/appletmixins.rb +218 -0
- data/lib/arrow/appletregistry.rb +590 -0
- data/lib/arrow/applettestcase.rb +503 -0
- data/lib/arrow/broker.rb +255 -0
- data/lib/arrow/cache.rb +176 -0
- data/lib/arrow/config-loaders/yaml.rb +75 -0
- data/lib/arrow/config.rb +615 -0
- data/lib/arrow/constants.rb +24 -0
- data/lib/arrow/cookie.rb +359 -0
- data/lib/arrow/cookieset.rb +108 -0
- data/lib/arrow/dispatcher.rb +368 -0
- data/lib/arrow/dispatcherloader.rb +50 -0
- data/lib/arrow/exceptions.rb +61 -0
- data/lib/arrow/fallbackhandler.rb +48 -0
- data/lib/arrow/formvalidator.rb +631 -0
- data/lib/arrow/htmltokenizer.rb +343 -0
- data/lib/arrow/logger.rb +488 -0
- data/lib/arrow/logger/apacheoutputter.rb +69 -0
- data/lib/arrow/logger/arrayoutputter.rb +63 -0
- data/lib/arrow/logger/coloroutputter.rb +111 -0
- data/lib/arrow/logger/fileoutputter.rb +96 -0
- data/lib/arrow/logger/htmloutputter.rb +54 -0
- data/lib/arrow/logger/outputter.rb +123 -0
- data/lib/arrow/mixins.rb +425 -0
- data/lib/arrow/monkeypatches.rb +94 -0
- data/lib/arrow/object.rb +117 -0
- data/lib/arrow/path.rb +196 -0
- data/lib/arrow/service.rb +447 -0
- data/lib/arrow/session.rb +289 -0
- data/lib/arrow/session/dbstore.rb +100 -0
- data/lib/arrow/session/filelock.rb +160 -0
- data/lib/arrow/session/filestore.rb +132 -0
- data/lib/arrow/session/id.rb +98 -0
- data/lib/arrow/session/lock.rb +253 -0
- data/lib/arrow/session/md5id.rb +42 -0
- data/lib/arrow/session/nulllock.rb +42 -0
- data/lib/arrow/session/posixlock.rb +166 -0
- data/lib/arrow/session/sha1id.rb +54 -0
- data/lib/arrow/session/store.rb +366 -0
- data/lib/arrow/session/usertrackid.rb +52 -0
- data/lib/arrow/spechelpers.rb +73 -0
- data/lib/arrow/template.rb +713 -0
- data/lib/arrow/template/attr.rb +31 -0
- data/lib/arrow/template/call.rb +31 -0
- data/lib/arrow/template/comment.rb +33 -0
- data/lib/arrow/template/container.rb +118 -0
- data/lib/arrow/template/else.rb +41 -0
- data/lib/arrow/template/elsif.rb +44 -0
- data/lib/arrow/template/escape.rb +53 -0
- data/lib/arrow/template/export.rb +87 -0
- data/lib/arrow/template/for.rb +145 -0
- data/lib/arrow/template/if.rb +78 -0
- data/lib/arrow/template/import.rb +119 -0
- data/lib/arrow/template/include.rb +206 -0
- data/lib/arrow/template/iterator.rb +208 -0
- data/lib/arrow/template/nodes.rb +734 -0
- data/lib/arrow/template/parser.rb +571 -0
- data/lib/arrow/template/prettyprint.rb +53 -0
- data/lib/arrow/template/render.rb +191 -0
- data/lib/arrow/template/selectlist.rb +94 -0
- data/lib/arrow/template/set.rb +87 -0
- data/lib/arrow/template/timedelta.rb +81 -0
- data/lib/arrow/template/unless.rb +78 -0
- data/lib/arrow/template/urlencode.rb +51 -0
- data/lib/arrow/template/yield.rb +139 -0
- data/lib/arrow/templatefactory.rb +125 -0
- data/lib/arrow/testcase.rb +567 -0
- data/lib/arrow/transaction.rb +608 -0
- data/rake/191_compat.rb +26 -0
- data/rake/dependencies.rb +76 -0
- data/rake/documentation.rb +114 -0
- data/rake/helpers.rb +502 -0
- data/rake/hg.rb +282 -0
- data/rake/manual.rb +787 -0
- data/rake/packaging.rb +129 -0
- data/rake/publishing.rb +278 -0
- data/rake/style.rb +62 -0
- data/rake/svn.rb +668 -0
- data/rake/testing.rb +187 -0
- data/rake/verifytask.rb +64 -0
- data/spec/arrow/acceptparam_spec.rb +157 -0
- data/spec/arrow/applet_spec.rb +575 -0
- data/spec/arrow/appletmixins_spec.rb +409 -0
- data/spec/arrow/appletregistry_spec.rb +294 -0
- data/spec/arrow/broker_spec.rb +153 -0
- data/spec/arrow/config_spec.rb +224 -0
- data/spec/arrow/cookieset_spec.rb +164 -0
- data/spec/arrow/dispatcher_spec.rb +137 -0
- data/spec/arrow/dispatcherloader_spec.rb +65 -0
- data/spec/arrow/formvalidator_spec.rb +781 -0
- data/spec/arrow/logger_spec.rb +346 -0
- data/spec/arrow/mixins_spec.rb +120 -0
- data/spec/arrow/service_spec.rb +645 -0
- data/spec/arrow/session_spec.rb +121 -0
- data/spec/arrow/template/iterator_spec.rb +222 -0
- data/spec/arrow/templatefactory_spec.rb +185 -0
- data/spec/arrow/transaction_spec.rb +319 -0
- data/spec/arrow_spec.rb +37 -0
- data/spec/lib/appletmatchers.rb +281 -0
- data/spec/lib/constants.rb +77 -0
- data/spec/lib/helpers.rb +41 -0
- data/spec/lib/matchers.rb +44 -0
- data/tests/cookie.tests.rb +310 -0
- data/tests/path.tests.rb +157 -0
- data/tests/session.tests.rb +111 -0
- data/tests/session_id.tests.rb +82 -0
- data/tests/session_lock.tests.rb +191 -0
- data/tests/session_store.tests.rb +53 -0
- data/tests/template.tests.rb +1360 -0
- metadata +339 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
#
|
|
3
|
+
# The MissingApplet class, a derivative of Arrow::Applet. It
|
|
4
|
+
# is an example 'missingApplet' applet.
|
|
5
|
+
#
|
|
6
|
+
# == Authors
|
|
7
|
+
#
|
|
8
|
+
# * Michael Granger <ged@FaerieMUD.org>
|
|
9
|
+
#
|
|
10
|
+
|
|
11
|
+
require 'arrow/applet'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### An example missingApplet applet.
|
|
15
|
+
class MissingApplet < Arrow::Applet
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# Applet signature
|
|
19
|
+
Signature = {
|
|
20
|
+
:name => "No-such-applet handler",
|
|
21
|
+
:description => "An example 'missingApplet' applet. If Arrow is configured " +
|
|
22
|
+
"with the uri of this applet as the missingApplet value, " +
|
|
23
|
+
"it will run this applet instead of declining requests for " +
|
|
24
|
+
"URIs that don't match a registered applet.",
|
|
25
|
+
:maintainer => "ged@FaerieMUD.org",
|
|
26
|
+
:default_action => 'display',
|
|
27
|
+
:templates => {
|
|
28
|
+
:display => 'missingapplet.tmpl',
|
|
29
|
+
},
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
# No action: defaults to loading and displaying the template with the same
|
|
33
|
+
# name as the action.
|
|
34
|
+
|
|
35
|
+
end # class NoSuchAppletHandler
|
|
36
|
+
|
|
37
|
+
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
#
|
|
3
|
+
# The ProtectedDelegator class, a derivative of
|
|
4
|
+
# Arrow::Applet. It is an applet you can chain through for authentication
|
|
5
|
+
# purposes.
|
|
6
|
+
#
|
|
7
|
+
# == Authors
|
|
8
|
+
#
|
|
9
|
+
# * Michael Granger <ged@FaerieMUD.org>
|
|
10
|
+
#
|
|
11
|
+
|
|
12
|
+
require 'digest/md5'
|
|
13
|
+
|
|
14
|
+
require 'arrow/applet'
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### An example applet that you can chain through for simple authentication.
|
|
18
|
+
class ProtectedDelegator < Arrow::Applet
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
Users = {
|
|
22
|
+
'ged' => "30ff9a6c184a0fde7ac7ade1479ee19f",
|
|
23
|
+
'stillflame' => "4a484004cef4efebf22b2f7ec9cdc439",
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
# Applet signature
|
|
27
|
+
Signature = {
|
|
28
|
+
:name => "Password-protected delegator",
|
|
29
|
+
:description => "It is an applet you can chain through for authentication purposes.",
|
|
30
|
+
:maintainer => "ged@FaerieMUD.org",
|
|
31
|
+
:default_action => 'default',
|
|
32
|
+
:templates => {
|
|
33
|
+
:default => 'protected.tmpl',
|
|
34
|
+
:loginform => 'loginform.tmpl',
|
|
35
|
+
:logout => 'logout.tmpl',
|
|
36
|
+
},
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
######
|
|
42
|
+
public
|
|
43
|
+
######
|
|
44
|
+
|
|
45
|
+
def delegate( txn, chain, *args )
|
|
46
|
+
self.log.debug "Checking authentication for the %s applet." % args[0]
|
|
47
|
+
|
|
48
|
+
if !txn.session.key?( :user )
|
|
49
|
+
rval = self.run( txn, 'loginform', *args )
|
|
50
|
+
unless rval == true
|
|
51
|
+
return rval
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
yield( chain )
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def_action :logout do |txn, *args|
|
|
60
|
+
txn.session.delete( :user )
|
|
61
|
+
|
|
62
|
+
templ = self.load_template( :logout )
|
|
63
|
+
templ.txn = txn
|
|
64
|
+
|
|
65
|
+
return templ
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def_action :loginform do |txn, *args|
|
|
69
|
+
self.log.debug "In the 'display' action of the '%s' applet." %
|
|
70
|
+
self.signature.name
|
|
71
|
+
|
|
72
|
+
username = txn.request.param('username')
|
|
73
|
+
password = txn.request.param('password')
|
|
74
|
+
errors = []
|
|
75
|
+
|
|
76
|
+
if username
|
|
77
|
+
pwhash = Digest::MD5.hexdigest( password )
|
|
78
|
+
if !password
|
|
79
|
+
errors << "No password given."
|
|
80
|
+
elsif Users[ username ] != pwhash
|
|
81
|
+
self.log.error "Auth failure: %p vs %p" %
|
|
82
|
+
[ Users[username], pwhash ]
|
|
83
|
+
errors << "Authentication failure."
|
|
84
|
+
else
|
|
85
|
+
txn.session[:user] = username
|
|
86
|
+
return true
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
templ = self.load_template( :loginform )
|
|
91
|
+
templ.txn = txn
|
|
92
|
+
templ.errors = errors unless errors.empty?
|
|
93
|
+
|
|
94
|
+
return templ
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
end # class ProtectedDelegator
|
|
99
|
+
|
|
100
|
+
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
#
|
|
3
|
+
# The RedirectorApplet class, a derivative of
|
|
4
|
+
# Arrow::Applet. It's only a demonstration of the Transaction's #redirect
|
|
5
|
+
# method.
|
|
6
|
+
#
|
|
7
|
+
# == VCS Id
|
|
8
|
+
#
|
|
9
|
+
# $Id$
|
|
10
|
+
#
|
|
11
|
+
# == Authors
|
|
12
|
+
#
|
|
13
|
+
# * Michael Granger <ged@FaerieMUD.org>
|
|
14
|
+
#
|
|
15
|
+
|
|
16
|
+
require 'arrow/applet'
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### It's only a demonstration of the Transaction's #redirect method.
|
|
20
|
+
class RedirectorApplet < Arrow::Applet
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
# The default URI to redirect to
|
|
24
|
+
DefaultURI = "status"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# Applet signature
|
|
28
|
+
Signature = {
|
|
29
|
+
:name => "Redirector",
|
|
30
|
+
:description => "It's only a demonstration of the Transaction's #redirect method.",
|
|
31
|
+
:maintainer => "ged@FaerieMUD.org",
|
|
32
|
+
:default_action => 'redirect',
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
######
|
|
38
|
+
public
|
|
39
|
+
######
|
|
40
|
+
|
|
41
|
+
def redirect_action( txn, *args )
|
|
42
|
+
self.log.debug "In the 'redirect' action of the '%s' app." %
|
|
43
|
+
self.signature.name
|
|
44
|
+
|
|
45
|
+
uri = args.empty? ? DefaultURI : args.join("/")
|
|
46
|
+
return txn.redirect( txn.app_root + "/" + uri )
|
|
47
|
+
end
|
|
48
|
+
alias_method :action_missing_action, :redirect_action
|
|
49
|
+
|
|
50
|
+
end # class RedirectorApplet
|
|
51
|
+
|
|
52
|
+
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
#
|
|
3
|
+
# The RandomImages class, a derivative of Arrow::Applet. It
|
|
4
|
+
# shows the 'latest images' feed from LiveJournal as a page full of clickable
|
|
5
|
+
# links.
|
|
6
|
+
#
|
|
7
|
+
# == VCS Id
|
|
8
|
+
#
|
|
9
|
+
# $Id$
|
|
10
|
+
#
|
|
11
|
+
# == Authors
|
|
12
|
+
#
|
|
13
|
+
# * Michael Granger <ged@FaerieMUD.org>
|
|
14
|
+
#
|
|
15
|
+
|
|
16
|
+
require 'uri'
|
|
17
|
+
require 'net/http'
|
|
18
|
+
|
|
19
|
+
require 'arrow/applet'
|
|
20
|
+
|
|
21
|
+
### It shows the 'latest images' feed from LiveJournal as a page full of clickable links.
|
|
22
|
+
class RandomImages < Arrow::Applet
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# Default feed URL if none is configured
|
|
26
|
+
DefaultFeedUrl = 'http://www.livejournal.com/stats/latest-img.bml'
|
|
27
|
+
|
|
28
|
+
# Default number of seconds to cache the image list
|
|
29
|
+
DefaultCacheSeconds = 15 * 60
|
|
30
|
+
|
|
31
|
+
# Recent-image entry pattern
|
|
32
|
+
RecentImagePattern = %r{
|
|
33
|
+
<recent-image # Tag open
|
|
34
|
+
\s+ # whitespace
|
|
35
|
+
img='([^']+)' # $1 = image URL
|
|
36
|
+
\s+ # whitespace
|
|
37
|
+
url='([^']+)' # $2 = link URL
|
|
38
|
+
\s* # whitspace
|
|
39
|
+
/> # Tag close
|
|
40
|
+
}x
|
|
41
|
+
|
|
42
|
+
# Image struct
|
|
43
|
+
Image = Struct.new( :src, :href )
|
|
44
|
+
|
|
45
|
+
# Default number of images to display from the feed at a time
|
|
46
|
+
DefaultImageCount = 15
|
|
47
|
+
|
|
48
|
+
# Applet signature
|
|
49
|
+
Signature = {
|
|
50
|
+
:name => "Random image gallery",
|
|
51
|
+
:description => "Shows the 'latest images' feed from LiveJournal as " +
|
|
52
|
+
"a page full of clickable links.",
|
|
53
|
+
:maintainer => "ged@FaerieMUD.org",
|
|
54
|
+
:default_action => 'display',
|
|
55
|
+
:templates => {
|
|
56
|
+
:display => 'rndimages.tmpl',
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
### Set up the random image gallery.
|
|
62
|
+
def initialize( *args )
|
|
63
|
+
super
|
|
64
|
+
|
|
65
|
+
if @config.respond_to?( :rndimages )
|
|
66
|
+
feeduri = @config.rndimages.feedurl
|
|
67
|
+
@cache_seconds = Integer( @config.rndimages.cacheseconds ) rescue nil
|
|
68
|
+
@count = Integer( @config.rndimages.displaycount ) rescue nil
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
feeduri ||= DefaultFeedUrl
|
|
72
|
+
@feeduri = URI.parse( feeduri )
|
|
73
|
+
|
|
74
|
+
@cache_seconds ||= DefaultCacheSeconds
|
|
75
|
+
@cache_expiry = Time.at( 0 )
|
|
76
|
+
@count ||= DefaultImageCount
|
|
77
|
+
@images = []
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
######
|
|
83
|
+
public
|
|
84
|
+
######
|
|
85
|
+
|
|
86
|
+
def_action :display do |txn, *args|
|
|
87
|
+
if @cache_expiry < Time.now
|
|
88
|
+
self.log.debug "Cached images expired at %s: Fetching new list" %
|
|
89
|
+
[ @cache_expiry ]
|
|
90
|
+
@images = self.build_imagelist( @feeduri )
|
|
91
|
+
@cache_expiry = Time.now + @cache_seconds
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
imgslice = []
|
|
95
|
+
until imgslice.nitems == @count
|
|
96
|
+
imgslice << rand( @images.nitems )
|
|
97
|
+
imgslice.uniq!
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
tmpl = self.load_template( :display )
|
|
101
|
+
tmpl.txn = txn
|
|
102
|
+
tmpl.app = self
|
|
103
|
+
tmpl.images = @images.values_at( *imgslice )
|
|
104
|
+
|
|
105
|
+
return tmpl
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
#########
|
|
111
|
+
protected
|
|
112
|
+
#########
|
|
113
|
+
|
|
114
|
+
### Fetch the list of images in the feed and replace the ones currently in
|
|
115
|
+
### @images, if any.
|
|
116
|
+
def build_imagelist( feeduri )
|
|
117
|
+
rawfeed = self.fetch_imagefeed( feeduri )
|
|
118
|
+
images = self.parse_imagefeed( rawfeed )
|
|
119
|
+
|
|
120
|
+
return images
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
### Fetch the raw imagelist over HTTP and return it. An exception is raised
|
|
125
|
+
### if the fetch fails for some reason.
|
|
126
|
+
def fetch_imagefeed( uri )
|
|
127
|
+
res = nil
|
|
128
|
+
|
|
129
|
+
Net::HTTP.start( uri.host, uri.port ) do |http|
|
|
130
|
+
res = http.get( uri.path )
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
unless Net::HTTPSuccess === res
|
|
134
|
+
raise "Fetch of %s failed: %d: %s" %
|
|
135
|
+
[ uri, res.code, res.message ]
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
return res.body
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
### Parse the given +rawdata+ from the image feed and return an Array of
|
|
143
|
+
### Hashes that describe the images referenced therein.
|
|
144
|
+
def parse_imagefeed( rawdata )
|
|
145
|
+
images = []
|
|
146
|
+
|
|
147
|
+
rawdata.scan( RecentImagePattern ) do |match|
|
|
148
|
+
self.log.debug "Matched image tag: %p" % match
|
|
149
|
+
images << Image.new( $1, $2 )
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
self.log.debug "Parsed images: %p ..." % images[0..3]
|
|
153
|
+
return images
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
end # class RandomImages
|
|
158
|
+
|
|
159
|
+
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
#
|
|
3
|
+
# The ShareNotes class, a derivative of Arrow::Applet. Render
|
|
4
|
+
# a shared document after being transformed via Markdown
|
|
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 'bluecloth'
|
|
17
|
+
|
|
18
|
+
### Render a shared document after being transformed via Markdown
|
|
19
|
+
class ShareNotes < Arrow::Applet
|
|
20
|
+
|
|
21
|
+
# Default share directory
|
|
22
|
+
DefaultDirectory = "/Users/ged/Documents"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# Applet signature
|
|
26
|
+
Signature = {
|
|
27
|
+
:name => "sharenotes",
|
|
28
|
+
:description => "Render a shared document after being transformed via Markdown",
|
|
29
|
+
:maintainer => "ged@FaerieMUD.org",
|
|
30
|
+
:default_action => 'display',
|
|
31
|
+
:templates => {
|
|
32
|
+
:display => "sharenotes/display.tmpl"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def initialize( *args )
|
|
38
|
+
super
|
|
39
|
+
|
|
40
|
+
if @config.respond_to?( :sharenotes )
|
|
41
|
+
@directory = @config.sharenotes.directory
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
@directory ||= DefaultDirectory
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
######
|
|
49
|
+
public
|
|
50
|
+
######
|
|
51
|
+
|
|
52
|
+
def display_action( txn, *args )
|
|
53
|
+
self.log.debug "In the 'display' action of the '%s' app." %
|
|
54
|
+
self.signature.name
|
|
55
|
+
|
|
56
|
+
doc = $1 if /(\w[\w. -]+)/.match( args.first )
|
|
57
|
+
doc.untaint
|
|
58
|
+
|
|
59
|
+
tmpl = self.load_template( :display )
|
|
60
|
+
|
|
61
|
+
begin
|
|
62
|
+
if doc
|
|
63
|
+
if File.readable?( doc )
|
|
64
|
+
markdown = File.read( doc )
|
|
65
|
+
tmpl.body = BlueCloth.new( markdown ).to_html
|
|
66
|
+
else
|
|
67
|
+
tmpl.error = "File '%s' is not readable." % [doc]
|
|
68
|
+
end
|
|
69
|
+
else
|
|
70
|
+
tmpl.error = "No document specified"
|
|
71
|
+
end
|
|
72
|
+
rescue RuntimeError => err
|
|
73
|
+
tmpl.error = err.message
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
return true
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
end # class ShareNotes
|
|
82
|
+
|
|
83
|
+
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
#
|
|
3
|
+
# The SubclassedHello class, a derivative of the Hello
|
|
4
|
+
# applet to test applet inheritance.
|
|
5
|
+
#
|
|
6
|
+
# == Authors
|
|
7
|
+
#
|
|
8
|
+
# * Martin Chase <stillflame@FaerieMUD.org>
|
|
9
|
+
#
|
|
10
|
+
|
|
11
|
+
begin
|
|
12
|
+
basedir = File.dirname(__FILE__)
|
|
13
|
+
$LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
require 'superhello'
|
|
17
|
+
|
|
18
|
+
Arrow::Logger.global.debug "SubclassedHello: Past the requires"
|
|
19
|
+
|
|
20
|
+
### An applet for testing inheritance from other derived applets
|
|
21
|
+
class SubclassedHello < SuperHello
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# Applet signature
|
|
25
|
+
Signature = {
|
|
26
|
+
:name => "Hello World (Subclassed)",
|
|
27
|
+
:description => %{A modified 'hello world' applet to figure out if subclassing works.},
|
|
28
|
+
:uri => "subhello",
|
|
29
|
+
:maintainer => "stillflame@FaerieMUD.org",
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
end # class SubclassedHello
|