sras 2.1.1.pre.10
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/.travis.yml +10 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +64 -0
- data/LICENSE +23 -0
- data/README.rst +59 -0
- data/Rakefile +19 -0
- data/bin/sras +117 -0
- data/config/config.yml.example +43 -0
- data/config.ru +3 -0
- data/lib/sras/helpers/asset.rb +107 -0
- data/lib/sras/helpers/init.rb +4 -0
- data/lib/sras/helpers/setup.rb +12 -0
- data/lib/sras/models/asset.rb +35 -0
- data/lib/sras/models/init.rb +20 -0
- data/lib/sras/views/create.erb +2 -0
- data/lib/sras/views/data.erb +1 -0
- data/lib/sras/views/index.erb +1 -0
- data/lib/sras/views/metadata.erb +13 -0
- data/lib/sras/views/show.erb +13 -0
- data/lib/sras.rb +97 -0
- data/sras.gemspec +23 -0
- data/test/test.asset +14 -0
- metadata +158 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
sras (2.1.1.pre.9)
|
5
|
+
dm-migrations (= 1.1.0)
|
6
|
+
dm-mysql-adapter (= 1.1.0)
|
7
|
+
dm-timestamps (= 1.1.0)
|
8
|
+
dm-types (= 1.1.0)
|
9
|
+
hpricot (= 0.8.4)
|
10
|
+
rake (= 0.9.2.2)
|
11
|
+
sinatra (= 1.2.6)
|
12
|
+
thin (= 1.2.11)
|
13
|
+
|
14
|
+
GEM
|
15
|
+
remote: http://rubygems.org/
|
16
|
+
specs:
|
17
|
+
addressable (2.2.6)
|
18
|
+
bcrypt-ruby (2.1.4)
|
19
|
+
daemons (1.1.4)
|
20
|
+
data_objects (0.10.6)
|
21
|
+
addressable (~> 2.1)
|
22
|
+
dm-core (1.1.0)
|
23
|
+
addressable (~> 2.2.4)
|
24
|
+
dm-do-adapter (1.1.0)
|
25
|
+
data_objects (~> 0.10.2)
|
26
|
+
dm-core (~> 1.1.0)
|
27
|
+
dm-migrations (1.1.0)
|
28
|
+
dm-core (~> 1.1.0)
|
29
|
+
dm-mysql-adapter (1.1.0)
|
30
|
+
dm-do-adapter (~> 1.1.0)
|
31
|
+
do_mysql (~> 0.10.2)
|
32
|
+
dm-timestamps (1.1.0)
|
33
|
+
dm-core (~> 1.1.0)
|
34
|
+
dm-types (1.1.0)
|
35
|
+
bcrypt-ruby (~> 2.1.4)
|
36
|
+
dm-core (~> 1.1.0)
|
37
|
+
fastercsv (~> 1.5.4)
|
38
|
+
json (~> 1.4.6)
|
39
|
+
stringex (~> 1.2.0)
|
40
|
+
uuidtools (~> 2.1.2)
|
41
|
+
do_mysql (0.10.6)
|
42
|
+
data_objects (= 0.10.6)
|
43
|
+
eventmachine (0.12.10)
|
44
|
+
fastercsv (1.5.4)
|
45
|
+
hpricot (0.8.4)
|
46
|
+
json (1.4.6)
|
47
|
+
rack (1.3.3)
|
48
|
+
rake (0.9.2.2)
|
49
|
+
sinatra (1.2.6)
|
50
|
+
rack (~> 1.1)
|
51
|
+
tilt (>= 1.2.2, < 2.0)
|
52
|
+
stringex (1.2.2)
|
53
|
+
thin (1.2.11)
|
54
|
+
daemons (>= 1.0.9)
|
55
|
+
eventmachine (>= 0.12.6)
|
56
|
+
rack (>= 1.0.0)
|
57
|
+
tilt (1.3.3)
|
58
|
+
uuidtools (2.1.2)
|
59
|
+
|
60
|
+
PLATFORMS
|
61
|
+
ruby
|
62
|
+
|
63
|
+
DEPENDENCIES
|
64
|
+
sras!
|
data/LICENSE
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2010-2011 Dave Coyle <http://coyled.com>
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
19
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
20
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
21
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
22
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
23
|
+
|
data/README.rst
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
SRAS -- An Asset Server for OpenSimulator
|
2
|
+
=========================================
|
3
|
+
|
4
|
+
Features
|
5
|
+
--------
|
6
|
+
|
7
|
+
* Asset de-duplication
|
8
|
+
* Compressed asset storage on disk
|
9
|
+
* Ability to disable serving of specific assets without deleting
|
10
|
+
|
11
|
+
|
12
|
+
Install
|
13
|
+
-------
|
14
|
+
|
15
|
+
The packages of Ruby shipping with Ubuntu don't include built-in zlib
|
16
|
+
support. I prefer using RVM [ http://rvm.beginrescueend.com/ ]
|
17
|
+
anyway.
|
18
|
+
|
19
|
+
Built & testing with Ruby v1.9.2. Tested with Thin, but should also
|
20
|
+
work with Passenger.
|
21
|
+
|
22
|
+
Install via: ::
|
23
|
+
|
24
|
+
$ gem install sras
|
25
|
+
|
26
|
+
then copy the following text into ``/etc/sras/sras.conf`` or
|
27
|
+
``~/.srasrc`` and edit as appropriate: ::
|
28
|
+
|
29
|
+
sras:
|
30
|
+
production:
|
31
|
+
default_asset_dir: /srv/sras
|
32
|
+
port: 8003
|
33
|
+
log_file: /var/log/sras.log
|
34
|
+
pid_file: /tmp/sras.pid
|
35
|
+
|
36
|
+
mysql:
|
37
|
+
production:
|
38
|
+
adapter: mysql
|
39
|
+
host: localhost
|
40
|
+
username: sras
|
41
|
+
password: sras
|
42
|
+
database: sras
|
43
|
+
|
44
|
+
|
45
|
+
Running
|
46
|
+
-------
|
47
|
+
|
48
|
+
Then just: ::
|
49
|
+
|
50
|
+
$ sras start
|
51
|
+
|
52
|
+
to start a single instance. In a production environment you would
|
53
|
+
likely want to run several instances behind a reverse proxy like
|
54
|
+
Nginx.
|
55
|
+
|
56
|
+
To see additional options: ::
|
57
|
+
|
58
|
+
$ sras --help
|
59
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rake/testtask'
|
2
|
+
require 'yaml'
|
3
|
+
require 'dm-core'
|
4
|
+
require 'dm-migrations'
|
5
|
+
|
6
|
+
#Rake::TestTask.new(:test) do |t|
|
7
|
+
# t.test_files = FileList['test/test_*.rb']
|
8
|
+
# t.verbose = true
|
9
|
+
#end
|
10
|
+
|
11
|
+
require ::File.dirname(__FILE__) + '/lib/sras/helpers/init'
|
12
|
+
|
13
|
+
namespace 'db' do
|
14
|
+
require ::File.dirname(__FILE__) + '/lib/sras/models/init'
|
15
|
+
|
16
|
+
task :create do
|
17
|
+
DataMapper.auto_upgrade!
|
18
|
+
end
|
19
|
+
end
|
data/bin/sras
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'yaml'
|
5
|
+
require 'thin'
|
6
|
+
|
7
|
+
options = {}
|
8
|
+
ROOT = ::File.dirname(::File.realdirpath(__FILE__))
|
9
|
+
|
10
|
+
# defaults...
|
11
|
+
options[:environment] = 'production'
|
12
|
+
options[:config_file] = '/etc/sras/sras.conf'
|
13
|
+
|
14
|
+
# look for more appropriate SRAS config file...
|
15
|
+
if File.exists?("#{ROOT}/config/config.yml")
|
16
|
+
options[:config_file] = "#{ROOT}/config/config.yml"
|
17
|
+
elsif File.exists?(File.expand_path('~/.srasrc'))
|
18
|
+
options[:config_file] = File.expand_path('~/.srasrc')
|
19
|
+
end
|
20
|
+
|
21
|
+
OptionParser.new do |opts|
|
22
|
+
opts.banner = 'Usage: sras [options] <start|stop>'
|
23
|
+
|
24
|
+
opts.on('-c', '--config <file>', 'SRAS config file') do |c|
|
25
|
+
options[:config_file] = c
|
26
|
+
end
|
27
|
+
|
28
|
+
opts.on('-e', '--environment <production|development|test>',
|
29
|
+
'Environment in which to run') do |e|
|
30
|
+
options[:environment] = e
|
31
|
+
end
|
32
|
+
|
33
|
+
opts.on('-h', '--host <hostname|ip_addy>', 'Address to which to bind') do |h|
|
34
|
+
options[:host] = h
|
35
|
+
end
|
36
|
+
|
37
|
+
opts.on('-p', '--port <N>', Integer, 'TCP port to which to bind') do |p|
|
38
|
+
options[:port] = p
|
39
|
+
end
|
40
|
+
|
41
|
+
opts.on('-l', '--log <file>', 'Log file') do |l|
|
42
|
+
options[:log_file] = l
|
43
|
+
end
|
44
|
+
|
45
|
+
opts.on('-P', '--pid <file>', 'PID file') do |p|
|
46
|
+
options[:pid_file] = p
|
47
|
+
end
|
48
|
+
|
49
|
+
opts.on_tail('-h', '--help', 'Show this message') do
|
50
|
+
puts opts
|
51
|
+
exit
|
52
|
+
end
|
53
|
+
|
54
|
+
if ARGV.last
|
55
|
+
command = ARGV.last.chomp
|
56
|
+
if command == 'start' || command == 'stop'
|
57
|
+
options[:command] = command
|
58
|
+
else
|
59
|
+
puts opts
|
60
|
+
exit
|
61
|
+
end
|
62
|
+
else
|
63
|
+
puts opts
|
64
|
+
exit
|
65
|
+
end
|
66
|
+
end.parse!
|
67
|
+
|
68
|
+
# load SRAS config file...
|
69
|
+
if File.exists?(options[:config_file])
|
70
|
+
@config = YAML.load_file(options[:config_file])
|
71
|
+
else
|
72
|
+
warn "Couldn't find SRAS config file. Exiting."
|
73
|
+
exit 1
|
74
|
+
end
|
75
|
+
|
76
|
+
# base thin options...
|
77
|
+
#-d -R #{::File.dirname(__FILE__)}/../config.ru"
|
78
|
+
#thin_opts << " -e #{options[:environment]}"
|
79
|
+
|
80
|
+
if ! options[:host]
|
81
|
+
if @config['sras'][options[:environment]]['host']
|
82
|
+
options[:host] = @config['sras'][options[:environment]]['host']
|
83
|
+
else
|
84
|
+
options[:host] = '0.0.0.0'
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
if ! options[:port]
|
89
|
+
if @config['sras'][options[:environment]]['port']
|
90
|
+
options[:port] = @config['sras'][options[:environment]]['port']
|
91
|
+
else
|
92
|
+
options[:port] = '8003'
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
if ! options[:log_file]
|
97
|
+
if @config['sras'][options[:environment]]['log_file']
|
98
|
+
options[:log_file] = @config['sras'][options[:environment]]['log_file']
|
99
|
+
else
|
100
|
+
options[:log_file] = "log/sras_#{options[:environment]}.log"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
if ! options[:pid_file]
|
105
|
+
if @config['sras'][options[:environment]]['pid_file']
|
106
|
+
options[:pid_file] = @config['sras'][options[:environment]]['pid_file']
|
107
|
+
else
|
108
|
+
options[:pid_file] = "/tmp/sras_#{options[:environment]}.pid"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
require "#{ROOT}/../lib/sras.rb"
|
113
|
+
server = Thin::Server.new(options[:host], options[:port], SRAS.new)
|
114
|
+
server.log_file = options[:log_file]
|
115
|
+
server.pid_file = options[:pid_file]
|
116
|
+
server.tag = 'sras'
|
117
|
+
server.start
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#
|
2
|
+
# copy or rename this config.yml.example file to config.yml and
|
3
|
+
# edit below...
|
4
|
+
#
|
5
|
+
|
6
|
+
sras:
|
7
|
+
production:
|
8
|
+
default_asset_dir: /srv/sras
|
9
|
+
|
10
|
+
#test:
|
11
|
+
# default_asset_dir: /var/tmp/sras
|
12
|
+
|
13
|
+
#development:
|
14
|
+
# default_asset_dir: /var/tmp/sras
|
15
|
+
|
16
|
+
|
17
|
+
mysql:
|
18
|
+
# the below 'production' settings are the only ones you need to
|
19
|
+
# update unless you plan on making changes to SRAS code...
|
20
|
+
production:
|
21
|
+
adapter: mysql
|
22
|
+
host: localhost
|
23
|
+
username: sras
|
24
|
+
password: sras
|
25
|
+
database: sras
|
26
|
+
|
27
|
+
# the below 'test' settings will be used only if you run tests.
|
28
|
+
# you can ignore, delete, or change these...
|
29
|
+
#test:
|
30
|
+
# adapter: mysql
|
31
|
+
# host: localhost
|
32
|
+
# username: sras_test
|
33
|
+
# password: sras_test
|
34
|
+
# database: sras_test
|
35
|
+
|
36
|
+
# the 'development' settings below are used only by the Travis CI
|
37
|
+
# service which is triggered when SRAS code changes are committed
|
38
|
+
# to GitHub. you can ignore, delete, or change these...
|
39
|
+
#development:
|
40
|
+
# adapter: mysql2
|
41
|
+
# database: sras_test
|
42
|
+
# username:
|
43
|
+
# encoding: ascii
|
data/config.ru
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
module AssetHelper
|
5
|
+
|
6
|
+
def get_asset_data(asset_id)
|
7
|
+
@asset = Asset.get(asset_id)
|
8
|
+
|
9
|
+
if @asset.enabled == false
|
10
|
+
return
|
11
|
+
end
|
12
|
+
|
13
|
+
@asset_file = @asset.base_dir + '/' + @asset.sha256[0..2] + '/' + @asset.sha256[3..5] + '/' + @asset.sha256
|
14
|
+
|
15
|
+
if File.exists?(@asset_file + '.gz')
|
16
|
+
Zlib::GzipReader.open(@asset_file + '.gz') do |file|
|
17
|
+
@asset_data = file.read
|
18
|
+
end
|
19
|
+
elsif File.exists?(@asset_file)
|
20
|
+
File.open(@asset_file) do |file|
|
21
|
+
@asset_data = file.read
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
return @asset_data
|
26
|
+
end
|
27
|
+
|
28
|
+
def write_asset_data()
|
29
|
+
@asset_file_dir = @asset.base_dir + '/' + @asset.sha256[0..2] + '/' + @asset.sha256[3..5]
|
30
|
+
@asset_file = @asset_file_dir + '/' + @asset.sha256
|
31
|
+
|
32
|
+
# see if asset file with this hash already exists. if it
|
33
|
+
# does, then we don't need to overwrite it with identical
|
34
|
+
# data...
|
35
|
+
if File.exists?(@asset_file + '.gz') || File.exists?(@asset_file)
|
36
|
+
return
|
37
|
+
end
|
38
|
+
|
39
|
+
# mkdirs if necessary...
|
40
|
+
FileUtils.mkpath @asset_file_dir
|
41
|
+
|
42
|
+
# write the data to a file, gzip'd...
|
43
|
+
Zlib::GzipWriter.open(@asset_file + '.gz') do |file|
|
44
|
+
file.write @asset_data
|
45
|
+
file.close
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Flags added to opensim in 9b22393. Current values (from
|
50
|
+
# OpenSim/Framework/AssetBase.cs):
|
51
|
+
#
|
52
|
+
# [Flags]
|
53
|
+
# public enum AssetFlags : int
|
54
|
+
# {
|
55
|
+
# Normal = 0,
|
56
|
+
# Maptile = 1,
|
57
|
+
# Rewritable = 2,
|
58
|
+
# Collectable = 4
|
59
|
+
# }
|
60
|
+
@flags = {
|
61
|
+
'Normal' => 0,
|
62
|
+
'Maptile' => 1,
|
63
|
+
'Rewritable' => 2,
|
64
|
+
'Collectable' => 4
|
65
|
+
}
|
66
|
+
|
67
|
+
# usage:
|
68
|
+
# asset_type = get_asset_type('image/tga')
|
69
|
+
# asset_type = get_asset_type(12)
|
70
|
+
def get_asset_type(request)
|
71
|
+
|
72
|
+
# default 'application/octet-stream'
|
73
|
+
asset_type = {
|
74
|
+
'image/jp2' => 0,
|
75
|
+
'application/ogg' => 1,
|
76
|
+
'application/x-metaverse-callingcard' => 2,
|
77
|
+
'application/x-metaverse-landmark' => 3,
|
78
|
+
'application/x-metaverse-clothing' => 5,
|
79
|
+
'application/x-metaverse-primitive' => 6,
|
80
|
+
'application/x-metaverse-notecard' => 7,
|
81
|
+
'application/x-metaverse-folder' => 8,
|
82
|
+
'application/x-metaverse-lsl' => 10,
|
83
|
+
'application/x-metaverse-lso' => 11,
|
84
|
+
'image/tga' => 12,
|
85
|
+
'application/x-metaverse-bodypart' => 13,
|
86
|
+
'audio/x-wav' => 17,
|
87
|
+
'image/jpeg' => 19,
|
88
|
+
'application/x-metaverse-animation' => 20,
|
89
|
+
'application/x-metaverse-gesture' => 21,
|
90
|
+
'application/x-metaverse-simstate' => 22
|
91
|
+
}
|
92
|
+
|
93
|
+
if asset_type[request]
|
94
|
+
response = asset_type[request]
|
95
|
+
elsif asset_type.invert[request]
|
96
|
+
response = asset_type.invert[request]
|
97
|
+
end
|
98
|
+
|
99
|
+
return response
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
helpers AssetHelper
|
106
|
+
|
107
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
RACK_ENV = ENV['RACK_ENV'] || 'production'
|
2
|
+
@dbms = ENV['DBMS'] || 'mysql'
|
3
|
+
|
4
|
+
if File.exists?("#{ROOT}/config/config.yml")
|
5
|
+
config_file = "#{ROOT}/config/config.yml"
|
6
|
+
elsif File.exists?(File.expand_path('~/.srasrc'))
|
7
|
+
config_file = File.expand_path('~/.srasrc')
|
8
|
+
else
|
9
|
+
config_file = '/etc/sras/sras.conf'
|
10
|
+
end
|
11
|
+
|
12
|
+
@config = YAML.load_file(config_file)
|
@@ -0,0 +1,35 @@
|
|
1
|
+
#CREATE TABLE `assets` (
|
2
|
+
# `id` char(36) NOT NULL,
|
3
|
+
# `asset_type` tinyint(4) NOT NULL,
|
4
|
+
# `sha256` char(64) NOT NULL,
|
5
|
+
# `name` varchar(64) DEFAULT NULL,
|
6
|
+
# `description` varchar(64) DEFAULT NULL,
|
7
|
+
# `local` tinyint(1) DEFAULT NULL,
|
8
|
+
# `temporary` tinyint(1) DEFAULT NULL,
|
9
|
+
# `base_dir` varchar(64) NOT NULL,
|
10
|
+
# `created_at` int(11) DEFAULT NULL,
|
11
|
+
# `updated_at` int(11) DEFAULT NULL,
|
12
|
+
# `enabled` tinyint(1) NOT NULL DEFAULT '1',
|
13
|
+
# PRIMARY KEY (`id`),
|
14
|
+
# KEY `assets_id_sha256` (`id`,`sha256`),
|
15
|
+
# KEY `assets_sha256` (`sha256`)
|
16
|
+
#) ENGINE=MyISAM DEFAULT CHARSET=ascii;
|
17
|
+
|
18
|
+
class Asset
|
19
|
+
include DataMapper::Resource
|
20
|
+
property :id, String, :length => 36, :required => true,
|
21
|
+
:key => true, :index => :id_sha256
|
22
|
+
property :asset_type, Integer, :required => true,
|
23
|
+
:min => 0, :max => 99
|
24
|
+
property :sha256, String, :length => 64, :required => true,
|
25
|
+
:index => [ :sha256, :id_sha256 ]
|
26
|
+
property :name, String, :length => 64
|
27
|
+
property :description, String, :length => 64
|
28
|
+
property :local, Boolean
|
29
|
+
property :temporary, Boolean
|
30
|
+
property :base_dir, String, :length => 64, :required => true,
|
31
|
+
:default => $default_asset_dir
|
32
|
+
property :created_at, EpochTime
|
33
|
+
property :updated_at, EpochTime
|
34
|
+
property :enabled, Boolean, :required => true, :default => true
|
35
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
require 'dm-core'
|
3
|
+
require 'dm-types'
|
4
|
+
require 'dm-timestamps'
|
5
|
+
|
6
|
+
configure :development do
|
7
|
+
DataMapper::Logger.new(STDOUT, :debug)
|
8
|
+
end
|
9
|
+
|
10
|
+
$default_asset_dir = @config['sras'][RACK_ENV]['default_asset_dir']
|
11
|
+
|
12
|
+
DataMapper.setup(:default, {
|
13
|
+
:adapter => @config[@dbms][RACK_ENV]['adapter'],
|
14
|
+
:host => @config[@dbms][RACK_ENV]['host'],
|
15
|
+
:username => @config[@dbms][RACK_ENV]['username'],
|
16
|
+
:password => @config[@dbms][RACK_ENV]['password'],
|
17
|
+
:database => @config[@dbms][RACK_ENV]['database']
|
18
|
+
})
|
19
|
+
|
20
|
+
require ::File.dirname(__FILE__) + '/asset'
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= @asset_data %>
|
@@ -0,0 +1 @@
|
|
1
|
+
SRAS
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<AssetMetadata xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
3
|
+
<FullID>
|
4
|
+
<Guid><%= @asset.id %></Guid>
|
5
|
+
</FullID>
|
6
|
+
<ID><%= @asset.id %></ID>
|
7
|
+
<Name><%= @asset.name %></Name>
|
8
|
+
<Description><%= @asset.description %></Description>
|
9
|
+
<CreationDate><%= @asset.created_at.to_time.iso8601 %></CreationDate>
|
10
|
+
<Type><%= @asset.asset_type %></Type>
|
11
|
+
<Local><%= @asset.local %></Local>
|
12
|
+
<Temporary><%= @asset.temporary %></Temporary>
|
13
|
+
</AssetMetadata>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<AssetBase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
3
|
+
<Data><%= Base64.encode64(@asset_data) %></Data>
|
4
|
+
<FullID>
|
5
|
+
<Guid><%= @asset.id %></Guid>
|
6
|
+
</FullID>
|
7
|
+
<ID><%= @asset.id %></ID>
|
8
|
+
<Name><%= @asset.name %></Name>
|
9
|
+
<Description><%= @asset.description %></Description>
|
10
|
+
<Type><%= @asset.asset_type %></Type>
|
11
|
+
<Local><%= @asset.local %></Local>
|
12
|
+
<Temporary><%= @asset.temporary %></Temporary>
|
13
|
+
</AssetBase>
|
data/lib/sras.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
#require 'bundler'
|
2
|
+
#Bundler.setup
|
3
|
+
|
4
|
+
require 'bundler/setup'
|
5
|
+
|
6
|
+
require 'sinatra'
|
7
|
+
require 'erb'
|
8
|
+
require 'base64'
|
9
|
+
require 'digest/sha2'
|
10
|
+
require 'hpricot'
|
11
|
+
|
12
|
+
class SRAS < Sinatra::Application
|
13
|
+
set :views, Proc.new { File.join(root, "sras/views") }
|
14
|
+
|
15
|
+
get '/' do
|
16
|
+
erb :index
|
17
|
+
end
|
18
|
+
|
19
|
+
get '/assets/?' do
|
20
|
+
erb :index
|
21
|
+
end
|
22
|
+
|
23
|
+
post '/assets/?' do
|
24
|
+
content_type 'application/xml'
|
25
|
+
|
26
|
+
doc = Hpricot.XML(request.body.read)
|
27
|
+
|
28
|
+
# 404 if the ID already exists. need to revisit this.
|
29
|
+
if Asset.get((doc/:ID).text)
|
30
|
+
not_found
|
31
|
+
end
|
32
|
+
|
33
|
+
@asset_data = Base64.decode64((doc/:Data).text.chomp)
|
34
|
+
@asset_hash = Digest::SHA256.digest(@asset_data).unpack('H*')[0].upcase
|
35
|
+
@asset = Asset.new(
|
36
|
+
:id => (doc/:ID).text,
|
37
|
+
:asset_type => (doc/:Type).text,
|
38
|
+
:sha256 => @asset_hash,
|
39
|
+
:name => (doc/:Name).text,
|
40
|
+
:description => (doc/:Description).text,
|
41
|
+
:local => (doc/:Local).text,
|
42
|
+
:temporary => (doc/:Temporary).text
|
43
|
+
)
|
44
|
+
write_asset_data
|
45
|
+
@asset.save
|
46
|
+
erb :create
|
47
|
+
end
|
48
|
+
|
49
|
+
get '/assets/:asset_id' do
|
50
|
+
if @asset = Asset.get(params[:asset_id])
|
51
|
+
if @asset_data = get_asset_data(params[:asset_id])
|
52
|
+
content_type get_asset_type(@asset.asset_type)
|
53
|
+
erb :show
|
54
|
+
else
|
55
|
+
not_found
|
56
|
+
end
|
57
|
+
else
|
58
|
+
not_found
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
get '/assets/:asset_id/data' do
|
63
|
+
if @asset = Asset.get(params[:asset_id])
|
64
|
+
if @asset_data = get_asset_data(params[:asset_id])
|
65
|
+
content_type 'application/octet-stream'
|
66
|
+
erb :data
|
67
|
+
else
|
68
|
+
not_found
|
69
|
+
end
|
70
|
+
else
|
71
|
+
not_found
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
get '/assets/:asset_id/metadata' do
|
76
|
+
if @asset = Asset.get(params[:asset_id])
|
77
|
+
if @asset_data = get_asset_data(params[:asset_id])
|
78
|
+
content_type get_asset_type(@asset.asset_type)
|
79
|
+
erb :metadata
|
80
|
+
else
|
81
|
+
not_found
|
82
|
+
end
|
83
|
+
else
|
84
|
+
not_found
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
delete '/*' do
|
89
|
+
# we don't trust anyone to delete assets. opensim complains if it
|
90
|
+
# gets 403s, so return a 404 instead...
|
91
|
+
not_found
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
require ::File.dirname(__FILE__) + '/sras/helpers/init'
|
97
|
+
require ::File.dirname(__FILE__) + '/sras/models/init'
|
data/sras.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'sras'
|
3
|
+
s.version = '2.1.1.pre.10'
|
4
|
+
s.summary = 'Simple Ruby Asset Server'
|
5
|
+
s.description = 'Asset server for use with OpenSimulator'
|
6
|
+
s.authors = 'Dave Coyle'
|
7
|
+
s.email = 'hello@coyled.com'
|
8
|
+
s.homepage = 'http://coyled.com/sras'
|
9
|
+
s.license = 'MIT'
|
10
|
+
|
11
|
+
s.files = `git ls-files`.split("\n")
|
12
|
+
s.test_files = `git ls-files -- test/*`.split("\n")
|
13
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
14
|
+
|
15
|
+
s.add_runtime_dependency 'dm-migrations', '1.1.0'
|
16
|
+
s.add_runtime_dependency 'dm-mysql-adapter', '1.1.0'
|
17
|
+
s.add_runtime_dependency 'dm-timestamps', '1.1.0'
|
18
|
+
s.add_runtime_dependency 'dm-types', '1.1.0'
|
19
|
+
s.add_runtime_dependency 'hpricot', '0.8.4'
|
20
|
+
s.add_runtime_dependency 'sinatra', '1.2.6'
|
21
|
+
s.add_runtime_dependency 'thin', '1.2.11'
|
22
|
+
s.add_runtime_dependency 'rake', '0.9.2.2'
|
23
|
+
end
|
data/test/test.asset
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<AssetBase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
3
|
+
<Data>SGkuICBJJ20gYSBzdWJtaXR0ZWQgYXNzZXQhCg==
|
4
|
+
</Data>
|
5
|
+
<FullID>
|
6
|
+
<Guid>0193663d-44e4-4e6e-9a1c-8dd2febc5fc5</Guid>
|
7
|
+
</FullID>
|
8
|
+
<ID>0193663d-44e4-4e6e-9a1c-8dd2febc5fc5</ID>
|
9
|
+
<Name>test1</Name>
|
10
|
+
<Description>test submitted asset</Description>
|
11
|
+
<Type>10</Type>
|
12
|
+
<Local>true</Local>
|
13
|
+
<Temporary>false</Temporary>
|
14
|
+
</AssetBase>
|
metadata
ADDED
@@ -0,0 +1,158 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sras
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.1.1.pre.10
|
5
|
+
prerelease: 6
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Dave Coyle
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-03-16 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: dm-migrations
|
16
|
+
requirement: &73169400 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - =
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.1.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *73169400
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: dm-mysql-adapter
|
27
|
+
requirement: &73169150 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - =
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.1.0
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *73169150
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: dm-timestamps
|
38
|
+
requirement: &73168920 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - =
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 1.1.0
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *73168920
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: dm-types
|
49
|
+
requirement: &73168690 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - =
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.1.0
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *73168690
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: hpricot
|
60
|
+
requirement: &73168460 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - =
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 0.8.4
|
66
|
+
type: :runtime
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *73168460
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: sinatra
|
71
|
+
requirement: &73168230 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - =
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 1.2.6
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *73168230
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: thin
|
82
|
+
requirement: &73168000 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - =
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: 1.2.11
|
88
|
+
type: :runtime
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *73168000
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: rake
|
93
|
+
requirement: &73167770 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - =
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: 0.9.2.2
|
99
|
+
type: :runtime
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *73167770
|
102
|
+
description: Asset server for use with OpenSimulator
|
103
|
+
email: hello@coyled.com
|
104
|
+
executables:
|
105
|
+
- sras
|
106
|
+
extensions: []
|
107
|
+
extra_rdoc_files: []
|
108
|
+
files:
|
109
|
+
- .gitignore
|
110
|
+
- .travis.yml
|
111
|
+
- Gemfile
|
112
|
+
- Gemfile.lock
|
113
|
+
- LICENSE
|
114
|
+
- README.rst
|
115
|
+
- Rakefile
|
116
|
+
- bin/sras
|
117
|
+
- config.ru
|
118
|
+
- config/config.yml.example
|
119
|
+
- lib/sras.rb
|
120
|
+
- lib/sras/helpers/asset.rb
|
121
|
+
- lib/sras/helpers/init.rb
|
122
|
+
- lib/sras/helpers/setup.rb
|
123
|
+
- lib/sras/models/asset.rb
|
124
|
+
- lib/sras/models/init.rb
|
125
|
+
- lib/sras/views/create.erb
|
126
|
+
- lib/sras/views/data.erb
|
127
|
+
- lib/sras/views/index.erb
|
128
|
+
- lib/sras/views/metadata.erb
|
129
|
+
- lib/sras/views/show.erb
|
130
|
+
- sras.gemspec
|
131
|
+
- test/test.asset
|
132
|
+
homepage: http://coyled.com/sras
|
133
|
+
licenses:
|
134
|
+
- MIT
|
135
|
+
post_install_message:
|
136
|
+
rdoc_options: []
|
137
|
+
require_paths:
|
138
|
+
- lib
|
139
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
140
|
+
none: false
|
141
|
+
requirements:
|
142
|
+
- - ! '>='
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
|
+
none: false
|
147
|
+
requirements:
|
148
|
+
- - ! '>'
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: 1.3.1
|
151
|
+
requirements: []
|
152
|
+
rubyforge_project:
|
153
|
+
rubygems_version: 1.8.15
|
154
|
+
signing_key:
|
155
|
+
specification_version: 3
|
156
|
+
summary: Simple Ruby Asset Server
|
157
|
+
test_files:
|
158
|
+
- test/test.asset
|