Script to copy random mp3s from a directory to an mp3 player

This is a Ruby script which randomly copies mp3 files from one directory to an mp3 player. I wrote it so I could easily fill up my mp3 player from the 9000 odd mp3s I have on a different external drive.

To run it, you'll need the sys-filesystem gem (see http://rubyforge.org/projects/sysutils):

$ gem install sys-filesystem

Next, edit these variables in the script (near the top):
* source_dir to the directory containing the mp3s you want to select from
* dest_dir to the path for the directory on your mp3 player you want to copy to

Be a bit careful, as this will attempt to fill the dest_dir you specify with mp3 files from source_dir. You might end up filling the wrong disk up.

Then just run it with ruby from the command line:

$ ruby mp3s_random.rb

Note that it won't delete anything from the destination drive, and will attempt to fill all the space available. Also note that it doesn't keep trying mp3s until it finds one which will fit the last remaining space: once it tries to copy a file which won't fit, it stops. You can always run it again to see whether the next run finds a file small enough to fit.

I've only tested it on Linux, but, who knows, it might work on Windows too. (No operating-system specific commands are used in the script, as it uses Ruby for all file operations.)

The code is below, but I've attached it as well.

require 'rubygems'
require 'sys/filesystem'
require 'ftools'

source_dir = '/media/disk/music'
dest_dir = '/media/disk-1/music'

files = Dir[File.join(source_dir, '/**/*.mp3')]
num_files = files.size

stat = Sys::Filesystem.stat(dest_dir)

disk_free_space_kb = (stat.blocks_free * stat.fragment_size).to_kb

files_selected = []

while disk_free_space_kb > 0 and num_files > 0 do
  # choose an mp3
  file_num_to_copy = rand(num_files - 1) + 1
  file_path = files.delete_at(file_num_to_copy)

  num_files = num_files - 1

  # work out how big file is
  file_size_kb = File.stat(file_path).size.to_kb

  # subtract from free space
  if (disk_free_space_kb - file_size_kb) > 0
    files_selected << file_path
    disk_free_space_kb = disk_free_space_kb - file_size_kb
  else
    break
  end
end

files_selected.each do |f|
  copy_to_path = File.join(dest_dir, File.basename(f))
  puts "Copying #{f} to device"
  File.copy(f, copy_to_path)
end
AttachmentSize
mp3s_random.rb939 bytes

Comments

error after finaly installing all in fedora 12 :((

after running ruby mp3s_random.rb

undefined method `to_kb' for 1977987072:Bignum (NoMethodError)

sudo yum install rubygems
sudo yum install ruby-devel
sudo rake install
gem install sys-filesystem

sys-filesystem should

sys-filesystem should include the to_kb method; if not, they may have changed the API.

This is so cool!

My husband has been teaching me about programming, he has recommend me to read this article and try to make it work on my MP2 Player.

This is a great project for me, fun fun fun!

Man, I wish I knew how to code

After reading this entry about your nifty script, I am filed with ENVY. I wish I know how to code. Some stuff that I would code:

If I paste a web page onto a form the form automatically takes out the links and spits out a nice clickable list

A script that takes all files from all folders and spits out a nice list

Anyway, enough of my daydreaming. Do you think it's possible to learn how to code just by reading webpages online? Are there any free tutorials?

Haha, you have no idea how

Haha, you have no idea how handy this script will be :) Just yesterday I've found a 5 year old shoe box full of cd's with thousand's mp3's. I've no idea what is there (well, I know a bit, but that's it). You see where I'm going with this ;)
Thanks again!

reply

there is no strategy just how nifty this unique illegal program would be :) Simply yesteryear There is a good 5 various year-old jogging shoe common box loaded with compact discs along with thousand's mp3's. I had no clue that which is presently there (good, I am aware of slightly, but that is the item). The thing is that just where Let me within this ;)
Thanks again
lynel