Advertisement
Guest User

Untitled

a guest
Feb 6th, 2016
41
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.48 KB | None | 0 0
  1. #!/usr/bin/env perl
  2. use strict;
  3. use warnings;
  4.  
  5. use PIR;
  6. use Capture::Tiny qw( capture_stdout capture_stderr );
  7. use Term::ANSIColor qw( colorstrip );
  8.  
  9. $ENV{TTY_WIDTH} ||= 80;
  10.  
  11. my $rule = PIR->new();
  12.  
  13. my $root = '/';
  14.  
  15. # This rule is like `find -xdev`
  16. my $dev_rule = PIR->new->not( PIR->new->dev( [ stat $root ]->[0] ) );
  17.  
  18. $rule->skip( $dev_rule );
  19. $rule->file;
  20.  
  21. my $it = $rule->iter( $root, {
  22. loop_safe => 1,
  23. relative => 1,
  24. depthfirst => -1,
  25. follow_symlinks => 0,
  26. sorted => 0,
  27. });
  28.  
  29. my $frag_db = {};
  30. my $seen = 0;
  31. *STDOUT->autoflush(1);
  32. scanner: while( my $row = $it->() ) {
  33. my $frags = get_frag_count($root . $row );
  34. $seen++;
  35. if ( $seen > 50 and $frags <= 1 ) {
  36. status_line($row);
  37. $seen = 0;
  38. }
  39. next scanner if $frags <= 1;
  40. message_line("33m", $row, "\e[33m$frags\e[0m");
  41. while ( ( my $saved = do_defrag( $root . $row, $frags ) ) > 0 ) {
  42. message_line("1;33m", $row, "\e[32m$saved\e[0m/\e[33m$frags\e[0m");
  43. $frags -= $saved;
  44. next scanner if $frags <= 1;
  45. }
  46. next scanner if $frags <= 1;
  47. $frag_db->{ $row } = $frags;
  48. }
  49. message_line("32m", "ENTERING MAIN LOOP", "");
  50. bigloop: while( keys %{$frag_db} ) {
  51. for my $key ( sort { $frag_db->{$b} <=> $frag_db->{$a} } keys %{$frag_db} ) {
  52. message_line("31m",$key, "\e[31m$frag_db->{$key}\e[0m");
  53. my $saved = do_defrag( $root . $key, $frag_db->{$key} );
  54. if ( $saved > 0 ) {
  55. message_line("31m",$key, "\e[32m$saved\e[0m/\e[31m$frag_db->{$key}\e[0m");
  56. $frag_db->{$key} = $frag_db->{$key} - $saved;
  57. if ( $frag_db->{$key} < 2 ) {
  58. delete $frag_db->{$key};
  59. }
  60. next bigloop;
  61. }
  62. }
  63. }
  64.  
  65. sub get_frag_count {
  66. my ( $path ) = @_;
  67. my $content = do {
  68. open my $fh, '-|', 'filefrag', $path or die "Cant call filefrag, $!";
  69. local $/;
  70. scalar <$fh>;
  71. };
  72. if ( $content =~ /:\s*(\d+)\s*extent[s]?\s+found\s$/ ) {
  73. return $1;
  74. }
  75. return 0;
  76. }
  77. sub do_defrag {
  78. my ( $path, $old_frag_count ) = @_;
  79. if ( not $old_frag_count ) {
  80. $old_frag_count = get_frag_count($path);
  81. }
  82. local $SIG{INT} = sub { die };
  83. local $?;
  84. my ( $capture, $return ) = capture_stdout {
  85. system('e4defrag', $path)
  86. };
  87. my ( $signal, $exit ) = ( $? & 127 , $? >> 8 );
  88. if ( $signal ) {
  89. warn "Exit with signal $signal";
  90. if ( $signal == 2 ) { die }
  91. }
  92. if ( $exit ) {
  93. warn "$capture: $exit";
  94. }
  95. my $new_frag_count = get_frag_count($path);
  96. return $old_frag_count - $new_frag_count;
  97. }
  98.  
  99. sub infix_wrap_text {
  100. my ( $text, $max_length ) = @_;
  101. my $textlen = length $text;
  102. return $text if length $text < $max_length;
  103.  
  104. my $dsize = $max_length - 3 ;
  105. my $left = substr $text, 0, ( $dsize / 3 * 1 );
  106. my $right = substr $text, $textlen - ( $dsize / 3 * 2 );
  107. return "$left...$right";
  108. }
  109.  
  110. sub status_line {
  111. my ( $value ) = @_;
  112. my $display_chars = length '[ ...]';
  113. my $space = $ENV{TTY_WIDTH} - $display_chars;
  114.  
  115. my $text = infix_wrap_text( $value, $space );
  116. my $display_space = (length $text) + $display_chars;
  117.  
  118. my $pad = "";
  119. if ( $display_space < $ENV{TTY_WIDTH} ) {
  120. $pad = ( " " x ( $ENV{TTY_WIDTH} - $display_space ) );
  121. }
  122. printf "\e[37m[ %s ...]%s\e[0m\r",$text, $pad;
  123. }
  124. sub message_line {
  125. my ( $color, $key, $value ) = @_;
  126.  
  127. my $display_chars = length "* ";
  128. my $space = $ENV{TTY_WIDTH} - $display_chars;
  129.  
  130. my $value_space = length( ': ' . colorstrip( $value ));
  131. my $text_space = $space - $value_space;
  132. my $text = infix_wrap_text( $key, $text_space );
  133. my $display_space = (length $text) + $value_space;
  134. my $pad = "";
  135. if ( $display_space < $ENV{TTY_WIDTH} ) {
  136. $pad = ( " " x ( $ENV{TTY_WIDTH} - $display_space ));
  137. }
  138. printf "\e[%s*\e[0m %s: %s%s\n", $color, $text, $value, $pad ;
  139. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement