Skip to content

Commit 85303a2

Browse files
committed
-> Tooltip fixes/improvements
-> Cart size reinstated, will disable over 3TB for JS download
1 parent 9b39112 commit 85303a2

13 files changed

Lines changed: 137 additions & 244 deletions

File tree

etl/etl.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
FIELD_MAP = {x: i for i, x in enumerate([
6262
"collection_id", "collection_uuid", "name", "collections", "image_types", "supporting_data", "subject_count", "doi",
6363
"source_url", "cancer_type", "species", "location", "analysis_artifacts", "description", "collection_type",
64-
"program", "access", "date_updated", "tcia_wiki_collection_id", "license_short_name", "active", "total_size"
64+
"program", "access", "date_updated", "tcia_wiki_collection_id", "license_short_name", "active", "total_size", "total_size_with_ar"
6565
])}
6666

6767
TOKENIZED_FIELDS = ["PatientID", "SeriesInstanceUID", "StudyInstanceUID"]
@@ -146,8 +146,8 @@
146146
}
147147

148148
SOLR_SINGLE_VAL = {
149-
"StudyInstanceUID": ["PatientID", "StudyInstanceUID", "crdc_study_uuid"],
150-
"SeriesInstanceUID": ["PatientID", "StudyInstanceUID", "SeriesInstanceUID", "crdc_study_uuid", "crdc_series_uuid"]
149+
"StudyInstanceUID": ["PatientID", "StudyInstanceUID", "crdc_study_uuid","instance_size"],
150+
"SeriesInstanceUID": ["PatientID", "StudyInstanceUID", "SeriesInstanceUID", "crdc_study_uuid", "crdc_series_uuid", "instance_size"]
151151
}
152152

153153
ETL_CONFIG = {}
@@ -356,7 +356,7 @@ def load_collections(filename, data_version="8.0"):
356356
exact_collection_fields = [
357357
"collection_id", "collection_uuid", "name", "collections", "image_types", "supporting_data", "subject_count", "doi",
358358
"source_url", "cancer_type", "species", "location", "analysis_artifacts", "description", "collection_type",
359-
"access", "date_updated", "active", "total_size"]
359+
"access", "date_updated", "active", "total_size", "total_size_with_ar"]
360360
field_map = FIELD_MAP
361361
for line in csv_reader(collection_file):
362362
if COLLECTION_HEADER_CHK in line:

idc/urls.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
re_path(r'^explore/manifest/$', views.explorer_manifest, name='get_explore_manifest'),
5252
re_path(r'^explore/manifest/series/$', views.explorer_manifest, name='get_series_ids_manifest'),
5353
re_path(r'^tables/', views.populate_tables, name='populate_tables'),
54-
re_path(r'^studymp/', views.studymp, name='studymp'),
5554
re_path(r'^warning/', views.warn_page, name='warn'),
5655
re_path(r'^about/$', views.about_page, name='about_page'),
5756
re_path(r'^dashboard/', views.dashboard_page, name='dashboard'),

idc/views.py

Lines changed: 14 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
from solr_helpers import build_solr_query, query_solr_and_format_result
5252

5353
from idc.settings import MAX_FILE_LIST_REQUEST
54+
from idc_collections.collex_metadata_utils import convert_disk_size
5455

5556
debug = settings.DEBUG
5657
logger = logging.getLogger(__name__)
@@ -247,86 +248,6 @@ def save_ui_hist(request):
247248
return JsonResponse({}, status=status)
248249

249250

250-
# returns various metadata mappings for selected projects used in calculating cart selection
251-
# counts 'on the fly' client side
252-
def studymp(request):
253-
response = {}
254-
status = 200
255-
sources = ImagingDataCommonsVersion.objects.get(active=True).get_data_sources(
256-
active=True, source_type=DataSource.SOLR,
257-
aggregate_level="StudyInstanceUID"
258-
)
259-
data_types = [DataSetType.IMAGE_DATA, DataSetType.ANCILLARY_DATA, DataSetType.DERIVED_DATA]
260-
data_sets = DataSetType.objects.filter(data_type__in=data_types)
261-
aggregate_level='StudyInstanceUID'
262-
versions=[]
263-
versions = ImagingDataCommonsVersion.objects.filter(
264-
version_number__in=versions
265-
).get_data_versions(active=True) if len(versions) else ImagingDataCommonsVersion.objects.filter(
266-
active=True
267-
).get_data_versions(active=True)
268-
aux_sources = data_sets.get_data_sources().filter(
269-
source_type=DataSource.SOLR,
270-
aggregate_level__in=["case_barcode", "sample_barcode", aggregate_level],
271-
id__in=versions.get_data_sources().filter(source_type=DataSource.SOLR).values_list("id", flat=True)
272-
).distinct()
273-
274-
try:
275-
req = request.GET if request.method == 'GET' else request.POST
276-
filters = json.loads(req.get('filters', '{}'))
277-
278-
mxSeries = int(req.get('mxseries'))
279-
mxStudies= int(req.get('mxstudies'))
280-
limit = int(req.get('limit', mxStudies))
281-
offset = int(req.get('offset',0))
282-
283-
casestudymp = dict()
284-
studymp = dict()
285-
projstudymp = dict()
286-
287-
idsEx = get_collex_metadata(
288-
filters, ['collection_id', 'PatientID','StudyInstanceUID', 'SeriesInstanceUID'], record_limit=limit,
289-
sources=sources, offset=offset, records_only=True, custom_facets={}, aux_sources=aux_sources,
290-
collapse_on='StudyInstanceUID', counts_only=False, filtered_needed=False,
291-
raw_format=True, default_facets=False, sort=None
292-
)
293-
294-
logger.debug("[STATUS] records pulled: {}".format(len(idsEx['docs'])))
295-
296-
for doc in idsEx['docs']:
297-
proj=doc['collection_id'][0]
298-
patientid=doc['PatientID']
299-
studyid= doc['StudyInstanceUID']
300-
cnt = len(doc['SeriesInstanceUID'])
301-
302-
if not patientid in casestudymp:
303-
casestudymp[patientid]={}
304-
if not proj in projstudymp:
305-
projstudymp[proj] = {}
306-
studymp[studyid]={}
307-
studymp[studyid]['cnt'] = cnt
308-
studymp[studyid]['proj'] = proj
309-
studymp[studyid]['PatientID'] = patientid
310-
studymp[studyid]['val'] = []
311-
projstudymp[proj][studyid] = cnt
312-
casestudymp[patientid][studyid] = cnt
313-
314-
response["studymp"] = studymp
315-
response['casestudymp'] = casestudymp
316-
response['projstudymp'] = projstudymp
317-
318-
except Exception as e:
319-
logger.error("[ERROR] While attempting to get studymp:")
320-
logger.exception(e)
321-
messages.error(
322-
request,
323-
"Encountered an error when attempting to get the studymp - please contact the administrator."
324-
)
325-
status = 400
326-
327-
return JsonResponse(response, status=status)
328-
329-
330251
def populate_tables(request):
331252
response = {}
332253
status = 200
@@ -648,6 +569,7 @@ def cart_data(request):
648569
aggregate_level = req.get('aggregate_level', 'StudyInstanceUID')
649570
results_level = req.get('results_level', 'StudyInstanceUID')
650571
dois_only = bool(req.get('dois_only', 'false').lower() == 'true')
572+
size_only = bool(req.get('size_only', 'false').lower() == 'true')
651573

652574
partitions = json.loads(req.get('partitions', '{}'))
653575

@@ -656,22 +578,29 @@ def cart_data(request):
656578
length = int(req.get('length', 100))
657579
mxseries = int(req.get('mxseries',1000))
658580

581+
doi_or_size_only = (dois_only or size_only)
582+
659583
if len(partitions) <= 0 or aggregate_level not in ['SeriesInstanceUID', 'StudyInstanceUID']:
660584
response['numFound'] = 0
661585
response['docs'] = []
662586
else:
663587
if aggregate_level == 'StudyInstanceUID':
664588
response = get_cart_data_studylvl(
665-
filtergrp_list, partitions, limit, offset, length, mxseries, with_records=(not dois_only),
666-
results_lvl=results_level, dois_only=dois_only
589+
filtergrp_list, partitions, limit, offset, length, mxseries, with_records=(not doi_or_size_only),
590+
results_lvl=results_level, dois_only=dois_only, size_only=size_only
667591
)
668592
elif aggregate_level == 'SeriesInstanceUID':
669593
response = get_cart_data_serieslvl(
670-
filtergrp_list, partitions, field_list if not dois_only else None, limit, offset,
671-
with_records=(not dois_only), dois_only=dois_only
594+
filtergrp_list, partitions, field_list if (not doi_or_size_only) else None, limit, offset,
595+
with_records=(not doi_or_size_only), dois_only=dois_only, size_only=size_only
672596
)
673597
if dois_only:
674598
response = {'dois': response['dois']}
599+
if size_only:
600+
response = {
601+
"total_size": response['total_size'],
602+
"display_size": convert_disk_size(response['total_size'])
603+
}
675604
except Exception as e:
676605
logger.error("[ERROR] While loading cart:")
677606
logger.exception(e)
@@ -704,7 +633,7 @@ def get_series(request, collection_id=None, patient_id=None, study_uid=None):
704633
filter_query = build_solr_query(
705634
{ w: v for x in filtergrp_list for w, v in list(x.items())},
706635
with_tags_for_ex=False,
707-
search_child_records_by=None, solr_default_op='AND'
636+
search_child_records_by={w: "StudyInstanceUID" for x in filtergrp_list for w in x}, solr_default_op='AND'
708637
)
709638
result = query_solr_and_format_result(
710639
{

static/css/style.css

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4524,8 +4524,11 @@ d-topics-list iframe {
45244524
}
45254525

45264526
.download-all-disabled {
4527-
cursor: not-allowed;
4528-
color: gray;
4527+
cursor: not-allowed !important;
4528+
}
4529+
4530+
.fa.download-all-disabled {
4531+
color: gray;
45294532
}
45304533

45314534
#floating-message {

static/css/vendor.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2832,7 +2832,7 @@ select[multiple].input-lg,
28322832
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); }
28332833
.btn.disabled, .btn[disabled],
28342834
fieldset[disabled] .btn {
2835-
cursor: not-allowed;
2835+
cursor: not-allowed !important;
28362836
opacity: 0.65;
28372837
filter: alpha(opacity=65);
28382838
-webkit-box-shadow: none;

static/js/base.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ define(['jquery', 'utils'], function($, utils) {
276276
utils.removeCookie(name, path);
277277
},
278278
blockResubmit: utils.blockResubmit,
279-
checkManifestReady: utils.checkManifestReady
279+
checkManifestReady: utils.checkManifestReady,
280+
updateDownloadBtns: utils.updateDownloadBtns
280281
};
281282
});

