File Coverage

lib/BalanceOfPower/Role/WebMaster.pm
Criterion Covered Total %
statement 23 326 7.0
branch 0 24 0.0
condition 0 14 0.0
subroutine 8 24 33.3
pod 0 16 0.0
total 31 404 7.6


line stmt bran cond sub pod time code
1             package BalanceOfPower::Role::WebMaster;
2             $BalanceOfPower::Role::WebMaster::VERSION = '0.400115';
3 13     13   6077 use strict;
  13         28  
  13         396  
4 13     13   131 use v5.10;
  13         43  
5 13     13   55 use Moo::Role;
  13         21  
  13         102  
6              
7 13     13   12398 use LWP::UserAgent;
  13         480960  
  13         433  
8 13     13   8856 use JSON;
  13         134245  
  13         64  
9 13     13   2130 use Data::Dumper;
  13         26  
  13         966  
10 13     13   72 use File::Path qw(make_path remove_tree);
  13         22  
  13         830  
11              
12 13     13   78 use BalanceOfPower::Utils qw(prev_turn next_turn);
  13         32  
  13         36596  
13              
14              
15             has site_root => (
16             is => 'rw',
17             );
18             has api_url => (
19             is => 'rw',
20             );
21             has admin_password => (
22             is => 'rw'
23             );
24              
25             requires 'print_hotspots';
26             requires 'print_allies';
27             requires 'print_influences';
28             requires 'print_military_supports';
29             requires 'print_rebel_military_supports';
30             requires 'print_war_history';
31             requires 'print_civil_war_history';
32             requires 'print_turn_statistics';
33             requires 'print_formatted_turn_events';
34             requires 'print_nation_actual_situation';
35             requires 'print_borders_analysis';
36             requires 'print_near_analysis';
37             requires 'print_diplomacy';
38             requires 'print_nation_events';
39             requires 'pre_decisions_elaborations';
40             requires 'decisions';
41             requires 'post_decisions_elaborations';
42             requires 'print_market';
43             requires 'print_nation_shop_prices';
44             requires 'print_all_nations_prices';
45             requires 'armies_on_territory';
46              
47              
48              
49             sub build_pre_statics
50             {
51 0     0 0   my $self = shift;
52 0           my $game = shift;
53 0   0       my $year = shift || $self->current_year;
54 0           my $site_root = $self->site_root;
55 0           my $dest_dir = "$site_root/views/generated/$game/" . $self->current_year();
56 0           say "Generating pre-decisions statics";
57 0           make_path $dest_dir;
58 0           open(my $hotspots, "> $dest_dir/hotspots.tt");
59 0           print {$hotspots} $self->print_hotspots('html');
  0            
60 0           close($hotspots);
61 0           open(my $allies, "> $dest_dir/alliances.tt");
62 0           print {$allies} $self->print_allies(undef, 'html');
  0            
63 0           close($allies);
64 0           open(my $influences, "> $dest_dir/influences.tt");
65 0           print {$influences} $self->print_influences(undef, 'html');
  0            
66 0           close($influences);
67 0           open(my $supports, "> $dest_dir/supports.tt");
68 0           print {$supports} $self->print_military_supports(undef, 'html');
  0            
69 0           close($supports);
70 0           open(my $reb_supports, "> $dest_dir/rebel-supports.tt");
71 0           print {$reb_supports} $self->print_rebel_military_supports(undef, 'html');
  0            
72 0           close($reb_supports);
73 0           open(my $whistory, "> $dest_dir/war-history.tt");
74 0           print {$whistory} $self->print_war_history('html');
  0            
75 0           close($whistory);
76 0           open(my $cwhistory, "> $dest_dir/civil-war-history.tt");
77 0           print {$cwhistory} $self->print_civil_war_history('html');
  0            
78 0           close($cwhistory);
79 0           open(my $market, "> $dest_dir/market.tt");
80 0           print {$market} $self->print_market('html');
  0            
81 0           close($market);
82 0           open(my $prices, "> $dest_dir/prices.tt");
83 0           print {$prices} $self->print_all_nations_prices($year, 'html');
  0            
84 0           close($prices);
85 0           $self->build_nations_statics($game, $site_root);
86 0           $self->build_players_statics($game, $site_root);
87             }
88              
89             sub build_post_statics
90             {
91 0     0 0   my $self = shift;
92 0           my $game = shift;
93 0           my $site_root = $self->site_root;
94 0   0       my $year = shift || $self->current_year;
95 0           my $dest_dir = "$site_root/views/generated/$game/" . next_turn($year);
96 0           make_path $dest_dir;
97 0           say "Generating post-decisions statics";
98 0           open(my $situation, "> $dest_dir/situation.tt");
99 0           print {$situation} $self->print_turn_statistics($year, undef, 'html');
  0            
100 0           close($situation);
101 0           open(my $events, "> $dest_dir/events.tt");
102 0           print {$events} $self->print_formatted_turn_events($year, undef, 'html');
  0            
103 0           close($events);
104 0           open(my $news, "> $dest_dir/newspaper.tt");
105 0           print {$news} $self->print_newspaper($year, "News", 'html');
  0            
106 0           close($news);
107             }
108              
109             sub build_meta_statics
110             {
111 0     0 0   my $self = shift;
112 0           my $game = shift;
113 0           my $site_root = $self->site_root;
114 0           my $dest_dir = "$site_root/metadata";
115 0           make_path $dest_dir;
116 0           my %nations_to_dump;
117 0           foreach my $n (@{$self->nations})
  0            
118             {
119 0           $nations_to_dump{$n->name} = {
120             code => $n->code,
121             area => $n->area };
122             }
123 0           my %data = ( current_year => $self->current_year,
124             nations => \%nations_to_dump );
125 0           open(my $meta, "> $dest_dir/$game.meta");
126 0           print {$meta} Dumper(\%data);
  0            
127 0           close($meta);
128             }
129              
130             sub build_nations_statics
131             {
132 0     0 0   my $self = shift;
133 0           my $game = shift;
134 0           my $site_root = $self->site_root;
135 0           say "Generating nations statics";
136 0           foreach my $code (keys %{$self->nation_codes})
  0            
137             {
138 0           my $nation = $self->nation_codes->{$code};
139              
140 0           my $dest_dir = "$site_root/views/generated/$game/" . $self->current_year() . "/n/$code";
141 0           make_path($dest_dir);
142 0           open(my $status, "> $dest_dir/actual.tt");
143 0           print {$status} $self->print_nation_actual_situation($nation, 1, 'html');
  0            
144 0           close($status);
145 0           open(my $borders, "> $dest_dir/borders.tt");
146 0           print {$borders} $self->print_borders_analysis($nation, 'html');
  0            
147 0           close($borders);
148 0           open(my $near, "> $dest_dir/near.tt");
149 0           print {$near} $self->print_near_analysis($nation, 'html');
  0            
150 0           close($near);
151 0           open(my $diplomacy, "> $dest_dir/diplomacy.tt");
152 0           print {$diplomacy} $self->print_diplomacy($nation, 'html');
  0            
153 0           close($diplomacy);
154 0           open(my $events, "> $dest_dir/events.tt");
155 0           print {$events} $self->print_nation_events($nation, prev_turn($self->current_year()), undef, 'html');
  0            
156 0           close($events);
157 0           open(my $graphs, "> $dest_dir/graphs.tt");
158 0           print {$graphs} $self->print_nation_graphs($nation, prev_turn($self->current_year()), 10, 'html');
  0            
159 0           close($graphs);
160 0           open(my $prices, "> $dest_dir/prices.tt");
161 0           print {$prices} $self->print_nation_shop_prices($self->current_year, $nation, 'html');
  0            
162 0           close($prices);
163 0           $dest_dir = "$site_root/metadata/$game/n";
164 0           make_path($dest_dir);
165 0           open(my $nation_meta, "> $dest_dir/" . $code . ".data");
166 0           my $at_civil_war = $self->at_civil_war($nation);
167 0 0         my $at_war = $self->at_war($nation) ? 1 : 0;
168              
169 0           my $commands = $self->build_commands();
170 0           my $exec = $commands->set_executive($nation);
171 0           my @allowed = $exec->allowed_orders();
172 0           my %command_matrix;
173 0           for(@allowed)
174             {
175 0           my $com_name = $_;
176 0           my $com = $exec->commands->{$com_name};
177 0 0         if($com->has_argument)
178             {
179 0           my @targets = $com->get_available_targets();
180 0 0         if(@targets)
181             {
182 0           $command_matrix{$com_name}->{targets} = \@targets;
183 0           $command_matrix{$com_name}->{argument} = $com->has_argument();
184             }
185             }
186             else
187             {
188 0           $command_matrix{$com_name}->{argument} = $com->has_argument();
189             }
190             }
191 0           my $nation_obj = $self->get_nation($nation);
192 0           my %travels = $self->make_travel_plan($nation);
193 0           my %prices = $self->get_all_nation_prices($nation, $self->current_year);
194 0           my $foreign_armies = $self->armies_on_territory($nation);
195 0 0         my $invaded = @{$foreign_armies->{invaders}} > 0 ? 1 : 0;
  0            
196 0           my %nation_hash = ( stocks => $nation_obj->available_stocks,
197             internal_production => $nation_obj->production_for_domestic,
198             export_production => $nation_obj->production_for_export,
199             prestige => $nation_obj->prestige,
200             army => $nation_obj->army,
201             war => $at_war,
202             civil_war => $at_civil_war,
203             invasion => $invaded,
204             commands => \%command_matrix,
205             travels => \%travels,
206             prices => \%prices,
207             foreigners => $foreign_armies );
208 0           print {$nation_meta} Dumper(\%nation_hash);
  0            
209 0           close($nation_meta);
210             }
211             }
212             sub build_players_statics
213             {
214 0     0 0   my $self = shift;
215 0           my $game = shift;
216 0           my $site_root = $self->site_root;
217 0           say "Generating player statics";
218 0           foreach my $p (@{$self->players})
  0            
219             {
220 0           my $dest_dir = "$site_root/views/generated/$game/" . $self->current_year() . '/p/' . $p->name;
221 0           make_path($dest_dir);
222 0           open(my $stocks, "> $dest_dir/stocks.tt");
223 0           print {$stocks} $self->print_stocks($p->name, 'html');
  0            
224 0           close($stocks);
225 0           open(my $events, "> $dest_dir/events.tt");
226 0           print {$events} $self->print_stock_events($p->name, prev_turn($self->current_year()), "My market events", 3, 'html');
  0            
227 0           close($events);
228 0           open(my $ranking, "> $dest_dir/ranking.tt");
229 0           print {$ranking} $self->print_all_stocks('html');
  0            
230 0           close($ranking);
231 0           open(my $graphs, "> $dest_dir/graphs.tt");
232 0           print {$graphs} $self->print_player_graphs($p->name, prev_turn($self->current_year()), 10, 'html');
  0            
233 0           close($graphs);
234 0           open(my $targets, "> $dest_dir/targets.tt");
235 0           print {$targets} $self->print_targets($p->name, 'html');
  0            
236 0           close($targets);
237              
238              
239 0           $dest_dir = "$site_root/metadata/$game/p";
240 0           make_path($dest_dir);
241 0           open(my $metawallet, "> $dest_dir/" . $p->name . "-wallet.data");
242 0           my %wallet;
243 0           for(keys %{$p->wallet})
  0            
244             {
245 0           my $code = $self->get_nation($_)->code;
246 0           $wallet{$code} = $p->wallet->{$_};
247             }
248 0           my $stock_status = $self->player_stocks_status($p->name);
249 0           my $w_metadata = { wallet => \%wallet, stock_value => $stock_status->{'stock_value'} };
250 0           print {$metawallet} Dumper($w_metadata);
  0            
251 0           close($metawallet);
252             }
253             }
254              
255             sub clean_statics
256             {
257 0     0 0   my $self = shift;
258 0           my $game = shift;
259 0           my $preservation_window = shift;
260 0           my $site_root = $self->site_root;
261 0           my $delete_year = $self->current_year;
262 0           say "Current year: $delete_year";
263 0           say "---";
264 0           for(my $i = $preservation_window; $i > 0; $i--)
265             {
266 0           $delete_year = prev_turn($delete_year);
267             }
268 0           my $deleting = 1;
269 0           while($deleting)
270             {
271 0           my $directory_to_delete = "$site_root/views/generated/$game/$delete_year";
272 0 0 0       if (-e $directory_to_delete and -d $directory_to_delete)
273             {
274 0           say "Deleting $directory_to_delete";
275 0           remove_tree($directory_to_delete);
276 0 0         if($delete_year =~ /1$/)
277             {
278 0           my $parent_directory_to_delete = $directory_to_delete;
279 0           $parent_directory_to_delete =~ s/\/1$//;
280 0           say "Deleting $parent_directory_to_delete";
281 0           remove_tree($parent_directory_to_delete);
282             }
283 0           $delete_year = prev_turn($delete_year);
284             }
285             else
286             {
287 0           $deleting = 0;
288             }
289             }
290             }
291              
292             sub server_available
293             {
294 0     0 0   my $self = shift;
295 0           my $alive = $self->get_web_data('/keepalive', 1);
296 0 0 0       if($alive && $alive eq 'OK')
297             {
298 0           return 1;
299             }
300             else
301             {
302 0           return 0;
303             }
304             }
305              
306             sub generate_whole_turn
307             {
308 0     0 0   my $self = shift;
309 0           my $game = shift;
310 0           my $turn = shift;
311 0           my $site_root = shift;
312 0           $self->pre_decisions_elaborations($turn);
313 0           $self->build_pre_statics($game, $site_root);
314 0           $self->decisions();
315 0           $self->post_decisions_elaborations();
316 0           $self->build_post_statics($game, $site_root);
317             }
318             sub generate_web_interactive_turn
319             {
320 0     0 0   my $self = shift;
321 0           my $game = shift;
322 0           my $site_root = shift;
323 0           $self->collect_api_data($game);
324 0           $self->decisions();
325 0           $self->post_decisions_elaborations();
326 0           $self->build_post_statics($game, $site_root);
327 0           $self->update_web_players($game);
328 0           $self->pre_decisions_elaborations(next_turn($self->current_year));
329 0           $self->build_pre_statics($game, $site_root);
330             }
331              
332             sub manage_web_players
333             {
334 0     0 0   my $self = shift;
335 0           my $game = shift;
336 0           my $players = $self->get_web_data("/api/$game/users");
337 0 0         if($players)
338             {
339 0           my $many = @{$players} + 0;
  0            
340 0           say "$game - $many players on DB";
341 0           for(@{$players})
  0            
342             {
343 0           $self->create_player($_->{'username'}, $_->{'position'}, $_->{'money'});
344             }
345             }
346             else
347             {
348 0           say "$game - players list NOT retrieved";
349             }
350             }
351              
352             sub collect_api_data
353             {
354 0     0 0   my $self = shift;
355 0           my $game = shift;
356 0           $self->manage_web_players($game);
357 0           $self->manage_stock_orders($game);
358 0           $self->manage_influence_orders($game);
359             }
360              
361             sub manage_stock_orders
362             {
363 0     0 0   my $self = shift;
364 0           my $game = shift;
365 0           foreach my $p (@{$self->players})
  0            
366             {
367 0           my $password = $self->admin_password;
368 0           my $user = $p->name;
369 0           my $call = "/api/$game/stock-orders?player=$user&password=$password";
370 0           my $orders = $self->get_web_data($call);
371 0 0         if(defined $orders)
372             {
373 0           say "$game - Stock orders for $user retrieved";
374 0           for(@{$orders})
  0            
375             {
376 0           $self->get_player($p->name)->add_stock_order($_);
377             }
378             }
379             else
380             {
381 0           say "$game - Stock orders for $user NOT retrieved";
382             }
383             }
384             }
385             sub manage_influence_orders
386             {
387 0     0 0   my $self = shift;
388 0           my $game = shift;
389 0           foreach my $p (@{$self->players})
  0            
390             {
391 0           my $password = $self->admin_password;
392 0           my $user = $p->name;
393 0           my $call = "/api/$game/influence-orders?player=$user&password=$password";
394 0           my $orders = $self->get_web_data($call);
395 0 0         if(defined $orders)
396             {
397 0           say "$game - Influence orders for $user retrieved";
398 0           for(@{$orders})
  0            
399             {
400 0           $self->get_player($p->name)->add_control_order($_->{nation}, $_->{command});
401             }
402             }
403             else
404             {
405 0           say "$game - Orders for $user NOT retrieved";
406             }
407             }
408             }
409              
410             sub update_web_players
411             {
412 0     0 0   my $self = shift;
413 0           my $game = shift;
414 0           my $password = $self->admin_password;
415 0           my @players = @{$self->players};
  0            
416 0           foreach my $p (@players)
417             {
418 0           my $res = $self->post_web_data("/api/$game/user-data", { password => $password,
419             player => $p->name,
420             money => $p->money,
421             position => $p->position });
422 0           say "$game - Updating " . $p->name. ": " . $res;
423             }
424             }
425              
426             sub get_web_data
427             {
428 0     0 0   my $self = shift;
429 0           my $call = shift;
430 0   0       my $bare = shift || 0;
431 0           my $ua = LWP::UserAgent->new;
432 0           $ua->timeout(10);
433 0           $ua->env_proxy;
434 0           my $response = $ua->get($self->api_url . $call);
435              
436            
437 0 0         if ($response->is_success) {
438 0 0         if($bare)
439             {
440 0           return $response->decoded_content;
441             }
442             else
443             {
444 0           my $json = JSON->new->allow_nonref;
445 0           return $json->decode( $response->decoded_content );
446             }
447             }
448             else {
449 0           return undef;
450             }
451             }
452              
453             sub post_web_data
454             {
455 0     0 0   my $self = shift;
456 0           my $call = shift;
457 0           my $form = shift;
458 0           my $ua = LWP::UserAgent->new;
459 0           $ua->timeout(10);
460 0           $ua->env_proxy;
461 0           my $response = $ua->post($self->api_url . $call, $form);
462 0           return $response->code;
463             }
464              
465             1;
466              
467