1616 get_new_subscribers_stats ,
1717)
1818from slack .models import Channel , SlackActivityBucket , SlackUser
19- from versions .models import Version
19+ from versions .models import Version , ReportConfiguration
2020from .models import (
2121 Commit ,
2222 CommitAuthor ,
@@ -232,8 +232,8 @@ class CreateReportForm(CreateReportFullForm):
232232
233233 html_template_name = "admin/release_report_detail.html"
234234
235- version = ModelChoiceField (
236- queryset = Version .objects .minor_versions (). order_by ("-version_array " )
235+ report_configuration = ModelChoiceField (
236+ queryset = ReportConfiguration .objects .order_by ("-version " )
237237 )
238238
239239 def __init__ (self , * args , ** kwargs ):
@@ -255,14 +255,12 @@ def cache_key(self):
255255 self .cleaned_data ["library_8" ],
256256 ]
257257 lib_string = "," .join (str (x .id ) if x else "" for x in chosen_libraries )
258- version = self .cleaned_data ["version " ]
259- return f"release-report-{ lib_string } -{ version . name } "
258+ report_configuration = self .cleaned_data ["report_configuration " ]
259+ return f"release-report-{ lib_string } -{ report_configuration . version } "
260260
261- def _get_top_contributors_for_version (self ):
261+ def _get_top_contributors_for_version (self , version ):
262262 return (
263- CommitAuthor .objects .filter (
264- commit__library_version__version = self .cleaned_data ["version" ]
265- )
263+ CommitAuthor .objects .filter (commit__library_version__version = version )
266264 .annotate (
267265 commit_count = Count (
268266 "commit" ,
@@ -277,30 +275,32 @@ def _get_top_contributors_for_version(self):
277275 def _get_library_queryset_by_version (
278276 self , version : Version , annotate_commit_count = False
279277 ):
280- qs = self .library_queryset .filter (
281- library_version = LibraryVersion .objects .filter (
282- library = OuterRef ("id" ), version = version
283- )[:1 ],
284- )
278+ qs = self .library_queryset .none ()
279+ if version :
280+ qs = self .library_queryset .filter (
281+ library_version = LibraryVersion .objects .filter (
282+ library = OuterRef ("id" ), version = version
283+ )[:1 ],
284+ )
285285 if annotate_commit_count :
286286 qs = qs .annotate (commit_count = Count ("library_version__commit" ))
287287 return qs
288288
289- def _get_top_libraries_for_version (self ):
289+ def _get_top_libraries_for_version (self , version ):
290290 library_qs = self ._get_library_queryset_by_version (
291- self . cleaned_data [ " version" ] , annotate_commit_count = True
291+ version , annotate_commit_count = True
292292 )
293293 return library_qs .order_by ("-commit_count" )
294294
295- def _get_libraries_by_name (self ):
295+ def _get_libraries_by_name (self , version ):
296296 library_qs = self ._get_library_queryset_by_version (
297- self . cleaned_data [ " version" ] , annotate_commit_count = True
297+ version , annotate_commit_count = True
298298 )
299299 return library_qs .order_by ("name" )
300300
301- def _get_libraries_by_quality (self ):
301+ def _get_libraries_by_quality (self , version ):
302302 # returns "great", "good", and "standard" libraries in that order
303- library_qs = self ._get_library_queryset_by_version (self . cleaned_data [ " version" ] )
303+ library_qs = self ._get_library_queryset_by_version (version )
304304 return list (
305305 chain (
306306 library_qs .filter (graphic__isnull = False ),
@@ -309,17 +309,16 @@ def _get_libraries_by_quality(self):
309309 )
310310 )
311311
312- def _get_library_version_counts (self , libraries , library_order ):
312+ def _get_library_version_counts (self , library_order , version ):
313313 library_qs = self ._get_library_queryset_by_version (
314- self . cleaned_data [ " version" ] , annotate_commit_count = True
314+ version , annotate_commit_count = True
315315 )
316316 return sorted (
317317 list (library_qs .values ("commit_count" , "id" )),
318318 key = lambda x : library_order .index (x ["id" ]),
319319 )
320320
321- def _global_new_contributors (self , library_version ):
322- version = self .cleaned_data ["version" ]
321+ def _global_new_contributors (self , version ):
323322 version_lt = list (
324323 Version .objects .minor_versions ()
325324 .filter (version_array__lt = version .cleaned_version_parts_int )
@@ -343,8 +342,7 @@ def _global_new_contributors(self, library_version):
343342
344343 return set (version_author_ids ) - set (prior_version_author_ids )
345344
346- def _count_new_contributors (self , libraries , library_order ):
347- version = self .cleaned_data ["version" ]
345+ def _count_new_contributors (self , libraries , library_order , version ):
348346 version_lt = list (
349347 Version .objects .minor_versions ()
350348 .filter (version_array__lt = version .cleaned_version_parts_int )
@@ -382,12 +380,12 @@ def _count_new_contributors(self, libraries, library_order):
382380 key = lambda x : library_order .index (x ["id" ]),
383381 )
384382
385- def _count_issues (self , libraries , library_order , version ):
383+ def _count_issues (self , libraries , library_order , version , prior_version ):
386384 data = {
387385 x ["library_id" ]: x
388- for x in Issue .objects .count_opened_closed_during_release (version ). filter (
389- library_id__in = [ x . id for x in libraries ]
390- )
386+ for x in Issue .objects .count_opened_closed_during_release (
387+ version , prior_version
388+ ). filter ( library_id__in = [ x . id for x in libraries ])
391389 }
392390 ret = []
393391 for lib_id in library_order :
@@ -397,14 +395,14 @@ def _count_issues(self, libraries, library_order, version):
397395 ret .append ({"opened" : 0 , "closed" : 0 , "library_id" : lib_id })
398396 return ret
399397
400- def _count_commit_contributors_totals (self , version ):
398+ def _count_commit_contributors_totals (self , version , prior_version ):
401399 """Get a count of contributors for this release, and a count of
402400 new contributors.
403401
404402 """
405403 version_lt = list (
406404 Version .objects .minor_versions ()
407- .filter (version_array__lt = version .cleaned_version_parts_int )
405+ .filter (version_array__lte = prior_version .cleaned_version_parts_int )
408406 .values_list ("id" , flat = True )
409407 )
410408 version_lte = version_lt + [version .id ]
@@ -439,24 +437,24 @@ def _count_commit_contributors_totals(self, version):
439437 this_release_count = qs ["this_release_count" ]
440438 return this_release_count , new_count
441439
442- def _get_top_contributors_for_library_version (self , library_order ):
440+ def _get_top_contributors_for_library_version (self , library_order , version ):
443441 top_contributors_release = []
444442 for library_id in library_order :
445443 top_contributors_release .append (
446444 CommitAuthor .objects .filter (
447445 commit__library_version = LibraryVersion .objects .get (
448- version = self . cleaned_data [ " version" ] , library_id = library_id
446+ version = version , library_id = library_id
449447 )
450448 )
451449 .annotate (commit_count = Count ("commit" ))
452450 .order_by ("-commit_count" )[:10 ]
453451 )
454452 return top_contributors_release
455453
456- def _count_mailinglist_contributors (self , version ):
454+ def _count_mailinglist_contributors (self , version , prior_version ):
457455 version_lt = list (
458456 Version .objects .minor_versions ()
459- .filter (version_array__lt = version .cleaned_version_parts_int )
457+ .filter (version_array__lte = prior_version .cleaned_version_parts_int )
460458 .values_list ("id" , flat = True )
461459 )
462460 version_lte = version_lt + [version .id ]
@@ -620,7 +618,9 @@ def _get_slack_stats_for_channels(
620618 ):
621619 """Get slack stats for specific channels, or all channels."""
622620 start = prior_version .release_date
623- end = version .release_date - timedelta (days = 1 )
621+ end = date .today ()
622+ if version .release_date :
623+ end = version .release_date - timedelta (days = 1 )
624624 # count of all messages in the date range
625625 q = Q (day__range = [start , end ])
626626 if channels :
@@ -671,7 +671,15 @@ def _get_dependency_data(self, library_order, version):
671671 return diffs
672672
673673 def get_stats (self ):
674- version = self .cleaned_data ["version" ]
674+ report_configuration = self .cleaned_data ["report_configuration" ]
675+ version = Version .objects .filter (name = report_configuration .version ).first ()
676+
677+ prior_version = None
678+ if not version :
679+ # if the version is not set then the user has chosen a report configuration
680+ # that's not matching a live version, so we use the most recent version
681+ version = Version .objects .filter (name = "master" ).first ()
682+ prior_version = Version .objects .most_recent ()
675683
676684 downloads = {
677685 k : list (v )
@@ -680,12 +688,14 @@ def get_stats(self):
680688 key = attrgetter ("operating_system" ),
681689 )
682690 }
683- prior_version = (
684- Version .objects .minor_versions ()
685- .filter (version_array__lt = version .cleaned_version_parts_int )
686- .order_by ("-version_array" )
687- .first ()
688- )
691+
692+ if not prior_version :
693+ prior_version = (
694+ Version .objects .minor_versions ()
695+ .filter (version_array__lt = version .cleaned_version_parts_int )
696+ .order_by ("-version_array" )
697+ .first ()
698+ )
689699
690700 commit_count = Commit .objects .filter (
691701 library_version__version__name__lte = version .name ,
@@ -696,8 +706,8 @@ def get_stats(self):
696706 library_version__library__in = self .library_queryset ,
697707 ).count ()
698708
699- top_libraries_for_version = self ._get_top_libraries_for_version ()
700- top_libraries_by_name = self ._get_libraries_by_name ()
709+ top_libraries_for_version = self ._get_top_libraries_for_version (version )
710+ top_libraries_by_name = self ._get_libraries_by_name (version )
701711 library_order = self ._get_library_order (top_libraries_by_name )
702712 libraries = Library .objects .filter (id__in = library_order ).order_by (
703713 Case (
@@ -719,18 +729,18 @@ def get_stats(self):
719729 for item in zip (
720730 libraries ,
721731 self ._get_library_full_counts (libraries , library_order ),
722- self ._get_library_version_counts (libraries , library_order ),
723- self ._get_top_contributors_for_library_version (library_order ),
724- self ._count_new_contributors (libraries , library_order ),
725- self ._count_issues (libraries , library_order , version ),
732+ self ._get_library_version_counts (library_order , version ),
733+ self ._get_top_contributors_for_library_version (library_order , version ),
734+ self ._count_new_contributors (libraries , library_order , version ),
735+ self ._count_issues (libraries , library_order , version , prior_version ),
726736 self ._get_library_versions (library_order , version ),
727737 self ._get_dependency_data (library_order , version ),
728738 )
729739 ]
730740 library_data = [
731741 x for x in library_data if x ["version_count" ]["commit_count" ] > 0
732742 ]
733- top_contributors = self ._get_top_contributors_for_version ()
743+ top_contributors = self ._get_top_contributors_for_version (version )
734744 # total messages sent during this release (version)
735745 total_mailinglist_count = EmailData .objects .filter (version = version ).aggregate (
736746 total = Sum ("count" )
@@ -743,11 +753,11 @@ def get_stats(self):
743753 (
744754 mailinglist_contributor_release_count ,
745755 mailinglist_contributor_new_count ,
746- ) = self ._count_mailinglist_contributors (version )
756+ ) = self ._count_mailinglist_contributors (version , prior_version )
747757 (
748758 commit_contributors_release_count ,
749759 commit_contributors_new_count ,
750- ) = self ._count_commit_contributors_totals (version )
760+ ) = self ._count_commit_contributors_totals (version , prior_version )
751761 library_count = LibraryVersion .objects .filter (
752762 version = version ,
753763 library__in = self .library_queryset ,
@@ -775,22 +785,35 @@ def get_stats(self):
775785 slack_channels = batched (
776786 Channel .objects .filter (name__istartswith = "boost" ).order_by ("name" ), 10
777787 )
778- committee_members = version .financial_committee_members .all ()
788+ committee_members = report_configuration .financial_committee_members .all ()
779789 mailinglist_post_stats = get_mailing_list_post_stats (
780- prior_version .release_date , version .release_date
790+ prior_version .release_date , version .release_date or date . today ()
781791 )
782792 new_subscribers_stats = get_new_subscribers_stats (
783- prior_version .release_date , version .release_date
793+ prior_version .release_date , version .release_date or date . today ()
784794 )
785795 library_index_library_data = []
786- for library in self ._get_libraries_by_quality ():
796+ for library in self ._get_libraries_by_quality (version ):
787797 library_index_library_data .append (
788798 (
789799 library ,
790800 library in [lib ["library" ] for lib in library_data ],
791801 )
792802 )
793- wordcloud_base64 , wordcloud_top_words = generate_wordcloud (version )
803+ wordcloud_base64 , wordcloud_top_words = generate_wordcloud (
804+ version , prior_version
805+ )
806+
807+ opened_issues_count = (
808+ Issue .objects .filter (library__in = self .library_queryset )
809+ .opened_during_release (version , prior_version )
810+ .count ()
811+ )
812+ closed_issues_count = (
813+ Issue .objects .filter (library__in = self .library_queryset )
814+ .closed_during_release (version , prior_version )
815+ .count ()
816+ )
794817
795818 return {
796819 "committee_members" : committee_members ,
@@ -799,17 +822,10 @@ def get_stats(self):
799822 "wordcloud_base64" : wordcloud_base64 ,
800823 "wordcloud_frequencies" : wordcloud_top_words ,
801824 "version" : version ,
825+ "report_configuration" : report_configuration ,
802826 "prior_version" : prior_version ,
803- "opened_issues_count" : Issue .objects .filter (
804- library__in = self .library_queryset
805- )
806- .opened_during_release (version )
807- .count (),
808- "closed_issues_count" : Issue .objects .filter (
809- library__in = self .library_queryset
810- )
811- .closed_during_release (version )
812- .count (),
827+ "opened_issues_count" : opened_issues_count ,
828+ "closed_issues_count" : closed_issues_count ,
813829 "mailinglist_counts" : mailinglist_counts ,
814830 "mailinglist_total" : total_mailinglist_count or 0 ,
815831 "mailinglist_contributor_release_count" : mailinglist_contributor_release_count , # noqa: E501
0 commit comments