static/js/cartutils.js

Lines changed: 26 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,10 @@ define(['filterutils','jquery', 'tippy', 'base' ], function(filterutils, $, tip
122122
return deferred.promise();
123123
};
124124

125-
126-
const updateCartCounts =function(){
125+
const updateCartCounts = async function(){
127126
var buttonContents = '<button class="btn filter-type clear-cart" role="button" title="Empty your cart."><i class="fa fa-rotate-left"></i></button>';
128-
if (Object.keys(window.proj_in_cart).length>0){
127+
let cart_has_contents = Boolean(Object.keys(window.proj_in_cart).length>0);
128+
if (cart_has_contents){
129129
var nmprojs = 0;
130130
var nmcases=0;
131131
var nmstudies=0;
@@ -138,7 +138,7 @@ define(['filterutils','jquery', 'tippy', 'base' ], function(filterutils, $, tip
138138
}
139139

140140
let content = buttonContents+'<span id ="#cart_stats">Cart contents: ' + nmseries.toString()+' series from '+nmprojs.toString()+
141-
' collections / '+nmcases.toString()+' cases / '+nmstudies.toString()+' studies</span>';
141+
' collections / '+nmcases.toString()+' cases / '+nmstudies.toString()+' studies</span> <span class="cart_disk_size">(Calculating size...)</span>';
142142
localStorage.setItem('manifestSeriesCount',nmseries);
143143

144144
$('#cart_stats_holder').html(content) ;
@@ -149,6 +149,28 @@ define(['filterutils','jquery', 'tippy', 'base' ], function(filterutils, $, tip
149149
$('#cart_stats').addClass('empty-cart');
150150
$('.cart-activated-controls').attr('disabled', 'disabled');
151151
}
152+
let cart_disk_size = 0;
153+
let cart_disk_display_size = "(Calculating...)";
154+
let cart_disk_resp = await fetch(`${BASE_URL}/cart_data/`, {
155+
method: "POST",
156+
body: new URLSearchParams({
157+
'filtergrp_list': JSON.stringify(window.filtergrp_list ? window.filtergrp_list : [{}]),
158+
'partitions': JSON.stringify(window.partitions),
159+
'size_only': 'true'
160+
}),
161+
headers: {"X-CSRFToken": $.getCookie('csrftoken'), "content-type": 'application/x-www-form-urlencoded'}
162+
});
163+
if(!cart_disk_resp.ok) {
164+
console.error("Unable to fetch cart size!");
165+
cart_disk_size = 4;
166+
cart_disk_display_size = "(Unable to retrieve size.)";
167+
} else {
168+
let cart_disk_res = await cart_disk_resp.json();
169+
cart_disk_size = cart_disk_res['total_size']/Math.pow(1000,4);
170+
cart_disk_display_size = cart_disk_res['display_size'];
171+
}
172+
$('.cart_disk_size').html(cart_disk_display_size);
173+
base.updateDownloadBtns('cart', cart_has_contents, cart_disk_size);
152174

153175
}
154176

@@ -298,7 +320,6 @@ define(['filterutils','jquery', 'tippy', 'base' ], function(filterutils, $, tip
298320

299321
window.updatePartitionsFromScratch = function(){
300322
window.partitions = new Array();
301-
302323
for (var i=0;i<window.cartHist.length;i++){
303324
var cartHist=window.cartHist[i];
304325
updateGlobalPartitions(cartHist.partitions);
@@ -308,10 +329,6 @@ define(['filterutils','jquery', 'tippy', 'base' ], function(filterutils, $, tip
308329
refilterGlobalPartitions(cartHist,i);
309330
}
310331
fixpartitions();
311-
var filtStrings = createFiltStrings();
312-
var solrStr = createSolrString(filtStrings);
313-
window.solrStr = solrStr;
314-
var ii=1;
315332
};
316333

317334
//looking across the history of cart selections, create one set of exclusive partitions of the imaging data
@@ -490,29 +507,6 @@ define(['filterutils','jquery', 'tippy', 'base' ], function(filterutils, $, tip
490507
return(filtStrings);
491508
}
492509

493-
// not really needed, but used to creating the solr string in on the client side
494-
const createSolrString = function(filtStringA){
495-
var solrStr=''
496-
var solrA=[]
497-
for (var i=0;i< window.partitions.length;i++){
498-
var curPart = window.partitions[i];
499-
if (!curPart['null']) {
500-
var curPartAttStrA = parsePartitionAttStrings(filtStringA, curPart);
501-
var curPartStr = parsePartitionStrings(curPart);
502-
for (var j = 0; j < curPartAttStrA.length; j++) {
503-
if (curPartAttStrA[j].length > 0) {
504-
solrA.push('(' + curPartStr + ')(' + curPartAttStrA[j] + ')')
505-
} else{
506-
solrA.push(curPartStr);
507-
}
508-
}
509-
}
510-
}
511-
solrA = solrA.map(x => '('+x+')');
512-
var solrStr = solrA.join(' OR ')
513-
return solrStr
514-
}
515-
516510
const parsePartitionAttStrings = function(filtStringA, partition){
517511
var attStrA =[];
518512
var filt2D = partition['filt'];

static/js/explore.js

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,6 @@ require([
7373
//sesssionStorage.setItem("cartHist",JSON.stringify(window.cartHist));
7474
window.partitions = new Array();
7575

76-
window.studymp=new Object();
77-
window.projstudymp = new Object();
78-
window.casestudymp = new Object();
7976
window.collection = JSON.parse(document.getElementById('collections').textContent);
8077
var lst = Object.keys(window.collection).sort();
8178
window.collectionData = new Array();
@@ -481,8 +478,17 @@ require([
481478
plugins: [dynamicTipFunc]
482479
};
483480

481+
let disabled_messages = {
482+
'download-all-disabled': chromium_only,
483+
'download-size-disabled': "This set of images is over 3TB in size. Please use manifest download to obtain these images.",
484+
'download-cart-disabled': "Add items to the cart to enable this feature.",
485+
'download-cohort-disabled': "Select a filter to enable this feature."
486+
};
484487
const download_tooltip = {
485488
dynamicTip: function(ref){
489+
if($(ref).hasClass('is-disabled')){
490+
return disabled_messages[$(ref).attr('data-disabled-type')];
491+
}
486492
let download_type = $(ref).attr('data-download-type');
487493
return `Download all of the image instances in this ${download_type}.`;
488494
},
@@ -491,15 +497,11 @@ require([
491497
placement: 'left',
492498
arrow: false,
493499
interactive:true,
494-
target: '.download-all-instances',
500+
target: '.download-instances',
495501
maxWidth: 200,
496502
plugins: [dynamicTipFunc]
497503
};
498504

499-
tippy.delegate('.projects-table', disabled_download_tooltip);
500-
501-
tippy.delegate('.projects-table', download_tooltip);
502-
503505
tippy.delegate('.projects-table', cart_tooltip);
504506

505507
tippy.delegate('.cases-table', cart_tooltip);
@@ -533,22 +535,10 @@ require([
533535
maxWidth: 200
534536
});
535537

536-
tippy.delegate('.cases-table', download_tooltip);
537-
538-
tippy.delegate('.cases-table', disabled_download_tooltip);
539-
540-
tippy.delegate('.studies-table', download_tooltip);
541-
542538
tippy.delegate('.studies-table', manifest_tooltip);
543539

544-
tippy.delegate('.studies-table', disabled_download_tooltip);
545-
546-
tippy.delegate('.series-table', download_tooltip);
547-
548540
tippy.delegate('.series-table', manifest_tooltip);
549541

550-
tippy.delegate('.series-table', disabled_download_tooltip);
551-
552542
tippy.delegate('.series-table', {
553543
content: 'Some or all of the images in this collection are not publicly available.',
554544
theme: 'dark',
@@ -571,6 +561,9 @@ require([
571561
maxWidth: 800
572562
});
573563

564+
tippy.delegate('#body', disabled_download_tooltip);
565+
tippy.delegate('#body', download_tooltip);
566+
574567
tippy.delegate('#body', {
575568
content: function(reference) {
576569
return "Copied!";

0 commit comments

Comments
 (0)