warehaus 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +16 -0
- data/README.md +95 -0
- data/Rakefile +2 -0
- data/bin/warehaus +4 -0
- data/lib/warehaus.rb +215 -0
- data/lib/warehaus/version.rb +3 -0
- data/warehaus.gemspec +26 -0
- metadata +111 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 2cf2e67f57b21ffa49d9df3452ad9f618ee7b2a5
|
|
4
|
+
data.tar.gz: 0d38310e2a73d1f01a77ed0ab4fed4e3e5cc92d5
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 9b27cd291efd923d3370f624f2d44fbbc589b6eb5a810df4aff17b7ceefdf29198d04afdd212dcfca36d50fd2e3b46e4a3eaa4b8973eec3a78c6cb046b366950
|
|
7
|
+
data.tar.gz: 671fdc2e459af846d4caae5d94febb5c25ba336c9031453168aad1294f233e59183f6bcb269e8b38f2ca79b30f863cf8c0794d9841c25aab744d6bc6c8c3b207
|
data/.gitignore
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
*.gem
|
|
2
|
+
*.rbc
|
|
3
|
+
.bundle
|
|
4
|
+
.config
|
|
5
|
+
.yardoc
|
|
6
|
+
Gemfile.lock
|
|
7
|
+
InstalledFiles
|
|
8
|
+
_yardoc
|
|
9
|
+
coverage
|
|
10
|
+
doc/
|
|
11
|
+
lib/bundler/man
|
|
12
|
+
pkg
|
|
13
|
+
rdoc
|
|
14
|
+
spec/reports
|
|
15
|
+
test/tmp
|
|
16
|
+
test/version_tmp
|
|
17
|
+
tmp
|
|
18
|
+
*.bundle
|
|
19
|
+
*.so
|
|
20
|
+
*.o
|
|
21
|
+
*.a
|
|
22
|
+
mkmf.log
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
warehaus Copyright (c) 2014 ErikPeterson
|
|
2
|
+
|
|
3
|
+
GNU General Public License
|
|
4
|
+
|
|
5
|
+
This program is free software: you can redistribute it and/or modify
|
|
6
|
+
it under the terms of the GNU General Public License as published by
|
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
(at your option) any later version.
|
|
9
|
+
|
|
10
|
+
This program is distributed in the hope that it will be useful,
|
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
GNU General Public License for more details.
|
|
14
|
+
|
|
15
|
+
You should have received a copy of the GNU General Public License
|
|
16
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
data/README.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Warehaus
|
|
2
|
+
|
|
3
|
+
This gem is a work in progress that allows you to programatically retrieve usable collada
|
|
4
|
+
and image files from the Sketchup 3D Warehouse.
|
|
5
|
+
|
|
6
|
+
Currently, the gem can be used as a class or through its CLI.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
Add this line to your application's Gemfile:
|
|
11
|
+
|
|
12
|
+
gem 'warehaus'
|
|
13
|
+
|
|
14
|
+
And then execute:
|
|
15
|
+
|
|
16
|
+
$ bundle
|
|
17
|
+
|
|
18
|
+
Or install it yourself as:
|
|
19
|
+
|
|
20
|
+
$ gem install warehaus
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
### CLI
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
WAREHAUS
|
|
28
|
+
|
|
29
|
+
NAME
|
|
30
|
+
warehaus
|
|
31
|
+
|
|
32
|
+
SYNOPSIS
|
|
33
|
+
warehouse COMMAND [-v] [ARGS]
|
|
34
|
+
|
|
35
|
+
DESCRIPTION
|
|
36
|
+
Takes URLS or IDs for Sketchup Warehouse models, grabs their collada
|
|
37
|
+
resources, and unpacks them into a target directory
|
|
38
|
+
|
|
39
|
+
OPTIONS
|
|
40
|
+
-v
|
|
41
|
+
Prints logging and debug information
|
|
42
|
+
|
|
43
|
+
WAREHAUS COMMANDS
|
|
44
|
+
unbox [identifier] [path=./] [name=warehouse_model]
|
|
45
|
+
[identifier] is a url or `contentId` for a Sketchup Warehouse model.
|
|
46
|
+
[path] is the path to the root directory to write the unboxed files
|
|
47
|
+
into. [name] will be the name of the directory containing the unboxed
|
|
48
|
+
files, and will also be the name of the collada file within that
|
|
49
|
+
directory.
|
|
50
|
+
json [path]
|
|
51
|
+
[path] is a path to a json file to parse and use for unboxing. see the
|
|
52
|
+
github docs for information on the strucure of this file
|
|
53
|
+
help
|
|
54
|
+
prints help
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Class
|
|
58
|
+
|
|
59
|
+
Simply:
|
|
60
|
+
|
|
61
|
+
```ruby
|
|
62
|
+
|
|
63
|
+
require 'warehaus'
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
And then you can do:
|
|
68
|
+
|
|
69
|
+
```ruby
|
|
70
|
+
|
|
71
|
+
Warehaus::Getter.new(URL, ROOT_PATH, NAME);
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Or:
|
|
76
|
+
|
|
77
|
+
```ruby
|
|
78
|
+
|
|
79
|
+
WareHause::Getter.from_hash(HASH_OF_RESOURCES)
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Hash/JSON import format
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
|
|
87
|
+
{
|
|
88
|
+
"dir":"path/to/root/dir",
|
|
89
|
+
"models":{
|
|
90
|
+
"name_of_model1":"http://urltomodel1onsketchup.com/blah",
|
|
91
|
+
"name_of_model2":"content_id_of_model_2"
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
```
|
data/Rakefile
ADDED
data/bin/warehaus
ADDED
data/lib/warehaus.rb
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
require "warehaus/version"
|
|
2
|
+
require "httparty"
|
|
3
|
+
require "json"
|
|
4
|
+
require "zip"
|
|
5
|
+
require "fileutils"
|
|
6
|
+
require "pry"
|
|
7
|
+
|
|
8
|
+
module Warehaus
|
|
9
|
+
$mode = "quiet"
|
|
10
|
+
|
|
11
|
+
class Getter
|
|
12
|
+
include HTTParty
|
|
13
|
+
|
|
14
|
+
base_uri '3dwarehouse.sketchup.com'
|
|
15
|
+
|
|
16
|
+
ENTITY_PATH = '/3dw/GetEntity'
|
|
17
|
+
KMZ_PATH = '/warehouse/getpubliccontent'
|
|
18
|
+
|
|
19
|
+
def initialize(url_or_id, dir='./', name='warehouse-model')
|
|
20
|
+
@name = name
|
|
21
|
+
@path = dir
|
|
22
|
+
@options = {
|
|
23
|
+
:query => {
|
|
24
|
+
:id => parse_input(url_or_id)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def parse_input(input)
|
|
30
|
+
(input =~ /^[\w|\-|\d]+$/) ? input : input.match(/id=([\w|\-|\d]+)/)[1]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def fetch_entity
|
|
34
|
+
log("📠 Fetching JSON representation of model")
|
|
35
|
+
@response = JSON.parse(self.class.get(ENTITY_PATH, @options), :symbolize_names => true)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def get_kmz_id
|
|
39
|
+
log("🔍 Checking for KMZ id in JSON")
|
|
40
|
+
|
|
41
|
+
if !@response[:binaries]
|
|
42
|
+
return log("No KMZ file available for this object 💣")
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
if @response[:binaries][:ks]
|
|
46
|
+
kmz_id = @response[:binaries][:ks][:id]
|
|
47
|
+
else
|
|
48
|
+
@response[:binaries].each{ |k, bin|
|
|
49
|
+
kmz_id = bin[:id] if (bin[:originalFileName] =~ /kmz$/) != nil
|
|
50
|
+
}
|
|
51
|
+
if !kmz_id
|
|
52
|
+
return log("No KMZ file available for this object 💣")
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
@kmz_options = {
|
|
57
|
+
:query =>{
|
|
58
|
+
:contentId => kmz_id,
|
|
59
|
+
:fn => "#{@name}.kmz"
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def download_kmz
|
|
65
|
+
log("📥 Downloading KMZ file")
|
|
66
|
+
@kmz = self.class.get(KMZ_PATH, @kmz_options).parsed_response
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def write_kmz
|
|
70
|
+
FileUtils::mkdir_p "#{@path}/#{@name}/.tmp"
|
|
71
|
+
log("📝 Writing KMZ file")
|
|
72
|
+
begin
|
|
73
|
+
File.open("#{@path}/#{@name}/.tmp/#{@name}.kmz", "wb") do |f|
|
|
74
|
+
f.write @kmz
|
|
75
|
+
end
|
|
76
|
+
FileUtils::mv "#{@path}/#{@name}/.tmp/#{@name}.kmz", "#{@path}/#{@name}/.tmp/#{@name}.zip"
|
|
77
|
+
rescue Exception => e
|
|
78
|
+
return raise_error e.message
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def unzip_kmz
|
|
83
|
+
log("📁 Creating model directory")
|
|
84
|
+
FileUtils::mkdir_p "#{@path}/#{@name}/untitled"
|
|
85
|
+
|
|
86
|
+
log("🎊 Cracking open the ZIP file")
|
|
87
|
+
Zip::File.open("#{@path}/#{@name}/.tmp/#{@name}.zip") do |zip_file|
|
|
88
|
+
|
|
89
|
+
valid_paths = zip_file.entries.select do |entry|
|
|
90
|
+
(entry.name =~ /models\//) != nil
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
valid_paths.each do |entry|
|
|
94
|
+
|
|
95
|
+
if entry.name =~ /\.dae$/
|
|
96
|
+
dest = "#{@path}/#{@name}/#{@name}.dae"
|
|
97
|
+
else
|
|
98
|
+
dest = "#{@path}/#{@name}/#{entry.name.match(/models\/(.*)$/)[1]}"
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
entry.extract(dest)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def cleanup
|
|
107
|
+
log("🛀 Cleaning up")
|
|
108
|
+
FileUtils.rm_rf("#{@path}")
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def unbox
|
|
112
|
+
log("📦 Beginning unbox!")
|
|
113
|
+
fetch_entity
|
|
114
|
+
get_kmz_id
|
|
115
|
+
download_kmz
|
|
116
|
+
write_kmz
|
|
117
|
+
unzip_kmz
|
|
118
|
+
cleanup
|
|
119
|
+
"#{@path}/#{@name}/"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def erase
|
|
123
|
+
FileUtils.rm_rf "#{@path}/#{@name}"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def raise_error(msg)
|
|
127
|
+
raise "Warehaus Error: #{msg}"
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def log(msg)
|
|
131
|
+
puts("Warehaus: #{msg}") if $mode == "verbose"
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def self.from_hash(hash)
|
|
135
|
+
hash[:models].each do |k, v|
|
|
136
|
+
getter = self.new(v, "#{hash[:dir]}/#{k}", k)
|
|
137
|
+
getter.unbox
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
class CLI
|
|
145
|
+
|
|
146
|
+
def initialize(args)
|
|
147
|
+
@options = args
|
|
148
|
+
.select{|arg| (arg =~ /^\-/) != nil}
|
|
149
|
+
.map{|arg| arg.gsub(/^\-/,'')}
|
|
150
|
+
|
|
151
|
+
set_options
|
|
152
|
+
|
|
153
|
+
stripped_args = args.reject{|arg| (arg =~ /^\-/) != nil}
|
|
154
|
+
@method = stripped_args[0]
|
|
155
|
+
@arguments = stripped_args[1..-1]
|
|
156
|
+
self.send(@method, @arguments)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def set_options
|
|
160
|
+
@options.each{ |opt| self.send(opt)}
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def json(args)
|
|
164
|
+
|
|
165
|
+
File.open(args[0]) do |file|
|
|
166
|
+
@json = JSON.parse(file.read, :symbolize_names => true)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
Warehaus::Getter.from_hash(@json)
|
|
170
|
+
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def v
|
|
174
|
+
$mode = "verbose"
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def unbox(args)
|
|
178
|
+
fetcher = Warehaus::Getter.new(*args)
|
|
179
|
+
fetcher.unbox
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def help(method="none")
|
|
183
|
+
puts <<eol
|
|
184
|
+
|
|
185
|
+
WAREHAUS
|
|
186
|
+
|
|
187
|
+
NAME
|
|
188
|
+
warehaus
|
|
189
|
+
|
|
190
|
+
SYNOPSIS
|
|
191
|
+
warehouse COMMAND [-v] [ARGS]
|
|
192
|
+
|
|
193
|
+
DESCRIPTION
|
|
194
|
+
Takes URLS or IDs for Sketchup Warehouse models, grabs their collada
|
|
195
|
+
resources, and unpacks them into a target directory
|
|
196
|
+
|
|
197
|
+
OPTIONS
|
|
198
|
+
-v
|
|
199
|
+
Prints logging and debug information
|
|
200
|
+
|
|
201
|
+
WAREHAUS COMMANDS
|
|
202
|
+
unbox [identifier] [path=./] [name=warehouse_model]
|
|
203
|
+
Unpacks Sketchup model identified by [identifier] to [path]/[name]/[name].dae
|
|
204
|
+
json [path]
|
|
205
|
+
[path] is a path to a json file to parse and use for unboxing. see the
|
|
206
|
+
github docs for information on the strucure of this file
|
|
207
|
+
help
|
|
208
|
+
prints help
|
|
209
|
+
|
|
210
|
+
eol
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
end
|
data/warehaus.gemspec
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'warehaus/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "warehaus"
|
|
8
|
+
spec.version = Warehaus::VERSION
|
|
9
|
+
spec.authors = ["Erik Sälgström Peterson"]
|
|
10
|
+
spec.email = ["eriksalgstrom@gmail.com"]
|
|
11
|
+
spec.summary = "Get files from the 3D warehouse"
|
|
12
|
+
spec.description = "Fetch KMZ files from the Sketchup 3D Warehouse, and convert them into sensibly named directories and DAE files"
|
|
13
|
+
spec.homepage = "https://github.com/ErikPeterson/warehaus"
|
|
14
|
+
spec.license = "GPL"
|
|
15
|
+
|
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
|
17
|
+
spec.executables = ['warehaus']
|
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
19
|
+
spec.require_paths = ["lib"]
|
|
20
|
+
|
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
|
22
|
+
spec.add_development_dependency "rake"
|
|
23
|
+
|
|
24
|
+
spec.add_dependency "httparty", "~> 0.13.1"
|
|
25
|
+
spec.add_dependency "rubyzip", "~> 1.1.6"
|
|
26
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: warehaus
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Erik Sälgström Peterson
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2014-10-14 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: bundler
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '1.6'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '1.6'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rake
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: httparty
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: 0.13.1
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: 0.13.1
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rubyzip
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: 1.1.6
|
|
62
|
+
type: :runtime
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: 1.1.6
|
|
69
|
+
description: Fetch KMZ files from the Sketchup 3D Warehouse, and convert them into
|
|
70
|
+
sensibly named directories and DAE files
|
|
71
|
+
email:
|
|
72
|
+
- eriksalgstrom@gmail.com
|
|
73
|
+
executables:
|
|
74
|
+
- warehaus
|
|
75
|
+
extensions: []
|
|
76
|
+
extra_rdoc_files: []
|
|
77
|
+
files:
|
|
78
|
+
- ".gitignore"
|
|
79
|
+
- Gemfile
|
|
80
|
+
- LICENSE.txt
|
|
81
|
+
- README.md
|
|
82
|
+
- Rakefile
|
|
83
|
+
- bin/warehaus
|
|
84
|
+
- lib/warehaus.rb
|
|
85
|
+
- lib/warehaus/version.rb
|
|
86
|
+
- warehaus.gemspec
|
|
87
|
+
homepage: https://github.com/ErikPeterson/warehaus
|
|
88
|
+
licenses:
|
|
89
|
+
- GPL
|
|
90
|
+
metadata: {}
|
|
91
|
+
post_install_message:
|
|
92
|
+
rdoc_options: []
|
|
93
|
+
require_paths:
|
|
94
|
+
- lib
|
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
96
|
+
requirements:
|
|
97
|
+
- - ">="
|
|
98
|
+
- !ruby/object:Gem::Version
|
|
99
|
+
version: '0'
|
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
101
|
+
requirements:
|
|
102
|
+
- - ">="
|
|
103
|
+
- !ruby/object:Gem::Version
|
|
104
|
+
version: '0'
|
|
105
|
+
requirements: []
|
|
106
|
+
rubyforge_project:
|
|
107
|
+
rubygems_version: 2.2.2
|
|
108
|
+
signing_key:
|
|
109
|
+
specification_version: 4
|
|
110
|
+
summary: Get files from the 3D warehouse
|
|
111
|
+
test_files: []
|