thingiverse 0.0.2 → 0.0.5

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