Ticket #1630: gsm-provider-db-v2-1630.patch

File gsm-provider-db-v2-1630.patch, 8.6 KB (added by aa, 9 years ago)
  • extensions/cpsection/modemconfiguration/model.py

    old new  
    1515# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  US
    1616
    1717import gconf
     18import gtk
     19import os
     20import locale
     21from xml.etree.cElementTree import ElementTree
     22from gettext import gettext as _
    1823
    1924from jarabe.model.network import GSM_USERNAME_PATH, GSM_PASSWORD_PATH, \
    2025                                 GSM_NUMBER_PATH, GSM_APN_PATH
    2126
     27PROVIDERS_PATH = '/usr/share/mobile-broadband-provider-info/serviceproviders.xml'
     28PROVIDERS_FORMAT_SUPPORTED = '2.0'
     29COUNTRY_CODES_PATH = '/usr/share/zoneinfo/iso3166.tab'
     30
    2231def get_username():
    2332    client = gconf.client_get_default()
    2433    return client.get_string(GSM_USERNAME_PATH) or ''
     
    5160    client = gconf.client_get_default()
    5261    client.set_string(GSM_APN_PATH, apn)
    5362
     63def has_providers_db():
     64    if not os.path.isfile(COUNTRY_CODES_PATH):
     65        return False
     66    try:
     67        et = ElementTree(file=PROVIDERS_PATH)
     68        elem = et.getroot()
     69        if elem is None or elem.get('format') != PROVIDERS_FORMAT_SUPPORTED:
     70            return False
     71        return True
     72    except IOError:
     73        return False
     74
     75class CountryListStore(gtk.ListStore):
     76    COUNTRY_CODE = os.environ['LANG'][3:5].lower()
     77
     78    def __init__(self):
     79        gtk.ListStore.__init__(self, str, object)
     80        codes = {}
     81        with open(COUNTRY_CODES_PATH) as f:
     82            for line in f:
     83                if line.startswith('#'):
     84                    continue
     85                code, name = line.split('\t')[:2]
     86                codes[code.lower()] = name.strip()
     87        etree = ElementTree(file=PROVIDERS_PATH).getroot()
     88        self._country_idx = None
     89        i = 0
     90        for elem in etree.findall('.//country'):
     91            code = elem.attrib['code']
     92            if code == self.COUNTRY_CODE:
     93                self._country_idx = i
     94            else:
     95                i += 1
     96            if code in codes:
     97                self.append((codes[code], elem))
     98            else:
     99                self.append((code, elem))
     100
     101    def get_row_providers(self, n):
     102        return self[n][1]
     103
     104    def guess_country_row(self):
     105        if self._country_idx is not None:
     106            return self._country_idx
     107        else:
     108            return -1
     109
     110class ProviderListStore(gtk.ListStore):
     111    def __init__(self, elem):
     112        gtk.ListStore.__init__(self, str, object)
     113        for provider_elem in elem.findall('.//provider'):
     114            apns = provider_elem.findall('.//apn')
     115            if not apns:
     116                # Skip carriers with CDMA entries only
     117                continue
     118            self.append((provider_elem.find('.//name').text, apns))
     119
     120    def get_row_plans(self, n):
     121        return self[n][1]
     122
     123class PlanListStore(gtk.ListStore):
     124    LANG_NS_ATTR = '{http://www.w3.org/XML/1998/namespace}lang'
     125    LANG = locale.getdefaultlocale()[0][:2]
     126    DEFAULT_NUMBER = '*99#'
     127
     128    def __init__(self, elems):
     129        gtk.ListStore.__init__(self, str, object)
     130        for apn_elem in elems:
     131            plan = {}
     132            names = apn_elem.findall('.//name')
     133            if names:
     134                for name in names:
     135                    if name.get(self.LANG_NS_ATTR) is None:
     136                        # serviceproviders.xml default value
     137                        plan['name'] = name.text
     138                    elif name.get(self.LANG_NS_ATTR) == self.LANG:
     139                        # Great! We found a name value for our locale!
     140                        plan['name'] = name.text
     141                        break
     142            else:
     143                plan['name'] = _('Default')
     144            plan['apn'] = apn_elem.get('value')
     145            user = apn_elem.find('.//username')
     146            if user is not None:
     147                plan['username'] = user.text
     148            else:
     149                plan['username'] = ''
     150            passwd = apn_elem.find('.//password')
     151            if passwd is not None:
     152                plan['password'] = passwd.text
     153            else:
     154                plan['password'] = ''
     155
     156            plan['number'] = self.DEFAULT_NUMBER
     157
     158            self.append((plan['name'], plan))
     159
     160    def get_row_plan(self, n):
     161        return self[n][1]
  • extensions/cpsection/modemconfiguration/view.py

    old new  
    7575    def set_text_from_model(self):
    7676        self._entry.set_text(self.get_value())
    7777
     78    def set_text(self, text):
     79        self._entry.set_text(text)
     80
    7881    def get_value(self):
    7982        raise NotImplementedError
    8083
     
    139142        self.set_border_width(style.DEFAULT_SPACING)
    140143        self.set_spacing(style.DEFAULT_SPACING)
    141144
     145        if self._model.has_providers_db():
     146            self._upper_box = gtk.VBox(spacing=style.DEFAULT_SPACING)
     147            self._upper_box.set_border_width(style.DEFAULT_SPACING)
     148            self.pack_start(self._upper_box, fill=False)
     149
     150            # Country
     151            box = gtk.HBox(True)
     152            box.pack_start(gtk.Label(_('Country')), False)
     153            store = self._model.CountryListStore()
     154            country_combo = gtk.ComboBox(store)
     155            cell = gtk.CellRendererText()
     156            cell.props.xalign = 0.5
     157            country_combo.pack_start(cell)
     158            country_combo.add_attribute(cell, 'text', 0)
     159            country_combo.connect('changed', self._country_selected)
     160            box.pack_start(country_combo, False)
     161            self._upper_box.pack_start(box, False)
     162
     163            #Provider
     164            box = gtk.HBox(True)
     165            box.pack_start(gtk.Label(_('Provider')), False)
     166            self._prov_combo = gtk.ComboBox()
     167            cell = gtk.CellRendererText()
     168            cell.props.xalign = 0.5
     169            self._prov_combo.pack_start(cell)
     170            self._prov_combo.add_attribute(cell, 'text', 0)
     171            self._prov_combo.connect('changed', self._provider_selected)
     172            box.pack_start(self._prov_combo, False)
     173            self._upper_box.pack_start(box, False)
     174
     175            #Plan
     176            box = gtk.HBox(True)
     177            box.pack_start(gtk.Label(_('Plan')), False)
     178            self._plan_combo = gtk.ComboBox()
     179            cell = gtk.CellRendererText()
     180            cell.props.xalign = 0.5
     181            self._plan_combo.pack_start(cell)
     182            self._plan_combo.add_attribute(cell, 'text', 0)
     183            self._plan_combo.connect('changed', self._plan_selected)
     184            box.pack_start(self._plan_combo, False)
     185            self._upper_box.pack_start(box, False)
     186
     187            country_combo.set_active(store.guess_country_row())
     188
     189            self.pack_start(gtk.HSeparator())
     190
     191        self._lower_box = gtk.VBox(spacing=style.DEFAULT_SPACING)
     192        self.pack_start(self._lower_box, fill=False)
     193
    142194        self._username_entry = UsernameEntry(model)
    143195        self._username_entry.connect('notify::is-valid',
    144196                                     self.__notify_is_valid_cb)
    145         self.pack_start(self._username_entry, expand=False)
    146         self._username_entry.show()
     197        self._lower_box.pack_start(self._username_entry, expand=False)
    147198
    148199        self._password_entry = PasswordEntry(model)
    149200        self._password_entry.connect('notify::is-valid',
    150201                                     self.__notify_is_valid_cb)
    151         self.pack_start(self._password_entry, expand=False)
    152         self._password_entry.show()
     202        self._lower_box.pack_start(self._password_entry, expand=False)
    153203
    154204        self._number_entry = NumberEntry(model)
    155205        self._number_entry.connect('notify::is-valid',
    156206                                   self.__notify_is_valid_cb)
    157         self.pack_start(self._number_entry, expand=False)
    158         self._number_entry.show()
     207        self._lower_box.pack_start(self._number_entry, expand=False)
    159208
    160209        self._apn_entry = ApnEntry(model)
    161210        self._apn_entry.connect('notify::is-valid',
    162211                                self.__notify_is_valid_cb)
    163         self.pack_start(self._apn_entry, expand=False)
    164         self._apn_entry.show()
     212        self._lower_box.pack_start(self._apn_entry, expand=False)
    165213
    166214        self.setup()
     215        self.show_all()
    167216
    168217    def setup(self):
    169218        self._username_entry.set_text_from_model()
     
    176225    def undo(self):
    177226        self._model.undo()
    178227
     228    def _country_selected(self, combo):
     229        model = combo.get_model()
     230        providers = model.get_row_providers(combo.get_active())
     231        self._prov_combo.set_model(self._model.ProviderListStore(providers))
     232
     233    def _provider_selected(self, combo):
     234        model = combo.get_model()
     235        plans = model.get_row_plans(combo.get_active())
     236        self._plan_combo.set_model(self._model.PlanListStore(plans))
     237
     238    def _plan_selected(self, combo):
     239        model = combo.get_model()
     240        plan = model.get_row_plan(combo.get_active())
     241        self._username_entry.set_text(plan['username'])
     242        self._password_entry.set_text(plan['password'])
     243        self._number_entry.set_text(plan['number'])
     244        self._apn_entry.set_text(plan['apn'])
     245
    179246    def _validate(self):
    180247        if self._username_entry.is_valid and \
    181248            self._password_entry.is_valid and \