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':
+ #
+ 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):
+ """ """
+
+ 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
+
+
+
+
+
+
+
+
+ """
+
+ 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):
+
+ """
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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.
+
+
+ """
+
+ 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'