Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bump sentry-sdk from 1.40.0 to 2.8.0 in /deployment/production #4080

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion bims/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -1901,7 +1901,11 @@ class TaxonomyUpdateProposalAdmin(admin.ModelAdmin):
'original_taxonomy',
'scientific_name',
'canonical_name',
'status'
'status',
'created_at'
)
autocomplete_fields = (
'vernacular_names',
)


Expand Down
95 changes: 92 additions & 3 deletions bims/api_views/checklist.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,24 @@
import os
from django.conf import settings
from django.http import Http404
from django.template.loader import render_to_string
from preferences import preferences
from reportlab.lib import colors
from reportlab.lib.pagesizes import A4, landscape
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.units import cm
from reportlab.platypus import SimpleDocTemplate, TableStyle, Table, Spacer
from reportlab.platypus.para import Paragraph
from rest_framework.response import Response
from rest_framework.views import APIView

from bims.api_views.search import CollectionSearch
from bims.models.taxonomy import Taxonomy
from bims.models.download_request import DownloadRequest
from bims.serializers.checklist_serializer import ChecklistSerializer
from bims.serializers.checklist_serializer import (
ChecklistSerializer,
ChecklistPDFSerializer
)
from bims.utils.url import parse_url_to_filters
from bims.tasks.checklist import download_checklist
from bims.tasks.email_csv import send_csv_via_email
Expand Down Expand Up @@ -61,10 +71,22 @@ def generate_checklist(download_request_id):
batch_size = 1000
collection_records = search.process_search().distinct('taxonomy')

if (
download_request.resource_type and
download_request.resource_type.lower() == 'pdf'
):
return generate_pdf_checklist(
download_request, collection_records, batch_size)
else:
return generate_csv_checklist(
download_request, collection_records, batch_size)


def generate_csv_checklist(download_request, collection_records, batch_size):
csv_file_path = os.path.join(
settings.MEDIA_ROOT,
'checklists',
f'checklist_{download_request_id}.csv')
f'checklist_{download_request.id}.csv')
os.makedirs(os.path.dirname(csv_file_path), exist_ok=True)

fieldnames = [key for key in get_serializer_keys(ChecklistSerializer) if key != 'id']
Expand All @@ -83,14 +105,81 @@ def generate_checklist(download_request_id):
batch = collection_records[start:start + batch_size]
process_batch(batch, writer, written_taxa_ids)

# Save file path to download_request
download_request.processing = False
download_request.request_file = csv_file_path
download_request.save()

return True


def generate_pdf_checklist(download_request, collection_records, batch_size):
pdf_file_path = os.path.join(
settings.MEDIA_ROOT,
'checklists',
f'checklist_{download_request.id}.pdf')
os.makedirs(os.path.dirname(pdf_file_path), exist_ok=True)

written_taxa_ids = set()
all_taxa = []

for start in range(0, collection_records.count(), batch_size):
batch = collection_records[start:start + batch_size]
record_taxonomy_ids = batch.values_list('taxonomy_id', flat=True)
unique_taxonomy_ids = set(record_taxonomy_ids) - written_taxa_ids

if unique_taxonomy_ids:
taxa = Taxonomy.objects.filter(id__in=unique_taxonomy_ids)
taxon_serializer = ChecklistPDFSerializer(taxa, many=True)
for taxon in taxon_serializer.data:
written_taxa_ids.add(taxon['id'])
del taxon['id']
all_taxa.append([
Paragraph(taxon['scientific_name'], getSampleStyleSheet()['Normal']),
Paragraph(taxon['common_name'], getSampleStyleSheet()['Normal']),
Paragraph(taxon['threat_status'], getSampleStyleSheet()['Normal']),
Paragraph(taxon['sources'], getSampleStyleSheet()['Normal'])
])

# Generate the PDF
doc = SimpleDocTemplate(
pdf_file_path,
pagesize=landscape(A4), topMargin=0.5 * cm, bottomMargin=0.35 * cm)
elements = []

