Skip to content

Commit

Permalink
feat(docworker): Add file question
Browse files Browse the repository at this point in the history
  • Loading branch information
MarekSuchanek committed Oct 29, 2024
1 parent 8b57d9d commit d2abf35
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 4 deletions.
2 changes: 1 addition & 1 deletion packages/dsw-document-worker/dsw/document_worker/consts.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
CMD_CHANNEL = 'doc_worker'
CMD_COMPONENT = 'doc_worker'
COMPONENT_NAME = 'Document Worker'
CURRENT_METAMODEL = 14
CURRENT_METAMODEL = 15
DEFAULT_ENCODING = 'utf-8'
EXIT_SUCCESS = 0
NULL_UUID = '00000000-0000-0000-0000-000000000000'
Expand Down
99 changes: 97 additions & 2 deletions packages/dsw-document-worker/dsw/document_worker/model/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,33 @@ def load(path: str, data: dict, **options):
)


class FileReply(Reply):

def __init__(self, path, created_at, created_by, file_uuid):
super().__init__(path, created_at, created_by, 'FileReply')
self.file_uuid = file_uuid # type: str
self.file = None # type: Optional[QuestionnaireFile]

@property
def value(self) -> str:
return self.file_uuid

def _resolve_links(self, ctx):
super()._resolve_links_parent(ctx)
self.file = ctx.questionnaire.files.get(self.file_uuid, None)
if self.file is not None:
self.file.reply = self

@staticmethod
def load(path: str, data: dict, **options):
return FileReply(
path=path,
created_at=_datetime(data['createdAt']),
created_by=SimpleAuthor.load(data['createdBy'], **options),
file_uuid=data['value']['value'],
)


class Answer:

def __init__(self, uuid, label, advice, metric_measures, followup_uuids,
Expand Down Expand Up @@ -1001,6 +1028,36 @@ def load(data: dict, **options):
)


class FileQuestion(Question):

def __init__(self, uuid, title, text, tag_uuids, reference_uuids,
expert_uuids, required_phase_uuid, max_size, file_types,
annotations):
super().__init__(uuid, 'FileQuestion', title, text, tag_uuids,
reference_uuids, expert_uuids, required_phase_uuid,
annotations)
self.max_size = max_size
self.file_types = file_types

def _resolve_links(self, ctx):
super()._resolve_links_parent(ctx)

@staticmethod
def load(data: dict, **options):
return FileQuestion(
uuid=data['uuid'],
title=data['title'],
text=data['text'],
tag_uuids=data['tagUuids'],
reference_uuids=data['referenceUuids'],
expert_uuids=data['expertUuids'],
required_phase_uuid=data['requiredPhaseUuid'],
max_size=data['maxSize'],
file_types=data['fileTypes'],
annotations=_load_annotations(data['annotations']),
)


class Chapter:

def __init__(self, uuid, title, text, question_uuids, annotations):
Expand Down Expand Up @@ -1053,6 +1110,8 @@ def _load_question(data: dict, **options):
return IntegrationQuestion.load(data, **options)
if data['questionType'] == 'ItemSelectQuestion':
return ItemSelectQuestion.load(data, **options)
if data['questionType'] == 'FileQuestion':
return FileQuestion.load(data, **options)
raise ValueError(f'Unknown question type: {data["questionType"]}')


Expand Down Expand Up @@ -1087,6 +1146,8 @@ def _load_reply(path: str, data: dict, **options):
return IntegrationReply.load(path, data, **options)
if data['value']['type'] == 'ItemSelectReply':
return ItemSelectReply.load(path, data, **options)
if data['value']['type'] == 'FileReply':
return FileReply.load(path, data, **options)
raise ValueError(f'Unknown reply type: {data["value"]["type"]}')


Expand Down Expand Up @@ -1318,6 +1379,33 @@ def items(self) -> ItemsView[str, Reply]:
return self.replies.items()


class QuestionnaireFile:

def __init__(self, uuid, file_name, file_size, content_type):
self.uuid = uuid # type: str
self.name = file_name # type: str
self.size = file_size # type: int
self.content_type = content_type # type: str

