parent
50bd19a5df
commit
3bbb970198
@ -1,78 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
###############################################################################
|
|
||||||
# Copyright (C) 2016-2018 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
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
'''
|
|
||||||
These are contants used by HBlink. Rather than stuff them into the main program
|
|
||||||
file, any new constants should be placed here. It makes them easier to keep track
|
|
||||||
of and keeps hblink.py shorter.
|
|
||||||
'''
|
|
||||||
|
|
||||||
__author__ = 'Cortney T. Buffington, N0MJS'
|
|
||||||
__copyright__ = 'Copyright (c) 2016 Cortney T. Buffington, N0MJS and the K0USY Group'
|
|
||||||
__credits__ = ''
|
|
||||||
__license__ = 'GNU GPLv3'
|
|
||||||
__maintainer__ = 'Cort Buffington, N0MJS'
|
|
||||||
__email__ = 'n0mjs@me.com'
|
|
||||||
|
|
||||||
|
|
||||||
# DMR Related constants
|
|
||||||
ID_MIN = 1
|
|
||||||
ID_MAX = 16776415
|
|
||||||
|
|
||||||
# Timers
|
|
||||||
STREAM_TO = .360
|
|
||||||
|
|
||||||
# Options from the LC - used for late entry
|
|
||||||
LC_OPT = b'\x00\x00\x20'
|
|
||||||
|
|
||||||
# HomeBrew Protocol Frame Types
|
|
||||||
HBPF_VOICE = 0x0
|
|
||||||
HBPF_VOICE_SYNC = 0x1
|
|
||||||
HBPF_DATA_SYNC = 0x2
|
|
||||||
HBPF_SLT_VHEAD = 0x1
|
|
||||||
HBPF_SLT_VTERM = 0x2
|
|
||||||
|
|
||||||
# HomeBrew Protocol Commands
|
|
||||||
DMRD = b'DMRD'
|
|
||||||
MSTCL = b'MSTCL'
|
|
||||||
MSTNAK = b'MSTNAK'
|
|
||||||
MSTPONG = b'MSTPONG'
|
|
||||||
MSTN = b'MSTN'
|
|
||||||
MSTP = b'MSTP'
|
|
||||||
MSTC = b'MSTC'
|
|
||||||
RPTL = b'RPTL'
|
|
||||||
RPTPING = b'RPTPING'
|
|
||||||
RPTCL = b'RPTCL'
|
|
||||||
RPTL = b'RPTL'
|
|
||||||
RPTACK = b'RPTACK'
|
|
||||||
RPTK = b'RPTK'
|
|
||||||
RPTC = b'RPTC'
|
|
||||||
RPTP = b'RPTP'
|
|
||||||
RPTA = b'RPTA'
|
|
||||||
RPTO = b'RPTO'
|
|
||||||
DMRA = b'DMRA'
|
|
||||||
|
|
||||||
#Bridge Control commands
|
|
||||||
BC = b'BC'
|
|
||||||
BCKA = b'BCKA'
|
|
||||||
BCSQ = b'BCSQ'
|
|
||||||
|
|
||||||
# Higheset peer ID permitted by HBP
|
|
||||||
PEER_MAX = 4294967295
|
|
||||||
@ -1,348 +0,0 @@
|
|||||||
###############################################################################
|
|
||||||
# Copyright (C) 2020 Simon Adlem, G7RZU <g7rzu@gb7fr.org.uk>
|
|
||||||
#
|
|
||||||
# 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
|
|
||||||
###############################################################################
|
|
||||||
voiceMap = {
|
|
||||||
'en_GB': {
|
|
||||||
'A': 'alpha',
|
|
||||||
'B': 'bravo',
|
|
||||||
'C': 'charlie',
|
|
||||||
'D': 'delta',
|
|
||||||
'E': 'echo',
|
|
||||||
'F': 'foxtrot',
|
|
||||||
'G': 'golf',
|
|
||||||
'H': 'hotel',
|
|
||||||
'I': 'india',
|
|
||||||
'J': 'juliet',
|
|
||||||
'K': 'kilo',
|
|
||||||
'L': 'lima',
|
|
||||||
'M': 'mike',
|
|
||||||
'N': 'november',
|
|
||||||
'O': 'oscar',
|
|
||||||
'P': 'papa',
|
|
||||||
'Q': 'quebec',
|
|
||||||
'R': 'romeo',
|
|
||||||
'S': 'sierra',
|
|
||||||
'T': 'tango',
|
|
||||||
'U': 'uniform',
|
|
||||||
'V': 'victor',
|
|
||||||
'W': 'whiskey',
|
|
||||||
'X': 'x-ray',
|
|
||||||
'Y': 'yankee',
|
|
||||||
'Z': 'zulu',
|
|
||||||
'to': 'silence',
|
|
||||||
'notlinked': 'not-linked',
|
|
||||||
'linkedto': 'linked-to'
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
'en_GB_2': {
|
|
||||||
'A': 'alpha',
|
|
||||||
'B': 'bravo',
|
|
||||||
'C': 'charlie',
|
|
||||||
'D': 'delta',
|
|
||||||
'E': 'echo',
|
|
||||||
'F': 'foxtrot',
|
|
||||||
'G': 'golf',
|
|
||||||
'H': 'hotel',
|
|
||||||
'I': 'india',
|
|
||||||
'J': 'juliet',
|
|
||||||
'K': 'kilo',
|
|
||||||
'L': 'lima',
|
|
||||||
'M': 'mike',
|
|
||||||
'N': 'november',
|
|
||||||
'O': 'oscar',
|
|
||||||
'P': 'papa',
|
|
||||||
'Q': 'quebec',
|
|
||||||
'R': 'romeo',
|
|
||||||
'S': 'sierra',
|
|
||||||
'T': 'tango',
|
|
||||||
'U': 'uniform',
|
|
||||||
'V': 'victor',
|
|
||||||
'W': 'whiskey',
|
|
||||||
'X': 'x-ray',
|
|
||||||
'Y': 'yankee',
|
|
||||||
'Z': 'zulu',
|
|
||||||
'to': 'silence',
|
|
||||||
'notlinked': 'not-linked',
|
|
||||||
'linkedto': 'linked-to'
|
|
||||||
},
|
|
||||||
'cy_GB': {
|
|
||||||
'A': 'alpha',
|
|
||||||
'B': 'bravo',
|
|
||||||
'C': 'charlie',
|
|
||||||
'D': 'delta',
|
|
||||||
'E': 'echo',
|
|
||||||
'F': 'foxtrot',
|
|
||||||
'G': 'golf',
|
|
||||||
'H': 'hotel',
|
|
||||||
'I': 'india',
|
|
||||||
'J': 'juliet',
|
|
||||||
'K': 'kilo',
|
|
||||||
'L': 'lima',
|
|
||||||
'M': 'mike',
|
|
||||||
'N': 'november',
|
|
||||||
'O': 'oscar',
|
|
||||||
'P': 'papa',
|
|
||||||
'Q': 'quebec',
|
|
||||||
'R': 'romeo',
|
|
||||||
'S': 'sierra',
|
|
||||||
'T': 'tango',
|
|
||||||
'U': 'uniform',
|
|
||||||
'V': 'victor',
|
|
||||||
'W': 'whiskey',
|
|
||||||
'X': 'x-ray',
|
|
||||||
'Y': 'yankee',
|
|
||||||
'Z': 'zulu',
|
|
||||||
'to': 'silence',
|
|
||||||
'notlinked': 'not-linked',
|
|
||||||
'linkedto': 'linked-to'
|
|
||||||
},
|
|
||||||
|
|
||||||
'en_US': {
|
|
||||||
'to': '2',
|
|
||||||
'freedmr': 'silence',
|
|
||||||
'this-is': 'silence'
|
|
||||||
},
|
|
||||||
|
|
||||||
'es_ES': {
|
|
||||||
'1': 'one',
|
|
||||||
'2': 'two',
|
|
||||||
'3': 'three',
|
|
||||||
'4': 'four',
|
|
||||||
'5': 'five',
|
|
||||||
'6': 'six',
|
|
||||||
'7': 'seven',
|
|
||||||
'8': 'eight',
|
|
||||||
'9': 'nine',
|
|
||||||
'A': 'alfa',
|
|
||||||
'B': 'bravo',
|
|
||||||
'C': 'charlie',
|
|
||||||
'D': 'delta',
|
|
||||||
'E': 'echo',
|
|
||||||
'F': 'foxtrot',
|
|
||||||
'G': 'golf',
|
|
||||||
'H': 'hotel',
|
|
||||||
'I': 'india',
|
|
||||||
'J': 'juliet',
|
|
||||||
'K': 'kilo',
|
|
||||||
'L': 'lima',
|
|
||||||
'M': 'mike',
|
|
||||||
'N': 'november',
|
|
||||||
'O': 'oscar',
|
|
||||||
'P': 'papa',
|
|
||||||
'Q': 'quebec',
|
|
||||||
'R': 'romeo',
|
|
||||||
'S': 'sierra',
|
|
||||||
'T': 'tango',
|
|
||||||
'U': 'uniform',
|
|
||||||
'V': 'victor',
|
|
||||||
'W': 'whiskey',
|
|
||||||
'X': 'x-ray',
|
|
||||||
'Y': 'yankee',
|
|
||||||
'Z': 'zulu',
|
|
||||||
'to': 'silence',
|
|
||||||
'notlinked': 'not-linked',
|
|
||||||
'linkedto': 'linked-to'
|
|
||||||
},
|
|
||||||
'es_ES_2': {
|
|
||||||
'1': 'one',
|
|
||||||
'2': 'two',
|
|
||||||
'3': 'three',
|
|
||||||
'4': 'four',
|
|
||||||
'5': 'five',
|
|
||||||
'6': 'six',
|
|
||||||
'7': 'seven',
|
|
||||||
'8': 'eight',
|
|
||||||
'9': 'nine',
|
|
||||||
'A': 'alfa',
|
|
||||||
'B': 'bravo',
|
|
||||||
'C': 'charlie',
|
|
||||||
'D': 'delta',
|
|
||||||
'E': 'echo',
|
|
||||||
'F': 'foxtrot',
|
|
||||||
'G': 'golf',
|
|
||||||
'H': 'hotel',
|
|
||||||
'I': 'india',
|
|
||||||
'J': 'juliet',
|
|
||||||
'K': 'kilo',
|
|
||||||
'L': 'lima',
|
|
||||||
'M': 'mike',
|
|
||||||
'N': 'november',
|
|
||||||
'O': 'oscar',
|
|
||||||
'P': 'papa',
|
|
||||||
'Q': 'quebec',
|
|
||||||
'R': 'romeo',
|
|
||||||
'S': 'sierra',
|
|
||||||
'T': 'tango',
|
|
||||||
'U': 'uniform',
|
|
||||||
'V': 'victor',
|
|
||||||
'W': 'whiskey',
|
|
||||||
'X': 'x-ray',
|
|
||||||
'Y': 'yankee',
|
|
||||||
'Z': 'zulu',
|
|
||||||
'to': 'silence',
|
|
||||||
'notlinked': 'not-linked',
|
|
||||||
'linkedto': 'linked-to'
|
|
||||||
},
|
|
||||||
|
|
||||||
'fr_FR': {
|
|
||||||
'A': 'alpha',
|
|
||||||
'B': 'bravo',
|
|
||||||
'C': 'charlie',
|
|
||||||
'D': 'delta',
|
|
||||||
'E': 'echo',
|
|
||||||
'F': 'foxtrot',
|
|
||||||
'G': 'golf',
|
|
||||||
'H': 'hotel',
|
|
||||||
'I': 'india',
|
|
||||||
'J': 'juliet',
|
|
||||||
'K': 'kilo',
|
|
||||||
'L': 'lima',
|
|
||||||
'M': 'mike',
|
|
||||||
'N': 'november',
|
|
||||||
'O': 'oscar',
|
|
||||||
'P': 'papa',
|
|
||||||
'Q': 'quebec',
|
|
||||||
'R': 'romeo',
|
|
||||||
'S': 'sierra',
|
|
||||||
'T': 'tango',
|
|
||||||
'U': 'uniform',
|
|
||||||
'V': 'victor',
|
|
||||||
'W': 'whiskey',
|
|
||||||
'X': 'x-ray',
|
|
||||||
'Y': 'yankee',
|
|
||||||
'Z': 'zulu',
|
|
||||||
'to': 'silence',
|
|
||||||
'notlinked': 'not-linked',
|
|
||||||
'linkedto': 'linked-to'
|
|
||||||
},
|
|
||||||
|
|
||||||
'pt_PT': {
|
|
||||||
'A': 'alpha',
|
|
||||||
'B': 'bravo',
|
|
||||||
'C': 'charlie',
|
|
||||||
'D': 'delta',
|
|
||||||
'E': 'echo',
|
|
||||||
'F': 'foxtrot',
|
|
||||||
'G': 'golf',
|
|
||||||
'H': 'hotel',
|
|
||||||
'I': 'india',
|
|
||||||
'J': 'juliet',
|
|
||||||
'K': 'kilo',
|
|
||||||
'L': 'lima',
|
|
||||||
'M': 'mike',
|
|
||||||
'N': 'november',
|
|
||||||
'O': 'oscar',
|
|
||||||
'P': 'papa',
|
|
||||||
'Q': 'quebec',
|
|
||||||
'R': 'romeo',
|
|
||||||
'S': 'sierra',
|
|
||||||
'T': 'tango',
|
|
||||||
'U': 'uniform',
|
|
||||||
'V': 'victor',
|
|
||||||
'W': 'whiskey',
|
|
||||||
'X': 'x-ray',
|
|
||||||
'Y': 'yankee',
|
|
||||||
'Z': 'zulu',
|
|
||||||
'to': 'silence',
|
|
||||||
'notlinked': 'not-linked',
|
|
||||||
'linkedto': 'linked-to'
|
|
||||||
},
|
|
||||||
|
|
||||||
'el_GR': {
|
|
||||||
'A': 'alpha',
|
|
||||||
'B': 'bravo',
|
|
||||||
'C': 'charlie',
|
|
||||||
'D': 'delta',
|
|
||||||
'E': 'echo',
|
|
||||||
'F': 'foxtrot',
|
|
||||||
'G': 'golf',
|
|
||||||
'H': 'hotel',
|
|
||||||
'I': 'india',
|
|
||||||
'J': 'juliet',
|
|
||||||
'K': 'kilo',
|
|
||||||
'L': 'lima',
|
|
||||||
'M': 'mike',
|
|
||||||
'N': 'november',
|
|
||||||
'O': 'oscar',
|
|
||||||
'P': 'papa',
|
|
||||||
'Q': 'quebec',
|
|
||||||
'R': 'romeo',
|
|
||||||
'S': 'sierra',
|
|
||||||
'T': 'tango',
|
|
||||||
'U': 'uniform',
|
|
||||||
'V': 'victor',
|
|
||||||
'W': 'whiskey',
|
|
||||||
'X': 'x-ray',
|
|
||||||
'Y': 'yankee',
|
|
||||||
'Z': 'zulu',
|
|
||||||
'to': 'silence',
|
|
||||||
'notlinked': 'not-linked',
|
|
||||||
'linkedto': 'linked-to'
|
|
||||||
},
|
|
||||||
|
|
||||||
'de_DE': {
|
|
||||||
|
|
||||||
'to': 'silence',
|
|
||||||
},
|
|
||||||
|
|
||||||
'dk_DK': {
|
|
||||||
'to': 'silence',
|
|
||||||
'freedmr': 'silence',
|
|
||||||
'this-is': 'silence'
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
'it_IT': {
|
|
||||||
'to': 'silence',
|
|
||||||
'freedmr': 'silence',
|
|
||||||
'this-is': 'silence'
|
|
||||||
},
|
|
||||||
|
|
||||||
'no_NO': {
|
|
||||||
'to': 'silence',
|
|
||||||
'freedmr': 'silence',
|
|
||||||
'this-is': 'silence'
|
|
||||||
},
|
|
||||||
|
|
||||||
'pl_PL': {
|
|
||||||
'to': 'silence',
|
|
||||||
'freedmr': 'silence',
|
|
||||||
'this-is': 'silence'
|
|
||||||
},
|
|
||||||
|
|
||||||
'se_SE': {
|
|
||||||
'to': 'silence',
|
|
||||||
'freedmr': 'silence',
|
|
||||||
'this-is': 'silence'
|
|
||||||
},
|
|
||||||
|
|
||||||
'CW': {
|
|
||||||
'to': 'silence',
|
|
||||||
'freedmr': 'silence',
|
|
||||||
'this-is': 'silence',
|
|
||||||
'linkedto': 'silence'
|
|
||||||
},
|
|
||||||
|
|
||||||
'th_TH': {
|
|
||||||
|
|
||||||
'to': 'silence',
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,107 +0,0 @@
|
|||||||
import mysql.connector
|
|
||||||
from mysql.connector import errorcode
|
|
||||||
#import mysql.connector.pooling
|
|
||||||
|
|
||||||
# Does anybody read this stuff? There's a PEP somewhere that says I should do this.
|
|
||||||
__author__ = 'Simon Adlem - G7RZU'
|
|
||||||
__copyright__ = 'Copyright (c) Simon Adlem, G7RZU 2020,2021'
|
|
||||||
__credits__ = 'Colin Durbridge, G4EML, Steve Zingman, N4IRS; Mike Zingman, N4IRR; Jonathan Naylor, G4KLX; Hans Barthen, DL5DI; Torsten Shultze, DG1HT; Jon Lee, G4TSN; Norman Williams, M6NBP'
|
|
||||||
__license__ = 'GNU GPLv3'
|
|
||||||
__maintainer__ = 'Simon Adlem G7RZU'
|
|
||||||
__email__ = 'simon@gb7fr.org.uk'
|
|
||||||
|
|
||||||
|
|
||||||
class useMYSQL:
|
|
||||||
#Init new object
|
|
||||||
def __init__(self, server,user,password,database,table,logger):
|
|
||||||
self.server = server
|
|
||||||
self.user = user
|
|
||||||
self.password = password
|
|
||||||
self.database = database
|
|
||||||
self.table = table
|
|
||||||
self.logger = logger
|
|
||||||
|
|
||||||
#Connect
|
|
||||||
def con(self):
|
|
||||||
logger = self.logger
|
|
||||||
try:
|
|
||||||
self.db = mysql.connector.connect(
|
|
||||||
host=self.server,
|
|
||||||
user=self.user,
|
|
||||||
password=self.password,
|
|
||||||
database=self.database,
|
|
||||||
# pool_name = "hblink_master",
|
|
||||||
# pool_size = 2
|
|
||||||
)
|
|
||||||
except mysql.connector.Error as err:
|
|
||||||
if err.errno == errorcode.ER_ACCESS_DENIED_ERROR:
|
|
||||||
logger.info('(MYSQL) username or password error')
|
|
||||||
return (False)
|
|
||||||
elif err.errno == errorcode.ER_BAD_DB_ERROR:
|
|
||||||
logger.info('(MYSQL) DB Error')
|
|
||||||
return (False)
|
|
||||||
else:
|
|
||||||
logger.info('(MYSQL) error: %s',err)
|
|
||||||
return(False)
|
|
||||||
|
|
||||||
return(True)
|
|
||||||
|
|
||||||
#Close DB connection
|
|
||||||
def close(self):
|
|
||||||
self.db.close()
|
|
||||||
|
|
||||||
#Get config from DB
|
|
||||||
def getConfig(self):
|
|
||||||
|
|
||||||
CONFIG = {}
|
|
||||||
CONFIG['SYSTEMS'] = {}
|
|
||||||
|
|
||||||
_cursor = self.db.cursor()
|
|
||||||
|
|
||||||
try:
|
|
||||||
_cursor.execute("select * from {} where MODE='MASTER'".format(self.table))
|
|
||||||
except mysql.connector.Error as err:
|
|
||||||
_cursor.close()
|
|
||||||
logger.info('(MYSQL) error, problem with cursor execute')
|
|
||||||
raise Exception('Problem with cursor execute')
|
|
||||||
|
|
||||||
for (callsign, mode, enabled, _repeat, max_peers, export_ambe, ip, port, passphrase, group_hangtime, use_acl, reg_acl, sub_acl, tgid_ts1_acl, tgid_ts2_acl, default_ua_timer, single_mode, voice_ident,ts1_static,ts2_static,default_reflector, announce_lang) in _cursor:
|
|
||||||
try:
|
|
||||||
CONFIG['SYSTEMS'].update({callsign: {
|
|
||||||
'MODE': mode,
|
|
||||||
'ENABLED': bool(enabled),
|
|
||||||
'REPEAT': bool(_repeat),
|
|
||||||
'MAX_PEERS': int(max_peers),
|
|
||||||
'IP': ip,
|
|
||||||
'PORT': int(port),
|
|
||||||
'PASSPHRASE': bytes(passphrase, 'utf-8'),
|
|
||||||
'GROUP_HANGTIME': int(group_hangtime),
|
|
||||||
'USE_ACL': bool(use_acl),
|
|
||||||
'REG_ACL': reg_acl,
|
|
||||||
'SUB_ACL': sub_acl,
|
|
||||||
'TG1_ACL': tgid_ts1_acl,
|
|
||||||
'TG2_ACL': tgid_ts2_acl,
|
|
||||||
'DEFAULT_UA_TIMER': int(default_ua_timer),
|
|
||||||
'SINGLE_MODE': bool(single_mode),
|
|
||||||
'VOICE_IDENT': bool(voice_ident),
|
|
||||||
'TS1_STATIC': ts1_static,
|
|
||||||
'TS2_STATIC': ts2_static,
|
|
||||||
'DEFAULT_REFLECTOR': int(default_reflector),
|
|
||||||
'GENERATOR': int(1),
|
|
||||||
'ANNOUNCEMENT_LANGUAGE': announce_lang
|
|
||||||
}})
|
|
||||||
CONFIG['SYSTEMS'][callsign].update({'PEERS': {}})
|
|
||||||
except TypeError:
|
|
||||||
logger.info('(MYSQL) Problem with data from MySQL - TypeError, carrying on to next row')
|
|
||||||
|
|
||||||
return(CONFIG['SYSTEMS'])
|
|
||||||
|
|
||||||
|
|
||||||
#For testing
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
|
||||||
sql = useMYSQL("ip","user","pass","db")
|
|
||||||
|
|
||||||
sql.con()
|
|
||||||
|
|
||||||
print( sql.getConfig())
|
|
||||||
@ -1,175 +0,0 @@
|
|||||||
###############################################################################
|
|
||||||
# Copyright (C) 2020 Simon Adlem, G7RZU <g7rzu@gb7fr.org.uk>
|
|
||||||
#
|
|
||||||
# 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 bitarray import bitarray
|
|
||||||
from itertools import islice
|
|
||||||
import os
|
|
||||||
import glob
|
|
||||||
|
|
||||||
class readAMBE:
|
|
||||||
|
|
||||||
def __init__(self, lang,path):
|
|
||||||
self.langcsv = lang
|
|
||||||
self.langs = lang.split(',')
|
|
||||||
self.path = path
|
|
||||||
|
|
||||||
def _make_bursts(self,data):
|
|
||||||
it = iter(data)
|
|
||||||
for i in range(0, len(data), 108):
|
|
||||||
yield bitarray([k for k in islice(it, 108)] )
|
|
||||||
|
|
||||||
#Read indexed files
|
|
||||||
def readfiles(self):
|
|
||||||
|
|
||||||
_AMBE_LENGTH = 9
|
|
||||||
|
|
||||||
_wordBADictofDicts = {}
|
|
||||||
|
|
||||||
for _lang in self.langs:
|
|
||||||
|
|
||||||
_prefix = self.path+_lang
|
|
||||||
_wordBADict = {}
|
|
||||||
|
|
||||||
indexDict = {}
|
|
||||||
|
|
||||||
if os.path.isdir(_prefix):
|
|
||||||
ambeBytearray = {}
|
|
||||||
_wordBitarray = bitarray(endian='big')
|
|
||||||
_wordBADict = {}
|
|
||||||
_glob = _prefix + "/*.ambe"
|
|
||||||
for ambe in glob.glob(_glob):
|
|
||||||
basename = os.path.basename(ambe)
|
|
||||||
_voice,ext = basename.split('.')
|
|
||||||
inambe = open(ambe,'rb')
|
|
||||||
_wordBitarray.frombytes(inambe.read())
|
|
||||||
inambe.close()
|
|
||||||
_wordBADict[_voice] = []
|
|
||||||
pairs = 1
|
|
||||||
_lastburst = ''
|
|
||||||
for _burst in self._make_bursts(_wordBitarray):
|
|
||||||
#Not sure if we need to pad or not? Seems to make little difference.
|
|
||||||
if len(_burst) < 108:
|
|
||||||
pad = (108 - len(_burst))
|
|
||||||
for i in range(0,pad,1):
|
|
||||||
_burst.append(False)
|
|
||||||
if pairs == 2:
|
|
||||||
_wordBADict[_voice].append([_lastburst,_burst])
|
|
||||||
_lastburst = ''
|
|
||||||
pairs = 1
|
|
||||||
next
|
|
||||||
else:
|
|
||||||
pairs = pairs + 1
|
|
||||||
_lastburst = _burst
|
|
||||||
|
|
||||||
_wordBitarray.clear()
|
|
||||||
_wordBADict['silence'] = ([
|
|
||||||
[bitarray('101011000000101010100000010000000000001000000000000000000000010001000000010000000000100000000000100000000000'),
|
|
||||||
bitarray('001010110000001010101000000100000000000010000000000000000000000100010000000100000000001000000000001000000000')]
|
|
||||||
])
|
|
||||||
_wordBADictofDicts[_lang] = _wordBADict
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
with open(_prefix+'.indx') as index:
|
|
||||||
for line in index:
|
|
||||||
(voice,start,length) = line.split()
|
|
||||||
indexDict[voice] = [int(start) * _AMBE_LENGTH ,int(length) * _AMBE_LENGTH]
|
|
||||||
index.close()
|
|
||||||
except IOError:
|
|
||||||
return False
|
|
||||||
|
|
||||||
ambeBytearray = {}
|
|
||||||
_wordBitarray = bitarray(endian='big')
|
|
||||||
_wordBADict = {}
|
|
||||||
try:
|
|
||||||
with open(_prefix+'.ambe','rb') as ambe:
|
|
||||||
for _voice in indexDict:
|
|
||||||
ambe.seek(indexDict[_voice][0])
|
|
||||||
_wordBitarray.frombytes(ambe.read(indexDict[_voice][1]))
|
|
||||||
#108
|
|
||||||
_wordBADict[_voice] = []
|
|
||||||
pairs = 1
|
|
||||||
_lastburst = ''
|
|
||||||
for _burst in self._make_bursts(_wordBitarray):
|
|
||||||
#Not sure if we need to pad or not? Seems to make little difference.
|
|
||||||
if len(_burst) < 108:
|
|
||||||
pad = (108 - len(_burst))
|
|
||||||
for i in range(0,pad,1):
|
|
||||||
_burst.append(False)
|
|
||||||
if pairs == 2:
|
|
||||||
_wordBADict[_voice].append([_lastburst,_burst])
|
|
||||||
_lastburst = ''
|
|
||||||
pairs = 1
|
|
||||||
next
|
|
||||||
else:
|
|
||||||
pairs = pairs + 1
|
|
||||||
_lastburst = _burst
|
|
||||||
|
|
||||||
_wordBitarray.clear()
|
|
||||||
ambe.close()
|
|
||||||
except IOError:
|
|
||||||
return False
|
|
||||||
_wordBADict['silence'] = ([
|
|
||||||
[bitarray('101011000000101010100000010000000000001000000000000000000000010001000000010000000000100000000000100000000000'),
|
|
||||||
bitarray('001010110000001010101000000100000000000010000000000000000000000100010000000100000000001000000000001000000000')]
|
|
||||||
])
|
|
||||||
_wordBADictofDicts[_lang] = _wordBADict
|
|
||||||
|
|
||||||
return _wordBADictofDicts
|
|
||||||
|
|
||||||
#Read a single ambe file from the audio directory
|
|
||||||
def readSingleFile(self,filename):
|
|
||||||
ambeBytearray = {}
|
|
||||||
_wordBitarray = bitarray(endian='big')
|
|
||||||
_wordBA= []
|
|
||||||
try:
|
|
||||||
with open(self.path+filename,'rb') as ambe:
|
|
||||||
_wordBitarray.frombytes(ambe.read())
|
|
||||||
#108
|
|
||||||
_wordBA = []
|
|
||||||
pairs = 1
|
|
||||||
_lastburst = ''
|
|
||||||
for _burst in self._make_bursts(_wordBitarray):
|
|
||||||
#Not sure if we need to pad or not? Seems to make little difference.
|
|
||||||
if len(_burst) < 108:
|
|
||||||
pad = (108 - len(_burst))
|
|
||||||
for i in range(0,pad,1):
|
|
||||||
_burst.append(False)
|
|
||||||
if pairs == 2:
|
|
||||||
_wordBA.append([_lastburst,_burst])
|
|
||||||
_lastburst = ''
|
|
||||||
pairs = 1
|
|
||||||
next
|
|
||||||
else:
|
|
||||||
pairs = pairs + 1
|
|
||||||
_lastburst = _burst
|
|
||||||
|
|
||||||
_wordBitarray.clear()
|
|
||||||
ambe.close()
|
|
||||||
except IOError:
|
|
||||||
raise
|
|
||||||
|
|
||||||
return(_wordBA)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
|
||||||
#test = readAMBE('en_GB','./Audio/')
|
|
||||||
|
|
||||||
#print(test.readfiles())
|
|
||||||
test = readAMBE('en_GB_2','./Audio/')
|
|
||||||
print(test.readfiles())
|
|
||||||
print(test.readSingleFile('44xx.ambe'))
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
###############################################################################
|
|
||||||
# Copyright (C) 2018 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
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
# Opcodes for the network-based reporting protocol
|
|
||||||
|
|
||||||
REPORT_OPCODES = {
|
|
||||||
'CONFIG_REQ': b'\x00',
|
|
||||||
'CONFIG_SND': b'\x01',
|
|
||||||
'BRIDGE_REQ': b'\x02',
|
|
||||||
'BRIDGE_SND': b'\x03',
|
|
||||||
'CONFIG_UPD': b'\x04',
|
|
||||||
'BRIDGE_UPD': b'\x05',
|
|
||||||
'LINK_EVENT': b'\x06',
|
|
||||||
'BRDG_EVENT': b'\x07',
|
|
||||||
}
|
|
||||||
Loading…
Reference in new issue