Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. # -*- coding: utf-8 -*-
  2.  
  3. #Horaires RATP StandAlone v0.96
  4. #Copyright <copyright>
  5. #
  6. #Permission is hereby granted, free of charge, to any person obtaining a copy of
  7. #this software and associated documentation files (the "Software"), to deal in
  8. #the Software without restriction, including without limitation the rights to
  9. #use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  10. #of the Software, and to permit persons to whom the Software is furnished to do
  11. #so, subject to the following conditions:
  12. #The above copyright notice and this permission notice shall be included in all
  13. #copies or substantial portions of the Software.
  14. #
  15. #The Software is provided "as is", without warranty of any kind, express or
  16. #implied, including but not limited to the warranties of merchantability,
  17. #fitness for a particular purpose and noninfringement. In no event shall the
  18. #authors or copyright holders be liable for any claim, damages or other
  19. #liability, whether in an action of contract, tort or otherwise, arising from,
  20. #out of or in connection with the software or the use or other dealings in the
  21. #Software.
  22. #
  23. # </copyright>
  24. # <author>Antoine FERRON</author>
  25. # <date>2012-06-06</date>
  26. # <summary>Affiche les horaires aux arrets de la RATP</summary>
  27. # Based On: Script RATP by Gawel (Gael Pasgrimaud) : hg.gawel.org/ratp/
  28. # This is the standalone version, which not requires a Metronomebus conected on a USB port.
  29. #
  30. # usage : [ -l <lineid> station name -d {1|2}} ]
  31. #
  32. # Compiled with : Python 2.7.3, PyWin32 2.1.7, PyInstaller 1.5.1
  33.  
  34. import re
  35. import os
  36. import sys
  37. import time
  38. import urllib2
  39. import httplib
  40. import logging as log
  41. from datetime import datetime
  42. from optparse import OptionParser
  43.  
  44.  
  45. def debug(func):
  46.     def wrapper(*args, **kwargs):
  47.         result = func(*args, **kwargs)
  48.         log.debug('%s(*%r, **%r) -> %s', func.func_name, args[1:], kwargs, result)
  49.         return result
  50.     return wrapper
  51.  
  52. entities = (
  53.         ('</', ''),
  54.         ('&eacute;', 'e'),
  55.         ('&egrave;', 'e'),
  56.         ('&acirc;', 'a'),
  57.         ('&ocirc;', 'o'),
  58.         )
  59.  
  60. def clean_html(data):
  61.     if data.startswith('<b>'):
  62.         data = data.replace('<b>', '').replace('</b>', '')
  63.     for a, b in entities:
  64.         data = data.replace(a, b)
  65.     return data
  66.    
  67.  
  68.  
  69. class Service(object):
  70.  
  71.     def __init__(self):
  72.         self.headers = {
  73.                 'User-Agent': 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; fr; rv:1.9.2) Gecko/20100115 Firefox/3.6',
  74.                 }
  75.         self.conn = httplib.HTTPConnection("wap.ratp.fr")
  76.  
  77.     def open(self, path, **kwargs):
  78.         self.conn.request("GET", path , '', self.headers)
  79.         resp = self.conn.getresponse()
  80.         return resp
  81.  
  82.     @debug
  83.     def post(self, path='', **kwargs):
  84.         resp = self.open(path)
  85.         self.headers['referer'] = 'http://www.ratp.fr%s' % path
  86.         data = resp.read()
  87.         if 'body' in data:
  88.             data = data.split('<body>')[1]
  89.             data = data.replace('div', '\n')
  90.             data = data.replace('class="subtitle">Direction&nbsp;<b class="bwhite">', 'class="bg3"><b> Direction ')
  91.             data = data.replace('\n          &gt;&nbsp;', '<b>')
  92.             data = re.findall('.*class="(?:bg|schmsg|space)(?:[0-9]+)">(.*)', data)
  93.             data = [clean_html(d) for d in data if d[:3] in ('<b>')]
  94.         self.conn.close()
  95.         return data
  96.  
  97.     def close(self):
  98.         self.conn.close()
  99.  
  100.     def get(self,**kwargs):
  101.         kwargs['reseau'] = kwargs.get('lineid')[0] == 'M' and 'metro' or 'bus'
  102.         kwargs['stationname'] = kwargs['station'].replace(' ', '+')
  103.         url = '/siv/schedule?service=next'
  104.         url += '&reseau=%(reseau)s&referer=station&lineid=%(lineid)s' % kwargs
  105.         url += '&directionsens=%(directionsens)s' % kwargs
  106.         url += '&stationname=%(stationname)s&submitAction=Valider' % kwargs
  107.         data = self.post(url)
  108.         return data
  109.        
  110. def dispinfo(lid,args,direction):
  111.     kwargs = dict(lineid=lid.upper(), station=' '.join(args), time=datetime.now().strftime('%H:%M:%S'))
  112.     header = 'A %(time)s - Ligne: %(lineid)s - Station: %(station)s' %kwargs
  113.     print header.center(60)
  114.     print '='*60
  115.     s=Service()
  116.     diraff=0
  117.     if lid.upper().startswith('M'):
  118.         direct='AR'
  119.         direct=direct[direction-1]
  120.         direction=1
  121.     else:
  122.         direct='A'
  123.     for directionsens in direct:
  124.         outputd = s.get(directionsens=directionsens, **kwargs)      
  125.         if outputd:
  126.             data=outputd
  127.             output = []
  128.             ligne=0
  129.             datatemp=''
  130.             while data:
  131.                 if len(data) == 1:
  132.                     datai=data.pop(0)
  133.                     if diraff==direction:
  134.                         if datai.startswith("DERNIE"):
  135.                             output.append(40*' '+datai)
  136.                         elif datai.startswith("SERVIC"):
  137.                             output.append('       '+datai)
  138.                         else:
  139.                             output.append(8*' '+datai)
  140.                 if len(data) > 1:
  141.                     datatemp=data[0]
  142.                     if datatemp.startswith(" Direction"):
  143.                         ligne=0
  144.                         diraff=diraff+1
  145.                         stroutput = '%.30s ' % data.pop(0)
  146.                         stroutput = stroutput.center(50,'-').center(60)
  147.                         if diraff==direction:
  148.                             output.append('\n'+stroutput)
  149.                     elif datatemp.startswith("DERNIE"):
  150.                         datai=data.pop(0)
  151.                         if diraff==direction:
  152.                             output.append(40*' '+datai)
  153.                     else:
  154.                         i1=data.pop(0)
  155.                         i2=data.pop(0)
  156.                         if diraff==direction:
  157.                             if i1.startswith("INFO INDISP"):
  158.                                 print '        INFO INDISPONIBLE'
  159.                                 return []
  160.                             elif i1.startswith("SERVIC"):
  161.                                 output.append('       '+i1+' '+i2)
  162.                             else:
  163.                                 ligne=ligne+1
  164.                                 output.append('       Vers %-30.30s: %-16.16s' % (i1, i2))
  165.             print '\n'.join(output)
  166.         else:
  167.             print '-* Pas de donnees / Arret inconnu *-'.center(60)
  168.             print '\r'
  169.             raw_input('APPUYER SUR UNE TOUCHE POUR QUITTER')
  170.             return 1
  171.     print '\nCTRL-C pour Quitter'
  172.     return 0
  173.  
  174. def dispdirect(lid,args):
  175.     kwargs = dict(lineid=lid.upper(), station=' '.join(args), time=datetime.now().strftime('%H:%M:%S'))
  176.     header = 'A %(time)s - Ligne: %(lineid)s - Station: %(station)s' %kwargs
  177.     s=Service()
  178.     direction=0
  179.     if lid.upper().startswith('M'):
  180.         direct='AR'
  181.     else:
  182.         direct='A'
  183.     for directionsens in direct:
  184.         kwargs['reseau'] = kwargs.get('lineid')[0] == 'M' and 'metro' or 'bus'
  185.         kwargs['stationname'] = kwargs['station'].replace(' ', '+')
  186.         url = '/siv/schedule?service=next'
  187.         url += '&reseau=%(reseau)s&referer=station&lineid=%(lineid)s' % kwargs
  188.         url += '&directionsens=%s' % directionsens
  189.         url += '&stationname=%(stationname)s&submitAction=Valider' % kwargs
  190.         path=url
  191.         try:
  192.             resp = s.open(path)
  193.             s.headers['referer'] = 'http://www.ratp.fr%s' % path
  194.             data = resp.read()
  195.         except Exception, (errnum, errmsg) :
  196.             if errnum==10054:
  197.                 print '! Erreur de connexion a Internet'
  198.             elif errnum==11001:
  199.                 print '! Erreur de connexion reseau\n'
  200.             elif errnum==11003:
  201.                 print '! Erreur de connexion reseau\n'
  202.             elif errnum==11004:
  203.                 print '! Erreur de connexion reseau\n'
  204.             else:
  205.                 log.error('! Erreur numero: %r : %r \n', errnum, errmsg)
  206.             raw_input ('\nAPPUYER SUR UNE TOUCHE POUR QUITTER')
  207.             return 1
  208.         if 'body' in data:
  209.             data = data.split('<body>')[1]
  210.             data = data.replace('div', '\n')
  211.             data = data.replace('class="subtitle">Direction&nbsp;<b class="bwhite">', 'class="bg3"><b> Direction ')
  212.             data = data.replace('\n          &gt;&nbsp;', '<c>')
  213.             data = re.findall('.*class="(?:bg|schmsg|space)(?:[0-9]+)">(.*)', data)
  214.             data = [clean_html(d) for d in data if d[:3] in ('<b>')]
  215.         s.conn.close()
  216.         if data:
  217.             output = []
  218.             ligne=0
  219.             while data:
  220.                 if len(data) == 1:
  221.                     if data[0].startswith("DERNIE"):
  222.                         output.append(40*' '+data.pop())
  223.                     else:
  224.                         output.append(8*' '+data.pop())    
  225.                 if len(data) > 1:
  226.                     if data[0].startswith(" Direction"):
  227.                         stroutput = '%.50s ' % data.pop(0)
  228.                         direction = direction + 1
  229.                         print('\n '+str(direction)+' ) '+stroutput)
  230.                     else:
  231.                         data.pop(0)          
  232.         else:
  233.             print '-* Pas de donnees / Arret inconnu *-'.center(60)
  234.             print '\r'
  235.             raw_input('APPUYER SUR UNE TOUCHE POUR QUITTER')
  236.             return 1
  237.     return 0
  238.  
  239. def main():
  240.     parser = OptionParser()
  241.     parser.usage = '%prog -l <lineid> station name -d <direction>'
  242.     parser.add_option("-l", "--lineid", dest="lineid",
  243.                       action="append", default=[],
  244.                       help="pour Metro Mxx pour Bus Bxxx")
  245.     parser.add_option("-d", "--direction", dest="direction",
  246.                       action="append", default=["0"])
  247.     parser.add_option("-v", "--verbose", dest="verbose",
  248.                       action="count", default=0)
  249.     options, args = parser.parse_args()
  250.  
  251.     log.basicConfig(stream=sys.stdout, level=options.verbose and log.DEBUG or log.INFO,
  252.                     format='%(asctime)s %(message)s',
  253.                     datefmt='%H:%M:%S',
  254.                     )
  255.     os.system('title Horaires RATP')
  256.    
  257.     if not options.verbose:
  258.         os.system('mode 64,12')
  259.     if not args:
  260.         print 'Horaires RATP StandAlone v0.96\n'
  261.         try:
  262.             ligne=int(raw_input('Num. de ligne : '))
  263.         except ValueError:
  264.             print '\nMerci d\'entrer un nombre :\nEntre 1 et 14 pour le metro\nEntre 20 et 999 pour le bus\n'
  265.             raw_input ('APPUYER SUR UNE TOUCHE POUR QUITTER')
  266.             return
  267.         reseau='B'
  268.         arrsta='l\'arret'
  269.         if ligne < 15:
  270.             reseau='M'
  271.             arrsta='la station'
  272.         options.lineid=[reseau+str(ligne)]
  273.         station=raw_input('Nom de '+arrsta+': ')
  274.         args = [station]
  275.         if not options.verbose:
  276.             os.system('cls')
  277.         retu = dispdirect(options.lineid[0], args)
  278.         if retu>0:
  279.             return
  280.         choixdir=raw_input('\nDirection (1 ou 2): ')
  281.         options.direction=['0',choixdir]
  282.        
  283.  
  284.     while True:
  285.         if not options.verbose:
  286.             os.system('cls')
  287.         if options.direction[1].__len__()>1:
  288.             print '\nMerci d\'entrer 1 ou 2 pour indiquer la direction\n'
  289.             raw_input('APPUYER SUR UNE TOUCHE POUR QUITTER')
  290.             return
  291.         if ord(options.direction[1])-48>2:
  292.             print '\nMerci d\'entrer 1 ou 2 pour indiquer la direction\n'
  293.             raw_input('APPUYER SUR UNE TOUCHE POUR QUITTER')
  294.             return
  295.         try:
  296.             for lid in options.lineid:
  297.                 retu = dispinfo(lid,args,ord(options.direction[1])-48)
  298.                 if retu>0:
  299.                     return
  300.             time.sleep(12)  
  301.         except KeyboardInterrupt:
  302.             print '\r'
  303.             return
  304.         except Exception, (errnum, errmsg) :
  305.             if errnum==10054:
  306.                 print '! Erreur de connexion a Internet'
  307.             elif errnum==11001:
  308.                 print '! Erreur de connexion reseau\n'
  309.             elif errnum==11003:
  310.                 print '! Erreur de connexion reseau\n'
  311.             elif errnum==11004:
  312.                 print '! Erreur de connexion reseau\n'
  313.             else:
  314.                 log.error('! Erreur numero: %r : %r \n', errnum, errmsg)          
  315.             raw_input ('\nAPPUYER SUR UNE TOUCHE POUR QUITTER')
  316.             return
  317.        
  318. if __name__ == '__main__':
  319.     main()