diff --git a/modules/pap/backend.py b/modules/pap/backend.py index 89de162f..542e8be2 100644 --- a/modules/pap/backend.py +++ b/modules/pap/backend.py @@ -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) diff --git a/modules/pap/browser.py b/modules/pap/browser.py index f57dff2f..1ddadc08 100644 --- a/modules/pap/browser.py +++ b/modules/pap/browser.py @@ -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', diff --git a/modules/pap/pages.py b/modules/pap/pages.py index 0e4b9d08..00a68a01 100644 --- a/modules/pap/pages.py +++ b/modules/pap/pages.py @@ -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 diff --git a/modules/seloger/backend.py b/modules/seloger/backend.py index d01b8ade..14d9d5fe 100644 --- a/modules/seloger/backend.py +++ b/modules/seloger/backend.py @@ -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) diff --git a/modules/seloger/browser.py b/modules/seloger/browser.py index 77dcb1e5..7ac8f147 100644 --- a/modules/seloger/browser.py +++ b/modules/seloger/browser.py @@ -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 diff --git a/weboob/applications/qflatboob/main_window.py b/weboob/applications/qflatboob/main_window.py index f2bec0f8..eb69fd1f 100644 --- a/weboob/applications/qflatboob/main_window.py +++ b/weboob/applications/qflatboob/main_window.py @@ -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'

%s

' % 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 diff --git a/weboob/applications/qflatboob/query.py b/weboob/applications/qflatboob/query.py index ca134bcc..e4e37522 100644 --- a/weboob/applications/qflatboob/query.py +++ b/weboob/applications/qflatboob/query.py @@ -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() diff --git a/weboob/applications/qflatboob/ui/query.ui b/weboob/applications/qflatboob/ui/query.ui index 7d4420f8..ab3edca1 100644 --- a/weboob/applications/qflatboob/ui/query.ui +++ b/weboob/applications/qflatboob/ui/query.ui @@ -33,6 +33,20 @@ + + + + + Rent + + + + + Sale + + + + diff --git a/weboob/capabilities/housing.py b/weboob/capabilities/housing.py index d975e3b1..46ebd490 100644 --- a/weboob/capabilities/housing.py +++ b/weboob/capabilities/housing.py @@ -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)