########################################### # Mike Schilli, 2006 (m@perlmeister.com) ########################################### package Videodir; ########################################### use strict; use warnings; use YAML qw(LoadFile DumpFile); use File::Basename; ########################################### sub new { ########################################### my($class, %options) = @_; my $self = { dir => "$ENV{HOME}/tv", meta_file => ".meta", keep_default => 5, meta => {}, max_gigs => 20, %options }; $self->{meta_path} = "$self->{dir}/$self->{meta_file}"; bless $self, $class; $self->rescan(); return $self; } ########################################### sub rescan { ########################################### my($self) = @_; if(-f $self->{meta_path}) { $self->{meta} = LoadFile($self->{meta_path}); } $self->{total_size} = 0; my @items = (); my $dir = $self->{dir}; for my $path (<$dir/*>) { next unless -f $path; my $file = basename $path; $self->{meta}->{$file}->{keep} = $self->{keep_default} unless defined $self->{meta}->{$file}->{keep}; my $size = -s $path; $self->{total_size} += $size; my $age = age_in_days($path); push @items, { file => $file, path => $path, age => $age, size => gb($size), ttl => $self->{meta}->{$file}->{keep} - $age, }; } $self->{total_size} = gb($self->{total_size}); # Delete outdated entries for my $k (keys %{$self->{meta}}) { delete $self->{meta}->{$k} unless -f "$self->{dir}/$k"; } $self->meta_save(); # Sort by descending by age $self->{items} = [ sort { $a->{age} <=> $b->{age} } @items ]; return $self->{items}; } ########################################### sub gb { # Umrechnen in Gigabytes ########################################### my($val) = @_; return sprintf "%.1f", $val / (1024**3); } ########################################### sub remove { ########################################### my($self, $file) = @_; my $path = "$self->{dir}/$file"; if(-f $path) { unlink $path or die "Cannot unlink $path"; } $self->rescan(); } ########################################### sub age_in_days { ########################################### my($file) = @_; return(sprintf "%.1f", (time() - (stat $file)[9]) / 24 / 3600); } ########################################### sub shrink { ########################################### my($self) = @_; my $deleted = 0; my @doomed = reverse grep { $_->{ttl} < 0 } @{$self->{items}}; while($self->{total_size} > $self->{max_gigs}) { last unless @doomed; my $item = shift @doomed; $deleted++; $self->remove($item->{file}); } return $deleted; } ########################################### sub meta_save { ########################################### my($self) = @_; DumpFile($self->{meta_path}, $self->{meta}); } 1;