Attached is a short perl script that, while still a little rough around
the edges, allows you to synchronize a given directory hierarchy of
podcasts with another directory (such as a USB Mass Storage Device type
player), while maintaining a history of what has been put there in the
past. License is GPLv2 and feedback is welcome.
Assume:
(1) The user gets podcasts via a podcast aggregator
(2) These podcasts are put in a directory $source_dir (in the script,
edit and change as necessary)
(3) The user wants to listen to them on his player, and deletes them
when done (either via player or computer. This script doesn't care,
because it doesn't assume anything about the state of the player)
(4) The user does not want already uploaded podcasts uploaded again (as
would happen with conventional sync tools when deleted on the target)
Logic:
- Scan the log file ($source_dir/sync_podcasts.log) and get the stuff
that has been uploaded. Read it into a hash for fast access.
- Recurse through all files and subdirectories below $source_dir
- If the target directory isn't there, make it.
- If a file is not in the log file, copy it to the player and add it to
the log file.
Notes:
- The first time the script is run, it assumes that you have nothing
that needs to go on the player and merely generates the log file from
the existing directory structure. To circumvent this behavior, create an
empty sync_podcast.log file in the directory to which $source_dir points.
TODO:
- Generate .m3u playlist for each directory in $target_dir
Known bugs / Issues:
- Untested on anything other than Ubuntu Linux. Should work on most
Linux distros. Your mileage might vary on anything else.
--
--------------------------------------------------------------------
PGP Key: http://www.mattcaron.net/pgp_key.txt
~~ Matt Caron ~~
#!/usr/bin/perl -w
####################################################
#
# sync_podcast - synchronize podcasts to USB Mass Storage Device type
# players
# Copyright (C) 2006 Matthew Caron <matt_at_mattcaron.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License, version 2, as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# Full license at: http://www.fsf.org/licensing/licenses/info/GPLv2.html
#
####################################################
use strict;
use File::Find;
use File::Path;
use File::Copy;
## Constants
my $source_dir = "/pub/matt/podcasts";
my $podcast_log_file = "sync_podcasts.log";
my $target_dir = "/media/ipod/podcasts";
my $initialize = 0;
## Derived constants
my $podcast_log = $source_dir . "/" . $podcast_log_file;
my %uploaded_files;
# Read in logfile and store file path and name in hash.
if(-e $podcast_log)
{
open(LOGFILE, $podcast_log);
while(<LOGFILE>)
{
chomp($_);
$uploaded_files{$_} = 1;
}
close(LOGFILE);
}
else
{
# logfile doesn't exist - assume initialization mode
$initialize = 1;
print "Initializing logile...\n";
}
# Recurse through directory and find each file there
find(\©_stuff, ($source_dir));
# Recurse through and build playlists for each directory
# find(\&build_playlists, ($source_dir));
# cd (dir) - \ls `pwd`/* > dir.m3u
# Spaces are a problem...
# Make sure to remove playlist ahead of time
sub copy_stuff
{
# file name
my $filename = $_;
# source directory
my $dirname = $File::Find::dir;
# source dir + file name
my $fullpath = $File::Find::name;
# If what we got isn't a directory, do something
# And it's not the log file
if(!-d $fullpath && $filename ne $podcast_log_file)
{
# get name of dir in isolation
my $source_dirname = $dirname;
$source_dirname =~ s/$source_dir//;
# target dir
my $destination_path = $target_dir . "/" . $source_dirname;
# target dir + file name
my $destination_path_file = $destination_path . "/" . $filename;
# make sure this hasn't been uploaded...
if(!defined $uploaded_files{$fullpath})
{
if(!$initialize)
{
# Put file on the music device, maintaining directory
# structure..
# make directory if it doesn't exist
if(!-d $destination_path)
{
print "\n\nMaking directory $destination_path...\n\n";
mkpath($destination_path) ||
die "Cannot mkpath $destination_path: $!";
}
print "$fullpath => $destination_path_file\n";
# copy file to that directory
copy($fullpath, $destination_path_file) ||
die "Cannot copy $fullpath to $destination_path_file: $!";
}
# Log that you did it
open(LOGFILE, ">>$podcast_log");
print LOGFILE $fullpath . "\n";
close(LOGFILE);
}
} # else, ignore directory
}
Received on 2006-08-02