wreckster 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.autotest ADDED
@@ -0,0 +1,23 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'autotest/restart'
4
+
5
+ # Autotest.add_hook :initialize do |at|
6
+ # at.extra_files << "../some/external/dependency.rb"
7
+ #
8
+ # at.libs << ":../some/external"
9
+ #
10
+ # at.add_exception 'vendor'
11
+ #
12
+ # at.add_mapping(/dependency.rb/) do |f, _|
13
+ # at.files_matching(/test_.*rb$/)
14
+ # end
15
+ #
16
+ # %w(TestA TestB).each do |klass|
17
+ # at.extra_class_map[klass] = "test/test_misc.rb"
18
+ # end
19
+ # end
20
+
21
+ # Autotest.add_hook :run_command do |at|
22
+ # system "rake build"
23
+ # end
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,6 @@
1
+ === 1.0.0 / 2010-05-26
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday!
6
+
data/Manifest.txt ADDED
@@ -0,0 +1,12 @@
1
+ .autotest
2
+ CHANGELOG.rdoc
3
+ Manifest.txt
4
+ README.rdoc
5
+ Rakefile
6
+ lib/wreckster.rb
7
+ lib/wreckster/graph.rb
8
+ lib/wreckster/object.rb
9
+ lib/wreckster/traversal.rb
10
+ test/helper.rb
11
+ test/test_object.rb
12
+ test/test_wreckster.rb
data/README.rdoc ADDED
@@ -0,0 +1,63 @@
1
+ = wreckster
2
+
3
+ * http://github.com/tenderlove/wreckster
4
+
5
+ == DESCRIPTION:
6
+
7
+ Wreckster is an API for accessing
8
+ Rexster[http://wiki.github.com/tinkerpop/rexster/].
9
+
10
+ == FEATURES/PROBLEMS:
11
+
12
+ * Lists graph traversals
13
+ * Accesses Rank based traversals
14
+
15
+
16
+ == SYNOPSIS:
17
+
18
+ graph = Wreckster::Graph.new('http://localhost:8182/')
19
+
20
+ # List the traversals available in this graph server
21
+ graph.traversals.each do |t|
22
+ puts t.name
23
+ end
24
+
25
+ # Execute a traversal with some parameters
26
+ traversal = graph.traversals.first
27
+ traversal.find('song.name' => 'SUGAREE').each do |song|
28
+ p song
29
+ end
30
+
31
+ == REQUIREMENTS:
32
+
33
+ * json
34
+ * net-http-persistent
35
+
36
+ == INSTALL:
37
+
38
+ * sudo gem install wreckster
39
+
40
+ == LICENSE:
41
+
42
+ (The MIT License)
43
+
44
+ Copyright (c) 2010 Aaron Patterson
45
+
46
+ Permission is hereby granted, free of charge, to any person obtaining
47
+ a copy of this software and associated documentation files (the
48
+ 'Software'), to deal in the Software without restriction, including
49
+ without limitation the rights to use, copy, modify, merge, publish,
50
+ distribute, sublicense, and/or sell copies of the Software, and to
51
+ permit persons to whom the Software is furnished to do so, subject to
52
+ the following conditions:
53
+
54
+ The above copyright notice and this permission notice shall be
55
+ included in all copies or substantial portions of the Software.
56
+
57
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
58
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
59
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
60
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
61
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
62
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
63
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+
6
+ Hoe.spec 'wreckster' do
7
+ developer('Aaron Patterson', 'aaron@tenderlovemaking.com')
8
+ self.readme_file = 'README.rdoc'
9
+ self.history_file = 'CHANGELOG.rdoc'
10
+ self.extra_rdoc_files = FileList['*.rdoc']
11
+ self.extra_deps << ['net-http-persistent', '~> 1.2.1']
12
+ self.extra_deps << ['json', '>= 0']
13
+ end
14
+
15
+ # vim: syntax=ruby
data/lib/wreckster.rb ADDED
@@ -0,0 +1,16 @@
1
+ require 'json'
2
+ require 'net/http'
3
+ require 'net/http/persistent'
4
+ require 'uri'
5
+ require 'wreckster/graph'
6
+ require 'wreckster/traversal'
7
+ require 'wreckster/object'
8
+
9
+ module Wreckster
10
+ VERSION = '1.0.0'
11
+
12
+ @connection = Net::HTTP::Persistent.new
13
+ class << self
14
+ attr_accessor :connection
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ module Wreckster
2
+ class Graph
3
+ def initialize url
4
+ @url = url
5
+ @payload = nil
6
+ end
7
+
8
+ def traversals
9
+ t = payload['traversals']
10
+ t = t.keys if Hash === t
11
+ t.map { |name| Traversal.new(@url, name) }
12
+ end
13
+
14
+ private
15
+ def payload
16
+ @payload ||= JSON.parse Wreckster.connection.request(URI.parse(@url)).body
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,22 @@
1
+ module Wreckster
2
+ class Object
3
+ attr_reader :identifier, :rank, :type
4
+
5
+ def initialize traversal, properties
6
+ @traversal = traversal
7
+ @properties = properties
8
+ @identifier = properties['_id']
9
+ @rank = properties[traversal]
10
+ @type = properties['type']
11
+ end
12
+
13
+ def respond_to? key
14
+ @properties.key?(key.to_s) || super
15
+ end
16
+
17
+ def method_missing key, *args
18
+ return super unless respond_to? key
19
+ @properties[key.to_s]
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,26 @@
1
+ module Wreckster
2
+ class Traversal
3
+ attr_reader :name
4
+
5
+ def initialize base, name
6
+ @base = base
7
+ @name = name
8
+ end
9
+
10
+ def find options = {}
11
+ params = options.map { |k,v| "#{k}=#{v}" }.join("&")
12
+ map = JSON.parse(
13
+ Wreckster.connection.request(URI.parse(url + "?#{params}")).body
14
+ )
15
+ map['ranks'].map { |thing| Wreckster::Object.new(name, thing) }
16
+ end
17
+
18
+ def info
19
+ JSON.parse Net::HTTP.get(URI.parse(url))
20
+ end
21
+
22
+ def url
23
+ @base + @name
24
+ end
25
+ end
26
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,21 @@
1
+ require "test/unit"
2
+ require "wreckster"
3
+
4
+ module Wreckster
5
+ class FakeConnector
6
+ attr_accessor :last_url, :responses
7
+
8
+ def initialize
9
+ @last_url = nil
10
+ @responses = []
11
+ end
12
+
13
+ def request url
14
+ @last_url = url
15
+ @responses.pop
16
+ end
17
+
18
+ end
19
+ Response = Struct.new(:body)
20
+ Wreckster.connection = FakeConnector.new
21
+ end
@@ -0,0 +1,32 @@
1
+ require 'helper'
2
+
3
+ module Wreckster
4
+ class TestObject < Test::Unit::TestCase
5
+ def test_identifier
6
+ obj = Wreckster::Object.new 'foo', '_id' => 100
7
+ assert_equal 100, obj.identifier
8
+ end
9
+
10
+ def test_rank
11
+ obj = Wreckster::Object.new 'foo', 'foo' => 100
12
+ assert_equal 100, obj.rank
13
+ end
14
+
15
+ def test_type
16
+ obj = Wreckster::Object.new 'foo', 'type' => 'america'
17
+ assert_equal 'america', obj.type
18
+ end
19
+
20
+ def test_responds_to?
21
+ obj = Wreckster::Object.new 'foo', 'hello' => 'world'
22
+ assert obj.respond_to?(:hello), 'responds to hello'
23
+ assert !obj.respond_to?(:world), 'does not respond to world'
24
+ end
25
+
26
+ def test_method_missing
27
+ obj = Wreckster::Object.new 'foo', 'hello' => 'world'
28
+ assert_equal 'world', obj.hello
29
+ assert_raises(NoMethodError) { obj.world }
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,48 @@
1
+ require 'helper'
2
+
3
+ module Wreckster
4
+ class TestWreckster < Test::Unit::TestCase
5
+ def setup
6
+ @url = 'http://localhost:8182/'
7
+ end
8
+
9
+ def test_traversals
10
+ conn.responses << Response.new(traversal_response)
11
+
12
+ graph = Wreckster::Graph.new('http://localhost:8182/')
13
+ traversals = graph.traversals
14
+ assert_equal 5, traversals.length
15
+ assert_equal 0, conn.responses.length
16
+
17
+ response = JSON.parse traversal_response
18
+ assert_equal response['traversals'].sort, traversals.map { |t| t.name }.sort
19
+ end
20
+
21
+ def test_traversal
22
+ conn.responses << Response.new(find_response)
23
+
24
+ t = Wreckster::Traversal.new @url, 'grateful/co-follows-rank'
25
+ objs = t.find('song.name' => 'SUGAREE', 'offset.end' => 2)
26
+
27
+ assert_equal 2, objs.length
28
+ assert_equal %w{ song song }, objs.map { |o| o.type }
29
+ assert_equal [5.0, 8.0], objs.map { |o| o.rank }
30
+ end
31
+
32
+ def conn
33
+ Wreckster.connection
34
+ end
35
+
36
+ def traversal_response
37
+ <<-eojson
38
+ {"query_time":0,"name":"Wreckster: A Graph-Based Ranking Engine","up_time":"0[d]:00[h]:54[m]:43[s]","traversals":["grateful\/singer-writer-rank","grateful\/follows-score","grateful\/co-follows-rank","gremlin","grateful\/artist-rank"]}
39
+ eojson
40
+ end
41
+
42
+ def find_response
43
+ <<-eojson
44
+ {"ranks":[{"grateful\/co-follows-rank":5.0,"_id":"35","name":"WAY TO GO HOME","song_type":"original","performances":92,"type":"song"},{"grateful\/co-follows-rank":8.0,"_id":"36","name":"SAINT OF CIRCUMSTANCE","song_type":"original","performances":222,"type":"song"}],"query_time":1,"success":true,"size":2,"total_rank":2777.0}
45
+ eojson
46
+ end
47
+ end
48
+ end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wreckster
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 0
8
+ - 0
9
+ version: 1.0.0
10
+ platform: ruby
11
+ authors:
12
+ - Aaron Patterson
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-06-01 00:00:00 -07:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: net-http-persistent
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 1
29
+ - 2
30
+ - 1
31
+ version: 1.2.1
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: json
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ type: :runtime
45
+ version_requirements: *id002
46
+ - !ruby/object:Gem::Dependency
47
+ name: rubyforge
48
+ prerelease: false
49
+ requirement: &id003 !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ segments:
54
+ - 2
55
+ - 0
56
+ - 4
57
+ version: 2.0.4
58
+ type: :development
59
+ version_requirements: *id003
60
+ - !ruby/object:Gem::Dependency
61
+ name: hoe
62
+ prerelease: false
63
+ requirement: &id004 !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ segments:
68
+ - 2
69
+ - 6
70
+ - 0
71
+ version: 2.6.0
72
+ type: :development
73
+ version_requirements: *id004
74
+ description: |-
75
+ Wreckster is an API for accessing
76
+ Rexster[http://wiki.github.com/tinkerpop/rexster/].
77
+ email:
78
+ - aaron@tenderlovemaking.com
79
+ executables: []
80
+
81
+ extensions: []
82
+
83
+ extra_rdoc_files:
84
+ - Manifest.txt
85
+ - CHANGELOG.rdoc
86
+ - README.rdoc
87
+ files:
88
+ - .autotest
89
+ - CHANGELOG.rdoc
90
+ - Manifest.txt
91
+ - README.rdoc
92
+ - Rakefile
93
+ - lib/wreckster.rb
94
+ - lib/wreckster/graph.rb
95
+ - lib/wreckster/object.rb
96
+ - lib/wreckster/traversal.rb
97
+ - test/helper.rb
98
+ - test/test_object.rb
99
+ - test/test_wreckster.rb
100
+ has_rdoc: true
101
+ homepage: http://github.com/tenderlove/wreckster
102
+ licenses: []
103
+
104
+ post_install_message:
105
+ rdoc_options:
106
+ - --main
107
+ - README.rdoc
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ segments:
115
+ - 0
116
+ version: "0"
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ segments:
122
+ - 0
123
+ version: "0"
124
+ requirements: []
125
+
126
+ rubyforge_project: wreckster
127
+ rubygems_version: 1.3.6
128
+ signing_key:
129
+ specification_version: 3
130
+ summary: Wreckster is an API for accessing Rexster[http://wiki.github.com/tinkerpop/rexster/].
131
+ test_files:
132
+ - test/test_object.rb
133
+ - test/test_wreckster.rb