diff options
Diffstat (limited to 'scripts/create-mcc-mnc-table.py')
-rw-r--r-- | scripts/create-mcc-mnc-table.py | 309 |
1 files changed, 210 insertions, 99 deletions
diff --git a/scripts/create-mcc-mnc-table.py b/scripts/create-mcc-mnc-table.py index a5af7c4..1f26fe4 100644 --- a/scripts/create-mcc-mnc-table.py +++ b/scripts/create-mcc-mnc-table.py @@ -1,114 +1,225 @@ #!/usr/bin/env python3 -#Generates MTS_IO_MccMncTable.cpp file by pulling latest MCC/MNC values -#from http://mcc-mnc.com +""" +Generates MTS_IO_MccMncTable.cpp file by pulling latest MCC/MNC values +from http://mcc-mnc.com or the csv file. -#Original Source Idea: https://github.com/musalbas/mcc-mnc-table +Original Source Idea: https://github.com/musalbas/mcc-mnc-table +""" +######################################################################################################################## import re import urllib.request import urllib.parse import datetime -print("/*!") -print(" \\file MTS_IO_MccMncTable.cpp") -print(" \\brief Auto-Generated MCC-MNC Lookup Table") -print(" \\date " + str(datetime.date.today())) -print(" \\author sgodinez") -print("") -print(" An Auto-Generated MCC-MNC Lookup Table") -print("*/") -print("") -print("#include <mts/MTS_IO_MccMncTable.h>") -print("#include <mts/MTS_Logger.h>") -print("#include <mts/MTS_Text.h>") -print("") -print("using namespace MTS::IO;") -print("") -print("MTS::AutoPtr<MTS::Lock> MccMncTable::m_apLock(new MTS::Lock());") -print("MccMncTable* MccMncTable::m_pInstance = NULL;") -print("") -print("MccMncTable* MccMncTable::getInstance() {") -print(" if(m_pInstance == NULL) {") -print(" m_apLock->lock();") -print(" if (m_pInstance == NULL) {") -print(" m_pInstance = new MccMncTable();") -print(" }") -print(" m_apLock->unlock();") -print(" }") -print(" return m_pInstance;") -print("}") -print("") -print("MccMncTable::MccMncTable() {") -print(" createTable();") -print("}") -print("") -print("Json::Value MccMncTable::lookup(const std::string& sMcc, const std::string& sMnc) {") -print(" uint32_t iMcc, iMnc;") -print(" std::string sNormalizedMnc = sMnc;") -print(' printTrace("[MCCMNC] MCCx[%s] MNCx[%s]", sMcc.c_str(), sMnc.c_str());') -print(" if (sMnc.length() == 2) {") -print(" sNormalizedMnc += 'f';") -print(" }") -print(" if (!MTS::Text::parseHex(iMcc, sMcc)) { return Json::Value::null; }") -print(" if (!MTS::Text::parseHex(iMnc, sNormalizedMnc)) { return Json::Value::null; }") -print(' printTrace("[MCCMNC] MCC0X[%d] MNC0X[%d]", iMcc, iMnc);') -print(" if (m_mTable.count(iMcc)) {") -print(" if(m_mTable[iMcc].count(iMnc)) {") -print(" std::vector<std::string> vJson = MTS::Text::split(m_mTable[iMcc][iMnc], ',');") -print(" Json::Value j;") -print(' j["iso"] = vJson[0];') -print(' j["country"] = vJson[1];') -print(' j["code"] = vJson[2];') -print(' j["carrier"] = vJson[3];') -print(" return j;") -print(" }") -print(" }") -print("") -print(" return Json::Value::null;") -print("}") -print("") -print("void MccMncTable::createTable() {") -print(" std::string sData;") - -td_re = re.compile('<td>([^<]*)</td>'*6) - -html_bytes = urllib.request.urlopen('http://mcc-mnc.com/').read() # type: bytes -html = html_bytes.decode(encoding='utf-8') - -tbody_start = False -for line in html.split('\n'): - if '<tbody>' in line: - tbody_start = True - elif '</tbody>' in line: - break - elif tbody_start: - td_search = td_re.search(line) - mcc = td_search.group(1).strip().replace(',','') - mnc = td_search.group(2).strip().replace(',','') - iso = td_search.group(3).strip().replace(',','') - countryCode = td_search.group(4).strip().replace(',','') - country = td_search.group(5).strip().replace(',','') - carrier = td_search.group(6).strip().replace(',','') - - if mnc != "n/a": - mcc_int = int(mcc, 16) - if len(mnc) == 2: - mnc_int = int(mnc + 'f', 16) - else: - mnc_int = int(mnc, 16) - print(' m_mTable[' + str(mcc_int) + '][' + str(mnc_int) + '] = "' + \ - iso + ',' + countryCode + ',' + country + ',' + carrier + '";') - else: - print(" //MCC(" + mcc + ') MNC(N/A) ISO(' + iso + ') Country Code(' + countryCode + ') Country(' + country + ') Carrier(' + carrier + ')') - - - -print("}") -print("") +from typing import Iterable, Generator +from collections import namedtuple + +######################################################################################################################## + +PREAMBLE_TEMPLATE = """\ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts-io. + * + * libmts-io is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * libmts-io 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libmts-io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \\file MTS_IO_MccMncTable.cpp + \\brief Auto-Generated MCC-MNC Lookup Table + \\date {today} + \\author sgodinez + + An Auto-Generated MCC-MNC Lookup Table +*/ +""" + +GENERAL_CODE = """\ +#include <mts/MTS_IO_MccMncTable.h> +#include <mts/MTS_Logger.h> +#include <mts/MTS_Text.h> + +using namespace MTS::IO; + +MTS::AutoPtr<MTS::Lock> MccMncTable::m_apLock(new MTS::Lock()); +MccMncTable* MccMncTable::m_pInstance = NULL; + +MccMncTable* MccMncTable::getInstance() { + if(m_pInstance == NULL) { + m_apLock->lock(); + if (m_pInstance == NULL) { + m_pInstance = new MccMncTable(); + } + m_apLock->unlock(); + } + return m_pInstance; +} + +MccMncTable::MccMncTable() { + createTable(); +} + +Json::Value MccMncTable::lookup(const std::string& sMcc, const std::string& sMnc) { + uint32_t iMcc, iMnc; + std::string sNormalizedMnc = sMnc; + printTrace("[MCCMNC] MCCx[%s] MNCx[%s]", sMcc.c_str(), sMnc.c_str()); + if (sMnc.length() == 2) { + sNormalizedMnc += 'f'; + } + if (!MTS::Text::parseHex(iMcc, sMcc)) { return Json::Value::null; } + if (!MTS::Text::parseHex(iMnc, sNormalizedMnc)) { return Json::Value::null; } + printTrace("[MCCMNC] MCC0X[%d] MNC0X[%d]", iMcc, iMnc); + if (m_mTable.count(iMcc)) { + if(m_mTable[iMcc].count(iMnc)) { + std::vector<std::string> vJson = MTS::Text::split(m_mTable[iMcc][iMnc], ','); + Json::Value j; + j["iso"] = vJson[0]; + j["country"] = vJson[1]; + j["code"] = vJson[2]; + j["carrier"] = vJson[3]; + return j; + } + } + + return Json::Value::null; +} +""" + +######################################################################################################################## + +MccMncElement = namedtuple( + 'MccMncData', + field_names=('mcc', 'mcc_int', 'mnc', 'mnc_int', 'iso', 'country', 'country_code', 'network') +) + + +######################################################################################################################## + + +def print_cpp_preamble() -> None: + print(PREAMBLE_TEMPLATE.format(today=datetime.date.today())) + + +def print_cpp_general_code() -> None: + print(GENERAL_CODE) + + +def format_mcc_mnc_line(el: MccMncElement) -> str: + if el.mnc.upper() != "N/A": + return ' m_mTable[{mcc_int}][{mnc_int}] = "{iso},{country},{country_code},{network}";'.format( + mcc_int=el.mcc_int, + mnc_int=el.mnc_int, + iso=el.iso, + country=el.country, + country_code=el.country_code, + network=el.network + ) + else: + # TODO: The Country and Country Code values were swapped in the original implementation due to a bug. + # Left as is for compatibility reasons. + return ' //MCC({mcc}) MNC(N/A) ISO({iso}) Country Code({country}) Country({country_code}) Carrier({network})'.format( + mcc=el.mcc, + iso=el.iso, + country=el.country, + country_code=el.country_code, + network=el.network + ) + + +def print_cpp_mcc_mnc_table(data: Iterable[MccMncElement]) -> None: + print("void MccMncTable::createTable() {") + print(" std::string sData;") + + for el in data: + print(format_mcc_mnc_line(el)) + + print("}") + print("") + + +def mcc_to_mcc_int(src: str) -> str: + if src.upper() == "N/A": + return src + + hash_ = int(src, 16) + return "{:d}".format(hash_) + + +def mnc_to_mnc_int(src: str) -> str: + if src.upper() == "N/A": + return src + + src_norm = src + if len(src) == 2: + src_norm += 'f' + + hash_ = int(src_norm, 16) + return "{:d}".format(hash_) + + +def mcc_mnc_from_website(url: str) -> Generator[MccMncElement, None, None]: + td_re = re.compile('<td>([^<]*)</td>' * 6) + html_bytes = urllib.request.urlopen(url).read() # type: bytes + html = html_bytes.decode(encoding='utf-8') + + tbody_start = False + + for line in html.split('\n'): + if '<tbody>' in line: + tbody_start = True + elif '</tbody>' in line: + break + elif tbody_start: + td_search = td_re.search(line) + mcc = td_search.group(1).strip().replace(',', '') + mnc = td_search.group(2).strip().replace(',', '') + iso = td_search.group(3).strip().replace(',', '') + country = td_search.group(4).strip().replace(',', '') + country_code = td_search.group(5).strip().replace(',', '') + carrier = td_search.group(6).strip().replace(',', '') + mcc_int = mcc_to_mcc_int(mcc) + mnc_int = mnc_to_mnc_int(mnc) + yield MccMncElement( + mcc=mcc, + mcc_int=mcc_int, + mnc=mnc, + mnc_int=mnc_int, + iso=iso, + country=country, + country_code=country_code, + network=carrier + ) +######################################################################################################################## +def main(): + print_cpp_preamble() + print_cpp_general_code() + print_cpp_mcc_mnc_table( + mcc_mnc_from_website('http://mcc-mnc.com/') + ) + + +######################################################################################################################## + +if __name__ == "__main__": + main() |