App-FQStat

 view release on metacpan or  search on metacpan

MANIFEST  view on Meta::CPAN

Changes
lib/App/FQStat.pm
lib/App/FQStat/Actions.pm
lib/App/FQStat/Colors.pm
lib/App/FQStat/Config.pm
lib/App/FQStat/Debug.pm
lib/App/FQStat/Drawing.pm
lib/App/FQStat/Input.pm
lib/App/FQStat/Menu.pm
lib/App/FQStat/PAR.pm
lib/App/FQStat/Scanner.pm
lib/App/FQStat/System.pm
Makefile.PL
MANIFEST			This list of files
README
script/fqstat.pl
t/App-FQStat.t
META.yml                                 Module meta-data (added by MakeMaker)

lib/App/FQStat.pm  view on Meta::CPAN


use strict;
use warnings;
use App::FQStat::Actions;
use App::FQStat::System;
use App::FQStat::Config;
use App::FQStat::Colors;
use App::FQStat::Scanner;
use App::FQStat::Input;
use App::FQStat::Drawing;
use App::FQStat::Menu;
use App::FQStat::PAR;
use App::FQStat::Debug ();

1;

__END__


=head1 NAME

lib/App/FQStat/Actions.pm  view on Meta::CPAN

  warnenter if ::DEBUG;
  cls();
  my $heading = get_color("menu_normal");
  my $h = get_color("warning");
  my $r = RESET;
  print <<"HERE";
${heading}  fqstat v$App::FQStat::VERSION - Interactive front-end for qstat               $r
Commands:
  ${h}'h'             ${r}     Show this (H)elp screen
  ${h}'q'             ${r}     (Q)uit
  ${h}F10             ${r}     Show Menu
  ${h}F5              ${r}     Refresh data from qstat and redraw
  ${h}'S'             ${r}     Toggle Summary Mode
  ${h}Up- / Down-Arrow${r}     Scroll up/down if possible
  ${h}Page-Up / -Down ${r}     Scroll one page up/down if possible
  ${h}Pos1 / End      ${r}     Jump to beginning / end
  ${h}Space / Enter   ${r}     Show detailed job info

  ${h}'u'             ${r}     Enter (U)ser name whose jobs to display
  ${h}'H'             ${r}     (H)ightlight a user's jobs
  ${h}'i'             ${r}     Set the desired update (I)nterval

lib/App/FQStat/Drawing.pm  view on Meta::CPAN



