From f8ff0b205e7cb9b6ff67aec9106e7f2c4e201838 Mon Sep 17 00:00:00 2001 From: RostislavB74 Date: Sun, 14 Apr 2024 08:28:32 +0300 Subject: [PATCH 01/19] test --- FRONTEND/fastparking/accounts/forms.py | 17 ++++++ .../accounts/templates/accounts/profile.html | 39 +++++++----- FRONTEND/fastparking/accounts/urls.py | 21 +++++-- FRONTEND/fastparking/accounts/views.py | 39 +++++++++--- FRONTEND/fastparking/cars/forms.py | 4 +- .../cars/migrations/0001_initial.py | 14 ++--- ...ar_blocked_remove_car_pay_pass_and_more.py | 46 -------------- ...o_car_photo_car_car_paypass_car_blocked.py | 28 +++++++++ FRONTEND/fastparking/cars/models.py | 29 ++++++--- FRONTEND/fastparking/finance/admin.py | 35 ++++++++++- .../finance/migrations/0001_initial.py | 35 +++++++++++ FRONTEND/fastparking/finance/models.py | 20 +++++- .../finance/templates/finance/tariff.html | 0 .../parking/migrations/0001_initial.py | 46 ++++++++++++++ FRONTEND/fastparking/parking/models.py | 31 +++++++++- .../parking/templates/parking/base.html | 1 + FRONTEND/fastparking/photos/forms.py | 9 +++ .../photos/migrations/0001_initial.py | 2 +- FRONTEND/fastparking/photos/models.py | 2 +- FRONTEND/fastparking/photos/repository.py | 61 +++++++++++++++++++ .../photos/templates/photos/main.html | 4 ++ .../photos/templates/photos/upload.html | 18 ++++++ FRONTEND/fastparking/photos/urls.py | 7 ++- FRONTEND/fastparking/photos/views.py | 36 ++++++++++- FRONTEND/fastparking/users/forms.py | 11 +++- .../users/migrations/0001_initial.py | 4 +- ..._remove_customuser_cars_customuser_cars.py | 22 +++++++ FRONTEND/fastparking/users/models.py | 38 ++---------- .../users/templates/users/add_car.html | 16 +++++ FRONTEND/fastparking/users/views.py | 29 +++++++++ 30 files changed, 526 insertions(+), 138 deletions(-) create mode 100644 FRONTEND/fastparking/accounts/forms.py delete mode 100644 FRONTEND/fastparking/cars/migrations/0002_remove_car_blocked_remove_car_pay_pass_and_more.py create mode 100644 FRONTEND/fastparking/cars/migrations/0002_rename_photo_car_photo_car_car_paypass_car_blocked.py create mode 100644 FRONTEND/fastparking/finance/migrations/0001_initial.py create mode 100644 FRONTEND/fastparking/finance/templates/finance/tariff.html create mode 100644 FRONTEND/fastparking/parking/migrations/0001_initial.py create mode 100644 FRONTEND/fastparking/photos/forms.py create mode 100644 FRONTEND/fastparking/photos/repository.py create mode 100644 FRONTEND/fastparking/photos/templates/photos/upload.html create mode 100644 FRONTEND/fastparking/users/migrations/0002_remove_customuser_cars_customuser_cars.py create mode 100644 FRONTEND/fastparking/users/templates/users/add_car.html diff --git a/FRONTEND/fastparking/accounts/forms.py b/FRONTEND/fastparking/accounts/forms.py new file mode 100644 index 00000000..edd4d565 --- /dev/null +++ b/FRONTEND/fastparking/accounts/forms.py @@ -0,0 +1,17 @@ +from django import forms +from cars.models import Car + +class CarForm(forms.ModelForm): + class Meta: + model = Car + fields = ['photo_car', 'car_number', 'predict'] + labels = { + 'photo_car': 'Photo', + 'car_number': 'Car Number', + 'predict': 'Prediction', + } + widgets = { + 'photo_car': forms.FileInput(attrs={'class': 'form-control-file'}), + 'car_number': forms.TextInput(attrs={'class': 'form-control'}), + 'predict': forms.NumberInput(attrs={'class': 'form-control'}), + } diff --git a/FRONTEND/fastparking/accounts/templates/accounts/profile.html b/FRONTEND/fastparking/accounts/templates/accounts/profile.html index 5a5779b8..d2f922b6 100644 --- a/FRONTEND/fastparking/accounts/templates/accounts/profile.html +++ b/FRONTEND/fastparking/accounts/templates/accounts/profile.html @@ -1,15 +1,24 @@ -{% comment %} - - - - - User Profile - - -

User Profile

-

Username: {{ request.user.username }}

-

Email: {{ request.user.email }}

- - - {% endcomment %} -{% extends "parking/base.html" %} \ No newline at end of file + +{% extends "base.html" %} + +{% block content %} +
+

Welcome to your profile

+ + +

Your Cars

+ + + +

Add a New Car

