aboutsummaryrefslogtreecommitdiff
path: root/src/ppm/providerdb.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/ppm/providerdb.py')
-rw-r--r--src/ppm/providerdb.py140
1 files changed, 140 insertions, 0 deletions
diff --git a/src/ppm/providerdb.py b/src/ppm/providerdb.py
new file mode 100644
index 0000000..a1bc394
--- /dev/null
+++ b/src/ppm/providerdb.py
@@ -0,0 +1,140 @@
+# vim: set fileencoding=utf-8 :
+#
+# (C) 2010 Guido Guenther <agx@sigxcpu.org>
+# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import os
+import logging
+from lxml import etree
+
+from provider import Provider
+
+class ProviderDB(object):
+ """Proxy to mobile broadband provider database"""
+
+ provider_info = os.getenv('PPM_PROVIDER_DB',
+ '/usr/share/mobile-broadband-provider-info/'
+ 'serviceproviders.xml')
+ country_codes = '/usr/share/zoneinfo/iso3166.tab'
+
+ def __init__(self):
+ self.__tree = None
+ self.__countries = {}
+
+ @property
+ def tree(self):
+ if self.__tree:
+ return self.__tree
+ else:
+ self.__tree = etree.parse(self.provider_info)
+ return self.__tree
+
+ @property
+ def countries(self):
+ if self.__countries:
+ return self.__countries
+ else:
+ self._tree = self._load_countries()
+ return self.__countries
+
+ def _load_countries(self):
+ try:
+ for line in file(self.country_codes, 'r'):
+ if line[0] != '#':
+ (code, country) = line.split('\t',2)
+ self.__countries[code.lower()] = country.strip()
+ except IOError as msg:
+ logging.warning("Loading country code database failed: %s" % msg)
+
+ def _fill_provider_info(self, provider_elem):
+ """Fill a provider object with data from the XML"""
+ name = provider_elem.xpath("./name")[0].text
+ country = provider_elem.getparent().attrib['code']
+ gsm_elem = provider_elem.xpath("./gsm")
+ provider = Provider(country = country,
+ name = name)
+ if gsm_elem:
+ self._fill_balance_check_cmd(gsm_elem[0], provider)
+ self._fill_top_up_cmd(gsm_elem[0], provider)
+ return provider
+
+ def _fill_balance_check_cmd(self, xmlelemnt, provider):
+ """Fetch balance check method from XML and add it to the provider"""
+ for child in xmlelemnt.iter(tag='balance-check'):
+ check_types = child.getchildren()
+ for t in check_types:
+ if t.tag == 'ussd':
+ sequence = t.text
+ provider.add_fetch_balance_cmd({'ussd': sequence})
+ if t.tag == 'sms':
+ number = t.text
+ text = t.attrib['text']
+ provider.add_fetch_balance_cmd({'sms': (number, text)})
+
+ def _fill_top_up_cmd(self, xmlelement, provider):
+ for child in xmlelement.iter(tag='balance-top-up'):
+ check_types = child.getchildren()
+ for t in check_types:
+ if t.tag == 'ussd':
+ sequence = t.text
+ replacement = t.attrib['replacement']
+ provider.add_top_up_cmd({'ussd': [sequence, replacement]})
+ if t.tag == 'sms':
+ number = t.text
+ text = t.attrib['text']
+ provicer.add_top_up_cmd({'sms': (number, text)})
+
+ def get_providers(self, mcc, mnc):
+ """
+ Get possible providers for the current mcc and mnc from the database
+ """
+ path = "//network-id[@mcc='%s' and @mnc='%s']" % (mcc, mnc)
+ searcher = etree.ETXPath(path)
+ providers = []
+
+ for r in searcher(self.tree):
+ provider_elem = r.getparent().getparent()
+ providers.append(self._fill_provider_info(provider_elem))
+ return providers
+
+ def get_provider(self, country_code, name):
+ path = "//country[@code='%s']/provider[name='%s']" % (country_code, name)
+ searcher = etree.ETXPath(path)
+
+ for r in searcher(self.tree):
+ return self._fill_provider_info(r)
+ return None
+
+ def get_country_codes(self):
+ path = "/serviceproviders/country"
+ searcher = etree.ETXPath(path)
+
+ for r in searcher(self.tree):
+ yield r.attrib['code']
+
+ def get_countries(self):
+ for code in self.get_country_codes():
+ try:
+ yield (self.countries[code], code)
+ except KeyError:
+ yield (None, code)
+
+ def get_providers_by_code(self, country_code):
+ path = ("/serviceproviders/country[@code='%s']/provider/name" %
+ country_code)
+ searcher = etree.ETXPath(path)
+
+ for r in searcher(self.tree):
+ yield r.text