maj
[masstransit] / src / opt / masstransit / masstransit.py
index e516fe6..5ae9447 100755 (executable)
 #!/usr/bin/python
-import pygtk
-pygtk.require("2.0")
-import gtk
+# -*- coding: utf-8 -*-
+"affichage des horaires de train"
+
+
+
 import urllib2
 import HTMLParser
-import hildon
 import ConfigParser
+import errno
+import conic
+
+
+magic = 0xAA55
 
-from portrait import FremantleRotation
+try:
+    import hildon
+except ImportError: 
+    raise ImportError("erreur d'importation de hildon")
 
-#main_window = mainWindow # your main hildon.StackableWindow
-app_name = 'NameOfYourApp' # the name of your app
-app_version = '1.0' # the version number of your app
-initial_mode = FremantleRotation.AUTOMATIC
+try :
+    from portrait import FremantleRotation
+except ImportError: 
+    raise ImportError("erreur d'importation de portrait")
+
+try :
+    import gtk
+except ImportError: 
+    raise ImportError("erreur d'importation de gtk")
+
+try : 
+    import pygtk
+except ImportError: 
+    raise ImportError("erreur d'importation de pygtk")
+    
+pygtk.require("2.0")
 
 class LigneHoraire(object):
-    def __init__(self, code_mission, heure_de_passage):
-        self.code_mission = code_mission
-        self.heure_de_passage = heure_de_passage
+    "une ligne code_mission | heure_de_passage"
+    def __init__(self, code_mission, heure_de_passage, destination, voie):
+        self.__code_mission = code_mission
+        self.__heure_de_passage = heure_de_passage
+        self.__destination = destination
+        self.__voie = voie
     
     def add_to_treestore(self, treestore):
-        print treestore
-        treestore.append(None, [self.code_mission, self.heure_de_passage])
+        "ajoute la ligne à un treestore"
+        treestore.append(None, [self.__code_mission, self.__heure_de_passage, self.__destination, self.__voie])
     
     
 
-class tableParser(HTMLParser.HTMLParser):
+class TableParser(HTMLParser.HTMLParser):
+    "Parse les tableaux html contenant les horaires"
     def __init__(self):
         HTMLParser.HTMLParser.__init__(self)
-        self.table_horaires3 = False
-        self.code_de_mission = False
-        self.a_code_de_mission = False
-        self.heure_de_passage = False
-        self.liste_train = []
-        self.liste_horaire = []
-        self.list_ligne_horaire = []
+        self.__table_horaires3 = False
+        self.__code_de_mission = False
+        self.__a_code_de_mission = False
+        self.__heure_de_passage = False
+        self.__destination = False
+        self.__voie = False
+        self.__liste_train = []
+        self.__liste_horaire = []
+        self.__liste_destination = []
+        self.__liste_voie = []
+        
         
     def handle_starttag(self, tag, attrs):
+        "execute a chaque balise ouvrante"
         if (tag == 'table' and (dict(attrs)['class'] == 'horaires3')):
-            self.table_horaires3 = True
+            self.__table_horaires3 = True
         
-        elif self.table_horaires3 and tag == 'td':
+        elif self.__table_horaires3 and tag == 'td':
             try:
