mirror of
https://github.com/almet/copanier.git
synced 2025-04-28 19:42:37 +02:00
When dupes are found, append a "-dedupe" to them.
This commit is contained in:
parent
2f2344d3b3
commit
4d17e28dd2
1 changed files with 41 additions and 8 deletions
|
@ -426,19 +426,52 @@ class Delivery(PersistedBase):
|
||||||
path = cls.get_root() / f"{id}.yml"
|
path = cls.get_root() / f"{id}.yml"
|
||||||
if not path.exists():
|
if not path.exists():
|
||||||
raise DoesNotExist
|
raise DoesNotExist
|
||||||
data = yaml.safe_load(path.read_text())
|
|
||||||
# Get the most common product key.
|
def _dedupe_products(raw_data):
|
||||||
# If we have multiple keys with the same name
|
"""On some rare occasions, different products get
|
||||||
# dedupe them by appending something to the newest of them.
|
the same identifier (ref).
|
||||||
if 'products' in data:
|
|
||||||
counter = Counter([i['ref'] for i in data['products']])
|
This function finds them and appends "-dedupe" to it.
|
||||||
|
This is not ideal but fixes the problem before it causes more
|
||||||
|
trouble (such as https://github.com/spiral-project/copanier/issues/136)
|
||||||
|
|
||||||
|
This function returns True if dupes have been found.
|
||||||
|
"""
|
||||||
|
if ('products' not in raw_data) or len(raw_data['products']) < 1:
|
||||||
|
return False
|
||||||
|
|
||||||
|
products = raw_data['products']
|
||||||
|
|
||||||
|
counter = Counter([p['ref'] for p in products])
|
||||||
most_common = counter.most_common(1)[0]
|
most_common = counter.most_common(1)[0]
|
||||||
if most_common[1] > 1:
|
number_of_dupes = most_common[1]
|
||||||
raise Exception(f'Duplicate product keys for "{most_common[0]}"')
|
|
||||||
|
if number_of_dupes < 2:
|
||||||
|
return False
|
||||||
|
|
||||||
|
dupe_id = most_common[0]
|
||||||
|
# Reconstruct the products list but change the duplicated ID.
|
||||||
|
counter = 0
|
||||||
|
new_products = []
|
||||||
|
for product in products:
|
||||||
|
ref = product['ref']
|
||||||
|
if ref == dupe_id:
|
||||||
|
counter = counter + 1
|
||||||
|
if counter == number_of_dupes: # Only change the last occurence.
|
||||||
|
product['ref'] = f'{ref}-dedupe'
|
||||||
|
new_products.append(product)
|
||||||
|
raw_data['products'] = new_products
|
||||||
|
return True
|
||||||
|
|
||||||
|
data = yaml.safe_load(path.read_text())
|
||||||
|
dupe_found = _dedupe_products(data)
|
||||||
# Tolerate extra fields (but we'll lose them if instance is persisted)
|
# Tolerate extra fields (but we'll lose them if instance is persisted)
|
||||||
data = {k: v for k, v in data.items() if k in cls.__dataclass_fields__}
|
data = {k: v for k, v in data.items() if k in cls.__dataclass_fields__}
|
||||||
delivery = cls(**data)
|
delivery = cls(**data)
|
||||||
delivery.id = id
|
delivery.id = id
|
||||||
|
|
||||||
|
if dupe_found:
|
||||||
|
delivery.persist()
|
||||||
return delivery
|
return delivery
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
Loading…
Reference in a new issue