from django.shortcuts import render, redirect from django.contrib import messages from django.http import JsonResponse 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 ) from mapsapp.utils import parse_transponders_from_json from .forms import LoadExcelData, LoadCsvData, UploadFileForm, VchLinkForm from .models import ObjItem from .clusters import get_clusters from dbapp.settings import BASE_DIR 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 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(id_vch_load__id_satellite=sat_id) if not locations: return JsonResponse({'error': 'Объектов не найдено'}, status=400) features = [] for loc in locations: features.append({ "type": "Feature", "geometry": { "type": "Point", "coordinates": [loc.id_geo.coords[0], loc.id_geo.coords[1]] }, "properties": { "pol": loc.id_vch_load.polarization.name, "freq": loc.id_vch_load.frequency*1000000, "name": f"{loc.name}", "id": loc.id_geo.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) # def upload_file(request): # if request.method == 'POST' and request.FILES: # form = UploadFileForm(request.POST, request.FILES) # if form.is_valid(): # uploaded_file = request.FILES['file'] # # Обработка текстового файла, например: # df = pd.read_csv(uploaded_file) # df = pd.read_csv(filepath, sep=";", # names=['id', 'obj', 'lat', 'lon', 'h', 'time', 'sat', 'norad_id', 'freq', 'f_range', 'et', 'qaul', 'mir_1', 'mir_2', 'mir_3']) # df[['lat', 'lon', 'freq', 'f_range']] = df[['lat', 'lon', 'freq', 'f_range']].replace(',', '.', regex=True).astype(float) # df['time'] = pd.to_datetime(df['time'], format='%d.%m.%Y %H:%M:%S') # get_points_from_csv(df) # return JsonResponse({'status': 'success'}) # else: # return JsonResponse({'status': 'error', 'errors': form.errors}, status=400) # return render(request, 'mainapp/add_data_from_csv.html') 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) for obj in locations: points.append({ 'name': f"{obj.name}", 'freq': f"{obj.id_vch_load.frequency} [{obj.id_vch_load.freq_range}] МГц", 'point': (obj.id_geo.coords.x, obj.id_geo.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 = UploadFileForm 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, ku_range) 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))