|
1 | | -from ted_sws.notice_publisher.adapters.notice_publisher import NoticePublisherABC |
2 | | -from ted_sws.notice_publisher.adapters.sftp_notice_publisher import SFTPNoticePublisher |
3 | | -from ted_sws.core.model.notice import Notice, NoticeStatus |
4 | | -from ted_sws.data_manager.adapters.notice_repository import NoticeRepositoryABC |
5 | 1 | import base64 |
6 | 2 | import tempfile |
| 3 | +from pathlib import Path |
| 4 | +from typing import Union |
| 5 | + |
| 6 | +from ted_sws import config |
| 7 | +from ted_sws.core.model.notice import Notice, NoticeStatus, UnsupportedStatusTransition |
| 8 | +from ted_sws.data_manager.adapters.notice_repository import NoticeRepositoryABC |
| 9 | +from ted_sws.notice_packager.adapters.archiver import ARCHIVE_DEFAULT_FORMAT |
| 10 | +from ted_sws.notice_publisher.adapters.notice_publisher import NoticePublisherFactory |
| 11 | +from ted_sws.notice_publisher.adapters.notice_publisher_abc import NoticePublisherABC |
| 12 | + |
| 13 | + |
| 14 | +class NoticePublishBuilder: |
| 15 | + def __init__(self, notice: Union[Notice, str], notice_repository: NoticeRepositoryABC, |
| 16 | + notice_publisher: NoticePublisherABC, remote_path: str = None): |
| 17 | + self.notice_repository = notice_repository |
| 18 | + if isinstance(notice, str): |
| 19 | + notice_id = notice |
| 20 | + notice: Notice = self.notice_repository.get(reference=notice_id) |
| 21 | + if notice is None: |
| 22 | + raise Exception(f"Notice {notice_id} could not be found.") |
| 23 | + |
| 24 | + self.notice = notice |
| 25 | + self.check_publish_eligibility() |
7 | 26 |
|
| 27 | + self.notice_publisher = notice_publisher |
| 28 | + self.remote_path = remote_path |
8 | 29 |
|
9 | | -def publish_notice_package(notice: Notice, notice_publisher: NoticePublisherABC, notice_repository: NoticeRepositoryABC, |
10 | | - remote_path=None): |
11 | | - mets_manifestation = notice.mets_manifestation |
12 | | - if not mets_manifestation: |
13 | | - raise ValueError("Notice does not have a METS manifestation to be published.") |
| 30 | + def check_publish_eligibility(self): |
| 31 | + if self.notice.status != NoticeStatus.ELIGIBLE_FOR_PUBLISHING: |
| 32 | + raise UnsupportedStatusTransition( |
| 33 | + f"Notice {self.notice.ted_id} is not Eligible for Publishing. Status: {self.notice.status}") |
14 | 34 |
|
15 | | - package_content = base64.b64decode(bytes(mets_manifestation.object_data), validate=True) |
| 35 | + def package_content(self) -> bytes: |
| 36 | + mets_manifestation = self.notice.mets_manifestation |
| 37 | + if not mets_manifestation or not mets_manifestation.object_data: |
| 38 | + raise ValueError("Notice does not have a METS manifestation to be published.") |
16 | 39 |
|
17 | | - source_file = tempfile.NamedTemporaryFile() |
18 | | - source_file.write(package_content) |
| 40 | + package_content = base64.b64decode(bytes(mets_manifestation.object_data, encoding='utf-8'), validate=True) |
| 41 | + return package_content |
19 | 42 |
|
20 | | - if notice_publisher.upload(source_file, remote_path): |
21 | | - notice.update_status_to(NoticeStatus.PUBLISHED) |
22 | | - notice_repository.update(notice) |
23 | | - else: |
24 | | - raise Exception(f"Notice {notice.ted_id} could not be published.") |
| 43 | + def build_remote_path(self) -> str: |
| 44 | + remote_path = self.remote_path |
| 45 | + if remote_path is None: |
| 46 | + remote_path = f"{config.SFTP_PATH}/{self.notice.ted_id}" |
| 47 | + if ARCHIVE_DEFAULT_FORMAT == "zip": |
| 48 | + remote_path += '.zip' |
| 49 | + return remote_path |
25 | 50 |
|
| 51 | + def publish(self): |
| 52 | + source_file = tempfile.NamedTemporaryFile() |
| 53 | + source_file.write(self.package_content()) |
26 | 54 |
|
27 | | -def publish_notice(notice: Notice, notice_repository: NoticeRepositoryABC, hostname, username, password, |
28 | | - remote_path=None, port=22): |
29 | | - notice_publisher = SFTPNoticePublisher(hostname=hostname, username=username, password=password, port=port, |
30 | | - remote_path=remote_path) |
| 55 | + try: |
| 56 | + if self.notice_publisher.publish(source_path=Path(source_file.name), remote_path=self.build_remote_path()): |
| 57 | + self.notice.update_status_to(NoticeStatus.PUBLISHED) |
| 58 | + self.notice_repository.update(self.notice) |
| 59 | + except Exception as e: |
| 60 | + raise Exception(f"Notice {self.notice.ted_id} could not be published: " + str(e)) |
| 61 | + |
| 62 | + return self.notice.status == NoticeStatus.PUBLISHED |
| 63 | + |
| 64 | + |
| 65 | +def publish_notice(notice: Union[Notice, str], notice_publisher: NoticePublisherABC, |
| 66 | + notice_repository: NoticeRepositoryABC, remote_path=None) -> bool: |
| 67 | + publish_builder = NoticePublishBuilder(notice, notice_repository, notice_publisher, remote_path) |
| 68 | + return publish_builder.publish() |
| 69 | + |
| 70 | + |
| 71 | +def publish_single_notice(notice: Union[Notice, str], notice_repository: NoticeRepositoryABC, hostname, username, |
| 72 | + password, port=None, remote_path=None) -> bool: |
| 73 | + notice_publisher: NoticePublisherABC = NoticePublisherFactory.get_publisher(hostname=hostname, username=username, |
| 74 | + password=password, port=port, |
| 75 | + remote_path=remote_path) |
31 | 76 | notice_publisher.connect() |
32 | | - publish_notice_package(notice, notice_publisher, notice_repository) |
| 77 | + notice_published: bool = publish_notice(notice, notice_publisher, notice_repository, remote_path) |
33 | 78 | notice_publisher.disconnect() |
34 | | - pass |
| 79 | + |
| 80 | + return notice_published |
0 commit comments