From 99b8ba80d59ce2ca5ef5b25ffb247d8dfb28e1d6 Mon Sep 17 00:00:00 2001 From: erjemin Date: Tue, 27 Dec 2022 14:13:29 +0300 Subject: [PATCH] =?UTF-8?q?=D0=92=D1=8C=D1=8E=D1=88=D0=BA=D0=B0=20=D0=B8?= =?UTF-8?q?=20=D1=88=D0=B0=D0=B1=D0=BB=D0=BE=D0=BD:=20"=D0=9A=D0=B0=D1=82?= =?UTF-8?q?=D0=B0=D0=BB=D0=BE=D0=B3=20/=20=D0=9E=D0=BA=D0=BE=D0=BD=D0=BD?= =?UTF-8?q?=D1=8B=D0=B5=20=D0=BF=D1=80=D0=BE=D1=91=D0=BC=D1=8B=20=D0=B8=20?= =?UTF-8?q?=D0=B1=D0=B0=D0=BB=D0=BA=D0=BE=D0=BD=D0=BD=D1=8B=D0=B5=20=D0=B1?= =?UTF-8?q?=D0=BB=D0=BE=D0=BA=D0=B8"=20--=20=D0=B3=D0=BE=D1=82=D0=BE=D0=B2?= =?UTF-8?q?=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- oknardia/oknardia/urls.py | 1 + .../catalog/catalog_standard_opening.html | 121 ++++++++++++++++++ oknardia/web/add_func.py | 87 ++++++++++++- oknardia/web/catalog.py | 84 +++++++++++- 4 files changed, 290 insertions(+), 3 deletions(-) create mode 100755 oknardia/templates/catalog/catalog_standard_opening.html diff --git a/oknardia/oknardia/urls.py b/oknardia/oknardia/urls.py index 094c96e..b5e4a90 100644 --- a/oknardia/oknardia/urls.py +++ b/oknardia/oknardia/urls.py @@ -62,6 +62,7 @@ urlpatterns = [ # --- --- Каталог серий типового строительства re_path(r'^catalog/seria[/*]$', catalog.catalog_seria), re_path(r'^catalog/seria/(?P[^/]*)/all(?P\d+)[/*]$', catalog.catalog_seria_info), + re_path(r'^catalog/standard_opening[/*]$', catalog.standard_opening), ] diff --git a/oknardia/templates/catalog/catalog_standard_opening.html b/oknardia/templates/catalog/catalog_standard_opening.html new file mode 100755 index 0000000..3d762b4 --- /dev/null +++ b/oknardia/templates/catalog/catalog_standard_opening.html @@ -0,0 +1,121 @@ +{% extends "base.html" %}{% load static %} + +{% block Title %} Каталог :: стандартные оконные проёмы типовых серий домов...{% endblock %} + +{% block Add_Body_Attribute %} style="padding-top:70px;"{% endblock %} + +{% block Description %}Каталог «Окнардия»: стандартные оконные проёмы типовых серий домов...{% endblock %} + +{% block Keywords %}Каталог, каталог оконных проёмов, oknardia, окнардия {{ META_KEYWORDS|default:"" }} {% endblock %} + +{% block Date4Meta %}{{ PUB_DAT|date:"c" }}{% endblock %} + +{% block Last4Meta %}{{ PUB_DAT|date:"c" }}{% endblock %} + +{% block Author4Meta %}: Каталог «Окнардия»{% endblock %} + +{% block CopyrightAuthor4Meta %}: Каталог «Окнардия»{% endblock %} + +{% block Top_Meta1 %}{# #} + {% if IMG_FOR_BLOG %} + {% else %} + {% endif %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{# #}{% endblock %} + +{% block Main_Content %} +
+ {# #}
+
+ +
+
{# #} +
+ {# ПЕРВЫЙ РАЗДЕЛ #}
+

Cтандартные оконные проёмы и балконные блоки

+

Ценовая выдача «Окнардии» основана на базе стандартных оконных проёмов в типовых сериях домов. Для каждого проёма существуют рекомендованные организациями-проектировщиками схемы открывание, но парнёры «Окнардии» могут предложить свои, более расширенные или наоборот сокращенные. В таблице приведены параметры стандартных проёмов базы.

+
+ {# реклама Oknardia 250x250 СБОКУ #}
{% include "ad/bannet-250x250.html" %}
+
+ + + + + + + + + + + + + + + + + + + {% for i in LIST_WIN_OPENING %} + + + + + + + + + + +{# {% for j in SERIAS %}#} +{# {% endfor %}#} + {% endfor %} + +
Размеры (мм)Стандартная
схема
открывания
Балконный блокОписание окнаТиповые серии домов где встречается данный окный проём
Ш×ВОкноДверь
{{ i.W|stringformat:".0f" }}×{{ i.H|stringformat:".0f" }}{{ i.DESCRIPTION_L }}{% if i.IS_NEAR_DOOR %}да{% else %}—{% endif %}{% if i.IS_DOOR %}да{% else %}—{% endif %}{{ i.DESCRIPTION }}{% for j in i.INCLUDING_IN_SERIA %}{{ j.NAME }}{% if not forloop.last %}, {% endif %}{% endfor %}цены{% if j.id in i.INCLUDING_IN_SERIA %}#{% endif %}
+
+ + +
+
+ + {# --- Баннер: НАЧАЛО --- #} +

{% include "ad/bannet-wide.html" %}
+ {# --- Баннер: конец --- #} +
+{% include "report/report_last_user_visit.html" %} +{% include "report/report_log_user_visit.html" %} +
+
{% endblock %} + + diff --git a/oknardia/web/add_func.py b/oknardia/web/add_func.py index c02fef2..4d0087a 100644 --- a/oknardia/web/add_func.py +++ b/oknardia/web/add_func.py @@ -382,8 +382,8 @@ def flap_analiz(flap_config: str) -> list: or flap_config[i] == "=" # горизонтальная перегородка or flap_config[i] == "X" # глухое окно or flap_config[i] == "x" # ^ - or flap_config[i] == u"х" # ^ - or flap_config[i] == u"Х" # ^ + or flap_config[i] == "х" # ^ + or flap_config[i] == "Х" # ^ or flap_config[i] == "+" # ^ or flap_config[i] == "M" # москитная сетка or flap_config[i] == "m" # ^ @@ -395,3 +395,86 @@ def flap_analiz(flap_config: str) -> list: or flap_config[i] == "s"): # ^ dim_flap[j]["row"][k].update({"flap": dim_flap[j]["row"][k]["flap"] + flap_config[i]}) return dim_flap + + +def make_flap_mini_pictures(path_to_img_file: str, str_flap_config: str, is_door: bool = False) -> None: + """ Функция создает файл мини-картинки схем открывания окна + + :param path_to_img_file: путь к файлу с изображением + :param str_flap_config: строка с описанием схемы открывания + :param is_door: + :return: + """ + # print(path_to_img_file, str_flap_config, is_door) + dim_flap = flap_analiz(str_flap_config) + v_ratio_max = 0 # число всех долей (частей) для построения пропорций по вертикали + h_ratio_max = 0 # число всех долей (частей) для построения пропорций по горизонтали + for i in dim_flap: + local_h_ratio_max = 0 + v_ratio_max += i["vRatio"] + for j in i["row"]: + local_h_ratio_max += j["hRatio"] + if local_h_ratio_max > h_ratio_max: + h_ratio_max = local_h_ratio_max + img = Image.new("RGBA", (h_ratio_max*PICT_MINWI+(h_ratio_max+1)*3, PICT_MINIH+6), (255, 255, 255, 0)) + top = 0 + left = 0 + bottom = img.size[1] + right = img.size[0] + flap_h = bottom - top + draw = ImageDraw.Draw(img) + draw.rectangle((left, top, right, bottom), fill=(200, 200, 200, 50), outline=None) + # рисуем внешнюю рамку + draw.line((left, bottom-1, right, bottom-1), fill=(125, 125, 125), width=5) # нижняя + draw.line((left, top, right, top), fill=(125, 125, 125), width=5) # верхняя + draw.line((left, top, left, bottom), fill=(125, 125, 125), width=5) # левая + draw.line((right-1, top, right-1, bottom), fill=(125, 125, 125), width=5) # правая + + ############################################################ + # НАЧИНАЕМ ОТРИСОВКУ СТВОРОК ОКНА НА КРТИНКУ + ############################################################ + local_top = top + local_bottom = top + for i in dim_flap: # цикл по рядам створок + local_bottom += i["vRatio"]*flap_h/v_ratio_max + local_right = 0 + local_left = 0 + for j in i["row"]: + local_right += j["hRatio"]*right/h_ratio_max + # отрисовка схему открывания створки + if "X" in j["flap"] or "x" in j["flap"] or "х" in j["flap"] or "Х" in j["flap"] or "+" in j["flap"]: + # глухое окно (рисуем крестик) + draw.line(((local_right + local_left) / 2 - 5, (local_bottom + local_top) / 2, + (local_right + local_left) / 2 + 5, (local_bottom + local_top)/2), + fill=(105, 105, 225), width=1) + draw.line(((local_right + local_left) / 2, (local_bottom + local_top) / 2 - 5, + (local_right + local_left) / 2, (local_bottom + local_top) / 2 + 5), + fill=(105, 105, 225), width=1) + if "V" in j["flap"]: # откидное открывание + draw.line((local_right - 3, local_bottom - 4, (local_right + local_left) / 2, local_top + 3), + fill=(125, 225, 125), width=1) + draw.line((local_left + 3, local_bottom - 4, (local_right + local_left) / 2, local_top + 3), + fill=(125, 225, 125), width=1) + if ">" in j["flap"] or "G" in j["flap"]: # поворотное влево + draw.line((local_left + 3, local_top + 3, local_right - 3, (local_bottom + local_top) / 2), + fill=(225, 125, 125), width=1) + draw.line((local_left + 3, local_bottom - 3, local_right - 3, (local_bottom + local_top) / 2), + fill=(225, 125, 125), width=1) + if "<" in j["flap"] or "L" in j["flap"]: # поворотное вправо + draw.line((local_right - 3, local_bottom - 3, local_left + 3, (local_bottom + local_top) / 2), + fill=(225, 125, 125), width=1) + draw.line((local_right - 3, local_top + 3, local_left + 3, (local_bottom+local_top) / 2), + fill=(225, 125, 125), width=1) + + # Отрисовка створки. ПЕРИМЕТР + draw.line((local_left, local_bottom, local_right, local_bottom), fill=(125, 125, 125), width=3) + draw.line((local_left, local_top, local_right, local_top), fill=(125, 125, 125), width=3) + draw.line((local_left, local_top, local_left, local_bottom), fill=(125, 125, 125), width=3) + draw.line((local_right, local_top, local_right, local_bottom), fill=(125, 125, 125), width=3) + local_left = local_right + local_top = local_bottom + del draw + # сохраняем картинку + img.save(path_to_img_file) + return + diff --git a/oknardia/web/catalog.py b/oknardia/web/catalog.py index fee7d49..c6e1916 100644 --- a/oknardia/web/catalog.py +++ b/oknardia/web/catalog.py @@ -7,7 +7,7 @@ from django.utils import timezone from oknardia.settings import * from oknardia.models import PVCprofiles, Seria_Info, Win_MountDim, Building_Info from web.report1 import get_last_all_user_visit_list, get_last_user_visit_cookies, get_last_user_visit_list -from web.add_func import normalize, get_rating_set_for_stars, get_flaps_for_big_pictures +from web.add_func import normalize, get_rating_set_for_stars, get_flaps_for_big_pictures, make_flap_mini_pictures import time import json import random @@ -809,3 +809,85 @@ def seria_info_geo_code(seria_id: str = '12') -> dict: "CONDITION_MIN": condition_min}) # print(seria_to_geo) return data_return + + +def standard_opening(request: HttpRequest) -> HttpResponse: + time_start = time.time() + to_template = {} # словарь, для передачи шаблону + q_seria = Seria_Info.objects.raw('SELECT oknardia_seria_info.id, oknardia_seria_info.sName ' + 'FROM oknardia_seria_info ' + 'WHERE oknardia_seria_info.id = oknardia_seria_info.kRoot_id ' + 'ORDER BY oknardia_seria_info.sName;') + to_template.update({'SERIAS': list(q_seria)}) + q_win_opening = Win_MountDim.objects.raw( + 'SELECT oknardia_win_mountdim.*,' + ' oknardia_seria_info.sName,' + ' oknardia_seria_info.id AS ID_Seria ' + 'FROM oknardia_win_mountdim' + ' INNER JOIN oknardia_mountdim2apartment' + ' ON oknardia_win_mountdim.id = oknardia_mountdim2apartment.kMountDim_id' + ' RIGHT OUTER JOIN oknardia_apartment_type' + ' ON oknardia_apartment_type.id = oknardia_mountdim2apartment.kApartment_id' + ' RIGHT OUTER JOIN oknardia_seria_info' + ' ON oknardia_apartment_type.kSeria_id = oknardia_seria_info.id ' + 'WHERE oknardia_seria_info.id = oknardia_seria_info.kRoot_id ' + 'GROUP BY oknardia_win_mountdim.iWinWidth, oknardia_win_mountdim.iWinHight,' + ' oknardia_win_mountdim.bIsDoor, oknardia_win_mountdim.bIsNearDoor,' + ' oknardia_win_mountdim.sFlapConfig, oknardia_win_mountdim.id,' + ' oknardia_seria_info.sName, oknardia_seria_info.id ' + 'ORDER BY oknardia_win_mountdim.iWinWidth DESC,' + ' oknardia_win_mountdim.iWinHight DESC,' + ' oknardia_win_mountdim.bIsNearDoor,' + ' oknardia_win_mountdim.bIsDoor,' + ' oknardia_win_mountdim.id,' + ' oknardia_seria_info.sName;') + list_windows_opening = [] + tmp_id = 0 + for i in q_win_opening: + if tmp_id != i.id: + tmp_id = i.id + image_file_name = i.sFlapConfig + image_file_name = image_file_name.replace(">", u"G") + image_file_name = image_file_name.replace("<", "L") + image_file_name = image_file_name.replace("|", "I") + image_file_name = image_file_name.replace("[", "(") + image_file_name = image_file_name.replace("]", ")") + image_file_name = image_file_name.replace("/", "-") + image_file_name = image_file_name.replace("\\", "-") + image_file_name = image_file_name.replace(".", "-") + u".png" + image_file_name = f"{PATH_FOR_IMG}/{PATH_FOR_IMGFLAPCONFIG}/{image_file_name}" + if not os.path.isfile(f"{STATIC_BASE_PATH}/{image_file_name}"): + make_flap_mini_pictures(f"{STATIC_BASE_PATH}/{image_file_name}", i.sFlapConfig, i.bIsDoor) + list_windows_opening.append({ + "ID": i.id, + "INCLUDING_IN_SERIA": [{ + "ID": i.ID_Seria, + "NAME_T": pytils.translit.slugify(i.sName), + "NAME": i.sName + }], + "INCLUDING_IN_SERIA_ID": [], + "URL2IMG": image_file_name, + "FLAP_CONFIG": i.sFlapConfig, + "DESCRIPTION": i.sDescripion.split(" для")[0].split(" (")[0], + "DESCRIPTION_L": i.sDescripion, + "IS_DOOR": i.bIsDoor, + "IS_NEAR_DOOR": i.bIsNearDoor, + "H": i.iWinHight * 10, + "W": i.iWinWidth * 10 + }) + else: + list_windows_opening[-1]["INCLUDING_IN_SERIA"].append({ + "ID": i.ID_Seria, + "NAME_T": pytils.translit.slugify(i.sName), + "NAME": i.sName + }) + to_template.update({ + 'LIST_WIN_OPENING': list_windows_opening, + # получаем последние визиты клиента через куки + 'LAST_VISIT': get_last_user_visit_list(get_last_user_visit_cookies(request)[:3]), + # получаем последние визиты всех посетителей из базы + # id2log, log_visit = get_last_all_user_visit_list() + 'LOG_VISIT': get_last_all_user_visit_list(), + 'ticks': float(time.time() - time_start) + }) + return render(request, "catalog/catalog_standard_opening.html", to_template)