Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env perl
- use strict;
- use warnings;
- use PIR;
- use Capture::Tiny qw( capture_stdout capture_stderr );
- use Term::ANSIColor qw( colorstrip );
- $ENV{TTY_WIDTH} ||= 80;
- my $rule = PIR->new();
- my $root = '/';
- # This rule is like `find -xdev`
- my $dev_rule = PIR->new->not( PIR->new->dev( [ stat $root ]->[0] ) );
- $rule->skip( $dev_rule );
- $rule->file;
- my $it = $rule->iter( $root, {
- loop_safe => 1,
- relative => 1,
- depthfirst => -1,
- follow_symlinks => 0,
- sorted => 0,
- });
- my $frag_db = {};
- my $seen = 0;
- *STDOUT->autoflush(1);
- scanner: while( my $row = $it->() ) {
- my $frags = get_frag_count($root . $row );
- $seen++;
- if ( $seen > 50 and $frags <= 1 ) {
- status_line($row);
- $seen = 0;
- }
- next scanner if $frags <= 1;
- message_line("33m", $row, "\e[33m$frags\e[0m");
- while ( ( my $saved = do_defrag( $root . $row, $frags ) ) > 0 ) {
- message_line("1;33m", $row, "\e[32m$saved\e[0m/\e[33m$frags\e[0m");
- $frags -= $saved;
- next scanner if $frags <= 1;
- }
- next scanner if $frags <= 1;
- $frag_db->{ $row } = $frags;
- }
- message_line("32m", "ENTERING MAIN LOOP", "");
- bigloop: while( keys %{$frag_db} ) {
- for my $key ( sort { $frag_db->{$b} <=> $frag_db->{$a} } keys %{$frag_db} ) {
- message_line("31m",$key, "\e[31m$frag_db->{$key}\e[0m");
- my $saved = do_defrag( $root . $key, $frag_db->{$key} );
- if ( $saved > 0 ) {
- message_line("31m",$key, "\e[32m$saved\e[0m/\e[31m$frag_db->{$key}\e[0m");
- $frag_db->{$key} = $frag_db->{$key} - $saved;
- if ( $frag_db->{$key} < 2 ) {
- delete $frag_db->{$key};
- }
- next bigloop;
- }
- }
- }
- sub get_frag_count {
- my ( $path ) = @_;
- my $content = do {
- open my $fh, '-|', 'filefrag', $path or die "Cant call filefrag, $!";
- local $/;
- scalar <$fh>;
- };
- if ( $content =~ /:\s*(\d+)\s*extent[s]?\s+found\s$/ ) {
- return $1;
- }
- return 0;
- }
- sub do_defrag {
- my ( $path, $old_frag_count ) = @_;
- if ( not $old_frag_count ) {
- $old_frag_count = get_frag_count($path);
- }
- local $SIG{INT} = sub { die };
- local $?;
- my ( $capture, $return ) = capture_stdout {
- system('e4defrag', $path)
- };
- my ( $signal, $exit ) = ( $? & 127 , $? >> 8 );
- if ( $signal ) {
- warn "Exit with signal $signal";
- if ( $signal == 2 ) { die }
- }
- if ( $exit ) {
- warn "$capture: $exit";
- }
- my $new_frag_count = get_frag_count($path);
- return $old_frag_count - $new_frag_count;
- }
- sub infix_wrap_text {
- my ( $text, $max_length ) = @_;
- my $textlen = length $text;
- return $text if length $text < $max_length;
- my $dsize = $max_length - 3 ;
- my $left = substr $text, 0, ( $dsize / 3 * 1 );
- my $right = substr $text, $textlen - ( $dsize / 3 * 2 );
- return "$left...$right";
- }
- sub status_line {
- my ( $value ) = @_;
- my $display_chars = length '[ ...]';
- my $space = $ENV{TTY_WIDTH} - $display_chars;
- my $text = infix_wrap_text( $value, $space );
- my $display_space = (length $text) + $display_chars;
- my $pad = "";
- if ( $display_space < $ENV{TTY_WIDTH} ) {
- $pad = ( " " x ( $ENV{TTY_WIDTH} - $display_space ) );
- }
- printf "\e[37m[ %s ...]%s\e[0m\r",$text, $pad;
- }
- sub message_line {
- my ( $color, $key, $value ) = @_;
- my $display_chars = length "* ";
- my $space = $ENV{TTY_WIDTH} - $display_chars;
- my $value_space = length( ': ' . colorstrip( $value ));
- my $text_space = $space - $value_space;
- my $text = infix_wrap_text( $key, $text_space );
- my $display_space = (length $text) + $value_space;
- my $pad = "";
- if ( $display_space < $ENV{TTY_WIDTH} ) {
- $pad = ( " " x ( $ENV{TTY_WIDTH} - $display_space ));
- }
- printf "\e[%s*\e[0m %s: %s%s\n", $color, $text, $value, $pad ;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement