Skeeve •---->


Anmeldedatum: 20.04.2006 Beiträge: 1067
|
Verfasst am: 26.12.2006 - 12:30 Titel: iTunes Bibliothek prüfen mit Perl und AppleScript |
|
|
Schon im April war mir aufgefallen, daß meine iTunes Bibliothek unter Amnesie leidet. Ich hatte ja damals schon hier nachgefragt ob jemand Reparaturideen hat.
Wie ja der eine oder die andere hier wissen dürfte, bin ich eher Perlator als ASi Ich habe mich gestern mal ein bischen mit Perl und AppleScript auseinandergestzt und festgestellt, daß im OS X (ab Tiger?) schon Mac::Glue enthalten ist, eine Modul mit dem man von Perl aus (Zitat) "mit Apple Events terminologie Mac Anwendungen steuern kann".
Ursprünglich wollte ich per osascript ein AppleScript starten, das mir die Speicherorte aller Musikdateien aus der iTunes Bibliothek liefert. Das steigt aber nach einigen Minuten mit der lapidaren Nachricht aus, daß es zwar ein Ergebnis gäbe, aber nicht genügend Speicher für die Ausgabe zur Verfügung stünde.
Da es offensichtlich nicht möglich ist von AppleScript aus auf STDOUT etwas auszugeben, kann man diesen Ansatz also vergessen. Man könnte noch den Weg über eine temporäre Datei oder FIFO gehen, aber das war mir dann doch zu umständlich, als ich herausfand, daß Mac::Glue schon installiert ist.
Einzige Voraussetzung, daß man Mac::Glue nutzen kann ist, daß man für jede Applikation, die man so steuern möchte, einmal das "glue" erzeugt. Im Falle von iTunes gibt man also im Terminal ein: Code: | $ sudo /System/Library/Perl/Extras/bin/gluemac /Applications/iTunes.app/
Password:
What is the glue name? [iTunes]:
Created and installed App glue for iTunes.app, vX.X (iTunes) |
Bei "Password:" Dein Passwort eingeben, bei "What is the glue name? [iTunes]:" einfach Return drücken.
Das war's! Ab nun kann man Mac::Glue in Perl nutzen um iTunes zu steuern.
Das macht dann auch dieses Script. Es gibt am Ende eine Übersicht aus, welche Dateien noch nicht in iTunes sind, welche Dateien fehlen und welche unterschiedliche Schreibweisen aufweisen.
Code: | #!/usr/bin/perl
use strict;
use warnings;
use File::Find;
use Mac::Glue ':glue';
my $itunes = new Mac::Glue 'iTunes';
my $tracks = $itunes->obj(file_tracks => library_playlist => 1);
my $locations = $tracks->prop('location');
my %tracks;
my $library=0;
foreach my $location ($locations->get) {
my($basepath, $artist, $album, $title)= ($location=~ m#(.*)/([^/]+)/([^/]+)/([^/]+)$#);
++$tracks{$basepath}->{$artist}->{$album}->{$title};
++$library;
}
print STDERR $library," files in library\n";
my $disk=0;
find( sub {
return if /^\./ or -d $_;
my($basepath, $artist, $album, $title)= ($File::Find::name=~ m#(.*)/([^/]+)/([^/]+)/([^/]+)$#);
--$tracks{$basepath}->{$artist}->{$album}->{$title};
++$disk
}, keys %tracks);
print STDERR $disk," files on disk\n";
my (
%count,
%diffs,
);
foreach my $basepath (keys %tracks) {
my $bp= $tracks{$basepath};
foreach my $artist (keys %$bp) {
my $ar= $bp->{$artist};
foreach my $album (keys %$ar) {
my $al= $ar->{$album};
foreach my $tr (sort keys %$al) {
my $state= $al->{$tr};
next if $state == 0;
if ( $state == -1 ) {
my $lc= lc "$basepath/$artist/$album/$tr";
--$count{ $lc };
$diffs{ $lc }= "$basepath/$artist/$album/$tr";
}
elsif ( $state == 1 ) {
my $lc= lc "$basepath/$artist/$album/$tr";
++$count{ $lc };
$diffs{ $lc } ||= "$basepath/$artist/$album/$tr";
}
else {
print $al->{$tr},": $basepath/$artist/$album/$tr\n";
}
}
}
}
}
my %states= (
-1 => 'Files with no library entry',
0 => 'Different upper/lower case',
1 => 'Missing files',
);
while (my($state, $text)= each %states) {
$text.="\n";
foreach my $lc (sort keys %diffs) {
if ( $count{ $lc } == $state ) {
print $text, $diffs{ $lc },"\n";
$text= '';
}
}
}
|
_________________ "All problems are solved in slightly less than half an hour" (Chumbawamba, "Hey Hey We're The Junkies") |
|