+
+ {% csrf_token %} + {{ form.as_p }} + +
+
+{% endblock %} diff --git a/FRONTEND/fastparking/accounts/urls.py b/FRONTEND/fastparking/accounts/urls.py index 0bf7695b..3e2dace0 100644 --- a/FRONTEND/fastparking/accounts/urls.py +++ b/FRONTEND/fastparking/accounts/urls.py @@ -1,11 +1,22 @@ # У вашому файлі urls.py у додатку accounts +# from django.urls import path +# from . import views + +# urlpatterns = [ +# # Інші URL-шляхи вашого додатку... + +# # URL-шлях для сторінки профілю користувача +# path('profile/', views.profile_view, name='profile'), +# ] + +# accounts/urls.py from django.urls import path -from . import views +from .views import CabinetView -urlpatterns = [ - # Інші URL-шляхи вашого додатку... +app_name = 'accounts' - # URL-шлях для сторінки профілю користувача - path('profile/', views.profile_view, name='profile'), +urlpatterns = [ + path('cabinet/', CabinetView.as_view(), name='cabinet'), + # Додайте інші URL-шляхи, якщо потрібно ] diff --git a/FRONTEND/fastparking/accounts/views.py b/FRONTEND/fastparking/accounts/views.py index 5688e137..14ff4316 100644 --- a/FRONTEND/fastparking/accounts/views.py +++ b/FRONTEND/fastparking/accounts/views.py @@ -1,9 +1,34 @@ -# У вашому файлі views.py у додатку accounts - -from django.shortcuts import render +from django.shortcuts import render, redirect from django.contrib.auth.decorators import login_required +from django.views import View +from django.utils.decorators import method_decorator +from .forms import CarForm + +# @method_decorator(login_required, name='dispatch') +# class CabinetView(View): +# def get(self, request, *args, **kwargs): +# # Отримуємо всі автомобілі поточного користувача +# user_cars = request.user.cars_set.all() +# # Передаємо список автомобілів у шаблон +# return render(request, 'accounts/profile.html', {'user_cars': user_cars}) +@method_decorator(login_required, name='dispatch') +class CabinetView(View): + def get(self, request, *args, **kwargs): + # Отримуємо всі автомобілі поточного користувача + user_cars = request.user.cars.all() + # Передаємо список автомобілів у шаблон + return render(request, 'accounts/profile.html', {'user_cars': user_cars}) + + def post(self, request, *args, **kwargs): + # Обробка POST-запиту для додавання автомобіля + form = CarForm(request.POST, request.FILES) + if form.is_valid(): + car = form.save(commit=False) + car.user = request.user + car.save() + return redirect('cabinet') + else: + # Якщо форма недійсна, повертаємо її разом з помилками + return render(request, 'accounts/profile.html', {'form': form}) + -@login_required -def profile_view(request): - # Ваш код для відображення сторінки профілю користувача - return render(request, 'accounts/profile.html') diff --git a/FRONTEND/fastparking/cars/forms.py b/FRONTEND/fastparking/cars/forms.py index 5c1b28e5..a9a16548 100644 --- a/FRONTEND/fastparking/cars/forms.py +++ b/FRONTEND/fastparking/cars/forms.py @@ -5,7 +5,7 @@ class CarForm(forms.ModelForm): class Meta: model = Car - fields = ['car_number', 'photo_car', 'predict', 'blocked', 'pay_pass', 'user'] # Перерахуйте всі поля, які ви хочете відображати у формі + fields = ['car_number', 'predict', 'blocked', 'pay_pass'] # Перерахуйте всі поля, які ви хочете відображати у формі widgets = { 'car_number': forms.TextInput(attrs={'class': 'form-control'}), @@ -13,5 +13,5 @@ class Meta: 'predict': forms.NumberInput(attrs={'class': 'form-control'}), 'blocked': forms.CheckboxInput(attrs={'class': 'form-check-input'}), 'pay_pass': forms.CheckboxInput(attrs={'class': 'form-check-input'}), - 'user': forms.Select(attrs={'class': 'form-select'}) + # 'user': forms.Select(attrs={'class': 'form-select'}) } diff --git a/FRONTEND/fastparking/cars/migrations/0001_initial.py b/FRONTEND/fastparking/cars/migrations/0001_initial.py index 1f83b855..3bbb10ac 100644 --- a/FRONTEND/fastparking/cars/migrations/0001_initial.py +++ b/FRONTEND/fastparking/cars/migrations/0001_initial.py @@ -1,7 +1,6 @@ -# Generated by Django 5.0.4 on 2024-04-10 16:57 +# Generated by Django 5.0.4 on 2024-04-13 11:59 import django.db.models.deletion -from django.conf import settings from django.db import migrations, models @@ -10,7 +9,7 @@ class Migration(migrations.Migration): initial = True dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('photos', '0001_initial'), ] operations = [ @@ -18,12 +17,9 @@ class Migration(migrations.Migration): name='Car', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('photo_car', models.ImageField(blank=True, null=True, upload_to='car_photos/')), - ('car_number', models.CharField(max_length=20)), - ('predict', models.FloatField(blank=True, null=True)), - ('blocked', models.BooleanField(default=False)), - ('pay_pass', models.BooleanField(default=False)), - ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)), + ('car_number', models.CharField(max_length=16, null=True)), + ('predict', models.FloatField(null=True)), + ('photo', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='photos.photo')), ], ), ] diff --git a/FRONTEND/fastparking/cars/migrations/0002_remove_car_blocked_remove_car_pay_pass_and_more.py b/FRONTEND/fastparking/cars/migrations/0002_remove_car_blocked_remove_car_pay_pass_and_more.py deleted file mode 100644 index af56300b..00000000 --- a/FRONTEND/fastparking/cars/migrations/0002_remove_car_blocked_remove_car_pay_pass_and_more.py +++ /dev/null @@ -1,46 +0,0 @@ -# Generated by Django 5.0.4 on 2024-04-13 06:20 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('cars', '0001_initial'), - ('photos', '0001_initial'), - ] - - operations = [ - migrations.RemoveField( - model_name='car', - name='blocked', - ), - migrations.RemoveField( - model_name='car', - name='pay_pass', - ), - migrations.RemoveField( - model_name='car', - name='photo_car', - ), - migrations.RemoveField( - model_name='car', - name='user', - ), - migrations.AddField( - model_name='car', - name='photo', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='photos.photo'), - ), - migrations.AlterField( - model_name='car', - name='car_number', - field=models.CharField(max_length=16, null=True), - ), - migrations.AlterField( - model_name='car', - name='predict', - field=models.FloatField(null=True), - ), - ] diff --git a/FRONTEND/fastparking/cars/migrations/0002_rename_photo_car_photo_car_car_paypass_car_blocked.py b/FRONTEND/fastparking/cars/migrations/0002_rename_photo_car_photo_car_car_paypass_car_blocked.py new file mode 100644 index 00000000..ba38e626 --- /dev/null +++ b/FRONTEND/fastparking/cars/migrations/0002_rename_photo_car_photo_car_car_paypass_car_blocked.py @@ -0,0 +1,28 @@ +# Generated by Django 5.0.4 on 2024-04-13 19:19 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('cars', '0001_initial'), + ] + + operations = [ + migrations.RenameField( + model_name='car', + old_name='photo', + new_name='photo_car', + ), + migrations.AddField( + model_name='car', + name='PayPass', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='car', + name='blocked', + field=models.BooleanField(default=False), + ), + ] diff --git a/FRONTEND/fastparking/cars/models.py b/FRONTEND/fastparking/cars/models.py index 4a5befc9..32f994d5 100644 --- a/FRONTEND/fastparking/cars/models.py +++ b/FRONTEND/fastparking/cars/models.py @@ -1,23 +1,32 @@ from django.urls import reverse -from django.db import models + from django.conf import settings + + + +from django.db import models from photos.models import Photo class Car(models.Model): - photo = models.ForeignKey(Photo, on_delete=models.SET_NULL, null=True) car_number = models.CharField(max_length=16, null=True) + photo_car = models.ForeignKey(Photo, on_delete=models.SET_NULL, null=True) predict = models.FloatField(null=True) + PayPass = models.BooleanField(default=False) + blocked = models.BooleanField(default=False) + + def __str__(self): + return self.car_number + def __str__(self): + return self.car_number def save(self, *args, **kwargs): - if self.photo: - self.car_number = self.photo.recognized_car_number - self.predict = self.photo.accuracy + if self.photo_car: + self.car_number = self.photo_car.recognized_car_number + self.predict = self.photo_car.accuracy super().save(*args, **kwargs) - - - def __str__(self): return self.car_number -def get_absolute_url(self): - return reverse("car_list", kwargs={"pk": self.pk}) + + def get_absolute_url(self): + return reverse("car_list", kwargs={"pk": self.pk}) diff --git a/FRONTEND/fastparking/finance/admin.py b/FRONTEND/fastparking/finance/admin.py index 8c38f3f3..15538594 100644 --- a/FRONTEND/fastparking/finance/admin.py +++ b/FRONTEND/fastparking/finance/admin.py @@ -1,3 +1,36 @@ from django.contrib import admin -# Register your models here. +from .models import Tariff +from .models import Payment + +admin.site.register(Tariff) +admin.site.register(Payment) +# from django.contrib import admin +# from .models import Tariff, Payment + +# class TariffAdmin(admin.ModelAdmin): +# list_display = ['description', 'price_per_hour', 'price_per_day', 'start_date', 'end_date'] +# readonly_fields = ['description', 'price_per_hour', 'price_per_day', 'start_date', 'end_date'] + +# class PaymentAdmin(admin.ModelAdmin): +# list_display = ['user', 'event_id', 'amount', 'datetime'] +# readonly_fields = ['user', 'event_id', 'amount', 'datetime'] + +# admin.site.register(Tariff, TariffAdmin) +# admin.site.register(Payment, PaymentAdmin) +# from django.contrib import admin +# from .models import Payment +# from users.models import CustomUser # Припущення: така структура вашої моделі користувача + +# class PaymentAdmin(admin.ModelAdmin): +# list_display = ['get_username', 'event_id', 'amount', 'datetime'] +# readonly_fields = ['user', 'event_id', 'amount', 'datetime'] + +# def get_username(self, obj): +# if obj.user: +# return obj.user.username +# return None + +# get_username.short_description = 'Username' + +# admin.site.register(Payment, PaymentAdmin) diff --git a/FRONTEND/fastparking/finance/migrations/0001_initial.py b/FRONTEND/fastparking/finance/migrations/0001_initial.py new file mode 100644 index 00000000..60c4a2f2 --- /dev/null +++ b/FRONTEND/fastparking/finance/migrations/0001_initial.py @@ -0,0 +1,35 @@ +# Generated by Django 5.0.4 on 2024-04-13 19:19 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Payment', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('user_id', models.IntegerField(blank=True, null=True)), + ('registration_id', models.IntegerField()), + ('amount', models.DecimalField(decimal_places=2, max_digits=10)), + ('datetime', models.DateTimeField()), + ], + ), + migrations.CreateModel( + name='Tariff', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('description', models.CharField(max_length=255)), + ('price_per_hour', models.DecimalField(decimal_places=2, max_digits=10)), + ('price_per_day', models.DecimalField(decimal_places=2, max_digits=10)), + ('start_date', models.DateTimeField()), + ('end_date', models.DateTimeField(default='2999-01-01 00:00:00')), + ], + ), + ] diff --git a/FRONTEND/fastparking/finance/models.py b/FRONTEND/fastparking/finance/models.py index 71a83623..2edca61a 100644 --- a/FRONTEND/fastparking/finance/models.py +++ b/FRONTEND/fastparking/finance/models.py @@ -1,3 +1,21 @@ from django.db import models -# Create your models here. +class Tariff(models.Model): + description = models.CharField(max_length=255) + price_per_hour = models.DecimalField(max_digits=10, decimal_places=2) + price_per_day = models.DecimalField(max_digits=10, decimal_places=2) + start_date = models.DateTimeField() + end_date = models.DateTimeField(default="2999-01-01 00:00:00") + + def __str__(self): + return self.description + +class Payment(models.Model): + user_id = models.IntegerField(blank=True, null=True) # ID користувача, який здійснив оплату (не обов'язкове) + registration_id = models.IntegerField() # ID реєстрації, за яку здійснюється оплата + amount = models.DecimalField(max_digits=10, decimal_places=2) + datetime = models.DateTimeField() + + def __str__(self): + return f"Payment {self.id}" + diff --git a/FRONTEND/fastparking/finance/templates/finance/tariff.html b/FRONTEND/fastparking/finance/templates/finance/tariff.html new file mode 100644 index 00000000..e69de29b diff --git a/FRONTEND/fastparking/parking/migrations/0001_initial.py b/FRONTEND/fastparking/parking/migrations/0001_initial.py new file mode 100644 index 00000000..6887cc6d --- /dev/null +++ b/FRONTEND/fastparking/parking/migrations/0001_initial.py @@ -0,0 +1,46 @@ +# Generated by Django 5.0.4 on 2024-04-13 19:19 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('cars', '0002_rename_photo_car_photo_car_car_paypass_car_blocked'), + ('finance', '0001_initial'), + ('photos', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='ParkingSpace', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('number', models.CharField(max_length=10, unique=True)), + ('status', models.BooleanField(default=False)), + ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='Registration', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('entry_datetime', models.DateTimeField(auto_now_add=True)), + ('car_number_in', models.CharField(max_length=16)), + ('exit_datetime', models.DateTimeField(blank=True, null=True)), + ('invoice', models.CharField(blank=True, max_length=255, null=True)), + ('car_number_out', models.CharField(blank=True, max_length=16, null=True)), + ('car', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='cars.car')), + ('parking', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='parking.parkingspace')), + ('payment', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='finance.payment')), + ('photo_in', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='entry_photo', to='photos.photo')), + ('photo_out', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='exit_photo', to='photos.photo')), + ('tariff', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='finance.tariff')), + ], + ), + ] diff --git a/FRONTEND/fastparking/parking/models.py b/FRONTEND/fastparking/parking/models.py index 71a83623..b7266964 100644 --- a/FRONTEND/fastparking/parking/models.py +++ b/FRONTEND/fastparking/parking/models.py @@ -1,3 +1,32 @@ from django.db import models +from cars.models import Car +from finance.models import Tariff +from finance.models import Payment +from users.models import CustomUser +from photos.models import Photo + + +class ParkingSpace(models.Model): + number = models.CharField(max_length=10, unique=True) + status = models.BooleanField(default=False) # False - вільно, True - зайнято + user = models.ForeignKey(CustomUser, on_delete=models.SET_NULL, null=True, blank=True) + + def __str__(self): + return self.number +class Registration(models.Model): + parking = models.ForeignKey(ParkingSpace, on_delete=models.CASCADE) + entry_datetime = models.DateTimeField(auto_now_add=True) + car_number_in = models.CharField(max_length=16) + tariff = models.ForeignKey(Tariff, on_delete=models.SET_NULL, null=True) + exit_datetime = models.DateTimeField(null=True, blank=True) + invoice = models.CharField(max_length=255, null=True, blank=True) + payment = models.ForeignKey(Payment, on_delete=models.SET_NULL, null=True, blank=True) + car_number_out = models.CharField(max_length=16, null=True, blank=True) + photo_in = models.ForeignKey(Photo, on_delete=models.SET_NULL, related_name=type, null=True, blank=True) + photo_out = models.ForeignKey(Photo, on_delete=models.SET_NULL, related_name=type, null=True, blank=True) + car = models.ForeignKey(Car, on_delete=models.SET_NULL, null=True, blank=True) + + def __str__(self): + return f"Registration ID: {self.id} - Parking ID: {self.parking_id} - Entry Time: {self.entry_datetime}" + -# Create your models here. diff --git a/FRONTEND/fastparking/parking/templates/parking/base.html b/FRONTEND/fastparking/parking/templates/parking/base.html index 99e0fe04..c14bc420 100644 --- a/FRONTEND/fastparking/parking/templates/parking/base.html +++ b/FRONTEND/fastparking/parking/templates/parking/base.html @@ -38,6 +38,7 @@

