Skip to content

Commit f725ca6

Browse files
author
George
committed
complete merge
2 parents 3e724cf + 6caf3d4 commit f725ca6

File tree

9 files changed

+424
-13
lines changed

9 files changed

+424
-13
lines changed

idc/urls.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from django.contrib import admin
2222
from django.conf import settings
2323

24-
from . import views
24+
from . import views, views_api
2525

2626
admin.autodiscover()
2727

@@ -32,6 +32,7 @@
3232
url(r'^test_methods/', views.test_methods, name='test_methods'),
3333
url(r'^style_guide/', views.css_test),
3434
url(r'^users/(?P<user_id>\d+)/$', views.user_detail, name='user_detail'),
35+
url(r'^users/api/', views_api.user_detail, name='user_detail_api'),
3536
url(r'^cohorts/', include('cohorts.urls')),
3637
path('admin/', admin.site.urls),
3738
url(r'^accounts/', include('accounts.urls')),

idc/views_api.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
###
2+
# Copyright 2015-2020, Institute for Systems Biology
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
###
16+
17+
import json
18+
from json import JSONEncoder
19+
import logging
20+
import sys
21+
22+
23+
from django.conf import settings
24+
from django.contrib.auth.models import User
25+
from allauth.socialaccount.models import SocialAccount
26+
from django.http import HttpResponse, JsonResponse
27+
28+
debug = settings.DEBUG
29+
logger = logging.getLogger('main_logger')
30+
from datetime import datetime
31+
32+
from django.views.decorators.csrf import csrf_exempt
33+
from django.views.decorators.http import require_http_methods
34+
from cohorts.decorators import api_auth
35+
36+
37+
class DateTimeEncoder(JSONEncoder):
38+
# Override the default method
39+
def default(self, obj):
40+
if isinstance(obj, datetime):
41+
encoded_object = obj.strftime('%s')
42+
else:
43+
encoded_object = super(self, obj)
44+
return encoded_object
45+
# if isinstance(obj, (datetime.date, datetime.datetime)):
46+
# return obj.isoformat()
47+
48+
# class JsonResponse(HttpResponse):
49+
# def __init__(self, content, mimetype='application/json', status=None, content_type='application/json'):
50+
# json_text = json.dumps(content, cls=DateTimeEncoder)
51+
# super(JsonResponse, self).__init__(
52+
# content=json_text,
53+
# status=status,
54+
# content_type=content_type)
55+
56+
@csrf_exempt
57+
@api_auth
58+
@require_http_methods(["GET"])
59+
def user_detail(request):
60+
if debug: logger.debug('Called ' + sys._getframe().f_code.co_name)
61+
62+
try:
63+
user = User.objects.get(email=request.GET.get('email', ''))
64+
except Exception as e:
65+
logger.error("[ERROR] {} is not a registered IDC web app user".format(request.GET.get('email', '')))
66+
logger.exception(e)
67+
user_details = {
68+
"message": "Not a registered IDC web app user",
69+
"code": 404
70+
}
71+
return JsonResponse(user_details)
72+
73+
try:
74+
social_account = SocialAccount.objects.get(user=user, provider='google')
75+
except Exception as e:
76+
# This is a local account
77+
social_account = None
78+
user_details = {
79+
'date_joined': user.date_joined,
80+
'email': user.email,
81+
'id': user.id,
82+
'last_login': user.last_login
83+
}
84+
85+
if social_account:
86+
user_details['extra_data'] = social_account.extra_data if social_account else None
87+
user_details['first_name'] = user.first_name
88+
user_details['last_name'] = user.last_name
89+
else:
90+
user_details['username'] = user.username
91+
92+
results = {"user_details": user_details}
93+
94+
return JsonResponse(results, encoder=DateTimeEncoder)
95+
96+
97+

static/css/style.css

Lines changed: 23 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

static/js/cohorts/cohort-details.js

Lines changed: 121 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,28 +55,137 @@ require([
5555
], function($, jqueryui, base, tippy, bootstrap) {
5656
A11y.Core();
5757

58+
tippy('.manifest-size-warning',{
59+
content: 'Your cohort is too large to be downloaded in its entirety, and will be truncated at 65,000 records ' +
60+
'ordered by PatientID, StudyID, SeriesID, and InstanceID.',
61+
theme: 'light',
62+
placement: 'left',
63+
arrow: false
64+
});
65+
5866
var downloadToken = new Date().getTime();
59-
$('#download-manifest').prop("href", $('#download-manifest').prop("href") + "?downloadToken="+downloadToken);
60-
$('#download-manifest').data('downloadToken',downloadToken);
6167

62-
$('#download-manifest').on('click', function() {
63-
var self=$(this);
68+
$('#download-csv').on('click', function(e) {
69+
download_manifest("csv", $(this), e)
70+
});
71+
72+
$('#download-tsv').on('click', function(e) {
73+
download_manifest("tsv", $(this), e)
74+
});
75+
76+
$('#download-json').on('click', function(e) {
77+
download_manifest("json", $(this), e)
78+
});
79+
80+
var download_manifest = function(file_type, clicked_button, e) {
81+
$('#unallowed-chars-alert').hide();
82+
$('#name-too-long-alert-modal').hide();
83+
84+
var name = $('#export-manifest-name').val();
85+
var unallowed = (name.match(base.blacklist) || []);
86+
87+
if (name.length == 0) {
88+
$('#download-csv').prop('title','Please input the name.');
89+
$('#export-manifest-name')[0].focus();
90+
e.preventDefault();
91+
return false;
92+
}
6493

65-
self.attr('disabled','disabled');
94+
if (clicked_button.is('[disabled=disabled]')) {
95+
e.preventDefault();
96+
return false;
97+
}
98+
99+
if (unallowed.length > 0) {
100+
$('.unallowed-chars').text(unallowed.join(", "));
101+
$('#unallowed-chars-alert').show();
102+
e.preventDefault();
103+
return false;
104+
}
105+
106+
if (name.length > 255) {
107+
$('#name-too-long-alert-modal').show();
108+
e.preventDefault();
109+
return false;
110+
}
111+
112+
$('#export-manifest-form').submit();
113+
114+
$('#download-csv').attr('disabled','disabled');
115+
$('#download-tsv').attr('disabled','disabled');
116+
$('#download-json').attr('disabled','disabled');
66117

67118
$('#download-in-progress').modal('show');
68119

69120
base.blockResubmit(function() {
70-
self.removeAttr('disabled');
121+
$('#download-csv').removeAttr('disabled');
122+
$('#download-tsv').removeAttr('disabled');
123+
$('#download-json').removeAttr('disabled');
71124
$('#download-in-progress').modal('hide');
72125
},downloadToken, 'downloadToken');
126+
127+
var checked_fields = [];
128+
$('.field-checkbox').each(function()
129+
{
130+
var cb = $(this)[0];
131+
if (cb.checked)
132+
{
133+
checked_fields.push(cb.value);
134+
}
135+
});
136+
137+
var checked_columns = [];
138+
$('.column-checkbox').each(function()
139+
{
140+
var cb = $(this)[0];
141+
if (cb.checked)
142+
{
143+
checked_columns.push(cb.value);
144+
}
145+
});
146+
147+
var url = BASE_URL + '/cohorts/download_manifest/' + cohort_id + '/';
148+
url += ("?file_type=" + file_type);
149+
url += ("&file_name=" + name);
150+
url += ("&header_fields=" + JSON.stringify(checked_fields));
151+
url += ("&columns=" + JSON.stringify(checked_columns));
152+
url += ("&downloadToken=" + downloadToken);
153+
154+
location.href = url;
155+
};
156+
157+
$('.column-checkbox').change(function() {
158+
update_download_manifest_buttons();
73159
});
74160

75-
tippy('.manifest-size-warning',{
76-
content: 'Your cohort is too large to be downloaded in its entirety, and will be truncated at 65,000 records ' +
77-
'ordered by PatientID, StudyID, SeriesID, and InstanceID.',
78-
theme: 'light',
79-
placement: 'left',
80-
arrow: false
161+
$("#export-manifest-name").change(function(){
162+
update_download_manifest_buttons();
81163
});
164+
165+
var update_download_manifest_buttons = function(){
166+
var num_selected_column =$('.column-checkbox:checked').length;
167+
var input_cohort_name_len = $('#export-manifest-name').val().length;
168+
169+
if (input_cohort_name_len == 0 || num_selected_column == 0) {
170+
$('#download-csv').attr('disabled', 'disabled');
171+
$('#download-tsv').attr('disabled', 'disabled');
172+
$('#download-json').attr('disabled', 'disabled');
173+
}
174+
else
175+
{
176+
$('#download-csv').removeAttr('disabled');
177+
$('#download-tsv').removeAttr('disabled');
178+
$('#download-json').removeAttr('disabled');
179+
}
180+
181+
if (num_selected_column == 0) {
182+
$('#no-column-alert-modal').show();
183+
}
184+
else
185+
{
186+
$('#no-column-alert-modal').hide();
187+
}
188+
};
189+
190+
update_download_manifest_buttons();
82191
});

static/js/image_search.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2672,6 +2672,11 @@ require([
26722672
console.debug("Load pending complete.");
26732673
cohort_loaded = true;
26742674
$('input[type="checkbox"]').prop("disabled", "disabled");
2675+
2676+
// Do not disable checkboxes for export manifest dialog
2677+
$('.field-checkbox').removeAttr('disabled');
2678+
$('.column-checkbox').removeAttr('disabled');
2679+
26752680
$('div.ui-slider').siblings('button').prop('disabled', 'disabled');
26762681
$('input#hide-zeros').prop("disabled", "");
26772682
$('input#hide-zeros').prop("checked", true);

templates/cohorts/cohort_details.html

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,14 @@ <h3 class="pull-left" role="heading" aria-level="1">Cohort Name: {{ cohort.name
4343
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-4">
4444
<div class="cohort-manifest pull-right">
4545
<div class="manifest-size-warning"><i class="fa fa-warning"></i></div>
46+
<button id="export-manifest" class="btn btn-special pull-right" data-toggle="modal"
47+
data-target="#export-manifest-modal"> Export Cohort Manifest
48+
</button>
49+
<!--
4650
<a id="download-manifest" class="btn btn-default pull-right" title="Download this cohort's manifest." href="{% url 'cohort_manifest' cohort.id %}">
4751
Download Cohort Manifest
4852
</a>
53+
-->
4954
</div>
5055
</div>
5156
</div>
@@ -64,6 +69,7 @@ <h3 class="pull-left" role="heading" aria-level="1">Cohort Name: {{ cohort.name
6469

6570
{% with is_cohort=True %}
6671
{% include "idc/explore_data_core.html" %}
72+
{% include "cohorts/export-manifest-modal.html" %}
6773
{% endwith %}
6874

6975
<!-- Download In Progress Modal -->
@@ -87,6 +93,7 @@ <h3 class="pull-left" role="heading" aria-level="1">Cohort Name: {{ cohort.name
8793
var is_cohort = true;
8894
var collection_tooltips = {{ collection_tooltips|safe }};
8995
var cohort_version = "{{ cohort_version|safe }}";
96+
var cohort_id = "{{ cohort_id|safe }}";
9097
</script>
9198
<script type="text/javascript" src="{% static 'js/libs/d3.v5.min.js' %}"></script>
9299
{{ block.super }}

0 commit comments

Comments
 (0)