Skip to content

Instantly share code, notes, and snippets.

@Nemo157
Created August 7, 2015 02:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Nemo157/74bddea59e17332430b1 to your computer and use it in GitHub Desktop.
Save Nemo157/74bddea59e17332430b1 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
#
require 'active_support/multibyte/chars'
class String
def mb_chars
ActiveSupport::Multibyte::Chars.new(self)
end
end
module Enumerable
def full_outer_join_by others, &test
map { |item| [item, others.find { |other| test[item, other] }] } + others.reject { |other| find { |item| test[item, other] } }.map { |other| [null, other] }
end
alias_method :fojb, :full_outer_join_by
end
class OtherFile
attr_accessor :file, :ext, :name
def initialize parent, file
@parent = parent
@file = file
@ext = File.extname(file)
@name = File.basename(file, @ext).mb_chars.compose.to_s
end
end
class OtherFileDiff
attr_accessor :first, :second
def initialize first, second
@first = first
@second = second
end
def has_difference?
!@first || !@second
end
end
class SongFile
attr_accessor :file, :ext, :name
def initialize parent, file
@parent = parent
@file = file
@ext = File.extname(file)
@name = File.basename(file, @ext).mb_chars.compose.to_s
end
def self.is_song? file
ext = File.extname(file)
[".mp3", ".flac"].include?(ext)
end
end
class SongFileDiff
attr_accessor :first, :second
def initialize first, second
@first = first
@second = second
end
def has_difference?
!@first || !@second
end
end
class DiscDirectory
attr_accessor :dir, :name, :songs, :files
def initialize parent, folder
@parent = parent
@name = folder.mb_chars.compose.to_s
@dir = File.join(parent.dir, folder)
@songs = Dir.entries(@dir).reject { |file| file == '.DS_Store' }.select { |file| File.file? File.join(@dir, file) }.select{ |file| SongFile.is_song? File.join(@dir, file) }.map { |file| SongFile.new self, file }
@files = Dir.entries(@dir).reject { |file| file == '.DS_Store' }.select { |file| File.file? File.join(@dir, file) }.reject{ |file| SongFile.is_song? File.join(@dir, file) }.map { |file| OtherFile.new self, file }
end
end
class DiscDiff
attr_accessor :first, :second, :song_diffs, :file_diffs
def initialize first, second
@first = first
@second = second
if first && second
@song_diffs = first.songs
.fojb(second.songs) { |first_song, second_song| first_song.name == second_song.name }
.map { |first_song, second_song| SongFileDiff.new first_song, second_song }
@file_diffs = first.files
.fojb(second.files) { |first_file, second_file| first_file.name == second_file.name }
.map { |first_file, second_file| OtherFileDiff.new first_file, second_file }
elsif first
@song_diffs = first.songs
.map { |first_song| SongFileDiff.new first_song, nil }
@file_diffs = first.files
.map { |first_file| OtherFileDiff.new first_file, nil }
else
@song_diffs = second.songs
.map { |second_song| SongFileDiff.new nil, second_song }
@file_diffs = second.files
.map { |second_file| OtherFileDiff.new nil, second_file }
end
end
def has_difference?
!@first || !@second || @file_diffs.any { |file_diff| file_diff.has_difference? } || @song_diffs.any { |song_diff| song_diff.has_difference? }
end
end
class AlbumDirectory
attr_accessor :dir, :name, :discs, :songs, :files
def initialize parent, folder
@parent = parent
@name = folder.mb_chars.compose.to_s
@dir = File.join(parent.dir, folder)
@discs = Dir.entries(@dir).reject{ |subdir| subdir == '.' || subdir == '..' }.select { |subdir| File.directory? File.join(@dir, subdir) }.map { |subdir| DiscDirectory.new self, subdir }
@songs = Dir.entries(@dir).reject { |file| file == '.DS_Store' }.select { |file| File.file? File.join(@dir, file) }.select{ |file| SongFile.is_song? File.join(@dir, file) }.map { |file| SongFile.new self, file }
@files = Dir.entries(@dir).reject { |file| file == '.DS_Store' }.select { |file| File.file? File.join(@dir, file) }.reject{ |file| SongFile.is_song? File.join(@dir, file) }.map { |file| OtherFile.new self, file }
end
end
class AlbumDiff
attr_accessor :first, :second, :disc_diffs, :song_diffs, :file_diffs
def initialize first, second
@first = first
@second = second
if first && second
@disc_diffs = first.discs
.fojb(second.discs) { |first_disc, second_disc| first_disc.name == second_disc.name }
.map { |first_disc, second_disc| DiscDiff.new first_disc, second_disc }
@song_diffs = first.songs
.fojb(second.songs) { |first_song, second_song| first_song.name == second_song.name }
.map { |first_song, second_song| SongFileDiff.new first_song, second_song }
@file_diffs = first.files
.fojb(second.files) { |first_file, second_file| first_file.name == second_file.name }
.map { |first_file, second_file| OtherFileDiff.new first_file, second_file }
elsif first
@disc_diffs = first.discs
.map { |first_disc| DiscDiff.new first_disc, nil }
@song_diffs = first.songs
.map { |first_song| SongFileDiff.new first_song, nil }
@file_diffs = first.files
.map { |first_file| OtherFileDiff.new first_file, nil }
elsif second
@disc_diffs = second.discs
.map { |second_disc| DiscDiff.new nil, second_disc }
@song_diffs = second.songs
.map { |second_song| SongFileDiff.new nil, second_song }
@file_diffs = second.files
.map { |second_file| OtherFileDiff.new nil, second_file }
end
end
def has_difference?
!@first || !@second || @disc_diffs.any { |disc_diff| disc_diff.has_difference? } || @file_diffs.any { |file_diff| file_diff.has_difference? } || @song_diffs.any { |song_diff| song_diff.has_difference? }
end
end
class ArtistDirectory
attr_accessor :dir, :name, :albums, :files
def initialize parent, folder
@parent = parent
@name = folder.mb_chars.compose.to_s
@dir = File.join(parent.dir, folder)
@albums = Dir.entries(@dir).reject{ |subdir| subdir == '.' || subdir == '..' }.select { |subdir| File.directory? File.join(@dir, subdir) }.map { |subdir| AlbumDirectory.new self, subdir }
@files = Dir.entries(@dir).reject { |file| file == '.DS_Store' }.select { |file| File.file? File.join(@dir, file) }.map { |file| OtherFile.new self, file }
end
end
class ArtistDiff
attr_accessor :first, :second, :album_diffs, :file_diffs
def initialize first, second
@first = first
@second = second
if first && second
@album_diffs = first.albums
.fojb(second.albums) { |first_album, second_album| first_album.name == second_album.name }
.map { |first_album, second_album| AlbumDiff.new first_album, second_album }
@file_diffs = first.files
.fojb(second.files) { |first_file, second_file| first_file.name == second_file.name }
.map { |first_file, second_file| OtherFileDiff.new first_file, second_file }
elsif first
@album_diffs = first.albums
.map { |first_album| AlbumDiff.new first_album, nil }
@file_diffs = first.files
.map { |first_file| OtherFileDiff.new first_file, nil }
elsif
@album_diffs = second.albums
.map { |second_album| AlbumDiff.new nil, second_album }
@file_diffs = second.files
.map { |second_file| OtherFileDiff.new nil, second_file }
end
end
def has_difference?
!@first || !@second || @album_diffs.any { |album_diff| album_diff.has_difference? } || @file_diffs.any { |file_diff| file_diff.has_difference? }
end
end
class MusicDirectory
attr_accessor :dir, :artists, :files
def initialize folder
@dir = folder
@artists = Dir.entries(@dir).reject{ |subdir| subdir == '.' || subdir == '..' }.select { |subdir| File.directory? File.join(@dir, subdir) }.map { |subdir| ArtistDirectory.new self, subdir }
@files = Dir.entries(@dir).reject { |file| file == '.DS_Store' }.select { |file| File.file? File.join(@dir, file) }.map { |file| OtherFile.new self, file }
end
end
class MusicDiff
attr_accessor :first, :second, :artist_diffs, :file_diffs
def initialize first, second
@first = first
@second = second
@artist_diffs = first.artists
.fojb(second.artists) { |first_artist, second_artist| first_artist.name == second_artist.name }
.map { |first_artist, second_artist| ArtistDiff.new first_artist, second_artist }
@file_diffs = first.files
.fojb(second.files) { |first_file, second_file| first_file.name == second_file.name }
.map { |first_file, second_file| OtherFileDiff.new first_file, second_file }
end
def has_difference?
!@first || !@second || @artist_diffs.any { |artist_diff| artist_diff.has_difference? } || @file_diffs.any { |file_diff| file_diff.has_difference? }
end
end
hifi_directory = MusicDirectory.new "#{ENV['HOME']}/test/Music"
lofi_directory = MusicDirectory.new "#{ENV['HOME']}/test/LoFi Music"
diff = MusicDiff.new hifi_directory, lofi_directory
puts "Diff:"
puts "[Music Directory] #{diff.first.dir.ljust 33} #{diff.second.dir}"
diff.artist_diffs.select { |artist_diff| artist_diff.has_difference? }.each do |artist_diff|
puts "[Artist Directory] #{artist_diff.first.name.ljust 31} #{artist_diff.second && artist_diff.second.name || "[missing]"}"
artist_diff.album_diffs.select { |album_diff| album_diff.has_difference? }.each do |album_diff|
puts "[Album Directory] #{album_diff.first.name.ljust 29} #{album_diff.second && album_diff.second.name || "[missing]"}"
album_diff.disc_diffs.select { |disc_diff| disc_diff.has_difference? }.each do |disc_diff|
puts "[Disc Directory] #{disc_diff.first.name.ljust 27} #{disc_diff.second && disc_diff.second.name || "[missing]"}"
disc_diff.song_diffs.select { |song_diff| song_diff.has_difference? }.each do |song_diff|
puts "[Song File] #{"#{song_diff.first.name}#{song_diff.first.ext}".ljust 25} #{song_diff.second && song_diff.second.name || "[missing]"}#{song_diff.second && song_diff.csecond.ext}"
end
disc_diff.file_diffs.select { |file_diff| file_diff.has_difference? }.each do |file_diff|
puts "[Other File] #{"#{file_diff.first.name}#{file_diff.first.ext}".ljust 25} #{file_diff.second && file_diff.second.name || "[missing]"}#{file_diff.second && file_diff.csecond.ext}"
end
end
album_diff.song_diffs.select { |song_diff| song_diff.has_difference? }.each do |song_diff|
puts "[Song File] #{"#{song_diff.first.name}#{song_diff.first.ext}".ljust 27} #{song_diff.second && song_diff.second.name || "[missing]"}#{song_diff.second && song_diff.csecond.ext}"
end
album_diff.file_diffs.select { |file_diff| file_diff.has_difference? }.each do |file_diff|
puts "[Other File] #{"#{file_diff.first.name}#{file_diff.first.ext}".ljust 27} #{file_diff.second && file_diff.second.name || "[missing]"}#{file_diff.second && file_diff.csecond.ext}"
end
end
artist_diff.file_diffs.select { |file_diff| file_diff.has_difference? }.each do |file_diff|
puts "[Other File] #{"#{file_diff.first.name}#{file_diff.first.ext}".ljust 29} #{file_diff.second && file_diff.second.name || "[missing]"}#{file_diff.second && file_diff.csecond.ext}"
end
end
diff.file_diffs.select { |file_diff| file_diff.has_difference? }.each do |file_diff|
puts "[Other File] #{"#{file_diff.first.name}#{file_diff.first.ext}".ljust 31} #{file_diff.second && file_diff.second.name || "[missing]"}#{file_diff.second && file_diff.second.ext}"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment