icemaker 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c9704bb75c9c106080a4816897bffb3c9edf9953
4
+ data.tar.gz: 38727cf25913f22bb78e87b87ab3f10ad5549e38
5
+ SHA512:
6
+ metadata.gz: c44e11e086d03248c277dc4cd5fcec8a0bda44c4afd2b1807c742f2ed131cfe85c5d9a588b52b0362e5b3d830e3b9bb04e763773230e4306b1ad17d595fdcc10
7
+ data.tar.gz: 556f996c0971dbe5df781db0c90eb2ab548c58600f3e50bef48d5744be366ccbfad0416f4de99ebe7d30175f5c438700195e0be43ea4f5283f5e8164db9d4bce
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ .gem
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.3
4
+ before_install: gem install bundler -v 1.10.6
5
+
6
+ notifications:
7
+ slack: smallisystems:qYVSKbwENqCV6qT6WeOpZb5J
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in icemaker.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,33 @@
1
+ # Icemaker
2
+
3
+ Create playlists by applying customized search filters to a set of audio files.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'icemaker'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install icemaker
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Development
26
+
27
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
28
+
29
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
30
+
31
+ ## Contributing
32
+
33
+ Bug reports and pull requests are welcome on GitHub at https://github.com/twocats/icemaker.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :test
data/bin/icemaker ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'icemaker'
4
+
5
+ load 'Icefile'
data/icemaker.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 'icemaker/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "icemaker"
8
+ spec.version = Icemaker::VERSION
9
+ spec.authors = ["twocats"]
10
+ spec.email = ["twocats@smallisystems.com"]
11
+
12
+ spec.summary = "Create playlists by applying customized search filters to a set of audio files."
13
+ spec.homepage = "https://github.com/twocats/icemaker.git"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
+ spec.bindir = "bin"
17
+ spec.executables = "icemaker"
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.10"
21
+ spec.add_development_dependency "rake", "~> 10.0"
22
+ spec.add_development_dependency "minitest"
23
+
24
+ spec.add_runtime_dependency 'taglib-ruby', ">= 0.7.0"
25
+
26
+ end
data/lib/icemaker.rb ADDED
@@ -0,0 +1,11 @@
1
+ require 'taglib'
2
+ require "icemaker/version"
3
+ require 'icemaker/filter'
4
+ require 'icemaker/query'
5
+ require 'icemaker/icemaker'
6
+
7
+ class String
8
+ def has(params)
9
+ self.index params[:substring]
10
+ end
11
+ end
@@ -0,0 +1,97 @@
1
+ module IceMaker
2
+
3
+ class Filter
4
+
5
+ attr_writer :tag_value
6
+
7
+ def regx
8
+ if @value_to_test.instance_of? Hash then
9
+
10
+ operator = @value_to_test.keys[0]
11
+ values = @value_to_test.values[0]
12
+
13
+ case operator
14
+ when :or, :union_of
15
+ values.any? { |value| @tag_value =~ (Regexp.new value) }
16
+ when :and, :intersection_of
17
+ values.all? { |value| @tag_value =~ (Regexp.new value) }
18
+ end
19
+
20
+ else
21
+ @tag_value =~ (Regexp.new @value_to_test)
22
+ end
23
+
24
+ end
25
+
26
+ def satisfies
27
+ regx
28
+ end
29
+
30
+ def has
31
+ if @value_to_test.instance_of? Hash then
32
+
33
+ operator = @value_to_test.keys[0]
34
+ values = @value_to_test.values[0]
35
+
36
+ case operator
37
+ when :or, :union_of
38
+ values.any? { |value| @tag_value.downcase.has substring: value.downcase }
39
+ when :and, :intersection_of
40
+ values.all? { |value| @tag_value.downcase.has substring: value.downcase }
41
+ end
42
+
43
+ else
44
+ @tag_value.downcase.has substring: @value_to_test.downcase
45
+ end
46
+ end
47
+
48
+ def contains
49
+ has
50
+ end
51
+
52
+ def is
53
+ if @value_to_test.instance_of? Hash then
54
+
55
+ operator = @value_to_test.keys[0]
56
+ values = @value_to_test.values[0]
57
+
58
+ puts "error in filter, #{@tag_value} :is #{@value_to_test}; applying 'or' rather than 'and' for :is" if (operator == :and || operator == :intersection_of)
59
+
60
+ values.any? { |value| @tag_value.downcase == value.downcase }
61
+ else
62
+ @tag_value.downcase == @value_to_test.downcase
63
+ end
64
+ end
65
+
66
+ def eq
67
+ is
68
+ end
69
+
70
+ def lte
71
+ @tag_value <= @value_to_test
72
+ end
73
+
74
+ def gte
75
+ @tag_value >= @value_to_test
76
+ end
77
+
78
+ def lt
79
+ @tag_value < @value_to_test
80
+ end
81
+
82
+ def gt
83
+ @tag_value > @value_to_test
84
+ end
85
+
86
+ def pass?
87
+ self.send @test
88
+ end
89
+
90
+ def initialize(tag, value_to_test, test)
91
+ @tag = tag
92
+ @value_to_test = value_to_test
93
+ @test = test
94
+ @tag_value = ''
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,133 @@
1
+ module IceMaker
2
+
3
+ VALID_MEDIA_EXTENSIONS = [".mp3", ".ogg", ".flac"]
4
+ UNKNOWN_VALUE = 'unknown'
5
+
6
+ class Playlist
7
+
8
+ def self.filter_tracks
9
+
10
+ @@filtered = ((Query.new with: @@icefile.filters).find in: @@tracks)
11
+
12
+ verbalize "#{@@filtered.length} tracks found."
13
+
14
+ end
15
+
16
+ def self.make_tracks_from_files
17
+
18
+ @@tracks = []
19
+
20
+ @@files.each do |file|
21
+
22
+ TagLib::FileRef.open(file) do |info|
23
+
24
+ unless info.null?
25
+
26
+ @@tracks << {
27
+ file: file,
28
+ title: info.tag.title ? info.tag.title : UNKNOWN_VALUE,
29
+ artist: info.tag.artist ? info.tag.artist : UNKNOWN_VALUE,
30
+ album: info.tag.album ? info.tag.album : UNKNOWN_VALUE,
31
+ genre: info.tag.genre ? info.tag.genre : UNKNOWN_VALUE,
32
+ year: info.tag.year ? info.tag.year : UNKNOWN_VALUE,
33
+ length: info.audio_properties.length ? info.audio_properties.length : 0,
34
+ bitrate: info.audio_properties.bitrate ? info.audio_properties.bitrate : 0,
35
+ channels: info.audio_properties.channels ? info.audio_properties.channels : 0,
36
+ sample_rate: info.audio_properties.sample_rate ? info.audio_properties.sample_rate : 0
37
+ }
38
+
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ def self.collect_files
45
+
46
+ @@files = []
47
+
48
+ @@icefile.sources.each do |source|
49
+
50
+ @@files << (get_entries from: source, and_recurse_into_if: @@icefile.is_recursive)
51
+
52
+ end
53
+
54
+ @@files.flatten!.map! { |file| "#{@@icefile.arbitrary_file_prefix}#{file}"}
55
+
56
+ @@files.uniq! if @@icefile.unique
57
+
58
+ end
59
+
60
+ def self.remove_non_audio_files
61
+
62
+ verbalize "#{@@files.length} total files found."
63
+
64
+ @@files.reject! { |file|
65
+ !(VALID_MEDIA_EXTENSIONS.include? (File.extname file).downcase) || (File.directory? file )
66
+ }
67
+
68
+ verbalize "#{@@files.length} audio files found."
69
+
70
+ end
71
+
72
+ def self.get_entries(params)
73
+
74
+ source = params[:from]
75
+ recurse = params[:and_recurse_into_if]
76
+
77
+ entries = []
78
+
79
+ if recurse
80
+ entries << Dir[File.join(source, "**", "*")]
81
+ else
82
+ entries << (Dir.entries source).reject! { |x| x == '..' || x == '.' }
83
+ entries.flatten!.map! { |file| "#{source}/#{file}"}
84
+ end
85
+
86
+ entries
87
+
88
+ end
89
+
90
+ def self.write_playlist
91
+ File.open(@@icefile.output_to_file, 'w') { |f| f.puts(@@formatted) }
92
+ end
93
+
94
+ def self.format_for_writing
95
+ @@formatted = @@filtered.map &@@icefile.formatter
96
+ end
97
+
98
+ def self.verbalize(some_words)
99
+ puts some_words if @@icefile.verbose
100
+ end
101
+
102
+ def self.make
103
+
104
+ @@icefile = Icefile.new
105
+
106
+ yield @@icefile
107
+
108
+ collect_files
109
+ remove_non_audio_files
110
+ make_tracks_from_files
111
+ filter_tracks
112
+ format_for_writing
113
+ write_playlist
114
+
115
+ end
116
+
117
+ class Icefile
118
+
119
+ attr_accessor :sources, :is_recursive, :unique, :verbose,
120
+ :output_to_file, :arbitrary_file_prefix, :filters, :formatter
121
+
122
+ def initialize
123
+ @sources = []
124
+ @filters = []
125
+ @verbose = false
126
+ @is_recursive = false
127
+ @unique = true
128
+ @arbitrary_file_prefix = ''
129
+ @formatter = lambda { |track| "#{track[:file]}"}
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,37 @@
1
+ module IceMaker
2
+
3
+ class Query
4
+
5
+ # TODO: THE NAMING/LANGUAGE IN THIS CLASS IS TEH SUCK
6
+
7
+ def find(params)
8
+
9
+ tracks = params[:in]
10
+
11
+ @filters.each { |expr|
12
+
13
+ tag = expr.keys[0]
14
+ value_to_test = expr.values[0].values[0]
15
+ operator = expr.values[0].keys[0]
16
+
17
+ filter = Filter.new tag, value_to_test, operator
18
+
19
+ tracks = tracks.select {
20
+
21
+ |track|
22
+
23
+ filter.tag_value = track[tag.to_sym]
24
+
25
+ filter.pass?
26
+ }
27
+ }
28
+
29
+ tracks
30
+
31
+ end
32
+
33
+ def initialize(params)
34
+ @filters = params[:with]
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,3 @@
1
+ module Icemaker
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: icemaker
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - twocats
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-12-16 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.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: taglib-ruby
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 0.7.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 0.7.0
69
+ description:
70
+ email:
71
+ - twocats@smallisystems.com
72
+ executables:
73
+ - icemaker
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - ".travis.yml"
79
+ - Gemfile
80
+ - README.md
81
+ - Rakefile
82
+ - bin/icemaker
83
+ - icemaker.gemspec
84
+ - lib/icemaker.rb
85
+ - lib/icemaker/filter.rb
86
+ - lib/icemaker/icemaker.rb
87
+ - lib/icemaker/query.rb
88
+ - lib/icemaker/version.rb
89
+ homepage: https://github.com/twocats/icemaker.git
90
+ licenses: []
91
+ metadata: {}
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ requirements: []
107
+ rubyforge_project:
108
+ rubygems_version: 2.4.8
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: Create playlists by applying customized search filters to a set of audio
112
+ files.
113
+ test_files: []