diff --git a/modules/champslibres/__init__.py b/modules/champslibres/__init__.py new file mode 100644 index 00000000..1646af73 --- /dev/null +++ b/modules/champslibres/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2010-2011 Jeremy Monnet +# +# 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 .backend import ChampslibresBackend + +__all__ = ['ChampslibresBackend'] diff --git a/modules/champslibres/backend.py b/modules/champslibres/backend.py new file mode 100644 index 00000000..422416b9 --- /dev/null +++ b/modules/champslibres/backend.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2010-2012 Florent Fourcot +# +# 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.library import ICapBook +from weboob.tools.backend import BaseBackend, BackendConfig +from weboob.tools.value import ValueBackendPassword, Value + +from .browser import ChampslibresBrowser + + +__all__ = ['ChampslibresBackend'] + + +class ChampslibresBackend(BaseBackend, ICapBook): + NAME = 'champslibres' + MAINTAINER = u'Florent Fourcot' + EMAIL = 'weboob@flo.fourcot.fr' + VERSION = '0.c' + DESCRIPTION = 'Champs Libres (Rennes) Library' + LICENSE = 'AGPLv3+' + CONFIG = BackendConfig(Value('login', label='Account ID', regexp='^\d{1,15}|$'), + ValueBackendPassword('password', label='Password of account'), + ) + BROWSER = ChampslibresBrowser + + def create_default_browser(self): + return self.create_browser(self.config['login'].get(), + self.config['password'].get()) + + def get_rented(self): + for book in self.browser.get_rented_books_list(): + yield book + + def get_booked(self): + raise NotImplementedError() + + def iter_books(self): + #for book in self.get_booked(): + # yield book + for book in self.get_rented(): + yield book + + def get_book(self, _id): + raise NotImplementedError() + + def search_books(self, _string): + raise NotImplementedError() diff --git a/modules/champslibres/browser.py b/modules/champslibres/browser.py new file mode 100644 index 00000000..a9b4d71b --- /dev/null +++ b/modules/champslibres/browser.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2010-2012 Florent Fourcot +# +# 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.browser import BaseBrowser, BrowserIncorrectPassword + +from .pages import LoginPage, HomePage, HistoryPage, RentedPage + + +__all__ = ['ChampslibresBrowser'] + + +# Browser +class ChampslibresBrowser(BaseBrowser): + PROTOCOL = 'http' + ENCODING = None + PAGES = { + '.*login.*': LoginPage, + '.*home\?lang=frf.*': HomePage, + 'http://.*/index.aspx\?IdPage=429': HistoryPage, + '.*patroninfo.*': RentedPage, + } + + def __init__(self, *args, **kwargs): + BaseBrowser.__init__(self, *args, **kwargs) + + def is_logged(self): + + return self.page \ + and not self.page.document.getroot().xpath('//input[contains(@id, "pin")]') + + def login(self): + assert isinstance(self.username, basestring) + assert isinstance(self.password, basestring) + if not self.is_on_page(HomePage): + self.location('https://sbib.si.leschampslibres.fr/iii/cas/login?null', no_login=True) + self.page.login(self.username, self.password) + if not self.is_logged(): + raise BrowserIncorrectPassword() + # Get home and get ID + self.location('http://opac.si.leschampslibres.fr/iii/encore/home?lang=frf') + self.id = self.page.get_id() + self.logger.debug('Get ID ' + self.id) + + def get_rented_books_list(self): + if not self.is_on_page(RentedPage): + self.location('https://sbib.si.leschampslibres.fr/patroninfo~S1*frf/1123477/items') + return self.page.get_list() + + # TODO + def get_booked_books_list(self): + return [] diff --git a/modules/champslibres/favicon.png b/modules/champslibres/favicon.png new file mode 100644 index 00000000..beb49765 Binary files /dev/null and b/modules/champslibres/favicon.png differ diff --git a/modules/champslibres/pages.py b/modules/champslibres/pages.py new file mode 100644 index 00000000..e1c203c3 --- /dev/null +++ b/modules/champslibres/pages.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2012 Florent Fourcot +# +# 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 datetime import date +from weboob.capabilities.library import Book +from weboob.tools.browser import BasePage + + +class SkipPage(BasePage): + pass + + +class HomePage(BasePage): + def on_loaded(self): + link = self.document.find('//a[@id="patronRSSFeedLinkComponent"]') + self.id = link.attrib['href'].split('/')[4] + + def get_id(self): + return self.id + + +def txt2date(s): + split = s.split('-') + return date(int(split[2]) + 2000, int(split[1]), int(split[0])) + + +class RentedPage(BasePage): + def get_list(self): + for tr in self.document.getroot().xpath('//tr[@class="patFuncEntry"]'): + id = tr.xpath('td/input')[0].attrib["value"] + book = Book(id) + bigtitle = tr.xpath('td[@class="patFuncTitle"]/label/a')[0].text + book.name = bigtitle.split('/')[0] + book.author = bigtitle.split('/')[1] + date = tr.xpath('td[@class="patFuncStatus"]')[0].text + book.date = txt2date(date.replace('RETOUR', '')) + yield book + + +class HistoryPage(BasePage): + pass + + +class BookedPage(BasePage): + # TODO: book some books... + pass + + +class LoginPage(BasePage): + def login(self, login, passwd): + self.browser.select_form(nr=0) + self.browser.form.set_all_readonly(False) + self.browser['code'] = login + self.browser['pin'] = passwd + self.browser.submit() diff --git a/modules/champslibres/test.py b/modules/champslibres/test.py new file mode 100644 index 00000000..a79174b0 --- /dev/null +++ b/modules/champslibres/test.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2010-2011 Jeremy Monnet +# +# 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 + + +class ChampslibresTest(BackendTest): + BACKEND = 'champslibres' + + def test_champslibres(self): + pass