File Coverage

blib/lib/App/EventStreamr/Config.pm
Criterion Covered Total %
statement 89 176 50.5
branch 13 68 19.1
condition 1 2 50.0
subroutine 40 50 80.0
pod 0 1 0.0
total 143 297 48.1


line stmt bran cond sub pod time code
1             package App::EventStreamr::Config;
2 8     8   141073 use Method::Signatures;
  8         401240  
  8         56  
3 8     8   4136 use Sys::Hostname;
  8         1717  
  8         419  
4 8     8   3815 use experimental 'say';
  8         23950  
  8         44  
5 8     8   5380 use Config::JSON; # libconfig-json-perl
  8         282819  
  8         257  
6 8     8   79 use File::Path qw(make_path);
  8         15  
  8         545  
7 8     8   32 use Carp 'croak';
  8         8  
  8         443  
8 8     8   3765 use App::EventStreamr::Devices;
  8         21  
  8         278  
9 8     8   41 use Moo;
  8         9  
  8         54  
10 8     8   4625 use namespace::clean;
  8         18921  
  8         56  
11              
12             # ABSTRACT: A config object
13              
14             our $VERSION = '0.4'; # VERSION: Generated by DZP::OurPkg:Version
15              
16              
17             has 'config_path' => ( is => 'rw', default => sub { "$ENV{HOME}/.eventstreamr" } );
18             has 'config_file' => ( is => 'rw', lazy => 1, builder => 1 );
19             has 'roles' => ( is => 'rw', default => sub { [ ] } );
20             has 'backend' => ( is => 'rw', default => sub { "DVswitch" } );
21             has 'nickname' => ( is => 'rw', lazy => 1, builder => 1 );
22             has 'room' => ( is => 'rw', lazy => 1, default => sub { 'test_room' } );
23             has 'record_path' => ( is => 'rw', lazy => 1, default => sub { '/tmp/$room/$date' } );
24             has 'run' => ( is => 'rw', lazy => 1, default => sub { '0' } );
25             has 'control' => ( is => 'rw' );
26             has 'stream' => ( is => 'rw' );
27             has 'sync' => ( is => 'rw' );
28             has 'pid' => ( is => 'ro', lazy => 1, builder => 1);
29             has 'log_level' => ( is => 'ro', default => sub { 'INFO, LOG1' } );
30             has 'mixer' => (
31             is => 'rw',
32             lazy => 1,
33             default => sub {
34             {
35             host => '127.0.0.1',
36             port => '1234',
37             }
38             }
39             );
40              
41             # TODO: Be more intelligent with devices
42             has 'devices_util' => ( is => 'rw', lazy => 1, builder => 1 );
43             has 'devices' => ( is => 'rw', default => sub { [ ] } );
44             has 'available_devices' => ( is => 'rw' );
45              
46             # TODO: this really needs to be changed to some
47             # type of GUID
48             has 'macaddress' => ( is => 'rw', lazy => 1, builder => 1 );
49              
50             # External utilities
51             has 'localconfig' => (
52             is => 'rw',
53             lazy => 1,
54             builder => 1,
55             handles => [ qw( create write config ) ],
56             );
57              
58             # DVswitch Checking - Probably better somewhere else
59             has 'dvswitch_running' => ( is => 'rw', default => sub { '0' } );
60              
61             sub BUILD {
62 14     14 0 182 my $self = shift;
63 14         291 $self->_load_config;
64             }
65              
66 8 0   8   13765 method _build_pid() {
  0     0   0  
  0         0  
67 0         0 return $$;
68             }
69              
70 8 50   8   4905 method _build_devices_util() {
  14     14   2494  
  14         46  
71 14         143 return App::EventStreamr::Devices->new();
72             }
73              
74 8 50   8   4633 method update_devices() {
  25     25   36  
  25         83  
75 25         339 $self->{available_devices} = $self->devices_util->all();
76             }
77              
78 8 50   8   4183 method _build_config_file() {
  14     14   2176  
  14         60  
79 14         564 return $self->config_path."/config.json";
80             }
81              
82 8 50   8   3708 method _build_nickname() {
  7     7   2836  
  7         41  
83 7   50     45 return hostname || "default_name";
84             }
85              
86 8 50   8   4270 method _build_macaddress() {
  11     11   1806  
  11         53  
87 11         3866140 my $macaddress = `ifdata -ph eth0`;
88 7         75 chomp $macaddress;
89 7         231 return $macaddress;
90             }
91              
92 8 50   8   4330 method _create_config_path() {
  5     5   9  
  5         20  
93 5 50       43 if ( ! -d $self->config_path ) {
94 5 50       1103 make_path($self->config_path) or
95             croak "Couldn't create config path $self->{config_path}";
96             }
97             }
98              
99 8 50   8   4652 method _build_localconfig() {
  14     14   2341  
  14         46  
100             # Config JSON barfs if you try to load a config that doesn't exist,
101             # this will load one or attempt to create it.
102 14 100       154 if ( -e $self->config_file ) {
103 9         199 return Config::JSON->new($self->config_file);
104             } else {
105 5         23 $self->_create_config_path();
106 5         114 my $config = Config::JSON->create($self->config_file);
107              
108 5         7873 $config->{config} = {
109             nickname => $self->nickname,
110             room => $self->room,
111             record_path => $self->record_path,
112             run => $self->run,
113             backend => $self->backend,
114             };
115 5         30 $config->write;
116 5         794 return $config;
117             }
118             }
119              
120 8     8   5372 method _load_config() {
121             # TODO: There has to be a better way..
122             foreach my $key (keys %{$self->localconfig->{config}}) {
123             $self->{$key} = $self->localconfig->{config}{$key};
124             }
125             }
126              
127 8 0   8   4611 method reload_config() {
  0     0   0  
  0         0  
128 0         0 $self->_build_localconfig;
129             }
130              
131 8 50   8   3920 method _clean_config() {
  34     34   47  
  34         79  
132             return {
133 34         660 nickname => $self->nickname,
134             room => $self->room,
135             record_path => $self->record_path,
136             run => $self->run,
137             backend => $self->backend,
138             roles => $self->roles,
139             stream => $self->stream,
140             sync => $self->sync,
141             mixer => $self->mixer,
142             control => $self->control,
143             devices => $self->devices,
144             backend => $self->backend,
145             }
146             }
147              
148 8 50   8   3767 method _post_data() {
  27     27   43  
  27         65  
149 27         83 my $config = $self->_clean_config();
150 27         1500 $config->{manager}{pid} = $$;
151 27         169 $config->{macaddress} = $self->macaddress();
152 23         247 return $config;
153             }
154              
155              
156 8     8   3459 method write_config() {
157             $self->localconfig->{config} = $self->_clean_config();
158             $self->localconfig->write;
159             }
160              
161              
162              
163 8 0   8   3412 method configure() {
  0     0      
  0            
164 0           say "Welcome to the EventStreamr config utility\n";
165            
166 0           my $answer = $self->prompt(
167             "It will clear the current config, is this ok? y/n",
168             "n",
169             );
170 0 0         exit 1 if ($answer =~ /n/i);
171            
172             # TODO: Write config clear method
173 0           $self->roles([]);
174             # Config Questions
175 0           $self->configure_room();
176 0           $self->configure_backend();
177 0           $self->configure_mixer();
178 0           $self->configure_ingest();
179 0           $self->write_config();
180            
181 0           say;
182              
183             # Confirm written.
184 0 0         if (-e $self->config_file) {
185 0           say "Config written successfully";
186             } else {
187 0           say "Config failed to write";
188             }
189             # TODO: Stream Configuration
190             #$answer = undef;
191             #$answer = $self->prompt(
192             # "Stream - stream to configured service y/n: ",
193             # "y",
194             #);
195              
196             #push(@{$self->{roles}}, "stream") if ($answer =~ /y/i);
197             }
198              
199 8 0   8   4480 method configure_mixer() {
  0     0      
  0            
200 0           my $answer = $self->prompt(
201             "Mixer - Video mixer interface y/n",
202             "y",
203             );
204              
205 0 0         if ($answer =~ /y/i) {
206 0           push(@{$self->roles}, "mixer");
  0            
207 0           $self->configure_remote_mixer();
208              
209             # We could run gst-switch srv or dvsink
210             # on separate hosts, but this will do
211             # for now.
212 0           push(@{$self->roles}, "record");
  0            
213 0           $self->configure_recordpath();
214             }
215             }
216              
217 8 0   8   4150 method configure_ingest() {
  0     0      
  0            
218 0           my $answer = $self->prompt(
219             "Ingest - audio/video ingest y/n",
220             "y",
221             );
222              
223 0 0         if ($answer =~ /y/i) {
224 0           push(@{$self->roles}, "ingest");
  0            
225            
226 0           $self->update_devices();
227 0           $self->devices([]);
228            
229 0           foreach my $device (@{$self->{available_devices}{array}}) {
  0            
230 0           my $ingest = $self->prompt(
231             "Enable '".$device->{name}."' for ingest",
232             "y",
233             );
234 0 0         push(@{$self->devices}, $device) if ($ingest =~ /y/i);
  0            
235             }
236 0 0         $self->configure_remote_mixer() if (! $self->{mixer}{host});
237             }
238             }
239              
240 8 0   8   5801 method configure_remote_mixer() {
  0     0      
  0            
241             # TODO: Setting config like this is terrible,
242             # figure out how to do it better
243 0           my $answer = $self->prompt(
244             "host - switching host",
245             "127.0.0.1",
246             );
247 0           $self->{mixer}{host} = $answer ;
248 0           $answer = $self->prompt(
249             "port - switching port",
250             "1234",
251             );
252 0           $self->{mixer}{port} = $answer;
253             }
254              
255 8 0   8   3729 method configure_backend() {
  0     0      
  0            
256 0           my $answer = $self->prompt(
257             "backend - DVswitch|GSTswitch",
258             $self->backend,
259             );
260 0 0         if ($answer =~ /gst/i) {
    0          
261 0           $self->backend('GSTswitch');
262 0           return;
263             } elsif ($answer =~ /dv/i) {
264 0           $self->backend('DVswitch');
265 0           return;
266             } else {
267 0           say "Invalid backend";
268 0           $self->configure_backend;
269             return
270 0           }
271             }
272              
273 8 0   8   4179 method configure_recordpath() {
  0     0      
  0            
274 0           say '$room + $date can be used as variables in the path and';
275 0           say 'will correctly be set and created at run time';
276 0           my $answer = $self->prompt(
277             "recordpath - ",
278             '/tmp/$room/$date',
279             );
280 0           $self->record_path($answer);
281             }
282              
283 8 0   8   3625 method configure_room() {
  0     0      
  0            
284 0           my $answer = $self->prompt(
285             "Room - For record path and controller",
286             $self->room,
287             );
288 0           $self->room($answer);
289             }
290              
291 8 0   8   648575 method prompt($question,$default?) { # inspired from here: http://alvinalexander.com/perl/edu/articles/pl010005
  0 0   0      
  0            
  0            
  0            
  0            
292 0 0         if ($default) {
293 0           print $question, " [", $default, "]: ";
294             } else {
295 0           print $question, ": ";
296 0           $default = "";
297             }
298              
299 0           $| = 1; # flush
300 0           $_ = <STDIN>; # get input
301              
302 0           chomp;
303 0 0         if ("$default") {
304 0 0         return $_ ? $_ : $default; # return $_ if it has a value
305             } else {
306 0           return $_;
307             }
308             }
309              
310             with('App::EventStreamr::Roles::Logger','App::EventStreamr::Roles::ConfigAPI');
311              
312             1;
313              
314             __END__
315              
316             =pod
317              
318             =encoding UTF-8
319              
320             =head1 NAME
321              
322             App::EventStreamr::Config - A config object
323              
324             =head1 VERSION
325              
326             version 0.4
327              
328             =head1 SYNOPSIS
329              
330             This package provides core configuration methods. Class
331             will attempt to load the config via a number of different
332             methods and fall back to a default state.
333              
334             =head1 DESCRIPTION
335              
336             Provides access to configuration methods.
337              
338             =head1 METHODS
339              
340             =head2 write_config
341              
342             $config->write_config();
343              
344             Will write the config out to disk.
345              
346             =head2 configure
347              
348             $config->configure();
349              
350             Will run through configuring EventStreamr.
351              
352             =head1 AUTHOR
353              
354             Leon Wright < techman@cpan.org >
355              
356             =head1 COPYRIGHT AND LICENSE
357              
358             This software is Copyright (c) 2014 by Leon Wright.
359              
360             This is free software, licensed under:
361              
362             The GNU Affero General Public License, Version 3, November 2007
363              
364             =cut