spfy 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. checksums.yaml +6 -14
  2. data/README.md +24 -22
  3. data/bin/spfy +2 -1
  4. data/lib/spfy.rb +108 -201
  5. data/spfy.gemspec +12 -12
  6. data/test.sh +36 -0
  7. metadata +8 -7
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ZWYwZjMxOGMyZjUyYzlhZGU2MDc0NTllYTFiMGUzMWMyNTY0YWY3Nw==
5
- data.tar.gz: !binary |-
6
- MWUyMGIyZTQwNGUwNGU4M2IwNWQyOTNkY2FjZDljZjRlYmQwMzkzOA==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- Y2MzMzQzZmYwOGJmYmU1OTRiNzNiMDRlYmE3ZTlkOGRhZDRkZTJmYjNlNzFm
10
- MjNjMmM2ZWQ0ZmZiNTZiNzIzNTkxM2VlNDIyMmIyNThmYzQxMzQ1MWZkMjM5
11
- MjRmYWVkMjI5MzRhMDgxZWI4YmY5ZWU3OGI3MjIyOTVlZDA4MWE=
12
- data.tar.gz: !binary |-
13
- YmY2OTZmZmQ1ODJkZDc5ZTFhMDc4YzM2YzY2MTA2ZjMwYzNjZGFkMjVlOGFi
14
- NTA2YWM0YWEyM2ZkY2Q5NzBiN2EyYTliNzAwZWIyMjc3OGJiZjdkNmMyMTE0
15
- YWEzYmRhNTMwMTI5Yjg4NzMxYTk1Mjk2MGNkNTljZjkxZDQzMDM=
2
+ SHA1:
3
+ metadata.gz: 263a54780311ead337a8a6fa7af294972a71cce2
4
+ data.tar.gz: d024e138047f87c0b32fe67734f16aad97b30e5c
5
+ SHA512:
6
+ metadata.gz: f9da4cce5e4d769b51ac5cfed7798c676a42e2061b45774c78400195071eaf07b0615e9196d524b6916aedeef407ddcdfc63b573c38781f3e61bf041ba710d07
7
+ data.tar.gz: af57dea93b88002ca38f8d1ee2d666dc455c6375030eaa53695cdfa6af8ee91bd49b0f96164e7e6945c0dab32020f5eabba2475dbe9bda5434a0950c695af797
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
- #Spfy ("spiffy")
1
+ # Spfy ("spiffy")
2
2
 
