This commit is contained in:
Rachid Mrad 2024-03-01 18:32:45 -05:00
parent 34769f2d01
commit 717f71f038
No known key found for this signature in database
6 changed files with 425 additions and 318 deletions

View file

@ -5,14 +5,14 @@ import datetime
from django import forms from django import forms
from django.db.models import Avg, F, Value, CharField, Q from django.db.models import Avg, F, Value, CharField, Q
from django.db.models.functions import Concat, Coalesce from django.db.models.functions import Concat, Coalesce
from django.http import HttpResponse, HttpResponseRedirect from django.http import HttpResponseRedirect
from django.shortcuts import redirect, render from django.shortcuts import redirect, render
from django_fsm import get_available_FIELD_transitions from django_fsm import get_available_FIELD_transitions
from django.contrib import admin, messages from django.contrib import admin, messages
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import Group from django.contrib.auth.models import Group
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.urls import path, reverse from django.urls import reverse
from dateutil.relativedelta import relativedelta # type: ignore from dateutil.relativedelta import relativedelta # type: ignore
from epplibwrapper.errors import ErrorCode, RegistryError from epplibwrapper.errors import ErrorCode, RegistryError
from registrar.models import Contact, Domain, DomainApplication, DraftDomain, User, Website from registrar.models import Contact, Domain, DomainApplication, DraftDomain, User, Website
@ -367,9 +367,7 @@ def analytics(request):
thirty_days_ago = datetime.datetime.today() - datetime.timedelta(days=30) thirty_days_ago = datetime.datetime.today() - datetime.timedelta(days=30)
last_30_days_applications = models.DomainApplication.objects.filter( last_30_days_applications = models.DomainApplication.objects.filter(created_at__gt=thirty_days_ago)
created_at__gt=thirty_days_ago
)
last_30_days_approved_applications = models.DomainApplication.objects.filter( last_30_days_approved_applications = models.DomainApplication.objects.filter(
created_at__gt=thirty_days_ago, status=DomainApplication.ApplicationStatus.APPROVED created_at__gt=thirty_days_ago, status=DomainApplication.ApplicationStatus.APPROVED
) )
@ -433,8 +431,6 @@ def analytics(request):
} }
deleted_domains_sliced_at_end_date = csv_export.get_sliced_domains(filter_deleted_domains_end_date) deleted_domains_sliced_at_end_date = csv_export.get_sliced_domains(filter_deleted_domains_end_date)
# Created and Submitted requests # Created and Submitted requests
filter_requests_start_date = { filter_requests_start_date = {
"created_at__lte": start_date_formatted, "created_at__lte": start_date_formatted,
@ -466,26 +462,23 @@ def analytics(request):
last_30_days_applications=last_30_days_applications.count(), last_30_days_applications=last_30_days_applications.count(),
last_30_days_approved_applications=last_30_days_approved_applications.count(), last_30_days_approved_applications=last_30_days_approved_applications.count(),
average_application_approval_time_last_30_days=avg_approval_time, average_application_approval_time_last_30_days=avg_approval_time,
managed_domains_sliced_at_start_date=managed_domains_sliced_at_start_date, managed_domains_sliced_at_start_date=managed_domains_sliced_at_start_date,
unmanaged_domains_sliced_at_start_date=unmanaged_domains_sliced_at_start_date, unmanaged_domains_sliced_at_start_date=unmanaged_domains_sliced_at_start_date,
managed_domains_sliced_at_end_date=managed_domains_sliced_at_end_date, managed_domains_sliced_at_end_date=managed_domains_sliced_at_end_date,
unmanaged_domains_sliced_at_end_date=unmanaged_domains_sliced_at_end_date, unmanaged_domains_sliced_at_end_date=unmanaged_domains_sliced_at_end_date,
ready_domains_sliced_at_start_date=ready_domains_sliced_at_start_date, ready_domains_sliced_at_start_date=ready_domains_sliced_at_start_date,
deleted_domains_sliced_at_start_date=deleted_domains_sliced_at_start_date, deleted_domains_sliced_at_start_date=deleted_domains_sliced_at_start_date,
ready_domains_sliced_at_end_date=ready_domains_sliced_at_end_date, ready_domains_sliced_at_end_date=ready_domains_sliced_at_end_date,
deleted_domains_sliced_at_end_date=deleted_domains_sliced_at_end_date, deleted_domains_sliced_at_end_date=deleted_domains_sliced_at_end_date,
requests_sliced_at_start_date=requests_sliced_at_start_date, requests_sliced_at_start_date=requests_sliced_at_start_date,
submitted_requests_sliced_at_start_date=submitted_requests_sliced_at_start_date, submitted_requests_sliced_at_start_date=submitted_requests_sliced_at_start_date,
requests_sliced_at_end_date=requests_sliced_at_end_date, requests_sliced_at_end_date=requests_sliced_at_end_date,
submitted_requests_sliced_at_end_date=submitted_requests_sliced_at_end_date, submitted_requests_sliced_at_end_date=submitted_requests_sliced_at_end_date,
), ),
) )
return render(request, "admin/analytics.html", context) return render(request, "admin/analytics.html", context)
class MyUserAdmin(BaseUserAdmin): class MyUserAdmin(BaseUserAdmin):
"""Custom user admin class to use our inlines.""" """Custom user admin class to use our inlines."""

