Merge remote-tracking branch 'origin/modularization' into modularization
# Conflicts: # dmrlink.py # dmrlink_config.py
This commit is contained in:
commit
23354574d1
114
dmr_utils.py
Executable file
114
dmr_utils.py
Executable file
@ -0,0 +1,114 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
###############################################################################
|
||||||
|
# Copyright (C) 2016 Cortney T. Buffington, N0MJS <n0mjs@me.com>
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from time import time
|
||||||
|
from urllib import URLopener
|
||||||
|
from csv import reader as csv_reader
|
||||||
|
from binascii import b2a_hex as ahex
|
||||||
|
|
||||||
|
# Does anybody read this stuff? There's a PEP somewhere that says I should do this.
|
||||||
|
__author__ = 'Cortney T. Buffington, N0MJS'
|
||||||
|
__copyright__ = 'Copyright (c) 2016 Cortney T. Buffington, N0MJS and the K0USY Group'
|
||||||
|
__credits__ = 'Colin Durbridge, G4EML, Steve Zingman, N4IRS; Mike Zingman'
|
||||||
|
__license__ = 'GNU GPLv3'
|
||||||
|
__maintainer__ = 'Cort Buffington, N0MJS'
|
||||||
|
__email__ = 'n0mjs@me.com'
|
||||||
|
|
||||||
|
#************************************************
|
||||||
|
# STRING UTILITY FUNCTIONS
|
||||||
|
#************************************************
|
||||||
|
|
||||||
|
# Create a 2 byte hex string from an integer
|
||||||
|
def hex_str_2(_int_id):
|
||||||
|
try:
|
||||||
|
return format(_int_id,'x').rjust(4,'0').decode('hex')
|
||||||
|
except TypeError:
|
||||||
|
raise
|
||||||
|
|
||||||
|
# Create a 3 byte hex string from an integer
|
||||||
|
def hex_str_3(_int_id):
|
||||||
|
try:
|
||||||
|
return format(_int_id,'x').rjust(6,'0').decode('hex')
|
||||||
|
except TypeError:
|
||||||
|
raise
|
||||||
|
|
||||||
|
# Create a 4 byte hex string from an integer
|
||||||
|
def hex_str_4(_int_id):
|
||||||
|
try:
|
||||||
|
return format(_int_id,'x').rjust(8,'0').decode('hex')
|
||||||
|
except TypeError:
|
||||||
|
raise
|
||||||
|
|
||||||
|
# Convert a hex string to an int (radio ID, etc.)
|
||||||
|
def int_id(_hex_string):
|
||||||
|
return int(ahex(_hex_string), 16)
|
||||||
|
|
||||||
|
|
||||||
|
#************************************************
|
||||||
|
# ID ALIAS FUNCTIONS
|
||||||
|
#************************************************
|
||||||
|
|
||||||
|
# Download and build dictionaries for mapping number to aliases
|
||||||
|
# Used by applications. These lookups take time, please do not shove them
|
||||||
|
# into this file everywhere and send a pull request!!!
|
||||||
|
# Download a new file if it doesn't exist, or is older than the stale time
|
||||||
|
def try_download(_path, _file, _url, _stale,):
|
||||||
|
now = time()
|
||||||
|
url = URLopener()
|
||||||
|
file_exists = os.path.isfile(_path+_file) == True
|
||||||
|
if file_exists:
|
||||||
|
file_old = (os.path.getmtime(_path+_file) + _stale) < now
|
||||||
|
if not file_exists or (file_exists and file_old):
|
||||||
|
try:
|
||||||
|
url.retrieve(_url, _path+_file)
|
||||||
|
result = 'ID ALIAS MAPPER: \'{}\' successfully downloaded'.format(_file)
|
||||||
|
except IOError:
|
||||||
|
result = 'ID ALIAS MAPPER: \'{}\' could not be downloaded'.format(_file)
|
||||||
|
else:
|
||||||
|
result = 'ID ALIAS MAPPER: \'{}\' is current, not downloaded'.format(_file)
|
||||||
|
url.close()
|
||||||
|
return result
|
||||||
|
|
||||||
|
def mk_id_dict(_path, _file):
|
||||||
|
dict = {}
|
||||||
|
try:
|
||||||
|
with open(_path+_file, 'rU') as _handle:
|
||||||
|
ids = csv_reader(_handle, dialect='excel', delimiter=',')
|
||||||
|
for row in ids:
|
||||||
|
dict[int(row[0])] = (row[1])
|
||||||
|
_handle.close
|
||||||
|
return dict
|
||||||
|
except IOError:
|
||||||
|
return dict
|
||||||
|
|
||||||
|
def get_info(_id, _dict):
|
||||||
|
if _id in _dict:
|
||||||
|
return _dict[_id]
|
||||||
|
return _id
|
||||||
|
|
||||||
|
def get_alias(_id, _dict):
|
||||||
|
_int_id = int_id(_id)
|
||||||
|
if _int_id in _dict:
|
||||||
|
return _dict[_int_id]
|
||||||
|
return _int_id
|
165
dmrlink.py
165
dmrlink.py
@ -48,11 +48,16 @@ from twisted.internet.protocol import DatagramProtocol
|
|||||||
from twisted.internet import reactor
|
from twisted.internet import reactor
|
||||||
from twisted.internet import task
|
from twisted.internet import task
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
from ipsc.ipsc_const import *
|
from ipsc.ipsc_const import *
|
||||||
from ipsc.ipsc_mask import *
|
from ipsc.ipsc_mask import *
|
||||||
from dmrlink_config import build_config
|
from dmrlink_config import build_config
|
||||||
from dmrlink_log import config_logging
|
from dmrlink_log import config_logging
|
||||||
|
|
||||||
|
=======
|
||||||
|
from dmr_utils import hex_str_2, hex_str_3, hex_str_4, int_id
|
||||||
|
from dmrlink_config import build_config
|
||||||
|
>>>>>>> origin/modularization
|
||||||
|
|
||||||
__author__ = 'Cortney T. Buffington, N0MJS'
|
__author__ = 'Cortney T. Buffington, N0MJS'
|
||||||
__copyright__ = 'Copyright (c) 2013 - 2016 Cortney T. Buffington, N0MJS and the K0USY Group'
|
__copyright__ = 'Copyright (c) 2013 - 2016 Cortney T. Buffington, N0MJS and the K0USY Group'
|
||||||
@ -61,6 +66,7 @@ __license__ = 'GNU GPLv3'
|
|||||||
__maintainer__ = 'Cort Buffington, N0MJS'
|
__maintainer__ = 'Cort Buffington, N0MJS'
|
||||||
__email__ = 'n0mjs@me.com'
|
__email__ = 'n0mjs@me.com'
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
# Global variables used whether we are a module or __main__
|
# Global variables used whether we are a module or __main__
|
||||||
systems = {}
|
systems = {}
|
||||||
|
|
||||||
@ -92,6 +98,95 @@ def config_reporting_loop(_type):
|
|||||||
def reporting_loop():
|
def reporting_loop():
|
||||||
logger.debug('Periodic Reporting Loop Started (NULL)')
|
logger.debug('Periodic Reporting Loop Started (NULL)')
|
||||||
|
|
||||||
|
=======
|
||||||
|
# Global variables for all class instances
|
||||||
|
systems = {}
|
||||||
|
|
||||||
|
#************************************************
|
||||||
|
# CONFIGURE THE SYSTEM LOGGER
|
||||||
|
#************************************************
|
||||||
|
|
||||||
|
def config_logging(_logger):
|
||||||
|
dictConfig({
|
||||||
|
'version': 1,
|
||||||
|
'disable_existing_loggers': False,
|
||||||
|
'filters': {
|
||||||
|
},
|
||||||
|
'formatters': {
|
||||||
|
'verbose': {
|
||||||
|
'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
|
||||||
|
},
|
||||||
|
'timed': {
|
||||||
|
'format': '%(levelname)s %(asctime)s %(message)s'
|
||||||
|
},
|
||||||
|
'simple': {
|
||||||
|
'format': '%(levelname)s %(message)s'
|
||||||
|
},
|
||||||
|
'syslog': {
|
||||||
|
'format': '%(name)s (%(process)d): %(levelname)s %(message)s'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'handlers': {
|
||||||
|
'null': {
|
||||||
|
'class': 'logging.NullHandler'
|
||||||
|
},
|
||||||
|
'console': {
|
||||||
|
'class': 'logging.StreamHandler',
|
||||||
|
'formatter': 'simple'
|
||||||
|
},
|
||||||
|
'console-timed': {
|
||||||
|
'class': 'logging.StreamHandler',
|
||||||
|
'formatter': 'timed'
|
||||||
|
},
|
||||||
|
'file': {
|
||||||
|
'class': 'logging.FileHandler',
|
||||||
|
'formatter': 'simple',
|
||||||
|
'filename': _logger['LOG_FILE'],
|
||||||
|
},
|
||||||
|
'file-timed': {
|
||||||
|
'class': 'logging.FileHandler',
|
||||||
|
'formatter': 'timed',
|
||||||
|
'filename': _logger['LOG_FILE'],
|
||||||
|
},
|
||||||
|
'syslog': {
|
||||||
|
'class': 'logging.handlers.SysLogHandler',
|
||||||
|
'formatter': 'syslog',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'loggers': {
|
||||||
|
_logger['LOG_NAME']: {
|
||||||
|
'handlers': _logger['LOG_HANDLERS'].split(','),
|
||||||
|
'level': _logger['LOG_LEVEL'],
|
||||||
|
'propagate': True,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return logging.getLogger(_logger['LOG_NAME'])
|
||||||
|
|
||||||
|
|
||||||
|
#************************************************
|
||||||
|
# IMPORTING OTHER FILES - '#include'
|
||||||
|
#************************************************
|
||||||
|
|
||||||
|
# Import IPSC message types and version information
|
||||||
|
#
|
||||||
|
try:
|
||||||
|
from ipsc.ipsc_const import *
|
||||||
|
except ImportError:
|
||||||
|
sys.exit('IPSC message types file not found or invalid')
|
||||||
|
|
||||||
|
# Import IPSC flag mask values
|
||||||
|
#
|
||||||
|
try:
|
||||||
|
from ipsc.ipsc_mask import *
|
||||||
|
except ImportError:
|
||||||
|
sys.exit('IPSC mask values file not found or invalid')
|
||||||
|
|
||||||
|
|
||||||
|
#************************************************
|
||||||
|
# UTILITY FUNCTIONS FOR INTERNAL USE
|
||||||
|
#************************************************
|
||||||
|
>>>>>>> origin/modularization
|
||||||
|
|
||||||
# Determine if the provided peer ID is valid for the provided network
|
# Determine if the provided peer ID is valid for the provided network
|
||||||
#
|
#
|
||||||
@ -321,6 +416,56 @@ def print_master(_network):
|
|||||||
print('\t\tStatus: {}, KeepAlives Sent: {}, KeepAlives Outstanding: {}, KeepAlives Missed: {}' .format(_master['STATUS']['CONNECTED'], _master['STATUS']['KEEP_ALIVES_SENT'], _master['STATUS']['KEEP_ALIVES_OUTSTANDING'], _master['STATUS']['KEEP_ALIVES_MISSED']))
|
print('\t\tStatus: {}, KeepAlives Sent: {}, KeepAlives Outstanding: {}, KeepAlives Missed: {}' .format(_master['STATUS']['CONNECTED'], _master['STATUS']['KEEP_ALIVES_SENT'], _master['STATUS']['KEEP_ALIVES_OUTSTANDING'], _master['STATUS']['KEEP_ALIVES_MISSED']))
|
||||||
print('\t\t KeepAlives Received: {}, Last KeepAlive Received at: {}' .format(_master['STATUS']['KEEP_ALIVES_RECEIVED'], _master['STATUS']['KEEP_ALIVE_RX_TIME']))
|
print('\t\t KeepAlives Received: {}, Last KeepAlive Received at: {}' .format(_master['STATUS']['KEEP_ALIVES_RECEIVED'], _master['STATUS']['KEEP_ALIVE_RX_TIME']))
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
|
=======
|
||||||
|
|
||||||
|
# Timed loop used for reporting IPSC status
|
||||||
|
#
|
||||||
|
# REPORT BASED ON THE TYPE SELECTED IN THE MAIN CONFIG FILE
|
||||||
|
def config_reports(_config):
|
||||||
|
global reporting_loop
|
||||||
|
|
||||||
|
if _config['REPORTS']['REPORT_NETWORKS'] == 'PICKLE':
|
||||||
|
def reporting_loop():
|
||||||
|
logger.debug('Periodic Reporting Loop Started (PICKLE)')
|
||||||
|
try:
|
||||||
|
with open(_config['REPORTS']['REPORT_PATH']+'dmrlink_stats.pickle', 'wb') as file:
|
||||||
|
pickle_dump(_config['SYSTEMS'], file, 2)
|
||||||
|
file.close()
|
||||||
|
except IOError as detail:
|
||||||
|
logger.error('I/O Error: %s', detail)
|
||||||
|
|
||||||
|
elif _config['REPORTS']['REPORT_NETWORKS'] == 'PRINT':
|
||||||
|
def reporting_loop():
|
||||||
|
logger.debug('Periodic Reporting Loop Started (PRINT)')
|
||||||
|
for system in _config['SYSTEMS']:
|
||||||
|
print_master(system)
|
||||||
|
print_peer_list(system)
|
||||||
|
|
||||||
|
else:
|
||||||
|
def reporting_loop():
|
||||||
|
logger.debug('Periodic Reporting Loop Started (NULL)')
|
||||||
|
|
||||||
|
|
||||||
|
# Shut ourselves down gracefully with the IPSC peers.
|
||||||
|
#
|
||||||
|
def handler(_signal, _frame):
|
||||||
|
logger.info('*** DMRLINK IS TERMINATING WITH SIGNAL %s ***', str(_signal))
|
||||||
|
|
||||||
|
for system in systems:
|
||||||
|
this_ipsc = systems[system]
|
||||||
|
logger.info('De-Registering from IPSC %s', system)
|
||||||
|
de_reg_req_pkt = this_ipsc.hashed_packet(this_ipsc._local['AUTH_KEY'], this_ipsc.DE_REG_REQ_PKT)
|
||||||
|
this_ipsc.send_to_ipsc(de_reg_req_pkt)
|
||||||
|
|
||||||
|
reactor.stop()
|
||||||
|
|
||||||
|
# Set signal handers so that we can gracefully exit if need be
|
||||||
|
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGQUIT]:
|
||||||
|
signal.signal(sig, handler)
|
||||||
|
|
||||||
|
|
||||||
|
>>>>>>> origin/modularization
|
||||||
|
|
||||||
#************************************************
|
#************************************************
|
||||||
# IPSC CLASS
|
# IPSC CLASS
|
||||||
@ -816,11 +961,13 @@ class IPSC(DatagramProtocol):
|
|||||||
return
|
return
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
# MOTOROLA XCMP/XNL CONTROL PROTOCOL: We don't process these (yet)
|
# MOTOROLA XCMP/XNL CONTROL PROTOCOL: We don't process these (yet)
|
||||||
elif _packettype == XCMP_XNL:
|
elif _packettype == XCMP_XNL:
|
||||||
self.xcmp_xnl(self._network, data)
|
self.xcmp_xnl(self._network, data)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
# ORIGINATED BY PEERS, NOT IPSC MAINTENANCE: Call monitoring is all we've found here so far
|
# ORIGINATED BY PEERS, NOT IPSC MAINTENANCE: Call monitoring is all we've found here so far
|
||||||
elif _packettype == CALL_MON_STATUS:
|
elif _packettype == CALL_MON_STATUS:
|
||||||
self.call_mon_status(self._network, data)
|
self.call_mon_status(self._network, data)
|
||||||
@ -834,6 +981,7 @@ class IPSC(DatagramProtocol):
|
|||||||
self.call_mon_nack(self._network, data)
|
self.call_mon_nack(self._network, data)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
# IPSC CONNECTION MAINTENANCE MESSAGES
|
# IPSC CONNECTION MAINTENANCE MESSAGES
|
||||||
elif _packettype == DE_REG_REQ:
|
elif _packettype == DE_REG_REQ:
|
||||||
de_register_peer(self._network, _peerid)
|
de_register_peer(self._network, _peerid)
|
||||||
@ -850,9 +998,8 @@ class IPSC(DatagramProtocol):
|
|||||||
return
|
return
|
||||||
return
|
return
|
||||||
|
|
||||||
#
|
|
||||||
# THE FOLLOWING PACKETS ARE RECEIVED ONLY IF WE ARE OPERATING AS A PEER
|
# THE FOLLOWING PACKETS ARE RECEIVED ONLY IF WE ARE OPERATING AS A PEER
|
||||||
#
|
|
||||||
|
|
||||||
# ONLY ACCEPT FROM A PREVIOUSLY VALIDATED PEER
|
# ONLY ACCEPT FROM A PREVIOUSLY VALIDATED PEER
|
||||||
if _packettype in PEER_REQUIRED:
|
if _packettype in PEER_REQUIRED:
|
||||||
@ -898,7 +1045,6 @@ class IPSC(DatagramProtocol):
|
|||||||
return
|
return
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
# THIS MEANS WE HAVE SUCCESSFULLY REGISTERED TO OUR MASTER - RECORD MASTER INFORMATION
|
# THIS MEANS WE HAVE SUCCESSFULLY REGISTERED TO OUR MASTER - RECORD MASTER INFORMATION
|
||||||
elif _packettype == MASTER_REG_REPLY:
|
elif _packettype == MASTER_REG_REPLY:
|
||||||
self.master_reg_reply(data, _peerid)
|
self.master_reg_reply(data, _peerid)
|
||||||
@ -906,7 +1052,6 @@ class IPSC(DatagramProtocol):
|
|||||||
|
|
||||||
|
|
||||||
# THE FOLLOWING PACKETS ARE RECEIVED ONLLY IF WE ARE OPERATING AS A MASTER
|
# THE FOLLOWING PACKETS ARE RECEIVED ONLLY IF WE ARE OPERATING AS A MASTER
|
||||||
|
|
||||||
# REQUESTS FROM PEERS: WE MUST REPLY IMMEDIATELY FOR IPSC MAINTENANCE
|
# REQUESTS FROM PEERS: WE MUST REPLY IMMEDIATELY FOR IPSC MAINTENANCE
|
||||||
|
|
||||||
# REQUEST TO REGISTER TO THE IPSC
|
# REQUEST TO REGISTER TO THE IPSC
|
||||||
@ -924,7 +1069,10 @@ class IPSC(DatagramProtocol):
|
|||||||
self.peer_list_req(_peerid)
|
self.peer_list_req(_peerid)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
|
|
||||||
|
=======
|
||||||
|
>>>>>>> origin/modularization
|
||||||
# PACKET IS OF AN UNKNOWN TYPE. LOG IT AND IDENTTIFY IT!
|
# PACKET IS OF AN UNKNOWN TYPE. LOG IT AND IDENTTIFY IT!
|
||||||
else:
|
else:
|
||||||
self.unknown_message(self._network, _packettype, _peerid, data)
|
self.unknown_message(self._network, _packettype, _peerid, data)
|
||||||
@ -949,11 +1097,20 @@ if __name__ == '__main__':
|
|||||||
if not cli_args.CFG_FILE:
|
if not cli_args.CFG_FILE:
|
||||||
cli_args.CFG_FILE = os.path.dirname(os.path.abspath(__file__))+'/dmrlink.cfg'
|
cli_args.CFG_FILE = os.path.dirname(os.path.abspath(__file__))+'/dmrlink.cfg'
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
# Call the external routine to build the configuration dictionary
|
# Call the external routine to build the configuration dictionary
|
||||||
CONFIG = build_config(cli_args.CFG_FILE)
|
CONFIG = build_config(cli_args.CFG_FILE)
|
||||||
|
|
||||||
# Call the external routing to start the system logger
|
# Call the external routing to start the system logger
|
||||||
logger = config_logging(CONFIG['LOGGER'])
|
logger = config_logging(CONFIG['LOGGER'])
|
||||||
|
=======
|
||||||
|
|
||||||
|
CONFIG = build_config(cli_args.CFG_FILE)
|
||||||
|
logger = config_logging(CONFIG['LOGGER'])
|
||||||
|
config_reports(CONFIG)
|
||||||
|
|
||||||
|
|
||||||
|
>>>>>>> origin/modularization
|
||||||
logger.info('DMRlink \'dmrlink.py\' (c) 2013 - 2015 N0MJS & the K0USY Group - SYSTEM STARTING...')
|
logger.info('DMRlink \'dmrlink.py\' (c) 2013 - 2015 N0MJS & the K0USY Group - SYSTEM STARTING...')
|
||||||
|
|
||||||
# Shut ourselves down gracefully with the IPSC peers.
|
# Shut ourselves down gracefully with the IPSC peers.
|
||||||
|
@ -23,6 +23,7 @@ import sys
|
|||||||
|
|
||||||
from socket import gethostbyname
|
from socket import gethostbyname
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
# Does anybody read this stuff? There's a PEP somewhere that says I should do this.
|
# Does anybody read this stuff? There's a PEP somewhere that says I should do this.
|
||||||
__author__ = 'Cortney T. Buffington, N0MJS'
|
__author__ = 'Cortney T. Buffington, N0MJS'
|
||||||
__copyright__ = 'Copyright (c) 2016 Cortney T. Buffington, N0MJS and the K0USY Group'
|
__copyright__ = 'Copyright (c) 2016 Cortney T. Buffington, N0MJS and the K0USY Group'
|
||||||
@ -30,6 +31,14 @@ __license__ = 'GNU GPLv3'
|
|||||||
__maintainer__ = 'Cort Buffington, N0MJS'
|
__maintainer__ = 'Cort Buffington, N0MJS'
|
||||||
__email__ = 'n0mjs@me.com'
|
__email__ = 'n0mjs@me.com'
|
||||||
|
|
||||||
|
=======
|
||||||
|
__author__ = 'Cortney T. Buffington, N0MJS'
|
||||||
|
__copyright__ = 'Copyright (c) 2016 Cortney T. Buffington, N0MJS and the K0USY Group'
|
||||||
|
__credits__ = 'Adam Fast, KC0YLK; Dave Kierzkowski, KD8EYF; Steve Zingman, N4IRS; Mike Zingman, N4IRR'
|
||||||
|
__license__ = 'GNU GPLv3'
|
||||||
|
__maintainer__ = 'Cort Buffington, N0MJS'
|
||||||
|
__email__ = 'n0mjs@me.com'
|
||||||
|
>>>>>>> origin/modularization
|
||||||
|
|
||||||
def build_config(_config_file):
|
def build_config(_config_file):
|
||||||
config = ConfigParser.ConfigParser()
|
config = ConfigParser.ConfigParser()
|
||||||
@ -178,6 +187,7 @@ def build_config(_config_file):
|
|||||||
return CONFIG
|
return CONFIG
|
||||||
|
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
# Used to run this file direclty and print the config,
|
# Used to run this file direclty and print the config,
|
||||||
# which might be useful for debugging
|
# which might be useful for debugging
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
@ -201,3 +211,7 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
|
|
||||||
pprint(build_config(cli_args.CONFIG_FILE))
|
pprint(build_config(cli_args.CONFIG_FILE))
|
||||||
|
=======
|
||||||
|
if __name__ == '__main__':
|
||||||
|
pass
|
||||||
|
>>>>>>> origin/modularization
|
||||||
|
Loading…
Reference in New Issue
Block a user