From 2e8f5023eb91736ec39c6be3165834ff13cc7729 Mon Sep 17 00:00:00 2001 From: Bezleputh Date: Fri, 4 Sep 2015 15:42:49 +0200 Subject: [PATCH] [blablacar] New CapTravel module that helps to find available trips on blablacar website --- modules/blablacar/__init__.py | 24 +++++++++++ modules/blablacar/browser.py | 49 +++++++++++++++++++++++ modules/blablacar/module.py | 44 ++++++++++++++++++++ modules/blablacar/pages.py | 75 +++++++++++++++++++++++++++++++++++ modules/blablacar/test.py | 30 ++++++++++++++ 5 files changed, 222 insertions(+) create mode 100644 modules/blablacar/__init__.py create mode 100644 modules/blablacar/browser.py create mode 100644 modules/blablacar/module.py create mode 100644 modules/blablacar/pages.py create mode 100644 modules/blablacar/test.py diff --git a/modules/blablacar/__init__.py b/modules/blablacar/__init__.py new file mode 100644 index 00000000..2a00b43a --- /dev/null +++ b/modules/blablacar/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2015 Bezleputh +# +# This file is part of weboob. +# +# weboob is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# weboob is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with weboob. If not, see . + + +from .module import BlablacarModule + + +__all__ = ['BlablacarModule'] diff --git a/modules/blablacar/browser.py b/modules/blablacar/browser.py new file mode 100644 index 00000000..0c520628 --- /dev/null +++ b/modules/blablacar/browser.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2015 Bezleputh +# +# This file is part of weboob. +# +# weboob is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# weboob is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with weboob. If not, see . + + +from weboob.browser import PagesBrowser, URL + +from .pages import DeparturesPage + +from datetime import datetime +import urllib + + +class BlablacarBrowser(PagesBrowser): + BASEURL = 'https://www.blablacar.fr' + + departures = URL('/search_xhr\?(?P.*)', DeparturesPage) + + def get_roadmap(self, departure, arrival, filters): + pass + + def get_station_departures(self, station_id, arrival_id, date): + query = {'fn': station_id} + if arrival_id: + query['tn'] = arrival_id + + if date: + _date = datetime.strftime(date, "%d/%m/%Y") + query['db'] = _date + _heure = datetime.strftime(date, "%H") + query['hb'] = _heure + query['he'] = '24' + + return self.departures.open(qry=urllib.urlencode(query)).get_station_departures() diff --git a/modules/blablacar/module.py b/modules/blablacar/module.py new file mode 100644 index 00000000..37cad489 --- /dev/null +++ b/modules/blablacar/module.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2015 Bezleputh +# +# This file is part of weboob. +# +# weboob is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# weboob is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with weboob. If not, see . + + +from weboob.tools.backend import Module +from weboob.capabilities.travel import CapTravel + +from .browser import BlablacarBrowser + + +__all__ = ['BlablacarModule'] + + +class BlablacarModule(Module, CapTravel): + NAME = 'blablacar' + DESCRIPTION = u'blablacar website' + MAINTAINER = u'Bezleputh' + EMAIL = 'carton_ben@yahoo.fr' + LICENSE = 'AGPLv3+' + VERSION = '1.1' + + BROWSER = BlablacarBrowser + + def iter_roadmap(self, departure, arrival, filters): + return self.browser.get_roadmap(departure, arrival, filters) + + def iter_station_departures(self, station_id, arrival_id, date): + return self.browser.get_station_departures(station_id, arrival_id, date) diff --git a/modules/blablacar/pages.py b/modules/blablacar/pages.py new file mode 100644 index 00000000..4d589cdd --- /dev/null +++ b/modules/blablacar/pages.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2015 Bezleputh +# +# This file is part of weboob. +# +# weboob is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# weboob is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with weboob. If not, see . + +from weboob.capabilities.travel import Departure +from weboob.browser.filters.standard import CleanText, Format, Regexp, CleanDecimal +from weboob.browser.filters.html import Link +from weboob.browser.elements import ListElement, ItemElement, method +from weboob.browser.pages import JsonPage +from weboob.capabilities.base import Currency + +from io import StringIO +import lxml.html as html +from datetime import datetime + + +class DeparturesPage(JsonPage): + + ENCODING = None + + def __init__(self, browser, response, *args, **kwargs): + super(DeparturesPage, self).__init__(browser, response, *args, **kwargs) + self.encoding = self.ENCODING or response.encoding + parser = html.HTMLParser(encoding=self.encoding) + if 'results' in self.doc['html']: + self.doc = html.parse(StringIO(self.doc['html']['results']), parser) + else: + self.doc = html.Element('brinbrin') + + @method + class get_station_departures(ListElement): + item_xpath = '//ul[@class="trip-search-results"]/li/a' + + class item(ItemElement): + klass = Departure + + obj_id = Regexp(Link('.'), '/(.*)') + + def obj_time(self): + _date = CleanText('./article/div/h3[@itemprop="startDate"]/@content')(self).split('-') + _time = Regexp(CleanText('./article/div/h3[@itemprop="startDate"]'), + u'.* à (\d+)h')(self) + return datetime(int(_date[0]), int(_date[1]), int(_date[2]), int(_time), 0) + + obj_type = Format('%s (%s)', + CleanText('./article/div/dl[@class="car-type"]/dt/strong'), + CleanText('./article/div/dl[@class="car-type"]/dd/span/@title')) + + obj_departure_station = CleanText('./article/div/dl[@class="geo-from"]/dd', + replace=[(": voir avec le conducteur", "")]) + obj_arrival_station = CleanText('./article/div/dl[@class="geo-to"]/dd', + replace=[(": voir avec le conducteur", "")]) + + obj_price = CleanDecimal(CleanText('./article/div/div[@itemprop="location"]/strong/span[last()]')) + + def obj_currency(self): + txt = CleanText('./article/div/div[@itemprop="location"]')(self) + return Currency.get_currency(txt) + + obj_information = CleanText('./article/div/div[@class="availability"]') diff --git a/modules/blablacar/test.py b/modules/blablacar/test.py new file mode 100644 index 00000000..957efcae --- /dev/null +++ b/modules/blablacar/test.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2015 Bezleputh +# +# This file is part of weboob. +# +# weboob is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# weboob is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with weboob. If not, see . + + +from weboob.tools.test import BackendTest +from datetime import datetime + + +class BlablacarTest(BackendTest): + MODULE = 'blablacar' + + def test_blablacar(self): + departures = list(self.backend.iter_station_departures('lille', 'lens', datetime.now())) + self.assertTrue(len(departures) > 0)