#!/usr/bin/perl -w # This program is free software. It comes without any warranty, to the # extent permitted by applicable law. You can redistribute it and/or # modify it under the terms of the Do What The Fuck You Want To Public # License, Version 2, as published by Sam Hocevar. # See http://sam.zoy.org/wtfpl/COPYING for more details. $VERSION = "0.1, 27 November 2011"; use DBI; use File::Spec::Functions; use Cwd; use Env qw /HOME/; use strict; ################################################################################ # Configuration my $confile = catfile ($HOME, '.videodb.rc'); die "Can't read `" .$confile. "'\n" unless -f $confile; my %config = do $confile; die "Error in `" .$confile. "'\n" if $@ || not %config; map { exists $config{$_} || die "Error: Missing `${_}'.\n" } qw /videodir driver database hostname user port password videodata/; my $symlinks = catdir($config{videodir},'MOVIES'); # Symlinks folder die "Error: No such directory: `" .$symlinks. "'.\n" unless -d $symlinks; ################################################################################ # Connect to database my $dsn = "DBI:$config{driver}:database=$config{database};host=$config{hostname};port=$config{port}"; my $dbh = DBI->connect($dsn, $config{user}, $config{password}) or die "Can't connect do database\n"; $dbh->do( "set names utf8" ) or die; ################################################################################ # Check that all entries in the DB have a symlink, that in turn have a # valid target my $res = $dbh->selectall_arrayref ( "SELECT filename FROM $config{videodata}" ) or die "Can't select: " .$dbh->errstr. "\n"; my @links; my @files; foreach (@$res) { my $l = File::Spec->catfile ($symlinks, $_->[0]); unless (-l $l or -f $l) { push @links, $_->[0]; } if (-l $l and not -f File::Spec->catfile ($symlinks, readlink $l)) { push @files, $_->[0]; } } my $r = 0; if (@links) { print STDERR "* The following entries are in the DB, but I can't file the files:\n"; foreach (@links) { print STDERR " ", $_, "\n"; } $r = 1; } if (@files) { print STDERR "* The following entries don't have a valid target:\n"; foreach (@files) { print STDERR " ", $_, "\n"; } $r = 1; } ################################################################################ # For all symlink, check that it has exactly one entry in the DB my @filelist; opendir (DIR, $symlinks) or die "Can't open dir `" .$symlinks. ".:" .$!. "\n"; while (my $l = readdir(DIR)) { next if $l eq File::Spec->curdir(); next if $l eq File::Spec->updir(); my $f = File::Spec->catfile($symlinks, $l); if ( -d Cwd::realpath($f) ) { opendir (SUBDIR, Cwd::realpath($f)) or die "Can't open dir `" .Cwd::realpath($f). ".:" .$!. "\n"; while (my $d = readdir(SUBDIR)) { next if $d eq File::Spec->curdir(); next if $d eq File::Spec->updir(); push @filelist, File::Spec->catfile($l,$d); } closedir(SUBDIR) or die "Can't close: $!\n"; } elsif ( -l $f or -f $f ) { push @filelist, $l; } } closedir(DIR) or die "Can't close: $!\n"; undef @files; my $sth = $dbh->prepare ( "SELECT id FROM $config{videodata} WHERE filename = ?" ) or die "Error: " .$dbh->errstr; foreach (@filelist) { $sth->execute ($_) or die "Can't select: " .$dbh->errstr. "\n"; my @res = $sth->fetchrow_array; die $sth->errstr if $sth->err; push @files, $_ unless $#res == 0; } $sth->finish; $dbh->disconnect; if (@files) { print STDERR "* The following files have <> 1 corresponding entries in the DB:\n"; foreach (@files) { print STDERR " ", $_, "\n"; } $r = 1; } ################################################################################ exit $r;