thingiverse 0.0.2 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/lib/thingiverse.rb CHANGED
@@ -4,8 +4,10 @@ require 'httparty'
4
4
  require 'curb'
5
5
  require 'active_model'
6
6
  require 'cgi'
7
+ require 'uri'
7
8
 
8
9
  require 'thingiverse/connection'
10
+ require 'thingiverse/pagination'
9
11
  require 'thingiverse/things'
10
12
  require 'thingiverse/files'
11
13
  require 'thingiverse/users'
@@ -14,5 +16,5 @@ require 'thingiverse/categories'
14
16
  require 'thingiverse/tags'
15
17
 
16
18
  module Thingiverse
17
- VERSION = '0.0.2'
19
+ VERSION = '0.0.5'
18
20
  end
@@ -9,7 +9,7 @@ module Thingiverse
9
9
  send("#{name}=", value)
10
10
  end
11
11
  end
12
-
12
+
13
13
  def attributes
14
14
  {
15
15
  :name => name,
@@ -3,14 +3,14 @@ module Thingiverse
3
3
  include HTTParty
4
4
  # debug_output $stderr
5
5
  attr_accessor :client_id, :client_secret, :code, :access_token, :auth_url, :base_url
6
-
6
+
7
7
  def initialize(client_id = nil, client_secret = nil, code = nil)
8
8
  @client_id = client_id
9
9
  @client_secret = client_secret
10
10
  @code = code
11
-
11
+
12
12
  self.class.base_uri(self.base_url)
13
-
13
+
14
14
  self.get_token if @client_id and @client_secret and @code
15
15
  end
16
16
 
@@ -33,7 +33,7 @@ module Thingiverse
33
33
  end
34
34
 
35
35
  def get_token
36
- auth_response = self.class.post(@auth_url, :query => {:client_id => @client_id, :client_secret => @client_secret, :code => @code})
36
+ auth_response = self.class.post(auth_url, :query => {:client_id => @client_id, :client_secret => @client_secret, :code => @code})
37
37
 
38
38
  raise "#{auth_response.code}: #{auth_response.body.inspect}" unless auth_response.success?
39
39
 
@@ -45,7 +45,7 @@ module Thingiverse
45
45
 
46
46
  @access_token
47
47
  end
48
-
48
+
49
49
  def things
50
50
  Thingiverse::Things
51
51
  end
@@ -53,5 +53,9 @@ module Thingiverse
53
53
  def users
54
54
  Thingiverse::Users
55
55
  end
56
+
57
+ def tags
58
+ Thingiverse::Tags
59
+ end
56
60
  end
57
61
  end
@@ -3,21 +3,22 @@ module Thingiverse
3
3
  include ActiveModel::Validations
4
4
  validates_presence_of :name
5
5
 
6
- attr_accessor :id, :name, :thumbnail, :url, :public_url, :threejs_url
6
+ attr_accessor :id, :name, :thumbnail, :url, :public_url, :threejs_url, :download_url
7
7
  def initialize(attributes={})
8
8
  attributes.each do |name, value|
9
9
  send("#{name}=", value)
10
10
  end
11
11
  end
12
-
12
+
13
13
  def attributes
14
14
  {
15
15
  :id => id,
16
16
  :name => name,
17
17
  :thumbnail => thumbnail,
18
18
  :url => url,
19
- :public_url => public_url,
20
- :threejs_url => threejs_url
19
+ :public_url => public_url,
20
+ :threejs_url => threejs_url,
21
+ :download_url => download_url
21
22
  }
22
23
  end
23
24
  end
@@ -9,7 +9,7 @@ module Thingiverse
9
9
  send("#{name}=", value)
10
10
  end
11
11
  end
12
-
12
+
13
13
  def attributes
14
14
  {
15
15
  :id => id,
@@ -0,0 +1,59 @@
1
+ module Thingiverse
2
+ require "forwardable"
3
+
4
+ class Pagination
5
+ include Enumerable
6
+ extend Forwardable
7
+
8
+ attr_reader :response, :object
9
+ attr_reader :current_page, :total_pages, :first_url, :last_url, :next_url, :prev_url
10
+
11
+ def initialize(response, object)
12
+ @response = response
13
+ @object = object
14
+
15
+ # TODO: provide more debug info and raise a custom exception
16
+ raise "#{@response.code}: #{JSON.parse(@response.body)['error']}" unless @response.success?
17
+
18
+ @objects = @response.parsed_response.collect do |attrs|
19
+ @object.new attrs
20
+ end
21
+
22
+ if @response.headers.include?("link")
23
+ @response.headers["link"].split(",").each do |link|
24
+ url, rel = link.split(";").collect{|p| p.gsub(/\<|\>|rel\=|\"/,'').strip}
25
+ instance_variable_set("@#{rel}_url", url)
26
+ url_params = CGI.parse(URI.parse(url).query.to_s)
27
+
28
+ case rel
29
+ when "last"
30
+ @total_pages = url_params["page"][0].to_i
31
+ when "next"
32
+ @current_page = url_params["page"][0].to_i - 1
33
+ when "prev"
34
+ @current_page = url_params["page"][0].to_i + 1
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ def_delegators :@objects, :<<, :[], :[]=, :last, :size
41
+
42
+ def method_missing(meth, *args, &block)
43
+ if meth.to_s =~ /^(.*)_page$/
44
+ get_url_page($1, *args, &block)
45
+ else
46
+ super
47
+ end
48
+ end
49
+
50
+ def get_url_page(which, *args, &block)
51
+ url = instance_variable_get("@#{which}_url")
52
+ Thingiverse::Pagination.new(Thingiverse::Connection.get(url), @object) if url
53
+ end
54
+
55
+ def each(&block)
56
+ @objects.each(&block)
57
+ end
58
+ end
59
+ end
@@ -3,19 +3,30 @@ module Thingiverse
3
3
  include ActiveModel::Validations
4
4
  validates_presence_of :name
5
5
 
6
- attr_accessor :name, :url, :count
6
+ attr_accessor :name, :url, :count, :things_url
7
7
  def initialize(attributes={})
8
8
  attributes.each do |name, value|
9
9
  send("#{name}=", value)
10
10
  end
11
11
  end
12
-
12
+
13
13
  def attributes
14
14
  {
15
15
  :name => name,
16
16
  :url => url,
17
- :count => count
17
+ :count => count,
18
+ :things_url => things_url
18
19
  }
19
20
  end
21
+
22
+ def self.find(tag_name)
23
+ response = Thingiverse::Connection.get("/tags/#{tag_name}")
24
+ raise "#{response.code}: #{JSON.parse(response.body)['error']}" unless response.success?
25
+ self.new response.parsed_response
26
+ end
27
+
28
+ def things(query = {})
29
+ Thingiverse::Pagination.new(Thingiverse::Connection.get(things_url, :query => query), Thingiverse::Things)
30
+ end
20
31
  end
21
32
  end
@@ -7,36 +7,36 @@ module Thingiverse
7
7
  attr_accessor :ratings_enabled, :like_count, :description, :instructions, :license
8
8
  attr_accessor :files_url, :images_url, :likes_url, :ancestors_url, :derivatives_url, :tags_url, :categories_url
9
9
  attr_accessor :category, :ancestors, :tags
10
-
10
+
11
11
  def initialize(params={})
12
12
  params.each do |name, value|
13
13
  send("#{name}=", value)
14
14
  end
15
15
  end
16
-
16
+
17
17
  def attributes
18
18
  {
19
19
  :id => id.to_s,
20
20
  :name => name.to_s,
21
21
  :thumbnail => thumbnail.to_s,
22
22
  :url => url.to_s,
23
- :public_url => public_url.to_s,
24
- :creator => creator.to_s,
25
- :added => added.to_s,
23
+ :public_url => public_url.to_s,
24
+ :creator => creator.to_s,
25
+ :added => added.to_s,
26
26
  :modified => modified.to_s,
27
- :is_published => is_published != true ? false : true,
27
+ :is_published => is_published != true ? false : true,
28
28
  :is_wip => is_wip != true ? false : true,
29
- :ratings_enabled => ratings_enabled != true ? false : true,
30
- :like_count => like_count.to_s,
31
- :description => description.to_s,
32
- :instructions => instructions.to_s,
33
- :license => license.to_s,
34
- :files_url => files_url.to_s,
35
- :images_url => images_url.to_s,
29
+ :ratings_enabled => ratings_enabled != true ? false : true,
30
+ :like_count => like_count.to_s,
31
+ :description => description.to_s,
32
+ :instructions => instructions.to_s,
33
+ :license => license.to_s,
34
+ :files_url => files_url.to_s,
35
+ :images_url => images_url.to_s,
36
36
  :likes_url => likes_url.to_s,
37
- :ancestors_url => ancestors_url.to_s,
38
- :derivatives_url => derivatives_url.to_s,
39
- :tags_url => tags_url.to_s,
37
+ :ancestors_url => ancestors_url.to_s,
38
+ :derivatives_url => derivatives_url.to_s,
39
+ :tags_url => tags_url.to_s,
40
40
  :categories_url => categories_url.to_s,
41
41
  :category => category.to_s,
42
42
  :ancestors => ancestors || [],
@@ -50,37 +50,20 @@ module Thingiverse
50
50
  Thingiverse::Users.new response.parsed_response
51
51
  end
52
52
 
53
- def files
54
- response = Thingiverse::Connection.get(files_url)
55
- raise "#{response.code}: #{JSON.parse(response.body)['error']}" unless response.success?
56
- response.parsed_response.collect do |attrs|
57
- Thingiverse::Files.new attrs
58
- end
53
+ def files(query = {})
54
+ Thingiverse::Pagination.new(Thingiverse::Connection.get(@files_url, :query => query), Thingiverse::Files)
59
55
  end
60
56
 
61
- def images
62
- response = Thingiverse::Connection.get(images_url)
63
- raise "#{response.code}: #{JSON.parse(response.body)['error']}" unless response.success?
64
- response.parsed_response.collect do |attrs|
65
- Thingiverse::Images.new attrs
66
- end
57
+ def images(query = {})
58
+ Thingiverse::Pagination.new(Thingiverse::Connection.get(@images_url, :query => query), Thingiverse::Images)
67
59
  end
68
60
 
69
- def categories
70
- response = Thingiverse::Connection.get(categories_url)
71
- raise "#{response.code}: #{JSON.parse(response.body)['error']}" unless response.success?
72
- response.parsed_response.collect do |attrs|
73
- Thingiverse::Categories.new attrs
74
- end
61
+ def categories(query = {})
62
+ Thingiverse::Pagination.new(Thingiverse::Connection.get(@categories_url, :query => query), Thingiverse::Categories)
75
63
  end
76
64
 
77
- # TODO: this is a dumb name, come up with a better way to set/retrieve
78
- def ancestor_things
79
- response = Thingiverse::Connection.get(ancestors_url)
80
- raise "#{response.code}: #{JSON.parse(response.body)['error']}" unless response.success?
81
- response.parsed_response.collect do |attrs|
82
- Thingiverse::Things.new attrs
83
- end
65
+ def parents(query = {})
66
+ Thingiverse::Pagination.new(Thingiverse::Connection.get(@ancestors_url, :query => query), Thingiverse::Things)
84
67
  end
85
68
 
86
69
  # TODO: this is a dumb name, come up with a better way to set/retrieve
@@ -103,7 +86,7 @@ module Thingiverse
103
86
 
104
87
  thing = Thingiverse::Things.new(response.parsed_response)
105
88
  end
106
-
89
+
107
90
  thing.attributes.each do |name, value|
108
91
  send("#{name}=", value)
109
92
  end
@@ -114,13 +97,13 @@ module Thingiverse
114
97
  raise "#{response.code}: #{JSON.parse(response.body)['error']} #{response.headers['x-error']}" unless response.success?
115
98
 
116
99
  parsed_response = JSON.parse(response.body)
117
- action = parsed_response["action"]
100
+ action = parsed_response["action"]
118
101
  query = parsed_response["fields"]
119
102
  query["file"] = file
120
103
 
121
- # stupid S3 requires params to be in a certain order... so can't use HTTParty :(
104
+ # stupid S3 requires params to be in a certain order... so can't use HTTParty :(
122
105
  # prepare post data
123
- post_data = []
106
+ post_data = []
124
107
  # TODO: is query['bucket'] needed here?
125
108
  post_data << Curl::PostField.content('key', query['key'])
126
109
  post_data << Curl::PostField.content('AWSAccessKeyId', query['AWSAccessKeyId'])
@@ -133,7 +116,7 @@ module Thingiverse
133
116
 
134
117
  post_data << Curl::PostField.file('file', file.path)
135
118
 
136
- # post
119
+ # post
137
120
  c = Curl::Easy.new(action) do |curl|
138
121
  # curl.verbose = true
139
122
  # can't follow redirect to finalize here because need to pass access_token for auth
@@ -161,30 +144,26 @@ module Thingiverse
161
144
 
162
145
  thing = Thingiverse::Things.new(response.parsed_response)
163
146
  end
164
-
147
+
165
148
  thing.attributes.each do |name, value|
166
149
  send("#{name}=", value)
167
150
  end
168
151
  end
169
-
152
+
170
153
  def self.find(thing_id)
171
154
  response = Thingiverse::Connection.get("/things/#{thing_id}")
172
155
  raise "#{response.code}: #{JSON.parse(response.body)['error']} #{response.headers['x-error']}" unless response.success?
173
156
  self.new response.parsed_response
174
157
  end
175
-
176
- def self.newest
177
- response = Thingiverse::Connection.get('/newest')
178
- raise "#{response.code}: #{JSON.parse(response.body)['error']}" unless response.success?
179
- response.parsed_response.collect do |attrs|
180
- self.new attrs
181
- end
158
+
159
+ def self.newest(query = {})
160
+ Thingiverse::Pagination.new(Thingiverse::Connection.get('/newest', :query => query), Thingiverse::Things)
182
161
  end
183
162
 
184
163
  def self.create(params)
185
164
  thing = self.new(params)
186
165
  raise "Invalid Parameters" unless thing.valid?
187
-
166
+
188
167
  response = Thingiverse::Connection.post('/things', :body => thing.attributes.to_json)
189
168
  raise "#{response.code}: #{JSON.parse(response.body)['error']} #{response.headers['x-error']}" unless response.success?
190
169
 
@@ -6,20 +6,20 @@ module Thingiverse
6
6
  attr_accessor :id, :name, :thumbnail, :url, :public_url, :bio, :location, :registered, :last_active
7
7
  attr_accessor :email, :default_license
8
8
  attr_accessor :things_url, :copies_url, :likes_url
9
-
9
+
10
10
  def initialize(attributes={})
11
11
  attributes.each do |name, value|
12
12
  send("#{name}=", value)
13
13
  end
14
14
  end
15
-
15
+
16
16
  def attributes
17
17
  {
18
18
  :id => id,
19
19
  :name => name,
20
20
  :thumbnail => thumbnail,
21
21
  :url => url,
22
- :public_url => public_url,
22
+ :public_url => public_url,
23
23
  :bio => bio,
24
24
  :location => location,
25
25
  :registered => registered,
@@ -31,7 +31,7 @@ module Thingiverse
31
31
  :default_license => default_license
32
32
  }
33
33
  end
34
-
34
+
35
35
  def self.find(user_name)
36
36
  response = Thingiverse::Connection.get("/users/#{user_name}")
37
37
  raise "#{response.code}: #{JSON.parse(response.body)['error']}" unless response.success?
data/test/test_helper.rb CHANGED
@@ -1 +1,9 @@
1
- $: << File.dirname(File.expand_path(__FILE__))+'/../lib'
1
+ $: << File.dirname(File.expand_path(__FILE__))+'/../lib'
2
+
3
+ THINGIVERSE_CLIENT_ID = ENV.fetch('THINGIVERSE_CLIENT_ID','6806845037e641ebaf75')
4
+ THINGIVERSE_SECRET = ENV.fetch('THINGIVERSE_SECRET','275908d8c6fa29900fd73199b1cea3b2')
5
+ THINGIVERSE_ACCESS_TOKEN = ENV.fetch('THINGIVERSE_ACCESS_TOKEN','d522b2638d92145e46bd6baf17555ca3')
6
+
7
+ THINGIVERSE_AUTH_URL = ENV.fetch('THINGIVERSE_AUTH_URL','http://thingiverse.dev:8888/login/oauth/access_token')
8
+
9
+ THINGIVERSE_BASE_URL = ENV.fetch('THINGIVERSE_BASE_URL','http://api.thingiverse.dev:8888')
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thingiverse
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 21
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 2
10
- version: 0.0.2
9
+ - 5
10
+ version: 0.0.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Tony Buser
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2013-01-09 00:00:00 Z
18
+ date: 2013-02-05 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: json
@@ -86,6 +86,7 @@ files:
86
86
  - lib/thingiverse/connection.rb
87
87
  - lib/thingiverse/files.rb
88
88
  - lib/thingiverse/images.rb
89
+ - lib/thingiverse/pagination.rb
89
90
  - lib/thingiverse/tags.rb
90
91
  - lib/thingiverse/things.rb
91
92
  - lib/thingiverse/users.rb