Sidebars examples

{% if user.is_authenticated %} +
  • Profile
  • diff --git a/FRONTEND/fastparking/photos/forms.py b/FRONTEND/fastparking/photos/forms.py new file mode 100644 index 00000000..3e1cd17b --- /dev/null +++ b/FRONTEND/fastparking/photos/forms.py @@ -0,0 +1,9 @@ +from django import forms +from django.contrib.auth.forms import UserCreationForm, AuthenticationForm +from django.contrib.auth.models import User + + +class UploadFileForm(forms.Form): + choices = [("0", "IN"), ("1", "OUT")] + type = forms.ChoiceField(choices=choices) + photo = forms.ImageField() diff --git a/FRONTEND/fastparking/photos/migrations/0001_initial.py b/FRONTEND/fastparking/photos/migrations/0001_initial.py index 81727b3e..92651cfc 100644 --- a/FRONTEND/fastparking/photos/migrations/0001_initial.py +++ b/FRONTEND/fastparking/photos/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.0.4 on 2024-04-13 06:20 +# Generated by Django 5.0.4 on 2024-04-13 11:59 from django.db import migrations, models diff --git a/FRONTEND/fastparking/photos/models.py b/FRONTEND/fastparking/photos/models.py index b7c7ced4..05e04f8e 100644 --- a/FRONTEND/fastparking/photos/models.py +++ b/FRONTEND/fastparking/photos/models.py @@ -1,6 +1,6 @@ from django.db import models from django.conf import settings -from django.contrib.auth.models import User +from users.models import CustomUser class Photo(models.Model): diff --git a/FRONTEND/fastparking/photos/repository.py b/FRONTEND/fastparking/photos/repository.py new file mode 100644 index 00000000..3d5a73fc --- /dev/null +++ b/FRONTEND/fastparking/photos/repository.py @@ -0,0 +1,61 @@ +import base64 +from datetime import datetime +from pathlib import Path +from django.conf import settings + +from ds.predict_num import get_num_auto_png_io + +from .models import Photo + +TYPES = {"0": "IN", "1": "OUT"} + + +def save_prediction(predict: dict, type: str) -> None: + num_auto = predict.get("num_avto_str") + accuracy = predict.get("accuracy") + num_img = predict.get("num_img") + if num_auto: + record = Photo() + record.recognized_car_number = num_auto + record.accuracy = accuracy + record.photo = num_img + record.type = type + record.save() + + +def save_image(f, type: str = "", filepath: Path | None = None): + if filepath is None: + if settings.MEDIA_ROOT: + utc_datetime = datetime.utcnow() + file_date = utc_datetime.strftime("%Y%m%d%H%M%S") + media: Path = settings.MEDIA_ROOT.joinpath("photos").joinpath( + TYPES.get(type) + ) + media.mkdir(parents=True, exist_ok=True) + image_type = "jpg" + filepath = media.joinpath(f"{file_date}.{image_type}") + if f and filepath: + with filepath.open("wb+") as destination: + for chunk in f.chunks(): + destination.write(chunk) + + +def handle_uploaded_file(f, type: str | None) -> dict[str, dict]: + if f and type: + info = f"File accepted, sizes: {len(f) // 1024} KB, {type=}" + # try to save + # try: + # save_image(f, type=type) + # except Exception: + # ... + + # analyze and calculate prediction of image + predict = get_num_auto_png_io(f.read()) + # store information to database + save_prediction(predict, type) + # prepare for show on web page + binary_image_data = predict.get("num_img") + if binary_image_data: + base64_image = base64.b64encode(binary_image_data).decode("utf-8") + predict["num_img"] = base64_image + return {"info": info, "predict": predict} diff --git a/FRONTEND/fastparking/photos/templates/photos/main.html b/FRONTEND/fastparking/photos/templates/photos/main.html index defe0f1a..c43dccbd 100644 --- a/FRONTEND/fastparking/photos/templates/photos/main.html +++ b/FRONTEND/fastparking/photos/templates/photos/main.html @@ -1,2 +1,6 @@ {% extends "parking/base.html" %} +{% block content %} + Title + Upload +{% endblock content %} \ No newline at end of file diff --git a/FRONTEND/fastparking/photos/templates/photos/upload.html b/FRONTEND/fastparking/photos/templates/photos/upload.html new file mode 100644 index 00000000..e74d195c --- /dev/null +++ b/FRONTEND/fastparking/photos/templates/photos/upload.html @@ -0,0 +1,18 @@ + +{% extends "parking/base.html" %} +{% block content %} +

    Upload photo

    +
    + {% csrf_token %} + {{ form.as_p }} + +
    +{% if info %} +

    RESULT:

    +

    info: {{ info }}

    +

    number: {{ predict.num_avto_str }}

    +

    accuracy: {{ predict.accuracy }}

    + img: +{% endif %} +{% endblock content %} + diff --git a/FRONTEND/fastparking/photos/urls.py b/FRONTEND/fastparking/photos/urls.py index 060f75c7..bcb81ec9 100644 --- a/FRONTEND/fastparking/photos/urls.py +++ b/FRONTEND/fastparking/photos/urls.py @@ -3,8 +3,9 @@ from django.urls import path from . import views -app_name = 'photos' +app_name = "photos" urlpatterns = [ - path('', views.main, name='main'), -] \ No newline at end of file + path("", views.main, name="main"), + path("upload", views.upload_file, name="upload"), +] diff --git a/FRONTEND/fastparking/photos/views.py b/FRONTEND/fastparking/photos/views.py index 41a43525..91b98328 100644 --- a/FRONTEND/fastparking/photos/views.py +++ b/FRONTEND/fastparking/photos/views.py @@ -1,5 +1,39 @@ +from django.http import HttpResponseRedirect from django.shortcuts import render +from .forms import UploadFileForm +from django.urls import reverse + + +# Imaginary function to handle an uploaded file. +from .repository import handle_uploaded_file + + +def upload_file(request): + if request.method == "POST": + form = UploadFileForm(request.POST, request.FILES) + if form.is_valid(): + type_of_photo = request.POST.get("type") + file_in = request.FILES.get("photo") + if file_in: + img_predict = handle_uploaded_file(file_in, type_of_photo) + info = img_predict.get("info") + predict = img_predict.get("predict") + # print(f"{info}") + if info: + return render( + request, + "photos/upload.html", + {"form": form, "info": info, "predict": predict}, + ) + # upload_url = reverse("upload") + return HttpResponseRedirect("") + else: + form = UploadFileForm() + return render(request, "photos/upload.html", {"form": form}) + def main(request): # ваш код для обробки запиту тут - return render(request, 'photos/main.html') # або інша логіка відповідно до вашого проекту \ No newline at end of file + return render( + request, "photos/main.html" + ) # або інша логіка відповідно до вашого проекту \ No newline at end of file diff --git a/FRONTEND/fastparking/users/forms.py b/FRONTEND/fastparking/users/forms.py index f64c7f0c..2e825b0d 100644 --- a/FRONTEND/fastparking/users/forms.py +++ b/FRONTEND/fastparking/users/forms.py @@ -5,6 +5,7 @@ from django.forms import CharField, TextInput, EmailField, EmailInput, PasswordInput from django import forms from .models import CustomUser +from cars.models import Car class RegisterForm(UserCreationForm): username = forms.CharField(max_length=100, required=True, widget=forms.TextInput(attrs={"class": "form-control"})) @@ -15,11 +16,12 @@ class RegisterForm(UserCreationForm): accept_oferta = forms.BooleanField(required=True) telegram_nickname = forms.CharField(max_length=20, required=False, widget=forms.TextInput(attrs={"class": "form-control"})) telegram_id = forms.CharField(max_length=50, required=False, widget=forms.TextInput(attrs={"class": "form-control"})) + # cars = forms.ModelMultipleChoiceField(queryset=Car.objects.all(), required=False) class Meta: model = get_user_model() # Змінено з User на CustomUser + # fields = ("username", "first_name", "last_name", "email", "phone_number", "accept_oferta", "password1", "password2", "telegram_nickname") fields = ("username", "first_name", "last_name", "email", "phone_number", "accept_oferta", "password1", "password2", "telegram_nickname") - def save(self, commit=True): user = super().save(commit=False) if not user.username: # Якщо користувач не вказав username (нікнейм), використовуємо номер телефону або Telegram нікнейм @@ -41,3 +43,10 @@ class LoginForm(AuthenticationForm): class Meta: model = get_user_model() fields = ("username", "password") + + + +class CarAddForm(forms.Form): + car_number = forms.CharField(label='Car Number', max_length=16) + brand = forms.CharField(label='Brand', max_length=100) + car_type = forms.CharField(label='Car Type', max_length=100) \ No newline at end of file diff --git a/FRONTEND/fastparking/users/migrations/0001_initial.py b/FRONTEND/fastparking/users/migrations/0001_initial.py index a57ce9cb..ce950345 100644 --- a/FRONTEND/fastparking/users/migrations/0001_initial.py +++ b/FRONTEND/fastparking/users/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.0.4 on 2024-04-12 15:43 +# Generated by Django 5.0.4 on 2024-04-13 11:59 import django.contrib.auth.models import django.contrib.auth.validators @@ -12,6 +12,7 @@ class Migration(migrations.Migration): dependencies = [ ('auth', '0012_alter_user_first_name_max_length'), + ('cars', '0001_initial'), ] operations = [ @@ -32,6 +33,7 @@ class Migration(migrations.Migration): ('telegram_nickname', models.CharField(blank=True, max_length=20, null=True)), ('phone_number', models.CharField(blank=True, max_length=20, null=True)), ('telegram_id', models.CharField(blank=True, max_length=50, null=True)), + ('cars', models.ManyToManyField(blank=True, related_name='owners', to='cars.car')), ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')), ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')), ], diff --git a/FRONTEND/fastparking/users/migrations/0002_remove_customuser_cars_customuser_cars.py b/FRONTEND/fastparking/users/migrations/0002_remove_customuser_cars_customuser_cars.py new file mode 100644 index 00000000..61d5bd77 --- /dev/null +++ b/FRONTEND/fastparking/users/migrations/0002_remove_customuser_cars_customuser_cars.py @@ -0,0 +1,22 @@ +# Generated by Django 5.0.4 on 2024-04-13 19:19 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0001_initial'), + ] + + operations = [ + migrations.RemoveField( + model_name='customuser', + name='cars', + ), + migrations.AddField( + model_name='customuser', + name='cars', + field=models.TextField(blank=True, null=True), + ), + ] diff --git a/FRONTEND/fastparking/users/models.py b/FRONTEND/fastparking/users/models.py index 452896b4..71e940f9 100644 --- a/FRONTEND/fastparking/users/models.py +++ b/FRONTEND/fastparking/users/models.py @@ -1,43 +1,15 @@ - -# from django.contrib.auth.models import AbstractUser -# from django.db import models -# from django.db.models.signals import post_save - -# class CustomUser(AbstractUser): -# # telegram_nickname = models.CharField(max_length=20, blank=True, null=True) - -# def __str__(self): -# return self.username - -# class Profile(models.Model): -# user = models.OneToOneField(CustomUser, on_delete=models.CASCADE) - -# def __str__(self): -# return self.user.username - -# def create_user_profile(sender, instance, created, **kwargs): -# if created: -# Profile.objects.create(user=instance) - -# # Підключення обробника сигналу -# post_save.connect(create_user_profile, sender=CustomUser) - from django.contrib.auth.models import AbstractUser from django.db import models from django.db.models.signals import post_save from django.dispatch import receiver +from cars.models import Car -# class Profile(models.Model): -# user = models.OneToOneField('CustomUser', on_delete=models.CASCADE) - -# def __str__(self): -# return self.user.username - class CustomUser(AbstractUser): + cars = models.TextField(blank=True, null=True) telegram_nickname = models.CharField(max_length=20, blank=True, null=True) phone_number = models.CharField(max_length=20, blank=True, null=True) - telegram_id = models.CharField(max_length=50,blank=True, null=True) + telegram_id = models.CharField(max_length=50, blank=True, null=True) + # cars = models.ManyToManyField(Car, related_name='owners', blank=True) # Додано поле багато-до-багатьох для прив'язки автомобілів до користувача def __str__(self): - return self.username - + return self.username \ No newline at end of file diff --git a/FRONTEND/fastparking/users/templates/users/add_car.html b/FRONTEND/fastparking/users/templates/users/add_car.html new file mode 100644 index 00000000..86f712af --- /dev/null +++ b/FRONTEND/fastparking/users/templates/users/add_car.html @@ -0,0 +1,16 @@ + + + + + + Add Car + + +

    Add a New Car

    +
    + {% csrf_token %} + {{ form.as_p }} + +
    + + \ No newline at end of file diff --git a/FRONTEND/fastparking/users/views.py b/FRONTEND/fastparking/users/views.py index e2eb3ead..30119d90 100644 --- a/FRONTEND/fastparking/users/views.py +++ b/FRONTEND/fastparking/users/views.py @@ -9,6 +9,9 @@ from django.contrib.auth import logout from django.shortcuts import redirect from django.contrib.auth.decorators import login_required +from django.shortcuts import render, redirect +from .models import Car +from .forms import CarAddForm @login_required def logout_view(request): @@ -43,3 +46,29 @@ class ResetPasswordView(SuccessMessageMixin, PasswordResetView): success_url = reverse_lazy('users:password_reset_done') success_message = "An email with instructions to reset your password has been sent to %(email)s." subject_template_name = 'users/password_reset_subject.txt' + + + +def add_car(request): + if request.method == 'POST': + form = CarAddForm(request.POST) + if form.is_valid(): + car_number = form.cleaned_data['car_number'] + brand = form.cleaned_data['brand'] + car_type = form.cleaned_data['car_type'] + + # Перевірка наявності автомобіля з введеним номером + car = Car.objects.filter(car_number=car_number).first() + if car: + # Якщо автомобіль існує, прив'яжіть його до поточного користувача + car.owners.add(request.user) + else: + # Якщо автомобіль не існує, створіть новий запис + car = Car.objects.create(car_number=car_number, brand=brand, car_type=car_type) + car.owners.add(request.user) + + return redirect('profile') # Перенаправлення на профіль користувача після успішного додавання автомобіля + else: + form = CarAddForm() + + return render(request, 'add_car.html', {'form': form}) \ No newline at end of file From 23eb903fd63df6894f172003bef1ae8ea36d892b Mon Sep 17 00:00:00 2001 From: RostislavB74 Date: Sun, 14 Apr 2024 08:36:27 +0300 Subject: [PATCH 02/19] test --- FRONTEND/fastparking/communications/admin.py | 9 +- .../communications/migrations/0001_initial.py | 29 ++++++ .../0002_alter_message_date_displayed.py | 17 ++++ FRONTEND/fastparking/communications/models.py | 9 +- .../fastparking/communications/send_news.py | 39 ++++++++ .../templates/communications/main.html | 20 ++-- FRONTEND/fastparking/communications/views.py | 20 +++- FRONTEND/fastparking/ds/predict_num.py | 93 ++++++++++++++----- FRONTEND/fastparking/finance/views.py | 8 +- .../parking/templates/parking/base.html | 16 ++-- FRONTEND/fastparking/parking/views.py | 8 +- FRONTEND/fastparking/photos/repository.py | 26 ++++++ .../photos/templates/photos/main.html | 6 ++ FRONTEND/fastparking/photos/views.py | 8 +- FRONTEND/fastparking/utils/get_news.py | 60 ++---------- FRONTEND/fastparking/utils/news.txt | 2 - FRONTEND/fastparking/utils/sheduler.py | 19 +++- FRONTEND/fastparking/utils/telegram_api.py | 39 +++++--- .../fastparking/utils/telegram_chanel.txt | 0 scripts/cron_loop.sh | 2 +- scripts/make_migrate_dev_app.sh | 0 21 files changed, 304 insertions(+), 126 deletions(-) create mode 100644 FRONTEND/fastparking/communications/migrations/0001_initial.py create mode 100644 FRONTEND/fastparking/communications/migrations/0002_alter_message_date_displayed.py create mode 100644 FRONTEND/fastparking/communications/send_news.py delete mode 100644 FRONTEND/fastparking/utils/news.txt delete mode 100644 FRONTEND/fastparking/utils/telegram_chanel.txt mode change 100644 => 100755 scripts/make_migrate_dev_app.sh diff --git a/FRONTEND/fastparking/communications/admin.py b/FRONTEND/fastparking/communications/admin.py index 8c38f3f3..445fff54 100644 --- a/FRONTEND/fastparking/communications/admin.py +++ b/FRONTEND/fastparking/communications/admin.py @@ -1,3 +1,10 @@ from django.contrib import admin -# Register your models here. +from .models import Message + + +class ModelAdmin(admin.ModelAdmin): + list_display = ("date_displayed", "news_text", "is_displayed") + + +admin.site.register(Message, ModelAdmin) diff --git a/FRONTEND/fastparking/communications/migrations/0001_initial.py b/FRONTEND/fastparking/communications/migrations/0001_initial.py new file mode 100644 index 00000000..ef2043cb --- /dev/null +++ b/FRONTEND/fastparking/communications/migrations/0001_initial.py @@ -0,0 +1,29 @@ +# Generated by Django 5.0.4 on 2024-04-13 19:16 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + initial = True + + dependencies = [] + + operations = [ + migrations.CreateModel( + name="Message", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("date_displayed", models.DateTimeField(auto_now_add=True)), + ("news_text", models.TextField()), + ("is_displayed", models.BooleanField(default=False)), + ], + ), + ] diff --git a/FRONTEND/fastparking/communications/migrations/0002_alter_message_date_displayed.py b/FRONTEND/fastparking/communications/migrations/0002_alter_message_date_displayed.py new file mode 100644 index 00000000..c56a5db4 --- /dev/null +++ b/FRONTEND/fastparking/communications/migrations/0002_alter_message_date_displayed.py @@ -0,0 +1,17 @@ +# Generated by Django 5.0.4 on 2024-04-13 21:26 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("communications", "0001_initial"), + ] + + operations = [ + migrations.AlterField( + model_name="message", + name="date_displayed", + field=models.DateTimeField(blank=True, null=True), + ), + ] diff --git a/FRONTEND/fastparking/communications/models.py b/FRONTEND/fastparking/communications/models.py index 71a83623..8eb15fef 100644 --- a/FRONTEND/fastparking/communications/models.py +++ b/FRONTEND/fastparking/communications/models.py @@ -1,3 +1,10 @@ from django.db import models -# Create your models here. + +class Message(models.Model): + date_displayed = models.DateTimeField(null=True, blank=True) + news_text = models.TextField() + is_displayed = models.BooleanField(default=False) + + def __str__(self): + return self.news_text diff --git a/FRONTEND/fastparking/communications/send_news.py b/FRONTEND/fastparking/communications/send_news.py new file mode 100644 index 00000000..a70ad0c8 --- /dev/null +++ b/FRONTEND/fastparking/communications/send_news.py @@ -0,0 +1,39 @@ +from django.db.models import Q +from django.utils import timezone + +from utils.telegram_api import send_message_news + +try: + from .models import Message +except ImportError: + from models import Message + + +def fetch_unsent_news(max_messages: int = 1): + unsent_message = Message.objects.filter( + Q(is_displayed=False) + & (Q(date_displayed__lte=timezone.now()) | Q(date_displayed__isnull=True)) + )[:max_messages] + return unsent_message + + +def mark_news_as_sent(message): + message.is_displayed = True + message.date_displayed = timezone.now() + message.save() + + +def send_news_to_telegram(max_messages=3, debug=False): + unsent_messages = fetch_unsent_news(max_messages) + sent_messages = 0 + for message in unsent_messages: + if debug: + print(f"{message.date_displayed=}, {timezone.now()=}") + print("MESSAGE TO NEWS: ", message.news_text) + mark_news_as_sent(message) + sent_messages += 1 + else: + if send_message_news(message.news_text): + mark_news_as_sent(message) + sent_messages += 1 + return sent_messages diff --git a/FRONTEND/fastparking/communications/templates/communications/main.html b/FRONTEND/fastparking/communications/templates/communications/main.html index e238c8ae..147a3907 100644 --- a/FRONTEND/fastparking/communications/templates/communications/main.html +++ b/FRONTEND/fastparking/communications/templates/communications/main.html @@ -1,14 +1,10 @@ {% extends "parking/base.html" %} - - - - - - Main Page - Communications - - -

    Main Page - Communications

    -

    This is a placeholder for the main page of the communications app.

    - - +{% block content %} +

    Messages

    +

    Перевіряємо чи є актуальні новини, і форсуємо їх надіслання до каналу новин.

    +Наш канал новин: @{{ news_channel }}. +{% if sent_messages %} +

    Надіслано повідомлень: {{ sent_messages }}.

    +{% endif%} +{% endblock content %} diff --git a/FRONTEND/fastparking/communications/views.py b/FRONTEND/fastparking/communications/views.py index f810577f..c177f4c6 100644 --- a/FRONTEND/fastparking/communications/views.py +++ b/FRONTEND/fastparking/communications/views.py @@ -1,5 +1,23 @@ from django.shortcuts import render +from django.conf import settings + +from .send_news import send_news_to_telegram + + +def check_news(): + return send_news_to_telegram() + def main(request): # ваш код для обробки запиту тут - return render(request, 'communications/main.html') # або інша логіка відповідно до вашого проекту \ No newline at end of file + active_menu = "messages" + sent_messages = check_news() + return render( + request, + "communications/main.html", + { + "active_menu": active_menu, + "news_channel": settings.TELEGRAM_NEWS_NAME[1:], + "sent_messages": sent_messages, + }, + ) # або інша логіка відповідно до вашого проекту diff --git a/FRONTEND/fastparking/ds/predict_num.py b/FRONTEND/fastparking/ds/predict_num.py index 882862db..27549564 100644 --- a/FRONTEND/fastparking/ds/predict_num.py +++ b/FRONTEND/fastparking/ds/predict_num.py @@ -1,16 +1,15 @@ import os - -os.environ["TF_ENABLE_ONEDNN_OPTS"] = "0" - +import io +from pathlib import Path import matplotlib.pyplot as plt import numpy as np import cv2 # import tensorflow as tf -from pathlib import Path +os.environ["TF_ENABLE_ONEDNN_OPTS"] = "0" # from sklearn.metrics import f1_score # from keras import optimizers # from keras.models import Sequential @@ -70,7 +69,6 @@ def extract_plate(img, plate_cascade, text=""): y_max = 0 for x, y, w, h in plate_rect: - # виконує пропорційне зміщення пікселів a, b = (int(0.1 * h), int(0.1 * w)) aa, bb = (int(0.1 * h), int(0.1 * w)) @@ -106,8 +104,7 @@ def extract_plate(img, plate_cascade, text=""): # Відповідність контурів номерному або символьному шаблону -def find_contours(dimensions, img): - +def find_contours(dimensions, img, debug=False): i_width_threshold = 6 # Знайдіть всі контури на зображенні @@ -180,8 +177,8 @@ def find_contours(dimensions, img): break # Return characters on ascending order with respect to the x-coordinate (most-left character first) - - plt.show() + if debug: + plt.show() # arbitrary function that stores sorted list of character indeces indices = sorted(range(len(x_cntr_list)), key=lambda k: x_cntr_list[k]) img_res_copy = [] @@ -195,8 +192,7 @@ def find_contours(dimensions, img): # Find characters in the resulting images -def segment_to_contours(image): - +def segment_to_contours(image, debug: bool = False): new_height = 75 # set fixed height # print("original plate[w,h]:", image.shape[1], image.shape[0], "new_shape:333,", new_height) @@ -219,9 +215,10 @@ def segment_to_contours(image): # Estimations of character contours sizes of cropped license plates dimensions = [LP_WIDTH / 24, LP_WIDTH / 8, LP_HEIGHT / 3, 2 * LP_HEIGHT / 3] - # plt.imshow(img_binary_lp, cmap='gray') - # plt.title("original plate contour (binary)") - # plt.show() + # if debug: + # plt.imshow(img_binary_lp, cmap='gray') + # plt.title("original plate contour (binary)") + # plt.show() # Get contours within cropped license plate char_list = find_contours(dimensions, img_binary_lp) @@ -242,22 +239,30 @@ def predict_result(ch_contours, model): for i, c in enumerate(characters): dic[i] = c + total_accuracy = 1.0 + output = [] for i, ch in enumerate(ch_contours): - img_ = cv2.resize(ch, (28, 28)) # interpolation=cv2.INTER_LINEAR by default img = fix_dimension(img_) img = img.reshape(1, 28, 28, 3) # preparing image for the model - y_ = np.argmax(model.predict(img, verbose=0), axis=-1)[ - 0 - ] # predicting the class + prediction = model.predict(img, verbose=0) + + y_ = np.argmax(prediction, axis=-1)[0] # predicting the class + + # print(y_, prediction.shape, prediction) character = dic[y_] + # accuracy = prediction[0][y_] + # print(f'{accuracy=}') + # total_accuracy *= accuracy + # print(f'{total_accuracy=}') + output.append(character) plate_number = "".join(output) - return plate_number + return plate_number, total_accuracy def get_num_avto(img_avto): @@ -266,16 +271,55 @@ def get_num_avto(img_avto): chars = segment_to_contours(num_img) - predicted_str = predict_result(chars, model) + predicted_str, total_accuracy = predict_result(chars, model) num_avto_str = str.replace(predicted_str, "#", "") - return num_avto_str, num_img + return { + "num_avto_str": num_avto_str, + "accuracy": total_accuracy, + "num_img": num_img, + } + + +def decode_io_file(f): + io_buf = io.BytesIO(f) + # io_buf.seek(0) + decode_img = cv2.imdecode(np.frombuffer(io_buf.getbuffer(), np.uint8), -1) + return decode_img + + +def get_num_auto_png_io(f) -> dict: + img = decode_io_file(f) + return get_num_auto_png(img) + + +def get_num_auto_png(img) -> dict: + num_result = get_num_avto(img) + img = np.zeros(0) + try: + is_success, im_buf_arr = cv2.imencode( + ".png", num_result["num_img"], params=[cv2.IMWRITE_PNG_COMPRESSION, 5] + ) + except Exception: + is_success = False + + if is_success: + io_buf = io.BytesIO(im_buf_arr) + num_result["num_img"] = io_buf.getvalue() + im_buf_arr = np.zeros(0) + else: + num_result["num_img"] = None + + # tune output accuracy + if len(num_result["num_avto_str"]) < 6: + num_result["accuracy"] *= 0.3 + + return num_result ################################################################################ if __name__ == "__main__": - img_path = ( Path(__file__) .resolve() @@ -290,5 +334,6 @@ def get_num_avto(img_avto): print("Помилка завантаження зображення. Перевірте шлях до файлу.") exit(1) - result = get_num_avto(original) - print(f"ok - {result}") + # num_result = get_num_avto(original) + num_result = get_num_auto_png(original) + print(num_result) diff --git a/FRONTEND/fastparking/finance/views.py b/FRONTEND/fastparking/finance/views.py index d9a706db..ed109640 100644 --- a/FRONTEND/fastparking/finance/views.py +++ b/FRONTEND/fastparking/finance/views.py @@ -1,7 +1,9 @@ - from django.shortcuts import render + def main(request): + active_menu = "finance" # ваш код для обробки запиту тут - return render(request, 'finance/main.html') # або інша логіка відповідно до вашого проекту - + return render( + request, "finance/main.html", {"active_menu": active_menu} + ) # або інша логіка відповідно до вашого проекту diff --git a/FRONTEND/fastparking/parking/templates/parking/base.html b/FRONTEND/fastparking/parking/templates/parking/base.html index c14bc420..2e623030 100644 --- a/FRONTEND/fastparking/parking/templates/parking/base.html +++ b/FRONTEND/fastparking/parking/templates/parking/base.html @@ -32,7 +32,7 @@

    Sidebars examples