thingfish 0.5.0.pre20160707192835

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/.simplecov +7 -0
  3. data/History.rdoc +5 -0
  4. data/LICENSE +29 -0
  5. data/Manifest.txt +39 -0
  6. data/Procfile +4 -0
  7. data/README.rdoc +92 -0
  8. data/Rakefile +92 -0
  9. data/bin/tfprocessord +6 -0
  10. data/bin/thingfish +10 -0
  11. data/etc/thingfish.conf.example +26 -0
  12. data/lib/strelka/app/metadata.rb +38 -0
  13. data/lib/strelka/httprequest/metadata.rb +70 -0
  14. data/lib/thingfish.rb +43 -0
  15. data/lib/thingfish/behaviors.rb +263 -0
  16. data/lib/thingfish/datastore.rb +55 -0
  17. data/lib/thingfish/datastore/memory.rb +93 -0
  18. data/lib/thingfish/handler.rb +728 -0
  19. data/lib/thingfish/metastore.rb +55 -0
  20. data/lib/thingfish/metastore/memory.rb +201 -0
  21. data/lib/thingfish/mixins.rb +57 -0
  22. data/lib/thingfish/processor.rb +79 -0
  23. data/lib/thingfish/processor/mp3.rb +167 -0
  24. data/lib/thingfish/processordaemon.rb +16 -0
  25. data/lib/thingfish/spechelpers.rb +165 -0
  26. data/spec/data/APIC-1-image.mp3 +0 -0
  27. data/spec/data/APIC-2-images.mp3 +0 -0
  28. data/spec/data/PIC-1-image.mp3 +0 -0
  29. data/spec/data/PIC-2-images.mp3 +0 -0
  30. data/spec/helpers.rb +67 -0
  31. data/spec/spec.opts +4 -0
  32. data/spec/thingfish/datastore/memory_spec.rb +19 -0
  33. data/spec/thingfish/datastore_spec.rb +64 -0
  34. data/spec/thingfish/handler_spec.rb +838 -0
  35. data/spec/thingfish/metastore/memory_spec.rb +17 -0
  36. data/spec/thingfish/metastore_spec.rb +96 -0
  37. data/spec/thingfish/mixins_spec.rb +63 -0
  38. data/spec/thingfish/processor/mp3_spec.rb +50 -0
  39. data/spec/thingfish/processor_spec.rb +65 -0
  40. data/spec/thingfish_spec.rb +23 -0
  41. metadata +244 -0
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../../helpers'
4
+
5
+ require 'securerandom'
6
+ require 'rspec'
7
+ require 'thingfish/metastore/memory'
8
+ require 'thingfish/behaviors'
9
+
10
+
11
+ describe Thingfish::Metastore::Memory do
12
+
13
+ it_behaves_like "a Thingfish metastore"
14
+
15
+ end
16
+
17
+ # vim: set nosta noet ts=4 sw=4 ft=rspec:
@@ -0,0 +1,96 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../helpers'
4
+
5
+ require 'rspec'
6
+ require 'thingfish/metastore'
7
+
8
+ class TestingMetastore < Thingfish::Metastore
9
+ end
10
+
11
+
12
+ describe Thingfish::Metastore do
13
+
14
+ before( :all ) do
15
+ setup_logging()
16
+ end
17
+
18
+
19
+ it "is abstract" do
20
+ expect { described_class.new }.to raise_error( NoMethodError, /private/i )
21
+ end
22
+
23
+
24
+ it "acts as a factory for its concrete derivatives" do
25
+ expect( described_class.create('testing') ).to be_a( TestingMetastore )
26
+ end
27
+
28
+
29
+ describe "an instance of a concrete derivative" do
30
+
31
+ let( :store ) { described_class.create('testing') }
32
+
33
+ it "raises an error if it doesn't implement #oids" do
34
+ expect { store.oids }.to raise_error( NotImplementedError, /oids/ )
35
+ end
36
+
37
+ it "raises an error if it doesn't implement #each_oid" do
38
+ expect { store.each_oid }.to raise_error( NotImplementedError, /each_oid/ )
39
+ end
40
+
41
+ it "raises an error if it doesn't implement #fetch" do
42
+ expect { store.fetch(TEST_UUID) }.to raise_error( NotImplementedError, /fetch/ )
43
+ end
44
+
45
+ it "raises an error if it doesn't implement #fetch_value" do
46
+ expect { store.fetch_value(TEST_UUID, :format) }.
47
+ to raise_error( NotImplementedError, /fetch_value/ )
48
+ end
49
+
50
+ it "raises an error if it doesn't implement #search" do
51
+ expect { store.search(limit: 100) }.to raise_error( NotImplementedError, /search/ )
52
+ end
53
+
54
+ it "raises an error if it doesn't implement #save" do
55
+ expect {
56
+ store.save( TEST_UUID, {name: 'foo'} )
57
+ }.to raise_error( NotImplementedError, /save/ )
58
+ end
59
+
60
+ it "raises an error if it doesn't implement #merge" do
61
+ expect {
62
+ store.merge( TEST_UUID, {name: 'foo'} )
63
+ }.to raise_error( NotImplementedError, /merge/ )
64
+ end
65
+
66
+ it "raises an error if it doesn't implement #include?" do
67
+ expect { store.include?(TEST_UUID) }.to raise_error( NotImplementedError, /include\?/ )
68
+ end
69
+
70
+ it "raises an error if it doesn't implement #remove" do
71
+ expect { store.remove(TEST_UUID) }.to raise_error( NotImplementedError, /remove/ )
72
+ end
73
+
74
+ it "raises an error if it doesn't implement #remove_except" do
75
+ expect { store.remove_except(TEST_UUID, :format) }.
76
+ to raise_error( NotImplementedError, /remove_except/ )
77
+ end
78
+
79
+ it "raises an error if it doesn't implement #size" do
80
+ expect { store.size }.to raise_error( NotImplementedError, /size/ )
81
+ end
82
+
83
+ it "raises an error if it doesn't implement #fetch_related_oids" do
84
+ expect {
85
+ store.fetch_related_oids( TEST_UUID )
86
+ }.to raise_error( NotImplementedError, /fetch_related_oids/i )
87
+ end
88
+
89
+ it "provides a transactional block method" do
90
+ expect {|block| store.transaction(&block) }.to yield_with_no_args
91
+ end
92
+ end
93
+
94
+ end
95
+
96
+ # vim: set nosta noet ts=4 sw=4 ft=rspec:
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env rspec -cfd -b
2
+ # vim: set noet nosta sw=4 ts=4 :
3
+
4
+ require_relative '../helpers'
5
+
6
+ require 'rspec'
7
+
8
+ require 'thingfish/mixins'
9
+
10
+
11
+ describe Thingfish, 'mixins' do
12
+
13
+ # A collection of functions for dealing with object IDs.
14
+ describe 'Normalization' do
15
+
16
+ it 'can generate a new object ID' do
17
+ expect( Thingfish::Normalization.make_object_id ).to match( UUID_PATTERN )
18
+ end
19
+
20
+ it 'can normalize an object ID' do
21
+ expect(
22
+ Thingfish::Normalization.normalize_oid( TEST_UUID.upcase )
23
+ ).to_not match( /[A-Z]/ )
24
+ end
25
+
26
+ it 'can normalize Hash metadata keys' do
27
+ metadata = { :pork => 1, :sausaged => 2 }
28
+ expect( Thingfish::Normalization.normalize_keys(metadata) ).
29
+ to eq({ 'pork' => 1, 'sausaged' => 2 })
30
+ end
31
+
32
+ it 'can normalize an Array of metadata keys' do
33
+ values = [ :pork, :sausaged ]
34
+ expect( Thingfish::Normalization.normalize_keys(values) ).
35
+ to eq([ 'pork', 'sausaged' ])
36
+ expect( values.first ).to be( :pork )
37
+ end
38
+
39
+ it "won't modify the original array of metadata keys" do
40
+ values = [ :pork, :sausaged ]
41
+ normalized = Thingfish::Normalization.normalize_keys( values )
42
+
43
+ expect( values.first ).to be( :pork )
44
+ expect( normalized ).to_not be( values )
45
+ end
46
+
47
+ it "replaces non metadata key characters with underscores" do
48
+ expect( Thingfish::Normalization::normalize_key('Sausaged!') ).to eq( 'sausaged_' )
49
+ expect( Thingfish::Normalization::normalize_key('SO sausaged') ).to eq( 'so_sausaged' )
50
+ expect( Thingfish::Normalization::normalize_key('*/porky+-') ).to eq( '_porky_' )
51
+ end
52
+
53
+ it "preserves colons in metadata keys" do
54
+ expect( Thingfish::Normalization::normalize_key('pork:sausaged') ).
55
+ to eq( 'pork:sausaged' )
56
+ end
57
+
58
+
59
+ end # module Normalization
60
+
61
+
62
+ end
63
+
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../../helpers'
4
+
5
+ require 'rspec'
6
+ require 'thingfish/processor'
7
+
8
+ require 'strelka/httprequest/metadata'
9
+
10
+
11
+ describe Thingfish::Processor, "MP3" do
12
+
13
+ before( :all ) do
14
+ Strelka::HTTPRequest.class_eval { include Strelka::HTTPRequest::Metadata }
15
+ end
16
+
17
+
18
+ let( :processor ) { described_class.create(:mp3) }
19
+
20
+ let( :factory ) do
21
+ Mongrel2::RequestFactory.new(
22
+ :route => '/',
23
+ :headers => {:accept => '*/*'})
24
+ end
25
+
26
+
27
+ it "extracts metadata from uploaded MP3 ID3 tags" do
28
+ req = factory.post( '/tf', fixture_data('APIC-1-image.mp3'), 'Content-type' => 'audio/mp3' )
29
+
30
+ processor.process_request( req )
31
+
32
+ expect( req.metadata ).to include( 'mp3:artist', 'mp3:bitrate', 'mp3:comments' )
33
+ end
34
+
35
+
36
+ it "attaches album art as a related resource" do
37
+ req = factory.post( '/tf', fixture_data('APIC-1-image.mp3'), 'Content-type' => 'audio/mp3' )
38
+
39
+ processor.process_request( req )
40
+
41
+ related = req.related_resources
42
+ expect( related.size ).to eq( 1 )
43
+ expect( related.values.first ).
44
+ to include( 'format' => 'image/jpeg', 'extent' => 7369, 'relationship' => 'album-art' )
45
+ expect( related.keys.first ).to respond_to( :read )
46
+ end
47
+
48
+ end
49
+
50
+ # vim: set nosta noet ts=4 sw=4 ft=rspec:
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../helpers'
4
+
5
+ require 'rspec'
6
+ require 'thingfish/processor'
7
+
8
+
9
+ describe Thingfish::Processor do
10
+
11
+ before( :all ) do
12
+ setup_logging()
13
+ end
14
+
15
+
16
+ it "has pluggability" do
17
+ expect( described_class.plugin_type ).to eq( 'Processor' )
18
+ end
19
+
20
+
21
+ it "defines a (no-op) method for handling requests" do
22
+ expect {
23
+ described_class.new.on_request( nil )
24
+ }.to_not raise_error
25
+ end
26
+
27
+
28
+ it "defines a (no-op) method for handling responses" do
29
+ expect {
30
+ described_class.new.on_response( nil )
31
+ }.to_not raise_error
32
+ end
33
+
34
+
35
+ describe "a subclass" do
36
+
37
+ let!( :subclass ) { Class.new(described_class) }
38
+
39
+ it "can declare a list of media types it handles" do
40
+ subclass.handled_types( 'image/*', 'video/*' )
41
+ expect( subclass.handled_types.size ).to be( 2 )
42
+ expect( subclass.handled_types[0] ).to be_a( Strelka::HTTPRequest::MediaType )
43
+ end
44
+
45
+ describe "instance" do
46
+
47
+ let!( :instance ) do
48
+ subclass.handled_types( 'audio/mpeg', 'audio/mpg', 'audio/mp3' )
49
+ subclass.new
50
+ end
51
+
52
+
53
+ it "knows that it doesn't handle a type it hasn't registered" do
54
+ expect( instance ).to_not be_handled_type( 'image/png' )
55
+ expect( instance ).to be_handled_type( 'audio/mp3' )
56
+ end
57
+
58
+
59
+ end
60
+
61
+ end
62
+
63
+ end
64
+
65
+ # vim: set nosta noet ts=4 sw=4 ft=rspec:
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative 'helpers'
4
+
5
+ require 'rspec'
6
+ require 'thingfish'
7
+
8
+
9
+ describe Thingfish do
10
+
11
+ it "returns a version string if asked" do
12
+ expect( described_class.version_string ).to match( /\w+ [\d.]+/ )
13
+ end
14
+
15
+
16
+ it "returns a version string with a build number if asked" do
17
+ expect( described_class.version_string(true) ).
18
+ to match(/\w+ [\d.]+ \(build [[:xdigit:]]+\)/)
19
+ end
20
+
21
+ end
22
+
23
+ # vim: set nosta noet ts=4 sw=4 ft=rspec:
metadata ADDED
@@ -0,0 +1,244 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: thingfish
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0.pre20160707192835
5
+ platform: ruby
6
+ authors:
7
+ - Michael Granger
8
+ - Mahlon E. Smith
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain:
12
+ - |
13
+ -----BEGIN CERTIFICATE-----
14
+ MIIDMDCCAhigAwIBAgIBAjANBgkqhkiG9w0BAQUFADA+MQwwCgYDVQQDDANnZWQx
15
+ GTAXBgoJkiaJk/IsZAEZFglGYWVyaWVNVUQxEzARBgoJkiaJk/IsZAEZFgNvcmcw
16
+ HhcNMTYwNjAyMDE1NTQ2WhcNMTcwNjAyMDE1NTQ2WjA+MQwwCgYDVQQDDANnZWQx
17
+ GTAXBgoJkiaJk/IsZAEZFglGYWVyaWVNVUQxEzARBgoJkiaJk/IsZAEZFgNvcmcw
18
+ ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDb92mkyYwuGBg1oRxt2tkH
19
+ +Uo3LAsaL/APBfSLzy8o3+B3AUHKCjMUaVeBoZdWtMHB75X3VQlvXfZMyBxj59Vo
20
+ cDthr3zdao4HnyrzAIQf7BO5Y8KBwVD+yyXCD/N65TTwqsQnO3ie7U5/9ut1rnNr
21
+ OkOzAscMwkfQxBkXDzjvAWa6UF4c5c9kR/T79iA21kDx9+bUMentU59aCJtUcbxa
22
+ 7kcKJhPEYsk4OdxR9q2dphNMFDQsIdRO8rywX5FRHvcb+qnXC17RvxLHtOjysPtp
23
+ EWsYoZMxyCDJpUqbwoeiM+tAHoz2ABMv3Ahie3Qeb6+MZNAtMmaWfBx3dg2u+/WN
24
+ AgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBSZ0hCV
25
+ qoHr122fGKelqffzEQBhszANBgkqhkiG9w0BAQUFAAOCAQEAF2XCzjfTFxkcVvuj
26
+ hhBezFkZnMDYtWezg4QCkR0RHg4sl1LdXjpvvI59SIgD/evD1hOteGKsXqD8t0E4
27
+ OPAWWv/z+JRma72zeYsBZLSDRPIUvBoul6qCpvY0MiWTh496mFwOxT5lvSAUoh+U
28
+ pQ/MQeH/yC6hbGp7IYska6J8T4z5XkYqafYZ3eKQ8H+xPd/z+gYx+jd0PfkWf1Wk
29
+ QQdziL01SKBHf33OAH/p/puCpwS+ZDfgnNx5oMijWbc671UXkrt7zjD0kGakq+9I
30
+ hnfm736z8j1wvWddqf45++gwPpDr1E4zoAq2PgRl/WBNyR0hfoZLpi3TnHu3eC0x
31
+ uALKNA==
32
+ -----END CERTIFICATE-----
33
+ date: 2016-07-08 00:00:00.000000000 Z
34
+ dependencies:
35
+ - !ruby/object:Gem::Dependency
36
+ name: strelka
37
+ requirement: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '0.9'
42
+ type: :runtime
43
+ prerelease: false
44
+ version_requirements: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '0.9'
49
+ - !ruby/object:Gem::Dependency
50
+ name: mongrel2
51
+ requirement: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '0.43'
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '0.43'
63
+ - !ruby/object:Gem::Dependency
64
+ name: hoe-mercurial
65
+ requirement: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '1.4'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '1.4'
77
+ - !ruby/object:Gem::Dependency
78
+ name: hoe-deveiate
79
+ requirement: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '0.8'
84
+ type: :development
85
+ prerelease: false
86
+ version_requirements: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '0.8'
91
+ - !ruby/object:Gem::Dependency
92
+ name: hoe-highline
93
+ requirement: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '0.2'
98
+ type: :development
99
+ prerelease: false
100
+ version_requirements: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '0.2'
105
+ - !ruby/object:Gem::Dependency
106
+ name: rdoc
107
+ requirement: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '4.0'
112
+ type: :development
113
+ prerelease: false
114
+ version_requirements: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - "~>"
117
+ - !ruby/object:Gem::Version
118
+ version: '4.0'
119
+ - !ruby/object:Gem::Dependency
120
+ name: simplecov
121
+ requirement: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - "~>"
124
+ - !ruby/object:Gem::Version
125
+ version: '0.7'
126
+ type: :development
127
+ prerelease: false
128
+ version_requirements: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - "~>"
131
+ - !ruby/object:Gem::Version
132
+ version: '0.7'
133
+ - !ruby/object:Gem::Dependency
134
+ name: ruby-mp3info
135
+ requirement: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - "~>"
138
+ - !ruby/object:Gem::Version
139
+ version: '0.8'
140
+ type: :development
141
+ prerelease: false
142
+ version_requirements: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - "~>"
145
+ - !ruby/object:Gem::Version
146
+ version: '0.8'
147
+ - !ruby/object:Gem::Dependency
148
+ name: hoe
149
+ requirement: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - "~>"
152
+ - !ruby/object:Gem::Version
153
+ version: '3.15'
154
+ type: :development
155
+ prerelease: false
156
+ version_requirements: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - "~>"
159
+ - !ruby/object:Gem::Version
160
+ version: '3.15'
161
+ description: |-
162
+ Thingfish is a extensible, web-based digital asset manager. It can be used to
163
+ store chunks of data on the network in an application-independent way, link the
164
+ chunks together with metadata, and then search for the chunk you need later and
165
+ fetch it, all through a REST API.
166
+ email:
167
+ - ged@FaerieMUD.org
168
+ - mahlon@martini.nu
169
+ executables:
170
+ - tfprocessord
171
+ - thingfish
172
+ extensions: []
173
+ extra_rdoc_files:
174
+ - History.rdoc
175
+ - Manifest.txt
176
+ - README.rdoc
177
+ files:
178
+ - ".simplecov"
179
+ - History.rdoc
180
+ - LICENSE
181
+ - Manifest.txt
182
+ - Procfile
183
+ - README.rdoc
184
+ - Rakefile
185
+ - bin/tfprocessord
186
+ - bin/thingfish
187
+ - etc/thingfish.conf.example
188
+ - lib/strelka/app/metadata.rb
189
+ - lib/strelka/httprequest/metadata.rb
190
+ - lib/thingfish.rb
191
+ - lib/thingfish/behaviors.rb
192
+ - lib/thingfish/datastore.rb
193
+ - lib/thingfish/datastore/memory.rb
194
+ - lib/thingfish/handler.rb
195
+ - lib/thingfish/metastore.rb
196
+ - lib/thingfish/metastore/memory.rb
197
+ - lib/thingfish/mixins.rb
198
+ - lib/thingfish/processor.rb
199
+ - lib/thingfish/processor/mp3.rb
200
+ - lib/thingfish/processordaemon.rb
201
+ - lib/thingfish/spechelpers.rb
202
+ - spec/data/APIC-1-image.mp3
203
+ - spec/data/APIC-2-images.mp3
204
+ - spec/data/PIC-1-image.mp3
205
+ - spec/data/PIC-2-images.mp3
206
+ - spec/helpers.rb
207
+ - spec/spec.opts
208
+ - spec/thingfish/datastore/memory_spec.rb
209
+ - spec/thingfish/datastore_spec.rb
210
+ - spec/thingfish/handler_spec.rb
211
+ - spec/thingfish/metastore/memory_spec.rb
212
+ - spec/thingfish/metastore_spec.rb
213
+ - spec/thingfish/mixins_spec.rb
214
+ - spec/thingfish/processor/mp3_spec.rb
215
+ - spec/thingfish/processor_spec.rb
216
+ - spec/thingfish_spec.rb
217
+ homepage: http://bitbucket.org/ged/thingfish
218
+ licenses:
219
+ - BSD
220
+ - BSD
221
+ metadata: {}
222
+ post_install_message:
223
+ rdoc_options:
224
+ - "--main"
225
+ - README.rdoc
226
+ require_paths:
227
+ - lib
228
+ required_ruby_version: !ruby/object:Gem::Requirement
229
+ requirements:
230
+ - - ">="
231
+ - !ruby/object:Gem::Version
232
+ version: 2.0.0
233
+ required_rubygems_version: !ruby/object:Gem::Requirement
234
+ requirements:
235
+ - - ">"
236
+ - !ruby/object:Gem::Version
237
+ version: 1.3.1
238
+ requirements: []
239
+ rubyforge_project:
240
+ rubygems_version: 2.4.8
241
+ signing_key:
242
+ specification_version: 4
243
+ summary: Thingfish is a extensible, web-based digital asset manager
244
+ test_files: []