Files
dbstorage/dbapp/mainapp/views/data_import.py

246 lines
9.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Data import views (Excel, CSV, Transponders, VCH, etc.).
"""
from io import BytesIO
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpResponse
from django.shortcuts import redirect
from django.urls import reverse_lazy
from django.views import View
from django.views.generic import FormView
import pandas as pd
from ..forms import (
LoadCsvData,
LoadExcelData,
NewEventForm,
UploadFileForm,
UploadVchLoad,
VchLinkForm,
)
from ..mixins import FormMessageMixin
from ..utils import (
add_satellite_list,
compare_and_link_vch_load,
fill_data_from_df,
get_points_from_csv,
get_vch_load_from_html,
kub_report,
)
from mapsapp.utils import parse_transponders_from_xml
class AddSatellitesView(LoginRequiredMixin, View):
"""View for adding satellites to the database."""
def get(self, request):
add_satellite_list()
return redirect("mainapp:source_list")
class AddTranspondersView(LoginRequiredMixin, FormMessageMixin, FormView):
"""View for uploading and parsing transponder data from XML."""
template_name = "mainapp/transponders_upload.html"
form_class = UploadFileForm
success_message = "Файл успешно обработан"
error_message = "Форма заполнена некорректно"
def form_valid(self, form):
uploaded_file = self.request.FILES["file"]
try:
content = uploaded_file.read()
# Передаем текущего пользователя в функцию парсинга
parse_transponders_from_xml(BytesIO(content), self.request.user.customuser)
except ValueError as e:
messages.error(self.request, f"Ошибка при чтении таблиц: {e}")
return redirect("mainapp:add_trans")
except Exception as e:
messages.error(self.request, f"Неизвестная ошибка: {e}")
return redirect("mainapp:add_trans")
return super().form_valid(form)
def get_success_url(self):
return reverse_lazy("mainapp:add_trans")
class LoadExcelDataView(LoginRequiredMixin, FormMessageMixin, FormView):
"""View for loading data from Excel files."""
template_name = "mainapp/add_data_from_excel.html"
form_class = LoadExcelData
error_message = "Форма заполнена некорректно"
def form_valid(self, form):
uploaded_file = self.request.FILES["file"]
selected_sat = form.cleaned_data["sat_choice"]
number = form.cleaned_data["number_input"]
is_automatic = form.cleaned_data.get("is_automatic", False)
try:
import io
df = pd.read_excel(io.BytesIO(uploaded_file.read()))
if number > 0:
df = df.head(number)
result = fill_data_from_df(df, selected_sat, self.request.user.customuser, is_automatic)
# Формируем сообщение об успехе
if is_automatic:
success_msg = f"Данные успешно загружены как автоматические! Добавлено точек: {result['added']}"
else:
success_msg = f"Данные успешно загружены! Создано источников: {result['new_sources']}, добавлено точек: {result['added']}"
if result['skipped'] > 0:
success_msg += f", пропущено дубликатов: {result['skipped']}"
messages.success(self.request, success_msg)
# Показываем ошибки, если они есть
if result['errors']:
error_count = len(result['errors'])
messages.warning(
self.request,
f"Обнаружено ошибок: {error_count}. Первые ошибки: " + "; ".join(result['errors'][:5])
)
except Exception as e:
messages.error(self.request, f"Ошибка при обработке файла: {str(e)}")
return redirect("mainapp:load_excel_data")
def get_success_url(self):
return reverse_lazy("mainapp:load_excel_data")
class LoadCsvDataView(LoginRequiredMixin, FormMessageMixin, FormView):
"""View for loading data from CSV files."""
template_name = "mainapp/add_data_from_csv.html"
form_class = LoadCsvData
success_message = "Данные успешно загружены!"
error_message = "Форма заполнена некорректно"
def form_valid(self, form):
uploaded_file = self.request.FILES["file"]
is_automatic = form.cleaned_data.get("is_automatic", False)
try:
content = uploaded_file.read()
if isinstance(content, bytes):
content = content.decode("utf-8")
result = get_points_from_csv(content, self.request.user.customuser, is_automatic)
# Формируем сообщение об успехе
if is_automatic:
success_msg = f"Данные успешно загружены как автоматические! Добавлено точек: {result['added']}"
else:
success_msg = f"Данные успешно загружены! Создано источников: {result['new_sources']}, добавлено точек: {result['added']}"
if result['skipped'] > 0:
success_msg += f", пропущено дубликатов: {result['skipped']}"
messages.success(self.request, success_msg)
# Показываем ошибки, если они есть
if result['errors']:
error_count = len(result['errors'])
messages.warning(
self.request,
f"Обнаружено ошибок: {error_count}. Первые ошибки: " + "; ".join(result['errors'][:5])
)
except Exception as e:
messages.error(self.request, f"Ошибка при обработке файла: {str(e)}")
return redirect("mainapp:load_csv_data")
return super().form_valid(form)
def get_success_url(self):
return reverse_lazy("mainapp:load_csv_data")
class UploadVchLoadView(LoginRequiredMixin, FormMessageMixin, FormView):
"""View for uploading VCH load data from HTML files."""
template_name = "mainapp/upload_html.html"
form_class = UploadVchLoad
success_message = "Файл успешно обработан"
error_message = "Форма заполнена некорректно"
def form_valid(self, form):
selected_sat = form.cleaned_data["sat_choice"]
uploaded_file = self.request.FILES["file"]
try:
get_vch_load_from_html(uploaded_file, selected_sat)
except ValueError as e:
messages.error(self.request, f"Ошибка при чтении таблиц: {e}")
return redirect("mainapp:vch_load")
except Exception as e:
messages.error(self.request, f"Неизвестная ошибка: {e}")
return redirect("mainapp:vch_load")
return super().form_valid(form)
def get_success_url(self):
return reverse_lazy("mainapp:vch_load")
class LinkVchSigmaView(LoginRequiredMixin, FormView):
"""View for linking VCH data with Sigma parameters."""
template_name = "mainapp/link_vch.html"
form_class = VchLinkForm
def form_valid(self, form):
# value1 is no longer used - frequency tolerance is determined automatically
freq_range = form.cleaned_data["value2"]
sat_id = form.cleaned_data["sat_choice"]
# Pass 0 for eps_freq and ku_range as they are not used
count_all, link_count = compare_and_link_vch_load(sat_id, 0, freq_range, 0)
messages.success(
self.request, f"Привязано {link_count} из {count_all} объектов"
)
return redirect("mainapp:link_vch_sigma")
def form_invalid(self, form):
return self.render_to_response(self.get_context_data(form=form))
class ProcessKubsatView(LoginRequiredMixin, FormMessageMixin, FormView):
"""View for processing Kubsat event data."""
template_name = "mainapp/process_kubsat.html"
form_class = NewEventForm
error_message = "Форма заполнена некорректно"
def form_valid(self, form):
uploaded_file = self.request.FILES["file"]
try:
content = uploaded_file.read()
df = kub_report(BytesIO(content))
output = BytesIO()
with pd.ExcelWriter(output, engine="openpyxl") as writer:
df.to_excel(writer, index=False, sheet_name="Результат")
output.seek(0)
response = HttpResponse(
output.getvalue(),
content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
)
response["Content-Disposition"] = (
'attachment; filename="kubsat_report.xlsx"'
)
messages.success(self.request, "Событие успешно обработано!")
return response
except Exception as e:
messages.error(self.request, f"Ошибка при обработке файла: {str(e)}")
return redirect("mainapp:kubsat_excel")