File Coverage

blib/lib/IRC/Indexer/Conf.pm
Criterion Covered Total %
statement 46 78 58.9
branch 5 28 17.8
condition 1 5 20.0
subroutine 14 19 73.6
pod 5 11 45.4
total 71 141 50.3


line stmt bran cond sub pod time code
1             package IRC::Indexer::Conf;
2              
3 1     1   1750 use 5.10.1;
  1         4  
  1         43  
4 1     1   5 use strict;
  1         2  
  1         28  
5 1     1   4 use warnings;
  1         2  
  1         33  
6 1     1   4 use Carp;
  1         2  
  1         63  
7              
8 1     1   5 use Scalar::Util qw/openhandle/;
  1         1  
  1         39  
9              
10 1     1   5 use File::Find;
  1         1  
  1         100  
11              
12 1     1   673 use YAML::XS ();
  1         2697  
  1         832  
13              
14 1     1 0 6103 sub new { bless {}, shift }
15              
16             sub slurp {
17 3     3 0 4 my ($self, $path) = @_;
18            
19 3         7 my $slurped;
20            
21 3 50       12 if ( openhandle($path) ) {
22 3         11 local $/; $slurped = <$path>;
  3         28  
23             } else {
24 0 0       0 open my $fh, '<:encoding(utf8)', $path
25             or croak "Conf open failed: $path: $!";
26 0         0 { local $/; $slurped = <$fh> }
  0         0  
  0         0  
27 0         0 close $fh;
28             }
29              
30 3         7 return $slurped
31             }
32              
33             sub parse_conf {
34 3     3 1 876 my ($self, $path) = @_;
35 3         10 my $yaml = $self->slurp($path);
36 3 50       9 croak "No data returned from parse_conf: $path"
37             unless $yaml;
38              
39 3         867 my $ref = YAML::XS::Load($yaml);
40              
41 3         17 return $ref
42             }
43              
44             sub parse_nets {
45 0     0 1 0 my ($self, $dir) = @_;
46            
47 0         0 my $nethash = {};
48            
49 0 0       0 my @specfiles = ref $dir eq 'ARRAY' ? @$dir
50             : $self->find_nets($dir) ;
51              
52 0         0 SERV: for my $specpath (@specfiles) {
53 0         0 my $this_spec = $self->parse_conf($specpath);
54            
55 0 0       0 unless ($this_spec->{Server}) {
56 0         0 croak "specfile missing Server definition: $specpath"
57             }
58            
59 0 0       0 unless ($this_spec->{Network}) {
60 0         0 croak "specfile missing Network definition: $specpath"
61             }
62              
63 0         0 my $servname = $this_spec->{Server};
64 0         0 my $netname = $this_spec->{Network};
65            
66 0         0 $nethash->{$netname}->{$servname} = $this_spec;
67             }
68              
69 0         0 return $nethash
70             }
71              
72             sub find_nets {
73 0     0 1 0 my ($self, $dir) = @_;
74            
75 0 0       0 croak "find_nets called with no NetworkDir"
76             unless $dir;
77            
78 0 0       0 croak "find_nets called against non-directory $dir"
79             unless -d $dir;
80            
81 0         0 my @found;
82             find(
83             sub {
84 0   0 0   0 my $thisext = (split /\./)[-1] // return;
85 0 0       0 push(@found, $File::Find::name)
86             if $thisext eq 'server';
87             },
88 0         0 $dir
89             );
90              
91 0 0       0 return wantarray ? @found : \@found ;
92             }
93              
94              
95             ## Example CF
96              
97 0     0 0 0 sub get_example_conf { get_example_cf(@_) }
98             sub get_example_cf {
99 3     3 1 6 my ($self, $cftype) = @_;
100 3         6 my $method = 'example_cf_'.$cftype;
101            
102 3 50       22 unless ($self->can($method)) {
103 0         0 croak "Invalid example conf type: $cftype"
104             }
105              
106 3         12 return $self->$method
107             }
108              
109 0     0 0 0 sub write_example_conf { write_example_cf(@_) }
110             sub write_example_cf {
111 1     1 1 2 my ($self, $cftype, $path) = @_;
112 1 50 33     10 croak "write_example_cf requires a type and path"
113             unless $cftype and $path;
114            
115 1         4 my $conf = $self->get_example_cf($cftype);
116              
117 1 50       5 if ( openhandle($path) ) {
118 1         8 print $path $conf;
119             } else {
120 0 0       0 open my $fh, '>', $path or die "open failed: $!\n";
121 0         0 print $fh $conf;
122 0         0 close $fh;
123             }
124             }
125              
126             sub example_cf_spec {
127 1     1 0 2 my $conf = <
128             ---
129             ### Example server spec file
130              
131             Network: CobaltIRC
132             Server: eris.oppresses.us
133             Port: 6667
134             # Defaults are probably fine here:
135             #Nickname:
136             #BindAddr:
137             #UseIPV6:
138             #Timeout: 90
139             #Interval: 5
140              
141             END
142              
143 1         5 return $conf
144             }
145              
146             sub example_cf_httpd {
147 2     2 0 3 my $conf = <
148             ---
149             ### Example HTTPD conf
150              
151             ## ServerPort:
152             ##
153             ## Port to run this HTTPD instance on.
154             ServerPort: 8700
155              
156             ## BindAddr:
157             ##
158             ## Optional local address to bind HTTPD to.
159             #BindAddr: '0.0.0.0'
160              
161             ## NetworkDir:
162             ##
163             ## Network spec files will be found recursively under NetworkDir:
164             ## A network spec file should end in ".server"
165             ## These specs tie networks together under their specified Network:
166             ## The files should be YAML, looking something like:
167             # ---
168             # Network: CobaltIRC
169             # Server: eris.oppresses.us
170             # Port: 6667
171             # Timeout: 90
172             # Interval: 5
173             ##
174             ## If you have multiple .server files for one Network, their Servers
175             ## will be cycled.
176             ## Specifying a round-robin will also generally do what you mean.
177             NetworkDir: /home/ircindex/networks
178              
179             ## CacheDir:
180             ##
181             ## Large pools of trawlers will store quite a bit of data after
182             ## a few runs have completed.
183             ## This trades some performance for significant memory savings.
184             ##
185             ## You probably want this.
186             ##
187             ## If a CacheDir is not specified, resultsets will live in memory;
188             ## additionally, due to the nature of the forking encoders,
189             ## there will be some extra processing overhead when results are
190             ## cached.
191             CacheDir: /home/ircindex/jsoncache
192              
193             ## LogFile:
194             ##
195             ## Path to log file.
196             ## If omitted, no logging takes place.
197             LogFile: /home/ircindex/indexer.log
198              
199             ## LogLevel:
200             ##
201             ## Log verbosity level.
202             ## 'debug', 'info', or 'warn'
203             LogLevel: info
204              
205             ## LogHTTP:
206             ##
207             ## If true, log HTTP-related activity
208             ## Defaults to ON
209             LogHTTP: 1
210              
211             ## LogIRC:
212             ##
213             ## If true, log trawling-related activity
214             ## Defaults to ON
215             LogIRC: 1
216              
217             ## PidFile:
218             ##
219             ## If a PidFile is specified, the server's PID will be written to the
220             ## specified file.
221             #PidFile:
222              
223             ## TrawlInterval:
224             ##
225             ## Delay (in seconds) between trawl runs per-network.
226             ## Can be overriden with the --interval command opt.
227             ## Defaults to 600 (10 mins)
228             #TrawlInterval: 600
229              
230             ## Forking:
231             ##
232             ## If Forking is enabled, trawlers will be spawned as external
233             ## processes rather than running asynchronously as part of a
234             ## single process.
235             ##
236             ## A trawler that is composing a very large list of channels
237             ## can use a fair bit of CPU; if you can spare a little extra
238             ## memory during runs and have the cores for it, fork them instead.
239             Forking: 0
240              
241             ## MaxTrawlers:
242             ##
243             ## If you are handling a lot of networks, you may want to limit
244             ## the number of forked trawlers that can be running at a given
245             ## time.
246             ##
247             ## If Forking is not enabled, this controls the number of async
248             ## trawlers that will be ->run() at a time.
249             ##
250             ## Only one trawler will run per network; in other words, the
251             ## theoretical maximum number of trawlers if MaxTrawlers is not
252             ## set is the number of configured networks.
253             ##
254             ## You might want a shorter per-trawler timeout if you are severely
255             ## limiting your MaxTrawlers.
256             ##
257             ## Defaults to 20; 0 or empty string '' disables.
258             #MaxTrawlers: 10
259              
260             ## MaxEncoders:
261             ##
262             ## Workers are forked off to handle the potentially expensive
263             ## JSON encoding of server trawl results; if you're trawling
264             ## a lot of networks, you may want to throttle these to avoid
265             ## resource starvation.
266             ##
267             ## It's perfectly safe to set to '1' -- the only downside is
268             ## increasing the odds of keeping more networks in memory
269             ## longer before they can be shuffled off to an encoder.
270             ##
271             ## Defaults to 20.
272             #MaxEncoders: 10
273              
274             ## ListChans:
275             ##
276             ## If ListChans is enabled, the server will create sorted lists of
277             ## channels as documented in IRC::Indexer::POD::ServerSpec
278             ##
279             ## Expensive in terms of CPU and space.
280             ListChans: 0
281              
282             END
283              
284 2         6 return $conf
285             }
286              
287             1;
288             __END__