source.py 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. from class_xml import XML
  2. import config
  3. import datetime
  4. # SOURCE CLASSES
  5. class Source:
  6. def __init__(self):
  7. pass
  8. class Source_ratp(Source):
  9. def __init__(self, ident, status, message):
  10. self.source = 'ratp_trafic'
  11. self.id = ident
  12. self.status = status
  13. self.message = message
  14. def problem(self):
  15. return self.status != 'normal'
  16. class Source_jcdecaux_vls_full(Source):
  17. def __init__(self, ident, nom, timestamp, places, status):
  18. self.source = 'jcdecaux_vls'
  19. self.id = ident + "_full"
  20. self.places = int(places)
  21. self.status = status # TODO dans l'API pour 1 station il semble que c'est toujours OPEN :-(
  22. date = datetime.datetime.fromtimestamp(int(timestamp)/1000).strftime('à %Hh%M le %d/%m')
  23. if(status != "OPEN"):
  24. self.message = 'Station vélo ' + nom.lower() + ' ' + date + ' : fermée !'
  25. else:
  26. self.message = 'Station vélo ' + nom.lower() + ' ' + date + ' : plus que ' + places + ' places disponibles !'
  27. def problem(self):
  28. return self.status != "OPEN" or self.places <= 4 # TODO config
  29. class Source_jcdecaux_vls_empty(Source):
  30. def __init__(self, ident, nom, timestamp, bikes, status):
  31. self.source = 'jcdecaux_vls'
  32. self.id = ident + "_empty"
  33. self.bikes = int(bikes)
  34. self.status = status # TODO dans l'API pour 1 station il semble que c'est toujours OPEN :-(
  35. date = datetime.datetime.fromtimestamp(int(timestamp)/1000).strftime('à %Hh%M le %d/%m')
  36. if(status != "OPEN"):
  37. self.message = 'Station vélo ' + nom.lower() + ' ' + date + ' : fermée !'
  38. else:
  39. self.message = 'Station vélo ' + nom.lower() + ' ' + date + ' : plus que ' + bikes + ' vélos !'
  40. def problem(self):
  41. return self.status != "OPEN" or self.bikes <= 4 # TODO config
  42. class Source_transilien(Source):
  43. def __init__(self, ident, message):
  44. self.source = 'transilien'
  45. self.id = ident
  46. self.message = message
  47. def problem(self):
  48. return self.message != 'Trafic normal'
  49. # SOURCES GENERATORS
  50. def ratp_trafic():
  51. for tag in XML(url="http://www.ratp.fr/meteo/", lang="html").data.select('div.encadre_ligne'):
  52. yield Source_ratp(tag['id'], tag.img['alt'], tag.select('span.perturb_message')[0].string)
  53. def jcdecaux_vls():
  54. ids = set(map(lambda s : s.split('_')[0], config.sources['jcdecaux_vls']))
  55. for station in ids:
  56. xml = XML(url="https://api.jcdecaux.com/vls/v1/stations/" + station + "?contract=paris&apiKey="+config.api_key['jcdecaux'], lang="json")
  57. tag = xml.data.json
  58. yield Source_jcdecaux_vls_full(tag.number.string, tag.find('name').string, tag.last_update.string, tag.available_bike_stands.string, tag.status.string)
  59. yield Source_jcdecaux_vls_empty(tag.number.string, tag.find('name').string, tag.last_update.string, tag.available_bikes.string, tag.status.string)
  60. def transilien():
  61. xml = XML(url="http://www.transilien.com/info-trafic/temps-reel", lang="html").data
  62. container = xml.select('div.b_info_trafic')[0]
  63. for line in container.find_all('div', recursive=False):
  64. id = line.select('.picto-transport')[1].get_text()
  65. message = ""
  66. for c in line.select_one('.title').children:
  67. if c.name: # a tag
  68. if 'picto-transport' not in c.attrs.get('class', ''):
  69. message += c.get_text()
  70. else: # a string
  71. message += c
  72. for det in line.select('.item-disruption'): # I think 0 or 1 elements
  73. message += det.get_text()
  74. message = " ".join(message.split()) # delete multiple spaces
  75. yield Source_transilien(id, message)