152aea6e39bf76ca63470f3adc5cc6036696c159
[ais.git] / bin / inputs / common.py
1 # -*- coding: utf-8 -*-
2 '''
3 AIS input basic functions
4 '''
5
6 __all__ = [
7     'NMEA_DIR',
8     'DEFAULT_MTU',
9     'Source', 
10     'get_source_by_id4', 'refresh_all_stats',
11     'SourceLogger',
12     'ais_line_reader']
13
14 import os.path
15 import logging
16 from datetime import datetime
17
18 from ais.inputs.stats import InStats
19 from ais.inputs.peers import SOURCES
20 from ais.inputs.outpeer import outpeers_from_config
21
22
23 NMEA_DIR = '/var/lib/ais/nmea'
24 DEFAULT_MTU = 1500
25
26 class SourceLogger:
27     def __init__(self, id4):
28         self.id4 = id4
29         self.dumpfile = None
30         self.last_timestamp = None
31         self.last_dumpdate = None
32         self.last_from = None
33
34     def log_line(self, timestamp, from_, line):
35         '''
36         Log line in file NMEA_DIR/YYYYMMDD-4444.log.
37         Add a line "Timestamp:" if different than previous call.
38         Add a line "From:" if different than previous call.
39         '''
40
41         timestamp = int(timestamp) # we don't  want to log second fragments
42         if timestamp != self.last_timestamp:
43             dumpdate = datetime.utcfromtimestamp(timestamp).date()
44             if dumpdate != self.last_dumpdate:
45                 if self.dumpfile:
46                     self.dumpfile.close()
47                 localfilename = '%s-%s.dump' \
48                                 % (dumpdate.strftime('%Y%m%d'), self.id4)
49                 filename = os.path.join(NMEA_DIR, localfilename)
50                 logging.info('Opening %s', filename)
51                 self.dumpfile = file(filename, 'a', 1)
52                 self.last_dumpdate = dumpdate
53                 self.last_from = None # make sure From: is present in new files
54             
55             self.dumpfile.write('Timestamp: %d\n' % timestamp)
56             self.last_timestamp = timestamp
57
58         if from_ != self.last_from:
59             self.dumpfile.write('From: %s\n' % from_)
60             self.last_from = from_
61
62         self.dumpfile.write(line+'\n')
63
64
65 __all_sources__ = {}
66
67 class Source:
68     def __init__(self, id4):
69         self.id4 = id4
70         assert id4 not in __all_sources__, \
71             '%s is allready a registered source.' % id4
72         __all_sources__[id4] = self
73         self.stats = InStats(id4)
74         self.logger = SourceLogger(id4)
75         logging.debug('sources: %s', SOURCES)
76         config_outpeers = SOURCES[id4].get('out', ())
77         self.outpeers = outpeers_from_config(config_outpeers)
78         logging.info('Outpeers for %s: %s', id4, self.outpeers)
79
80 def get_source_by_id4(id4):
81     '''
82     Returns a Source object with that id4.
83     Create one if not found.
84     '''
85     return __all_sources__.get(id4, None) or Source(id4)
86
87
88 def refresh_all_stats():
89     '''
90     Calls stats.refresh() for all sources.
91     '''
92     for source in __all_sources__.itervalues():
93         source.stats.refresh()
94     
95