2017-04-03 17:29:29 +02:00
|
|
|
# coding: utf-8
|
|
|
|
"""
|
|
|
|
This modules defines an SQLAlchemy ORM model for a flat.
|
|
|
|
"""
|
2017-04-13 23:24:31 +02:00
|
|
|
# pylint: disable=locally-disabled,invalid-name,too-few-public-methods
|
2017-04-03 17:29:29 +02:00
|
|
|
from __future__ import absolute_import, print_function, unicode_literals
|
|
|
|
|
2017-04-13 23:24:31 +02:00
|
|
|
import logging
|
2018-01-18 14:48:28 +01:00
|
|
|
import enum
|
2017-04-13 23:24:31 +02:00
|
|
|
|
|
|
|
import arrow
|
2017-04-03 17:29:29 +02:00
|
|
|
|
2017-05-03 22:10:24 +02:00
|
|
|
from sqlalchemy import (
|
2021-01-26 14:39:52 +01:00
|
|
|
Boolean,
|
|
|
|
Column,
|
|
|
|
DateTime,
|
|
|
|
Enum,
|
|
|
|
Float,
|
|
|
|
SmallInteger,
|
|
|
|
String,
|
|
|
|
Text,
|
|
|
|
inspect,
|
2017-05-03 22:10:24 +02:00
|
|
|
)
|
2017-12-05 12:20:40 +01:00
|
|
|
from sqlalchemy.orm import validates
|
2017-04-03 17:29:29 +02:00
|
|
|
|
|
|
|
from flatisfy.database.base import BASE
|
|
|
|
from flatisfy.database.types import MagicJSON
|
|
|
|
|
|
|
|
|
2017-04-13 23:24:31 +02:00
|
|
|
LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
class FlatUtilities(enum.Enum):
|
|
|
|
"""
|
|
|
|
An enum of the possible utilities status for a flat entry.
|
|
|
|
"""
|
2021-01-26 14:39:52 +01:00
|
|
|
|
2017-04-13 23:24:31 +02:00
|
|
|
included = 10
|
|
|
|
unknown = 0
|
|
|
|
excluded = -10
|
|
|
|
|
|
|
|
|
2017-04-03 17:29:29 +02:00
|
|
|
class FlatStatus(enum.Enum):
|
|
|
|
"""
|
|
|
|
An enum of the possible status for a flat entry.
|
|
|
|
"""
|
2021-01-26 14:39:52 +01:00
|
|
|
|
2017-04-13 23:24:31 +02:00
|
|
|
user_deleted = -100
|
2017-04-27 17:08:10 +02:00
|
|
|
duplicate = -20
|
2017-04-13 23:24:31 +02:00
|
|
|
ignored = -10
|
2017-04-03 17:29:29 +02:00
|
|
|
new = 0
|
2017-04-13 23:24:31 +02:00
|
|
|
followed = 10
|
|
|
|
contacted = 20
|
|
|
|
answer_no = 30
|
|
|
|
answer_yes = 31
|
2017-04-03 17:29:29 +02:00
|
|
|
|
|
|
|
|
2017-05-02 16:05:15 +02:00
|
|
|
# List of statuses that are automatically handled, and which the user cannot
|
|
|
|
# manually set through the UI.
|
2021-01-26 14:39:52 +01:00
|
|
|
AUTOMATED_STATUSES = [FlatStatus.new, FlatStatus.duplicate, FlatStatus.ignored]
|
2017-05-02 16:05:15 +02:00
|
|
|
|
|
|
|
|
2017-04-03 17:29:29 +02:00
|
|
|
class Flat(BASE):
|
|
|
|
"""
|
|
|
|
SQLAlchemy ORM model to store a flat.
|
|
|
|
"""
|
2021-01-26 14:39:52 +01:00
|
|
|
|
2017-04-03 17:29:29 +02:00
|
|
|
__tablename__ = "flats"
|
2021-01-26 14:39:52 +01:00
|
|
|
__searchable__ = ["title", "text", "station", "location", "details", "notes"]
|
2017-04-03 17:29:29 +02:00
|
|
|
|
|
|
|
# Weboob data
|
|
|
|
id = Column(String, primary_key=True)
|
|
|
|
area = Column(Float)
|
|
|
|
bedrooms = Column(Float)
|
|
|
|
cost = Column(Float)
|
|
|
|
currency = Column(String)
|
2017-04-13 23:24:31 +02:00
|
|
|
utilities = Column(Enum(FlatUtilities), default=FlatUtilities.unknown)
|
2017-04-03 17:29:29 +02:00
|
|
|
date = Column(DateTime)
|
|
|
|
details = Column(MagicJSON)
|
|
|
|
location = Column(String)
|
|
|
|
phone = Column(String)
|
|
|
|
photos = Column(MagicJSON)
|
|
|
|
rooms = Column(Float)
|
|
|
|
station = Column(String)
|
|
|
|
text = Column(Text)
|
|
|
|
title = Column(String)
|
2017-04-13 23:24:31 +02:00
|
|
|
urls = Column(MagicJSON)
|
|
|
|
merged_ids = Column(MagicJSON)
|
2017-05-03 19:17:19 +02:00
|
|
|
notes = Column(Text)
|
2017-05-03 22:10:24 +02:00
|
|
|
notation = Column(SmallInteger, default=0)
|
2018-09-28 19:22:27 +02:00
|
|
|
is_expired = Column(Boolean, default=False)
|
2017-04-03 17:29:29 +02:00
|
|
|
|
|
|
|
# Flatisfy data
|
|
|
|
# TODO: Should be in another table with relationships
|
|
|
|
flatisfy_stations = Column(MagicJSON)
|
|
|
|
flatisfy_postal_code = Column(String)
|
|
|
|
flatisfy_time_to = Column(MagicJSON)
|
2017-06-16 16:21:13 +02:00
|
|
|
flatisfy_constraint = Column(String)
|
2021-01-16 17:11:34 +01:00
|
|
|
flatisfy_position = Column(MagicJSON)
|
2017-04-03 17:29:29 +02:00
|
|
|
|
|
|
|
# Status
|
|
|
|
status = Column(Enum(FlatStatus), default=FlatStatus.new)
|
|
|
|
|
2017-11-09 17:33:39 +01:00
|
|
|
# Date for visit
|
|
|
|
visit_date = Column(DateTime)
|
|
|
|
|
2021-01-26 14:39:52 +01:00
|
|
|
@validates("utilities")
|
2017-12-05 12:20:40 +01:00
|
|
|
def validate_utilities(self, _, utilities):
|
|
|
|
"""
|
|
|
|
Utilities validation method
|
|
|
|
"""
|
|
|
|
if isinstance(utilities, FlatUtilities):
|
|
|
|
return utilities
|
|
|
|
|
|
|
|
if utilities == "C.C.":
|
|
|
|
return FlatUtilities.included
|
|
|
|
elif utilities == "H.C.":
|
|
|
|
return FlatUtilities.excluded
|
2017-12-05 15:17:03 +01:00
|
|
|
return FlatUtilities.unknown
|
2017-12-05 12:20:40 +01:00
|
|
|
|
|
|
|
@validates("status")
|
|
|
|
def validate_status(self, _, status):
|
|
|
|
"""
|
|
|
|
Status validation method
|
|
|
|
"""
|
|
|
|
if isinstance(status, FlatStatus):
|
|
|
|
return status
|
|
|
|
|
|
|
|
try:
|
|
|
|
return getattr(FlatStatus, status)
|
|
|
|
except (AttributeError, TypeError):
|
2021-01-26 14:39:52 +01:00
|
|
|
LOGGER.warn("Unkown flat status %s, ignoring it.", status)
|
2017-12-05 12:20:40 +01:00
|
|
|
return self.status.default.arg
|
|
|
|
|
|
|
|
@validates("notation")
|
2017-12-05 15:17:03 +01:00
|
|
|
def validate_notation(self, _, notation):
|
2017-12-05 12:20:40 +01:00
|
|
|
"""
|
|
|
|
Notation validation method
|
|
|
|
"""
|
|
|
|
try:
|
|
|
|
notation = int(notation)
|
|
|
|
assert notation >= 0 and notation <= 5
|
|
|
|
except (ValueError, AssertionError):
|
2021-01-26 14:39:52 +01:00
|
|
|
raise ValueError("notation should be an integer between 0 and 5")
|
2017-12-05 12:20:40 +01:00
|
|
|
return notation
|
|
|
|
|
|
|
|
@validates("date")
|
|
|
|
def validate_date(self, _, date):
|
|
|
|
"""
|
|
|
|
Date validation method
|
|
|
|
"""
|
|
|
|
return arrow.get(date).naive
|
|
|
|
|
|
|
|
@validates("visit_date")
|
|
|
|
def validate_visit_date(self, _, visit_date):
|
|
|
|
"""
|
|
|
|
Visit date validation method
|
|
|
|
"""
|
|
|
|
return arrow.get(visit_date).naive
|
|
|
|
|
2018-01-18 15:43:39 +01:00
|
|
|
@validates("photos")
|
|
|
|
def validate_photos(self, _, photos):
|
|
|
|
"""
|
|
|
|
Photos validation method
|
|
|
|
"""
|
2018-03-04 18:40:57 +01:00
|
|
|
if not photos:
|
|
|
|
photos = []
|
2018-01-18 15:43:39 +01:00
|
|
|
for photo in photos:
|
|
|
|
try:
|
|
|
|
# Remove computed hash to avoid storing it in db
|
|
|
|
del photo["hash"]
|
|
|
|
except KeyError:
|
|
|
|
pass
|
|
|
|
return photos
|
|
|
|
|
2017-04-03 17:29:29 +02:00
|
|
|
@staticmethod
|
|
|
|
def from_dict(flat_dict):
|
|
|
|
"""
|
|
|
|
Create a Flat object from a flat dict as manipulated by the filtering
|
|
|
|
pass.
|
|
|
|
"""
|
|
|
|
# Handle flatisfy metadata
|
|
|
|
flat_dict = flat_dict.copy()
|
2017-04-27 17:08:10 +02:00
|
|
|
if "flatisfy" in flat_dict:
|
2021-01-26 16:49:43 +01:00
|
|
|
flat_dict["flatisfy_stations"] = flat_dict["flatisfy"].get("matched_stations", [])
|
|
|
|
flat_dict["flatisfy_postal_code"] = flat_dict["flatisfy"].get("postal_code", None)
|
2021-01-26 14:39:52 +01:00
|
|
|
flat_dict["flatisfy_position"] = flat_dict["flatisfy"].get("position", None)
|
|
|
|
flat_dict["flatisfy_time_to"] = flat_dict["flatisfy"].get("time_to", {})
|
2021-01-26 16:49:43 +01:00
|
|
|
flat_dict["flatisfy_constraint"] = flat_dict["flatisfy"].get("constraint", "default")
|
2017-04-27 17:08:10 +02:00
|
|
|
del flat_dict["flatisfy"]
|
2017-04-03 17:29:29 +02:00
|
|
|
|
2021-01-26 16:49:43 +01:00
|
|
|
flat_dict = {k: v for k, v in flat_dict.items() if k in inspect(Flat).columns.keys()}
|
2017-12-06 19:03:25 +01:00
|
|
|
return Flat(**flat_dict)
|
2017-04-03 17:29:29 +02:00
|
|
|
|
|
|
|
def __repr__(self):
|
2017-04-13 23:24:31 +02:00
|
|
|
return "<Flat(id=%s, urls=%s)>" % (self.id, self.urls)
|
2017-04-03 17:29:29 +02:00
|
|
|
|
|
|
|
def json_api_repr(self):
|
|
|
|
"""
|
|
|
|
Return a dict representation of this flat object that is JSON
|
|
|
|
serializable.
|
|
|
|
"""
|
2021-01-26 14:39:52 +01:00
|
|
|
flat_repr = {k: v for k, v in self.__dict__.items() if not k.startswith("_")}
|
2017-04-13 23:24:31 +02:00
|
|
|
if isinstance(flat_repr["status"], FlatStatus):
|
|
|
|
flat_repr["status"] = flat_repr["status"].name
|
|
|
|
if isinstance(flat_repr["utilities"], FlatUtilities):
|
|
|
|
flat_repr["utilities"] = flat_repr["utilities"].name
|
2017-04-03 17:29:29 +02:00
|
|
|
|
|
|
|
return flat_repr
|