thingiverse 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/lib/thingiverse.rb CHANGED
@@ -2,10 +2,10 @@ require 'rubygems'
2
2
  require 'json'
3
3
  require 'httparty'
4
4
  require 'curb'
5
- require 'active_model'
6
5
  require 'cgi'
7
6
  require 'uri'
8
7
 
8
+ require 'thingiverse/dynamic_attributes'
9
9
  require 'thingiverse/connection'
10
10
  require 'thingiverse/pagination'
11
11
  require 'thingiverse/things'
@@ -16,5 +16,5 @@ require 'thingiverse/categories'
16
16
  require 'thingiverse/tags'
17
17
 
18
18
  module Thingiverse
19
- VERSION = '0.0.6'
19
+ VERSION = '0.0.7'
20
20
  end
@@ -1,22 +1,6 @@
1
1
  module Thingiverse
2
2
  class Categories
3
- include ActiveModel::Validations
4
- validates_presence_of :name
3
+ include Thingiverse::DynamicAttributes
5
4
 
6
- attr_accessor :name, :url, :count, :things_url
7
- def initialize(attributes={})
8
- attributes.each do |name, value|
9
- send("#{name}=", value)
10
- end
11
- end
12
-
13
- def attributes
14
- {
15
- :name => name,
16
- :url => url,
17
- :count => count,
18
- :things_url => things_url
19
- }
20
- end
21
5
  end
22
6
  end
@@ -0,0 +1,33 @@
1
+ module Thingiverse
2
+ module DynamicAttributes
3
+ def eigenclass
4
+ class << self; self; end
5
+ end
6
+
7
+ attr_reader :attributes
8
+
9
+ def initialize(attributes={})
10
+ @attributes = attributes
11
+ @attributes.each do |k,v|
12
+ add_attribute(k, v)
13
+ end
14
+ end
15
+
16
+ def method_missing(method_sym, *arguments, &block)
17
+ method = (method_sym.instance_of? Symbol) ? method_sym.to_s : method_sym.clone
18
+
19
+ if method.end_with? "="
20
+ method.chomp! "="
21
+ @attributes[method] = arguments[0]
22
+ add_attribute(method, arguments[0])
23
+ else
24
+ super(method_sym, *arguments, &block)
25
+ end
26
+ end
27
+
28
+ def add_attribute(name, value)
29
+ eigenclass.class_eval{ attr_reader name.to_sym }
30
+ instance_variable_set("@#{name}", value)
31
+ end
32
+ end
33
+ end
@@ -1,25 +1,6 @@
1
1
  module Thingiverse
2
2
  class Files
3
- include ActiveModel::Validations
4
- validates_presence_of :name
3
+ include Thingiverse::DynamicAttributes
5
4
 
6
- attr_accessor :id, :name, :thumbnail, :url, :public_url, :threejs_url, :download_url
7
- def initialize(attributes={})
8
- attributes.each do |name, value|
9
- send("#{name}=", value)
10
- end
11
- end
12
-
13
- def attributes
14
- {
15
- :id => id,
16
- :name => name,
17
- :thumbnail => thumbnail,
18
- :url => url,
19
- :public_url => public_url,
20
- :threejs_url => threejs_url,
21
- :download_url => download_url
22
- }
23
- end
24
5
  end
25
6
  end
@@ -1,22 +1,6 @@
1
1
  module Thingiverse
2
2
  class Images
3
- include ActiveModel::Validations
4
- validates_presence_of :name
3
+ include Thingiverse::DynamicAttributes
5
4
 
6
- attr_accessor :id, :name, :url, :sizes
7
- def initialize(attributes={})
8
- attributes.each do |name, value|
9
- send("#{name}=", value)
10
- end
11
- end
12
-
13
- def attributes
14
- {
15
- :id => id,
16
- :name => name,
17
- :url => url,
18
- :sizes => sizes
19
- }
20
- end
21
5
  end
22
6
  end
@@ -1,24 +1,7 @@
1
1
  module Thingiverse
2
2
  class Tags
3
- include ActiveModel::Validations
4
- validates_presence_of :name
3
+ include Thingiverse::DynamicAttributes
5
4
 
6
- attr_accessor :name, :url, :count, :things_url
7
- def initialize(attributes={})
8
- attributes.each do |name, value|
9
- send("#{name}=", value)
10
- end
11
- end
12
-
13
- def attributes
14
- {
15
- :name => name,
16
- :url => url,
17
- :count => count,
18
- :things_url => things_url
19
- }
20
- end
21
-
22
5
  def self.find(tag_name)
