File Coverage

blib/lib/App/Metabase/Relayd.pm
Criterion Covered Total %
statement 22 24 91.6
branch n/a
condition n/a
subroutine 8 8 100.0
pod n/a
total 30 32 93.7


line stmt bran cond sub pod time code
1             package App::Metabase::Relayd;
2              
3 1     1   13265 use strict;
  1         1  
  1         23  
4 1     1   2 use warnings;
  1         1  
  1         20  
5 1     1   460 use Pod::Usage;
  1         42662  
  1         123  
6 1     1   682 use Config::Tiny;
  1         1035  
  1         31  
7 1     1   5 use File::Spec;
  1         2  
  1         19  
8 1     1   4 use Cwd;
  1         1  
  1         62  
9 1     1   936 use Getopt::Long;
  1         9796  
  1         4  
10 1     1   440 use Module::Pluggable search_path => ['App::Metabase::Relayd::Plugin'];
  0            
  0            
11             use Module::Load::Conditional qw[can_load];
12             use if ( $^O eq 'linux' ), 'POE::Kernel', { loop => 'POE::XS::Loop::EPoll' };
13             use unless ( $^O =~ /^(?:linux|MSWin32|darwin)$/ ), 'POE::Kernel', { loop => 'POE::XS::Loop::Poll' };
14             use if ( scalar grep { $^O eq $_ } qw(MSWin32 darwin) ), 'POE::Kernel', { loop => 'POE::Loop::Event' };
15             use POE;
16             use POE::Component::Metabase::Relay::Server;
17              
18             use vars qw($VERSION);
19              
20             $VERSION = '0.38';
21              
22             sub _metabase_dir {
23             return $ENV{PERL5_MBRELAYD_DIR}
24             if exists $ENV{PERL5_MBRELAYD_DIR}
25             && defined $ENV{PERL5_MBRELAYD_DIR};
26              
27             my @os_home_envs = qw( APPDATA HOME USERPROFILE WINDIR SYS$LOGIN );
28              
29             for my $env ( @os_home_envs ) {
30             next unless exists $ENV{ $env };
31             next unless defined $ENV{ $env } && length $ENV{ $env };
32             return $ENV{ $env } if -d $ENV{ $env };
33             }
34              
35             return cwd();
36             }
37              
38             sub _read_config {
39             my $metabase_dir = File::Spec->catdir( _metabase_dir(), '.metabase' );
40             return unless -d $metabase_dir;
41             my $conf_file = File::Spec->catfile( $metabase_dir, 'relayd' );
42             return unless -e $conf_file;
43             my $Config = Config::Tiny->read( $conf_file );
44             my @config;
45             if ( defined $Config->{_} ) {
46             my $root = delete $Config->{_};
47             @config = map { $_, $root->{$_} } grep { exists $root->{$_} }
48             qw(debug url idfile dbfile address port multiple nocurl norelay offline submissions);
49             push @config, 'plugins', $Config;
50             }
51             return @config;
52             }
53              
54             sub _display_version {
55             print "metabase-relayd version ", $VERSION,
56             ", powered by POE::Component::Metabase::Relay::Server ", POE::Component::Metabase::Relay::Server->VERSION, "\n\n";
57             print <<EOF;
58             Copyright (C) 2014 Chris 'BinGOs' Williams
59             This module may be used, modified, and distributed under the same terms as Perl itself.
60             Please see the license that came with your Perl distribution for details.
61             EOF
62             exit;
63             }
64              
65             sub run {
66             my $package = shift;
67             my %config = _read_config();
68             $config{offline} = delete $config{norelay} if $config{norelay};
69             my $version;
70             GetOptions(
71             "help" => sub { pod2usage(1); },
72             "version" => sub { $version = 1 },
73             "debug" => \$config{debug},
74             "address=s@" => \$config{address},
75             "port=s" => \$config{port},
76             "url=s" => \$config{url},
77             "dbfile=s" => \$config{dbfile},
78             "idfile=s" => \$config{idfile},
79             "multiple" => \$config{multiple},
80             "norelay|offline" => \$config{offline},
81             "nocurl" => \$config{nocurl},
82             "submissions" => \$config{submissions},
83             ) or pod2usage(2);
84              
85             _display_version() if $version;
86              
87             $config{idfile} = File::Spec->catfile( _metabase_dir(), '.metabase', 'metabase_id.json' ) unless $config{idfile};
88             $config{dbfile} = File::Spec->catfile( _metabase_dir(), '.metabase', 'relay.db' ) unless $config{dbfile};
89              
90             print "Running metabase-relayd with options:\n";
91             printf("%-20s %s\n", $_, ref $config{$_}
92             ? (join q{, } => @{ $config{$_} })
93             : $config{$_})
94             for grep { defined $config{$_} } qw(debug url dbfile idfile address port multiple offline nocurl);
95              
96             my $self = bless \%config, $package;
97              
98             if ( $self->{address} ) {
99             $self->{address} = [
100             split(/,/,join(',',( ref $self->{address} eq 'ARRAY' ? @{ $self->{address} } : $self->{address} )))
101             ];
102             s/\s+//g for @{ $self->{address} };
103             }
104              
105             $self->{id} = POE::Session->create(
106             object_states => [
107             $self => [qw(_start _child _recv_evt)],
108             ],
109             )->ID();
110              
111             $self->{relayd} = POE::Component::Metabase::Relay::Server->spawn(
112             ( defined $self->{address} ? ( address => $self->{address} ) : () ),
113             ( defined $self->{port} ? ( port => $self->{port} ) : () ),
114             id_file => $self->{idfile},
115             dsn => 'dbi:SQLite:dbname=' . $self->{dbfile},
116             uri => $self->{url},
117             debug => $self->{debug},
118             multiple => $self->{multiple},
119             no_relay => $self->{offline},
120             no_curl => $self->{nocurl},
121             session => $self->{id},
122             recv_event => '_recv_evt',
123             ( defined $self->{submissions} ? ( submissions => $self->{submissions} ) : () ),
124             );
125              
126             $poe_kernel->run();
127             return 1;
128             }
129              
130             sub _start {
131             my ($kernel,$self) = @_[KERNEL,OBJECT];
132             $self->{id} = $_[SESSION]->ID();
133             $kernel->refcount_increment( $self->{id}, __PACKAGE__ );
134             # Initialise plugins
135             foreach my $plugin ( $self->plugins() ) {
136             next unless can_load( modules => { $plugin => '0' } );
137             eval { $plugin->init( $self->{plugins} ); };
138             }
139             return;
140             }
141              
142             sub _child {
143             my ($kernel,$self,$reason,$child) = @_[KERNEL,OBJECT,ARG0,ARG1];
144             return unless $reason eq 'create';
145             push @{ $self->{_sessions} }, $child->ID();
146             $kernel->detach_child( $child );
147             return;
148             }
149              
150             sub _recv_evt {
151             my ($kernel,$self,$data,$ip) = @_[KERNEL,OBJECT,ARG0,ARG1];
152             $kernel->post( $_, 'mbrd_received', $data, $ip ) for @{ $self->{_sessions} };
153             return;
154             }
155              
156             'Relay it!';
157              
158             __END__
159              
160             =head1 NAME
161              
162             App::Metabase::Relayd - the guts of the metabase-relayd command
163              
164             =head1 SYNOPSIS
165              
166             #!/usr/bin/perl
167             use strict;
168             use warnings;
169             BEGIN { eval "use Event;"; }
170             use App::Metabase::Relayd;
171             App::Metabase::Relayd->run();
172              
173             =head2 run
174              
175             This method is called by L<metabase-relayd> to do all the work.
176              
177             =head1 AUTHOR
178              
179             Chris C<BinGOs> Williams <chris@bingosnet.co.uk>
180              
181             =head1 LICENSE
182              
183             Copyright E<copy> Chris Williams
184              
185             This module may be used, modified, and distributed under the same terms as Perl itself. Please see the license that came with your Perl distribution for details.
186              
187             =cut