self.reply = None # type: Optional[FileReply]
self.download_url = '' # type: str

def _resolve_links(self, ctx):
# Update the download URL: /projects/<projectUuid>/files/<fileUuid>/download
project_uuid = ctx.questionnaire.uuid
client_url = ctx.config.client_url
self.download_url = f'{client_url}/projects/{project_uuid}/files/{self.uuid}/download'

@staticmethod
def load(data: dict, questionnaire_uuid: str, **options):
return QuestionnaireFile(
uuid=data['uuid'],
file_name=data['fileName'],
file_size=data['fileSize'],
content_type=data['contentType'],
)


class Questionnaire:

def __init__(self, uuid, name, description, created_by, phase_uuid,
Expand All @@ -1327,6 +1415,7 @@ def __init__(self, uuid, name, description, created_by, phase_uuid,
self.description = description # type: str
self.version = None # type: Optional[QuestionnaireVersion]
self.versions = list() # type: list[QuestionnaireVersion]
self.files = dict() # type: dict[str, QuestionnaireFile]
self.todos = list() # type: list[str]
self.created_by = created_by # type: User
self.phase_uuid = phase_uuid # type: Optional[str]
Expand All @@ -1339,19 +1428,24 @@ def __init__(self, uuid, name, description, created_by, phase_uuid,
def _resolve_links(self, ctx):
for reply in self.replies.values():
reply._resolve_links(ctx)
for file in self.files.values():
file._resolve_links(ctx)

@staticmethod
def load(data: dict, **options):
questionnaire_uuid = data['uuid']
versions = [QuestionnaireVersion.load(d, **options)
for d in data['versions']]
version = None
replies = {p: _load_reply(p, d, **options)
for p, d in data['replies'].items()}
files = {d['uuid']: QuestionnaireFile.load(d, questionnaire_uuid, **options)
for d in data.get('files', [])}
for v in versions:
if v.uuid == data['versionUuid']:
version = v
qtn = Questionnaire(
uuid=data['uuid'],
uuid=questionnaire_uuid,
name=data['name'],
description=data['description'] or '',
created_by=User.load(data['createdBy'], **options),
Expand All @@ -1361,6 +1455,7 @@ def load(data: dict, **options):
)
qtn.version = version
qtn.versions = versions
qtn.files = files
qtn.project_tags = data.get('projectTags', [])
qtn.replies.replies = replies
qtn.todos = [k for k, v in data.get('labels', {}).items() if TODO_LABEL_UUID in v]
Expand Down Expand Up @@ -1670,7 +1765,7 @@ def load(data: dict, **options):

class DocumentContext:
"""Document Context smart representation"""
METAMODEL_VERSION = 14
METAMODEL_VERSION = 15

def __init__(self, ctx, **options):
self.metamodel_version = int(ctx.get('metamodelVersion', '0'))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from ..exceptions import JobException
from ..model import DocumentContext
from dsw.document_worker.utils import byte_size_format


LOG = logging.getLogger(__name__)
Expand Down Expand Up @@ -226,6 +227,7 @@ def raise_error(message, title='Document rendering error'):
filters = {
'any': any,
'all': all,
'bytesize_format': byte_size_format,
'datetime_format': datetime_format,
'extract': extract,
'of_alphabet': of_alphabet,
Expand Down
2 changes: 1 addition & 1 deletion packages/dsw-tdk/dsw/tdk/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

APP = 'dsw-tdk'
VERSION = '4.11.0'
METAMODEL_VERSION = 14
METAMODEL_VERSION = 15

REGEX_SEMVER = re.compile(r'^[0-9]+\.[0-9]+\.[0-9]+$')
REGEX_ORGANIZATION_ID = re.compile(r'^(?![.])(?!.*[.]$)[a-zA-Z0-9.]+$')
Expand Down
1 change: 1 addition & 0 deletions packages/dsw-tdk/dsw/tdk/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def __init__(self, message: str, hint: str):
12: (4, 1, 0),
13: (4, 3, 0),
14: (4, 10, 0),
15: (4, 12, 0),
}


Expand Down

0 comments on commit d2abf35

Please sign in to comment.