23
6
  response = Thingiverse::Connection.get("/tags/#{tag_name}")
24
7
  raise "#{response.code}: #{JSON.parse(response.body)['error']}" unless response.success?
@@ -1,48 +1,6 @@
1
1
  module Thingiverse
2
2
  class Things
3
- include ActiveModel::Validations
4
- validates_presence_of :name
5
-
6
- attr_accessor :id, :name, :thumbnail, :url, :public_url, :creator, :added, :modified, :is_published, :is_wip
7
- attr_accessor :ratings_enabled, :like_count, :description, :instructions, :license
8
- attr_accessor :files_url, :images_url, :likes_url, :ancestors_url, :derivatives_url, :tags_url, :categories_url
9
- attr_accessor :category, :ancestors, :tags
10
-
11
- def initialize(params={})
12
- params.each do |name, value|
13
- send("#{name}=", value)
14
- end
15
- end
16
-
17
- def attributes
18
- {
19
- :id => id.to_s,
20
- :name => name.to_s,
21
- :thumbnail => thumbnail.to_s,
22
- :url => url.to_s,
23
- :public_url => public_url.to_s,
24
- :creator => creator.to_s,
25
- :added => added.to_s,
26
- :modified => modified.to_s,
27
- :is_published => is_published != true ? false : true,
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,
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,
40
- :categories_url => categories_url.to_s,
41
- :category => category.to_s,
42
- :ancestors => ancestors || [],
43
- :tags => tags || []
44
- }
45
- end
3
+ include Thingiverse::DynamicAttributes
46
4
 
47
5
  def user
48
6
  response = Thingiverse::Connection.get("/users/#{creator['name']}")
@@ -62,12 +20,11 @@ module Thingiverse
62
20
  Thingiverse::Pagination.new(Thingiverse::Connection.get(@categories_url, :query => query), Thingiverse::Categories)
63
21
  end
64
22
 
65
- def parents(query = {})
23
+ def ancestors(query = {})
66
24
  Thingiverse::Pagination.new(Thingiverse::Connection.get(@ancestors_url, :query => query), Thingiverse::Things)
67
25
  end
68
26
 
69
- # TODO: this is a dumb name, come up with a better way to set/retrieve
70
- def tag_records
27
+ def tags
71
28
  response = Thingiverse::Connection.get(tags_url)
72
29
  raise "#{response.code}: #{JSON.parse(response.body)['error']}" unless response.success?
73
30
  response.parsed_response.collect do |attrs|
@@ -76,12 +33,10 @@ module Thingiverse
76
33
  end
77
34
 
78
35
  def save
79
- if id.to_s == ""
80
- thing = Thingiverse::Things.create(attributes)
36
+ if @id.to_s == ""
37
+ thing = Thingiverse::Things.create(@attributes)
81
38
  else
82
- raise "Invalid Parameters" unless self.valid?
83
-
84
- response = Thingiverse::Connection.patch("/things/#{id}", :body => attributes.to_json)
39
+ response = Thingiverse::Connection.patch("/things/#{id}", :body => @attributes.to_json)
85
40
  raise "#{response.code}: #{JSON.parse(response.body)['error']}" unless response.success?
86
41
 
87
42
  thing = Thingiverse::Things.new(response.parsed_response)
@@ -91,15 +46,28 @@ module Thingiverse
91
46
  send("#{name}=", value)
92
47
  end
93
48
  end
94
-
95
- def upload(file)
96
- response = Thingiverse::Connection.post("/things/#{id}/files", :body => {:filename => File.basename(file.path)}.to_json)
49
+
50
+ # file_or_string can be a File or a String.
51
+ # thingiverse_filename is optional if using a File (the File filename will be used by default) but is required if using a String
52
+ def upload(file_or_string, thingiverse_filename=nil)
53
+ # to support different File type objects (like Tempfile) lets look for .path
54
+ if file_or_string.respond_to?("path")
55
+ thingiverse_filename = File.basename(file_or_string.path) if thingiverse_filename.to_s == ""
56
+ file_data = File.read(file_or_string.path)
57
+ elsif file_or_string.is_a?(String)
58
+ file_data = file_or_string
59
+ else
60
+ raise ArgumentError, "file_or_string not of accepted type. Expected File or String. Actual: #{file_or_string.class}"
61
+ end
62
+
63
+ raise ArgumentError, "Unable to determine filename" if thingiverse_filename.to_s == ""
64
+
65
+ response = Thingiverse::Connection.post("/things/#{id}/files", :body => {:filename => thingiverse_filename}.to_json)
97
66
  raise "#{response.code}: #{JSON.parse(response.body)['error']} #{response.headers['x-error']}" unless response.success?
