call mkbasepath for .meta dir
[cloudstore.git] / lib / CloudStore / API.pm
index 197e488..d68cd1e 100644 (file)
@@ -116,7 +116,7 @@ sub mkbasepath {
 }
 
 sub user_dir {
-       my ( $self,$user, $dir ) = @_;
+       my ( $self, $user, $dir ) = @_;
        $user = $self->user_info($user) unless ref $user eq 'HASH';
        my $path;
        if ( exists $user->{dir} ) {
@@ -160,6 +160,23 @@ sub append_meta {
 sub usage {
        my ( $self, $user ) = @_;
        $user = $self->user_info($user) unless ref $user eq 'HASH';
+
+       my $usage_path = $user->{dir} . '/.meta/files.usage';
+       $self->mkbasepath( $usage_path, { uid => $user->{uid} } );
+       if ( ! -e $usage_path ) {
+               warn "# usage $usage_path missing";
+               $self->list_files($user);
+       }
+
+       open(my $fh, '<', $usage_path);
+       my $size = <$fh>;
+       chomp $size;
+
+       warn "# usage $user->{login} usage: $size\n";
+       return $size;
+
+=for slow and broken
+
        my $path = $self->user_dir( $user => 'usage');
        my $sum;
        open(my $fh, '<', $path);
@@ -176,6 +193,9 @@ sub usage {
        $sum->{_quota} = $quota;
        warn "## usage ",dump($user, $sum), $/;
        return $sum;
+
+=cut
+
 }
 
 sub send_file {
@@ -303,6 +323,55 @@ sub file_size {
        return -s $full_path;
 }
 
+sub list_files {
+       my ( $self, $user, $path ) = @_;
+
+       $user =~ s{/+$}{} && warn "cleanup list_files arg [$user]";
+
+       $user = $self->user_info($user) unless ref $user eq 'HASH';
+
+       die "no dir for ",dump($user) unless exists $user->{dir};
+
+       my $files = $user->{dir} . '/.meta/files';
+       $self->mkbasepath( $files, { uid => $user->{uid} } );
+       if ( -e $files && -s $files > 0) {
+               local $/ = undef;
+               open(my $fh, '<', $files);
+               my $list = <$fh>;
+               close($fh);
+               warn "# list_files $user->{login} cached ", length($list), " bytes";
+               return $list;
+       }
+
+       my $dir = $user->{dir};
+       open(my $pipe, '-|', qq|find -L $dir -printf "%y %s %p\n"|);
+       open(my $fh, '>', "$files.new");
+       my $total_usage = 0;
+       my $list_txt;
+       while(<$pipe>) {
+               chomp;
+               my ( $type, $size, $name ) = split(/\s/, $_);
+               $name =~ s{$dir}{./};
+               $name =~ s{//+}{/}g;
+               my $line = "$type $size $name\n";
+               print $fh $line;
+               $list_txt .= $line;
+               $total_usage += $size;
+       }
+       close($pipe);
+       close($fh);
+       rename "$files.new", $files;
+
+       open(my $usage, '>', "$files.usage.new");
+       print $usage $total_usage;
+       close($usage);
+       rename "$files.usage.new", "$files.usage";
+
+       warn "# list_files $dir usage: $total_usage\n";
+
+       return $list_txt;
+}
+
 sub refresh_file_list {
        my ( $self, $user ) = @_;
        $user = $self->user_info($user) unless ref $user eq 'HASH';
@@ -313,6 +382,8 @@ sub refresh_file_list {
        } else {
                warn "## refresh_file_list $full_path missing";
        }
+
+       unlink "$full_path.usage" if -e "$full_path.usage";
 }
 
 1;