# draws the first, title line
sub draw_title_line {
  warnenter if ::DEBUG > 1;
  locate(1,1);
  my $line;

  my $summary_mode = $::SummaryMode;

  if ($::MenuMode) {
    print get_color("menu_normal");
    $line = App::FQStat::Menu::get_menu_title_line();
  }
  elsif ($summary_mode) {
    lock($::Interval);
    my $progress = ::PROGRESS_INDICATORS()->[$::ProgressIndicator];
    $progress = ' ' if not defined $progress;
    $line = sprintf(
      'fqstat v%.1f %s Jobs:%i Upd:%.1fs [S]witch [F10] Menu ' . get_color('header_highlight') . 'Summary Mode' . RESET . ', Nodes:%i',
      $App::FQStat::VERSION||0,
      $progress,
      scalar(@{$::Records})||0,
      $::Interval||0,
      $::NoActiveNodes||0,
    );
  }
  else {
    lock($::RecordsReversed);
    lock($::Interval);

lib/App/FQStat/Drawing.pm  view on Meta::CPAN


    # reversed list indicator
    my $status = get_color('reverse_indicator').'[';
    if ($::RecordsReversed) { $status .= 'R' }
    if ($status =~ /\[$/) { $status = '' }
    else { $status .= ']'.RESET.' ' }

    my $progress = ::PROGRESS_INDICATORS()->[$::ProgressIndicator];
    $progress = ' ' if not defined $progress;
    $line = sprintf(
      'fqstat v%.1f %s %s%sJobs:%i Upd:%.1fs [h]elp [F10] Menu (c) S. Mueller, Nodes:%i',
      $App::FQStat::VERSION||0,
      $progress,
      $status||'',
      (defined($::User) ? "User:$::User " : ""),
      scalar(@{$::Records})||0,
      $::Interval||0,
      $::NoActiveNodes||0,
    );
  }
  ::GetTermSize();
  $line = substr($line, 0, $::Termsize[0]) if $::Termsize[0] < length($line);
  printline($line);
  print RESET if $::MenuMode;
}

# draws the column header line
sub draw_header_line {
  warnenter if ::DEBUG > 1;
  my @highlight = @_;
  my %highlight = map {($_ => 1)} @highlight;

  # Header Line
  locate(2,1);

lib/App/FQStat/Drawing.pm  view on Meta::CPAN

  draw_title_line(); # first line
  draw_header_line(); # second line
  my $summary_mode = $::SummaryMode;

  if ($summary_mode) {
    draw_summary();
  } else {
    draw_job_display(); # list of jobs
  }

  if ($::MenuMode) {
    App::FQStat::Menu::draw_menu();
  }

  locate(1,1);
}

# Draws the job summary
sub draw_summary {
  warnenter if ::DEBUG;

  # before there's any jobs, warn the user that the

lib/App/FQStat/Menu.pm  view on Meta::CPAN


package App::FQStat::Menu;
# App::FQStat is (c) 2007-2009 Steffen Mueller
#
# This program is free software; you can redistribute it and/or
# modify it under the same terms as Perl itself.

use strict;
use warnings;
use Term::ANSIScreen qw/RESET :cursor/;
use App::FQStat::Debug;
use App::FQStat::Config qw(get_config);
use App::FQStat::Colors qw(get_color);

use base 'Exporter';
our %EXPORT_TAGS = (
  'all' => [qw(
  )],
);
our @EXPORT_OK = @{$EXPORT_TAGS{'all'}};

our @Menus = (
  { width => 11, name => 'Display', entries => [
      { name => 'Summary',     action => \&App::FQStat::Actions::toggle_summary_mode },
      { name => 'Summ.Clust.', action => \&App::FQStat::Actions::toggle_summary_name_clustering },
      { name => 'Refresh',     action => sub { App::FQStat::Drawing::update_display(1) } },
      { name => 'Sort',        action => \&App::FQStat::Actions::select_sort_field },
      { name => 'Reverse',     action => \&App::FQStat::Actions::toggle_reverse_sort },
      { name => 'Interval',    action => \&App::FQStat::Actions::set_user_interval },
      { name => 'Highl. User', action => \&App::FQStat::Actions::update_highlighted_user_name },
      { name => 'Job Details', action => \&App::FQStat::Actions::show_job_details, },
      { name => 'Job Log',     action => \&App::FQStat::Actions::show_job_log, },

lib/App/FQStat/Menu.pm  view on Meta::CPAN

  ], },
  { width => 5, name => 'Help', entries => [
      { name => 'Help',  action => \&App::FQStat::Actions::show_manual, },
      { name => 'About', action => \&App::FQStat::Actions::show_manual, },
  ], },
  { width => 6, name => 'Config', entries => [
      { name => 'Edit',  action => \&App::FQStat::Config::edit_configuration, },
      { name => 'Reset',  action => \&App::FQStat::Config::reset_configuration, },
  ], },
  { width => 4, name => 'Quit', entries => [
      { name => 'Menu',  action => \&App::FQStat::Menu::close_menu, },
      { name => 'Quit',  action => \&main::cleanup_and_exit, },
  ], },
  {
    width => 8, name => 'Colors', entries => \&App::FQStat::Colors::get_color_scheme_menu_entries,
    nEntries => \&App::FQStat::Colors::get_n_color_scheme_entries,
  },
);

# Set cumulative width
{
  my $width = 0;
  foreach my $menu (@Menus) {
    $menu->{startx} = $width+1;
    $width += $menu->{width} + 2;
  }
}

sub enter_menu {
  warnenter if ::DEBUG > 0;
  $::MenuMode = 1;
  $::MenuNumber = 0;
  $::MenuEntryNumber = 0;
  App::FQStat::Drawing::update_display(@_);
}

sub close_menu {
  warnenter if ::DEBUG > 0;
  $::MenuMode = 0;
  App::FQStat::Drawing::update_display(@_);
}

sub toggle_menu {
  warnenter if ::DEBUG > 0;
  $::MenuMode = ($::MenuMode ? 0 : 1);
  $::MenuNumber = 0;
  $::MenuEntryNumber = 0;
  App::FQStat::Drawing::update_display(@_);
}


sub get_menu_title_line {
  warnenter if ::DEBUG > 1;

  my $line;
  foreach my $menu_no (0..$#Menus) {
    my $menu = $Menus[$menu_no];
    my $name = $menu->{name};
    $line .= " " . $name;
    $line .= " " x ($menu->{width} - length($name) + ($menu_no != $#Menus ? 1 : 0));
  }
  return $line;
}

sub draw_menu {
  warnenter if ::DEBUG > 0;
  my $width = 1;

  my $menu = $Menus[$::MenuNumber];
  my $thisEntries = $menu->{entries};
  $thisEntries = $thisEntries->() if ref($thisEntries) eq 'CODE';
  my $startx = $menu->{startx};
  draw_menubox($startx, $startx + $menu->{width}+2, $menu->{name}, $thisEntries, $::MenuEntryNumber);

  locate(1, 1);
}

sub draw_menubox {
  warnenter if ::DEBUG > 1;
  my ($x1, $x2, $title, $entries, $selentry) = @_;
  locate(1, $x1);
  my $width = $x2-$x1;

lib/App/FQStat/Menu.pm  view on Meta::CPAN

    print $thiscolor . $name . RESET;
    $y++;
  }
  #locate($y, $x1);
  #print $color . (" "x($width)) . RESET;
}


sub menu_up {
  warnenter if ::DEBUG > 1;
  return if not $::MenuMode;
  if ($::MenuEntryNumber == 0) {
    my $max_entry = menu_entries() - 1;
    $::MenuEntryNumber = $max_entry;
  }
  else {
    $::MenuEntryNumber--;
  }
  return 1;
}

sub menu_down {
  warnenter if ::DEBUG > 1;
  return if not $::MenuMode;
  my $max_entry = menu_entries() - 1;
  if ($::MenuEntryNumber == $max_entry) {
    $::MenuEntryNumber = 0;
  }
  else {
    $::MenuEntryNumber++;
  }
  return 1;
}

sub menu_right {
  warnenter if ::DEBUG > 1;
  return if not $::MenuMode;
  my $max_menu = @Menus - 1;
  if ($::MenuNumber == $max_menu) {
    $::MenuNumber = 0;
  }
  else {
    $::MenuNumber++;
  }
  $::MenuEntryNumber = 0;
  return 1;
}

sub menu_left {
  warnenter if ::DEBUG > 1;
  return if not $::MenuMode;
  if ($::MenuNumber == 0) {
    my $max_menu = @Menus - 1;
    $::MenuNumber = $max_menu;
  }
  else {
    $::MenuNumber--;
  }
  $::MenuEntryNumber = 0;
  return 1;
}



sub menu_select {
  warnenter if ::DEBUG > 1;
  return if not $::MenuMode;

  my $menu  = $Menus[$::MenuNumber];
  my $entries = $menu->{entries};
  $entries = $entries->() if ref($entries) eq 'CODE';
  my $entry = $entries->[$::MenuEntryNumber];
  my $action = $entry->{action};
  $::MenuMode = 0;
  App::FQStat::Drawing::update_display();
  return $action->($entry);
}

sub menu_entries {
  return @{ $Menus[$::MenuNumber]->{entries} } if ref($Menus[$::MenuNumber]->{entries}) eq 'ARRAY';
  my $nentries = $Menus[$::MenuNumber]->{nEntries};
  $nentries = $nentries->() if defined($nentries) and ref($nentries) eq 'CODE';
  return $nentries;
}

1;


script/fqstat.pl  view on Meta::CPAN

ReadMode 3;
$|=1;

##############
# Declare globals

# action & key globals
use constant KEY_POLL_INTERVAL => 0.2;  # blocking time for keyboard polling
our %Keys;                              # hash of key => action for main loop
our %ControlKeys;                       # hash of control key id => action for main loop
our %MenuKeys;                          # hash of key => action for menu 
our %MenuControlKeys;                   # hash of control key id => action for menu
our %SummaryKeys;
our %SummaryControlKeys;

# twiddly globals
use constant PROGRESS_INDICATORS => ['-', '\\', '|', '/']; # progress indicator states
our $ProgressIndicator = 0;             # progress indicator current state number

# displaying globals
our $Initialized = 0;
our @Termsize : shared;                 # holds terminal size

script/fqstat.pl  view on Meta::CPAN

our $Interval : shared;                 # Effective data refreshing interval. Do not change. Is set to $UserInterval below
our $HighlightUser;
{
  my $curuser = $ENV{USER};
  if (defined $curuser) {
    $HighlightUser = quotemeta($curuser);
  }
}

# application mode globals
our $MenuMode            = 0; # in menu or not
our $SummaryMode :shared = App::FQStat::Config::get("summary_mode") || 0; # in summary mode or not

# menu globals
our $MenuNumber      = 0; # which menu (see @App::FQStat::Menu::Menus)
our $MenuEntryNumber = 0; # in which entry of that menu


# Displayed column descriptions
our %Columns =  (
  prio   => { format => '%.5f',  width => 7,  name => 'Prio',  key => 'prio',  'index' => F_prio,  order => 'num_highlow' },
  name   => { format => '%-10s', width => 10, name => 'Name',  key => 'name',  'index' => F_name,  order => 'alpha'       },
  user   => { format => '%-12s', width => 12, name => 'Owner', key => 'user',  'index' => F_user,  order => 'alpha'       },
  id     => { format => '%7u',   width => 7,  name => 'Id',    key => 'id',    'index' => F_id,    order => 'num'         },
  date   => { format => '%-10s', width => 10, name => 'Date',  key => 'date',  'index' => F_date,  order => 'date'        },
  'time' => { format => '%-8s',  width => 8,  name => 'Time',  key => 'time',  'index' => F_time,  order => 'time'        },

script/fqstat.pl  view on Meta::CPAN


BEGIN {
  %ControlKeys = (
    'A'  => sub { App::FQStat::Actions::scroll_up(1); 1 },                # up
    'B'  => sub { App::FQStat::Actions::scroll_down(1); 1 },              # down
    '5'  => sub { App::FQStat::Actions::scroll_up($Termsize[1]-4); 1 },   # pgup
    '6'  => sub { App::FQStat::Actions::scroll_down($Termsize[1]-4); 1 }, # pgdown
    'H'  => sub { App::FQStat::Actions::scroll_up(1e9); 1 },              # pos1 (640kb ought to be enough for everyone!)
    'F'  => sub { App::FQStat::Actions::scroll_down(1e9); 1 },            # end (640kb ought to be enough for everyone!)
    '15' => sub { App::FQStat::Drawing::update_display(1) },              # F5
    '21' => sub { App::FQStat::Menu::toggle_menu() },                     # F10
  );

  %Keys = (
    'q' => \&cleanup_and_exit,
    'i' => \&App::FQStat::Actions::set_user_interval,
    'H' => \&App::FQStat::Actions::update_highlighted_user_name,
    'r' => \&App::FQStat::Actions::toggle_reverse_sort,
    's' => \&App::FQStat::Actions::select_sort_field,
    'u' => \&App::FQStat::Actions::update_user_name,
    'k' => \&App::FQStat::Actions::kill_jobs,

script/fqstat.pl  view on Meta::CPAN

    '?' => \&App::FQStat::Actions::show_manual,
    'c' => \&App::FQStat::Actions::clear_job_error_state,
    'd' => \&App::FQStat::Actions::change_dependencies,
    ' ' => \&App::FQStat::Actions::show_job_details,
    "\n" => \&App::FQStat::Actions::show_job_details,
    'l' => \&App::FQStat::Actions::show_job_log,
    'S' => \&App::FQStat::Actions::toggle_summary_mode,
  );

  # copy of the key maps for the menu
  %MenuControlKeys = %ControlKeys;
  delete $MenuControlKeys{$_} foreach qw(5 6 H F); # pg-up, pg-down, home, end
  $MenuControlKeys{A}    = \&App::FQStat::Menu::menu_up,     # up-arrow
  $MenuControlKeys{B}    = \&App::FQStat::Menu::menu_down,   # down-arrow
  $MenuControlKeys{C}    = \&App::FQStat::Menu::menu_right,  # right-arrow
  $MenuControlKeys{D}    = \&App::FQStat::Menu::menu_left,   # left-arrow
  
  %MenuKeys = %Keys;
  $MenuKeys{"\n"} = \&App::FQStat::Menu::menu_select, # Enter
  $MenuKeys{" "}  = \&App::FQStat::Menu::menu_select, # space
  delete $MenuKeys{$_} foreach qw(S);

  %SummaryKeys = map {($_ => $Keys{$_})} qw(q i h S);
  $SummaryKeys{c} = \&App::FQStat::Actions::toggle_summary_name_clustering;
  $SummaryKeys{s} = $SummaryKeys{S};
  %SummaryControlKeys = map {($_ => $ControlKeys{$_})} qw(15 21);
}

my @OldTermSize = @Termsize;
sub main_loop {
  warnenter if ::DEBUG;
  my $Redraw = 1;
  my $RedrawTime = time();
  my $RedrawOffset = $DisplayOffset;
  while (1) {
    my $input = get_input_key();
    if (defined $input) {
      my ($KeysHash, $ControlKeysHash);
      if ($MenuMode) {
        $KeysHash = \%MenuKeys;
        $ControlKeysHash = \%MenuControlKeys;
      }
      elsif ($SummaryMode) {
        $KeysHash = \%SummaryKeys;
        $ControlKeysHash = \%SummaryControlKeys;
      }
      else {
        $KeysHash = \%Keys;
        $ControlKeysHash = \%ControlKeys;
      }



( run in 0.709 second using v1.01-cache-2.11-cpan-49f99fa48dc )