This repository was archived by the owner on Mar 31, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy paththings.rb
More file actions
141 lines (115 loc) · 5.31 KB
/
things.rb
File metadata and controls
141 lines (115 loc) · 5.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
module Thingiverse
class Things
include Thingiverse::DynamicAttributes
def user
response = Thingiverse::Connection.get("/users/#{creator['name']}")
raise ResponseError.new(response) unless response.success?
Thingiverse::Users.new response.parsed_response
end
def files(query = {})
Thingiverse::Pagination.new(Thingiverse::Connection.get(@files_url, :query => query), Thingiverse::Files)
end
def images(query = {})
Thingiverse::Pagination.new(Thingiverse::Connection.get(@images_url, :query => query), Thingiverse::Images)
end
def categories(query = {})
Thingiverse::Pagination.new(Thingiverse::Connection.get(@categories_url, :query => query), Thingiverse::Categories)
end
def ancestors(query = {})
Thingiverse::Pagination.new(Thingiverse::Connection.get(@ancestors_url, :query => query), Thingiverse::Things)
end
def tags
response = Thingiverse::Connection.get(tags_url)
raise ResponseError.new(response) unless response.success?
response.parsed_response.collect do |attrs|
Thingiverse::Tags.new attrs
end
end
def save
if @id.to_s == ""
thing = Thingiverse::Things.create(@attributes)
else
response = Thingiverse::Connection.patch("/things/#{id}", :body => @attributes.to_json)
raise ResponseError.new(response) unless response.success?
thing = Thingiverse::Things.new(response.parsed_response)
end
thing.attributes.each do |name, value|
send("#{name}=", value)
end
end
# file_or_string can be a File or a String.
# thingiverse_filename is optional if using a File (the File filename will be used by default) but is required if using a String
def upload(file_or_string, thingiverse_filename=nil)
# to support different File type objects (like Tempfile) lets look for .path
if file_or_string.respond_to?("path")
thingiverse_filename = File.basename(file_or_string.path) if thingiverse_filename.to_s == ""
file_data = File.read(file_or_string.path)
elsif file_or_string.is_a?(String)
file_data = file_or_string
else
raise ArgumentError, "file_or_string not of accepted type. Expected File or String. Actual: #{file_or_string.class}"
end
raise ArgumentError, "Unable to determine filename" if thingiverse_filename.to_s == ""
response = Thingiverse::Connection.post("/things/#{id}/files", :body => {:filename => thingiverse_filename}.to_json)
raise ResponseError.new(response) unless response.success?
parsed_response = JSON.parse(response.body)
action = parsed_response["action"]
query = parsed_response["fields"]
# stupid S3 requires params to be in a certain order... so can't use HTTParty :(
# prepare post data
post_data = []
# TODO: is query['bucket'] needed here?
post_data << Curl::PostField.content('key', query['key'])
post_data << Curl::PostField.content('AWSAccessKeyId', query['AWSAccessKeyId'])
post_data << Curl::PostField.content('acl', query['acl'])
post_data << Curl::PostField.content('success_action_redirect', query['success_action_redirect'])
post_data << Curl::PostField.content('policy', query['policy'])
post_data << Curl::PostField.content('signature', query['signature'])
post_data << Curl::PostField.content('Content-Type', query['Content-Type'])
post_data << Curl::PostField.content('Content-Disposition', query['Content-Disposition'])
post_data << Curl::PostField.file('file', thingiverse_filename) { file_data }
# post
c = Curl::Easy.new(action) do |curl|
# curl.verbose = true
# can't follow redirect to finalize here because need to pass access_token for auth
curl.follow_location = false
end
c.multipart_form_post = true
c.http_post(post_data)
if c.response_code == 303
# finalize it
response = Thingiverse::Connection.post(query['success_action_redirect'])
raise ResponseError.new(response) unless response.success?
Thingiverse::Files.new(response.parsed_response)
else
raise "#{c.response_code}: #{c.body_str}"
end
end
def publish
if @id.to_s == ""
raise "Cannot publish until thing is saved"
else
response = Thingiverse::Connection.post("/things/#{id}/publish")
raise ResponseError.new(response) unless response.success?
thing = Thingiverse::Things.new(response.parsed_response)
end
thing.attributes.each do |name, value|
send("#{name}=", value)
end
end
def self.find(thing_id)
response = Thingiverse::Connection.get("/things/#{thing_id}")
raise ResponseError.new(response) unless response.success?
self.new response.parsed_response
end
def self.newest(query = {})
Thingiverse::Pagination.new(Thingiverse::Connection.get('/newest', :query => query), Thingiverse::Things)
end
def self.create(params)
thing = self.new(params)
response = Thingiverse::Connection.post('/things', :body => thing.attributes.to_json)
raise ResponseError.new(response) unless response.success?
self.new(response.parsed_response)
end
end
end