Skip to content

Instantly share code, notes, and snippets.

@alexchee
Created August 30, 2016 23:58
Show Gist options
  • Save alexchee/1a045cd90a51d9a9f06f63aa52f67638 to your computer and use it in GitHub Desktop.
Save alexchee/1a045cd90a51d9a9f06f63aa52f67638 to your computer and use it in GitHub Desktop.
Copies songs from m3u playlist to another directory
#!/bin/ruby
require 'xmlsimple'
require 'fileutils'
require 'optparse'
DEST="/Volumes/TB/NewMusic/"
options = {
destination: DEST,
dry_run: false
}
OptionParser.new do |opts|
opts.banner = "Usage: #{$0} [m3u file]"
opts.on("-t", "--dry-run", "Dry Run") do
options[:dry_run] = true
end
opts.on("-d", "--dest", "Destination") do |d|
options[:destination] = d
end
end.parse
m3u_file=ARGV.last
raise "files not found: #{m3u_file}" unless File.exists?(m3u_file)
raise "directory does not exists" unless Dir.exists?(options[:destination])
class M3UCopier
attr_accessor :m3u_file, :destination, :dry_run
attr_accessor :options
def initialize(m3u_file, options)
self.m3u_file = m3u_file
self.destination = options[:destination]
self.dry_run = options[:dry_run] || false
self.options = options
end
def copy_songs!
lines = File.read(m3u_file).split("\r")
songs = lines.reject{|p| p.match /^#EXT/ }
source_dir = find_common_dir(songs)
songs.each do |song|
puts "Looking at #{song}"
new_directory = File.dirname(song).gsub(Regexp.new("^#{source_dir}"), destination)
unless Dir.exists?(new_directory)
puts "\tCreating directory #{new_directory}"
FileUtils.mkdir_p(new_directory) unless dry_run
end
new_path = song.gsub(Regexp.new("^#{source_dir}"), destination)
unless File.exists?(new_path)
puts "\tcopying to #{new_path}"
FileUtils.cp(song, new_path) unless dry_run
else
puts "\tfile already exists: #{new_path}"
end
end
end
def find_common_dir(dirs)
shared_dir = File.dirname(dirs.first)
dirs.each_with_index do |dir, idx|
shared_dir = find_common_string(shared_dir, dir)
end
shared_dir
end
def find_common_string(dir1, dir2)
str1 = dir1.split('')
str2 = dir2.split('')
common_chars = -1
str1.each_with_index do |char, idx|
if char == str2[idx]
common_chars = idx
else
break
end
end
if common_chars >= 0
dir1[0..common_chars]
end
end
end
M3UCopier.new(m3u_file, options).copy_songs!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment