Skip to content
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
125 changes: 70 additions & 55 deletions client/platform/web-girder/views/Admin/AdminJobs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -76,25 +76,44 @@ export default defineComponent({
(item) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let params: Record<string, any> = {};
if (isObject(item.kwargs)) {
params = item.kwargs;
} else if (typeof (item.kwargs) === 'string') {
const temp = JSON.parse(item.kwargs);
if (temp.params !== undefined) {
params = temp.params;
} else if (isObject(temp)) {
params = temp;
// Prefer the persisted job.params blob (pipelines/training), then celery kwargs.
// Kwargs may arrive as an object or JSON string; nested .params must be unwrapped
// in both cases or login/userDir show as Unknown.
const jobParams = (item as GirderJob & { params?: Record<string, unknown> }).params;
if (isObject(jobParams) && Object.keys(jobParams).length) {
params = jobParams;
} else {
let raw: Record<string, unknown> = {};
if (typeof item.kwargs === 'string') {
try {
raw = JSON.parse(item.kwargs) || {};
} catch {
raw = {};
}
} else if (isObject(item.kwargs)) {
raw = item.kwargs as Record<string, unknown>;
}
if (isObject(raw.params)) {
params = raw.params as Record<string, unknown>;
} else {
params = raw;
}
}
const datasetId = (item as GirderJob & { dataset_id?: string }).dataset_id
|| params?.input_folder
|| params?.folderId
|| params?.source_folder_id
|| null;
return {
title: item?.title || 'Unknown',
type: item.type,
login: params?.user_login || 'Unknown',
userDir: params?.user_id || 'Unknown',
userDir: params?.user_id || params?.userId || 'Unknown',
created: moment(item.created).format('MM/DD/YY @ h:mm a'),
modified: moment(item.updated).format('MM/DD/YY @ h:mm a'),
status: item.status,
params,
datasetId,
actions: item._id,
};
},
Expand Down Expand Up @@ -282,53 +301,49 @@ export default defineComponent({
<JobProgress :formatted-job="formatStatus(item.status)" />
</template>
<template #item.params="{ item }">
<div v-if="item.type === 'pipelines'">
<div v-if="item.params.input_folder">
<v-tooltip
bottom
>
<template #activator="{ on, attrs }">
<v-btn
v-bind="attrs"
x-small
depressed
:to="{ name: 'viewer', params: { id: item.params.input_folder } }"
color="info"
class="ml-0"
v-on="on"
>
<v-icon small>
mdi-eye
</v-icon>
</v-btn>
</template>
<span>Launch dataset viewer</span>
</v-tooltip>
</div>
<div v-if="item.type === 'training' && item.params.dataset_input_list">
<v-tooltip
bottom
>
<template #activator="{ on, attrs }">
<v-btn
v-bind="attrs"
x-small
depressed
color="info"
class="ml-0"
v-on="on"
@click="viewTrainingList(item.params.dataset_input_list)"
>
<v-icon small>
mdi-eye
</v-icon>
</v-btn>
</template>
<span>View Training List</span>
</v-tooltip>
</div>
<div v-if="item.type === 'training'">
<div v-if="item.params.dataset_input_list">
<v-tooltip
bottom
>
<template #activator="{ on, attrs }">
<v-btn
v-bind="attrs"
x-small
depressed
color="info"
class="ml-0"
v-on="on"
@click="viewTrainingList(item.params.dataset_input_list)"
>
<v-icon small>
mdi-eye
</v-icon>
</v-btn>
</template>
<span>View Training List</span>
</v-tooltip>
</div>
<div v-else-if="item.datasetId">
<v-tooltip
bottom
>
<template #activator="{ on, attrs }">
<v-btn
v-bind="attrs"
x-small
depressed
:to="{ name: 'viewer', params: { id: item.datasetId } }"
color="info"
class="ml-0"
v-on="on"
>
<v-icon small>
mdi-eye
</v-icon>
</v-btn>
</template>
<span>Launch dataset viewer</span>
</v-tooltip>
</div>
</template>
<template #item.actions="{ item }">
Expand Down
3 changes: 2 additions & 1 deletion server/dive_server/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ def load(self, info):
)
User().exposeFields(AccessType.READ, constants.UserPrivateQueueEnabledMarker)

# Expose Job dataset assocation
# Expose Job dataset association and params (login, input_folder, etc.)
Job().exposeFields(AccessType.READ, constants.JOBCONST_DATASET_ID)
Job().exposeFields(AccessType.READ, constants.JOBCONST_PARAMS)

DIVE_MAIL_TEMPLATES = Path(os.path.realpath(__file__)).parent / 'mail_templates'
mail_utils.addTemplateDirectory(str(DIVE_MAIL_TEMPLATES))
Expand Down
43 changes: 39 additions & 4 deletions server/dive_server/crud_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -817,14 +817,21 @@ def postprocess(
total_items = len(list((Folder().childItems(dsFolder))))
if total_items > 1:
raise RestException('There are multiple files besides a zip, cannot continue')
convert_params = {
'user_id': str(user["_id"]),
'user_login': str(user["login"]),
'input_folder': str(dsFolder["_id"]),
}
newjob = tasks.extract_zip.apply_async(
queue=_get_queue_name(user),
kwargs=dict(
folderId=str(item["folderId"]),
itemId=str(item["_id"]),
user_id=str(user["_id"]),
user_login=str(user["login"]),
girder_job_title=f"Extracting {item['_id']} to folder {str(dsFolder['_id'])}",
girder_job_title=(
f"Extracting {item['name']} to folder {dsFolder['name']}"
),
girder_client_token=str(token["_id"]),
girder_job_type="private" if job_is_private else "convert",
),
Expand All @@ -834,6 +841,7 @@ def postprocess(
**{
constants.JOBCONST_PRIVATE_QUEUE: job_is_private,
constants.JOBCONST_DATASET_ID: str(item["folderId"]),
constants.JOBCONST_PARAMS: convert_params,
constants.JOBCONST_CREATOR: str(user['_id']),
},
)
Expand All @@ -846,6 +854,11 @@ def postprocess(
)

for item in videoItems:
convert_params = {
'user_id': str(user["_id"]),
'user_login': str(user["login"]),
'input_folder': str(dsFolder["_id"]),
}
newjob = tasks.convert_video.apply_async(
queue=_get_queue_name(user),
kwargs=dict(
Expand All @@ -854,7 +867,9 @@ def postprocess(
user_id=str(user["_id"]),
user_login=str(user["login"]),
skip_transcoding=skipTranscoding,
girder_job_title=f"Converting {item['_id']} to a web friendly format",
girder_job_title=(
f"Converting {dsFolder['name']} to a web friendly format"
),
girder_client_token=str(token["_id"]),
girder_job_type="private" if job_is_private else "convert",
),
Expand All @@ -864,6 +879,8 @@ def postprocess(
**{
constants.JOBCONST_PRIVATE_QUEUE: job_is_private,
constants.JOBCONST_DATASET_ID: dsFolder["_id"],
constants.JOBCONST_PARAMS: convert_params,
constants.JOBCONST_CREATOR: str(user['_id']),
},
)
created_job_ids.append(job['_id'])
Expand All @@ -880,14 +897,21 @@ def postprocess(
)

if imageItems.count() > safeImageItems.count():
convert_params = {
'user_id': str(user["_id"]),
'user_login': str(user["login"]),
'input_folder': str(dsFolder["_id"]),
}
newjob = tasks.convert_images.apply_async(
queue=_get_queue_name(user),
kwargs=dict(
folderId=dsFolder["_id"],
user_id=str(user["_id"]),
user_login=str(user["login"]),
girder_client_token=str(token["_id"]),
girder_job_title=f"Converting {dsFolder['_id']} to a web friendly format",
girder_job_title=(
f"Converting {dsFolder['name']} to a web friendly format"
),
girder_job_type="private" if job_is_private else "convert",
),
)
Expand All @@ -896,6 +920,8 @@ def postprocess(
**{
constants.JOBCONST_PRIVATE_QUEUE: job_is_private,
constants.JOBCONST_DATASET_ID: dsFolder["_id"],
constants.JOBCONST_PARAMS: convert_params,
constants.JOBCONST_CREATOR: str(user['_id']),
},
)
created_job_ids.append(job['_id'])
Expand Down Expand Up @@ -930,14 +956,21 @@ def convert_large_image(

if not isClone:
token = Token().createToken(user=user, days=2)
convert_params = {
'user_id': str(user["_id"]),
'user_login': str(user["login"]),
'input_folder': str(dsFolder["_id"]),
}
newjob = tasks.convert_large_images.apply_async(
queue=_get_queue_name(user),
kwargs=dict(
folderId=dsFolder["_id"],
user_id=str(user["_id"]),
user_login=str(user["login"]),
girder_client_token=str(token["_id"]),
girder_job_title=f"Converting {dsFolder['_id']} to a web friendly format",
girder_job_title=(
f"Converting {dsFolder['name']} to a web friendly format"
),
girder_job_type="private" if job_is_private else "convert",
),
)
Expand All @@ -946,6 +979,8 @@ def convert_large_image(
**{
constants.JOBCONST_PRIVATE_QUEUE: job_is_private,
constants.JOBCONST_DATASET_ID: dsFolder["_id"],
constants.JOBCONST_PARAMS: convert_params,
constants.JOBCONST_CREATOR: str(user['_id']),
},
)
Notification().createNotification(
Expand Down
1 change: 1 addition & 0 deletions server/dive_server/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ def convert_video_recursive(folder, user):
"additive": False,
"additivePrepend": '',
"userId": str(user['_id']),
"user_login": str(user.get('login', 'unknown')),
"girderToken": str(token['_id']),
"girderApiUrl": getWorkerApiUrl(),
}
Expand Down
2 changes: 2 additions & 0 deletions server/dive_tasks/dive_batch_postprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ def __init__(
userId: str,
girderToken: str,
girderApiUrl: str,
user_login: str = 'unknown',
):
self.source_folder_id = source_folder_id
self.skipJobs = skipJobs
self.skipTranscoding = skipTranscoding
self.additive = additive
self.additivePrepend = additivePrepend
self.userId = userId
self.user_login = user_login
self.girderToken = girderToken
self.girderApiUrl = girderApiUrl

Expand Down
Loading