From da1369ef7b768868e9dd0ff761da95853c54bc81 Mon Sep 17 00:00:00 2001 From: Romain Bignon Date: Sat, 13 Feb 2010 18:00:09 +0100 Subject: [PATCH] imported aum as a backend --- weboob/backends/aum/__init__.py | 1 + weboob/backends/aum/adopte.py | 215 ++++++++++ weboob/backends/aum/exceptions.py | 30 ++ weboob/backends/aum/mail.py | 69 +++ weboob/backends/aum/pages/__init__.py | 0 weboob/backends/aum/pages/base.py | 96 +++++ weboob/backends/aum/pages/baskets.py | 26 ++ weboob/backends/aum/pages/contact_list.py | 117 +++++ weboob/backends/aum/pages/contact_thread.py | 314 ++++++++++++++ weboob/backends/aum/pages/edit.py | 58 +++ weboob/backends/aum/pages/home.py | 55 +++ weboob/backends/aum/pages/login.py | 81 ++++ weboob/backends/aum/pages/profile.py | 405 ++++++++++++++++++ .../backends/aum/pages/profileslist_base.py | 50 +++ weboob/backends/aum/pages/search.py | 54 +++ weboob/backends/aum/pages/wait.py | 39 ++ weboob/backends/dlfp/browser.py | 2 +- weboob/backends/dlfp/feeds.py | 1 + weboob/tools/browser.py | 1 + 19 files changed, 1613 insertions(+), 1 deletion(-) create mode 100644 weboob/backends/aum/__init__.py create mode 100644 weboob/backends/aum/adopte.py create mode 100644 weboob/backends/aum/exceptions.py create mode 100644 weboob/backends/aum/mail.py create mode 100644 weboob/backends/aum/pages/__init__.py create mode 100644 weboob/backends/aum/pages/base.py create mode 100644 weboob/backends/aum/pages/baskets.py create mode 100644 weboob/backends/aum/pages/contact_list.py create mode 100644 weboob/backends/aum/pages/contact_thread.py create mode 100644 weboob/backends/aum/pages/edit.py create mode 100644 weboob/backends/aum/pages/home.py create mode 100644 weboob/backends/aum/pages/login.py create mode 100644 weboob/backends/aum/pages/profile.py create mode 100644 weboob/backends/aum/pages/profileslist_base.py create mode 100644 weboob/backends/aum/pages/search.py create mode 100644 weboob/backends/aum/pages/wait.py diff --git a/weboob/backends/aum/__init__.py b/weboob/backends/aum/__init__.py new file mode 100644 index 00000000..399b414f --- /dev/null +++ b/weboob/backends/aum/__init__.py @@ -0,0 +1 @@ +from adopte import AdopteUnMec diff --git a/weboob/backends/aum/adopte.py b/weboob/backends/aum/adopte.py new file mode 100644 index 00000000..98482683 --- /dev/null +++ b/weboob/backends/aum/adopte.py @@ -0,0 +1,215 @@ +# -*- coding: utf-8 -*- + +""" +Copyright(C) 2008-2010 Romain Bignon + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 3 of the License. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +""" + +import time +from logging import warning + +from weboob.tools.browser import Browser +from weboob.backends.aum.exceptions import AdopteWait + +from weboob.backends.aum.pages.home import HomePage +from weboob.backends.aum.pages.contact_list import ContactListPage +from weboob.backends.aum.pages.contact_thread import ContactThreadPage +from weboob.backends.aum.pages.baskets import BasketsPage +from weboob.backends.aum.pages.profile import ProfilePage +from weboob.backends.aum.pages.search import SearchPage +from weboob.backends.aum.pages.login import LoginPage, RedirectPage, BanPage, ErrPage, RegisterPage, RegisterWaitPage, RegisterConfirmPage +from weboob.backends.aum.pages.edit import EditPhotoPage, EditPhotoCbPage, EditAnnouncePage, EditDescriptionPage, EditSexPage, EditPersonalityPage +from weboob.backends.aum.pages.wait import WaitPage + +class AdopteUnMec(Browser): + DOMAIN = 'www.adopteunmec.com' + PROTOCOL = 'http' + PAGES = {'http://www.adopteunmec.com/': LoginPage, + 'http://www.adopteunmec.com/index.html': LoginPage, + 'http://www.adopteunmec.com/index.php': LoginPage, + 'http://www.adopteunmec.com/loginErr.php.*': ErrPage, + 'http://www.adopteunmec.com/bans.php\?who=auto': BanPage, + 'http://www.adopteunmec.com/redirect.php\?action=login': RedirectPage, + 'http://www.adopteunmec.com/wait.php': WaitPage, + 'http://www.adopteunmec.com/register2.php': RegisterPage, + 'http://www.adopteunmec.com/register3.php.*': RegisterWaitPage, + 'http://www.adopteunmec.com/register4.php.*': RegisterConfirmPage, + 'http://www.adopteunmec.com/home.php': HomePage, + 'http://www.adopteunmec.com/mails.php': ContactListPage, + 'http://www.adopteunmec.com/mails.php\?type=1': BasketsPage, + 'http://www.adopteunmec.com/thread.php\?id=([0-9]+)': ContactThreadPage, + 'http://www.adopteunmec.com/edit.php\?type=1': EditPhotoPage, + 'http://s\d+.adopteunmec.com/upload2.php\?.*': EditPhotoCbPage, + 'http://www.adopteunmec.com/edit.php\?type=2': EditAnnouncePage, + 'http://www.adopteunmec.com/edit.php\?type=3': EditDescriptionPage, + 'http://www.adopteunmec.com/edit.php\?type=4': EditSexPage, + 'http://www.adopteunmec.com/edit.php\?type=5': EditPersonalityPage, + 'http://www.adopteunmec.com/search.php.*': SearchPage, + 'http://www.adopteunmec.com/rencontres-femmes/(.*)/([0-9]+)': ProfilePage, + 'http://www.adopteunmec.com/catalogue-hommes/(.*)/([0-9]+)': ProfilePage, + 'http://www.adopteunmec.com/view2.php': ProfilePage, # my own profile + 'http://www.adopteunmec.com/(\w+)': ProfilePage, # a custom profile url + } + + def login(self): + if not self.isOnPage(LoginPage): + self.home() + self.page.login(self.username, self.password) + + def isLogged(self): + return not self.isOnPage(LoginPage) + + def home(self): + return self.location('http://www.adopteunmec.com/home.php') + + def pageaccess(func): + def inner(self, *args, **kwargs): + if self.isOnPage(WaitPage): + if not self.page.check(): + raise AdopteWait() + self.home() + if not self.page or self.isOnPage(LoginPage) and self.password: + self.home() + + return func(self, *args, **kwargs) + return inner + + def register(self, nickname, password, sex, birthday_d, birthday_m, birthday_y, zipcode, country, godfather=''): + if not self.isOnPage(RegisterPage): + self.location('http://www.adopteunmec.com/register2.php') + + return self.page.register(nickname, password, sex, birthday_d, birthday_m, birthday_y, zipcode, country, godfather) + + @pageaccess + def addPhoto(self, name, f): + if not self.isOnPage(EditPhotoPage): + self.location('/edit.php?type=1') + return self.page.addPhoto(name, f) + + @pageaccess + def setNickname(self, nickname): + if not self.isOnPage(EditAnnouncePage): + self.location('/edit.php?type=2') + return self.page.setNickname(nickname) + + @pageaccess + def setAnnounce(self, title=None, description=None, lookingfor=None): + if not self.isOnPage(EditAnnouncePage): + self.location('/edit.php?type=2') + return self.page.setAnnounce(title, description, lookingfor) + + @pageaccess + def score(self): + if time.time() - self.__last_update > 60: + self.home() + return self.page.score() + + @pageaccess + def getMyName(self): + if time.time() - self.__last_update > 60: + self.home() + return self.page.getMyName() + + @pageaccess + def getMyID(self): + if not self.isOnPage(HomePage): + self.home() + return self.page.getMyID() + + @pageaccess + def nbNewMails(self): + if time.time() - self.__last_update > 60: + self.home() + return self.page.nbNewMails() + + @pageaccess + def nbNewBaskets(self): + if time.time() - self.__last_update > 60: + self.home() + return self.page.nbNewBaskets() + + @pageaccess + def nbNewVisites(self): + if time.time() - self.__last_update > 60: + self.home() + return self.page.nbNewVisites() + + @pageaccess + def nbAvailableCharms(self): + self.home() + return self.page.nbAvailableCharms() + + @pageaccess + def getBaskets(self): + self.location('/mails.php?type=1') + return self.page.getProfilesIDsList() + + @pageaccess + def getContactList(self): + if not self.isOnPage(ContactListPage): + self.location('/mails.php') + + return self.page.getContactList() + + @pageaccess + def getThreadMails(self, id): + self.page.openThreadPage(id) + return self.page.getMails() + + @pageaccess + def postMail(self, id, content): + self.page.openThreadPage(id) + self.page.post(content) + + @pageaccess + def sendCharm(self, id): + result = self.openurl('http://www.adopteunmec.com/fajax_addBasket.php?id=%s' % id).read() + warning('Charm: %s' % result) + return result.find('noMoreFlashes') < 0 + + @pageaccess + def addBasket(self, id): + result = self.openurl('http://www.adopteunmec.com/fajax_addBasket.php?id=%s' % id).read() + warning('Basket: %s' % result) + # TODO check if it works (but it should) + return True + + @pageaccess + def rate(self, id, what, rating): + print 'rate "%s"' % id, what, rating + result = self.openurl('http://www.adopteunmec.com/fajax_vote.php', 'member=%s&what=%s&rating=%s' % (id, what, rating)).read() + print result + return True + + @pageaccess + def searchProfiles(self, **kwargs): + self.location('/search.php?display=1') + self.page.search(**kwargs) + return self.page.getProfilesIDs() + + @pageaccess + def getProfile(self, link): + if isinstance(link, (str,unicode)) and link.startswith('/'): + link = link[1:] + self.location('/%s' % link) + return self.page + + @pageaccess + def isSlutOnline(self, id): + result = self.openurl('http://www.adopteunmec.com/%s' % id).read() + r = result.find('en ligne') >= 0 + print 'isSlutOnline(%s) = %s' % (id, r) + return r diff --git a/weboob/backends/aum/exceptions.py b/weboob/backends/aum/exceptions.py new file mode 100644 index 00000000..f620a6d1 --- /dev/null +++ b/weboob/backends/aum/exceptions.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- + +""" +Copyright(C) 2008-2010 Romain Bignon + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 3 of the License. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +""" + +from weboob.tools.browser import BrowserUnavailable + +class AdopteWait(BrowserUnavailable): + pass + +class AdopteBanned(BrowserUnavailable): + pass + +class AdopteCantPostMail(Exception): + pass diff --git a/weboob/backends/aum/mail.py b/weboob/backends/aum/mail.py new file mode 100644 index 00000000..c42940ee --- /dev/null +++ b/weboob/backends/aum/mail.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- + +""" +Copyright(C) 2008 Romain Bignon + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 3 of the License. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +""" + +import time +import datetime + +class Mail: + + def __init__(self, id, name): + self.id = id + self.reply_date = 0 + self.name = name + self.sender = name + self.profile_link = '' + + self.new = False + self.content = '' + self.date = datetime.datetime.utcnow() + + def getDateInt(self): + return int(time.strftime('%Y%m%d%H%M%S', self.getDate().timetuple())) + + def getMsgID(self, sender): + return '<%s.%d@%s>' % (self.getDateInt(), self.id, sender) + + def getReplyID(self, sender): + if self.reply_date: + return '<%s.%d@%s>' % (self.reply_date, self.id, sender) + else: + return '' + + def getID(self): + return self.id + + def getName(self): + return self.name + + def getDate(self): + return self.date + + def getProfileLink(self): + return self.profile_link + + def getFrom(self): + return self.sender + + def getContent(self): + return self.content + + def isNew(self): + return self.new + diff --git a/weboob/backends/aum/pages/__init__.py b/weboob/backends/aum/pages/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/weboob/backends/aum/pages/base.py b/weboob/backends/aum/pages/base.py new file mode 100644 index 00000000..5e5788b3 --- /dev/null +++ b/weboob/backends/aum/pages/base.py @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- + +""" +Copyright(C) 2008-2010 Romain Bignon + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 3 of the License. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +""" + +import re +from logging import error, warning +from weboob.tools.browser import BasePage + +class PageBase(BasePage): + def openContactListPage(self): + self.browser.follow_link(url_regex=r"/mails.php$") + + def openThreadPage(self, id): + self.browser.location('/thread.php?id=%d' % int(id)) + + def score(self): + """ + + + + + +
popularité7.230 pts
+ """ + + l = self.document.getElementsByTagName('table') + for tag in l: + if tag.getAttribute('width') == '220': + # + + + + + + + + + + + + + + """ + + fields = ['thread_link', 'photo', 'useless3', 'name', 'resume', 'status', 'useless', 'remove', 'useless2'] + + def __init__(self, tr): + self.tr = tr + + def __get_element(self, id): + + return self.tr.getElementsByTagName('td')[self.fields.index(id)] + + def getName(self): + tag = self.__get_element('name') + node = tag.getElementsByTagName('b')[0].firstChild + if node: + name = node.data + else: + # it is possible if the user has left site and hasn't any nickname + name = '' + + return name + + def getStatus(self): + + tag = self.__get_element('status') + + return tag.firstChild.data + + def isNew(self): + return self.getStatus() == u'nouveau' + + def isAnswered(self): + return self.getStatus() == u'répondu' + + def getResume(self): + tag = self.__get_element('resume') + + return tag.getElementsByTagName('b')[0].firstChild.data.split('\n')[0] + + def getID(self): + tag = self.__get_element('thread_link') + + text = tag.getAttribute('onclick') + + regexp = re.compile("window.location='/thread.php\?id=(.*)'") + m = regexp.match(text) + + if m: + return int(m.group(1)) + + return 0 + + +class ContactListPage(PageBase): + + def loaded(self): + + self.items = [] + + tags = self.document.getElementsByTagName('form')[0].childNodes[3].childNodes[1].childNodes + + for tag in tags: + if not hasattr(tag, 'tagName') or tag.tagName != u'tr': + continue + + if tag.hasAttribute('bgcolor'): + continue + + self.items += [ContactItem(tag)] + + def getContactList(self): + return self.items diff --git a/weboob/backends/aum/pages/contact_thread.py b/weboob/backends/aum/pages/contact_thread.py new file mode 100644 index 00000000..24da645f --- /dev/null +++ b/weboob/backends/aum/pages/contact_thread.py @@ -0,0 +1,314 @@ +# -*- coding: utf-8 -*- + +""" +Copyright(C) 2008-2010 Romain Bignon + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 3 of the License. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +""" + +import re +from datetime import datetime +from dateutil import tz +from logging import error, warning +from mechanize import FormNotFoundError + +from weboob.backends.aum.pages.base import PageBase +from weboob.backends.aum.exceptions import AdopteCantPostMail +from weboob.backends.aum.mail import Mail + +class MailParser(Mail): + + """ + + """ + + DATETIME_REGEXP = re.compile(u'([0-9]{1,2}) ([a-zéû]*) ([0-9]{4}), ([0-9]{2}):([0-9]{2}):([0-9]{2})(.*)') + months = [u'', u'janvier', u'février', u'mars', u'avril', u'mai', u'juin', u'juillet', u'août', u'septembre', u'octobre', u'novembre', u'décembre'] + SMILEY_REGEXP = re.compile('http://s.adopteunmec.com/img/smile/([0-9]+).gif') + smileys = {0: ':)', + 1: ':D', + 2: ':o', + 3: ':p', + 4: ';)', + 5: ':(', + 6: ':$', + 7: ':\'(', + 11: ':#', + 14: ':\\', + 15: ':|', + 10: '(L)', + } + + def __init__(self, id, name, tr): + #
+ child = tag.childNodes[1].childNodes[0].childNodes[3] + return child.childNodes[0].childNodes[0].data + + error("Error: I can't find the score :(") + return '0' + + def __get_indicator(self, elementName): + """ 1 """ + + l = self.document.getElementsByTagName('span') + for tag in l: + if tag.getAttribute('id') == elementName: + child = tag.childNodes[0] + + if not hasattr(child, 'data'): + if child.tagName != u'blink': + warning("Warning: %s counter isn't a blink and hasn't data" % elementName) + child = child.childNodes[0] + if not hasattr(child, 'data'): + break + + return int(child.data) + + error("Error: I can't find the %s counter :(" % elementName) + return 0 + + MYNAME_REGEXP = re.compile("Bonjour (.*)") + def getMyName(self): + """ Bonjour Romain """ + + tags = self.document.getElementsByTagName('span') + for tag in tags: + if hasattr(tag.firstChild, 'data'): + m = self.MYNAME_REGEXP.match(tag.firstChild.data) + if m: + return m.group(1) + + warning('Warning: Unable to fetch name') + return '?' + + def nbNewMails(self): + + return self.__get_indicator(u'mailsCounter') + + def nbNewBaskets(self): + + return self.__get_indicator(u'flashsCounter') + + def nbNewVisites(self): + + return self.__get_indicator(u'visitesCounter') diff --git a/weboob/backends/aum/pages/baskets.py b/weboob/backends/aum/pages/baskets.py new file mode 100644 index 00000000..8f6570d8 --- /dev/null +++ b/weboob/backends/aum/pages/baskets.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +""" +Copyright(C) 2008 Romain Bignon + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 3 of the License. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +""" + +from weboob.backends.aum.pages.profileslist_base import ProfilesListBase + +class BasketsPage(ProfilesListBase): + + pass + diff --git a/weboob/backends/aum/pages/contact_list.py b/weboob/backends/aum/pages/contact_list.py new file mode 100644 index 00000000..3944c6b6 --- /dev/null +++ b/weboob/backends/aum/pages/contact_list.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- + +""" +Copyright(C) 2008 Romain Bignon + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 3 of the License. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +""" + +import re + +from weboob.backends.aum.pages.base import PageBase + +class ContactItem: + u""" +
+
 
+
Hen
+ 19ans, Montreuil
Comme ça, on est deux.
+ il y a 1 heure
nouveau     +  
+ + + + + + + +
+ + + + + + + + +
+ + + + + + + + + + + + + +
+ + +
Romain
+
+
+

27 octobre 2008, 01:11:32, nouveau +
+

+
Moi en g�n�ral j'aime sortir tout simplement dans des bars, pour discuter avec mes amis et/ou coll�gues, et rencontrer des gens. Sinon je fais de la guitare, et je d�veloppe des projets perso.

+
+
+
implicit + Mail.__init__(self, id, name) + self.tr = tr.childNodes[0].childNodes[1].childNodes[0].childNodes[0] + + tds = self.tr.childNodes + + counter = 0 + for td in tds: + if not hasattr(td, 'tagName') or td.tagName != u'td': + continue + + counter += 1 + + if counter == 3: + date = u'' + for child in td.childNodes[1].childNodes: + if hasattr(child, 'data'): + date += child.data + self.parseDate(date) + content = '' + for c in td.childNodes[3].childNodes: + if hasattr(c, 'data'): + content += ''.join(c.data.split('\n')) # to strip \n + elif hasattr(c, 'tagName'): + if c.tagName == 'br': + content += '\n' + elif c.tagName == 'img' and c.hasAttribute('src'): + m = self.SMILEY_REGEXP.match(c.getAttribute('src')) + if m and self.smileys.has_key(int(m.group(1))): + try: + content += self.smileys[int(m.group(1))] + except KeyError: + error('Mail: unable to find this smiley: %s' % c.getAttribute('src')) + self.content = content + break + + self.parseProfileLink() + self.parseFrom() + + def parseDate(self, date_str): + + + # To match regexp, we have to remove any return chars in string + # before the status ('nouveau', 'lu', etc) + date_str = u''.join(date_str.split(u'\n')) + + m = self.DATETIME_REGEXP.match(date_str) + if m: + day = int(m.group(1)) + month = self.months.index(m.group(2)) + year = int(m.group(3)) + hour = int(m.group(4)) + minute = int(m.group(5)) + sec = int(m.group(6)) + # build datetime object with local timezone + d = datetime(year, month, day, hour, minute, sec, tzinfo=tz.tzlocal()) + # then, convert it to UTC timezone + d = d.astimezone(tz.tzutc()) + # and get timestamp + self.date = d + + if m.group(7).find('nouveau') >= 0: + self.new = True + else: + error('Error: unable to parse the datetime string "%s"' % date_str) + + def parseProfileLink(self): + tables = self.tr.getElementsByTagName('div') + + for table in tables: + if table.hasAttribute('class') and table.getAttribute('class') == 'mini' and table.hasAttribute('onclick'): + + text = table.getAttribute('onclick') + + regexp = re.compile("window.location='(.*)'") + m = regexp.match(text) + + if m: + self.profile_link = m.group(1) + return + + warning('Unable to find the profile URL in the message %s@%s' % (self.getFrom(), self.getID())) + + def parseFrom(self): + tds = self.tr.getElementsByTagName('div') + + for td in tds: + if not td.hasAttribute('class') or td.getAttribute('class') != 'mini_pseudo': + continue + + self.sender = td.childNodes[0].data + return + + warning('Warning: unable to find from in the mail %s' % self.getID()) + +class ContactThreadPage(PageBase): + + """ + +
+ +
+ + + + + + + +
  Ecrire � zoe
