Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto increase date range package tag module #39

Merged
merged 1 commit into from
Jan 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions bin/package
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env python

import pathlib
import sys

rootdir = pathlib.Path(__file__).parent.parent
sys.path.append(str(rootdir))

import odp.logfile
import odp.package

if __name__ == '__main__':
marksparkza marked this conversation as resolved.
Show resolved Hide resolved
odp.logfile.initialize()
odp.package.run_all()
4 changes: 4 additions & 0 deletions migrate/systemdata/schemas.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ Tag.DateRange:
type: tag
uri: https://odp.saeon.ac.za/schema/tag/daterange

Tag.DateRangeInc:
type: tag
uri: https://odp.saeon.ac.za/schema/tag/daterangeinc

Vocabulary.Infrastructure:
type: vocabulary
uri: https://odp.saeon.ac.za/schema/vocabulary/infrastructure
Expand Down
7 changes: 7 additions & 0 deletions migrate/systemdata/tags.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ Package.SDG:
schema_id: Tag.Generic
vocabulary_id: SDG

Package.DateRangeInc:
type: package
cardinality: one
public: False
scope_id: odp.package:admin
schema_id: Tag.DateRangeInc

Collection.Published:
type: collection
cardinality: one
Expand Down
26 changes: 26 additions & 0 deletions odp/package/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import logging

from odp.db import Session

logger = logging.getLogger(__name__)


class PackageModule:

def execute(self):
try:
self._internal_execute()
Session.commit()
except Exception as e:
Session.rollback()
logger.exception(f'PACKAGING EXECUTION FAILED: {str(e)}')

def _internal_execute(self):
raise NotImplementedError


def run_all():
from .date_range import DateRangeInc

DateRangeInc().execute()

73 changes: 73 additions & 0 deletions odp/package/date_range.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import copy
import logging
from datetime import date, datetime, timezone

from sqlalchemy import and_, select
from sqlalchemy.orm import aliased

from odp.const import ODPPackageTag, ODPDateRangeIncType
from odp.db import Session
from odp.db.models import PackageTag, Package
from odp.package import PackageModule

logger = logging.getLogger(__name__)


class DateRangeInc(PackageModule):

def _internal_execute(self):
"""
Fetch and increment date of package date range tag according to it's related date range increment tag.
"""
date_range_package_tag: PackageTag = aliased(PackageTag)
date_range_inc_package_tag: PackageTag = aliased(PackageTag)

stmt = (
select(Package, date_range_package_tag, date_range_inc_package_tag)
.join(
date_range_package_tag,
and_(
Package.id == date_range_package_tag.package_id,
date_range_package_tag.tag_id == ODPPackageTag.DATERANGE
)
)
.join(
date_range_inc_package_tag,
and_(
Package.id == date_range_inc_package_tag.package_id,
date_range_inc_package_tag.tag_id == ODPPackageTag.DATERANGEINC
)
)
)

for (package, date_range_package_tag, date_range_inc_package_tag) in Session.execute(stmt).all():
try:
date_range_data = self._get_updated_date_range_data(date_range_package_tag.data,
date_range_inc_package_tag)
self._update_date_range_package_tag(date_range_package_tag, date_range_data, package)
except Exception as e:
logger.error(f'Date range increment failed for package {package.id}: {str(e)}')

@staticmethod
def _get_updated_date_range_data(date_range_package_tag_data, date_range_inc_package_tag) -> dict:
date_range_data = copy.deepcopy(date_range_package_tag_data)
# Iterate through the date range increment types and update the corresponding date range dates.
for (date_type, increment_type) in date_range_inc_package_tag.data.items():

match increment_type:
case ODPDateRangeIncType.CURRENT_DATE:
date_range_data[date_type] = date.today().isoformat()
case _:
raise ValueError("Invalid date range increment type")

return date_range_data

@staticmethod
def _update_date_range_package_tag(date_range_package_tag, updated_data, package):
# Save the changes and update the timestamps.
date_range_package_tag.data = updated_data
date_range_package_tag.timestamp = (timestamp := datetime.now(timezone.utc))
date_range_package_tag.save()

package.timestamp = timestamp
package.save()
71 changes: 67 additions & 4 deletions test/api/test_package.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from datetime import datetime
from datetime import datetime, date
from random import randint

import pytest
from sqlalchemy import select

from odp.const import ODPScope
from odp.db.models import Package, PackageAudit, PackageTag, Resource, Tag, User
from odp.const import ODPScope, ODPTagSchema, ODPDateRangeIncType, ODPPackageTag
from odp.db.models import Package, PackageAudit, PackageTag, PackageTagAudit, Resource, Tag, User, Scope
from test import TestSession
from test.api import test_resource
from test.api.assertions import assert_forbidden, assert_new_timestamp, assert_not_found, assert_ok_null
Expand All @@ -24,6 +24,9 @@
PackageTagFactory,
ProviderFactory,
ResourceFactory,
SchemaFactory,
TagFactory,
ScopeFactory
)


Expand Down Expand Up @@ -775,7 +778,8 @@ def test_tag_package(
dict(command=tag3_command, object_id=package_id, tag_instance=package_tag_3),
)
elif tag_cardinality == 'multi':
assert_tag_instance_db_state('package', api.grant_type, package_id, package_tag_1, package_tag_2, package_tag_3)
assert_tag_instance_db_state('package', api.grant_type, package_id, package_tag_1, package_tag_2,
package_tag_3)
assert_tag_instance_audit_log(
'package', api.grant_type,
dict(command='insert', object_id=package_id, tag_instance=package_tag_1),
Expand Down Expand Up @@ -911,3 +915,62 @@ def _test_untag_package(

assert_db_state(package_batch)
assert_no_audit_log()


def get_date_range_tag(schema_id: str, schema_uri: str, tag_id: str):
date_range_schema = SchemaFactory(
id=schema_id,
uri=schema_uri,
type='tag',
)

return TagFactory(
id=tag_id,
type='package',
cardinality='one',
scope=FactorySession.get(Scope, (ODPScope.PACKAGE_WRITE, 'odp')),
schema=date_range_schema
)


def test_inc_end_date():
from odp.package.date_range import DateRangeInc

test_package = PackageFactory()

PackageTagFactory(
package=test_package,
tag=get_date_range_tag(
ODPTagSchema.DATERANGEINC,
'https://odp.saeon.ac.za/schema/tag/daterangeinc',
ODPPackageTag.DATERANGEINC
),
data={
'end': ODPDateRangeIncType.CURRENT_DATE
}
)

PackageTagFactory(
package=test_package,
tag=get_date_range_tag(
ODPTagSchema.DATERANGE,
'https://odp.saeon.ac.za/schema/tag/daterange',
ODPPackageTag.DATERANGE
),
data={
'start': '1990/01/01',
'end': '2000/01/01'
}
)

DateRangeInc().execute()

stmt = (
select(Package, PackageTag)
.where(PackageTag.package_id == test_package.id)
.where(PackageTag.tag_id == ODPPackageTag.DATERANGE.value)
)

res = TestSession.execute(stmt).first()

assert res.PackageTag.data['end'] == date.today().isoformat()