from django.shortcuts import render, redirect from django.contrib import messages from django.http import JsonResponse, HttpResponse from django.views.decorators.http import require_GET from django.contrib.admin.views.decorators import staff_member_required from django.utils.decorators import method_decorator from django.views import View from django.views.generic import TemplateView, FormView from django.contrib.auth.mixins import UserPassesTestMixin import pandas as pd from .utils import ( fill_data_from_df, add_satellite_list, get_points_from_csv, get_vch_load_from_html, compare_and_link_vch_load, kub_report ) from mapsapp.utils import parse_transponders_from_json, parse_transponders_from_xml from .forms import LoadExcelData, LoadCsvData, UploadFileForm, VchLinkForm, UploadVchLoad, NewEventForm from .models import ObjItem from .clusters import get_clusters from io import BytesIO class AddSatellitesView(View): def get(self, request): add_satellite_list() return redirect('home') # class AddTranspondersView(View): # def get(self, request): # try: # parse_transponders_from_json(BASE_DIR / "transponders.json") # except FileNotFoundError: # print("Файл не найден") # return redirect('home') class AddTranspondersView(FormView): template_name = 'mainapp/transponders_upload.html' form_class = UploadFileForm def form_valid(self, form): uploaded_file = self.request.FILES['file'] try: content = uploaded_file.read() parse_transponders_from_xml(BytesIO(content)) messages.success(self.request, "Файл успешно обработан") except ValueError as e: messages.error(self.request, f"Ошибка при чтении таблиц: {e}") except Exception as e: messages.error(self.request, f"Неизвестная ошибка: {e}") return redirect('add_trans') def form_invalid(self, form): messages.error(self.request, "Форма заполнена некорректно.") return super().form_invalid(form) class HomePageView(TemplateView): template_name = 'mainapp/home.html' class LoadExcelDataView(FormView): template_name = 'mainapp/add_data_from_excel.html' form_class = LoadExcelData def form_valid(self, form): uploaded_file = self.request.FILES['file'] selected_sat = form.cleaned_data['sat_choice'] number = form.cleaned_data['number_input'] 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) messages.success(self.request, f"Данные успешно загружены! Обработано строк: {result}") return redirect('load_excel_data') except Exception as e: messages.error(self.request, f"Ошибка при обработке файла: {str(e)}") return redirect('load_excel_data') def form_invalid(self, form): messages.error(self.request, "Форма заполнена некорректно.") return super().form_invalid(form) from django.views.generic import View class GetLocationsView(View): def get(self, request, sat_id): locations = ObjItem.objects.filter(parameters_obj__id_satellite=sat_id) if not locations: return JsonResponse({'error': 'Объектов не найдено'}, status=400) features = [] for loc in locations: param = loc.parameters_obj.get() features.append({ "type": "Feature", "geometry": { "type": "Point", "coordinates": [loc.geo_obj.coords[0], loc.geo_obj.coords[1]] }, "properties": { "pol": param.polarization.name, "freq": param.frequency*1000000, "name": f"{loc.name}", "id": loc.geo_obj.id } }) return JsonResponse({ "type": "FeatureCollection", "features": features }) class LoadCsvDataView(FormView): template_name = 'mainapp/add_data_from_csv.html' form_class = LoadCsvData def form_valid(self, form): uploaded_file = self.request.FILES['file'] try: # Read the file content and pass it directly to the function content = uploaded_file.read() if isinstance(content, bytes): content = content.decode('utf-8') get_points_from_csv(content) messages.success(self.request, f"Данные успешно загружены!") return redirect('load_csv_data') except Exception as e: messages.error(self.request, f"Ошибка при обработке файла: {str(e)}") return redirect('load_csv_data') def form_invalid(self, form): messages.error(self.request, "Форма заполнена некорректно.") return super().form_invalid(form) from collections import defaultdict @method_decorator(staff_member_required, name='dispatch') class ShowMapView(UserPassesTestMixin, View): def test_func(self): return self.request.user.is_staff def get(self, request): ids = request.GET.get('ids', '') points = [] if ids: id_list = [int(x) for x in ids.split(',') if x.isdigit()] locations = ObjItem.objects.filter(id__in=id_list).prefetch_related( 'parameters_obj__id_satellite', 'parameters_obj__polarization', 'parameters_obj__modulation', 'parameters_obj__standard', 'geo_obj' ) for obj in locations: param = obj.parameters_obj.get() points.append({ 'name': f"{obj.name}", 'freq': f"{param.frequency} [{param.freq_range}] МГц", 'point': (obj.geo_obj.coords.x, obj.geo_obj.coords.y) }) else: return redirect('admin') grouped = defaultdict(list) for p in points: grouped[p["name"]].append({ 'point': p["point"], 'frequency': p["freq"] }) groups = [ { "name": name, "points": coords_list } for name, coords_list in grouped.items() ] context = { 'groups': groups, } return render(request, 'admin/map_custom.html', context) class ClusterTestView(View): def get(self, request): objs = ObjItem.objects.filter(name__icontains="! Astra 4A 12654,040 [1,962] МГц H") coords = [] for obj in objs: coords.append((obj.id_geo.coords[1], obj.id_geo.coords[0])) get_clusters(coords) return JsonResponse({"success": "ок"}) class UploadVchLoadView(FormView): template_name = 'mainapp/upload_html.html' form_class = UploadVchLoad 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) messages.success(self.request, "Файл успешно обработан") except ValueError as e: messages.error(self.request, f"Ошибка при чтении таблиц: {e}") except Exception as e: messages.error(self.request, f"Неизвестная ошибка: {e}") return redirect('vch_load') def form_invalid(self, form): messages.error(self.request, "Форма заполнена некорректно.") return super().form_invalid(form) class LinkVchSigmaView(FormView): template_name = 'mainapp/link_vch.html' form_class = VchLinkForm def form_valid(self, form): freq = form.cleaned_data['value1'] freq_range = form.cleaned_data['value2'] # ku_range = float(form.cleaned_data['ku_range']) sat_id = form.cleaned_data['sat_choice'] # print(freq, freq_range, ku_range, sat_id.pk) count_all, link_count = compare_and_link_vch_load(sat_id, freq, freq_range, 1) messages.success(self.request, f"Привязано {link_count} из {count_all} объектов") return redirect('link_vch_sigma') def form_invalid(self, form): return self.render_to_response(self.get_context_data(form=form)) class ProcessKubsatView(FormView): template_name = 'mainapp/process_kubsat.html' form_class = NewEventForm def form_valid(self, form): # selected_sat = form.cleaned_data['sat_choice'] # selected_pol = form.cleaned_data['pol_choice'] 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'] = f'attachment; filename="kubsat_report.xlsx"' messages.success(self.request, "Событие успешно обработано!") return response except Exception as e: messages.error(self.request, f"Ошибка при обработке файла: {str(e)}") return redirect('kubsat_excel') # return redirect('kubsat_excel') def form_invalid(self, form): messages.error(self.request, "Форма заполнена некорректно.") return super().form_invalid(form)