imported aum as a backend

This commit is contained in:
Romain Bignon 2010-02-13 18:00:09 +01:00
commit da1369ef7b
19 changed files with 1613 additions and 1 deletions

View file

@ -0,0 +1 @@
from adopte import AdopteUnMec

View file

@ -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('<td align="right" style="font-size:12px;font-weight:bold">en ligne</td>') >= 0
print 'isSlutOnline(%s) = %s' % (id, r)
return r

View file

@ -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

View file

@ -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

View file

View file

@ -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):
"""
<table width="220">
<tr>
<td align=left class=header>popularité</td>
<td align=right class=header><big style="color:#ff0198;" id=popScore>7.230</big> pts</td>
</tr>
</table>
"""
l = self.document.getElementsByTagName('table')
for tag in l:
if tag.getAttribute('width') == '220':
# <table><tbody(implicit)><td>
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):
""" <span id=mailsCounter><blink>1</blink></span> """
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):
""" <span class=header2>Bonjour Romain</span> """
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')

View file

@ -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

View file

@ -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"""
<tr bgcolor="#ff7ccb" height=1><td colspan=10></td></tr>
<tr style="background:#ffd5ee" height=74 onmouseover="this.style.background='#f3d5e7'" onmouseout="this.style.background='#ffd5ee'">
<td class=a onclick="window.location='/thread.php?id=110921'" width=4></td>
<td class=a onclick="window.location='/rencontres-femmes/france/ile-de-france/Hen/110921'" width=70 align=left>
<table><tr valign="bottom"><td style="background:url(http://p1.adopteunmec.com/1/2/9/0/1/thumb0_7.jpg);width:66px;height:66px" align="right">&nbsp;</td></tr></table>
</td>
<td class=a onclick="window.location='/thread.php?id=110921'" width=150 align=left><big><b>Hen</b></big><br>
19ans, Montreuil</td>
<td class=a onclick="window.location='/thread.php?id=110921'" width=320 align=left><b>Comme ça, on est deux.</b><br>
il y a 1 heure</td>
<td class=a onclick="window.location='/thread.php?id=110921'" width=100 align=right>nouveau&nbsp;<img src="http://img.adopteunmec.com/img/ico_mail0.gif" />&nbsp;&nbsp;&nbsp;
</td>
<td class=a onclick="window.location='/thread.php?id=110921'" width=30 align=left></td>
<td width=20 align=right><input id='fcc_suppr_545615' name='suppr[]' type='hidden' /><img id='cc_suppr_545615' src='http://img.adopteunmec.com/img/i/check0.png' onclick='customCheckClick(this)' align="absmiddle"/>&nbsp;</td>
<script>supprs[supprs.length] = 'cc_suppr_545615';</script>
</td>
<td width=7></td>
</tr>
"""
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

View file

