thingfish 0.5.0.pre20161103181816 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
data/Procfile DELETED
@@ -1,4 +0,0 @@
1
- # Foreman procfile
2
- mongrel: m2sh.rb -c etc/mongrel2.sqlite start
3
- thingfish: ruby -Ilib:../Thingfish-Datastore-Filesystem/lib:../Mongrel2/lib bin/thingfish etc/thingfish.conf
4
-
@@ -1,6 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'thingfish/processordaemon'
4
-
5
- Thingfish::ProcessorDaemon.run( ARGV )
6
-
@@ -1,26 +0,0 @@
1
- ---
2
- logging:
3
- __default__: debug STDERR
4
- thingfish: info (color)
5
-
6
- # Thingfish specific configuration.
7
- #
8
- thingfish:
9
- datastore: memory
10
- metastore: memory
11
-
12
- # The path to the Mongrel2 config database.
13
- #
14
- mongrel2:
15
- configdb: example/mongrel2.sqlite
16
-
17
- # Strelka configuration knobs that influence Thingfish's handler.
18
- #
19
- app:
20
- devmode: false
21
- app_glob_pattern: '{apps,handlers}/**/*'
22
- local_data_dirs: data/*
23
- multipartparser:
24
- bufsize: 524288
25
- spooldir: /var/folders/1f/6ymhh79s0n3gjdw16fj7tp480000gp/T/strelka-mimeparts
26
-
@@ -1,167 +0,0 @@
1
- # -*- ruby -*-
2
- #encoding: utf-8
3
-
4
- require 'mp3info'
5
-
6
- require 'thingfish' unless defined?( Thingfish )
7
- require 'thingfish/processor' unless defined?( Thingfish::Processor )
8
-
9
-
10
- # Attach ID3 data to an mp3, along with any embedded album art as a related resource.
11
- class Thingfish::Processor::MP3 < Thingfish::Processor
12
- extend Loggability
13
-
14
- # Loggability API -- log to the :thingfish logger
15
- log_to :thingfish
16
-
17
- # The list of handled types
18
- handled_types 'audio/mpeg', 'audio/mpg', 'audio/mp3'
19
-
20
-
21
- # Null character
22
- NULL = "\x0"
23
-
24
- # Attached picture "PIC"
25
- # Frame size $xx xx xx
26
- # ---- mp3info is 'helpfully' cropping out frame size.
27
- # Text encoding $xx
28
- # Image format $xx xx xx
29
- # Picture type $xx
30
- # Description <textstring> $00 (00)
31
- # Picture data <binary data>
32
- PIC_FORMAT = 'h a3 h Z* a*'
33
-
34
- # Attached picture "APIC"
35
- # Text encoding $xx
36
- # MIME type <text string> $00
37
- # Picture type $xx
38
- # Description <text string according to encoding> $00 (00)
39
- # Picture data <binary data>
40
- APIC_FORMAT = 'h Z* h Z* a*'
41
-
42
-
43
- ### Synchronous processor API -- extract metadata from uploaded MP3s
44
- def on_request( request )
45
- mp3info = Mp3Info.new( request.body )
46
-
47
- mp3_metadata = self.extract_id3_metadata( mp3info )
48
- request.add_metadata( mp3_metadata )
49
-
50
- self.extract_images( mp3info ) do |imageio, metadata|
51
- metadata[:title] = "Album art for %s - %s" % mp3_metadata.values_at( 'mp3:artist', 'mp3:title' )
52
- request.add_related_resource( imageio, metadata )
53
- end
54
- end
55
-
56
-
57
- ### Normalize metadata from the MP3Info object and return it as a hash.
58
- def extract_id3_metadata( mp3info )
59
- self.log.debug "Extracting MP3 metadata"
60
-
61
- mp3_metadata = {
62
- 'mp3:frequency' => mp3info.samplerate,
63
- 'mp3:bitrate' => mp3info.bitrate,
64
- 'mp3:vbr' => mp3info.vbr,
65
- 'mp3:title' => mp3info.tag.title,
66
- 'mp3:artist' => mp3info.tag.artist,
67
- 'mp3:album' => mp3info.tag.album,
68
- 'mp3:year' => mp3info.tag.year,
69
- 'mp3:genre' => mp3info.tag.genre,
70
- 'mp3:tracknum' => mp3info.tag.tracknum,
71
- 'mp3:comments' => mp3info.tag.comments,
72
- }
73
-
74
- # ID3V2 2.2.0 has three-letter tags, so map those if the artist info isn't set
75
- if mp3info.hastag2?
76
- if mp3_metadata['mp3:artist'].nil?
77
- self.log.debug " extracting old-style ID3v2 info" % [mp3info.tag2.version]
78
-
79
- mp3_metadata.merge!({
80
- 'mp3:title' => mp3info.tag2.TT2,
81
- 'mp3:artist' => mp3info.tag2.TP1,
82
- 'mp3:album' => mp3info.tag2.TAL,
83
- 'mp3:year' => mp3info.tag2.TYE,
84
- 'mp3:tracknum' => mp3info.tag2.TRK,
85
- 'mp3:comments' => mp3info.tag2.COM,
86
- 'mp3:genre' => mp3info.tag2.TCO,
87
- })
88
- end
89
- end
90
-
91
- self.log.debug " raw metadata: %p" % [ mp3_metadata ]
92
- return sanitize_values( mp3_metadata )
93
- end
94
-
95
-
96
- ### Extract image data from ID3 information, supports both APIC (2.3) and the older style
97
- ### PIC (2.2). Return value is a hash with IO keys and mimetype values.
98
- ### {
99
- ### io => { format => 'image/jpeg' }
100
- ### io2 => { format => 'image/jpeg' }
101
- ### }
102
- def extract_images( mp3info )
103
- self.log.debug "Extracting embedded images"
104
- raise LocalJumpError, "no block given" unless block_given?
105
-
106
- unless mp3info.hastag2?
107
- self.log.debug "...no id3v2 tag, so no embedded images possible."
108
- return
109
- end
110
-
111
- self.log.debug "...id3v2 tag present..."
112
-
113
- if mp3info.tag2.APIC
114
- self.log.debug "...extracting APIC (id3v2.3+) image data."
115
-
116
- images = [ mp3info.tag2.APIC ].flatten
117
- images.each do |img|
118
- blob, mime = img.unpack( APIC_FORMAT ).values_at( 4, 1 )
119
- yield( StringIO.new(blob),
120
- :format => mime,
121
- :extent => blob.length,
122
- :relationship => 'album-art' )
123
- end
124
-
125
- elsif mp3info.tag2.PIC
126
- self.log.debug "...extracting PIC (id3v2.2) image data."
127
-
128
- images = [ mp3info.tag2.PIC ].flatten
129
- images.each do |img|
130
- blob, type = img.unpack( PIC_FORMAT ).values_at( 4, 1 )
131
- mime = Mongrel2::Config.mimetypes[ ".#{type.downcase}" ] or next
132
- yield( StringIO.new(blob),
133
- :format => mime,
134
- :extent => blob.length,
135
- :relationship => 'album-art' )
136
- end
137
-
138
- else
139
- self.log.debug "...no known image tag types in tags: %p" % [ mp3info.tag2.keys.sort ]
140
- end
141
- end
142
-
143
-
144
-
145
- #######
146
- private
147
- #######
148
-
149
- ### Strip NULLs from the values of the given +metadata_hash+ and return it.
150
- def sanitize_values( metadata_hash )
151
- metadata_hash.each do |k,v|
152
- case v
153
- when String
154
- metadata_hash[k] = v.chomp(NULL).strip
155
- when Array
156
- metadata_hash[k] = v.collect {|vv| vv.chomp(NULL).strip }
157
- when Numeric, TrueClass, FalseClass
158
- # No-op
159
- end
160
- end
161
-
162
- return metadata_hash.delete_if {|_,v| v.nil? }
163
- end
164
-
165
-
166
- end # class Thingfish::Processor::MP3
167
-
@@ -1,16 +0,0 @@
1
- # -*- ruby -*-
2
- #encoding: utf-8
3
-
4
- require 'zmq'
5
- require 'configurability'
6
- require 'loggability'
7
-
8
- require 'thingfish' unless defined?( Thingfish )
9
-
10
-
11
- # Currently just a placeholder for what will eventually be the runner for
12
- # async processors.
13
- class Thingfish::ProcessorDaemon
14
- end # class Thingfish::ProcessorDaemon
15
-
16
-