From 6110a01e090130a3de96cf242c4533378dcf7e05 Mon Sep 17 00:00:00 2001 From: Yugay Vasiliy Date: Mon, 8 Apr 2024 11:12:26 +0000 Subject: [PATCH 1/3] * Added endpoint to get preceding signs for specific sign and sortkey * Added method to mongo_sign_repository for getting preceding signs --- .../infrastructure/mongo_sign_repository.py | 45 +++++++++++++++++++ ebl/signs/web/bootstrap.py | 4 +- ebl/signs/web/signs.py | 10 +++++ 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/ebl/signs/infrastructure/mongo_sign_repository.py b/ebl/signs/infrastructure/mongo_sign_repository.py index cd8bf8be8..ec2f65e10 100644 --- a/ebl/signs/infrastructure/mongo_sign_repository.py +++ b/ebl/signs/infrastructure/mongo_sign_repository.py @@ -43,6 +43,12 @@ def filter_none(self, data, **kwargs): return {key: value for key, value in data.items() if value is not None} +class OrderedSignSchema(Schema): + name = fields.String(required=True) + unicode = fields.List(fields.Int(), required=True) + sort_key = fields.Int(required=True) + + class LogogramSchema(Schema): logogram = fields.String(required=True) atf = fields.String(required=True) @@ -101,6 +107,10 @@ def make_sign(self, data, **kwargs) -> Sign: return Sign(**data) +class OrderedSignsSchema(Schema): + ordered_signs = fields.Nested(OrderedSignSchema, many=True, data_key="signs") + + class SignDtoSchema(SignSchema): @post_dump def make_sign_dto(self, data, **kwargs) -> Dict: @@ -123,6 +133,41 @@ def find(self, name: SignName) -> Sign: data = self._collection.find_one_by_id(name) return cast(Sign, SignSchema(unknown=EXCLUDE).load(data)) + def find_signs_by_order(self, name: SignName, order: str, sort_era: str) -> Sign: + key = self._collection.find_one_by_id(name)["sortKeys"][sort_era][0] + if order == "preceding": + cursor = self._collection.aggregate( + [ + { + "$match": { + f"sortKeys.{sort_era}": { + "$elemMatch": {"$lt": key, "$gte": key - 5} + } + } + }, + {"$unwind": f"$sortKeys.{sort_era}"}, + {"$match": {f"sortKeys.{sort_era}": {"$lt": key, "$gt": key - 5}}}, + { + "$project": { + "sign": 1, + "unicode": 1, + "name": "$_id", + "sort_key": f"$sortKeys.{sort_era}", + } + }, + {"$sort": {"sort_key": 1}}, + {"$group": {"_id": "1", "signs": {"$push": "$$ROOT"}}}, + { + "$project": { + "signs.name": 1, + "signs.unicode": 1, + "signs.sort_key": 1, + } + }, + ] + ) + return OrderedSignsSchema().load(cursor, unknown=EXCLUDE, many=True) + def search(self, reading: str, sub_index: Optional[int] = None) -> Optional[Sign]: sub_index_query = {"$exists": False} if sub_index is None else sub_index try: diff --git a/ebl/signs/web/bootstrap.py b/ebl/signs/web/bootstrap.py index 1f8fb42c2..d042c6c88 100644 --- a/ebl/signs/web/bootstrap.py +++ b/ebl/signs/web/bootstrap.py @@ -5,13 +5,14 @@ CroppedAnnotationService, ) from ebl.signs.web.sign_search import SignsSearch -from ebl.signs.web.signs import SignsResource, SignsListResource +from ebl.signs.web.signs import SignsResource, SignsListResource, SignsOrderResource from ebl.signs.web.cropped_annotations import CroppedAnnotationsResource def create_signs_routes(api: falcon.App, context: Context): signs_search = SignsSearch(context.sign_repository) signs = SignsResource(context.sign_repository) + ordered_signs = SignsOrderResource(context.sign_repository) signs_images = CroppedAnnotationsResource( CroppedAnnotationService( context.annotations_repository, @@ -24,3 +25,4 @@ def create_signs_routes(api: falcon.App, context: Context): api.add_route("/signs/{sign_name}", signs) api.add_route("/signs/{sign_name}/images", signs_images) api.add_route("/signs/all", signs_all) + api.add_route("/signs/{sign_name}/{order}/{sort_era}", ordered_signs) diff --git a/ebl/signs/web/signs.py b/ebl/signs/web/signs.py index 5f6e975d6..baf2529a2 100644 --- a/ebl/signs/web/signs.py +++ b/ebl/signs/web/signs.py @@ -35,3 +35,13 @@ def __init__(self, signs: SignRepository): def on_get(self, req, resp): resp.media = self.sign_repository.list_all_signs() + + +class SignsOrderResource: + def __init__(self, signs: SignRepository): + self.sign_repository = signs + + def on_get(self, req, resp, sign_name, order, sort_era): + resp.media = self.sign_repository.find_signs_by_order( + sign_name, order, sort_era + ) From 92c1016851f19d5cd9469e7217ad932498837a55 Mon Sep 17 00:00:00 2001 From: Yugay Vasiliy Date: Mon, 15 Apr 2024 07:59:45 +0000 Subject: [PATCH 2/3] added endpoint for the following signs --- .../infrastructure/mongo_sign_repository.py | 73 ++++++++++++------- 1 file changed, 45 insertions(+), 28 deletions(-) diff --git a/ebl/signs/infrastructure/mongo_sign_repository.py b/ebl/signs/infrastructure/mongo_sign_repository.py index ec2f65e10..be52f54ec 100644 --- a/ebl/signs/infrastructure/mongo_sign_repository.py +++ b/ebl/signs/infrastructure/mongo_sign_repository.py @@ -136,37 +136,54 @@ def find(self, name: SignName) -> Sign: def find_signs_by_order(self, name: SignName, order: str, sort_era: str) -> Sign: key = self._collection.find_one_by_id(name)["sortKeys"][sort_era][0] if order == "preceding": - cursor = self._collection.aggregate( - [ - { - "$match": { - f"sortKeys.{sort_era}": { - "$elemMatch": {"$lt": key, "$gte": key - 5} + range_start = "$lt" + range_end = "$gte" + end_key = key - 5 + elif order == "following": + range_start = "$gt" + range_end = "$lte" + end_key = key + 5 + cursor = self._collection.aggregate( + [ + { + "$match": { + f"sortKeys.{sort_era}": { + "$elemMatch": { + f"{range_start}": key, + f"{range_end}": end_key, } } - }, - {"$unwind": f"$sortKeys.{sort_era}"}, - {"$match": {f"sortKeys.{sort_era}": {"$lt": key, "$gt": key - 5}}}, - { - "$project": { - "sign": 1, - "unicode": 1, - "name": "$_id", - "sort_key": f"$sortKeys.{sort_era}", - } - }, - {"$sort": {"sort_key": 1}}, - {"$group": {"_id": "1", "signs": {"$push": "$$ROOT"}}}, - { - "$project": { - "signs.name": 1, - "signs.unicode": 1, - "signs.sort_key": 1, + } + }, + {"$unwind": f"$sortKeys.{sort_era}"}, + { + "$match": { + f"sortKeys.{sort_era}": { + f"{range_start}": key, + f"{range_end}": end_key, } - }, - ] - ) - return OrderedSignsSchema().load(cursor, unknown=EXCLUDE, many=True) + } + }, + { + "$project": { + "sign": 1, + "unicode": 1, + "name": "$_id", + "sort_key": f"$sortKeys.{sort_era}", + } + }, + {"$sort": {"sort_key": 1}}, + {"$group": {"_id": "1", "signs": {"$push": "$$ROOT"}}}, + { + "$project": { + "signs.name": 1, + "signs.unicode": 1, + "signs.sort_key": 1, + } + }, + ] + ) + return OrderedSignsSchema().load(cursor, unknown=EXCLUDE, many=True) def search(self, reading: str, sub_index: Optional[int] = None) -> Optional[Sign]: sub_index_query = {"$exists": False} if sub_index is None else sub_index From 551745f7c0af5d4d32f6f05a843ee3342772e9b3 Mon Sep 17 00:00:00 2001 From: Yugay Vasiliy Date: Mon, 22 Apr 2024 12:21:43 +0000 Subject: [PATCH 3/3] typecheck errors fixed --- ebl/signs/infrastructure/mongo_sign_repository.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/ebl/signs/infrastructure/mongo_sign_repository.py b/ebl/signs/infrastructure/mongo_sign_repository.py index be52f54ec..604cba7df 100644 --- a/ebl/signs/infrastructure/mongo_sign_repository.py +++ b/ebl/signs/infrastructure/mongo_sign_repository.py @@ -135,11 +135,10 @@ def find(self, name: SignName) -> Sign: def find_signs_by_order(self, name: SignName, order: str, sort_era: str) -> Sign: key = self._collection.find_one_by_id(name)["sortKeys"][sort_era][0] - if order == "preceding": - range_start = "$lt" - range_end = "$gte" - end_key = key - 5 - elif order == "following": + range_start = "$lt" + range_end = "$gte" + end_key = key - 5 + if order == "following": range_start = "$gt" range_end = "$lte" end_key = key + 5