10 my @pokinom_banner = (
11 " _/_/_/ _/_/ _/ _/ _/_/_/ _/ _/ _/_/ _/ _/",
12 " _/ _/ _/ _/ _/ _/ _/ _/_/ _/ _/ _/ _/_/ _/_/ ",
13 " _/_/_/ _/ _/ _/_/ _/ _/ _/ _/ _/ _/ _/ _/ _/ ",
14 " _/ _/ _/ _/ _/ _/ _/ _/_/ _/ _/ _/ _/ ",
15 "_/ _/_/ _/ _/ _/_/_/ _/ _/ _/_/ _/ _/ ",
19 # 0 = clean UI; 1 = lots of scrolling junk; anything else = both (pipe to file)
24 my ($pressed_key) = @_;
25 if ($pressed_key eq 267) { qx($shut_down_action); }
26 elsif ($pressed_key eq 273) { # F9
27 $shut_down_when_done = $shut_down_when_done ?
0 : 1; }
30 my %being_deleted_thread;
31 my %rsync_worker_thread;
34 $ENV{USER
} = $rsync_username if ($rsync_username);
35 $ENV{RSYNC_PASSWORD
} = $rsync_password if ($rsync_password);
38 $display_thread->kill('TERM')->join;
39 die "Caught signal $_[0]";
42 # Preparations done; sleeves up!
44 # Make sure we have dirs to put our logs in:
46 ## my ($filename, $directory) = fileparse $_;
47 ## qx(mkdir -p $directory);
48 ## } ( $rsync_log_prefix, $interrupted_prefix );
50 ## # Find usable (i.e. mounted) sources
51 ## my @raw_mount_points = grep (s/\S+ on (.*) type .*/$1/, qx/mount/);
52 ## chomp @raw_mount_points;
53 ## my @sources = intersection @raw_mount_points, @usable_mount_points;
54 ## debug_print "SOURCES:\n";
55 ## debug_print @sources;
66 # Turn a path into a legal perl identifier:
67 sub make_key_from_path
{
69 ($path) =~ s/\/?(.*)\/?
/$1/g;
75 $source_roots{make_key_from_path
$_} = $_
79 'media_disk_1' => '15.20MB/s',
80 'media_disk_2' => '10.02MB/',
81 'media_disk_3' => '-',
82 'media_disk_4' => '242.73kB/s',
83 'media_disk_5' => '6.78MB/s',
84 'media_disk_6' => '-',
85 'media_disk_7' => '-',
99 'media_disk_1' => '951/2300',
100 'media_disk_2' => '217/352',
101 'media_disk_3' => 'Done',
102 'media_disk_4' => '16/223',
103 'media_disk_5' => '1854/1929',
104 'media_disk_6' => 'Wait',
105 'media_disk_7' => 'Done',
109 unless ($debug == 1) {
111 $display_thread = async
{
113 endwin
(); # Leave a usable terminal.
117 my $redraw_window_count = 0;
122 my $window_top = newwin
(LINES
() - 8, 79, 0, 0);
123 my $window_center = newwin
(5, 79, LINES
() - 8, 0);
124 my $window_bottom = newwin
(3, 79, LINES
() - 3, 0);
125 $window_bottom->keypad(1);
126 $window_bottom->nodelay(1);
128 init_pair
1, COLOR_MAGENTA
, COLOR_BLACK
;
129 init_pair
2, COLOR_RED
, COLOR_BLACK
;
130 init_pair
3, COLOR_CYAN
, COLOR_BLACK
;
131 init_pair
4, COLOR_YELLOW
, COLOR_BLACK
;
132 my $MAGENTA = COLOR_PAIR
(1);
133 my $RED = COLOR_PAIR
(2);
134 my $CYAN = COLOR_PAIR
(3);
135 my $YELLOW = COLOR_PAIR
(4);
137 $window_top->attron($CYAN);
138 $window_top->box(0,0);
139 $window_top->addstr(0, 30, " P r o g r e s s ");
140 $window_top->attroff($CYAN);
141 my $sources_format = "%-25s%-18s%-8s";
142 $window_top->attron(A_BOLD
);
143 $window_top->addstr(1, 12,
144 sprintf ($sources_format,
145 "Source Medium", "Speed", "To Do"));
146 $window_top->attroff(A_BOLD
);
150 $window_top->attron($CYAN);
151 $window_top->attron($RED) if $done{$source};
153 addstr
($line_number, 12,
154 sprintf($sources_format,
155 substr($source_roots{$source}, 0, 24),
156 substr($speeds{$source}, 0, 17),
157 substr($progress_ratios{$source}, -8, 8)));
159 $window_top->addstr($line_number, 1,
160 sprintf($sources_format, "", "", "", ""));
161 $window_top->attroff($RED);
162 $window_top->attroff($CYAN);
163 } sort (keys %source_roots);
166 $window_center->addstr($line_number, 2, $_);
169 $window_center->move(0, 0);
171 $window_bottom->box(0,0);
172 $window_bottom->attron(A_BOLD
);
175 sprintf ("[F3]: Turn off now.%54s",
176 $shut_down_when_done ?
"Turning off when done. [F9]: Stay on."
177 : "Staying on. [F9]: Turn off when done."));
178 $window_bottom->attroff(A_BOLD
);
180 $window_top->noutrefresh();
181 $window_bottom->noutrefresh();
182 $window_center->noutrefresh(); # Last window gets the cursor.
184 if (++ $redraw_window_count > 5) {
185 $redraw_window_count = 0;
189 act_on_keypress
($window_bottom->getch());
190 if (! grep(/0/, values %done) && $shut_down_when_done) {
191 qx ($shut_down_action);