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

Reactivate Japanese Locale #542

Merged
merged 11 commits into from
Oct 24, 2023
18 changes: 9 additions & 9 deletions microsetta_private_api/LEGACY/locale_data/japanese_gut.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,24 @@
_NEW_PARTICIPANT = {
'ADD_HUMAN_TITLE': '新しいプロフィール情報を追加する',
'SEL_AGE_RANGE': '参加者の年齢層を選択する:',
'AGE_0_6': '',
'AGE_7_12': '',
'AGE_13_17': '',
'AGE_0_6': '3ヶ月 - 6才',
'AGE_7_12': '7〜12才',
'AGE_13_17': '13〜17年',
'AGE_18': '18歳以上',

'PARTICIPATION_AGREEMENT': '''''',

'EXHIBIT_A': '''''',
'BILL_OF_RIGHTS': '''研究被験者の権利章典''',
'TEXT_I_HAVE_READ_1': '私は同意書を読みました (又は代読してもらいました)。研究試験への参加を求められていることを理解し、この試験への参加に自由意志で同意します。私の個人データが処理される方法、関連した私の権利を理解しており、この同意書に記載されているように私のデータが処理されることに同意します。',
'TEXT_I_HAVE_READ_SIMPLIFIED': '',
'PERSON_ATTAINING_ASSENT': '',
'TEXT_ASSENT_WITNESS': '',
'OBTAINER_NAME': '',
'TEXT_I_HAVE_READ_PARENT': '',
'TEXT_I_HAVE_READ_SIMPLIFIED': 'はい、あなたはこの調査研究に参加します。',
'PERSON_ATTAINING_ASSENT': '同意を得る人の署名',
'TEXT_ASSENT_WITNESS': '私の判断において、参加者は自発的かつ自主的に同意し、研究に参加する意思を示す法的能力を持っています。',
'OBTAINER_NAME': '同意を得る人の名前',
'TEXT_I_HAVE_READ_PARENT': '私はこのフォームを読みました(または誰かが代読した)。私は、我が子の調査研究への参加に、同意を求められていることを理解しました。私は自発的に我が子がこの研究に参加することに同意します。我が子の個人データの処理方法、これに関連する権利、そして提供す',
'PARTICIPANT_NAME': '参加者名',
'PARTICIPANT_EMAIL': 'Eメール',
'PARTICIPANT_PARENT_1': '',
'PARTICIPANT_PARENT_1': '親/保護者の名前',
'PARTICIPANT_PARENT_2': '',
'PARTICIPANT_DECEASED_PARENTS': '',
'DATE_SIGNED': 'DATE_SIGNED',
Expand Down
6 changes: 5 additions & 1 deletion microsetta_private_api/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
from ._source import (
create_source, read_source, update_source, read_sources,
create_human_source_from_consent, check_duplicate_source_name,
scrub_source, check_source_ffq_prereqs, check_prompt_survey_update
scrub_source, check_source_ffq_prereqs, check_prompt_survey_update,
get_external_reports, get_external_report, get_external_report_bytes
)
from ._survey import (
read_survey_template, read_survey_templates, read_answered_survey,
Expand Down Expand Up @@ -84,6 +85,9 @@
'read_source',
'check_source_ffq_prereqs',
'check_prompt_survey_update',
'get_external_reports',
'get_external_report',
'get_external_report_bytes',
'update_source',
'scrub_source',
'read_sources',
Expand Down
55 changes: 54 additions & 1 deletion microsetta_private_api/api/_source.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import uuid
from datetime import date
from flask import jsonify
from flask import jsonify, make_response

from microsetta_private_api.api._account import _validate_account_access
from microsetta_private_api.api.literals import SRC_NOT_FOUND_MSG,\
Expand Down Expand Up @@ -194,3 +194,56 @@ def check_prompt_survey_update(account_id, source_id, token_info):
s_t_r = SurveyTemplateRepo(t)
prompt_update = s_t_r.check_prompt_survey_update(source_id)
return jsonify({"prompt": prompt_update}), 200


def get_external_reports(account_id, source_id, token_info):
_validate_account_access(token_info, account_id)

with Transaction() as t:
source_repo = SourceRepo(t)
reports = source_repo.get_external_reports(source_id)
for r in reports:
r.file_contents = ""
return jsonify(reports), 200


def get_external_report(
account_id, source_id, external_report_id, token_info
):
_validate_account_access(token_info, account_id)

with Transaction() as t:
source_repo = SourceRepo(t)
reports = source_repo.get_external_reports(
source_id, external_report_id
)
if len(reports) != 1:
return jsonify(code=404, message="Report not found"), 404

report = reports[0]

# Trying to jsonify the actual contents gets ugly, so we return
# everything else here, and the contents in get_external_report_bytes
report.file_contents = ""
return jsonify(report.to_api()), 200


def get_external_report_bytes(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def get_external_report_bytes(
def get_external_report_pdf(

The MIME type is specific to PDF

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The MIME type is stored on a per-file basis and it's entirely possible it will be used for non-PDF file types in the future. Do you have a suggestion on an alternative to _bytes that's not specific to a single file type?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bytes is fine but perhaps use the stored MIME type rather than hard code it on response?

account_id, source_id, external_report_id, token_info
):
_validate_account_access(token_info, account_id)

with Transaction() as t:
source_repo = SourceRepo(t)
reports = source_repo.get_external_reports(
source_id, external_report_id
)

if len(reports) != 1:
return jsonify(code=404, message="Report not found"), 404

report = reports[0]
response = make_response(bytes(report.file_contents))
response.headers.set("Content-Type", report.file_type)

return response
112 changes: 112 additions & 0 deletions microsetta_private_api/api/microsetta_private_api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,79 @@ paths:
$ref: '#/components/responses/422UnprocessableEntity'
# NB: This would be returned if source cannot be deleted bc has a sample assigned to it

'/accounts/{account_id}/sources/{source_id}/external_reports':
get:
operationId: microsetta_private_api.api.get_external_reports
tags:
- Sources
summary: Get external reports attached to the source
description: Get external reports attached to the source
parameters:
- $ref: '#/components/parameters/account_id'
- $ref: '#/components/parameters/source_id'
- $ref: '#/components/parameters/language_tag'
responses:
'200':
description: Successfully returned list of external reports
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/external_report'
'401':
$ref: '#/components/responses/401Unauthorized'
'403':
$ref: '#/components/responses/403Forbidden'

'/accounts/{account_id}/sources/{source_id}/external_reports/{external_report_id}':
get:
operationId: microsetta_private_api.api.get_external_report
tags:
- Sources
summary: Get full contents of external report
description: Get full contents of external report
parameters:
- $ref: '#/components/parameters/account_id'
- $ref: '#/components/parameters/source_id'
- $ref: '#/components/parameters/external_report_id'
- $ref: '#/components/parameters/language_tag'
responses:
'200':
description: Successfully returned external report information
content:
application/json:
schema:
type: "object"
'401':
$ref: '#/components/responses/401Unauthorized'
'403':
$ref: '#/components/responses/403Forbidden'
'404':
$ref: '#/components/responses/404NotFound'

'/accounts/{account_id}/sources/{source_id}/external_reports/{external_report_id}/bytes':
get:
operationId: microsetta_private_api.api.get_external_report_bytes
tags:
- Sources
summary: Get full contents of external report
description: Get full contents of external report
parameters:
- $ref: '#/components/parameters/account_id'
- $ref: '#/components/parameters/source_id'
- $ref: '#/components/parameters/external_report_id'
- $ref: '#/components/parameters/language_tag'
responses:
'200':
description: Successfully returned contents of an external report
'401':
$ref: '#/components/responses/401Unauthorized'
'403':
$ref: '#/components/responses/403Forbidden'
'404':
$ref: '#/components/responses/404NotFound'

'/accounts/{account_id}/sources/{source_id}/check_ffq_prereqs':
get:
operationId: microsetta_private_api.api.check_source_ffq_prereqs
Expand Down Expand Up @@ -3014,6 +3087,12 @@ components:
description: Type of consent
schema:
$ref: '#/components/schemas/consent_type'
external_report_id:
name: external_report_id
in: path
description: Unique identifier of external report
schema:
$ref: '#/components/schemas/external_report_id'

# query parameters
activation_code:
Expand Down Expand Up @@ -3425,6 +3504,18 @@ components:
type: string
assent_content:
type: string
external_report_id:
type: string
file_name:
type: string
file_title:
type: string
file_type:
type: string
file_contents:
type: string
report_type:
enum: ["kit", "ffq"]
nonhuman_source:
type: object
properties:
Expand Down Expand Up @@ -3472,6 +3563,27 @@ components:
type: string
additionalProperties: false
additionalProperties: false
external_report:
type: object
properties:
external_report_id:
$ref: '#/components/schemas/external_report_id'
source_id:
$ref: '#/components/schemas/source_id'
file_name:
$ref: '#/components/schemas/file_name'
file_title:
$ref: '#/components/schemas/file_title'
file_type:
$ref: '#/components/schemas/file_type'
file_contents:
$ref: '#/components/schemas/file_contents'
report_type:
$ref: '#/components/schemas/report_type'
required:
- external_report_id
- source_id
- report_type

# survey template section
survey_template_id:
Expand Down
54 changes: 54 additions & 0 deletions microsetta_private_api/db/migration_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,59 @@ def migrate_96(TRN):
(r[0], hsi))
TRN.execute()

@staticmethod
def migrate_133(TRN):
ffq_key_path = SERVER_CONFIG["japanese_ffqs_path_key"]
ffq_file_path = SERVER_CONFIG["japanese_ffqs_path_reports"]

# The below string translates to "Food frequency questionnaire"
JFFQ_FILE_LABEL = "食物摂取頻度調査票"

if not os.path.exists(ffq_key_path):
print("Key not found:" + ffq_key_path)
return

with open(ffq_key_path) as csv_file:
csv_contents = csv.reader(csv_file)
header = True

for csv_row in csv_contents:
if header:
header = False
continue
ffq_id, barcode = csv_row

# Find the source associated with the barcode and make sure
# it wasn't scrubbed or removed
TRN.add(
"SELECT akb.source_id "
"FROM ag.ag_kit_barcodes akb "
"INNER JOIN ag.source s "
"ON akb.source_id = s.id "
"WHERE akb.barcode = %s AND s.date_revoked IS NULL",
(barcode, )
)
rows = TRN.execute()[-1]

if len(rows) == 1:
row = rows[0]
source_id = row[0]
pdf_name = ffq_id + ".pdf"
pdf_path = ffq_file_path + pdf_name
pdf_contents = open(pdf_path, "rb").read()

TRN.add(
"INSERT INTO ag.external_reports ("
"source_id, file_name, file_title, file_type, "
"file_contents, report_type"
") VALUES (%s, %s, %s, %s, %s, %s)",
(source_id, pdf_name, JFFQ_FILE_LABEL,
"application/pdf", pdf_contents, "ffq")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the MIME type is stored along side the contents, why not pull this out for the _bytes API call?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file_contents value (the actual bytes of the file) don't go through the jsonify process cleanly, so I've separated the API calls to return the bytes in one call and the other information in another call.

)
else:
print("No mapping: " + ffq_id + " - " + barcode)
TRN.execute()

MIGRATION_LOOKUP = {
"0048.sql": migrate_48.__func__,
"0050.sql": migrate_50.__func__,
Expand All @@ -753,6 +806,7 @@ def migrate_96(TRN):
# "0082.sql": migrate_82.__func__
# ...
"0096.sql": migrate_96.__func__,
"0133.sql": migrate_133.__func__
}

@classmethod
Expand Down
Loading
Loading