actionservice 0.2.99
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 +3 -0
- data/HACKING +39 -0
- data/MIT-LICENSE +21 -0
- data/README +36 -0
- data/Rakefile +121 -0
- data/TODO +25 -0
- data/examples/soap/README +121 -0
- data/examples/soap/app/controllers/search_controller.rb +8 -0
- data/examples/soap/lib/google_search_service.rb +90 -0
- data/lib/action_service/base.rb +74 -0
- data/lib/action_service/container.rb +69 -0
- data/lib/action_service/invocation.rb +172 -0
- data/lib/action_service/protocol/abstract.rb +61 -0
- data/lib/action_service/protocol/registry.rb +49 -0
- data/lib/action_service/protocol/soap.rb +386 -0
- data/lib/action_service/protocol.rb +3 -0
- data/lib/action_service/router/action_controller.rb +71 -0
- data/lib/action_service/router/wsdl.rb +180 -0
- data/lib/action_service/router.rb +2 -0
- data/lib/action_service/struct.rb +15 -0
- data/lib/action_service/support/class_inheritable_options.rb +26 -0
- data/lib/action_service.rb +50 -0
- data/setup.rb +1360 -0
- data/test/abstract_unit.rb +9 -0
- data/test/base_test.rb +47 -0
- data/test/container_test.rb +29 -0
- data/test/invocation_test.rb +144 -0
- data/test/protocol_registry_test.rb +54 -0
- data/test/protocol_soap_test.rb +94 -0
- data/test/router_action_controller_test.rb +98 -0
- data/test/router_wsdl_test.rb +43 -0
- data/test/struct_test.rb +16 -0
- metadata +87 -0
data/CHANGELOG
ADDED
data/HACKING
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
== Coding Style
|
2
|
+
|
3
|
+
Please try to follow Rails conventions and idioms.
|
4
|
+
|
5
|
+
|
6
|
+
== Concepts
|
7
|
+
|
8
|
+
* Service
|
9
|
+
A service contains zero or more exports (methods)
|
10
|
+
|
11
|
+
* Container
|
12
|
+
A container contains zero or more services
|
13
|
+
|
14
|
+
* Router
|
15
|
+
A router takes raw wire requests, decodes them, performs the invocation on
|
16
|
+
the service, and generates raw wire responses from the invocation result.
|
17
|
+
A router is mixed into a container class.
|
18
|
+
|
19
|
+
* Protocol
|
20
|
+
A protocol implementation implements the unmarshaling and marshaling of
|
21
|
+
raw wire requests and responses. Registers with router.
|
22
|
+
|
23
|
+
|
24
|
+
== Action Pack Integration
|
25
|
+
|
26
|
+
For Action Pack, the ActionController is both container and router, and also contains
|
27
|
+
the protocol implementations.
|
28
|
+
|
29
|
+
|
30
|
+
== Adding support for a new protocol
|
31
|
+
|
32
|
+
1. Add an ActionService::Protocol::YourProtocol module and any classes you need to
|
33
|
+
perform unmarshaling/marshaling of protocol requests. See the SOAP implementation
|
34
|
+
for an example of a complex mapping, and also see
|
35
|
+
ActionService::Protocol::AbstractProtocol for the methods you need to implement.
|
36
|
+
|
37
|
+
2. Add unit tests for your new protocol. Be sure to test using a Action Pack test request
|
38
|
+
duplicating how the real requests will arrive and verify that mapping to and from Ruby
|
39
|
+
types works correctly.
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (C) 2005 Leon Breedt
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
data/README
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
= Action Service -- Web service integration with Action Pack
|
2
|
+
|
3
|
+
FIXME
|
4
|
+
|
5
|
+
== Dependencies
|
6
|
+
|
7
|
+
Action Service requires that the Action Pack is either available to be required immediately
|
8
|
+
or is accessible as a GEM.
|
9
|
+
|
10
|
+
It also requires a version of Ruby that includes SOAP support in the standard library. At
|
11
|
+
least version 1.8.2 final is recommended.
|
12
|
+
|
13
|
+
|
14
|
+
== Download
|
15
|
+
|
16
|
+
|
17
|
+
FIXME
|
18
|
+
|
19
|
+
|
20
|
+
== Installation
|
21
|
+
|
22
|
+
You can install Action Service with the following command.
|
23
|
+
|
24
|
+
% [sudo] ruby install.rb
|
25
|
+
|
26
|
+
from its distribution directory.
|
27
|
+
|
28
|
+
|
29
|
+
== License
|
30
|
+
|
31
|
+
Action Service is released under the MIT license.
|
32
|
+
|
33
|
+
|
34
|
+
== Support
|
35
|
+
|
36
|
+
FIXME
|
data/Rakefile
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'rake/rdoctask'
|
5
|
+
require 'rake/packagetask'
|
6
|
+
require 'rake/gempackagetask'
|
7
|
+
require 'rake/contrib/rubyforgepublisher'
|
8
|
+
|
9
|
+
PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
|
10
|
+
PKG_NAME = 'actionservice'
|
11
|
+
PKG_VERSION = '0.2.99' + PKG_BUILD
|
12
|
+
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
13
|
+
|
14
|
+
desc "Default Task"
|
15
|
+
task :default => [ :test ]
|
16
|
+
|
17
|
+
|
18
|
+
# Run the unit tests
|
19
|
+
Rake::TestTask.new { |t|
|
20
|
+
t.libs << "test"
|
21
|
+
t.pattern = 'test/*_test.rb'
|
22
|
+
t.verbose = true
|
23
|
+
}
|
24
|
+
|
25
|
+
|
26
|
+
# Generate the RDoc documentation
|
27
|
+
Rake::RDocTask.new { |rdoc|
|
28
|
+
rdoc.rdoc_dir = 'doc'
|
29
|
+
rdoc.title = "Action Service -- Web services for Action Pack"
|
30
|
+
rdoc.options << '--line-numbers --inline-source --main README'
|
31
|
+
rdoc.rdoc_files.include('README', 'CHANGELOG')
|
32
|
+
rdoc.rdoc_files.include('lib/action_service.rb')
|
33
|
+
rdoc.rdoc_files.include('lib/action_service/*.rb')
|
34
|
+
rdoc.rdoc_files.include('lib/action_service/protocol/*.rb')
|
35
|
+
rdoc.rdoc_files.include('lib/action_service/router/*.rb')
|
36
|
+
}
|
37
|
+
|
38
|
+
|
39
|
+
# Create compressed packages
|
40
|
+
spec = Gem::Specification.new do |s|
|
41
|
+
s.platform = Gem::Platform::RUBY
|
42
|
+
s.name = PKG_NAME
|
43
|
+
s.summary = "Web service support for Action Pack."
|
44
|
+
s.description = %q{Adds WSDL/SOAP and XML-RPC web service support to Action Pack}
|
45
|
+
s.version = PKG_VERSION
|
46
|
+
|
47
|
+
s.author = "Leon Breedt"
|
48
|
+
s.email = "bitserf@gmail.com"
|
49
|
+
s.rubyforge_project = "actionservice"
|
50
|
+
s.homepage = "http://rubyforge.org/projects/actionservice"
|
51
|
+
|
52
|
+
s.add_dependency('actionpack', '>= 1.4.0')
|
53
|
+
|
54
|
+
s.has_rdoc = true
|
55
|
+
s.requirements << 'none'
|
56
|
+
s.require_path = 'lib'
|
57
|
+
s.autorequire = 'action_service'
|
58
|
+
|
59
|
+
s.files = [ "Rakefile", "setup.rb", "README", "TODO", "HACKING", "CHANGELOG", "MIT-LICENSE" ]
|
60
|
+
s.files = s.files + Dir.glob( "examples/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
|
61
|
+
s.files = s.files + Dir.glob( "lib/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
|
62
|
+
s.files = s.files + Dir.glob( "test/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
|
63
|
+
end
|
64
|
+
Rake::GemPackageTask.new(spec) do |p|
|
65
|
+
p.gem_spec = spec
|
66
|
+
p.need_tar = true
|
67
|
+
p.need_zip = true
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
desc "Publish the beta gem"
|
72
|
+
task :pgem => [:package] do
|
73
|
+
# Rake::SshFilePublisher.new("davidhh@comox.textdrive.com", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
desc "Publish the API documentation"
|
78
|
+
task :pdoc => [:rdoc] do
|
79
|
+
# Rake::SshDirPublisher.new("davidhh@comox.textdrive.com", "public_html/am", "doc").upload
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
desc "Publish to RubyForge"
|
84
|
+
task :rubyforge do
|
85
|
+
Rake::RubyForgePublisher.new('actionservice', 'ljb').upload
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
desc "Count lines in the main rake file"
|
90
|
+
task :lines do
|
91
|
+
lines = 0
|
92
|
+
codelines = 0
|
93
|
+
prefix = File.join(File.dirname(__FILE__), 'lib')
|
94
|
+
puts "Per File:"
|
95
|
+
%w{
|
96
|
+
action_service
|
97
|
+
action_service/protocol
|
98
|
+
action_service/router
|
99
|
+
}.each do |dir|
|
100
|
+
Dir.foreach(File.join(prefix, dir)) { |file_name|
|
101
|
+
next unless file_name =~ /.*rb$/
|
102
|
+
full_file_name = File.join(prefix, dir, file_name)
|
103
|
+
|
104
|
+
f = File.open(full_file_name)
|
105
|
+
|
106
|
+
file_lines = 0
|
107
|
+
file_codelines = 0
|
108
|
+
while line = f.gets
|
109
|
+
file_lines += 1
|
110
|
+
next if line =~ /^\s*$/
|
111
|
+
next if line =~ /^\s*#/
|
112
|
+
file_codelines += 1
|
113
|
+
end
|
114
|
+
puts " #{File.join('lib', dir, file_name)}: Lines #{file_lines}, LOC #{file_codelines}"
|
115
|
+
lines += file_lines
|
116
|
+
codelines += file_codelines
|
117
|
+
}
|
118
|
+
end
|
119
|
+
puts "Total:"
|
120
|
+
puts " Lines #{lines}, LOC #{codelines}"
|
121
|
+
end
|
data/TODO
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
= Features Remaining
|
2
|
+
- XML-RPC support
|
3
|
+
- Support for ActiveRecord model classes as structure types as well, since
|
4
|
+
we can reflect all the details to do proper mapping from model classes.
|
5
|
+
|
6
|
+
= Ideas
|
7
|
+
- <nextangle> Support a second dispatching mechanism, where incoming
|
8
|
+
operation requests are mapped directly to a controller action.
|
9
|
+
|
10
|
+
Advantages: No seperate API service class, the controller becomes the
|
11
|
+
service class.
|
12
|
+
|
13
|
+
Possible approaches:
|
14
|
+
Create a new router that maps an 'api' action to do dispatching using
|
15
|
+
itself as the target service.
|
16
|
+
|
17
|
+
This dispatching would:
|
18
|
+
|
19
|
+
* Unpack request parameters into @params
|
20
|
+
* Execute the action
|
21
|
+
* Use the return value of the action to send back to the client
|
22
|
+
|
23
|
+
= Warts
|
24
|
+
- Don't have clean way to go from SOAP Class object to the xsd:NAME type
|
25
|
+
string
|
@@ -0,0 +1,121 @@
|
|
1
|
+
= Google Service example
|
2
|
+
|
3
|
+
|
4
|
+
This example shows how one would implement an API like Google
|
5
|
+
Search, that uses lots of structured types.
|
6
|
+
|
7
|
+
|
8
|
+
= Testing
|
9
|
+
|
10
|
+
1. Ensure you have the 'actionservice' Gem installed. You can generate it using
|
11
|
+
this command:
|
12
|
+
|
13
|
+
$ rake package
|
14
|
+
|
15
|
+
2. Copy lib/google_search_service.rb and app/controllers/search_controller.rb
|
16
|
+
into a Rails project.
|
17
|
+
|
18
|
+
3. Edit config/environment.rb, and add the following line after the rest of the
|
19
|
+
require_gem statements:
|
20
|
+
|
21
|
+
require_gem 'actionservice'
|
22
|
+
|
23
|
+
4. Go to the url http://URL/search/wsdl in a browser, and check that it looks
|
24
|
+
correct.
|
25
|
+
|
26
|
+
You can compare it to Google's hand-coded WSDL at http://api.google.com/GoogleSearch.wsdl
|
27
|
+
and see how close (or not) the generated version is.
|
28
|
+
|
29
|
+
Note that I used GoogleSearch as the canonical "best practice"
|
30
|
+
interoperable example, which might explain extreme similarities :)
|
31
|
+
|
32
|
+
5. Test that it works with .NET (Mono in this example):
|
33
|
+
|
34
|
+
$ wget http://APP/search/wsdl
|
35
|
+
$ mv wsdl GoogleSearch.wsdl
|
36
|
+
$ wsdl -out:GoogleSearch.cs GoogleSearch.wsdl
|
37
|
+
|
38
|
+
Add these lines to the GoogleSearchService class body (be mindful of the
|
39
|
+
wrapping):
|
40
|
+
|
41
|
+
public static void Main(string[] args)
|
42
|
+
{
|
43
|
+
GoogleSearchResult result;
|
44
|
+
GoogleSearchService service;
|
45
|
+
|
46
|
+
service = new GoogleSearchService();
|
47
|
+
result = service.doGoogleSearch("myApiKey", "my query", 10, 30, true, "restrict", false, "lr", "ie", "oe");
|
48
|
+
System.Console.WriteLine("documentFiltering: {0}", result.documentFiltering);
|
49
|
+
System.Console.WriteLine("searchComments: {0}", result.searchComments);
|
50
|
+
System.Console.WriteLine("estimatedTotalResultsCount: {0}", result.estimatedTotalResultsCount);
|
51
|
+
System.Console.WriteLine("estimateIsExact: {0}", result.estimateIsExact);
|
52
|
+
System.Console.WriteLine("resultElements:");
|
53
|
+
foreach (ResultElement element in result.resultElements) {
|
54
|
+
System.Console.WriteLine("\tsummary: {0}", element.summary);
|
55
|
+
System.Console.WriteLine("\tURL: {0}", element.URL);
|
56
|
+
System.Console.WriteLine("\tsnippet: {0}", element.snippet);
|
57
|
+
System.Console.WriteLine("\ttitle: {0}", element.title);
|
58
|
+
System.Console.WriteLine("\tcachedSize: {0}", element.cachedSize);
|
59
|
+
System.Console.WriteLine("\trelatedInformationPresent: {0}", element.relatedInformationPresent);
|
60
|
+
System.Console.WriteLine("\thostName: {0}", element.hostName);
|
61
|
+
System.Console.WriteLine("\tdirectoryCategory: {0}", element.directoryCategory.fullViewableName);
|
62
|
+
System.Console.WriteLine("\tdirectoryTitle: {0}", element.directoryTitle);
|
63
|
+
}
|
64
|
+
System.Console.WriteLine("searchQuery: {0}", result.searchQuery);
|
65
|
+
System.Console.WriteLine("startIndex: {0}", result.startIndex);
|
66
|
+
System.Console.WriteLine("endIndex: {0}", result.endIndex);
|
67
|
+
System.Console.WriteLine("searchTips: {0}", result.searchTips);
|
68
|
+
System.Console.WriteLine("directoryCategories:");
|
69
|
+
foreach (DirectoryCategory cat in result.directoryCategories) {
|
70
|
+
System.Console.WriteLine("\t{0} ({1})", cat.fullViewableName, cat.specialEncoding);
|
71
|
+
}
|
72
|
+
System.Console.WriteLine("searchTime: {0}", result.searchTime);
|
73
|
+
}
|
74
|
+
|
75
|
+
Now compile and run:
|
76
|
+
|
77
|
+
$ mcs -reference:System.Web.Services GoogleSearch.cs
|
78
|
+
$ mono GoogleSearch.exe
|
79
|
+
|
80
|
+
|
81
|
+
If you had the application running (on the same host you got
|
82
|
+
the WSDL from), you should see something like this (values will match up
|
83
|
+
with those in lib/google_search_service.rb):
|
84
|
+
|
85
|
+
|
86
|
+
documentFiltering: True
|
87
|
+
searchComments:
|
88
|
+
estimatedTotalResultsCount: 322000
|
89
|
+
estimateIsExact: False
|
90
|
+
resultElements:
|
91
|
+
summary: ONlamp.com: Rolling with Ruby on Rails
|
92
|
+
URL: http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html
|
93
|
+
snippet: Curt Hibbs shows off Ruby on Rails by building a simple ...
|
94
|
+
title: Teh Railz0r
|
95
|
+
cachedSize: Almost no lines of code!
|
96
|
+
relatedInformationPresent: True
|
97
|
+
hostName: rubyonrails.com
|
98
|
+
directoryCategory: Web Development
|
99
|
+
directoryTitle:
|
100
|
+
searchQuery: http://www.google.com/search?q=ruby+on+rails
|
101
|
+
startIndex: 10
|
102
|
+
endIndex: 40
|
103
|
+
searchTips: "on" is a very common word and was not included in your search [details]
|
104
|
+
directoryCategories:
|
105
|
+
Web Development (UTF-8)
|
106
|
+
Programming (US-ASCII)
|
107
|
+
searchTime: 1E-06
|
108
|
+
|
109
|
+
|
110
|
+
Also, if an API method throws an exception, it will be sent back to the
|
111
|
+
caller in SOAP exception format, so they'll get an exception thrown on
|
112
|
+
their side with a meaningful error message.
|
113
|
+
|
114
|
+
If you don't like this behaviour, you can do:
|
115
|
+
|
116
|
+
class MyService < ActionService::Base
|
117
|
+
exception_reporting false
|
118
|
+
end
|
119
|
+
|
120
|
+
6. Crack open a beer. Publishing APIs for working with the same model as
|
121
|
+
your Rails web app should be easy from now on :)
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'action_service'
|
2
|
+
|
3
|
+
class DirectoryCategory < ActionService::Struct
|
4
|
+
member :fullViewableName, String
|
5
|
+
member :specialEncoding, String
|
6
|
+
end
|
7
|
+
|
8
|
+
class ResultElement < ActionService::Struct
|
9
|
+
member :summary, String
|
10
|
+
member :URL, String
|
11
|
+
member :snippet, String
|
12
|
+
member :title, String
|
13
|
+
member :cachedSize, String
|
14
|
+
member :relatedInformationPresent, TrueClass
|
15
|
+
member :hostName, String
|
16
|
+
member :directoryCategory, DirectoryCategory
|
17
|
+
member :directoryTitle, String
|
18
|
+
end
|
19
|
+
|
20
|
+
class GoogleSearchResult < ActionService::Struct
|
21
|
+
member :documentFiltering, TrueClass
|
22
|
+
member :searchComments, String
|
23
|
+
member :estimatedTotalResultsCount, Integer
|
24
|
+
member :estimateIsExact, TrueClass
|
25
|
+
member :resultElements, [ResultElement]
|
26
|
+
member :searchQuery, String
|
27
|
+
member :startIndex, Integer
|
28
|
+
member :endIndex, Integer
|
29
|
+
member :searchTips, String
|
30
|
+
member :directoryCategories, [DirectoryCategory]
|
31
|
+
member :searchTime, Float
|
32
|
+
end
|
33
|
+
|
34
|
+
class GoogleSearchService < ActionService::Base
|
35
|
+
export_name_mangling false
|
36
|
+
|
37
|
+
def doGetCachedPage(key, url)
|
38
|
+
"<html><body>i am a cached page</body></html>"
|
39
|
+
end
|
40
|
+
|
41
|
+
def doSpellingSuggestion(key, phrase)
|
42
|
+
"Did you mean 'teh'?"
|
43
|
+
end
|
44
|
+
|
45
|
+
def doGoogleSearch(key, q, start, maxResults, filter, restrict, safeSearch, lr, ie, oe)
|
46
|
+
resultElement = ResultElement.new
|
47
|
+
resultElement.summary = "ONlamp.com: Rolling with Ruby on Rails"
|
48
|
+
resultElement.URL = "http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html"
|
49
|
+
resultElement.snippet = "Curt Hibbs shows off Ruby on Rails by building a simple application that requires " +
|
50
|
+
"almost no Ruby experience. ... Rolling with Ruby on Rails. ..."
|
51
|
+
resultElement.title = "Teh Railz0r"
|
52
|
+
resultElement.cachedSize = "Almost no lines of code!"
|
53
|
+
resultElement.relatedInformationPresent = true
|
54
|
+
resultElement.hostName = "rubyonrails.com"
|
55
|
+
resultElement.directoryCategory = category("Web Development", "UTF-8")
|
56
|
+
|
57
|
+
result = GoogleSearchResult.new
|
58
|
+
result.documentFiltering = filter
|
59
|
+
result.searchComments = ""
|
60
|
+
result.estimatedTotalResultsCount = 322000
|
61
|
+
result.estimateIsExact = false
|
62
|
+
result.resultElements = [resultElement]
|
63
|
+
result.searchQuery = "http://www.google.com/search?q=ruby+on+rails"
|
64
|
+
result.startIndex = start
|
65
|
+
result.endIndex = start + maxResults
|
66
|
+
result.searchTips = "\"on\" is a very common word and was not included in your search [details]"
|
67
|
+
result.searchTime = 0.000001
|
68
|
+
|
69
|
+
# For Mono, we have to clone objects if they're referenced by more than one place, otherwise
|
70
|
+
# the Ruby SOAP collapses them into one instance and uses references all over the
|
71
|
+
# place, confusing Mono
|
72
|
+
result.directoryCategories = [
|
73
|
+
category("Web Development", "UTF-8"),
|
74
|
+
category("Programming", "US-ASCII"),
|
75
|
+
]
|
76
|
+
|
77
|
+
result
|
78
|
+
end
|
79
|
+
|
80
|
+
def category(name, encoding)
|
81
|
+
cat = DirectoryCategory.new
|
82
|
+
cat.fullViewableName = name.dup
|
83
|
+
cat.specialEncoding = encoding.dup
|
84
|
+
cat
|
85
|
+
end
|
86
|
+
|
87
|
+
export :doGetCachedPage, :returns => [String], :expects => [String, String]
|
88
|
+
export :doGetSpellingSuggestion, :returns => [String], :expects => [String, String]
|
89
|
+
export :doGoogleSearch, :returns => [GoogleSearchResult], :expects => [String, String, Integer, Integer, TrueClass, String, TrueClass, String, String, String]
|
90
|
+
end
|