Newer
Older
# -*- coding: utf-8 -*-
# Copyright(C) 2017 Phyks (Lucas Verney)
#
# This woob module is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This woob module 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this woob module. If not, see <http://www.gnu.org/licenses/>.
from decimal import Decimal
import requests
from woob.browser.elements import ItemElement, method, DictElement
from woob.browser.filters.json import Dict
from woob.browser.filters.standard import (
Format, DateTime, CleanDecimal, Field)
from woob.browser.pages import JsonPage, pagination
from woob.browser.selenium import SeleniumPage
from woob.capabilities.address import PostalAddress
from woob.capabilities.base import NotAvailable, NotLoaded
from woob.capabilities.housing import (
City, Housing, HousingPhoto, POSTS_TYPES,
ENERGY_CLASS, ADVERT_TYPES, UTILITIES
from woob.tools.capabilities.housing.housing import PricePerMeterFilter
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
from .constants import QUERY_TYPES, QUERY_HOUSE_TYPES, BASE_URL, AVAILABLE_TYPES
class FonciaItemElement(ItemElement):
klass = Housing
obj_id = Format('%s/%s', Dict('typeAnnonce'), Dict('reference'))
obj_url = Format(f'{BASE_URL}%s', Dict('canonicalUrl'))
obj_advert_type = ADVERT_TYPES.PROFESSIONAL
def obj_area(self):
area = Dict('surface/totale', default=None)(self)
if area is None:
area = Dict('surface/habitable', default=None)(self)
return Decimal(area)
def obj_cost(self):
if Field('type')(self) == POSTS_TYPES.SALE:
return CleanDecimal(Dict('prixVente', default=0))(self)
else:
return CleanDecimal(Dict('loyer'))(self) +\
CleanDecimal(Dict('loyerAnnexe', default=0))(self)
obj_currency = '€'
obj_price_per_meter = PricePerMeterFilter()
def obj_text(self):
text = Dict('description', default=None)(self)
if text is None:
text = Dict('libelle')(self)
return text
obj_date = DateTime(Dict('datePublication'))
obj_rooms = CleanDecimal(Dict('nbPiece', default=NotAvailable), default=NotAvailable)
obj_bedrooms = CleanDecimal(Dict('nbChambre', default=NotAvailable), default=NotAvailable)
obj_title = Format(r'%s %s - %sm²',
Dict('typeBien'),
Dict('localisation/locality/libelleDisplay'),
Format('%.2f', Field('area')))
def obj_address(self):
location = PostalAddress()
location.postal_code = Dict('localisation/codePostal')(self)
location.city = Dict('localisation/ville')(self)
location.full_address = f'{location.city} ({location.postal_code})'
return location
def obj_type(self):
_ = Dict('typeAnnonce')(self)
for k, v in QUERY_TYPES.items():
if v == _:
if k == POSTS_TYPES.RENT and Dict('typeBien') in AVAILABLE_TYPES[POSTS_TYPES.FURNISHED_RENT]:
return POSTS_TYPES.FURNISHED_RENT
return k
return NotAvailable
def obj_house_type(self):
_ = Dict('typeBien')(self)
for house_type, types in QUERY_HOUSE_TYPES.items():
if _ in types:
return house_type
return NotLoaded
def obj_photos(self):
return [HousingPhoto(url) for url in Dict('medias', default=[])(self)]
def obj_DPE(self):
return getattr(ENERGY_CLASS, Dict('noteConsoEnergie', default='')(self), NotAvailable)
def obj_GES(self):
return getattr(ENERGY_CLASS, Dict('noteEmissionGES', default='')(self), NotAvailable)
def obj_utilities(self):
if Field('type')(self) == POSTS_TYPES.SALE:
return UTILITIES.UNKNOWN
return UTILITIES.INCLUDED
class IndexPage(SeleniumPage):
pass
@method
class iter_cities(DictElement):
item_xpath = 'localities'
ignore_duplicate = True
class item(ItemElement):
klass = City
obj_id = Dict('slug')
obj_name = Dict('libelleDisplay')
class HousingPage(JsonPage):
def get_agency_id(self):
return Dict('numeroAgence')(self.doc)
@method
class get_housing(FonciaItemElement):
for k, v in Dict('caracteristiques', default={})(self).items():
if type(v) is dict:
if v.get('available', False):
details[k] = ''
else:
details[k] = v
copro = Dict('copro', default=False)(self)
if copro:
details = {**details, **copro}
class iter_housings(DictElement):
item_xpath = 'annonces'
def next_page(self):
if Dict('count')(self) > 0:
data = self.env['data']
data['page'] = data['page'] + 1
return requests.Request('POST', self.page.url, json=data)
class item(FonciaItemElement):
pass
class AgencyPage(JsonPage):
def get_phone(self):
return Dict('tel')(self.doc)