@ -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):
"""
<td>
<table width="100%">
<tr valign="top">
<td width="1" bgcolor="black">
<td width="88" align="center">
<table class=a onclick="window.location='romainn'" style="background:url(http://img.adopteunmec.com/img/bg_mini.png);width:74px;height:85px">
<tr height=4>
<td></td>
</tr>
<tr valign=top height=66>
<td width=74 align=center style="-moz-opacity:0.5;opacity:0.5">
<table class=a onclick="window.location='romainn'" style="width:66px;background-image:url(http://p7.adopteunmec.com/7/7/0/8/7/4/thumb0_3.jpg);background-repeat:no-repeat">
<tr height=2><td></td></tr>
<tr height=31 valign=top>
<td width=2></td>
<td align=left><img width=7 heght=7 src='http://img.adopteunmec.com/img/i/null.png'id=status_ /></td>
</tr>
<tr height=31 valign=bottom>
<td width=2></td>
<td width=63 align=right id=online_>
<blnk><blink><img src="http://img.adopteunmec.com/img/online0.png" width=7 height=7 /></blink></blnk>
<img src="http://img.adopteunmec.com/img/online1.png" width=25 height=10 />
</td>
<td width=3></td>
</tr>
<tr height=2><td></td></tr>
<tr><td colspan=10 align=center style="font-size:10px;font-weight:bold;letter-spacing:-1px">Romain</td></tr>
</table>
</td>
</tr>
</table>
</td>
<td>
<p style="color:#444444;font-size:10px">27 octobre 2008, 01:11:32, nouveau
<br />
</p>
<br>Moi en g<EFBFBD>n<EFBFBD>ral j'aime sortir tout simplement dans des bars, pour discuter avec mes amis et/ou coll<6C>gues, et rencontrer des gens. Sinon je fais de la guitare, et je d<>veloppe des projets perso.</p>
</td>
<td width="1" bgcolor="black">
</tr>
<tr height="6"><td width="1" bgcolor="black"><td colspan="2"></td><td width="1" bgcolor="black"></tr>
</table>
</td>
"""
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):
# <td> <table> implicit<tbody> <tr>
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):
"""
<form name=sendMsg method="post" action="/thread.php?id=1567992">
<table align=center width=700>
<tr valign="top"><td width=370 align="left">
<table width=370>
<tr height=25 style="background:url(http://img.adopteunmec.com/img/bg_list1.gif)"><td colspan=4>&nbsp;&nbsp;<font color=#ff0198>Ecrire <20> <big><b>zoe</b></big></font></td></tr>
<tr height=193 valign=top><td width=1 bgcolor=black></td><td colspan=2 bgcolor=white><textarea id=message name=message style="width:366px;height:190px;border:none"></textarea></td><td width=1 bgcolor=black></td></tr>
<tr height=1><td width=1 bgcolor=black></td><td bgcolor="#d15c91" colspan=2></td><td width=1 bgcolor=black></td></tr>
<tr height=1><td width=1 bgcolor=black></td><td bgcolor="#ffffff" colspan=2></td><td width=1 bgcolor=black></td></tr>
<tr><td width=1 bgcolor=black></td><td bgcolor="#ffe8f3">
<table><tr>
<td width=8></td>
<td width=23><img src="http://img.adopteunmec.com/img/smile/0.gif" style="cursor:pointer" onclick="emote(':)')"></td>
<td width=23><img src="http://img.adopteunmec.com/img/smile/1.gif" style="cursor:pointer" onclick="emote(':D')"></td>
<td width=23><img src="http://img.adopteunmec.com/img/smile/2.gif" style="cursor:pointer" onclick="emote(':o')"></td>
<td width=23><img src="http://img.adopteunmec.com/img/smile/3.gif" style="cursor:pointer" onclick="emote(':p')"></td>
<td width=23><img src="http://img.adopteunmec.com/img/smile/4.gif" style="cursor:pointer" onclick="emote(';)')"></td>
<td width=23><img src="http://img.adopteunmec.com/img/smile/5.gif" style="cursor:pointer" onclick="emote(':(')"></td>
<td width=23><img src="http://img.adopteunmec.com/img/smile/6.gif" style="cursor:pointer" onclick="emote(':$')"></td>
<td width=23><img src="http://img.adopteunmec.com/img/smile/7.gif" style="cursor:pointer" onclick="emote(':\'(')"></td>
<td width=23><img src="http://img.adopteunmec.com/img/smile/11.gif" style="cursor:pointer" onclick="emote(':#')"></td>
<td width=23><img src="http://img.adopteunmec.com/img/smile/14.gif" style="cursor:pointer" onclick="emote(':\\')"></td>
<td width=23><img src="http://img.adopteunmec.com/img/smile/15.gif" style="cursor:pointer" onclick="emote(':|')"></td>
<td width=23><img src="http://img.adopteunmec.com/img/smile/10.gif" style="cursor:pointer" onclick="emote('(L)')"></td>
</tr></table>
</td><td bgcolor="#ffe8f3" align=right><input type="image" src="http://img.adopteunmec.com/img/buttonSendMail.jpg" style="border:none"></td><td width=1 bgcolor=black></td></tr>
<tr height=1><td width=1 bgcolor=black colspan=4></tr>
</table>
</td><td width=304 align="right">
<iframe frameborder=0 scrolling=NO style='width:300px;height:250px;boder:0' src='http://graphs.adopteunmec.com/ads/index.php?i=5'></iframe>
</td></tr>
</table>
<input type=hidden id=link name=link>
</form>
"""
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)
"""
<table align=center style="width:700px;background:black">
<tr style="height:1px">
<td>
</td>
</tr>
<tr bgcolor="#ffe9f6" valign="top">
content
</tr>
...
<tr height="25" style="background:url(http://img.adopteunmec.com/img/bg_list1.gif)"><td>&nbsp;&nbsp;<a href="/thread.php?id=1567992&see=all">voir tous les messages</a></td></tr>
</table>
"""
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

View file

@ -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

View file

@ -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

View file

@ -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()

View file

@ -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 '<Profile name="%s">' % 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

View file

@ -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

View file

@ -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()

View file

@ -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')

View file

@ -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,

View file

@ -18,6 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
"""
from logging import warning
import feedparser
import re

View file

@ -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'