# Define table style
style_table = TableStyle([
('BACKGROUND', (0, 0), (-1, 0), '#0D3511'),
('TEXTCOLOR', (0, 0), (-1, 0), colors.white),
('ALIGN', (0, 0), (-1, -1), 'LEFT'),
('VALIGN', (0, 0), (-1, -1), 'TOP'),
('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
('FONTSIZE', (0, 0), (-1, 0), 11),
('BOTTOMPADDING', (0, 0), (-1, 0), 5),
('BACKGROUND', (0, 1), (-1, -1), colors.white),
('GRID', (0, 0), (-1, -1), 1, colors.black),
('LEFTPADDING', (0, 0), (-1, -1), 2),
('RIGHTPADDING', (0, 0), (-1, -1), 2),
('TOPPADDING', (0, 0), (-1, -1), 2),
('BOTTOMPADDING', (0, 0), (-1, -1), 2),
])

data = [['Scientific Name', 'Common Name', 'Threat Status', 'Sources']] + all_taxa
table_width = doc.width
col_widths = [table_width * 0.35, table_width * 0.30, table_width * 0.15, table_width * 0.30]

table = Table(data, colWidths=col_widths)
table.setStyle(style_table)

elements.append(table)
doc.build(elements)

download_request.processing = False
download_request.request_file = pdf_file_path
download_request.save()

return True


def process_batch(batch, writer, written_taxa_ids):
"""
Process a batch of collection records and write unique taxa to the CSV file.
Expand Down
51 changes: 38 additions & 13 deletions bims/api_views/module_summary.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from django.contrib.sites.models import Site
import threading

from django.db.models.functions import Coalesce
from rest_framework.views import APIView
from rest_framework.response import Response
from allauth.utils import get_user_model
Expand All @@ -13,7 +15,7 @@
)
from bims.models.taxonomy import Taxonomy
from bims.enums.taxonomic_group_category import TaxonomicGroupCategory
from bims.cache import get_cache, LANDING_PAGE_MODULE_SUMMARY_CACHE, set_cache
from bims.cache import get_cache, LANDING_PAGE_MODULE_SUMMARY_CACHE, set_cache, delete_cache
from sass.models.site_visit_taxon import SiteVisitTaxon
from sass.models.site_visit import SiteVisit

Expand Down Expand Up @@ -90,17 +92,26 @@ def get_origin_summary(self, collections):
"""
Returns origin summary data from the provided collections
"""
origin_data = dict(
collections.exclude(taxonomy__origin__exact='').values(
'taxonomy__origin').annotate(
count=Count('taxonomy__origin')
).values_list('taxonomy__origin', 'count'))
origin_data = collections.annotate(
origin_value=Coalesce(
Case(
When(taxonomy__origin='', then=Value('Unknown')),
default=F('taxonomy__origin')
),
Value('Unknown')
)
).values('origin_value').annotate(
count=Count('origin_value')
).values_list('origin_value', 'count')

origin_data_dict = dict(origin_data)
updated_origin_data = {}
origin_category = dict(Taxonomy.CATEGORY_CHOICES)
for key in origin_data.keys():
updated_origin_data[origin_category[key]] = (
origin_data[key]
)

for key, count in origin_data_dict.items():
category_name = origin_category.get(key, 'Unknown')
updated_origin_data[category_name] = count

return updated_origin_data

def get_endemism_summary(self, collections):
Expand Down Expand Up @@ -148,16 +159,29 @@ def get_conservation_status_summary(self, collections):
collections.annotate(
value=Case(When(taxonomy__iucn_status__isnull=False,
then=F('taxonomy__iucn_status__category')),
default=Value('Not evaluated'))
default=Value('NE'))
).values('value').annotate(
count=Count('value')
).values_list('value', 'count')
)
iucn_category = dict(IUCNStatus.CATEGORY_CHOICES)
updated_summary = {}
iucn_status = IUCNStatus.objects.filter(
national=False
)
updated_summary = {
'chart_data': {},
'colors': []
}
for key in summary_temp.keys():
if key in iucn_category:
updated_summary[iucn_category[key]] = summary_temp[key]
updated_summary['chart_data'][iucn_category[key]] = summary_temp[key]
try:
updated_summary['colors'].append(
iucn_status.filter(category=key).first().colour
)
except AttributeError:
updated_summary['colors'].append('#000000')

return updated_summary

def general_summary_data(self):
Expand Down Expand Up @@ -221,6 +245,7 @@ def summary_data(self):
return module_summary

def call_summary_data_in_background(self):
delete_cache(self._cache_key())
background_thread = threading.Thread(
target=self.summary_data,
)
Expand Down
78 changes: 3 additions & 75 deletions bims/api_views/remove_occurrences.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,8 @@
from preferences import preferences
from bims.models import (
TaxonGroup,
Taxonomy,
BiologicalCollectionRecord,
Survey,
LocationSite,
LocationContext
)
from bims.tasks.taxon_group import delete_occurrences_by_taxon_group


class RemoveOccurrencesApiView(UserPassesTestMixin, APIView):
Expand All @@ -29,74 +25,6 @@ def get(self, request, *args):
except TaxonGroup.DoesNotExist:
return JsonResponse({'error': 'Taxon group does not exist'})

messages = {
'success': 'OK'
}
if taxon_group:
collections = (
BiologicalCollectionRecord.objects.filter(
module_group=taxon_group
)
)
total_collections = collections.count()
task = delete_occurrences_by_taxon_group.delay(taxon_module_id)

# -- Survey
survey_ids = list(
collections.values_list(
'survey_id', flat=True).distinct('survey')
)
surveys = Survey.objects.filter(id__in=survey_ids)
total_surveys = surveys.count()

# -- Taxonomy
taxa_ids = list(taxon_group.taxonomies.all().values_list(
'id', flat=True
))
taxa = Taxonomy.objects.filter(id__in=taxa_ids)
total_taxa = taxa.count()

# -- Sites
site_ids = list(
collections.values_list('site_id', flat=True).distinct('site'))
sites = LocationSite.objects.filter(
id__in=site_ids
)
total_sites = sites.count()

# -- Location Context
location_contexts = LocationContext.objects.filter(
site__in=sites
)

if collections.exists():
collections._raw_delete(collections.db)
messages['Collections deleted'] = total_collections

if surveys.exists():
surveys._raw_delete(surveys.db)
messages['Survey deleted'] = total_surveys

if taxa.exists():
taxon_group.taxonomies.clear()
taxa = taxa.filter(
biologicalcollectionrecord__isnull=True
)
taxa_with_vernacular = taxa.filter(
vernacular_names__isnull=False)
for taxon_with_vernacular in taxa_with_vernacular:
taxon_with_vernacular.vernacular_names.clear()
taxa._raw_delete(taxa.db)
messages['Taxa deleted'] = total_taxa

if sites.exists():
location_contexts._raw_delete(location_contexts.db)
sites = sites.filter(
survey__isnull=True,
biological_collection_record__isnull=True
)
sites._raw_delete(sites.db)
messages['Sites deleted'] = total_sites

taxon_group.delete()

return JsonResponse(messages)
return JsonResponse({'status': 'Task initiated', 'task_id': task.id})
7 changes: 6 additions & 1 deletion bims/api_views/taxon_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,12 @@ def add_taxa_to_taxon_group(taxa_ids, taxon_group_id):
legacy_canonical_name=taxonomy.legacy_canonical_name,
taxon_group_under_review=taxon_group
)
taxon_group.taxonomies.add(taxonomy)
taxon_group.taxonomies.add(
taxonomy,
through_defaults={
'is_validated': False
}
)


class TaxaUpdateMixin(UserPassesTestMixin, APIView):
Expand Down
Loading
Loading