-                self.code_de_mission = (
+                self.__code_de_mission = (
                     dict(attrs)['headers'] == 'Code_de_mission')
-                self.heure_de_passage = (
+                self.__heure_de_passage = (
                     dict(attrs)['headers'] == 'Heure_de_passage')
+                self.__destination = (
+                    dict(attrs)['headers'] == 'Destination')
+                self.__voie = (
+                    dict(attrs)['headers'] == 'Voie')
             except KeyError:
                 if dict(attrs).has_key('headers'):
                     raise
                 else:
                     pass
         else:
-            self.a_code_de_mission = (tag == 'a' and self.code_de_mission)
+            self.__a_code_de_mission = (tag == 'a' and self.__code_de_mission)
         
     def handle_data(self, data):
-        if self.a_code_de_mission:
-            self.liste_train.append(data.strip())
-        if self.heure_de_passage:
-            self.liste_horaire.append(data.strip())
+        "execute pour chaque contenu de balise"
+        if self.__a_code_de_mission:
+            self.__liste_train.append(data.strip())
+        if self.__heure_de_passage:
+            self.__liste_horaire.append(data.strip())
+        if self.__destination:
+            self.__liste_destination.append(data.strip())
+        if self.__voie:
+            self.__liste_voie.append(data.strip())
             
-    def handle_endtag(self,tag):
-        self.a_code_de_mission ^= (self.a_code_de_mission and tag == 'a')
-        self.heure_de_passage ^= (self.heure_de_passage and tag == 'td')
-    
-    def get_list_ligne_horaire(self):
-        print 'get_list_ligne_horaire'
-        z = 0
-        print self.liste_train
-        for i in self.liste_train:
-            self.list_ligne_horaire.append(LigneHoraire(code_mission=i, heure_de_passage=self.liste_horaire[z]))
-            z += 1
-        return self.list_ligne_horaire
+    def handle_endtag(self, tag):
+        "execute à chaque balise fermante"
+        self.__a_code_de_mission ^= (self.__a_code_de_mission and tag == 'a')
+        self.__heure_de_passage ^= (self.__heure_de_passage and tag == 'td')
+        self.__destination ^= (self.__destination and tag == 'td')
+        self.__voie ^= (self.__voie and tag == 'td')
     
     
+    @property
+    def __list_ligne_horaire(self):
+        "getter"
+        __list_ligne_horaire = []
+        __curseur_horaire = 0
+        for __i in self.__liste_train:
+            __list_ligne_horaire.append(LigneHoraire(
+                code_mission=__i, 
+                heure_de_passage=self.__liste_horaire[__curseur_horaire],
+                destination=self.__liste_destination[__curseur_horaire],
+                voie=self.__liste_voie[__curseur_horaire]
+                ))
+            __curseur_horaire += 1
+        return __list_ligne_horaire
+
+    def fill_treestore(self, treestore):
+        "remlpli le treestore avec les resultats"
+        for __i in self.__list_ligne_horaire:
+            __i.add_to_treestore(treestore)
+
+def connection_cb(connection, event, magic):
+    print "connection_cb(%s, %s, %x)" % (connection, event, magic)
+    print event.get_status()
 
 class Trajet(object):
+    "trajet d'une gare source à une gare_dest"
     def __init__(self, gare_source, gare_dest):
-        self.gare_source = gare_source
-        self.gare_dest = gare_dest
-        self.parse() 
-    def get_liste_train(self):
-        return self.p.liste_train 
-    def get_liste_horaire(self): 
-        return self.p.liste_horaire
-    def parse(self):
-        self.p = tableParser()
-        #print "URL:" 
-        #print 'http://www.transilien.com/web/ITProchainsTrainsAvecDest.do?codeTr3aDepart='+self.gare_source.shortname+'&codeTr3aDest='+self.gare_dest.shortname+'&urlModule=/site/pid/184&gareAcc=true'
-        rsrc = urllib2.urlopen('http://www.transilien.com/web/ITProchainsTrainsAvecDest.do?codeTr3aDepart='+self.gare_source.shortname+'&codeTr3aDest='+self.gare_dest.shortname+'&urlModule=/site/pid/184&gareAcc=true')
-        self.p.feed(rsrc.read())
-        print "parsing ok"
+        self.__gare_source = gare_source
+        self.__gare_dest = gare_dest
         
     def refresh_treestore(self, treestore):
-        print 'refresh'
-        print treestore
-        
+        "met à jour les horaires d'un trajet"
         treestore.clear()
-        liste_ligne_horaire = self.p.get_list_ligne_horaire()
-        print liste_ligne_horaire
-        for i in liste_ligne_horaire:
-            print i
-            i.add_to_treestore(treestore)
+        __parser = TableParser()
+        __parser.feed(urllib2.urlopen('http://www.transilien.com/web/ITProchainsTrainsAvecDest.do?codeTr3aDepart='+self.__gare_source.shortname+'&codeTr3aDest='+self.__gare_dest.shortname+'&urlModule=/site/pid/184&gareAcc=true').read())
+        __parser.fill_treestore(treestore)
+
 
 class ConfFile(object):
+    "fichier contenant les gares"
     def __init__(self, fichier):
-        self.c = ConfigParser.ConfigParser()
-        self.c.read(fichier)
-    def get_short_name(self, longname):
-        return self.c.get('ListeDesGares', longname)
-    def get_liste_des_gares(self):
-        return self.c.items('ListeDesGares') 
+        self.config = ConfigParser.ConfigParser()
+        self.config.read(fichier)
+        
 
 class LongNameGare(object):
+    "nom long d'une gare"
     def __init__(self, longname):
-        self.longname = longname
+        self.__longname = longname
     def get_gare(self, conffile):
-        short_name = conffile.get_short_name(self.longname)
-        return Gare(short_name)
+        "retourne une gare à partir d'un nom long"
+        return Gare(conffile.config.get('ListeDesGares', self.__longname))
 
 class Gare(object):
+    "gare"
     def __init__(self, shortname):
         self.shortname = shortname
 
-
-
-
 class TransilienUI:
+    "interface hildon"
     def __init__(self):
-        mainWindow = hildon.Window()
-        mainWindow.set_title("Horaires des Prochains Trains")
-        mainWindow.connect("destroy", self.on_mainWindow_destroy)
+        self.main_window = hildon.Window()
+        self.main_window.set_title("Horaires des Prochains Trains")
+        self.main_window.connect("destroy", self.on_main_window_destroy)
 
-        rotation_object = FremantleRotation(app_name, mainWindow, app_version, initial_mode)
-        refreshButton = hildon.Button(gtk.HILDON_SIZE_AUTO_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT,
-                              hildon.BUTTON_ARRANGEMENT_HORIZONTAL, "Actualiser")
-        refreshButton.connect("clicked", self.on_refreshButton_clicked)
+        rotation_object = FremantleRotation(
+            'NameOfYourApp', 
+            self.main_window, 
+            '1.0', 
+            FremantleRotation.AUTOMATIC
+            )
+        
+        refresh_button = hildon.Button(
+            gtk.HILDON_SIZE_AUTO_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT, 
+            hildon.BUTTON_ARRANGEMENT_HORIZONTAL, 
+            "Actualiser"
+            )
+        retour_button = hildon.Button(
+            gtk.HILDON_SIZE_AUTO_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT, 
+            hildon.BUTTON_ARRANGEMENT_HORIZONTAL, 
+            "Retour"
+            )
+        refresh_button.connect("clicked", self.on_refresh_button_clicked)
+        retour_button.connect("clicked", self.on_retour_button_clicked)
 
-        self.treestore = gtk.TreeStore(str, str)
+        self.treestore = gtk.TreeStore(str, str, str, str)
         self.treeview = gtk.TreeView(self.treestore)
 
-        self.tvcolumn_train = gtk.TreeViewColumn('Train', gtk.CellRendererText(), text=0)
-        self.treeview.append_column(self.tvcolumn_train)
+        self.treeview.append_column(
+            gtk.TreeViewColumn( 
+                'Train', 
+                gtk.CellRendererText(), 
+                text=0
+            ))
         
-        self.tvcolumn_horaire = gtk.TreeViewColumn('Horaire', gtk.CellRendererText(), text=1)
-        self.treeview.append_column(self.tvcolumn_horaire)
+        self.treeview.append_column(
+            gtk.TreeViewColumn(
+                'Horaire', 
+                gtk.CellRendererText(), 
+                text=1
+            ))
+            
+        self.treeview.append_column(
+            gtk.TreeViewColumn(
+                'Destination', 
+                gtk.CellRendererText(), 
+                text=2
+            ))
+        self.treeview.append_column(
+            gtk.TreeViewColumn(
+                'Voie', 
+                gtk.CellRendererText(), 
+                text=3
+            ))
 
 
-        picker_button_source = hildon.PickerButton(gtk.HILDON_SIZE_AUTO,                            hildon.BUTTON_ARRANGEMENT_VERTICAL)
-        picker_button_source.set_title("Gare de Depart")
+        
+        
         self.combo_source = hildon.TouchSelectorEntry(text=True)
         self.combo_dest = hildon.TouchSelectorEntry(text=True)
 
-        for i in ConfFile('/opt/masstransit/masstransit.cfg').get_liste_des_gares():
-            self.combo_source.append_text(i[0])
-            self.combo_dest.append_text(i[0])
-        picker_button_source.set_selector(self.combo_source)
+        liste = ConfFile('/opt/masstransit/masstransit.cfg').config.items('ListeDesGares')
+        liste.sort()
+        for i in liste:
+            self.combo_source.append_text(i[0].capitalize())
+            self.combo_dest.append_text(i[0].capitalize())
         
-
-        picker_button_dest = hildon.PickerButton(gtk.HILDON_SIZE_AUTO,                            hildon.BUTTON_ARRANGEMENT_VERTICAL)
+        picker_button_source = hildon.PickerButton(
+            gtk.HILDON_SIZE_AUTO, 
+            hildon.BUTTON_ARRANGEMENT_VERTICAL)
+        
+        picker_button_dest = hildon.PickerButton(
+            gtk.HILDON_SIZE_AUTO, 
+            hildon.BUTTON_ARRANGEMENT_VERTICAL
+            )
+        
+        picker_button_source.set_title("Gare de Depart")
         picker_button_dest.set_title("Gare d'arrivee")
-        picker_button_dest.set_selector(self.combo_dest)
         
-        vBox = gtk.VBox()
-        hBox = gtk.HBox()
-        vBox.pack_start(hBox)
-        hBox.pack_start(picker_button_source)
-        hBox.pack_start(picker_button_dest)
-        vBox.pack_start(self.treeview)
-        vBox.pack_start(refreshButton)
+        picker_button_source.set_selector(self.combo_source)
+        picker_button_dest.set_selector(self.combo_dest)
         
+        vertical_box = gtk.VBox()
+        horizontal_box = gtk.HBox()
+        vertical_box.pack_start(horizontal_box)
+        horizontal_box.pack_start(picker_button_source)
+        horizontal_box.pack_start(picker_button_dest)
+        horizontal_box.pack_start(retour_button)
+        vertical_box.pack_start(self.treeview)
+        vertical_box.pack_start(refresh_button)
 
-        mainWindow.add(vBox)
-        mainWindow.show_all()
+        self.main_window.add(vertical_box)
+        self.main_window.show_all()
 
-    def on_mainWindow_destroy(self, widget):
+    def on_main_window_destroy(self, widget):
+        "quitte l'application à la fermeture de la fenetre"
         gtk.main_quit()
 
-    def on_refreshButton_clicked(self, widget):
+    
+    def on_retour_button_clicked(self, widget):
+        "le bouton retour est clicked"
+        col_source = self.combo_source.get_active(0)
+        col_dest = self.combo_dest.get_active(0)
+        self.combo_source.set_active(0, col_dest)
+        self.combo_dest.set_active(0, col_source)
+        self.refresh()
+    
+    def on_refresh_button_clicked(self, widget):
+        "le bouton refresh est clicked"
+        self.refresh()
+    
+    def refresh(self):
+        "met a jour les horaires"
         conf = ConfFile('/opt/masstransit/masstransit.cfg')
-        gare_source = LongNameGare(self.combo_source.get_current_text()).get_gare(conf)
-        gare_dest = LongNameGare(self.combo_dest.get_current_text()).get_gare(conf)
-        trajet = Trajet(gare_source , gare_dest)
-        print trajet
-        print self.treestore
-        trajet.refresh_treestore(self.treestore)
-
-
+        try :
+            gare_source = LongNameGare(self.combo_source.get_current_text()).get_gare(conf)
+        except AttributeError:
+            if self.combo_source.get_current_text() is None:
+                gtk.Dialog.run(hildon.hildon_note_new_information(self.main_window, "Vous devez remplir la gare source"))
+            else:
+                raise
+        else:
+            try :
+                gare_dest = LongNameGare(self.combo_dest.get_current_text()).get_gare(conf)     
+            except AttributeError:
+                if self.combo_dest.get_current_text() is None:
+                    gtk.Dialog.run(hildon.hildon_note_new_information(self.main_window, "Vous devez remplir la gare de destination"))
+                else:
+                    raise
+            else:
+                trajet = Trajet(gare_source , gare_dest)
+                try :
+                    trajet.refresh_treestore(self.treestore)
+                except urllib2.URLError, e:
+                    global magic
+                    connection = conic.Connection()
+                    connection.connect("connection-event", connection_cb, magic)
+                    connection.request_connection(conic.CONNECT_FLAG_NONE)
+                    trajet.refresh_treestore(self.treestore)
+                    
+        
 if __name__ == "__main__":
     TransilienUI()
     gtk.main()
+