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

RDISCROWD-5852 Calc task expiration by create date #836

Merged
merged 12 commits into from
Apr 18, 2023
2 changes: 1 addition & 1 deletion pybossa/api/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def _update_attribute(self, new, old):
new.id, old.state, new.state,
str(old.exported), str(new.exported))
if new.expiration is not None:
new.expiration = get_task_expiration(new.expiration)
new.expiration = get_task_expiration(new.expiration, old.created)

def _preprocess_post_data(self, data):
project_id = data["project_id"]
Expand Down
13 changes: 8 additions & 5 deletions pybossa/task_creator_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from flask import current_app
import hashlib
from pybossa.cloud_store_api.s3 import upload_json_data, get_content_from_s3
from pybossa.util import get_now_plus_delta_ts
from pybossa.util import get_now_plus_delta_ts, get_time_plus_delta_ts
from flask import url_for
import json
from six import string_types
Expand All @@ -40,19 +40,22 @@ def s3_conn_type():
return current_app.config.get('S3_CONN_TYPE')


def get_task_expiration(current_expiration):
def get_task_expiration(current_expiration, create_time=None):
"""
Find the appropriate expiration to be added to a task with expiring data.
If no expiration is set, return the data expiration; otherwise, return
the smallest between the current expiration and the data expiration.
current_expiration can be a iso datetime string or a datetime object
dchhabda marked this conversation as resolved.
Show resolved Hide resolved
"""
validity = current_app.config.get('TASK_EXPIRATION', 60)
return _get_task_expiration(current_expiration, validity)
return _get_task_expiration(current_expiration, create_time, validity)


def _get_task_expiration(current_expiration, validity):
task_exp = get_now_plus_delta_ts(days=validity)
def _get_task_expiration(current_expiration, create_time, validity):
if create_time is None:
task_exp = get_now_plus_delta_ts(days=validity)
else:
task_exp = get_time_plus_delta_ts(create_time, days=validity)
dchhabda marked this conversation as resolved.
Show resolved Hide resolved
if isinstance(current_expiration, string_types):
task_exp = task_exp.isoformat()
current_expiration = current_expiration or task_exp
Expand Down
6 changes: 6 additions & 0 deletions pybossa/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@

from bs4 import BeautifulSoup

from six import string_types

misaka = Misaka()
TP_COMPONENT_TAGS = ["text-input", "dropdown-input", "radio-group-input",
"checkbox-input", "multi-select-input", "input-text-area"]
Expand Down Expand Up @@ -1111,6 +1113,10 @@ def sign_task(task):
def get_now_plus_delta_ts(**kwargs):
return (datetime.utcnow() + timedelta(**kwargs))

def get_time_plus_delta_ts(time, **kwargs):
if isinstance(time, string_types):
dchhabda marked this conversation as resolved.
Show resolved Hide resolved
time = datetime.fromisoformat(time)
return (time + timedelta(**kwargs))

def get_taskrun_date_range_sql_clause_params(start_date, end_date):
"""Generate date cause and sql params for queriying db."""
Expand Down
21 changes: 16 additions & 5 deletions test/test_api/test_task_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -770,8 +770,13 @@ def test_task_put_with_reserved_fields_returns_error(self):
def test_task_put_with_expiration_within_bound(self):
admin = UserFactory.create()
project = ProjectFactory.create(owner=admin)
task = TaskFactory.create(project=project, info=dict(x=1))
expiration = (datetime.datetime.utcnow() + datetime.timedelta(30)).isoformat()
task = TaskFactory.create(
project=project,
info=dict(x=1),
created='2015-01-01T14:37:30.642119'
)
# 40 days after creation date
expiration = '2015-02-10T14:37:30.642119'
datajson = json.dumps({'expiration': expiration})

url = '/api/task/%s?api_key=%s' % (task.id, admin.api_key)
Expand All @@ -788,9 +793,15 @@ def test_task_put_with_expiration_within_bound(self):
def test_task_put_with_expiration_out_of_bounds(self):
admin = UserFactory.create()
project = ProjectFactory.create(owner=admin)
task = TaskFactory.create(project=project, info=dict(x=1))
expiration = (datetime.datetime.utcnow() + datetime.timedelta(1000)).isoformat()
max_expiration = (datetime.datetime.utcnow() + datetime.timedelta(60)).isoformat()
task = TaskFactory.create(
project=project,
info=dict(x=1),
created='2015-01-01T14:37:30.642119'
)
# the task expires 60 days after creation date
max_expiration = '2015-03-02T14:37:30.642119'
# 365 days after creation date
expiration = '2016-01-01T14:37:30.642119'
datajson = json.dumps({'expiration': expiration})

url = '/api/task/%s?api_key=%s' % (task.id, admin.api_key)
Expand Down
22 changes: 17 additions & 5 deletions test/test_task_creator_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,24 @@ class TestGetTaskExpirationDatetime(object):
def test_current_expiration_is_before(self):
now = datetime.utcnow()
current_exp = now + timedelta(days=30)
exp = _get_task_expiration(current_exp, 60)
exp = _get_task_expiration(current_exp, None, 60)
assert exp == current_exp

def test_current_expiration_is_after(self):
now = datetime.utcnow()
current_exp = now + timedelta(days=90)
exp = _get_task_expiration(current_exp, 60)
exp = _get_task_expiration(current_exp, None, 60)
assert are_almost_equal(exp, now + timedelta(days=60))

def test_create_date_is_set(self):
now = datetime.utcnow()
current_exp = now + timedelta(days=90)
exp = _get_task_expiration(current_exp, now, 60)
assert are_almost_equal(exp, now + timedelta(days=60))

def test_current_expiration_is_none(self):
now = datetime.utcnow()
exp = _get_task_expiration(None, 60)
exp = _get_task_expiration(None, None, 60)
assert are_almost_equal(exp, now + timedelta(days=60))


Expand All @@ -38,12 +44,18 @@ class TestGetTaskExpirationString(object):
def test_current_expiration_is_before(self):
now = datetime.utcnow()
current_exp = now + timedelta(days=30)
exp = _get_task_expiration(current_exp.isoformat(), 60)
exp = _get_task_expiration(current_exp.isoformat(), None, 60)
assert to_datetime(exp) == current_exp

def test_current_expiration_is_after(self):
now = datetime.utcnow()
current_exp = now + timedelta(days=90)
exp = _get_task_expiration(current_exp.isoformat(), 60)
exp = _get_task_expiration(current_exp.isoformat(), None, 60)
assert are_almost_equal(
to_datetime(exp), now + timedelta(days=60))

def test_create_date_is_set(self):
now = datetime.utcnow()
current_exp = now + timedelta(days=30)
exp = _get_task_expiration(current_exp.isoformat(), now, 60)
assert to_datetime(exp) == current_exp