3
- ##Overview
3
+ ## Overview
4
4
  **Spfy** is a command-line tool for generating [XSPF](http://xspf.org/) playlists from metadata stored in several popular audio formats and is developed entirely in [Ruby](http://www.ruby-lang.org/). It takes one or more local directory paths as input, extracts metadata tags from any audio files that it encounters, and generates a valid XSPF playlist.
5
5
 
6
- ##Prerequisites
6
+ ## Prerequisites
7
7
  A working Ruby installation (version 1.9 or greater) is required for Spfy to work, but this is outside the scope of this guide. For more information refer to the [official installation procedure](http://www.ruby-lang.org/en/downloads/).
8
8
 
9
9
  [TagLib](http://developer.kde.org/~wheeler/taglib.html) is also required. Follow the steps below (taken from the [taglib-ruby installation guide](http://robinst.github.com/taglib-ruby/)) to install the necessary files for your respective system type:
@@ -15,12 +15,12 @@ A working Ruby installation (version 1.9 or greater) is required for Spfy to wor
15
15
  | Brew | `brew install taglib` |
16
16
  | MacPorts | `sudo port install taglib` |
17
17
 
18
- ##Installation
18
+ ## Installation
19
19
  With the prerequisites above taken care of Spfy can be installed with the following command:
20
20
 
21
21
  $ gem install spfy
22
22
 
23
- ##Using Spfy
23
+ ## Using Spfy
24
24
  By default, Spfy will output a formatted XSPF playlist to the standard output stream that will include _location_, _title_, _creator_, _album_, and _trackNum_ elements for each audio file where available.
25
25
 
26
26
  The general syntax for Spfy is `spfy [options] dir1 ... dirN`, where _dir1 ... dirN_ is one or more paths to directories containing audio files.
@@ -31,19 +31,21 @@ For example:
31
31
 
32
32
  ..will produce the following output (where ~/music contains one audio file with valid metadata):
33
33
 
34
- <?xml version="1.0" encoding="UTF-8"?>
35
- <playlist version="1" xmlns="http://xspf.org/ns/0/">
36
- <trackList>
37
- <track>
38
- <location>file:///Users/spfy/music/03%20A%20Stitch%20In%20Time.mp3</location>
39
- <title>A Stitch In Time</title>
40
- <creator>The Smashing Pumpkins</creator>
41
- <album>Teargarden by Kaleidyscope</album>
42
- <trackNum>3</trackNum>
43
- </track>
44
- </trackList>
45
- </playlist>
46
-
34
+ ```xml
35
+ <?xml version="1.0" encoding="UTF-8"?>
36
+ <playlist version="1" xmlns="http://xspf.org/ns/0/">
37
+ <trackList>
38
+ <track>
39
+ <location>file:///Users/spfy/music/03%20A%20Stitch%20In%20Time.mp3</location>
40
+ <title>A Stitch In Time</title>
41
+ <creator>The Smashing Pumpkins</creator>
42
+ <album>Teargarden by Kaleidyscope</album>
43
+ <trackNum>3</trackNum>
44
+ </track>
45
+ </trackList>
46
+ </playlist>
47
+ ```
48
+
47
49
  Spfy supports multiple directory paths (e.g. `spfy /dir1 /dir2`) and traverses each directory recursively by default. Unsupported files and empty directories in a directory tree are silently ignored and will not impact Spfy's output.
48
50
 
49
51
  Command-line arguments allow you to control which elements Spfy outputs:
@@ -56,13 +58,13 @@ Command-line arguments allow you to control which elements Spfy outputs:
56
58
 
57
59
  For additional options use `spfy --help`.
58
60
 
59
- ##License
61
+ ## License
60
62
  Spfy is free software, and you are welcome to redistribute it under certain conditions. See the [GNU General Public License](http://www.gnu.org/licenses/gpl.html) for more details.
61
63
 
62
- ##Acknowledgments
64
+ ## Acknowledgments
63
65
  Spfy uses the following third party software components:
64
66
 
65
67
  * [taglib-ruby](http://robinst.github.com/taglib-ruby/) by Robin Stocker
66
68
 
67
- ##Comments or suggestions?
68
- Email me at [marc.ransome@fidgetbox.co.uk](marc.ransome@fidgetbox.co.uk) with bug reports, feature requests or general comments and follow [@marcransome](http://www.twitter.com/marcransome) for updates.
69
+ ## Comments or suggestions?
70
+ Email me at [marc.ransome@fidgetbox.co.uk](mailto://marc.ransome@fidgetbox.co.uk) with bug reports, feature requests or general comments and follow [@marcransome](http://www.twitter.com/marcransome) for updates.
data/bin/spfy CHANGED
@@ -2,4 +2,5 @@
2
2
 
3
3
  require 'spfy'
4
4
 
5
- Spfy.generate
5
+ Spfy.parse_args
6
+ Spfy.generate_xml
data/lib/spfy.rb CHANGED
@@ -23,208 +23,115 @@ require "spfy/optionreader"
23
23
  require "optparse"
24
24
  require "ostruct"
25
25
  require "taglib"
26
- require 'find'
27
- require 'uri'
26
+ require "find"
27
+ require "uri"
28
28
 
29
- # The main Spfy class
30
29
  class Spfy
31
-
32
- VERSION = "0.2.2"
30
+
31
+ VERSION = "1.0.0"
32
+ USAGE = "Use `#{File.basename($0)} --help` for available options."
33
+
34
+ @xspf_tags = {
35
+ :header => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"\
36
+ "<playlist version=\"1\" xmlns=\"http://xspf.org/ns/0/\">\n"\
37
+ "\t<trackList>\n",
38
+ :footer => "\t</trackList>\n</playlist>\n",
39
+ :title_start => "\t\t\t<title>",
40
+ :title_end => "</title>\n",
41
+ :creator_start => "\t\t\t<creator>",
42
+ :creator_end => "</creator>\n",
43
+ :album_start => "\t\t\t<album>",
44
+ :album_end => "</album>\n",
45
+ :location_start => "\t\t\t<location>file://",
46
+ :location_end => "</location>\n",
47
+ :track_start => "\t\t<track>\n",
48
+ :track_end => "\t\t</track>\n",
49
+ :track_num_start => "\t\t\t<trackNum>",
50
+ :track_num_end => "</trackNum>\n"
51
+ }
52
+
53
+ def self.parse_args
54
+ begin
55
+ # test for zero arguments
56
+ if ARGV.empty? then
57
+ self.exit_with_banner
58
+ end
59
+
60
+ # parse command-line arguments
61
+ @options = OptionReader.parse(ARGV)
62
+
63
+ # test for zero source paths
64
+ if @options.dirs.empty?
65
+ exit_with_message("No source path(s) specified.")
66
+ end
67
+
68
+ rescue OptionParser::InvalidOption, OptionParser::MissingArgument => error
69
+ exit_with_message(error.to_s.capitalize)
70
+ end
71
+ end
72
+
73
+ def self.generate_xml
33
74
 
34
- ##
35
- # Starts the XSPF generator.
36
- #
37
- def self.generate
75
+ if @options.output.any?
76
+ puts "Generating XML..."
77
+ self.capture_stdout
78
+ end
79
+
80
+ puts @xspf_tags[:header]
81
+ tracks_processed = 0
82
+
83
+ @options.dirs.each do |dir|
84
+ begin
85
+ Find.find(dir) do |path|
86
+ TagLib::FileRef.open(path) do |fileref|
87
+ tag = fileref.tag
88
+
89
+ next if tag.nil? # skip files with no tags
90
+
91
+ puts "#{@xspf_tags[:track_start]}"
92
+
93
+ if !@options.hide_location
94
+ encoded_path = URI.escape(path).sub("%5C", "/") # percent encode string for local path
95
+ puts "#{@xspf_tags[:location_start]}#{encoded_path}#{@xspf_tags[:location_end]}"
96
+ end
97
+
98
+ puts "#{@xspf_tags[:title_start]}#{tag.title}#{@xspf_tags[:title_end]}" if !@options.hide_title and !tag.title.nil?
99
+ puts "#{@xspf_tags[:creator_start]}#{tag.artist}#{@xspf_tags[:creator_end]}" if !@options.hide_artist and !tag.artist.nil?
100
+ puts "#{@xspf_tags[:album_start]}#{tag.album}#{@xspf_tags[:album_end]}" if !@options.hide_album and !tag.album.nil?
101
+
102
+ if !@options.hide_tracknum and !tag.track.nil?
103
+ if tag.track > 0
104
+ puts "#{@xspf_tags[:track_num_start]}#{tag.track}#{@xspf_tags[:track_num_end]}"
105
+ end
106
+ end
107
+
108
+ puts "#{@xspf_tags[:track_end]}"
109
+
110
+ tracks_processed += 1
111
+ break if @options.tracks_to_process[0].to_i > 0 and tracks_processed == options.tracks_to_process[0].to_i
112
+ end
113
+ end
114
+ rescue Interrupt
115
+ abort("\nCancelled, exiting..")
116
+ end
117
+ end
118
+ puts @xspf_tags[:footer]
119
+
120
+ $stdout = STDOUT if @options.output.any?
121
+ end
38
122
 
39
- # start processing command line arguments
40
- begin
41
-
42
- # short usage banner
43
- simple_usage = "Use `#{File.basename($0)} --help` for available options."
44
-
45
- # test for zero arguments
46
- if ARGV.empty? then
47
- puts simple_usage
48
- exit
49
- end
50
-
51
- # parse command-line arguments
52
- options = OptionReader.parse(ARGV)
53
-
54
- # dirs for traversing
55
- dirs = options.dirs
56
-
57
- # test for zero source paths
58
- if dirs.empty?
59
- puts "No source path specified."
60
- puts simple_usage
61
- exit
62
- end
63
-
64
- rescue OptionParser::InvalidOption => t
65
- puts t
66
- puts simple_usage
67
- exit
68
- rescue OptionParser::MissingArgument => m
69
- puts m
70
- puts simple_usage
71
- exit
72
- end
73
-
74
- # start processing source paths
75
- if options.output.any?
76
- # source path(s) provided, output should be to disk
77
-
78
- # open output file for writing
79
- begin
80
- xmlFile = File.open(options.output[0], "w")
81
- rescue
82
- puts "Unable to open output file for writing."
83
- puts simple_usage
84
- exit
85
- end
86
-
87
- print "Generating XML.."
88
-
89
- # write XSPF header
90
- xmlFile.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
91
- xmlFile.write("<playlist version=\"1\" xmlns=\"http://xspf.org/ns/0/\">\n")
92
- xmlFile.write("\t<trackList>\n")
93
-
94
- # track count for track limit option
95
- tracks_processed = 0
96
-
97
- # repeat for each source dir argument
98
- dirs.each do |dir|
99
-
100
- begin
101
-
102
- # repeat for each file recursively
103
- Find.find(dir) do |path|
104
-
105
- TagLib::FileRef.open(path) do |fileref|
106
-
107
- tag = fileref.tag
108
-
109
- # skip files with no tags
110
- next if tag.nil?
111
-
112
- # write track metadata
113
- xmlFile.write("\t\t<track>\n")
114
-
115
- if !options.hide_location
116
- # generate a percent encoded string from the local path
117
- encoded_path = URI.escape(path).sub("%5C", "/")
118
- xmlFile.write("\t\t\t<location>file://#{encoded_path}</location>\n")
119
- end
120
-
121
- xmlFile.write("\t\t\t<title>#{tag.title}</title>\n") if !options.hide_title and !tag.title.nil?
122
- xmlFile.write("\t\t\t<creator>#{tag.artist}</creator>\n") if !options.hide_artist and !tag.artist.nil?
123
- xmlFile.write("\t\t\t<album>#{tag.album}</album>\n") if !options.hide_album and !tag.album.nil?
124
-
125
- if !options.hide_tracknum and !tag.track.nil?
126
- if tag.track > 0
127
- xmlFile.write("\t\t\t<trackNum>#{tag.track}</trackNum>\n")
128
- end
129
- end
130
-
131
- xmlFile.write("\t\t</track>\n")
132
-
133
- # increment our track processed count
134
- tracks_processed += 1
135
-
136
- # if a maximum number track numbe has been set, test whether we have reached the limit
137
- if options.tracks_to_process[0].to_i > 0 and tracks_processed == options.tracks_to_process[0].to_i
138
- # write XSPF footer
139
- xmlFile.write("\t</trackList>\n")
140
- xmlFile.write("</playlist>\n")
141
- xmlFile.close
142
- print " success\n"
143
- exit
144
- end
145
- end
146
- end
147
- rescue Interrupt
148
- abort("\nCancelled, exiting..")
149
- end # begin
150
- end # dirs.each do |dir|
151
-
152
- # write XSPF footer
153
- xmlFile.write("\t</trackList>\n")
154
- xmlFile.write("</playlist>\n")
155
-
156
- xmlFile.close
157
-
158
- print " success\n"
159
-
160
- else
161
- # no source path(s) provided, output to stdout
162
-
163
- # write XSPF header
164
- puts "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
165
- puts "<playlist version=\"1\" xmlns=\"http://xspf.org/ns/0/\">\n"
166
- puts "\t<trackList>\n"
167
-
168
- # track count for track limit option
169
- tracks_processed = 0
170
-
171
- # repeat for each source dir argument
172
- dirs.each do |dir|
173
-
174
- begin
175
-
176
- # repeat for each file recursively
177
- Find.find(dir) do |path|
178
-
179
- TagLib::FileRef.open(path) do |fileref|
180
-
181
- tag = fileref.tag
182
-
183
- # skip files with no tags
184
- next if tag.nil?
185
-
186
- # output track metadata
187
- puts "\t\t<track>\n"
188
-
189
- if !options.hide_location
190
- encoded_path = URI.escape(path).sub("%5C", "/")
191
- puts "\t\t\t<location>file://#{encoded_path}</location>\n"
192
- end
193
-
194
- puts "\t\t\t<title>#{tag.title}</title>\n" if !options.hide_title and !tag.title.nil?
195
- puts "\t\t\t<creator>#{tag.artist}</creator>\n" if !options.hide_artist and !tag.artist.nil?
196
- puts "\t\t\t<album>#{tag.album}</album>\n" if !options.hide_album and !tag.album.nil?
197
-
198
- if !options.hide_tracknum and !tag.track.nil?
199
- if tag.track > 0
200
- puts "\t\t\t<trackNum>#{tag.track}</trackNum>\n"
201
- end
202
- end
203
-
204
- puts "\t\t</track>\n"
205
-
206
- # increment our track processed count
207
- tracks_processed += 1
208
-
209
- # if a maximum number track numbe has been set, test whether we have reached the limit
210
- if options.tracks_to_process[0].to_i > 0 and tracks_processed == options.tracks_to_process[0].to_i
211
- # output XSPF footer
212
- puts "\t</trackList>\n"
213
- puts "</playlist>\n"
214
- exit
215
- end
216
- end
217
- end
218
- rescue Interrupt
219
- abort("\nCancelled, exiting..")
220
- end # begin
221
- end # dirs.each do |dir|
222
-
223
- # write XSPF footer
224
- puts "\t</trackList>\n"
225
- puts "</playlist>\n"
226
- end
227
-
228
- end # def self.generate
229
-
230
- end # class Spyf
123
+ def self.exit_with_message(message)
124
+ puts message if message
125
+ exit_with_banner
126
+ end
127
+
128
+ def self.exit_with_banner
129
+ puts USAGE
130
+ exit
131
+ end
132
+
133
+ def self.capture_stdout
134
+ $stdout = File.open(@options.output[0], "w")
135
+ end
136
+
137
+ end
data/spfy.gemspec CHANGED
@@ -20,16 +20,16 @@
20
20
  # along with Spfy. If not, see <http://www.gnu.org/licenses/>.
21
21
 
22
22
  Gem::Specification.new do |s|
23
- s.name = 'spfy'
24
- s.version = '0.2.2'
25
- s.date = '2013-02-26'
26
- s.summary = 'XSPF playlist generator'
27
- s.description = 'Spfy is a simple command-line tool for generating XSPF playlists from metadata stored in several popular audio formats.'
28
- s.authors = ["Marc Ransome"]
29
- s.email = 'marc.ransome@fidgetbox.co.uk'
30
- s.files = `git ls-files`.split("\n")
31
- s.executables << 'spfy'
32
- s.add_runtime_dependency 'taglib-ruby', '>= 0.5.0'
33
- s.homepage = 'http://marcransome.github.com/spfy'
34
- s.license = 'GPL-3'
23
+ s.name = 'spfy'
24
+ s.version = '0.3.0'
25
+ s.date = '2013-07-28'
26
+ s.summary = 'XSPF playlist generator'
27
+ s.description = 'Spfy is a simple command-line tool for generating XSPF playlists from metadata stored in several popular audio formats.'
28
+ s.authors = ["Marc Ransome"]
29
+ s.email = 'marc.ransome@fidgetbox.co.uk'
30
+ s.files = `git ls-files`.split("\n")
31
+ s.executables << 'spfy'
32
+ s.add_runtime_dependency 'taglib-ruby', '>= 0.5.0'
33
+ s.homepage = 'http://marcransome.github.com/spfy'
34
+ s.license = 'GPL-3'
35
35
  end
data/test.sh ADDED
@@ -0,0 +1,36 @@
1
+ #!/bin/bash
2
+ #
3
+ # test.sh
4
+ # Spfy ("spiffy")
5
+ #
6
+ # Copyright (c) 2012, Marc Ransome <marc.ransome@fidgetbox.co.uk>
7
+ #
8
+ # This file is part of Spfy.
9
+ #
10
+ # Spfy is free software: you can redistribute it and/or modify
11
+ # it under the terms of the GNU General Public License as published by
12
+ # the Free Software Foundation, either version 3 of the License, or
13
+ # (at your option) any later version.
14
+ #
15
+ # Spfy is distributed in the hope that it will be useful,
16
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
+ # GNU General Public License for more details.
19
+ #
20
+ # You should have received a copy of the GNU General Public License
21
+ # along with Spfy. If not, see <http://www.gnu.org/licenses/>.
22
+
23
+ version_from_gemspec=$( grep 's.version' spfy.gemspec | cut -c 16-20 )
24
+ gem_file="spfy-$version_from_gemspec.gem"
25
+
26
+ echo "Removing outdated gem files.."
27
+ rm *.gem
28
+
29
+ echo "Uninstalling previous versions.."
30
+ gem uninstall -a -x spfy
31
+
32
+ echo "Building gem.."
33
+ gem build spfy.gemspec
34
+
35
+ echo "Installing gem file.."
36
+ gem install $gem_file
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spfy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marc Ransome
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-02-26 00:00:00.000000000 Z
11
+ date: 2013-07-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: taglib-ruby
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ! '>='
17
+ - - '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: 0.5.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ! '>='
24
+ - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.5.0
27
27
  description: Spfy is a simple command-line tool for generating XSPF playlists from
@@ -38,6 +38,7 @@ files:
38
38
  - lib/spfy.rb
39
39
  - lib/spfy/optionreader.rb
40
40
  - spfy.gemspec
41
+ - test.sh
41
42
  homepage: http://marcransome.github.com/spfy
42
43
  licenses:
43
44
  - GPL-3
@@ -48,17 +49,17 @@ require_paths:
48
49
  - lib
49
50
  required_ruby_version: !ruby/object:Gem::Requirement
50
51
  requirements:
51
- - - ! '>='
52
+ - - '>='
52
53
  - !ruby/object:Gem::Version
53
54
  version: '0'
54
55
  required_rubygems_version: !ruby/object:Gem::Requirement
55
56
  requirements:
56
- - - ! '>='
57
+ - - '>='
57
58
  - !ruby/object:Gem::Version
58
59
  version: '0'
59
60
  requirements: []
60
61
  rubyforge_project:
61
- rubygems_version: 2.0.0
62
+ rubygems_version: 2.0.6
62
63
  signing_key:
63
64
  specification_version: 4
64
65
  summary: XSPF playlist generator