-
-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: listen to updates from Product Opener using Redis (#618)
- Loading branch information
1 parent
797c1bf
commit 9e4d326
Showing
10 changed files
with
347 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
59 changes: 59 additions & 0 deletions
59
open_prices/products/management/commands/run_update_listener.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import time | ||
|
||
from django.conf import settings | ||
from django.core.management.base import BaseCommand | ||
from openfoodfacts import Flavor | ||
from openfoodfacts.redis import RedisUpdate | ||
from openfoodfacts.redis import UpdateListener as BaseUpdateListener | ||
from openfoodfacts.redis import get_redis_client | ||
from openfoodfacts.utils import get_logger | ||
|
||
from open_prices.products.tasks import process_delete, process_update | ||
|
||
logger = get_logger() | ||
|
||
|
||
class UpdateListener(BaseUpdateListener): | ||
def process_redis_update(self, redis_update: RedisUpdate): | ||
logger.debug("New update: %s", redis_update) | ||
|
||
if redis_update.product_type == "food": | ||
flavor = Flavor.off | ||
elif redis_update.product_type == "beauty": | ||
redis_update.obf | ||
elif redis_update.product_type == "petfood": | ||
flavor = Flavor.opff | ||
elif redis_update.product_type == "product": | ||
flavor = Flavor.opf | ||
else: | ||
raise ValueError( | ||
f"no Flavor matched for product_type {redis_update.product_type}" | ||
) | ||
if redis_update.action == "deleted": | ||
logger.info("Product %s has been deleted", redis_update.code) | ||
process_delete(redis_update.code, flavor) | ||
elif redis_update.action == "updated": | ||
process_update(redis_update.code, flavor) | ||
|
||
|
||
class Command(BaseCommand): | ||
help = """Run a daemon that listens to product updates from Open Food Facts from a Redis stream.""" | ||
|
||
def handle(self, *args, **options) -> None: # type: ignore | ||
self.stdout.write("Launching the update listener...") | ||
|
||
if settings.ENABLE_REDIS_UPDATES is False: | ||
self.stdout.write("Redis updates are disabled, waiting forever...") | ||
|
||
while True: | ||
time.sleep(60) | ||
|
||
redis_client = get_redis_client( | ||
host=settings.REDIS_HOST, port=settings.REDIS_PORT | ||
) | ||
listener = UpdateListener( | ||
redis_client=redis_client, | ||
redis_stream_name=settings.REDIS_STREAM_NAME, | ||
redis_latest_id_key=settings.REDIS_LATEST_ID_KEY, | ||
) | ||
listener.run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,47 @@ | ||
import logging | ||
|
||
from openfoodfacts import Flavor | ||
|
||
from open_prices.common import openfoodfacts as common_openfoodfacts | ||
from open_prices.products.models import Product | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
def fetch_and_save_data_from_openfoodfacts(product: Product): | ||
product_openfoodfacts_details = common_openfoodfacts.get_product_dict(product) | ||
product_openfoodfacts_details = common_openfoodfacts.get_product_dict(product.code) | ||
if product_openfoodfacts_details: | ||
for key, value in product_openfoodfacts_details.items(): | ||
setattr(product, key, value) | ||
product.save() | ||
|
||
|
||
def process_update(code: str, flavor: Flavor): | ||
product_openfoodfacts_details = common_openfoodfacts.get_product_dict(code, flavor) | ||
|
||
if product_openfoodfacts_details: | ||
try: | ||
product = Product.objects.get(code=code) | ||
except Product.DoesNotExist: | ||
logger.info( | ||
"Product %s does not exist in the database, cannot update product table", | ||
code, | ||
) | ||
return | ||
|
||
for key, value in product_openfoodfacts_details.items(): | ||
setattr(product, key, value) | ||
product.save() | ||
|
||
|
||
def process_delete(code: str, flavor: Flavor): | ||
try: | ||
product = Product.objects.get(code=code) | ||
except Product.DoesNotExist: | ||
logger.info( | ||
"Product %s does not exist in the database, cannot delete product table", | ||
code, | ||
) | ||
return | ||
|
||
product.delete() |
Oops, something went wrong.