+ + + + + + + + + + + + + + +
+
+
+ +
+ + + """ + + def post(self, content): + try: + self.browser.select_form(name="sendMsg") + if isinstance(content, unicode): + content = content.encode('iso-8859-15', 'replace') + self.browser['message'] = content + + self.browser.submit() # submit current form + except FormNotFoundError: + error = 'Unknown error' + p_list = self.document.getElementsByTagName('p') + for p in p_list: + if p.hasAttribute('align') and p.getAttribute('align') == 'center': + error = p.firstChild.data + break + + raise AdopteCantPostMail(error) + + + """ + + + + + + content + + ... + +
+
  voir tous les messages
+ + """ + + id_regexp = re.compile("/thread.php\?id=([0-9]+)") + + def loaded(self): + + self.items = [] + + a_list = self.document.getElementsByTagName('a') + self.id = 0 + for a in a_list: + if a.hasAttribute('href'): + m = self.id_regexp.match(a.getAttribute('href')) + if m: + self.id = int(m.group(1)) + break + + self.name = '' + big_list = self.document.getElementsByTagName('big') + for big in big_list: + child = big.firstChild + if hasattr(child, 'tagName') and child.tagName == u'b': + self.name = child.firstChild.data + break + + tables = self.document.getElementsByTagName('table') + table = None + for t in tables: + if t.hasAttribute('style') and t.getAttribute('style') == 'width:700px;background:black': + table = t + break + + if not table: + # It is probably the 'sent' page + return + + for tag in table.childNodes[1].childNodes[1:]: + if not hasattr(tag, 'tagName') or tag.tagName != u'tr': + continue + + if not tag.hasAttribute('valign'): + continue + + mail = MailParser(self.id, self.name, tag) + + if self.items: + self.items[-1].reply_date = mail.getDateInt() + self.items += [mail] + + def getMails(self): + + return self.items diff --git a/weboob/backends/aum/pages/edit.py b/weboob/backends/aum/pages/edit.py new file mode 100644 index 00000000..23c99a67 --- /dev/null +++ b/weboob/backends/aum/pages/edit.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- + +""" +Copyright(C) 2008-2010 Romain Bignon + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 3 of the License. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +""" + +from weboob.backends.aum.pages.base import PageBase + +class EditPhotoPage(PageBase): + def addPhoto(self, name, f): + self.browser.select_form(name="form") + self.browser.find_control('uploaded').add_file(f, 'image/jpeg', name) + self.browser.submit() + self.browser.openurl('http://www.adopteunmec.com/home.php') + +class EditPhotoCbPage(PageBase): + # Do nothing + pass + +class EditAnnouncePage(PageBase): + def setNickname(self, nickname): + self.browser.select_form(name="form") + self.browser['pseudo'] = nickname + self.browser.submit() + + def setAnnounce(self, title=None, description=None, lookingfor=None): + self.browser.select_form(name="form") + if title is not None: + self.browser['title'] = title + if description is not None: + self.browser['about1'] = description + if lookingfor is not None: + self.browser['about2'] = lookingfor + + self.browser.submit() + +class EditDescriptionPage(PageBase): + pass + +class EditSexPage(PageBase): + pass + +class EditPersonalityPage(PageBase): + pass diff --git a/weboob/backends/aum/pages/home.py b/weboob/backends/aum/pages/home.py new file mode 100644 index 00000000..cb46e245 --- /dev/null +++ b/weboob/backends/aum/pages/home.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- + +""" +Copyright(C) 2008-2010 Romain Bignon + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 3 of the License. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +""" + +import re + +from weboob.backends.aum.pages.base import PageBase +from logging import error + +class HomePage(PageBase): + + MYID_REGEXP = re.compile("http://www.adopteunmec.com/\?mid=(\d+)") + + def getMyID(self): + fonts = self.document.getElementsByTagName('font') + for font in fonts: + m = self.MYID_REGEXP.match(font.firstChild.data) + if m: + return m.group(1) + + error("Error: Unable to find my ID") + return 0 + + def nbAvailableCharms(self): + tables = self.document.getElementsByTagName('table') + for table in tables: + if table.hasAttribute('style') and table.getAttribute('style') == 'background-color:black;background-image:url(http://s.adopteunmec.com/img/barmec.gif);background-repeat:no-repeat': + + fonts = table.getElementsByTagName('font') + i = 0 + + for font in fonts: + if font.hasAttribute('color') and font.getAttribute('color') == '#ff0198': + i += 1 + if i == 3: + return int(font.firstChild.data) + + error('Error: Unable to find the available charms counter') + return 0 diff --git a/weboob/backends/aum/pages/login.py b/weboob/backends/aum/pages/login.py new file mode 100644 index 00000000..a2e74084 --- /dev/null +++ b/weboob/backends/aum/pages/login.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- + +""" +Copyright(C) 2008-2010 Romain Bignon + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 3 of the License. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +""" + +from weboob.backends.aum.pages.base import PageBase +from weboob.tools.browser import BrowserIncorrectPassword + +class LoginPage(PageBase): + def login(self, login, password): + self.browser.select_form(name="form_login") + self.browser['login'] = login + self.browser['password'] = password + + self.browser.submit() # submit current form + +class RegisterPage(PageBase): + def register(self, nickname, password, sex, birthday_d, birthday_m, birthday_y, zipcode, country, godfather): + """ form2: + - pseudo + - email + - password + - sex (0=m, 1=f) + - birthday0 (0-31) + - birthday1 (0-12) + - birthday2 (1930-1999) + - zip + - country (fr,be,ch,ca) + - godfather + """ + self.browser.select_form(name="form2") + self.browser.controls.pop() + + if isinstance(nickname, unicode): + nickname = nickname.encode('iso-8859-15', 'ignore') + self.browser['pseudo'] = nickname + self.browser['email'] = self.browser.login + self.browser['pass'] = password + self.browser['sex'] = [str(sex)] + self.browser['birthday0'] = [str(birthday_d)] + self.browser['birthday1'] = [str(birthday_m)] + self.browser['birthday2'] = [str(birthday_y)] + self.browser['zip'] = str(zipcode) + self.browser['country'] = [str(country)] + self.browser['godfather'] = godfather + + self.browser.submit() + +class RegisterWaitPage(PageBase): + pass + +class RegisterConfirmPage(PageBase): + pass + +class RedirectPage(PageBase): + def loaded(self): + for link in self.browser.links(): + print link + self.browser.location('/wait.php') + +class BanPage(PageBase): + pass + +class ErrPage(PageBase): + def loaded(self): + raise BrowserIncorrectPassword() diff --git a/weboob/backends/aum/pages/profile.py b/weboob/backends/aum/pages/profile.py new file mode 100644 index 00000000..24f38d85 --- /dev/null +++ b/weboob/backends/aum/pages/profile.py @@ -0,0 +1,405 @@ +# -*- coding: utf-8 -*- + +""" +Copyright(C) 2008-2010 Romain Bignon + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 3 of the License. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +""" + +from weboob.backends.aum.pages.base import PageBase +from copy import deepcopy +from logging import warning +import re + +class FieldBase: + + def __init__(self, key): + self.key = key + + def putValue(self, d, value): + raise NotImplementedError + +class FieldString(FieldBase): + def putValue(self, d, value): + d[self.key] = unicode(value) + +class FieldList(FieldBase): + def putValue(self, d, value): + d[self.key] = value.split(', ') + +class FieldWideList(FieldBase): + + def putValue(self, d, value): + d[self.key] += [value] + +class FieldOld(FieldBase): + regexp = re.compile('([0-9]+) ans') + def putValue(self, d, value): + m = self.regexp.match(value) + if m: + d[self.key] = int(m.group(1)) + +class FieldLocation(FieldBase): + location = re.compile('(.*) \(([0-9]{5})\), (.*)') + + def __init__(self): + FieldBase.__init__(self, '') + def putValue(self, d, value): + # TODO: determine distance, or something like + m = self.location.match(value) + if m: + d['location'] = m.group(1) + d['zipcode'] = int(m.group(2)) + d['country'] = m.group(3) + else: + warning('Unable to parse the location "%s"' % value) + d['location'] = unicode(value) + +class FieldMeasurements(FieldBase): + height = re.compile('([0-9]{1,3}) cm') + weight = re.compile('([0-9]{1,3}) kg') + # TODO: parse third parameter + + def __init__(self): + FieldBase.__init__(self, '') + def putValue(self, d, value): + for s in value.split(', '): + m = self.height.match(s) + if m: + d['height'] = int(m.group(1)) + continue + m = self.weight.match(s) + if m: + d['weight'] = int(m.group(1)) + continue + if d['height'] and d['weight']: + bmi = (d['weight']/float(pow(d['height']/100.0, 2))) + if bmi < 15.5: + d['fat'] = 'severely underweight' + elif bmi < 18.4: + d['fat'] = 'underweight' + elif bmi < 24.9: + d['fat'] = 'normal' + elif bmi < 30: + d['fat'] = 'overweight' + else: + d['fat'] = 'obese' + d['BMI'] = bmi + +class FieldParticularSignes(FieldBase): + def __init__(self): FieldBase.__init__(self, '') + def putValue(self, d, value): + for s in value.split(', '): + if s.find('tatouages') >= 0: + d['tatoos'] = True + elif s.find('piercing') >= 0: + d['piercing'] = True + elif s.find('lunettes') >= 0: + d['glasses'] = True + elif s.find('rousseur') >= 0: + d['freckle'] = True + +class ProfilePage(PageBase): + + empty_table = {'details': {'old': 0, + 'zipcode': 0, + 'location': '', + 'country': '', + 'eyes': '', + 'hairs': [], + 'height': 0, + 'weight': 0, + 'BMI': 0, + 'fat': '', + 'from': '', + 'tatoos': False, + 'piercing': False, + 'freckle': False, + 'glasses': False, + 'job': '', + 'style': '', + 'alimentation': '', + 'alcool': '', + 'tabac': '', + }, + 'liking': {'activities': '', + 'music': [], + 'cinema': [], + 'books': [], + 'tv': [], + }, + 'sex': {'underwear': [], + 'top': [], + 'bottom': [], + 'interval': '', + 'practices': [], + 'favorite': '', + 'toys': [], + }, + 'personality': {'snap': '', + 'exciting': '', + 'hate': '', + 'vices': '', + 'assets': '', + 'fantasies': '', + 'is': [], + }, + } + + tables = {'tab_0': 'details', + 'tab_1': 'liking', + 'tab_2': 'sex', + 'tab_3': 'personality' + } + + fields = {'details': {'Age': FieldOld('old'), + u'Réside à': FieldLocation(), + 'Yeux': FieldString('eyes'), + 'Cheveux ': FieldList('hairs'), + 'Mensurations ': FieldMeasurements(), + 'Origines ': FieldString('from'), + 'Signes particuliers ': FieldParticularSignes(), + 'Style ': FieldString('style'), + 'Profession ': FieldString('job'), + 'Alimentation': FieldString('alimentation'), + 'Alcool': FieldString('alcool'), + 'Tabac': FieldString('tabac'), + }, + 'liking': {'Hobbies ': FieldString('activities'), + 'Musique ': FieldWideList('music'), + u'Cinéma': FieldWideList('cinema'), + 'Livres ': FieldWideList('books'), + u'Télé': FieldWideList('tv'), + }, + 'sex': {u'Sous-v\xeatements ': FieldList('underwear'), + '... en haut ': FieldList('top'), + '... en bas ': FieldList('bottom'), + u'Fréquence idéale des rapports sexuels ': + FieldString('interval'), + 'Pratiques sexuelles ': FieldList('practices'), + u'Accessoires préférés ':FieldList('toys'), + u'Position favorite ': FieldString('favorite'), + }, + 'personality': {u'Ça la fait craquer ': FieldString('snap'), + u'Ça l\'excite ': FieldString('exciting'), + u'Elle déteste ': FieldString('hate'), + 'Ses vices ': FieldString('vices'), + 'Ses atouts ': FieldString('assets'), + 'Ses fantasmes ': FieldString('fantasies'), + 'Elle est ': FieldList('is'), + }, + } + + ID_REGEXP = re.compile('(charm|addBasket|openAlbum)\(([0-9]+)(,[\s\'\d]+)?\)') + PHOTO_REGEXP = re.compile('http://(s|p)([0-9]+)\.adopteunmec\.com/(.*)') + + STATS2ID = {'visites': 'visits', + 'charmes': 'charms', + 'paniers': 'baskets', + 'mails': 'mails', + 'POPULARIT': 'score', + } + STATS_VALUE_REGEXP = re.compile('([0-9\s]+).*') + + def __repr__(self): + if isinstance(self.name, unicode): + name = self.name.encode('ascii', 'backslashreplace') + else: + name = self.name + return '' % name + + def loaded(self): + self.name = u'' + self.description = u'' + self.table = deepcopy(self.empty_table) + self.id = 0 + self.photos = [] + self.status = '' + self.stats = {'score': 0, + 'visits': 0, + 'charms': 0, + 'baskets': 0, + 'mails': 0, + } + + divs = self.document.getElementsByTagName('td') + for div in divs: + if (div.hasAttribute('style') and + div.getAttribute('style') == "color:#ffffff;font-size:32px;font-weight:bold;letter-spacing:-2px" and + hasattr(div.firstChild, 'data')): + self.name = div.firstChild.data + if (div.hasAttribute('style') and + div.getAttribute('style') == "font-size:12px;font-weight:bold" and + hasattr(div.firstChild, 'data')): + self.status = div.firstChild.data + if div.hasAttribute('background'): + m = self.PHOTO_REGEXP.match(div.getAttribute('background')) + if m: + self.photos += [re.sub(u'thumb[0-2]_', u'image', div.getAttribute('background'))] + if div.hasAttribute('width') and str(div.getAttribute('width')) == '226': + trs = div.getElementsByTagName('tr') + for tr in trs: + tds = tr.getElementsByTagName('td') + if len(tds) > 2 and hasattr(tds[2].firstChild, 'data'): + label = tds[0].firstChild.data + value = tds[2].firstChild.data + elif len(tds) == 2: + label = unicode(tds[0].childNodes[1].data) + value = tds[1].childNodes[1].data + else: + continue + + m = self.STATS_VALUE_REGEXP.match(value) + if m and self.STATS2ID.has_key(label): + self.stats[self.STATS2ID[label]] = int(m.group(1).replace(' ', '')) + + divs = self.document.getElementsByTagName('div') + for div in divs: + if div.hasAttribute('id'): + if div.getAttribute('id') == 'about_div': + self.parseDescription(div) + + if div.getAttribute('id').startswith('tab_'): + self.parseTable(div) + + for tag in ('img', 'td'): + imgs = self.document.getElementsByTagName(tag) + for img in imgs: + if img.hasAttribute('onclick'): + m = self.ID_REGEXP.match(img.getAttribute('onclick')) + if m: + self.id = int(m.group(2)) + break + if self.id: + break + + def parseDescription(self, div): + # look for description + + description = '' + for c in div.childNodes: + if hasattr(c, 'data'): + description += ''.join(c.data.split('\n')) # to strip \n + elif hasattr(c, 'tagName') and c.tagName == 'br': + description += '\n' + + self.description = description + + def parseTable(self, div): + + d = self.table[self.tables[div.getAttribute('id')]] + fields = self.fields[self.tables[div.getAttribute('id')]] + table = div.getElementsByTagName('table')[1] + + field1 = None + field2 = None + + for tr in table.getElementsByTagName('tr'): + tds = tr.getElementsByTagName('td') + if len(tds) != 2: + continue + + label1 = '' + label2 = '' + value1 = '' + value2 = '' + # Check for first column + if len(tds[0].childNodes) > 2: + b = tds[0].childNodes[2] + if hasattr(b, 'tagName') and b.tagName == 'b': + for child in b.childNodes: + label1 += child.data + else: + for child in tds[0].childNodes[2:]: + value1 += child.data + + # Check for second column + if len(tds[1].childNodes) > 2: + b = tds[1].childNodes[2] + if hasattr(b, 'tagName') and b.tagName == 'b': + for child in b.firstChild.childNodes: + label2 += child.data + else: + for child in tds[1].childNodes[2:]: + if hasattr(child, 'data'): + value2 += child.data + + if label1 and value2: + # This is a typically tuple of key/value on the line. + try: + fields[label1].putValue(d, value2) + except KeyError: + warning('Unable to find "%s" (%s)' % (label1, repr(label1))) + elif label1 and label2: + # two titles, so there will have a list of value in + # next lines on each columns + field1 = fields[label1] + field2 = fields[label2] + elif not label1 and not label1: + # two values, so it is a line of values + if field1 and value1: + field1.putValue(d, value1) + if field2 and value2: + field2.putValue(d, value2) + + def getName(self): + return self.name + + def getDescription(self): + return self.description + + def getTable(self): + return self.table + + def getID(self): + return self.id + + def getPhotos(self): + return self.photos + + def getStatus(self): + return self.status + + def isOnline(self): + return self.status.find('en ligne') >= 0 + + def getStats(self): + return self.stats + + def getProfileText(self): + body = u'Status: %s' % unicode(self.status) + if self.photos: + body += u'\nPhotos:' + for photo in self.photos: + body += u'\n\t\t%s' % unicode(photo) + body += u'\nStats:' + for label, value in self.getStats().iteritems(): + body += u'\n\t\t%-15s %s' % (label + ':', value) + body += u'\n\nInformations:' + for section, d in self.getTable().iteritems(): + body += u'\n\t%s\n' % section + for key, value in d.items(): + key = '%s:' % key + if isinstance(value, list): + body += u'\t\t%-15s %s\n' % (key, u', '.join([unicode(s) for s in value])) + elif isinstance(value, float): + body += u'\t\t%-15s %.2f\n' % (key, value) + else: + body += u'\t\t%-15s %s\n' % (key, unicode(value)) + body += u'\n\nDescription:\n%s' % unicode(self.getDescription()) + + return body + + diff --git a/weboob/backends/aum/pages/profileslist_base.py b/weboob/backends/aum/pages/profileslist_base.py new file mode 100644 index 00000000..fe9fc1f8 --- /dev/null +++ b/weboob/backends/aum/pages/profileslist_base.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- + +""" +Copyright(C) 2008 Romain Bignon + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 3 of the License. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +""" + +from weboob.backends.aum.pages.base import PageBase +import re + +class ProfilesListBase(PageBase): + + PROFILE_REGEXP = re.compile(".*window\.location='(.*)'") + PHOTO_REGEXP = re.compile(".*background-image:url\(([A-Za-z0-9_\-:/\.]+)\).*") + WITHOUT_PHOTO = 'http://s.adopteunmec.com/img/thumb1.gif' + SHOW_WITHOUT_PHOTO = True + + def loaded(self): + + self.id_list = [] + + a_list = self.document.getElementsByTagName('div') + for a in a_list: + if a.hasAttribute('onclick') and a.hasAttribute('class') and a.getAttribute('class') in ('small', 'mini'): + m = self.PROFILE_REGEXP.match(a.getAttribute('onclick')) + if m: + url = m.group(1).split('/')[-1] + m = self.PHOTO_REGEXP.match(a.getElementsByTagName('div')[0].getAttribute('style')) + if url != 'home.php' and not url in self.id_list and \ + m and (self.SHOW_WITHOUT_PHOTO or m.group(1) != self.WITHOUT_PHOTO): + self.id_list.append(url) + + def getProfilesIDs(self): + return set(self.id_list) + + def getProfilesIDsList(self): + return self.id_list diff --git a/weboob/backends/aum/pages/search.py b/weboob/backends/aum/pages/search.py new file mode 100644 index 00000000..855719f0 --- /dev/null +++ b/weboob/backends/aum/pages/search.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- + +""" +Copyright(C) 2008 Romain Bignon + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 3 of the License. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +""" + +import ClientForm +from weboob.backends.aum.pages.profileslist_base import ProfilesListBase + +class SearchPage(ProfilesListBase): + + SHOW_WITHOUT_PHOTO = False + + def set_field(self, args, label, field=None, value=None, is_list=False): + try: + if not field: + field = label + if args.get(label, None) is not None: + if not value: + if is_list: + value = [str(args[label])] + else: + value = str(args[label]) + self.browser[field] = value + except ClientForm.ControlNotFoundError: + return + + def search(self, **kwargs): + + self.browser.select_form(name="form") + self.browser.set_all_readonly(False) + + self.set_field(kwargs, 'ageMin', is_list=True) + self.set_field(kwargs, 'ageMax', is_list=True) + self.set_field(kwargs, 'country', is_list=True) + self.set_field(kwargs, 'dist', is_list=True) + self.set_field(kwargs, 'nickname', field='pseudo') + self.set_field(kwargs, 'save', value='true') + + self.browser.submit() diff --git a/weboob/backends/aum/pages/wait.py b/weboob/backends/aum/pages/wait.py new file mode 100644 index 00000000..09edc61f --- /dev/null +++ b/weboob/backends/aum/pages/wait.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- + +""" +Copyright(C) 2008-2010 Romain Bignon + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 3 of the License. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +""" + +from weboob.backends.aum.pages.base import PageBase +from weboob.backends.aum.exceptions import AdopteWait +from time import sleep + +class WaitPage(PageBase): + + def loaded(self): + raise AdopteWait() + + def check(self): + result = self.browser.openurl('http://www.adopteunmec.com/fajax_checkEnter.php?anticache=0.46168455299380795').read() + return result == 'Ok' + + def processWait(self): + while not self.check(self): + sleep(10) + + self.browser.location('/home.php') + diff --git a/weboob/backends/dlfp/browser.py b/weboob/backends/dlfp/browser.py index 1f48387a..5a8ded0c 100644 --- a/weboob/backends/dlfp/browser.py +++ b/weboob/backends/dlfp/browser.py @@ -22,8 +22,8 @@ from weboob.tools.browser import Browser from weboob.backends.dlfp.pages.index import IndexPage, LoginPage class DLFP(Browser): - DOMAIN = 'linuxfr.org' + PROTOCOL = 'https' PAGES = {'https://linuxfr.org/': IndexPage, 'https://linuxfr.org/pub/': IndexPage, 'https://linuxfr.org/my/': IndexPage, diff --git a/weboob/backends/dlfp/feeds.py b/weboob/backends/dlfp/feeds.py index e77f4fda..ea06a873 100644 --- a/weboob/backends/dlfp/feeds.py +++ b/weboob/backends/dlfp/feeds.py @@ -18,6 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. """ +from logging import warning import feedparser import re diff --git a/weboob/tools/browser.py b/weboob/tools/browser.py index 36d34f60..8cef4e77 100644 --- a/weboob/tools/browser.py +++ b/weboob/tools/browser.py @@ -60,6 +60,7 @@ class Browser(mechanize.Browser): # ------ Class attributes -------------------------------------- DOMAIN = None + PROTOCOL = 'http' PAGES = {} USER_AGENT = 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.4) Gecko/2008111318 Ubuntu/8.10 (intrepid) Firefox/3.0.3'