wreckster 1.0.0

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/.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