@@ -353,25 +353,77 @@ def check_feature_flag(self, flag_name):
353353
354354 def check_channel_space (self , channel ):
355355 tree_cte = With (self .get_user_active_trees ().distinct (), name = "trees" )
356- files_cte = With (
357- tree_cte .join (
358- self .files .get_queryset (), contentnode__tree_id = tree_cte .col .tree_id
359- )
360- .values ("checksum" )
361- .distinct (),
362- name = "files" ,
356+
357+ user_files_cte = With (
358+ self .files .get_queryset ().values (
359+ "id" ,
360+ "checksum" ,
361+ "contentnode_id" ,
362+ "file_format_id" ,
363+ "file_size" ,
364+ "preset_id" ,
365+ ),
366+ name = "user_files" ,
363367 )
364368
365- staging_tree_files = (
366- self . files . filter ( contentnode__tree_id = channel . staging_tree . tree_id )
369+ editable_files_qs = (
370+ user_files_cte . queryset ( )
367371 .with_cte (tree_cte )
368- .with_cte (files_cte )
369- .exclude (Exists (files_cte .queryset ().filter (checksum = OuterRef ("checksum" ))))
370- .values ("checksum" )
371- .distinct ()
372+ .with_cte (user_files_cte )
373+ .filter (
374+ Exists (
375+ tree_cte .join (
376+ ContentNode .objects .all (),
377+ tree_id = tree_cte .col .tree_id ,
378+ )
379+ .with_cte (tree_cte )
380+ .filter (id = OuterRef ("contentnode_id" ))
381+ )
382+ )
383+ )
384+
385+ existing_checksums_cte = With (
386+ editable_files_qs .values ("checksum" ).distinct (),
387+ name = "existing_checksums" ,
388+ )
389+
390+ staging_files_qs = (
391+ user_files_cte .queryset ()
392+ .with_cte (user_files_cte )
393+ .filter (
394+ Exists (
395+ ContentNode .objects .filter (
396+ tree_id = channel .staging_tree .tree_id ,
397+ id = OuterRef ("contentnode_id" ),
398+ )
399+ )
400+ )
401+ )
402+
403+ new_staging_files_qs = (
404+ staging_files_qs .with_cte (tree_cte )
405+ .with_cte (existing_checksums_cte )
406+ .exclude (
407+ Exists (
408+ existing_checksums_cte .queryset ().filter (
409+ checksum = OuterRef ("checksum" ),
410+ )
411+ )
412+ )
413+ )
414+
415+ new_staging_files_qs = self ._filter_storage_billable_files (new_staging_files_qs )
416+
417+ unique_staging_ids = (
418+ new_staging_files_qs .order_by ("checksum" , "id" )
419+ .distinct ("checksum" )
420+ .values ("id" )
372421 )
373422 staged_size = float (
374- staging_tree_files .aggregate (used = Sum ("file_size" ))["used" ] or 0
423+ new_staging_files_qs .filter (id__in = Subquery (unique_staging_ids )).aggregate (
424+ used = Sum ("file_size" )
425+ )["used" ]
426+ or 0
375427 )
376428
377429 if self .get_available_space () < staged_size :
@@ -414,13 +466,55 @@ def get_user_active_trees(self):
414466 )
415467
416468 def get_user_active_files (self ):
417- cte = With (self .get_user_active_trees ().distinct ())
418469
419- return (
420- cte .join (self .files .get_queryset (), contentnode__tree_id = cte .col .tree_id )
421- .with_cte (cte )
422- .values ("checksum" )
423- .distinct ()
470+ tree_cte = With (self .get_user_active_trees ().distinct (), name = "trees" )
471+
472+ user_files_cte = With (
473+ self .files .get_queryset ().only (
474+ "id" ,
475+ "checksum" ,
476+ "contentnode_id" ,
477+ "file_format_id" ,
478+ "file_size" ,
479+ "preset_id" ,
480+ ),
481+ name = "user_files" ,
482+ )
483+
484+ base_files_qs = (
485+ user_files_cte .queryset ()
486+ .with_cte (tree_cte )
487+ .with_cte (user_files_cte )
488+ .filter (
489+ Exists (
490+ tree_cte .join (
491+ ContentNode .objects .only ("id" , "tree_id" ),
492+ tree_id = tree_cte .col .tree_id ,
493+ )
494+ .with_cte (tree_cte )
495+ .filter (id = OuterRef ("contentnode_id" ))
496+ )
497+ )
498+ )
499+
500+ base_files_qs = self ._filter_storage_billable_files (base_files_qs )
501+
502+ unique_file_ids = (
503+ base_files_qs .order_by ("checksum" , "id" ).distinct ("checksum" ).values ("id" )
504+ )
505+
506+ files_qs = base_files_qs .filter (id__in = Subquery (unique_file_ids ))
507+
508+ return files_qs
509+
510+ def _filter_storage_billable_files (self , queryset ):
511+ """
512+ Perseus exports would not be included in storage calculations.
513+ """
514+ if queryset is None :
515+ return queryset
516+ return queryset .exclude (file_format_id__isnull = True ).exclude (
517+ file_format_id = file_formats .PERSEUS
424518 )
425519
426520 def get_space_used (self , active_files = None ):
0 commit comments