Skip to content

Commit

Permalink
Merge pull request #31 from mlibrary/refactor-functions-to-item
Browse files Browse the repository at this point in the history
Refactor functions to item
  • Loading branch information
niquerio authored Dec 6, 2024
2 parents 7e333a5 + 62a9dfc commit 1ac772a
Show file tree
Hide file tree
Showing 8 changed files with 317 additions and 392 deletions.
20 changes: 13 additions & 7 deletions aim/cli/digifeeds.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from typing_extensions import Annotated
from aim.digifeeds.database import models, main
from aim.digifeeds import functions
from aim.digifeeds.item import get_item
from aim.services import S

import json
Expand Down Expand Up @@ -37,12 +38,15 @@ def add_to_digifeeds_set(
message="Start adding item to digifeeds set",
barcode=barcode,
)
item = functions.add_to_digifeeds_set(barcode)
if item.has_status("not_found_in_alma"):
item = get_item(barcode)
result = item.add_to_digifeeds_set()

if result.has_status("not_found_in_alma"):
S.logger.info(
"not_found_in_alma", message="Item not found in alma.", barcode=barcode
)
if item.has_status("added_to_digifeeds_set"):

if result.has_status("added_to_digifeeds_set"):
S.logger.info(
"added_to_digifeeds_set",
message="Item added to digifeeds set",
Expand Down Expand Up @@ -70,8 +74,9 @@ def check_zephir(
"""

print(f"Checking Zephir for {barcode}")
item = functions.check_zephir(barcode)
if item:
item = get_item(barcode)
result = item.check_zephir()
if result:
S.logger.info("in_zephir", message="Item is in zephir", barcode=barcode)
else:
S.logger.info("not_in_zephir", message="Item is NOT in zephir", barcode=barcode)
Expand Down Expand Up @@ -111,8 +116,9 @@ def move_to_pickup(
message="Start moving item from s3 bucket to pickup google drive",
barcode=barcode,
)
item = functions.move_to_pickup(barcode)
if item is None:
item = get_item(barcode)
result = item.move_to_pickup()
if result is None:
S.logger.info(
"not_in_zephir_long_enough",
message="Item has not been in zephir long enough",
Expand Down
87 changes: 0 additions & 87 deletions aim/digifeeds/functions.py
Original file line number Diff line number Diff line change
@@ -1,80 +1,6 @@
from aim.services import S
from aim.digifeeds.db_client import DBClient
from aim.digifeeds.item import Item
import requests
import boto3
from pathlib import Path
from rclone_python import rclone
from datetime import datetime
from aim.digifeeds.alma_client import AlmaClient
from requests.exceptions import HTTPError


def add_to_digifeeds_set(barcode: str):
"""
Adds a barcode to the digifeeds set and to the digifeeds database if it
doesn't already exist. If the barcode is in the digifeeds set already but
doesn't have an added_to_digifeeds_set status in the digifeeds db, that
status gets added.
Args:
barcode (str): Barcode of the item
Raises:
ext_inst: HTTPError
Returns:
aim.digifeeds.database.models.Item: Item object
"""
item = Item(DBClient().get_or_add_item(barcode))
if not item.has_status("added_to_digifeeds_set"):
try:
AlmaClient().add_barcode_to_digifeeds_set(barcode)
except HTTPError as ext_inst:
errorList = ext_inst.response.json()["errorList"]["error"]
if any(e["errorCode"] == "60120" for e in errorList):
if not item.has_status("not_found_in_alma"):
item = Item(
DBClient().add_item_status(
barcode=barcode, status="not_found_in_alma"
)
)
return item
elif any(e["errorCode"] == "60115" for e in errorList):
# 60115 means the barcode is already in the set. That means the
# db entry from this barcdoe needs to have
# added_to_digifeeds_set
pass
else:
raise ext_inst
item = Item(
DBClient().add_item_status(barcode=barcode, status="added_to_digifeeds_set")
)
return item


def move_to_pickup(barcode: str):
item = Item(DBClient().get_or_add_item(barcode))

if not item.in_zephir_for_long_enough:
return None

DBClient().add_item_status(barcode=barcode, status="copying_start")
rclone.copyto(
f"{S.digifeeds_s3_rclone_remote}:{S.digifeeds_s3_input_path}/{barcode}.zip",
f"{S.digifeeds_gdrive_rclone_remote}:{barcode}.zip",
)
DBClient().add_item_status(barcode=barcode, status="copying_end")
timestamp = datetime.now().strftime("%F_%H-%M-%S")
rclone.moveto(
f"{S.digifeeds_s3_rclone_remote}:{S.digifeeds_s3_input_path}/{barcode}.zip",
f"{S.digifeeds_s3_rclone_remote}:{S.digifeeds_s3_processed_path}/{timestamp}_{barcode}.zip",
)
final_raw_item = DBClient().add_item_status(
barcode=barcode, status="pending_deletion"
)

return final_raw_item


def list_barcodes_in_input_bucket():
Expand All @@ -87,16 +13,3 @@ def list_barcodes_in_input_bucket():
response = s3.list_objects_v2(Bucket=S.digifeeds_s3_bucket, Prefix=prefix)
barcodes = [Path(object["Key"]).stem for object in response["Contents"]]
return barcodes


def check_zephir(barcode: str):
item = Item(DBClient().get_or_add_item(barcode))
if item.has_status("in_zephir"):
return item

response = requests.get(f"{S.zephir_bib_api_url}/mdp.{barcode}")
if response.status_code == 200:
DBClient().add_item_status(barcode=barcode, status="in_zephir")
return item
else:
return None
74 changes: 74 additions & 0 deletions aim/digifeeds/item.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import requests
from rclone_python import rclone
from datetime import datetime, timedelta
from aim.digifeeds.alma_client import AlmaClient
from aim.digifeeds.db_client import DBClient
from aim.services import S
from requests.exceptions import HTTPError


class Item:
Expand Down Expand Up @@ -29,6 +35,70 @@ def has_status(self, status: str) -> bool:
"""
return any(s["name"] == status for s in self.data["statuses"])

def add_to_digifeeds_set(self):
if self.has_status("added_to_digifeeds_set"):
return self

try:
AlmaClient().add_barcode_to_digifeeds_set(self.barcode)
except HTTPError as ext_inst:
errorList = ext_inst.response.json()["errorList"]["error"]
if any(e["errorCode"] == "60120" for e in errorList):
if not self.has_status("not_found_in_alma"):
item = Item(
DBClient().add_item_status(
barcode=self.barcode, status="not_found_in_alma"
)
)
return item
elif any(e["errorCode"] == "60115" for e in errorList):
# 60115 means the barcode is already in the set. That means the
# db entry from this barcdoe needs to have
# added_to_digifeeds_set
pass
else:
raise ext_inst
item = Item(
DBClient().add_item_status(
barcode=self.barcode, status="added_to_digifeeds_set"
)
)
return item

def check_zephir(self):
if self.has_status("in_zephir"):
return self

response = requests.get(f"{S.zephir_bib_api_url}/mdp.{self.barcode}")
if response.status_code == 200:
db_resp = DBClient().add_item_status(
barcode=self.barcode, status="in_zephir"
)
return Item(db_resp)
else:
return None

def move_to_pickup(self):
if not self.in_zephir_for_long_enough:
return None

DBClient().add_item_status(barcode=self.barcode, status="copying_start")
rclone.copyto(
f"{S.digifeeds_s3_rclone_remote}:{S.digifeeds_s3_input_path}/{self.barcode}.zip",
f"{S.digifeeds_gdrive_rclone_remote}:{self.barcode}.zip",
)
DBClient().add_item_status(barcode=self.barcode, status="copying_end")
timestamp = datetime.now().strftime("%F_%H-%M-%S")
rclone.moveto(
f"{S.digifeeds_s3_rclone_remote}:{S.digifeeds_s3_input_path}/{self.barcode}.zip",
f"{S.digifeeds_s3_rclone_remote}:{S.digifeeds_s3_processed_path}/{timestamp}_{self.barcode}.zip",
)
db_resp = DBClient().add_item_status(
barcode=self.barcode, status="pending_deletion"
)

return Item(db_resp)

@property
def barcode(self) -> str:
"""The barcode of the Digifeeds item.
Expand Down Expand Up @@ -66,3 +136,7 @@ def in_zephir_for_long_enough(self) -> bool:
return True
else:
return False


def get_item(barcode: str) -> Item:
return Item(DBClient().get_or_add_item(barcode))
26 changes: 14 additions & 12 deletions tests/cli/test_digifeeds.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,12 @@ def test_add_to_db_where_item_is_not_in_digifeeds_set(item_data):
assert "added_to_digifeeds_set" in result.stdout


def test_add_to_db_where_item_is_not_in_alma(item_data, mocker):
item_data["statuses"][0]["name"] = "not_found_in_alma"
item = Item(item_data)
mocker.patch.object(functions, "add_to_digifeeds_set", return_value=item)
def test_add_to_db_where_item_is_not_in_alma(mocker):
item_mock = mocker.MagicMock(Item)
item_mock.has_status.side_effect = [True, False]
item_mock.add_to_digifeeds_set.return_value = item_mock

mocker.patch("aim.cli.digifeeds.get_item", return_value=item_mock)

result = runner.invoke(app, ["digifeeds", "add-to-digifeeds-set", "some_barcode"])
assert "not_found_in_alma" in result.stdout
Expand Down Expand Up @@ -119,24 +121,24 @@ def test_check_zephir_for_item_when_item_is_not_in_zephir(item_data):

def test_move_to_pickup_success(mocker, item_data):
item = Item(item_data)
move_volume_to_pickup_mock = mocker.patch.object(
functions, "move_to_pickup", return_value=item
)
item_mock = mocker.MagicMock(Item)
item_mock.move_to_pickup.return_value = item

mocker.patch("aim.cli.digifeeds.get_item", return_value=item_mock)

result = runner.invoke(app, ["digifeeds", "move-to-pickup", "some_barcode"])

move_volume_to_pickup_mock.assert_called_once()
assert "move_to_pickup_success" in result.stdout
assert result.exit_code == 0


def test_move_to_pickup_where_not_in_zephir(mocker):
move_volume_to_pickup_mock = mocker.patch.object(
functions, "move_to_pickup", return_value=None
)
item_mock = mocker.MagicMock(Item)
item_mock.move_to_pickup.return_value = None

mocker.patch("aim.cli.digifeeds.get_item", return_value=item_mock)

result = runner.invoke(app, ["digifeeds", "move-to-pickup", "some_barcode"])

move_volume_to_pickup_mock.assert_called_once()
assert "not_in_zephir_long_enough" in result.stdout
assert result.exit_code == 0
Loading

0 comments on commit 1ac772a

Please sign in to comment.