98
67
 
99
68
  parsed_response = JSON.parse(response.body)
100
69
  action = parsed_response["action"]
101
70
  query = parsed_response["fields"]
102
- query["file"] = file
103
71
 
104
72
  # stupid S3 requires params to be in a certain order... so can't use HTTParty :(
105
73
  # prepare post data
@@ -114,7 +82,7 @@ module Thingiverse
114
82
  post_data << Curl::PostField.content('Content-Type', query['Content-Type'])
115
83
  post_data << Curl::PostField.content('Content-Disposition', query['Content-Disposition'])
116
84
 
117
- post_data << Curl::PostField.file('file', file.path)
85
+ post_data << Curl::PostField.file('file', thingiverse_filename) { file_data }
118
86
 
119
87
  # post
120
88
  c = Curl::Easy.new(action) do |curl|
@@ -136,7 +104,7 @@ module Thingiverse
136
104
  end
137
105
 
138
106
  def publish
139
- if id.to_s == ""
107
+ if @id.to_s == ""
140
108
  raise "Cannot publish until thing is saved"
141
109
  else
142
110
  response = Thingiverse::Connection.post("/things/#{id}/publish")
@@ -162,7 +130,6 @@ module Thingiverse
162
130
 
163
131
  def self.create(params)
164
132
  thing = self.new(params)
165
- raise "Invalid Parameters" unless thing.valid?
166
133
 
167
134
  response = Thingiverse::Connection.post('/things', :body => thing.attributes.to_json)
168
135
  raise "#{response.code}: #{JSON.parse(response.body)['error']} #{response.headers['x-error']}" unless response.success?
@@ -1,41 +1,7 @@
1
1
  module Thingiverse
2
2
  class Users
3
- include ActiveModel::Validations
4
- validates_presence_of :name
5
-
6
- attr_accessor :id, :name, :full_name, :thumbnail, :url, :public_url, :bio, :location, :registered, :last_active
7
- attr_accessor :email, :default_license, :is_following
8
- attr_accessor :things_url, :copies_url, :likes_url, :downloads_url, :collections_url
9
-
10
- def initialize(attributes={})
11
- attributes.each do |name, value|
12
- send("#{name}=", value)
13
- end
14
- end
15
-
16
- def attributes
17
- {
18
- :id => id,
19
- :name => name,
20
- :full_name => full_name,
21
- :thumbnail => thumbnail,
22
- :url => url,
23
- :public_url => public_url,
24
- :bio => bio,
25
- :location => location,
26
- :registered => registered,
27
- :last_active => last_active,
28
- :things_url => things_url,
29
- :copies_url => copies_url,
30
- :likes_url => likes_url,
31
- :email => email,
32
- :default_license => default_license,
33
- :downloads_url => downloads_url,
34
- :collections_url => collections_url,
35
- :is_following => is_following
36
- }
37
- end
38
-
3
+ include Thingiverse::DynamicAttributes
4
+
39
5
  def self.find(user_name)
40
6
  response = Thingiverse::Connection.get("/users/#{user_name}")
41
7
  raise "#{response.code}: #{JSON.parse(response.body)['error']}" unless response.success?
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: 19
4
+ hash: 17
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 6
10
- version: 0.0.6
9
+ - 7
10
+ version: 0.0.7
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-04-15 00:00:00 Z
18
+ date: 2013-05-02 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: json
@@ -59,20 +59,6 @@ dependencies:
59
59
  version: "0"
60
60
  type: :runtime
61
61
  version_requirements: *id003
62
- - !ruby/object:Gem::Dependency
63
- name: activemodel
64
- prerelease: false
65
- requirement: &id004 !ruby/object:Gem::Requirement
66
- none: false
67
- requirements:
68
- - - ">="
69
- - !ruby/object:Gem::Version
70
- hash: 3
71
- segments:
72
- - 0
73
- version: "0"
74
- type: :runtime
75
- version_requirements: *id004
76
62
  description: Thingiverse API
77
63
  email: tony@makerbot.com
78
64
  executables: []
@@ -84,6 +70,7 @@ extra_rdoc_files: []
84
70
  files:
85
71
  - lib/thingiverse/categories.rb
86
72
  - lib/thingiverse/connection.rb
73
+ - lib/thingiverse/dynamic_attributes.rb
87
74
  - lib/thingiverse/files.rb
88
75
  - lib/thingiverse/images.rb
89
76
  - lib/thingiverse/pagination.rb