can looking for a rent or a sale
This commit is contained in:
parent
3eddf8e6dd
commit
f5ca33f80e
9 changed files with 79 additions and 29 deletions
|
|
@ -41,7 +41,7 @@ class PapBackend(BaseBackend, ICapHousing):
|
|||
return list()
|
||||
|
||||
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.cost_min, query.cost_max)
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import urllib
|
|||
import json
|
||||
|
||||
from weboob.tools.browser import BaseBrowser
|
||||
from weboob.capabilities.housing import Query
|
||||
|
||||
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))
|
||||
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),
|
||||
'surface[min]': area_min or '',
|
||||
'surface[max]': area_max or '',
|
||||
'prix[min]': cost_min or '',
|
||||
'prix[max]': cost_max or '',
|
||||
'produit': 'location',
|
||||
'produit': self.TYPES.get(type, 'location'),
|
||||
'recherche': 1,
|
||||
'nb_resultats_par_page': 40,
|
||||
'submit': 'rechercher',
|
||||
|
|
|
|||
|
|
@ -51,7 +51,11 @@ class SearchResultsPage(BasePage):
|
|||
id = a.attrib['href'].split('-')[-1]
|
||||
housing = Housing(id)
|
||||
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'€'
|
||||
|
||||
m = self.DATE_RE.match(div.cssselect('p.date-publication')[0].text.strip())
|
||||
|
|
@ -75,6 +79,8 @@ class SearchResultsPage(BasePage):
|
|||
else:
|
||||
housing.text = p.text.strip()
|
||||
|
||||
housing.photos = NotAvailable
|
||||
|
||||
yield housing
|
||||
|
||||
class HousingPage(BasePage):
|
||||
|
|
@ -84,12 +90,12 @@ class HousingPage(BasePage):
|
|||
|
||||
parts = div.find('h1').text.split(' - ')
|
||||
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'€'
|
||||
|
||||
m = re.match('(\w+) ([\w\s]+) (\d+)\xa0m\xb2 (.*)', housing.title)
|
||||
m = re.match('(\w+) (.+) (\d+)\xa0m\xb2 (.*)', housing.title)
|
||||
if m:
|
||||
housing.area = int(m.group(3))
|
||||
housing.area = float(m.group(3))
|
||||
|
||||
housing.date = housing.station = housing.location = housing.phone = NotAvailable
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class SeLogerBackend(BaseBackend, ICapHousing):
|
|||
return list([])
|
||||
|
||||
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.cost_min, query.cost_max)
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
import json
|
||||
|
||||
from weboob.tools.browser import BaseBrowser
|
||||
from weboob.capabilities.housing import Query
|
||||
|
||||
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))
|
||||
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),
|
||||
'idtt': 1, #location
|
||||
'idtt': self.TYPES.get(type, 1),
|
||||
'idtypebien': 1, #appart
|
||||
'org': 'advanced_search',
|
||||
'px_loyermax': cost_max or '',
|
||||
'px_loyermin': cost_min or '',
|
||||
'surfacemax': area_max or '',
|
||||
'surfacemin': area_min or '',
|
||||
'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:
|
||||
data['nb_pieces'] = nb_rooms
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ from PyQt4.QtCore import SIGNAL, Qt
|
|||
from weboob.tools.application.qt import QtMainWindow, QtDo, HTMLDelegate
|
||||
from weboob.tools.application.qt.backendcfg import BackendCfg
|
||||
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 .query import QueryDialog
|
||||
|
|
@ -35,8 +35,8 @@ class HousingListWidgetItem(QListWidgetItem):
|
|||
self.read = False
|
||||
|
||||
def __lt__(self, other):
|
||||
return '%s%s' % (self.read, float(self.housing.cost) / float(self.housing.area)) < \
|
||||
'%s%s' % (other.read, float(other.housing.cost) / float(other.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 or 0) / float(other.housing.area or 1))
|
||||
|
||||
def setAttrs(self, storage):
|
||||
text = u'<h2>%s</h2>' % self.housing.title
|
||||
|
|
@ -53,6 +53,8 @@ class HousingListWidgetItem(QListWidgetItem):
|
|||
self.read = True
|
||||
if self.housing.fullid in storage.get('bookmarks'):
|
||||
self.setBackground(QBrush(QColor(255, 200, 200)))
|
||||
elif self.background().color() != QColor(0,0,0):
|
||||
self.setBackground(QBrush())
|
||||
|
||||
class MainWindow(QtMainWindow):
|
||||
def __init__(self, config, storage, weboob, parent=None):
|
||||
|
|
@ -140,18 +142,17 @@ class MainWindow(QtMainWindow):
|
|||
item = querydlg.buildCityItem(city)
|
||||
querydlg.ui.citiesList.addItem(item)
|
||||
|
||||
querydlg.ui.typeBox.setCurrentIndex(int(query.get('type', 0)))
|
||||
querydlg.ui.areaMin.setValue(query['area_min'])
|
||||
querydlg.ui.areaMax.setValue(query['area_max'])
|
||||
querydlg.ui.costMin.setValue(query['cost_min'])
|
||||
querydlg.ui.costMax.setValue(query['cost_max'])
|
||||
for i in xrange(querydlg.ui.nbRooms.count()):
|
||||
if querydlg.ui.nbRooms.itemText(i) == str(query['nb_rooms']):
|
||||
querydlg.ui.nbRooms.setCurrentIndex(i)
|
||||
break
|
||||
querydlg.selectComboValue(querydlg.ui.nbRooms, query['nb_rooms'])
|
||||
|
||||
if querydlg.exec_():
|
||||
name = unicode(querydlg.ui.nameEdit.text())
|
||||
query = {}
|
||||
query['type'] = querydlg.ui.typeBox.currentIndex()
|
||||
query['cities'] = []
|
||||
for i in xrange(len(querydlg.ui.citiesList)):
|
||||
item = querydlg.ui.citiesList.item(i)
|
||||
|
|
@ -185,6 +186,7 @@ class MainWindow(QtMainWindow):
|
|||
self.ui.bookmarksButton.setEnabled(False)
|
||||
|
||||
query = Query()
|
||||
query.type = int(q.get('type', 0))
|
||||
query.cities = []
|
||||
for c in q['cities']:
|
||||
city = City(c['id'])
|
||||
|
|
@ -227,7 +229,7 @@ class MainWindow(QtMainWindow):
|
|||
process = QtDo(self.weboob, lambda b, c: self.setPhoto(c, item))
|
||||
process.do('fillobj', housing, ['photos'], backends=housing.backend)
|
||||
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):
|
||||
photo = housing.photos[0]
|
||||
process = QtDo(self.weboob, lambda b, p: self.setPhoto(housing, item))
|
||||
|
|
@ -240,22 +242,26 @@ class MainWindow(QtMainWindow):
|
|||
self.process_bookmarks.pop(housing.fullid)
|
||||
|
||||
def housingSelected(self, item, prev):
|
||||
housing = item.housing
|
||||
self.ui.queriesFrame.setEnabled(False)
|
||||
if item is not None:
|
||||
housing = item.housing
|
||||
self.ui.queriesFrame.setEnabled(False)
|
||||
|
||||
read = set(self.storage.get('read'))
|
||||
read.add(housing.fullid)
|
||||
self.storage.set('read', list(read))
|
||||
self.storage.save()
|
||||
read = set(self.storage.get('read'))
|
||||
read.add(housing.fullid)
|
||||
self.storage.set('read', list(read))
|
||||
self.storage.save()
|
||||
|
||||
self.process = QtDo(self.weboob, self.gotHousing)
|
||||
self.process.do('fillobj', housing, backends=housing.backend)
|
||||
|
||||
else:
|
||||
housing = None
|
||||
|
||||
self.setHousing(housing)
|
||||
|
||||
if prev:
|
||||
prev.setAttrs(self.storage)
|
||||
|
||||
self.process = QtDo(self.weboob, self.gotHousing)
|
||||
self.process.do('fillobj', housing, backends=housing.backend)
|
||||
|
||||
def setPhoto(self, housing, item):
|
||||
if not housing:
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -47,6 +47,12 @@ class QueryDialog(QDialog):
|
|||
"""
|
||||
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):
|
||||
pattern = unicode(self.ui.cityEdit.text())
|
||||
self.ui.resultsList.clear()
|
||||
|
|
|
|||
|
|
@ -33,6 +33,20 @@
|
|||
<item>
|
||||
<widget class="QLineEdit" name="nameEdit"/>
|
||||
</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>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
|
|
|
|||
|
|
@ -57,8 +57,12 @@ class Housing(CapBaseObject):
|
|||
self.add_field('details', dict)
|
||||
|
||||
class Query(CapBaseObject):
|
||||
TYPE_RENT = 0
|
||||
TYPE_SALE = 1
|
||||
|
||||
def __init__(self):
|
||||
CapBaseObject.__init__(self, '')
|
||||
self.add_field('type', int)
|
||||
self.add_field('cities', (list,tuple))
|
||||
self.add_field('area_min', int)
|
||||
self.add_field('area_max', int)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue