New release mechanism.
[monikop.git] / doc / fake-monikop-screenshot.pl
blob5bd8281cba625be7f1fb5d00c970230ffbd5c950
1 #! /usr/bin/perl
2 #use strict;
3 #use warnings;
4 use integer;
5 use File::Rsync;
6 use File::Basename;
7 use Thread 'async';
8 use threads::shared;
9 use Curses;
11 my @monikop_banner = (
12 " _/ _/ _/_/ _/ _/ _/_/_/ _/ _/ _/_/ _/_/_/ ",
13 " _/_/ _/_/ _/ _/ _/_/ _/ _/ _/ _/ _/ _/ _/ _/",
14 " _/ _/ _/ _/ _/ _/ _/ _/ _/ _/_/ _/ _/ _/_/_/ ",
15 " _/ _/ _/ _/ _/ _/_/ _/ _/ _/ _/ _/ _/ ",
16 "_/ _/ _/_/ _/ _/ _/_/_/ _/ _/ _/_/ _/ ",
19 $version = "v0.0.1";
21 # Debug mode:
22 # 0 = clean UI; 1 = lots of scrolling junk; anything else = both (pipe to file)
23 my $debug = 0;
24 $debug = $ARGV[1] if $ARGV[1];
26 # Where to read local configuration:
27 my $monikop_config = '~/monikop/monikop.config';
28 $monikop_config = $ARGV[0] if $ARGV[0];
30 ########################################
31 # Settings
32 ########################################
33 # Possible data sources, and by what directory name to represent them in
34 # destination.
35 # When the latter is not unique, care must be taken that all pathnames in the
36 # respective sources are unique.
37 my %sources = (
38 'data_producer1::data' => 'p1_dir',
39 'data_producer2::data' => 'p2_dir',
40 'data_producer3::data' => '',
41 'data_producer4::data' => '',
42 'data_producer5::data' => '',
43 'data_producer6::data' => '',
44 'data_producer7::data' => '',
47 # Places to store run-time information to share between threads:
48 my %speeds :shared; # rsync output
49 my %progress_ratios :shared; # rsync output
50 my %destination_usages :shared; # i.e. used/unused
51 my %destination_usage_ratios :shared;
52 my %destination_source_is_writing_to :shared;
53 my %reachable :shared;
55 sub debug_print { if ($debug) { print @_; } };
57 # Turn a path into a legal perl identifier:
58 sub make_key_from_path {
59 my $path = shift;
60 ($path) =~ s/\/?(.*)\/?/$1/g;
61 ($path) =~ s/\W/_/g;
62 $path;
65 my %source_roots;
66 map {
67 $source_roots{make_key_from_path $_} = $_
68 } keys %sources;
70 my %source_dirs_in_destination;
71 map {
72 $source_dirs_in_destination{make_key_from_path $_} = $sources{$_}
73 } keys %sources;
75 sub act_on_keypress {
76 my ($pressed_key) = @_;
77 if ($pressed_key eq 267) { qx($key_f3_action) }
78 elsif ($pressed_key eq 270) { qx($key_f6_action); }
81 %destination_source_is_writing_to = (
82 make_key_from_path ('/data_producer1::data') => '/media/disk_2',
83 make_key_from_path ('/data_producer2::data') => '/media/disk_4',
84 make_key_from_path ('/data_producer3::data') => '/media/disk_7',
85 make_key_from_path ('/data_producer4::data') => '/media/disk_5',
86 make_key_from_path ('/data_producer5::data') => '/media/disk_8',
87 make_key_from_path ('/data_producer6::data') => '/media/disk_3',
90 $SIG{TERM} = sub {
91 $display_thread->kill('TERM')->join;
92 die "Caught signal $_[0]";
95 @destination_roots = (
96 '/media/disk_1',
97 '/media/disk_2',
98 '/media/disk_3',
99 '/media/disk_4',
100 '/media/disk_5',
101 '/media/disk_6',
102 '/media/disk_7',
103 '/media/disk_8',
106 %destination_usage_ratios = (
107 '/media/disk_1' => 38,
108 '/media/disk_2' => 94,
109 '/media/disk_3' => 10,
110 '/media/disk_4' => 27,
111 '/media/disk_5' => 6,
112 '/media/disk_6' => 5,
113 '/media/disk_7' => 99,
114 '/media/disk_8' => 10,
117 %destination_usages = (
118 '/media/disk_1' => 0,
119 '/media/disk_2' => 1,
120 '/media/disk_3' => 1,
121 '/media/disk_4' => 1,
122 '/media/disk_5' => 1,
123 '/media/disk_6' => 0,
124 '/media/disk_7' => 1,
125 '/media/disk_8' => 1,
128 %reachable = (
129 'data_producer1__data' => 1,
130 'data_producer2__data' => 1,
131 'data_producer3__data' => 1,
132 'data_producer4__data' => 1,
133 'data_producer5__data' => 1,
134 'data_producer6__data' => 1,
137 %speeds = (
138 'data_producer1__data' => '23.30MB/s',
139 'data_producer2__data' => '31.53MB/s',
140 'data_producer3__data' => '-',
141 'data_producer4__data' => '243.81kB/s',
142 'data_producer5__data' => '39.19MB/s',
143 'data_producer6__data' => '23.30MB/s',
146 %progress_ratios = (
147 'data_producer1__data' => '951/2300',
148 'data_producer2__data' => '217/352',
149 'data_producer3__data' => '0',
150 'data_producer4__data' => '16/223',
151 'data_producer5__data' => '1854/1929',
152 'data_producer6__data' => '1773/1929',
155 unless ($debug == 1) {
156 # Talk to the user.
157 $display_thread = async {
158 $SIG{TERM} = sub {
159 endwin(); # Leave a usable terminal.
160 threads->exit()
163 my $redraw_window_count = 0;
164 initscr();
165 cbreak();
166 noecho();
167 curs_set(0);
168 my $window_left = newwin(24 -8, 29, 0, 0);
169 my $window_right = newwin(24 -8, 50, 0, 29);
170 my $window_center = newwin(5, 79, 24 -8, 0);
171 my $window_bottom = newwin(3, 79, 24 -3, 0);
172 $window_bottom->keypad(1);
173 $window_bottom->nodelay(1);
174 start_color;
175 init_pair 1, COLOR_MAGENTA, COLOR_BLACK;
176 init_pair 2, COLOR_RED, COLOR_BLACK;
177 init_pair 3, COLOR_CYAN, COLOR_BLACK;
178 init_pair 4, COLOR_YELLOW, COLOR_BLACK;
179 my $MAGENTA = COLOR_PAIR(1);
180 my $RED = COLOR_PAIR(2);
181 my $CYAN = COLOR_PAIR(3);
182 my $YELLOW = COLOR_PAIR(4);
184 while (1) {
185 $window_left->attron($CYAN);
186 $window_left->box(0, 0);
187 $window_left->addstr(0, 6, "Data Destinations");
188 $window_left->attroff($CYAN);
189 my $destinations_format = "%-18s%-6s%-3s";
190 $window_left->attron(A_BOLD);
191 $window_left->addstr(1, 1, sprintf($destinations_format,
192 "Removable", "Fresh", "Usg"));
193 $window_left->addstr(2, 1, sprintf($destinations_format,
194 "Disk", "Data?", "%"));
195 $window_left->attroff(A_BOLD);
196 my $destination_usage;
197 my $line_number = 3;
198 map {
199 if ($destination_usages{$_}) {
200 $window_left->attron($RED);
201 $destination_usage = "yes";
202 } else {
203 $window_left->attron($CYAN);
204 $destination_usage = "no";
206 $window_left->
207 addstr($line_number, 1,
208 sprintf($destinations_format,
209 substr($_, -17, 17),
210 substr($destination_usage, -6, 6),
211 substr($destination_usage_ratios{$_}
212 ? $destination_usage_ratios{$_}
213 : "?",
214 -3, 3)));
215 ++ $line_number;
216 $window_left->attroff($RED);
217 $window_left->attroff($CYAN);
218 } sort @destination_roots;
220 $window_right->attron($MAGENTA);
221 $window_right->box(0,0);
222 $window_right->addstr(0, 19, "Data Sources");
223 $window_right->attroff($MAGENTA);
224 my $sources_format = "%-15s%-11s%-9s%-13s";
225 $window_right->attron(A_BOLD);
226 $window_right->
227 addstr(1, 1, sprintf ($sources_format,
228 "Data", "", "Files", " Writing"));
229 $window_right->
230 addstr(2, 1, sprintf ($sources_format,
231 "Source", "Speed", "To Copy", " To"));
232 $window_right->attroff(A_BOLD);
233 $line_number = 3;
234 $window_right->attron($MAGENTA);
235 map {
236 my $source = $_;
237 my $current_destination = '?';
238 if (exists $destination_source_is_writing_to{$source}) {
239 $current_destination =
240 $destination_source_is_writing_to{$source};
242 if ($reachable{$source}) {
243 $window_right->
244 addstr($line_number, 1,
245 sprintf($sources_format,
246 substr($source_roots{$source}, 0, 14),
247 substr($speeds{$source}, 0, 11),
248 substr($progress_ratios{$source},
249 -9, 9),
250 substr($current_destination, -13, 13)));
251 ++ $line_number;
253 $window_right->
254 addstr($line_number, 1,
255 sprintf($sources_format, "", "", "", ""));
256 } sort (keys %source_roots);
257 $window_right->attroff($MAGENTA);
259 $line_number = 0;
260 map {
261 $window_center->addstr($line_number, 2, $_);
262 ++ $line_number;
263 } @monikop_banner;
264 $window_center->addstr(4, 72, "$version");
265 $window_center->move(0, 0);
267 $window_bottom->box(0,0);
268 $window_bottom->attron(A_BOLD);
269 $window_bottom->addstr(1, 3, "[F3]: Turn off computer.");
270 $window_bottom->addstr(1, 53, "[F6]: Restart computer.");
271 $window_bottom->attroff(A_BOLD);
273 $window_left->noutrefresh();
274 $window_right->noutrefresh();
275 $window_bottom->noutrefresh();
276 $window_center->noutrefresh(); # Last window gets the cursor.
277 act_on_keypress($window_bottom->getch());
278 sleep 2;
279 if (++ $redraw_window_count > 5) {
280 $redraw_window_count = 0;
281 redrawwin();
283 doupdate();
285 endwin();
289 sleep;