View file

@ -10,7 +10,15 @@ from django.views.generic import RedirectView
from registrar import views from registrar import views
from registrar.admin import analytics from registrar.admin import analytics
from registrar.views.admin_views import ExportDataDomainsGrowth, ExportDataFederal, ExportDataFull, ExportDataManagedDomains, ExportDataRequestsGrowth, ExportDataType, ExportDataUnmanagedDomains from registrar.views.admin_views import (
ExportDataDomainsGrowth,
ExportDataFederal,
ExportDataFull,
ExportDataManagedDomains,
ExportDataRequestsGrowth,
ExportDataType,
ExportDataUnmanagedDomains,
)
from registrar.views.application import Step from registrar.views.application import Step
from registrar.views.utility import always_404 from registrar.views.utility import always_404
@ -91,7 +99,6 @@ urlpatterns = [
admin.site.admin_view(analytics), admin.site.admin_view(analytics),
name="analytics", name="analytics",
), ),
path("admin/", admin.site.urls), path("admin/", admin.site.urls),
path( path(
"application/<id>/edit/", "application/<id>/edit/",

View file

@ -27,7 +27,7 @@ def handle_profile(sender, instance, **kwargs):
last_name = getattr(instance, "last_name", "") last_name = getattr(instance, "last_name", "")
email = getattr(instance, "email", "") email = getattr(instance, "email", "")
phone = getattr(instance, "phone", "") phone = getattr(instance, "phone", "")
logger.info(f'in handle_profile first {instance}') logger.info(f"in handle_profile first {instance}")
is_new_user = kwargs.get("created", False) is_new_user = kwargs.get("created", False)
@ -37,7 +37,7 @@ def handle_profile(sender, instance, **kwargs):
contacts = Contact.objects.filter(user=instance) contacts = Contact.objects.filter(user=instance)
if len(contacts) == 0: # no matching contact if len(contacts) == 0: # no matching contact
logger.info(f'inside no matching contacts for first {first_name} last {last_name} email {email}') logger.info(f"inside no matching contacts for first {first_name} last {last_name} email {email}")
Contact.objects.create( Contact.objects.create(
user=instance, user=instance,
first_name=first_name, first_name=first_name,

View file

@ -22,10 +22,8 @@
</ul> </ul>
</div> </div>
</div> </div>
</div> </div>
<div class="tablet:grid-col-6 margin-top-2"> <div class="tablet:grid-col-6 margin-top-2">
<div class="module height-full"> <div class="module height-full">
<h2>Current domains</h2> <h2>Current domains</h2>
<div class="padding-top-2 padding-x-2"> <div class="padding-top-2 padding-x-2">
@ -54,8 +52,9 @@
</ul> </ul>
</div> </div>
</div> </div>
</div>
</div>
</div></div>
<div class="grid-row grid-gap-2 margin-top-2"> <div class="grid-row grid-gap-2 margin-top-2">
<div class="grid-col"> <div class="grid-col">
<div class="module"> <div class="module">
@ -78,7 +77,6 @@
<input type="date" id="end" name="end" value="2023-12-01" min="2023-12-01" /> <input type="date" id="end" name="end" value="2023-12-01" min="2023-12-01" />
</div> </div>
</div> </div>
<ul class="usa-button-group"> <ul class="usa-button-group">
<li class="usa-button-group__item"> <li class="usa-button-group__item">
<button class="button exportLink" data-export-url="{% url 'export_domains_growth' %}" type="button"> <button class="button exportLink" data-export-url="{% url 'export_domains_growth' %}" type="button">
@ -166,6 +164,5 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View file

@ -22,6 +22,7 @@ def write_header(writer, columns):
""" """
writer.writerow(columns) writer.writerow(columns)
def get_domain_infos(filter_condition, sort_fields): def get_domain_infos(filter_condition, sort_fields):
domain_infos = ( domain_infos = (
DomainInformation.objects.select_related("domain", "authorizing_official") DomainInformation.objects.select_related("domain", "authorizing_official")
@ -42,6 +43,7 @@ def get_domain_infos(filter_condition, sort_fields):
) )
return domain_infos_cleaned return domain_infos_cleaned
def parse_row(columns, domain_info: DomainInformation, security_emails_dict=None, get_domain_managers=False): def parse_row(columns, domain_info: DomainInformation, security_emails_dict=None, get_domain_managers=False):
"""Given a set of columns, generate a new row from cleaned column data""" """Given a set of columns, generate a new row from cleaned column data"""
@ -102,6 +104,7 @@ def parse_row(columns, domain_info: DomainInformation, security_emails_dict=None
row = [FIELDS.get(column, "") for column in columns] row = [FIELDS.get(column, "") for column in columns]
return row return row
def _get_security_emails(sec_contact_ids): def _get_security_emails(sec_contact_ids):
""" """
Retrieve security contact emails for the given security contact IDs. Retrieve security contact emails for the given security contact IDs.
@ -123,6 +126,7 @@ def _get_security_emails(sec_contact_ids):
return security_emails_dict return security_emails_dict
def update_columns_with_domain_managers(columns, max_dm_count): def update_columns_with_domain_managers(columns, max_dm_count):
""" """
Update the columns list to include "Domain manager email {#}" headers Update the columns list to include "Domain manager email {#}" headers
@ -131,6 +135,7 @@ def update_columns_with_domain_managers(columns, max_dm_count):
for i in range(1, max_dm_count + 1): for i in range(1, max_dm_count + 1):
columns.append(f"Domain manager email {i}") columns.append(f"Domain manager email {i}")
def write_csv( def write_csv(
writer, writer,
columns, columns,
@ -180,19 +185,17 @@ def write_csv(
writer.writerows(rows) writer.writerows(rows)
def get_requests(filter_condition, sort_fields): def get_requests(filter_condition, sort_fields):
requests = ( requests = DomainApplication.objects.all().filter(**filter_condition).order_by(*sort_fields)
DomainApplication.objects.all()
.filter(**filter_condition)
.order_by(*sort_fields)
)
return requests return requests
def parse_request_row(columns, request: DomainApplication): def parse_request_row(columns, request: DomainApplication):
"""Given a set of columns, generate a new row from cleaned column data""" """Given a set of columns, generate a new row from cleaned column data"""
requested_domain_name = 'No requested domain' requested_domain_name = "No requested domain"
# Domain should never be none when parsing this information # Domain should never be none when parsing this information
if request.requested_domain is not None: if request.requested_domain is not None:
@ -224,6 +227,7 @@ def parse_request_row(columns, request: DomainApplication):
row = [FIELDS.get(column, "") for column in columns] row = [FIELDS.get(column, "") for column in columns]
return row return row
def write_requests_csv( def write_requests_csv(
writer, writer,
columns, columns,
@ -231,8 +235,7 @@ def write_requests_csv(
filter_condition, filter_condition,
should_write_header=True, should_write_header=True,
): ):
""" """ """
"""
all_requetsts = get_requests(filter_condition, sort_fields) all_requetsts = get_requests(filter_condition, sort_fields)
@ -257,6 +260,7 @@ def write_requests_csv(
writer.writerows(rows) writer.writerows(rows)
def export_data_type_to_csv(csv_file): def export_data_type_to_csv(csv_file):
"""All domains report with extra columns""" """All domains report with extra columns"""
@ -293,6 +297,7 @@ def export_data_type_to_csv(csv_file):
} }
write_csv(writer, columns, sort_fields, filter_condition, get_domain_managers=True, should_write_header=True) write_csv(writer, columns, sort_fields, filter_condition, get_domain_managers=True, should_write_header=True)
def export_data_full_to_csv(csv_file): def export_data_full_to_csv(csv_file):
"""All domains report""" """All domains report"""
@ -323,6 +328,7 @@ def export_data_full_to_csv(csv_file):
} }
write_csv(writer, columns, sort_fields, filter_condition, get_domain_managers=False, should_write_header=True) write_csv(writer, columns, sort_fields, filter_condition, get_domain_managers=False, should_write_header=True)
def export_data_federal_to_csv(csv_file): def export_data_federal_to_csv(csv_file):
"""Federal domains report""" """Federal domains report"""
@ -354,20 +360,25 @@ def export_data_federal_to_csv(csv_file):
} }
write_csv(writer, columns, sort_fields, filter_condition, get_domain_managers=False, should_write_header=True) write_csv(writer, columns, sort_fields, filter_condition, get_domain_managers=False, should_write_header=True)
def get_default_start_date(): def get_default_start_date():
# Default to a date that's prior to our first deployment # Default to a date that's prior to our first deployment
return timezone.make_aware(datetime(2023, 11, 1)) return timezone.make_aware(datetime(2023, 11, 1))
def get_default_end_date(): def get_default_end_date():
# Default to now() # Default to now()
return timezone.now() return timezone.now()
def format_start_date(start_date): def format_start_date(start_date):
return timezone.make_aware(datetime.strptime(start_date, "%Y-%m-%d")) if start_date else get_default_start_date() return timezone.make_aware(datetime.strptime(start_date, "%Y-%m-%d")) if start_date else get_default_start_date()
def format_end_date(end_date): def format_end_date(end_date):
return timezone.make_aware(datetime.strptime(end_date, "%Y-%m-%d")) if end_date else get_default_end_date() return timezone.make_aware(datetime.strptime(end_date, "%Y-%m-%d")) if end_date else get_default_end_date()
def export_data_domain_growth_to_csv(csv_file, start_date, end_date): def export_data_domain_growth_to_csv(csv_file, start_date, end_date):
""" """
Growth report: Growth report:
@ -425,15 +436,17 @@ def export_data_domain_growth_to_csv(csv_file, start_date, end_date):
should_write_header=False, should_write_header=False,
) )
def get_sliced_domains(filter_condition): def get_sliced_domains(filter_condition):
"""Get fitered domains counts sliced by org type and election office. """Get fitered domains counts sliced by org type and election office."""
"""
domains = DomainInformation.objects.all().filter(**filter_condition) domains = DomainInformation.objects.all().filter(**filter_condition)
domains_count = domains.count() domains_count = domains.count()
federal = domains.filter(organization_type=DomainApplication.OrganizationChoices.FEDERAL).count() federal = domains.filter(organization_type=DomainApplication.OrganizationChoices.FEDERAL).count()
interstate = domains.filter(organization_type=DomainApplication.OrganizationChoices.INTERSTATE).count() interstate = domains.filter(organization_type=DomainApplication.OrganizationChoices.INTERSTATE).count()
state_or_territory = domains.filter(organization_type=DomainApplication.OrganizationChoices.STATE_OR_TERRITORY).count() state_or_territory = domains.filter(
organization_type=DomainApplication.OrganizationChoices.STATE_OR_TERRITORY
).count()
tribal = domains.filter(organization_type=DomainApplication.OrganizationChoices.TRIBAL).count() tribal = domains.filter(organization_type=DomainApplication.OrganizationChoices.TRIBAL).count()
county = domains.filter(organization_type=DomainApplication.OrganizationChoices.COUNTY).count() county = domains.filter(organization_type=DomainApplication.OrganizationChoices.COUNTY).count()
city = domains.filter(organization_type=DomainApplication.OrganizationChoices.CITY).count() city = domains.filter(organization_type=DomainApplication.OrganizationChoices.CITY).count()
@ -441,7 +454,8 @@ def get_sliced_domains(filter_condition):
school_district = domains.filter(organization_type=DomainApplication.OrganizationChoices.SCHOOL_DISTRICT).count() school_district = domains.filter(organization_type=DomainApplication.OrganizationChoices.SCHOOL_DISTRICT).count()
election_board = domains.filter(is_election_board=True).count() election_board = domains.filter(is_election_board=True).count()
return [domains_count, return [
domains_count,
federal, federal,
interstate, interstate,
state_or_territory, state_or_territory,
@ -450,17 +464,20 @@ def get_sliced_domains(filter_condition):
city, city,
special_district, special_district,
school_district, school_district,
election_board] election_board,
]
def get_sliced_requests(filter_condition): def get_sliced_requests(filter_condition):
"""Get fitered requests counts sliced by org type and election office. """Get fitered requests counts sliced by org type and election office."""
"""
requests = DomainApplication.objects.all().filter(**filter_condition) requests = DomainApplication.objects.all().filter(**filter_condition)
requests_count = requests.count() requests_count = requests.count()
federal = requests.filter(organization_type=DomainApplication.OrganizationChoices.FEDERAL).count() federal = requests.filter(organization_type=DomainApplication.OrganizationChoices.FEDERAL).count()
interstate = requests.filter(organization_type=DomainApplication.OrganizationChoices.INTERSTATE).count() interstate = requests.filter(organization_type=DomainApplication.OrganizationChoices.INTERSTATE).count()
state_or_territory = requests.filter(organization_type=DomainApplication.OrganizationChoices.STATE_OR_TERRITORY).count() state_or_territory = requests.filter(
organization_type=DomainApplication.OrganizationChoices.STATE_OR_TERRITORY
).count()
tribal = requests.filter(organization_type=DomainApplication.OrganizationChoices.TRIBAL).count() tribal = requests.filter(organization_type=DomainApplication.OrganizationChoices.TRIBAL).count()
county = requests.filter(organization_type=DomainApplication.OrganizationChoices.COUNTY).count() county = requests.filter(organization_type=DomainApplication.OrganizationChoices.COUNTY).count()
city = requests.filter(organization_type=DomainApplication.OrganizationChoices.CITY).count() city = requests.filter(organization_type=DomainApplication.OrganizationChoices.CITY).count()
@ -468,7 +485,8 @@ def get_sliced_requests(filter_condition):
school_district = requests.filter(organization_type=DomainApplication.OrganizationChoices.SCHOOL_DISTRICT).count() school_district = requests.filter(organization_type=DomainApplication.OrganizationChoices.SCHOOL_DISTRICT).count()
election_board = requests.filter(is_election_board=True).count() election_board = requests.filter(is_election_board=True).count()
return [requests_count, return [
requests_count,
federal, federal,
interstate, interstate,
state_or_territory, state_or_territory,
@ -477,11 +495,12 @@ def get_sliced_requests(filter_condition):
city, city,
special_district, special_district,
school_district, school_district,
election_board] election_board,
]
def export_data_managed_domains_to_csv(csv_file, start_date, end_date): def export_data_managed_domains_to_csv(csv_file, start_date, end_date):
"""Get domains have domain managers for two different dates. """Get domains have domain managers for two different dates."""
"""
start_date_formatted = format_start_date(start_date) start_date_formatted = format_start_date(start_date)
end_date_formatted = format_end_date(end_date) end_date_formatted = format_end_date(end_date)
@ -501,11 +520,31 @@ def export_data_managed_domains_to_csv(csv_file, start_date, end_date):
managed_domains_sliced_at_start_date = get_sliced_domains(filter_managed_domains_start_date) managed_domains_sliced_at_start_date = get_sliced_domains(filter_managed_domains_start_date)
writer.writerow(["MANAGED DOMAINS COUNTS AT SRAT DATE"]) writer.writerow(["MANAGED DOMAINS COUNTS AT SRAT DATE"])
writer.writerow(["Total", "Federal", "Interstate", "State or territory", "Tribal", "County", "City", "Special district", "School district", "Election office"]) writer.writerow(
[
"Total",
"Federal",
"Interstate",
"State or territory",
"Tribal",
"County",
"City",
"Special district",
"School district",
"Election office",
]
)
writer.writerow(managed_domains_sliced_at_start_date) writer.writerow(managed_domains_sliced_at_start_date)
writer.writerow([]) writer.writerow([])
write_csv(writer, columns, sort_fields, filter_managed_domains_start_date, get_domain_managers=True, should_write_header=True) write_csv(
writer,
columns,
sort_fields,
filter_managed_domains_start_date,
get_domain_managers=True,
should_write_header=True,
)
writer.writerow([]) writer.writerow([])
filter_managed_domains_end_date = { filter_managed_domains_end_date = {
@ -515,15 +554,35 @@ def export_data_managed_domains_to_csv(csv_file, start_date, end_date):
managed_domains_sliced_at_end_date = get_sliced_domains(filter_managed_domains_end_date) managed_domains_sliced_at_end_date = get_sliced_domains(filter_managed_domains_end_date)
writer.writerow(["MANAGED DOMAINS COUNTS AT END DATE"]) writer.writerow(["MANAGED DOMAINS COUNTS AT END DATE"])
writer.writerow(["Total", "Federal", "Interstate", "State or territory", "Tribal", "County", "City", "Special district", "School district", "Election office"]) writer.writerow(
[
"Total",
"Federal",
"Interstate",
"State or territory",
"Tribal",
"County",
"City",
"Special district",
"School district",
"Election office",
]
)
writer.writerow(managed_domains_sliced_at_end_date) writer.writerow(managed_domains_sliced_at_end_date)
writer.writerow([]) writer.writerow([])
write_csv(writer, columns, sort_fields, filter_managed_domains_end_date, get_domain_managers=True, should_write_header=True) write_csv(
writer,
columns,
sort_fields,
filter_managed_domains_end_date,
get_domain_managers=True,
should_write_header=True,
)
def export_data_unmanaged_domains_to_csv(csv_file, start_date, end_date): def export_data_unmanaged_domains_to_csv(csv_file, start_date, end_date):
""" Get domains that do not have domain managers for two different dates. """Get domains that do not have domain managers for two different dates."""
"""
start_date_formatted = format_start_date(start_date) start_date_formatted = format_start_date(start_date)
end_date_formatted = format_end_date(end_date) end_date_formatted = format_end_date(end_date)
@ -543,11 +602,31 @@ def export_data_unmanaged_domains_to_csv(csv_file, start_date, end_date):
unmanaged_domains_sliced_at_start_date = get_sliced_domains(filter_unmanaged_domains_start_date) unmanaged_domains_sliced_at_start_date = get_sliced_domains(filter_unmanaged_domains_start_date)
writer.writerow(["UNMANAGED DOMAINS AT START DATE"]) writer.writerow(["UNMANAGED DOMAINS AT START DATE"])
writer.writerow(["Total", "Federal", "Interstate", "State or territory", "Tribal", "County", "City", "Special district", "School district", "Election office"]) writer.writerow(
[
"Total",
"Federal",
"Interstate",
"State or territory",
"Tribal",
"County",
"City",
"Special district",
"School district",
"Election office",
]
)
writer.writerow(unmanaged_domains_sliced_at_start_date) writer.writerow(unmanaged_domains_sliced_at_start_date)
writer.writerow([]) writer.writerow([])
write_csv(writer, columns, sort_fields, filter_unmanaged_domains_start_date, get_domain_managers=True, should_write_header=True) write_csv(
writer,
columns,
sort_fields,
filter_unmanaged_domains_start_date,
get_domain_managers=True,
should_write_header=True,
)
writer.writerow([]) writer.writerow([])
filter_unmanaged_domains_end_date = { filter_unmanaged_domains_end_date = {
@ -557,15 +636,35 @@ def export_data_unmanaged_domains_to_csv(csv_file, start_date, end_date):
unmanaged_domains_sliced_at_end_date = get_sliced_domains(filter_unmanaged_domains_end_date) unmanaged_domains_sliced_at_end_date = get_sliced_domains(filter_unmanaged_domains_end_date)
writer.writerow(["UNMANAGED DOMAINS AT END DATE"]) writer.writerow(["UNMANAGED DOMAINS AT END DATE"])
writer.writerow(["Total", "Federal", "Interstate", "State or territory", "Tribal", "County", "City", "Special district", "School district", "Election office"]) writer.writerow(
[
"Total",
"Federal",
"Interstate",
"State or territory",
"Tribal",
"County",
"City",
"Special district",
"School district",
"Election office",
]
)
writer.writerow(unmanaged_domains_sliced_at_end_date) writer.writerow(unmanaged_domains_sliced_at_end_date)
writer.writerow([]) writer.writerow([])
write_csv(writer, columns, sort_fields, filter_unmanaged_domains_end_date, get_domain_managers=True, should_write_header=True) write_csv(
writer,
columns,
sort_fields,
filter_unmanaged_domains_end_date,
get_domain_managers=True,
should_write_header=True,
)
def export_data_requests_growth_to_csv(csv_file, start_date, end_date): def export_data_requests_growth_to_csv(csv_file, start_date, end_date):
""" """ """
"""
start_date_formatted = format_start_date(start_date) start_date_formatted = format_start_date(start_date)
end_date_formatted = format_end_date(end_date) end_date_formatted = format_end_date(end_date)

View file

@ -9,6 +9,7 @@ import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class ExportDataType(View): class ExportDataType(View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
# match the CSV example with all the fields # match the CSV example with all the fields
@ -17,6 +18,7 @@ class ExportDataType(View):
csv_export.export_data_type_to_csv(response) csv_export.export_data_type_to_csv(response)
return response return response
class ExportDataFull(View): class ExportDataFull(View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
# Smaller export based on 1 # Smaller export based on 1
@ -25,6 +27,7 @@ class ExportDataFull(View):
csv_export.export_data_full_to_csv(response) csv_export.export_data_full_to_csv(response)
return response return response
class ExportDataFederal(View): class ExportDataFederal(View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
# Federal only # Federal only
@ -33,6 +36,7 @@ class ExportDataFederal(View):
csv_export.export_data_federal_to_csv(response) csv_export.export_data_federal_to_csv(response)
return response return response
class ExportDataDomainsGrowth(View): class ExportDataDomainsGrowth(View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
# Get start_date and end_date from the request's GET parameters # Get start_date and end_date from the request's GET parameters
@ -48,6 +52,7 @@ class ExportDataDomainsGrowth(View):
return response return response
class ExportDataRequestsGrowth(View): class ExportDataRequestsGrowth(View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
# Get start_date and end_date from the request's GET parameters # Get start_date and end_date from the request's GET parameters
@ -63,6 +68,7 @@ class ExportDataRequestsGrowth(View):
return response return response
class ExportDataManagedDomains(View): class ExportDataManagedDomains(View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
# Get start_date and end_date from the request's GET parameters # Get start_date and end_date from the request's GET parameters
@ -70,11 +76,14 @@ class ExportDataManagedDomains(View):
start_date = request.GET.get("start_date", "") start_date = request.GET.get("start_date", "")
end_date = request.GET.get("end_date", "") end_date = request.GET.get("end_date", "")
response = HttpResponse(content_type="text/csv") response = HttpResponse(content_type="text/csv")
response["Content-Disposition"] = f'attachment; filename="managed-vs-unamanaged-domains-{start_date}-to-{end_date}.csv"' response["Content-Disposition"] = (
f'attachment; filename="managed-vs-unamanaged-domains-{start_date}-to-{end_date}.csv"'
)
csv_export.export_data_managed_domains_to_csv(response, start_date, end_date) csv_export.export_data_managed_domains_to_csv(response, start_date, end_date)
return response return response
class ExportDataUnmanagedDomains(View): class ExportDataUnmanagedDomains(View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
# Get start_date and end_date from the request's GET parameters # Get start_date and end_date from the request's GET parameters
@ -82,7 +91,9 @@ class ExportDataUnmanagedDomains(View):
start_date = request.GET.get("start_date", "") start_date = request.GET.get("start_date", "")
end_date = request.GET.get("end_date", "") end_date = request.GET.get("end_date", "")
response = HttpResponse(content_type="text/csv") response = HttpResponse(content_type="text/csv")
response["Content-Disposition"] = f'attachment; filename="managed-vs-unamanaged-domains-{start_date}-to-{end_date}.csv"' response["Content-Disposition"] = (
f'attachment; filename="managed-vs-unamanaged-domains-{start_date}-to-{end_date}.csv"'
)
csv_export.export_data_unmanaged_domains_to_csv(response, start_date, end_date) csv_export.export_data_unmanaged_domains_to_csv(response, start_date, end_date)
return response return response