create Transpose Words automation

This commit is contained in:
smilerz 2023-04-24 11:58:21 -05:00
parent 8fa00972bd
commit 479cf1a042
No known key found for this signature in database
GPG Key ID: 39444C7606D47126
6 changed files with 56 additions and 10 deletions

View File

@ -13,6 +13,7 @@ class IngredientParser:
food_aliases = {}
unit_aliases = {}
never_unit = {}
transpose_words = {}
def __init__(self, request, cache_mode, ignore_automations=False):
"""
@ -50,10 +51,22 @@ class IngredientParser:
for a in Automation.objects.filter(space=self.request.space, disabled=False, type=Automation.NEVER_UNIT).only('param_1', 'param_2').order_by('order').all():
self.never_unit[a.param_1] = a.param_2
caches['default'].set(NEVER_UNIT_CACHE_KEY, self.never_unit, 30)
TRANSPOSE_WORDS_CACHE_KEY = f'automation_transpose_words_{self.request.space.pk}'
if c := caches['default'].get(TRANSPOSE_WORDS_CACHE_KEY, None):
self.transpose_words = c
caches['default'].touch(TRANSPOSE_WORDS_CACHE_KEY, 30)
else:
i = 0
for a in Automation.objects.filter(space=self.request.space, disabled=False, type=Automation.TRANSPOSE_WORDS).only('param_1', 'param_2').order_by('order').all():
self.never_unit[i] = [a.param_1, a.param_2]
i += 1
caches['default'].set(TRANSPOSE_WORDS_CACHE_KEY, self.transpose_words, 30)
else:
self.food_aliases = {}
self.unit_aliases = {}
self.never_unit = {}
self.transpose_words = {}
def apply_food_automation(self, food):
"""
@ -83,7 +96,7 @@ class IngredientParser:
if self.ignore_rules:
return unit
else:
if self.unit_aliases:
if self.transpose_words:
try:
return self.unit_aliases[unit]
except KeyError:
@ -249,15 +262,31 @@ class IngredientParser:
return tokens
def parse_tokens(self, tokens):
def apply_transpose_words_automations(self, ingredient):
"""
parser that applies automations to unmodified tokens
If two words (param_1 & param_2) are detected in sequence, swap their position in the ingredient string
:param 1: first word to detect
:param 2: second word to detect
return: new ingredient string
"""
####################################################
####################################################
####################################################
####################################################
if self.ignore_rules:
return tokens
return ingredient
return self.apply_never_unit_automations(tokens)
else:
if self.transpose_words:
for rule in self.transpose_words:
ingredient = re.sub(rf"\b({rule[0]}) ({rule[1]})\b", r"\2 \1", ingredient)
else:
for rule in Automation.objects.filter(space=self.request.space, type=Automation.TRANSPOSE_WORDS, disabled=False).order_by('order'):
ingredient = re.sub(rf"\b({rule.param_1}) ({rule.param_2})\b", r"\2 \1", ingredient)
return ingredient
def parse(self, ingredient):
"""
@ -275,6 +304,8 @@ class IngredientParser:
if len(ingredient) == 0:
raise ValueError('string to parse cannot be empty')
ingredient = self.apply_transpose_words_automations(ingredient)
# some people/languages put amount and unit at the end of the ingredient string
# if something like this is detected move it to the beginning so the parser can handle it
if len(ingredient) < 1000 and re.search(r'^([^\W\d_])+(.)*[1-9](\d)*\s*([^\W\d_])+', ingredient):
@ -311,7 +342,7 @@ class IngredientParser:
# three arguments if it already has a unit there can't be
# a fraction for the amount
if len(tokens) > 2:
tokens = self.parse_tokens(tokens)
tokens = self.apply_never_unit_automations(tokens)
try:
if unit is not None:
# a unit is already found, no need to try the second argument for a fraction

View File

@ -1,4 +1,4 @@
# Generated by Django 4.1.7 on 2023-04-24 15:00
# Generated by Django 4.1.7 on 2023-04-24 16:22
from django.db import migrations, models
@ -13,7 +13,7 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='automation',
name='type',
field=models.CharField(choices=[('FOOD_ALIAS', 'Food Alias'), ('UNIT_ALIAS', 'Unit Alias'), ('KEYWORD_ALIAS', 'Keyword Alias'), ('DESCRIPTION_REPLACE', 'Description Replace'), ('INSTRUCTION_REPLACE', 'Instruction Replace'), ('NEVER_UNIT', 'Never Unit')], max_length=128),
field=models.CharField(choices=[('FOOD_ALIAS', 'Food Alias'), ('UNIT_ALIAS', 'Unit Alias'), ('KEYWORD_ALIAS', 'Keyword Alias'), ('DESCRIPTION_REPLACE', 'Description Replace'), ('INSTRUCTION_REPLACE', 'Instruction Replace'), ('NEVER_UNIT', 'Never Unit'), ('TRANSPOSE_WORDS', 'Transpose Words')], max_length=128),
),
migrations.AlterField(
model_name='userpreference',

View File

@ -1320,11 +1320,12 @@ class Automation(ExportModelOperationsMixin('automations'), models.Model, Permis
DESCRIPTION_REPLACE = 'DESCRIPTION_REPLACE'
INSTRUCTION_REPLACE = 'INSTRUCTION_REPLACE'
NEVER_UNIT = 'NEVER_UNIT'
TRANSPOSE_WORDS = 'TRANSPOSE_WORDS'
type = models.CharField(max_length=128,
choices=((FOOD_ALIAS, _('Food Alias')), (UNIT_ALIAS, _('Unit Alias')), (KEYWORD_ALIAS, _('Keyword Alias')),
(DESCRIPTION_REPLACE, _('Description Replace')), (INSTRUCTION_REPLACE, _('Instruction Replace')),
(NEVER_UNIT, _('Never Unit')),))
(NEVER_UNIT, _('Never Unit')), (TRANSPOSE_WORDS, _('Transpose Words')),))
name = models.CharField(max_length=128, default='')
description = models.TextField(blank=True, null=True)

View File

@ -68,6 +68,17 @@ You can also create them manually by setting the following
These rules are processed whenever you are importing recipes from websites or other apps
and when using the simple ingredient input (shopping, recipe editor, ...).
## Transpose Words
Some recipes list the food before the units for some foods (garlic cloves). This automation will transpose 2 words in an
ingredient so "garlic cloves" will automatically become "cloves garlic"
- **Parameter 1**: first word to detect
- **Parameter 2**: second word to detect
These rules are processed whenever you are importing recipes from websites or other apps
and when using the simple ingredient input (shopping, recipe editor, ...).
# Order
If the Automation type allows for more than one rule to be executed (for example description replace)

View File

@ -527,5 +527,6 @@
"plural_usage_info": "Use the plural form for units and food inside this space.",
"Create Recipe": "Create Recipe",
"Import Recipe": "Import Recipe",
"Never_Unit": "Never Unit"
"Never_Unit": "Never Unit",
"Transpose_Words": "Transpose Words"
}

View File

@ -558,6 +558,8 @@ export class Models {
{ value: "KEYWORD_ALIAS", text: "Keyword_Alias" },
{ value: "DESCRIPTION_REPLACE", text: "Description_Replace" },
{ value: "INSTRUCTION_REPLACE", text: "Instruction_Replace" },
{ value: "NEVER_UNIT", text: "Never_Unit" },
{ value: "TRANSPOSE_WORDS", text: "Transpose_Words" },
],
field: "type",
label: "Type",