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

File gsm-provider-db-v3-1630.patch, 16.3 KB (added by aa, 9 years ago)
  • configure.ac

    diff --git a/configure.ac b/configure.ac
    index 0b271fc..78f9461 100644
    a b extensions/cpsection/frame/Makefile 
    5656extensions/cpsection/keyboard/Makefile
    5757extensions/cpsection/language/Makefile
    5858extensions/cpsection/modemconfiguration/Makefile
     59extensions/cpsection/modemconfiguration/config.py
    5960extensions/cpsection/Makefile
    6061extensions/cpsection/network/Makefile
    6162extensions/cpsection/power/Makefile
  • extensions/cpsection/modemconfiguration/Makefile.am

    diff --git a/extensions/cpsection/modemconfiguration/Makefile.am b/extensions/cpsection/modemconfiguration/Makefile.am
    index 3e2613e..525e02e 100644
    a b sugar_PYTHON = \ 
    44        __init__.py     \
    55        model.py        \
    66        view.py         
     7
     8nodist_sugar_PYTHON = config.py
  • new file extensions/cpsection/modemconfiguration/config.py.in

    diff --git a/extensions/cpsection/modemconfiguration/config.py.in b/extensions/cpsection/modemconfiguration/config.py.in
    new file mode 100644
    index 0000000..6fa688e
    - +  
     1# -*- encoding: utf-8 -*-
     2# Copyright (C) 2010 Andrés Ambrois
     3#
     4# This program is free software; you can redistribute it and/or modify
     5# it under the terms of the GNU General Public License as published by
     6# the Free Software Foundation; either version 2 of the License, or
     7# (at your option) any later version.
     8#
     9# This program is distributed in the hope that it will be useful,
     10# but WITHOUT ANY WARRANTY; without even the implied warranty of
     11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12# GNU General Public License for more details.
     13#
     14# You should have received a copy of the GNU General Public License
     15# along with this program; if not, write to the Free Software
     16# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  US
     17
     18PROVIDERS_PATH = "@prefix@/share/mobile-broadband-provider-info/serviceproviders.xml"
     19PROVIDERS_FORMAT_SUPPORTED = "2.0"
     20COUNTRY_CODES_PATH = "@prefix@/share/zoneinfo/iso3166.tab"
  • extensions/cpsection/modemconfiguration/model.py

    diff --git a/extensions/cpsection/modemconfiguration/model.py b/extensions/cpsection/modemconfiguration/model.py
    old mode 100755
    new mode 100644
    index 2545ce1..49b3fc3
    a b  
     1# -*- coding: utf-8 -*-
    12# Copyright (C) 2009 Paraguay Educa, Martin Abente
     3# Copyright (C) 2010 Andrés Ambrois
    24#
    35# This program is free software; you can redistribute it and/or modify
    46# it under the terms of the GNU General Public License as published by
     
    1517# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  US
    1618
    1719import gconf
     20import gtk
     21import os
     22import locale
     23from xml.etree.cElementTree import ElementTree
     24from gettext import gettext as _
    1825
    1926from jarabe.model.network import GSM_USERNAME_PATH, GSM_PASSWORD_PATH, \
    2027                                 GSM_NUMBER_PATH, GSM_APN_PATH, GSM_PIN_PATH, \
    2128                                 GSM_PUK_PATH
    2229
     30from cpsection.modemconfiguration.config import *
     31
    2332def get_username():
    2433    client = gconf.client_get_default()
    2534    return client.get_string(GSM_USERNAME_PATH) or ''
    def set_puk(puk): 
    6877    client = gconf.client_get_default()
    6978    client.set_string(GSM_PUK_PATH, puk)
    7079
     80def has_providers_db():
     81    if not os.path.isfile(COUNTRY_CODES_PATH):
     82        return False
     83    try:
     84        tree = ElementTree(file=PROVIDERS_PATH)
     85        elem = tree.getroot()
     86        if elem is None or elem.get('format') != PROVIDERS_FORMAT_SUPPORTED:
     87            return False
     88        return True
     89    except IOError:
     90        return False
     91
     92class CountryListStore(gtk.ListStore):
     93    COUNTRY_CODE = locale.getdefaultlocale()[0][3:5].lower()
     94
     95    def __init__(self):
     96        gtk.ListStore.__init__(self, str, object)
     97        codes = {}
     98        with open(COUNTRY_CODES_PATH) as codes_file:
     99            for line in codes_file:
     100                if line.startswith('#'):
     101                    continue
     102                code, name = line.split('\t')[:2]
     103                codes[code.lower()] = name.strip()
     104        etree = ElementTree(file=PROVIDERS_PATH).getroot()
     105        self._country_idx = None
     106        i = 0
     107        for elem in etree.findall('.//country'):
     108            code = elem.attrib['code']
     109            if code == self.COUNTRY_CODE:
     110                self._country_idx = i
     111            else:
     112                i += 1
     113            if code in codes:
     114                self.append((codes[code], elem))
     115            else:
     116                self.append((code, elem))
     117
     118    def get_row_providers(self, row):
     119        return self[row][1]
     120
     121    def guess_country_row(self):
     122        if self._country_idx is not None:
     123            return self._country_idx
     124        else:
     125            return -1
     126
     127class ProviderListStore(gtk.ListStore):
     128    def __init__(self, elem):
     129        gtk.ListStore.__init__(self, str, object)
     130        for provider_elem in elem.findall('.//provider'):
     131            apns = provider_elem.findall('.//apn')
     132            if not apns:
     133                # Skip carriers with CDMA entries only
     134                continue
     135            self.append((provider_elem.find('.//name').text, apns))
     136
     137    def get_row_plans(self, row):
     138        return self[row][1]
     139
     140class PlanListStore(gtk.ListStore):
     141    LANG_NS_ATTR = '{http://www.w3.org/XML/1998/namespace}lang'
     142    LANG = locale.getdefaultlocale()[0][:2]
     143    DEFAULT_NUMBER = '*99#'
     144
     145    def __init__(self, elems):
     146        gtk.ListStore.__init__(self, str, object)
     147        for apn_elem in elems:
     148            plan = {}
     149            names = apn_elem.findall('.//name')
     150            if names:
     151                for name in names:
     152                    if name.get(self.LANG_NS_ATTR) is None:
     153                        # serviceproviders.xml default value
     154                        plan['name'] = name.text
     155                    elif name.get(self.LANG_NS_ATTR) == self.LANG:
     156                        # Great! We found a name value for our locale!
     157                        plan['name'] = name.text
     158                        break
     159            else:
     160                plan['name'] = _('Default')
     161            plan['apn'] = apn_elem.get('value')
     162            user = apn_elem.find('.//username')
     163            if user is not None:
     164                plan['username'] = user.text
     165            else:
     166                plan['username'] = ''
     167            passwd = apn_elem.find('.//password')
     168            if passwd is not None:
     169                plan['password'] = passwd.text
     170            else:
     171                plan['password'] = ''
     172
     173            plan['number'] = self.DEFAULT_NUMBER
     174
     175            self.append((plan['name'], plan))
     176
     177    def get_row_plan(self, row):
     178        return self[row][1]
     179
  • extensions/cpsection/modemconfiguration/view.py

    diff --git a/extensions/cpsection/modemconfiguration/view.py b/extensions/cpsection/modemconfiguration/view.py
    index 2445005..6463954 100644
    a b  
     1# -*- coding: utf-8 -*-
    12# Copyright (C) 2009 Paraguay Educa, Martin Abente
     3# Copyright (C) 2010 Andrés Ambrois
    24#
    35# This program is free software; you can redistribute it and/or modify
    46# it under the terms of the GNU General Public License as published by
     
    1416# along with this program; if not, write to the Free Software
    1517# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  US
    1618
    17 import os
    18 import logging
    1919from gettext import gettext as _
    2020
    2121import gtk
    class EntryWithLabel(gtk.HBox): 
    3737        self._changed_handler = None
    3838        self._is_valid = True
    3939
    40         label = gtk.Label(label_text)
    41         label.modify_fg(gtk.STATE_NORMAL,
     40        self._label = gtk.Label(label_text)
     41        self._label.modify_fg(gtk.STATE_NORMAL,
    4242                        style.COLOR_SELECTION_GREY.get_gdk_color())
    43         self.pack_start(label, True, True)
    44         label.show()
     43        self.pack_start(self._label, False)
     44        self._label.show()
    4545
    4646        self._entry = gtk.Entry(25)
    4747        self._entry.connect('changed', self.__entry_changed_cb)
    4848        self._entry.set_width_chars(25)
    49         self.pack_start(self._entry, expand=False)
     49        self._entry.set_alignment(0.5)
     50        self.pack_start(self._entry, False)
    5051        self._entry.show()
    5152
    5253    def __entry_changed_cb(self, widget, data=None):
    class EntryWithLabel(gtk.HBox): 
    7879    def get_value(self):
    7980        raise NotImplementedError
    8081
    81     def set_value(self):
     82    def set_value(self, value):
    8283        raise NotImplementedError   
    8384
     85    def get_label(self):
     86        return self._label
     87
    8488    def _get_is_valid(self):
    8589        return self._is_valid
    8690    is_valid = gobject.property(type=bool, getter=_get_is_valid, default=True)
    class ModemConfiguration(SectionView): 
    159163        self._model = model
    160164        self.restart_alerts = alerts
    161165
    162         self.set_border_width(style.DEFAULT_SPACING)
    163166        self.set_spacing(style.DEFAULT_SPACING)
    164167
     168        label_group = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
     169
     170        scrolled_win = gtk.ScrolledWindow()
     171        scrolled_win.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
     172        scrolled_win.show()
     173        self.add(scrolled_win)
     174
     175        main_box = gtk.VBox(spacing=style.DEFAULT_SPACING)
     176        main_box.set_border_width(style.DEFAULT_SPACING)
     177        main_box.show()
     178        scrolled_win.add_with_viewport(main_box)
     179
     180        if model.has_providers_db():
     181            self._upper_box = gtk.VBox(spacing=style.DEFAULT_SPACING)
     182            self._upper_box.set_border_width(style.DEFAULT_SPACING)
     183            main_box.pack_start(self._upper_box, expand=False)
     184            self._upper_box.show()
     185
     186            combo_group = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
     187
     188            box = gtk.HBox(spacing=style.DEFAULT_SPACING)
     189            label = gtk.Label(_('Country:'))
     190            label_group.add_widget(label)
     191            box.pack_start(label, False)
     192            label.show()
     193            country_store = model.CountryListStore()
     194            country_combo = gtk.ComboBox(country_store)
     195            combo_group.add_widget(country_combo)
     196            cell = gtk.CellRendererText()
     197            cell.props.xalign = 0.5
     198            country_combo.pack_start(cell)
     199            country_combo.add_attribute(cell, 'text', 0)
     200            country_combo.connect('changed', self.__country_selected_cb)
     201            box.pack_start(country_combo, False)
     202            country_combo.show()
     203            self._upper_box.pack_start(box, False)
     204            box.show()
     205
     206            box = gtk.HBox(spacing=style.DEFAULT_SPACING)
     207            label = gtk.Label(_('Provider:'))
     208            label_group.add_widget(label)
     209            box.pack_start(label, False)
     210            label.show()
     211            self._providers_combo = gtk.ComboBox()
     212            combo_group.add_widget(self._providers_combo)
     213            cell = gtk.CellRendererText()
     214            cell.props.xalign = 0.5
     215            self._providers_combo.pack_start(cell)
     216            self._providers_combo.add_attribute(cell, 'text', 0)
     217            self._providers_combo.connect('changed',
     218                                          self.__provider_selected_cb)
     219            box.pack_start(self._providers_combo, False)
     220            self._providers_combo.show()
     221            self._upper_box.pack_start(box, False)
     222            box.show()
     223
     224            box = gtk.HBox(spacing=style.DEFAULT_SPACING)
     225            label = gtk.Label(_('Plan:'))
     226            label_group.add_widget(label)
     227            box.pack_start(label, False)
     228            label.show()
     229            self._plan_combo = gtk.ComboBox()
     230            combo_group.add_widget(self._plan_combo)
     231            cell = gtk.CellRendererText()
     232            cell.props.xalign = 0.5
     233            self._plan_combo.pack_start(cell)
     234            self._plan_combo.add_attribute(cell, 'text', 0)
     235            self._plan_combo.connect('changed', self.__plan_selected_cb)
     236            box.pack_start(self._plan_combo, False)
     237            self._plan_combo.show()
     238            self._upper_box.pack_start(box, False)
     239            box.show()
     240
     241            country_combo.set_active(country_store.guess_country_row())
     242
     243            separator = gtk.HSeparator()
     244            main_box.pack_start(separator, False)
     245            separator.show()
     246
     247        self._lower_box = gtk.VBox(spacing=style.DEFAULT_SPACING)
     248        self._lower_box.set_border_width(style.DEFAULT_SPACING)
     249        main_box.pack_start(self._lower_box, expand=False)
     250        self._lower_box.show()
     251
    165252        self._username_entry = UsernameEntry(model)
    166253        self._username_entry.connect('notify::is-valid',
    167254                                     self.__notify_is_valid_cb)
    168         self.pack_start(self._username_entry, expand=False)
     255        self._lower_box.pack_start(self._username_entry, fill=False)
     256        label_group.add_widget(self._username_entry.get_label())
    169257        self._username_entry.show()
    170258
    171259        self._password_entry = PasswordEntry(model)
    172260        self._password_entry.connect('notify::is-valid',
    173261                                     self.__notify_is_valid_cb)
    174         self.pack_start(self._password_entry, expand=False)
     262        self._lower_box.pack_start(self._password_entry, fill=False)
     263        label_group.add_widget(self._password_entry.get_label())
    175264        self._password_entry.show()
    176265
    177266        self._number_entry = NumberEntry(model)
    178267        self._number_entry.connect('notify::is-valid',
    179268                                   self.__notify_is_valid_cb)
    180         self.pack_start(self._number_entry, expand=False)
     269        self._lower_box.pack_start(self._number_entry, fill=False)
     270        label_group.add_widget(self._number_entry.get_label())
    181271        self._number_entry.show()
    182272
    183273        self._apn_entry = ApnEntry(model)
    184274        self._apn_entry.connect('notify::is-valid',
    185275                                self.__notify_is_valid_cb)
    186         self.pack_start(self._apn_entry, expand=False)
     276        self._lower_box.pack_start(self._apn_entry, fill=False)
     277        label_group.add_widget(self._apn_entry.get_label())
    187278        self._apn_entry.show()
    188279
    189280        self._pin_entry = PinEntry(model)
    190281        self._pin_entry.connect('notify::is-valid',
    191282                                self.__notify_is_valid_cb)
    192         self.pack_start(self._pin_entry, expand=False)
     283        self._lower_box.pack_start(self._pin_entry, fill=False)
     284        label_group.add_widget(self._pin_entry.get_label())
    193285        self._pin_entry.show()
    194286       
    195287        self._puk_entry = PukEntry(model)
    196288        self._puk_entry.connect('notify::is-valid',
    197289                                self.__notify_is_valid_cb)
    198         self.pack_start(self._puk_entry, expand=False)       
     290        self._lower_box.pack_start(self._puk_entry, fill=False)
     291        label_group.add_widget(self._puk_entry.get_label())
    199292        self._puk_entry.show()
    200293
    201294        self.setup()
    class ModemConfiguration(SectionView): 
    213306    def undo(self):
    214307        self._model.undo()
    215308
     309    def __country_selected_cb(self, combo):
     310        model = combo.get_model()
     311        providers = model.get_row_providers(combo.get_active())
     312        self._providers_combo.set_model(
     313            self._model.ProviderListStore(providers))
     314
     315    def __provider_selected_cb(self, combo):
     316        model = combo.get_model()
     317        plans = model.get_row_plans(combo.get_active())
     318        self._plan_combo.set_model(self._model.PlanListStore(plans))
     319
     320    def __plan_selected_cb(self, combo):
     321        model = combo.get_model()
     322        plan = model.get_row_plan(combo.get_active())
     323        self._username_entry.set_value(plan['username'])
     324        self._username_entry.set_text_from_model()
     325        self._password_entry.set_value(plan['password'])
     326        self._password_entry.set_text_from_model()
     327        self._number_entry.set_value(plan['number'])
     328        self._number_entry.set_text_from_model()
     329        self._apn_entry.set_value(plan['apn'])
     330        self._apn_entry.set_text_from_model()
     331
    216332    def _validate(self):
    217333        if self._username_entry.is_valid and \
    218334            self._password_entry.is_valid and \
    class ModemConfiguration(SectionView): 
    220336                    self._apn_entry.is_valid and \
    221337                        self._pin_entry.is_valid and \
    222338                            self._puk_entry.is_valid:
    223                                 self.props.is_valid = True
     339            self.props.is_valid = True
    224340        else:
    225341            self.props.is_valid = False
    226342