music_meta_fixer 0.0.1

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: 1e00914b7ebaff094156bd180a5da95450c4985e
4
+ data.tar.gz: d6ea2c04a3ec6dd37f2d654ced6827bac346811c
5
+ SHA512:
6
+ metadata.gz: 0ddea86194905d8077cdae4c3c8e3a07a220a6d4c5cecbf74545a7e3f6c358ec9d6baff176b8775bee5a41aed914c0dd5d32c727ebbdb543e8a6aeb63bfa1185
7
+ data.tar.gz: 3a6a037b2a8904631e4808870a47986daa96112215c8bf6bc89262422408c76ec75796369da6ad126e38fd2441f03e9520cb0c178f2794e07d9ed7258cbe386b
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.vim
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in music_meta_fixer.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Michael Villena
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,16 @@
1
+ # MusicMetaFixer
2
+
3
+ Somewhat manual, somewhat automated way of updating the metadata of the music
4
+ in your iTunes Library.
5
+
6
+ # Install
7
+
8
+ $ gem install music_meta_fixer
9
+
10
+ ## How to Use?
11
+
12
+ In your CLI:
13
+
14
+ $ music_meta_fixer
15
+
16
+ ![DatSceenTho](/screenshots/screen1.png)
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << 'test'
6
+ t.test_files = FileList['test/*test.rb']
7
+ end
8
+
9
+ desc "Run tests"
10
+ task :test
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'music_meta_fixer'
3
+
4
+ MusicMetaFixer.run
@@ -0,0 +1,28 @@
1
+ module MusicMetaFixer
2
+ module ItunesAPI
3
+ ITUNES_API_URL = 'https://itunes.apple.com/search?'
4
+ LIMIT = 1
5
+ MEDIA = 'music'
6
+
7
+ def self.get_song_info(term)
8
+ encoded_term = URI::encode(term)
9
+ query = "term=#{encoded_term}&media=#{MEDIA}&limit=#{LIMIT}"
10
+ res = Typhoeus.get(ITUNES_API_URL + query)
11
+
12
+ if res.code == 200
13
+ json = JSON.parse res.body
14
+
15
+ if json["resultCount"].to_i > 0
16
+ song_info = json["results"].first
17
+ new_music = Song.new(song_info["trackName"])
18
+ new_music.artist = song_info["artistName"]
19
+ new_music.genre = song_info["primaryGenreName"]
20
+ new_music.album = song_info["collectionName"]
21
+ new_music.year = song_info["releaseDate"].split("-").first
22
+ return new_music
23
+ end
24
+ end
25
+ nil
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,74 @@
1
+ require 'nokogiri'
2
+ module MusicMetaFixer
3
+ class ItunesLibParser < Nokogiri::XML::SAX::Document
4
+ ITUNES_API = 'https://itunes.apple.com/search?'
5
+
6
+ ARTIST = 1
7
+ NAME = 2
8
+ LOCATION = 3
9
+
10
+ SONG_KEY_PATH = %w(plist dict dict dict key)
11
+ SONG_VALUE_STRING_PATH = %w(plist dict dict dict string)
12
+ SONG_VALUE_DATE_PATH = %w(plist dict dict dict integer)
13
+ SONG_END_PATH = %w(plist dict dict)
14
+
15
+
16
+ def initialize
17
+ @counter = 0
18
+ @path = []
19
+ # @longest_counter = File.read('counter.txt').to_i
20
+ end
21
+
22
+ def end_document
23
+ puts "Finished reading iTunesLibary file"
24
+ end
25
+
26
+ def start_element name, attributes = []
27
+ @path += [name]
28
+ end
29
+
30
+ def characters chars
31
+ if @path == SONG_KEY_PATH
32
+ if chars == "Location"
33
+ @key = LOCATION
34
+ else
35
+ @key = nil
36
+ end
37
+ elsif @path == SONG_VALUE_STRING_PATH && @key
38
+ if @key == LOCATION
39
+ @song_path = URI::decode(chars).gsub(/file:\/\/localhost/, "")
40
+ end
41
+ end
42
+ end
43
+
44
+ def end_element name
45
+ @path.pop
46
+ if @path == SONG_END_PATH && name == "dict"
47
+ @song = TagEditor.get_song_info(@song_path)
48
+
49
+ if @song
50
+ @new_song = ItunesAPI.get_song_info("#{@song.artist} #{@song.name}")
51
+
52
+ if @new_song
53
+ puts "######## OLD #######"
54
+ current_info = "Change:\n" + @song.pretty_string
55
+ puts current_info
56
+ puts "######## NEW ########\n"
57
+ puts @new_song.pretty_string
58
+
59
+ print "Change? "
60
+ answer = gets.chomp
61
+ if answer.match(/y/i)
62
+ puts "Changing #{@song.name} at #{@song_path}"
63
+ TagEditor.change_tag_info(@song_path, @new_song)
64
+ else
65
+ puts "Moving on"
66
+ end
67
+ puts ""
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ end
74
+ end
@@ -0,0 +1,17 @@
1
+ module MusicMetaFixer
2
+ class Song
3
+ attr_accessor :name, :artist, :location, :genre, :album, :album_artist, :year
4
+
5
+ def initialize name
6
+ @name = name
7
+ end
8
+
9
+ def pretty_string
10
+ "Artist: #{artist}\n" \
11
+ "Song: #{name}\n" \
12
+ "Genre: #{genre}\n" \
13
+ "Album: #{album}\n" \
14
+ "Year: #{year}"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,32 @@
1
+ module MusicMetaFixer
2
+ module TagEditor
3
+ def self.get_song_info(music_path)
4
+ current_song_info = nil
5
+ TagLib::FileRef.open(music_path) do |fileref|
6
+ unless fileref.null?
7
+ tag = fileref.tag
8
+ current_song_info = Song.new(tag.title)
9
+ current_song_info.artist = tag.artist
10
+ current_song_info.album = tag.album
11
+ current_song_info.genre = tag.genre
12
+ current_song_info.year = tag.year
13
+ end
14
+ end
15
+ current_song_info
16
+ end
17
+
18
+ def self.change_tag_info(music_path, song_info)
19
+ TagLib::FileRef.open(music_path) do |fileref|
20
+ unless fileref.null?
21
+ tag = fileref.tag
22
+ tag.title = song_info.name unless song_info.name == tag.title
23
+ tag.artist = song_info.artist unless song_info.artist == tag.artist
24
+ tag.album = song_info.album unless tag.album == song_info.album
25
+ tag.genre = song_info.genre unless tag.genre == song_info.genre
26
+ tag.year = song_info.year.to_i unless tag.year == song_info.year.to_i
27
+ fileref.save
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,3 @@
1
+ module MusicMetaFixer
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,22 @@
1
+ require 'music_meta_fixer/version'
2
+ require 'music_meta_fixer/song'
3
+ require 'music_meta_fixer/itunes_lib_parser'
4
+ require 'music_meta_fixer/itunes_api'
5
+ require 'music_meta_fixer/tag_editor'
6
+
7
+ require 'taglib'
8
+ require 'nokogiri'
9
+ require 'typhoeus'
10
+ require 'uri'
11
+ require 'open-uri'
12
+ require 'json'
13
+
14
+ module MusicMetaFixer
15
+ def self.run
16
+ parser = Nokogiri::XML::SAX::Parser.new(MusicMetaFixer::ItunesLibParser.new)
17
+ filepath = File.join(Dir.home, 'Music', 'iTunes', 'iTunes Music Library.xml')
18
+ file = File.open(filepath)
19
+ parser.parse file
20
+ file.close
21
+ end
22
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'music_meta_fixer/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "music_meta_fixer"
8
+ spec.version = MusicMetaFixer::VERSION
9
+ spec.authors = ["Michael Villena"]
10
+ spec.email = ["mavoir6@gmail.com"]
11
+ spec.description = %q{Somewhat automated iTunes meta data fixer. Built on Ruby 2.0}
12
+ spec.summary = %q{Fix your music on your Mac}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+
24
+ spec.add_runtime_dependency 'taglib-ruby', '~> 0.6.0'
25
+ spec.add_runtime_dependency 'nokogiri', '~> 1.6.0'
26
+ spec.add_runtime_dependency 'typhoeus', '~> 0.6.6'
27
+ end
Binary file
@@ -0,0 +1,26 @@
1
+ require 'test/unit'
2
+ require 'music_meta_fixer'
3
+
4
+ class MusicMetaFixerTest < Test::Unit::TestCase
5
+ def test_itunes_api
6
+ song_info = MusicMetaFixer::ItunesAPI.get_song_info("Hardwell Apollo")
7
+
8
+ assert_equal "Hardwell", song_info.artist
9
+ assert_equal "Apollo (feat. Amba Shepherd)", song_info.name
10
+ assert_equal "Dance" , song_info.genre
11
+ assert_equal "2012", song_info.year
12
+ assert_equal "Apollo (feat. Amba Shepherd) - Single", song_info.album
13
+ end
14
+
15
+ def test_tag_editor_getting_song_info
16
+ # TODO Fill in below
17
+ filepath = URI::decode('/path/to/Music/iTunes/iTunes%20Media/Music/Airbase/Pandemonium%20_%20Ocean%20Realm%20-%20Single/02%20Ocean%20Realm.m4p')
18
+ song_info = MusicMetaFixer::TagEditor.get_song_info(filepath)
19
+
20
+ assert_equal "Airbase", song_info.artist
21
+ assert_equal "Ocean Realm", song_info.name
22
+ assert_equal "Dance" , song_info.genre
23
+ assert_equal 2004, song_info.year
24
+ assert_equal "Pandemonium / Ocean Realm - Single", song_info.album
25
+ end
26
+ end
metadata ADDED
@@ -0,0 +1,131 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: music_meta_fixer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Michael Villena
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-21 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.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: taglib-ruby
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 0.6.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 0.6.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: nokogiri
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.6.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 1.6.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: typhoeus
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: 0.6.6
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: 0.6.6
83
+ description: Somewhat automated iTunes meta data fixer. Built on Ruby 2.0
84
+ email:
85
+ - mavoir6@gmail.com
86
+ executables:
87
+ - music_meta_fixer
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - .gitignore
92
+ - Gemfile
93
+ - LICENSE.txt
94
+ - README.md
95
+ - Rakefile
96
+ - bin/music_meta_fixer
97
+ - lib/music_meta_fixer.rb
98
+ - lib/music_meta_fixer/itunes_api.rb
99
+ - lib/music_meta_fixer/itunes_lib_parser.rb
100
+ - lib/music_meta_fixer/song.rb
101
+ - lib/music_meta_fixer/tag_editor.rb
102
+ - lib/music_meta_fixer/version.rb
103
+ - music_meta_fixer.gemspec
104
+ - screenshots/screen1.png
105
+ - test/music_meta_fixer_test.rb
106
+ homepage: ''
107
+ licenses:
108
+ - MIT
109
+ metadata: {}
110
+ post_install_message:
111
+ rdoc_options: []
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - '>='
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ requirements: []
125
+ rubyforge_project:
126
+ rubygems_version: 2.0.3
127
+ signing_key:
128
+ specification_version: 4
129
+ summary: Fix your music on your Mac
130
+ test_files:
131
+ - test/music_meta_fixer_test.rb