can looking for a rent or a sale

This commit is contained in:
Romain Bignon 2012-02-19 18:35:20 +01:00
commit f5ca33f80e
9 changed files with 79 additions and 29 deletions

View file

@ -41,7 +41,7 @@ class PapBackend(BaseBackend, ICapHousing):
return list() return list()
with self.browser: with self.browser:
return self.browser.search_housings(cities, query.nb_rooms, return self.browser.search_housings(query.type, cities, query.nb_rooms,
query.area_min, query.area_max, query.area_min, query.area_max,
query.cost_min, query.cost_max) query.cost_min, query.cost_max)

View file

@ -22,6 +22,7 @@ import urllib
import json import json
from weboob.tools.browser import BaseBrowser from weboob.tools.browser import BaseBrowser
from weboob.capabilities.housing import Query
from .pages import SearchResultsPage, HousingPage from .pages import SearchResultsPage, HousingPage
@ -42,13 +43,16 @@ class PapBrowser(BaseBrowser):
fp = self.openurl(self.buildurl('http://www.pap.fr/index/ac-geo', q=pattern)) fp = self.openurl(self.buildurl('http://www.pap.fr/index/ac-geo', q=pattern))
return json.load(fp) return json.load(fp)
def search_housings(self, cities, nb_rooms, area_min, area_max, cost_min, cost_max): TYPES = {Query.TYPE_RENT: 'location',
Query.TYPE_SALE: 'vente',
}
def search_housings(self, type, cities, nb_rooms, area_min, area_max, cost_min, cost_max):
data = {'geo_objets_ids': ','.join(cities), data = {'geo_objets_ids': ','.join(cities),
'surface[min]': area_min or '', 'surface[min]': area_min or '',
'surface[max]': area_max or '', 'surface[max]': area_max or '',
'prix[min]': cost_min or '', 'prix[min]': cost_min or '',
'prix[max]': cost_max or '', 'prix[max]': cost_max or '',
'produit': 'location', 'produit': self.TYPES.get(type, 'location'),
'recherche': 1, 'recherche': 1,
'nb_resultats_par_page': 40, 'nb_resultats_par_page': 40,
'submit': 'rechercher', 'submit': 'rechercher',

View file

@ -51,7 +51,11 @@ class SearchResultsPage(BasePage):
id = a.attrib['href'].split('-')[-1] id = a.attrib['href'].split('-')[-1]
housing = Housing(id) housing = Housing(id)
housing.title = a.text.strip() housing.title = a.text.strip()
housing.cost = int(div.cssselect('td.prix')[0].text.strip(u' \t\u20ac\xa0\n\r')) m = re.match('(\w+) (.+) (\d+)\xa0m\xb2 (.*)', housing.title)
if m:
housing.area = float(m.group(3))
housing.cost = float(div.cssselect('td.prix')[0].text.strip(u' \t\u20ac\xa0\n\r').replace('.', '').replace(',', '.'))
housing.currency = u'' housing.currency = u''
m = self.DATE_RE.match(div.cssselect('p.date-publication')[0].text.strip()) m = self.DATE_RE.match(div.cssselect('p.date-publication')[0].text.strip())
@ -75,6 +79,8 @@ class SearchResultsPage(BasePage):
else: else:
housing.text = p.text.strip() housing.text = p.text.strip()
housing.photos = NotAvailable
yield housing yield housing
class HousingPage(BasePage): class HousingPage(BasePage):
@ -84,12 +90,12 @@ class HousingPage(BasePage):
parts = div.find('h1').text.split(' - ') parts = div.find('h1').text.split(' - ')
housing.title = parts[0].strip() housing.title = parts[0].strip()
housing.cost = int(parts[1].strip(u' \t\u20ac\xa0\n\r')) housing.cost = float(parts[1].strip(u' \t\u20ac\xa0\n\r').replace('.', '').replace(',', '.'))
housing.currency = u'' housing.currency = u''
m = re.match('(\w+) ([\w\s]+) (\d+)\xa0m\xb2 (.*)', housing.title) m = re.match('(\w+) (.+) (\d+)\xa0m\xb2 (.*)', housing.title)
if m: if m:
housing.area = int(m.group(3)) housing.area = float(m.group(3))
housing.date = housing.station = housing.location = housing.phone = NotAvailable housing.date = housing.station = housing.location = housing.phone = NotAvailable

View file

@ -42,7 +42,7 @@ class SeLogerBackend(BaseBackend, ICapHousing):
return list([]) return list([])
with self.browser: with self.browser:
return self.browser.search_housings(cities, query.nb_rooms, return self.browser.search_housings(query.type, cities, query.nb_rooms,
query.area_min, query.area_max, query.area_min, query.area_max,
query.cost_min, query.cost_max) query.cost_min, query.cost_max)

View file

@ -21,6 +21,7 @@
import json import json
from weboob.tools.browser import BaseBrowser from weboob.tools.browser import BaseBrowser
from weboob.capabilities.housing import Query
from .pages import SearchResultsPage, HousingPage from .pages import SearchResultsPage, HousingPage
@ -42,18 +43,27 @@ class SeLogerBrowser(BaseBrowser):
fp = self.openurl(self.buildurl('http://www.seloger.com/js,ajax,villequery_v3.htm', ville=pattern, mode=1)) fp = self.openurl(self.buildurl('http://www.seloger.com/js,ajax,villequery_v3.htm', ville=pattern, mode=1))
return json.load(fp) return json.load(fp)
def search_housings(self, cities, nb_rooms, area_min, area_max, cost_min, cost_max): TYPES = {Query.TYPE_RENT: 1,
Query.TYPE_SALE: 2
}
def search_housings(self, type, cities, nb_rooms, area_min, area_max, cost_min, cost_max):
data = {'ci': ','.join(cities), data = {'ci': ','.join(cities),
'idtt': 1, #location 'idtt': self.TYPES.get(type, 1),
'idtypebien': 1, #appart 'idtypebien': 1, #appart
'org': 'advanced_search', 'org': 'advanced_search',
'px_loyermax': cost_max or '',
'px_loyermin': cost_min or '',
'surfacemax': area_max or '', 'surfacemax': area_max or '',
'surfacemin': area_min or '', 'surfacemin': area_min or '',
'tri': 'd_dt_crea', 'tri': 'd_dt_crea',
} }
if type == Query.TYPE_SALE:
data['pxmax'] = cost_max or ''
data['pxmin'] = cost_min or ''
else:
data['px_loyermax'] = cost_max or ''
data['px_loyermin'] = cost_min or ''
if nb_rooms: if nb_rooms:
data['nb_pieces'] = nb_rooms data['nb_pieces'] = nb_rooms

View file

@ -23,7 +23,7 @@ from PyQt4.QtCore import SIGNAL, Qt
from weboob.tools.application.qt import QtMainWindow, QtDo, HTMLDelegate from weboob.tools.application.qt import QtMainWindow, QtDo, HTMLDelegate
from weboob.tools.application.qt.backendcfg import BackendCfg from weboob.tools.application.qt.backendcfg import BackendCfg
from weboob.capabilities.housing import ICapHousing, Query, City from weboob.capabilities.housing import ICapHousing, Query, City
from weboob.capabilities.base import NotLoaded from weboob.capabilities.base import NotLoaded, NotAvailable
from .ui.main_window_ui import Ui_MainWindow from .ui.main_window_ui import Ui_MainWindow
from .query import QueryDialog from .query import QueryDialog
@ -35,8 +35,8 @@ class HousingListWidgetItem(QListWidgetItem):
self.read = False self.read = False
def __lt__(self, other): def __lt__(self, other):
return '%s%s' % (self.read, float(self.housing.cost) / float(self.housing.area)) < \ return '%s%s' % (self.read, float(self.housing.cost or 0) / float(self.housing.area or 1)) < \
'%s%s' % (other.read, float(other.housing.cost) / float(other.housing.area)) '%s%s' % (other.read, float(other.housing.cost or 0) / float(other.housing.area or 1))
def setAttrs(self, storage): def setAttrs(self, storage):
text = u'<h2>%s</h2>' % self.housing.title text = u'<h2>%s</h2>' % self.housing.title
@ -53,6 +53,8 @@ class HousingListWidgetItem(QListWidgetItem):
self.read = True self.read = True
if self.housing.fullid in storage.get('bookmarks'): if self.housing.fullid in storage.get('bookmarks'):
self.setBackground(QBrush(QColor(255, 200, 200))) self.setBackground(QBrush(QColor(255, 200, 200)))
elif self.background().color() != QColor(0,0,0):
self.setBackground(QBrush())
class MainWindow(QtMainWindow): class MainWindow(QtMainWindow):
def __init__(self, config, storage, weboob, parent=None): def __init__(self, config, storage, weboob, parent=None):
@ -140,18 +142,17 @@ class MainWindow(QtMainWindow):
item = querydlg.buildCityItem(city) item = querydlg.buildCityItem(city)
querydlg.ui.citiesList.addItem(item) querydlg.ui.citiesList.addItem(item)
querydlg.ui.typeBox.setCurrentIndex(int(query.get('type', 0)))
querydlg.ui.areaMin.setValue(query['area_min']) querydlg.ui.areaMin.setValue(query['area_min'])
querydlg.ui.areaMax.setValue(query['area_max']) querydlg.ui.areaMax.setValue(query['area_max'])
querydlg.ui.costMin.setValue(query['cost_min']) querydlg.ui.costMin.setValue(query['cost_min'])
querydlg.ui.costMax.setValue(query['cost_max']) querydlg.ui.costMax.setValue(query['cost_max'])
for i in xrange(querydlg.ui.nbRooms.count()): querydlg.selectComboValue(querydlg.ui.nbRooms, query['nb_rooms'])
if querydlg.ui.nbRooms.itemText(i) == str(query['nb_rooms']):
querydlg.ui.nbRooms.setCurrentIndex(i)
break
if querydlg.exec_(): if querydlg.exec_():
name = unicode(querydlg.ui.nameEdit.text()) name = unicode(querydlg.ui.nameEdit.text())
query = {} query = {}
query['type'] = querydlg.ui.typeBox.currentIndex()
query['cities'] = [] query['cities'] = []
for i in xrange(len(querydlg.ui.citiesList)): for i in xrange(len(querydlg.ui.citiesList)):
item = querydlg.ui.citiesList.item(i) item = querydlg.ui.citiesList.item(i)
@ -185,6 +186,7 @@ class MainWindow(QtMainWindow):
self.ui.bookmarksButton.setEnabled(False) self.ui.bookmarksButton.setEnabled(False)
query = Query() query = Query()
query.type = int(q.get('type', 0))
query.cities = [] query.cities = []
for c in q['cities']: for c in q['cities']:
city = City(c['id']) city = City(c['id'])
@ -227,7 +229,7 @@ class MainWindow(QtMainWindow):
process = QtDo(self.weboob, lambda b, c: self.setPhoto(c, item)) process = QtDo(self.weboob, lambda b, c: self.setPhoto(c, item))
process.do('fillobj', housing, ['photos'], backends=housing.backend) process.do('fillobj', housing, ['photos'], backends=housing.backend)
self.process_photo[housing.id] = process self.process_photo[housing.id] = process
elif len(housing.photos) > 0: elif housing.photos is not NotAvailable and len(housing.photos) > 0:
if not self.setPhoto(housing, item): if not self.setPhoto(housing, item):
photo = housing.photos[0] photo = housing.photos[0]
process = QtDo(self.weboob, lambda b, p: self.setPhoto(housing, item)) process = QtDo(self.weboob, lambda b, p: self.setPhoto(housing, item))
@ -240,22 +242,26 @@ class MainWindow(QtMainWindow):
self.process_bookmarks.pop(housing.fullid) self.process_bookmarks.pop(housing.fullid)
def housingSelected(self, item, prev): def housingSelected(self, item, prev):
housing = item.housing if item is not None:
self.ui.queriesFrame.setEnabled(False) housing = item.housing
self.ui.queriesFrame.setEnabled(False)
read = set(self.storage.get('read')) read = set(self.storage.get('read'))
read.add(housing.fullid) read.add(housing.fullid)
self.storage.set('read', list(read)) self.storage.set('read', list(read))
self.storage.save() self.storage.save()
self.process = QtDo(self.weboob, self.gotHousing)
self.process.do('fillobj', housing, backends=housing.backend)
else:
housing = None
self.setHousing(housing) self.setHousing(housing)
if prev: if prev:
prev.setAttrs(self.storage) prev.setAttrs(self.storage)
self.process = QtDo(self.weboob, self.gotHousing)
self.process.do('fillobj', housing, backends=housing.backend)
def setPhoto(self, housing, item): def setPhoto(self, housing, item):
if not housing: if not housing:
return False return False

View file

@ -47,6 +47,12 @@ class QueryDialog(QDialog):
""" """
event.ignore() event.ignore()
def selectComboValue(self, box, value):
for i in xrange(box.count()):
if box.itemText(i) == str(value):
box.setCurrentIndex(i)
break
def searchCity(self): def searchCity(self):
pattern = unicode(self.ui.cityEdit.text()) pattern = unicode(self.ui.cityEdit.text())
self.ui.resultsList.clear() self.ui.resultsList.clear()

View file

@ -33,6 +33,20 @@
<item> <item>
<widget class="QLineEdit" name="nameEdit"/> <widget class="QLineEdit" name="nameEdit"/>
</item> </item>
<item>
<widget class="QComboBox" name="typeBox">
<item>
<property name="text">
<string>Rent</string>
</property>
</item>
<item>
<property name="text">
<string>Sale</string>
</property>
</item>
</widget>
</item>
<item> <item>
<widget class="QGroupBox" name="groupBox"> <widget class="QGroupBox" name="groupBox">
<property name="title"> <property name="title">

View file

@ -57,8 +57,12 @@ class Housing(CapBaseObject):
self.add_field('details', dict) self.add_field('details', dict)
class Query(CapBaseObject): class Query(CapBaseObject):
TYPE_RENT = 0
TYPE_SALE = 1
def __init__(self): def __init__(self):
CapBaseObject.__init__(self, '') CapBaseObject.__init__(self, '')
self.add_field('type', int)
self.add_field('cities', (list,tuple)) self.add_field('cities', (list,tuple))
self.add_field('area_min', int) self.add_field('area_min', int)
self.add_field('area_max', int) self.add_field('area_max', int)