icemaker 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []