Various bug fixes
Fix some bugs introduced in recent developments as well as some UI issues (and i18n). Closes issue #42.
This commit is contained in:
parent
49f5b6a714
commit
a5aeadef86
@ -35,6 +35,7 @@ def filter_flats(config, flats_list, fetch_details=True):
|
|||||||
|
|
||||||
first_pass_result = collections.defaultdict(list)
|
first_pass_result = collections.defaultdict(list)
|
||||||
second_pass_result = collections.defaultdict(list)
|
second_pass_result = collections.defaultdict(list)
|
||||||
|
third_pass_result = collections.defaultdict(list)
|
||||||
# Do a first pass with the available infos to try to remove as much
|
# Do a first pass with the available infos to try to remove as much
|
||||||
# unwanted postings as possible
|
# unwanted postings as possible
|
||||||
if config["passes"] > 0:
|
if config["passes"] > 0:
|
||||||
@ -58,14 +59,25 @@ def filter_flats(config, flats_list, fetch_details=True):
|
|||||||
else:
|
else:
|
||||||
second_pass_result["new"] = first_pass_result["new"]
|
second_pass_result["new"] = first_pass_result["new"]
|
||||||
|
|
||||||
|
# Do a third pass to deduplicate better
|
||||||
|
if config["passes"] > 2:
|
||||||
|
third_pass_result = flatisfy.filters.third_pass(
|
||||||
|
second_pass_result["new"], config
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
third_pass_result["new"] = second_pass_result["new"]
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"new": second_pass_result["new"],
|
"new": third_pass_result["new"],
|
||||||
"duplicate": (
|
"duplicate": (
|
||||||
first_pass_result["duplicate"] +
|
first_pass_result["duplicate"] +
|
||||||
second_pass_result["duplicate"]
|
second_pass_result["duplicate"] +
|
||||||
|
third_pass_result["duplicate"]
|
||||||
),
|
),
|
||||||
"ignored": (
|
"ignored": (
|
||||||
first_pass_result["ignored"] + second_pass_result["ignored"]
|
first_pass_result["ignored"] +
|
||||||
|
second_pass_result["ignored"] +
|
||||||
|
third_pass_result["ignored"]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ DEFAULT_CONFIG = {
|
|||||||
# Navitia API key
|
# Navitia API key
|
||||||
"navitia_api_key": None,
|
"navitia_api_key": None,
|
||||||
# Number of filtering passes to run
|
# Number of filtering passes to run
|
||||||
"passes": 2,
|
"passes": 3,
|
||||||
# Maximum number of entries to fetch
|
# Maximum number of entries to fetch
|
||||||
"max_entries": None,
|
"max_entries": None,
|
||||||
# Directory in wich data will be put. ``None`` is XDG default location.
|
# Directory in wich data will be put. ``None`` is XDG default location.
|
||||||
@ -129,7 +129,7 @@ def validate_config(config):
|
|||||||
assert "time" in item
|
assert "time" in item
|
||||||
_check_constraints_bounds(item["time"])
|
_check_constraints_bounds(item["time"])
|
||||||
|
|
||||||
assert config["passes"] in [0, 1, 2]
|
assert config["passes"] in [0, 1, 2, 3]
|
||||||
assert config["max_entries"] is None or (isinstance(config["max_entries"], int) and config["max_entries"] > 0) # noqa: E501
|
assert config["max_entries"] is None or (isinstance(config["max_entries"], int) and config["max_entries"] > 0) # noqa: E501
|
||||||
|
|
||||||
assert config["data_directory"] is None or isinstance(config["data_directory"], str) # noqa: E501
|
assert config["data_directory"] is None or isinstance(config["data_directory"], str) # noqa: E501
|
||||||
|
@ -44,13 +44,14 @@ def refine_with_housing_criteria(flats_list, config):
|
|||||||
|
|
||||||
# Check time_to
|
# Check time_to
|
||||||
for place_name, time in flat["flatisfy"].get("time_to", {}).items():
|
for place_name, time in flat["flatisfy"].get("time_to", {}).items():
|
||||||
|
time = time["time"]
|
||||||
is_within_interval = tools.is_within_interval(
|
is_within_interval = tools.is_within_interval(
|
||||||
time,
|
time,
|
||||||
*(config["constraints"]["time_to"][place_name]["time"])
|
*(config["constraints"]["time_to"][place_name]["time"])
|
||||||
)
|
)
|
||||||
if not is_within_interval:
|
if not is_within_interval:
|
||||||
LOGGER.info("Flat %s is too far from place %s.",
|
LOGGER.info("Flat %s is too far from place %s: %ds.",
|
||||||
flat["id"], place_name)
|
flat["id"], place_name, time)
|
||||||
is_ok[i] = is_ok[i] and is_within_interval
|
is_ok[i] = is_ok[i] and is_within_interval
|
||||||
|
|
||||||
# Check other fields
|
# Check other fields
|
||||||
@ -148,14 +149,32 @@ def second_pass(flats_list, config):
|
|||||||
# Compute travel time to specified points
|
# Compute travel time to specified points
|
||||||
flats_list = metadata.compute_travel_times(flats_list, config)
|
flats_list = metadata.compute_travel_times(flats_list, config)
|
||||||
|
|
||||||
# Deduplicate the list using every available data
|
|
||||||
flats_list, duplicate_flats = duplicates.deep_detect(flats_list)
|
|
||||||
|
|
||||||
# Remove returned housing posts that do not match criteria
|
# Remove returned housing posts that do not match criteria
|
||||||
flats_list, ignored_list = refine_with_housing_criteria(flats_list, config)
|
flats_list, ignored_list = refine_with_housing_criteria(flats_list, config)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"new": flats_list,
|
"new": flats_list,
|
||||||
"ignored": ignored_list,
|
"ignored": ignored_list,
|
||||||
|
"duplicate": []
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def third_pass(flats_list, config):
|
||||||
|
"""
|
||||||
|
Third filtering pass.
|
||||||
|
|
||||||
|
This pass is expected to perform deep duplicate detection on available
|
||||||
|
flats.
|
||||||
|
|
||||||
|
:param flats_list: A list of flats dict to filter.
|
||||||
|
:param config: A config dict.
|
||||||
|
:return: A dict mapping flat status and list of flat objects.
|
||||||
|
"""
|
||||||
|
# Deduplicate the list using every available data
|
||||||
|
flats_list, duplicate_flats = duplicates.deep_detect(flats_list)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"new": flats_list,
|
||||||
|
"ignored": [],
|
||||||
"duplicate": duplicate_flats
|
"duplicate": duplicate_flats
|
||||||
}
|
}
|
||||||
|
@ -184,6 +184,7 @@ def deep_detect(flats_list):
|
|||||||
the flats objects that should be removed and considered as duplicates (they
|
the flats objects that should be removed and considered as duplicates (they
|
||||||
were already merged).
|
were already merged).
|
||||||
"""
|
"""
|
||||||
|
LOGGER.info("Running deep duplicates detection.")
|
||||||
matching_flats = collections.defaultdict(list)
|
matching_flats = collections.defaultdict(list)
|
||||||
for i, flat1 in enumerate(flats_list):
|
for i, flat1 in enumerate(flats_list):
|
||||||
matching_flats[flat1["id"]].append(flat1["id"])
|
matching_flats[flat1["id"]].append(flat1["id"])
|
||||||
|
@ -268,6 +268,10 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
updateFlatStatus (status) {
|
||||||
|
this.$store.dispatch('updateFlatStatus', { flatId: this.$route.params.id, newStatus: status })
|
||||||
|
},
|
||||||
|
|
||||||
updateFlatNotes () {
|
updateFlatNotes () {
|
||||||
const notes = this.$refs.notesTextarea.value
|
const notes = this.$refs.notesTextarea.value
|
||||||
this.$store.dispatch(
|
this.$store.dispatch(
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<h2>{{ $t("home.new_available_flats") }}</h2>
|
<h2>{{ $t("home.new_available_flats") }}</h2>
|
||||||
<template v-if="Object.keys(postalCodesFlatsBuckets).length > 0">
|
<template v-if="Object.keys(postalCodesFlatsBuckets).length > 0">
|
||||||
<template v-for="(postal_code_data, postal_code) in postalCodesFlatsBuckets">
|
<template v-for="(postal_code_data, postal_code) in postalCodesFlatsBuckets">
|
||||||
<h3>{{ postal_code_data.name }} ({{ postal_code }}) - {{ postal_code_data.flats.length }} {{ $tc("common.flats", Object.keys(postalCodesFlatsBuckets).length) }}</h3>
|
<h3>{{ postal_code_data.name }} ({{ postal_code }}) - {{ postal_code_data.flats.length }} {{ $tc("common.flats", postal_code_data.flats.length) }}</h3>
|
||||||
<FlatsTable :flats="postal_code_data.flats"></FlatsTable>
|
<FlatsTable :flats="postal_code_data.flats"></FlatsTable>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template v-else-if="Object.keys(postalCodesFlatsBuckets).length > 0">
|
<template v-else-if="Object.keys(postalCodesFlatsBuckets).length > 0">
|
||||||
<template v-for="(postal_code_data, postal_code) in postalCodesFlatsBuckets">
|
<template v-for="(postal_code_data, postal_code) in postalCodesFlatsBuckets">
|
||||||
<h3>{{ postal_code_data.name }} ({{ postal_code }}) - {{ postal_code_data.flats.length }} {{ $tc("common.flats", Object.keys(postalCodesFlatsBuckets).length) }}</h3>
|
<h3>{{ postal_code_data.name }} ({{ postal_code }}) - {{ postal_code_data.flats.length }} {{ $tc("common.flats", postal_code_data.flats.length) }}</h3>
|
||||||
<FlatsTable :flats="postal_code_data.flats"></FlatsTable>
|
<FlatsTable :flats="postal_code_data.flats"></FlatsTable>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
@ -47,7 +47,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return this.$store.getters.postalCodesFlatsBuckets(
|
return this.$store.getters.postalCodesFlatsBuckets(
|
||||||
flat => flat.status !== 'duplicate' && flat.status !== 'ignored'
|
flat => flat.status !== 'duplicate' && flat.status !== 'ignored' && flat.status !== "user_deleted"
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
loading () {
|
loading () {
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
</h2>
|
</h2>
|
||||||
<template v-if="Object.keys(postalCodesFlatsBuckets).length">
|
<template v-if="Object.keys(postalCodesFlatsBuckets).length">
|
||||||
<template v-for="(postal_code_data, postal_code) in postalCodesFlatsBuckets">
|
<template v-for="(postal_code_data, postal_code) in postalCodesFlatsBuckets">
|
||||||
<h3>{{ postal_code_data.name }} ({{ postal_code }}) - {{ postal_code_data.flats.length }} {{ $tc("common.flats", Object.keys(postalCodesFlatsBuckets).length) }}</h3>
|
<h3>{{ postal_code_data.name }} ({{ postal_code }}) - {{ postal_code_data.flats.length }} {{ $tc("common.flats", postal_code_data.flats.length) }}</h3>
|
||||||
<FlatsTable :flats="postal_code_data.flats"></FlatsTable>
|
<FlatsTable :flats="postal_code_data.flats"></FlatsTable>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
@ -191,7 +191,7 @@ def update_flat_notation_v1(flat_id, db):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
flat.notation = json.load(bottle.request.body)["notation"]
|
flat.notation = json.load(bottle.request.body)["notation"]
|
||||||
assert flat.notes >= 0 and flat.notes <= 5
|
assert flat.notation >= 0 and flat.notation <= 5
|
||||||
except (AssertionError, ValueError, KeyError):
|
except (AssertionError, ValueError, KeyError):
|
||||||
return bottle.HTTPError(400, "Invalid notation provided.")
|
return bottle.HTTPError(400, "Invalid notation provided.")
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user