Skip to content

Commit

Permalink
[PP-2018] Replace email attachments with links to S3 on time tracking… (
Browse files Browse the repository at this point in the history
  • Loading branch information
dbernstein authored Dec 18, 2024
1 parent ff63d23 commit 44008e2
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ def run(self) -> None:

uid = uuid.uuid4()
key = (
f"inventory_and_holds/{library.short_name}/"
f"{S3Service.DOWNLOADS_PREFIX}/inventory_and_holds/{library.short_name}/"
f"inventory-and-holds-for-library-{file_name_modifier}-{uid}.zip"
)
self.s3_service.store_stream(
Expand Down
32 changes: 26 additions & 6 deletions src/palace/manager/scripts/playtime_entries.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import argparse
import csv
import os
import uuid
from collections import defaultdict
from collections.abc import Iterable
from datetime import datetime, timedelta
Expand All @@ -18,6 +19,7 @@

from palace.manager.core.config import Configuration
from palace.manager.scripts.base import Script
from palace.manager.service.storage.s3 import S3Service
from palace.manager.sqlalchemy.model.time_tracking import PlaytimeEntry, PlaytimeSummary
from palace.manager.util.datetime_helpers import previous_months, utc_now

Expand Down Expand Up @@ -182,17 +184,17 @@ def do_run(self):

email_subject = f"{subject_prefix}Playtime Summaries {formatted_start_date} - {formatted_until_date}"
reporting_name_with_no_spaces = reporting_name.replace(" ", "_") + "-"
attachment_extension = "csv"
attachment_name = (
link_extension = "csv"
linked_file_name = (
f"playtime-summary-{reporting_name_with_no_spaces}"
f"{formatted_start_date}-{formatted_until_date}.{attachment_extension}"
f"{formatted_start_date}-{formatted_until_date}.{link_extension}"
)

# Write to a temporary file so we don't overflow the memory
with TemporaryFile(
"w+",
prefix=f"playtimereport{formatted_until_date}",
suffix=attachment_extension,
suffix=link_extension,
) as temp:
# Write the data as a CSV
writer = csv.writer(temp)
Expand All @@ -207,12 +209,30 @@ def do_run(self):
recipient = os.environ.get(
Configuration.REPORTING_EMAIL_ENVIRONMENT_VARIABLE
)

if recipient:
uid = uuid.uuid4()
key = (
f"{S3Service.DOWNLOADS_PREFIX}/{reporting_name}/"
f"{linked_file_name}"
)

s3_service = self.services.storage.public()
s3_service.store_stream(
key,
temp,
content_type="text/csv",
)

s3_file_link = s3_service.generate_url(key)

self.services.email.send_email(
subject=email_subject,
receivers=[recipient],
text="",
attachments={attachment_name: temp.read()},
text=(
f"Download Report here -> {s3_file_link} \n\n"
f"This report will be available for download for 30 days."
),
)
else:
self.log.error("No reporting email found, logging complete report.")
Expand Down
1 change: 1 addition & 0 deletions src/palace/manager/service/storage/s3.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ def exception(self) -> BaseException | None:

class S3Service(LoggerMixin):
MINIMUM_MULTIPART_UPLOAD_SIZE = 5 * 1024 * 1024 # 5MB
DOWNLOADS_PREFIX = "downloads"

def __init__(
self,
Expand Down
16 changes: 11 additions & 5 deletions tests/manager/scripts/test_playtime_entries.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from palace.manager.sqlalchemy.model.time_tracking import PlaytimeEntry, PlaytimeSummary
from palace.manager.util.datetime_helpers import datetime_utc, previous_months, utc_now
from tests.fixtures.database import DatabaseTransactionFixture
from tests.fixtures.services import ServicesEmailFixture
from tests.fixtures.services import ServicesEmailFixture, ServicesFixture


def create_playtime_entries(
Expand Down Expand Up @@ -533,6 +533,7 @@ def test_do_run(
self,
db: DatabaseTransactionFixture,
services_email_fixture: ServicesEmailFixture,
services_fixture: ServicesFixture,
):
identifier = db.identifier()
collection = db.default_collection()
Expand Down Expand Up @@ -663,6 +664,11 @@ def test_do_run(
)

reporting_name = "test cm"

mock_s3_service = MagicMock()
mock_s3_service.generate_url.return_value = "http://test"
services_fixture.services.storage.public.override(mock_s3_service)

with (
patch("palace.manager.scripts.playtime_entries.csv.writer") as writer,
patch(
Expand Down Expand Up @@ -799,15 +805,15 @@ def test_do_run(
# verify the number of unique loans
assert len(loan_identifiers) == sum([x.args[0][7] for x in call_args[1:]])
assert services_email_fixture.mock_emailer.send.call_count == 1
mock_s3_service.store_stream.assert_called_once()
mock_s3_service.generate_url.assert_called_once()
assert services_email_fixture.mock_emailer.send.call_args == call(
subject=f"{reporting_name}: Playtime Summaries {cutoff} - {until}",
sender=services_email_fixture.sender_email,
receivers=["[email protected]"],
text="",
text="Download Report here -> http://test \n\nThis report will be available for download for 30 days.",
html=None,
attachments={
f"playtime-summary-{reporting_name.replace(' ', '_')}-{cutoff}-{until}.csv": ""
}, # Mock objects do not write data
attachments=None,
)

def test_no_reporting_email(self, db: DatabaseTransactionFixture):
Expand Down

0 comments on commit 44008e2

Please sign in to comment.