Compare commits
96 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 19a595fb10 | |||
| 917d62cc21 | |||
| 71b5089a61 | |||
| 9e27089638 | |||
| af67b69418 | |||
| af2489f923 | |||
| 0b6536b8f4 | |||
| c930e059a0 | |||
| c0b41cd866 | |||
| b348c8fe81 | |||
| e7da2cdeb9 | |||
| d5719015b0 | |||
| bcc10de4d4 | |||
| 55f9a74231 | |||
| 49c19d9f92 | |||
| 67a8c093f5 | |||
| e0a5a5739b | |||
| 3e67d6cf71 | |||
| 917bcb42c8 | |||
| 5bdb97f5e8 | |||
| e2091b72b1 | |||
| 446cbe8c5c | |||
| bdca8dfc6a | |||
| 111dd7bd33 | |||
| 57a522f4b7 | |||
| 2b37f709a9 | |||
| f480dc3666 | |||
| 2da036e4e0 | |||
| 28620ce2a9 | |||
| 574ae84321 | |||
| 796cb89525 | |||
| 0e8839bf18 | |||
| dbd622e456 | |||
| 741dd2685e | |||
| c01873144e | |||
| 8387d36abf | |||
| 2bc0869104 | |||
| 8c7972178c | |||
| c338a17dd8 | |||
| 3cc4ae39f7 | |||
| d789b2443a | |||
| 25beecdf60 | |||
| 5eb2f304a3 | |||
| 0246c1de8c | |||
| 4196cd64d8 | |||
| 60b6582f1b | |||
| 4a91928bc7 | |||
| b322331366 | |||
| e041110059 | |||
| ae1b851db7 | |||
| 28aa35d617 | |||
| b296ad79e9 | |||
| fbea58b1c4 | |||
| 30084dd6ac | |||
| c961b64036 | |||
| ad74f0a51e | |||
| 78ec6077b6 | |||
| c68fa5be07 | |||
| ee1dd31d54 | |||
| 6066e5df29 | |||
| 8704f4125b | |||
| 2777f3fde2 | |||
| 4b9ca319f9 | |||
| 56d7af5c9d | |||
| 0368c1c34e | |||
| fbdf95b66f | |||
| 8fdaf6935e | |||
| 8272bdb25f | |||
| 6a4c315cdc | |||
| f2c89abe1c | |||
| 37a605ef09 | |||
| 28a680fdf1 | |||
| 9bcbc73602 | |||
| 8ca1f5b36e | |||
| 6c4dcd1cb7 | |||
| 5a38181cd3 | |||
| 5738ee9c9e | |||
| 9535424e6a | |||
| 4e03fead67 | |||
| 5de28c8bfb | |||
| de45931ff4 | |||
| d27d0e7173 | |||
| f3a8a65afe | |||
| 72b71c7810 | |||
| 6bd8143d83 | |||
| a970b7109b | |||
| 99b8ba80d5 | |||
| 7cc438d1c5 | |||
| 034ec20c26 | |||
| 90ddc0d88c | |||
| 6e92eca67a | |||
| 6a9c0e4568 | |||
| 265732bae8 | |||
| cded4e407e | |||
| f996dd891e | |||
| 748a1882e5 |
+30
-13
@@ -1,5 +1,6 @@
|
||||
# Django Configuration Example
|
||||
# Копируйте этот файл в .env.local и заполните реальные значения
|
||||
# Все настройки читаются из переменных окружения (DEV/PROD без распознавания хоста)
|
||||
# Для локальной разработки можно скопировать файл в .env.local и экспортировать его.
|
||||
|
||||
# ============================================================================
|
||||
# DJANGO
|
||||
@@ -15,19 +16,35 @@ DEBUG=False
|
||||
# Допустимые хосты (разделены запятой без пробелов)
|
||||
ALLOWED_HOSTS=localhost,127.0.0.1,yourdomain.com
|
||||
|
||||
# Базовый публичный URL сайта (используется для абсолютных URL в sitemap.xml)
|
||||
SITE_BASE_URL=https://yourdomain.com
|
||||
|
||||
# Админы для email-оповещений Django (формат: Имя:email,Имя2:email2)
|
||||
ADMINS=Admin:admin@example.com
|
||||
|
||||
# ============================================================================
|
||||
# DATABASE
|
||||
# ============================================================================
|
||||
|
||||
# Database backend (по умолчанию mysql)
|
||||
DATABASE_ENGINE=django.db.backends.mysql
|
||||
# Database backend (по умолчанию SQLite)
|
||||
DATABASE_ENGINE=django.db.backends.sqlite3
|
||||
|
||||
# Database connection
|
||||
DATABASE_HOST=localhost
|
||||
DATABASE_PORT=3306
|
||||
DATABASE_NAME=django_oknardia
|
||||
DATABASE_USER=web
|
||||
DATABASE_PASSWORD=your-db-password-here
|
||||
# Имя/путь базы данных:
|
||||
# - для SQLite: только имя файла (полный путь соберется в settings.py через PROJECT_ROOT/database)
|
||||
# - для MySQL/MariaDB: имя базы
|
||||
DATABASE_NAME=oknadria.sqlite3
|
||||
|
||||
# Для MySQL/MariaDB (используются, если DATABASE_ENGINE=django.db.backends.mysql)
|
||||
# DATABASE_HOST=localhost
|
||||
# DATABASE_PORT=3306
|
||||
# DATABASE_USER=name-for-db-user
|
||||
# DATABASE_PASSWORD=your-db-password-here
|
||||
|
||||
# Пути вычисляются автоматически внутри settings.py от PROJECT_ROOT
|
||||
TOUCH_RELOAD=/app/logs/touch-reload.txt
|
||||
|
||||
# Подкаталог в MEDIA_ROOT, где хранится кеш sitemap-файлов
|
||||
SITEMAP_SUBDIR=_serv_sitemap
|
||||
|
||||
# ============================================================================
|
||||
# EMAIL
|
||||
@@ -40,6 +57,7 @@ EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
|
||||
EMAIL_HOST=smtp.example.com
|
||||
EMAIL_PORT=587
|
||||
EMAIL_USE_TLS=True
|
||||
EMAIL_USE_SSL=False
|
||||
EMAIL_HOST_USER=your-email@example.com
|
||||
EMAIL_HOST_PASSWORD=your-email-password
|
||||
|
||||
@@ -100,7 +118,7 @@ LOG_LEVEL=INFO
|
||||
# ============================================================================
|
||||
|
||||
# 1. Скопируйте этот файл:
|
||||
# cp .env.example .env.local
|
||||
# cp .env.sample .env.local
|
||||
#
|
||||
# 2. Отредактируйте значения в .env.local:
|
||||
# nano .env.local
|
||||
@@ -108,9 +126,8 @@ LOG_LEVEL=INFO
|
||||
# 3. Убедитесь, что .env.local в .gitignore:
|
||||
# grep ".env" .gitignore
|
||||
#
|
||||
# 4. Используйте python-dotenv для загрузки переменных в settings.py:
|
||||
# from dotenv import load_dotenv
|
||||
# load_dotenv()
|
||||
# 4. Экспортируйте переменные перед запуском Django:
|
||||
# set -a; source .env.local; set +a
|
||||
#
|
||||
# ВАЖНО:
|
||||
# - НИКОГДА не коммитьте .env.local или файлы с реальными значениями в git!
|
||||
|
||||
+32
-1
@@ -132,4 +132,35 @@ venv.bak/
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
.pyre/
|
||||
|
||||
# MacOS specific files
|
||||
.DS_Store
|
||||
|
||||
# Database dumps and backups (CRITICAL - NEVER commit production data!)
|
||||
SQL/
|
||||
*.sql
|
||||
*.dump
|
||||
*.backup
|
||||
*.sql.gz
|
||||
db.json
|
||||
db.json.zip
|
||||
|
||||
# API keys, certificates, and credentials
|
||||
*.key
|
||||
*.pem
|
||||
*.p12
|
||||
*.p8
|
||||
*.crt
|
||||
*.cert
|
||||
|
||||
# IDE and editor specific
|
||||
.vscode/settings.json
|
||||
.idea/vcs.xml
|
||||
.idea/inspectionProfiles/
|
||||
|
||||
# Project specific ignore patterns
|
||||
.github/
|
||||
.log/
|
||||
.logs/
|
||||
sitemap*.xml
|
||||
|
||||
@@ -213,6 +213,7 @@ python manage.py collectstatic # собрать статику для
|
||||
5. **Foreign Key ON_DELETE**: используется в основном `DO_NOTHING` и `SET_NULL`, будь осторожен при удалении
|
||||
6. **Двойной хост**: убедись, что используешь правильные переменные из `my_secret.py` для текущей машины
|
||||
7. **Индексирование БД**: большинство полей для поиска уже имеют `db_index=True`, но проверь при добавлении фильтров
|
||||
8. **SEO-даты и свежесть контента**: при переделке вьюх/шаблонов отдельно проверяй, нужны ли ещё `last_update`, `PUB_DAT`, `Date4Meta` и `Last4Meta`; если дата не участвует в смысловой логике страницы, лучше оставить базовые `{% now %}` из `base.html`, а не тащить лишний контекст во вьюху и не нагружать бекенд.
|
||||
|
||||
## Реферальные ссылки (для более глубокого изучения)
|
||||
|
||||
|
||||
@@ -1,6 +1,40 @@
|
||||
# Оконный агрегатор «Окнардия»
|
||||
### Переделка под Python 3.8 и Django 4.1
|
||||
### Переделка под Python 3.12 и Django 5.2
|
||||
|
||||
### Актуальная памятка дорожная карта
|
||||
|
||||
#### Готово:
|
||||
|
||||
* Изменена база данных используемая в проекте (SQLite вместо MariaDB).
|
||||
* Окружение проекта теперь настраивается через `poetry` вместо `pip` и `requirements.txt`.
|
||||
* Проект получает настройки и секреты через переменные окружения (`.env`) вместо `my_secret*.py`.
|
||||
* Рефакторинг создания `sitemap.xml`: raw ⟶ ORM, создание через Django-команду `generate_sitemaps` в медиа-файлы.
|
||||
* Рефакторинг URL `/catalog/profil/`: raw SQL ⟶ ORM, убран `last_update`, измененs SEO `description` и `keywords`.
|
||||
* Распилен `oknardia/web/catalog.py` на тематические модули (`catalog_companies.py`, `catalog_profiles.py`, `catalog_series.py`, `catalog_openings.py`) с вынесением общей логики в `catalog_utils.py`; маршруты обновлены без изменения внешних URL.
|
||||
* Рефакторинг `catalog_profile_model` (`/catalog/profile/...`): raw SQL ⟶ ORM, упрощена логика, вынесены helper-функции, сокращено дублирование расчёта цветов рейтинга, нормализована подготовка `LIST_OTHER`/`MERCHANTS`/`PROFILES`/`PROFILE_DETAIL`, сохранена совместимость шаблонов.
|
||||
* Рефакторинг `catalog_profile_manufacture` (`/catalog/profile/<id>-<manufacturer>`): упрощена валидация URL, убран дублирующий код маппинга для `PROFILES` и `MERCHANTS` через общие хелперы, стандартизирован хвост контекста (`LAST_VISIT`, `LOG_VISIT`, `ticks`) через `_append_visit_context`.
|
||||
|
||||
#### Планы, задачи, маркеры и идеи на будущее:
|
||||
|
||||
* Переделать все raw SQL-запросы на ORM (для перехода на SQLite и для лучшей поддержки разных СУБД в будущем).
|
||||
* Для легаси-страниц (шаблоны и вьюхи) поэтапно проверять (если нужно убирать) старые SEO-хвосты вроде `last_update` / `PUB_DAT` / `Date4Meta` / `Last4Meta`: если дата не несёт смысловой нагрузки, лучше оставлять базовые `{% now %}` из `base.html`, а не тащить лишний контекст во вьюху.
|
||||
* Шаблоны `report/report_last_user_visit.html` и `report/report_log_user_visit.html` сделать с конентом
|
||||
подгружаемым через AJAX (использовать HTMX, напрмемер) и убрать вызовы `get_last_user_visit_list` и `get_last_all_user_visit_list` их соответствующих вьюх. Это должно разгрузить бекенд и, возможно, сделать кеширование.
|
||||
* Упаковать всё в контейнеры (Django + Gunicorn + WhiteNoise...
|
||||
|
||||
|
||||
См. также:
|
||||
|
||||
* [`AGENTS.md`](AGENTS.md) – контекст проекта для AI-ассистентов (архитектура, конвенции, рабочие сценарии).
|
||||
* [`SETUP.md`](SETUP.md) – пошаговая настройка окружения, запуск проекта и базовые команды разработки.
|
||||
* Сервисные утилиты:
|
||||
- [`SITEMAP_RUNBOOK.md`](SITEMAP_RUNBOOK.md) – sitemap (генерация, веса, cron, nginx)
|
||||
|
||||
|
||||
|
||||
---
|
||||
Легаси-материалы старого README, которые могут быть полезны для понимания устройства проекта и его
|
||||
администрирования, а также для будущей реорганизации документации.
|
||||
|
||||
### Немного о механике кеширования:
|
||||
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
# SITEMAP_RUNBOOK.md
|
||||
|
||||
## Что изменено
|
||||
|
||||
- Генерация sitemap выполняется только через custom management command: `generate_sitemaps`.
|
||||
- Генерация через интерфейс `/service/*` и URL-роуты удалена.
|
||||
- Файлы sitemap хранятся в media-каталоге: `MEDIA_ROOT/_serv_sitemap`.
|
||||
- `robots.txt` указывает на `https://oknardia.ru/media/_serv_sitemap/sitemap.xml`.
|
||||
- Глубина `compare_offers` по-молчанию ограничена диапазоном `2..4`.
|
||||
- В `lastmod` записывается только дата (`YYYY-MM-DD`), без времени.
|
||||
|
||||
## Что сейчас входит в sitemap
|
||||
|
||||
- главная страница `/`;
|
||||
- список и карточки блога (`/blog/Pn`, `/blogpost/...`);
|
||||
- каталог профилей: корень, производители и карточки моделей;
|
||||
- каталог серий домов и детальные страницы типовых серий;
|
||||
- каталог оконных компаний и карточки брендов;
|
||||
- каталог стандартных оконных проёмов;
|
||||
- страница рейтинга профилей;
|
||||
- страницы цен по адресам и по одиночным проёмам;
|
||||
- страницы `compare_offers` (с `changefreq=monthly` и пониженным приоритетом).
|
||||
|
||||
## Ручной запуск
|
||||
|
||||
Из каталога `oknardia/`:
|
||||
|
||||
```bash
|
||||
poetry run python manage.py generate_sitemaps
|
||||
```
|
||||
|
||||
С явными параметрами:
|
||||
|
||||
```bash
|
||||
poetry run python manage.py generate_sitemaps \
|
||||
--compare-min-depth 2 \
|
||||
--compare-max-depth 4 \
|
||||
--max-items 40000 \
|
||||
--max-file-size 5242880 \
|
||||
--max-files-qty 998
|
||||
```
|
||||
|
||||
## Параметры команды
|
||||
|
||||
- `--compare-min-depth` — минимальная глубина комбинаций `compare_offers` (по умолчанию `2`).
|
||||
- `--compare-max-depth` — максимальная глубина комбинаций `compare_offers` (по умолчанию `4`).
|
||||
- `--max-items` — лимит URL в одном sitemap-файле (по умолчанию `40000`).
|
||||
- `--max-file-size` — лимит размера sitemap-файла в байтах (по умолчанию `5242880`).
|
||||
- `--max-files-qty` — лимит количества вложенных sitemap-файлов (по умолчанию `998`).
|
||||
|
||||
## Важные переменные окружения
|
||||
|
||||
- `SITE_BASE_URL` — базовый URL сайта (например, `https://oknardia.ru`).
|
||||
- `SITEMAP_SUBDIR` — подкаталог в `MEDIA_ROOT` для sitemap (по умолчанию `_serv_sitemap`).
|
||||
|
||||
## Что добавить в контейнер
|
||||
|
||||
Минимально (после миграций и перед запуском веб-процесса):
|
||||
|
||||
```bash
|
||||
poetry run python manage.py generate_sitemaps || true
|
||||
```
|
||||
|
||||
> `|| true` можно убрать, если хотите падать при любой ошибке генерации.
|
||||
|
||||
## Вариант для расписания (когда определитесь)
|
||||
|
||||
Можно запускать команду по расписанию любым внешним scheduler:
|
||||
|
||||
```bash
|
||||
poetry run python manage.py generate_sitemaps
|
||||
```
|
||||
|
||||
- через cron хоста,
|
||||
- или через отдельный scheduler-контейнер.
|
||||
|
||||
### Пример внешнего cron на хосте
|
||||
|
||||
Пример строки для `crontab -e` на хост-машине (запуск раз в 3 дня в 03:30) с явным именем контейнера `oknarida-backend`:
|
||||
|
||||
```bash
|
||||
30 3 */3 * * /usr/bin/docker exec -i oknarida-backend /bin/sh -lc 'cd /app/oknardia && poetry run python manage.py generate_sitemaps --compare-min-depth 2 --compare-max-depth 4 --max-items 40000 --max-file-size 5242880 --max-files-qty 998' >> /var/log/oknardia-sitemap.log 2>&1
|
||||
```
|
||||
|
||||
> Если путь проекта внутри контейнера отличается от `/app/oknardia`, просто замени `cd /app/oknardia` на фактический путь.
|
||||
|
||||
## Прокси/NGINX
|
||||
|
||||
Можно хранить физические файлы в media-volume и при этом проксировать/алиасить корневой URL `sitemap.xml` на файл из `media/_serv_sitemap`.
|
||||
|
||||
Допустимо, что файл доступен по двум URL (корневой и media), но в `robots.txt` должен быть указан один канонический вариант.
|
||||
|
||||
### NGINX snippet (alias для корневого sitemap)
|
||||
|
||||
```nginx
|
||||
# Корневой sitemap.xml (для привычного для поисковиков URL)
|
||||
location = /sitemap.xml {
|
||||
alias /<путь-к-каталогку-с-докер-приложением>/media/_serv_sitemap/sitemap.xml;
|
||||
default_type application/xml;
|
||||
add_header Cache-Control "public, max-age=300";
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,3 @@
|
||||
# Это папака для хранения базы данных SQLite, не должна быть в репозитории.
|
||||
*.*
|
||||
*
|
||||
@@ -1 +0,0 @@
|
||||
1
|
||||
@@ -1,185 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
ШАБЛОН для my_secret.py
|
||||
|
||||
ИНСТРУКЦИЯ: скопируйте этот файл в my_secret.py и заполните реальные значения.
|
||||
|
||||
Пример:
|
||||
cp oknardia/oknardia/my_secret.py.template oknardia/oknardia/my_secret.py
|
||||
# затем отредактируйте значения в my_secret.py
|
||||
|
||||
ВАЖНО: my_secret.py НИКОГДА не должен быть в git!
|
||||
Используйте .gitignore для исключения файла.
|
||||
"""
|
||||
|
||||
# ============================================================================
|
||||
# РАЗРАБОТКА (DEV) - Хосты и сетевые настройки
|
||||
# ============================================================================
|
||||
|
||||
# Хосты на которых может работать приложение (разработка)
|
||||
MY_ALLOWED_HOSTS = [
|
||||
'127.0.0.1',
|
||||
'localhost',
|
||||
'your-dev-hostname.local', # ИЗМЕНИТЕ на ваше имя хоста
|
||||
]
|
||||
|
||||
# Допустимые хосты для разработки
|
||||
MY_HOST_HOME1 = 'your-dev-hostname-windows' # ИЗМЕНИТЕ
|
||||
MY_HOST_HOME2 = 'your-dev-hostname-mac' # ИЗМЕНИТЕ
|
||||
MY_HOST_DEV = [MY_HOST_HOME1, MY_HOST_HOME2]
|
||||
|
||||
# Хосты для продакшена (заполнять с осторожностью)
|
||||
MY_HOST_PROD = [] # На продакшене используйте переменные окружения!
|
||||
|
||||
# ============================================================================
|
||||
# БЕЗОПАСНОСТЬ - Django SECRET_KEY
|
||||
# ============================================================================
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
# Сгенерируйте новый ключ с помощью:
|
||||
# python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())'
|
||||
MY_SECRET_KEY = 'ЗАПОЛНИТЕ_СЛУЧАЙНОЙ_СТРОКОЙ_БОЛЬШОЙ_ДЛИНЫ'
|
||||
|
||||
# ============================================================================
|
||||
# АДМИНИСТРАТОРЫ - для оповещений об ошибках
|
||||
# ============================================================================
|
||||
|
||||
MY_ADMINS = (
|
||||
('Your Name', 'your-email@example.com'),
|
||||
('Admin Name', 'admin@example.com'),
|
||||
)
|
||||
|
||||
# ============================================================================
|
||||
# ПУТИ К ФАЙЛАМ - разработка
|
||||
# ============================================================================
|
||||
|
||||
# путь к каталогу media (статика, для web-сервера nginx или apache)
|
||||
MY_MEDIA_ROOT_DEV1 = 'M:\\path\\to\\your\\media\\' # Windows (если применимо)
|
||||
MY_MEDIA_ROOT_DEV2 = '/path/to/your/media/' # Mac/Linux - ИЗМЕНИТЕ!
|
||||
|
||||
# путь к каталогу static (статика, для web-сервера nginx или apache)
|
||||
MY_STATIC_ROOT_DEV1 = 'M:\\path\\to\\your\\static' # Windows (если применимо)
|
||||
MY_STATIC_ROOT_DEV2 = '/path/to/your/static' # Mac/Linux - ИЗМЕНИТЕ!
|
||||
|
||||
# путь для кэш-блоков шаблонов
|
||||
MY_STATIC_BASE_PATH_DEV1 = MY_STATIC_ROOT_DEV1
|
||||
MY_STATIC_BASE_PATH_DEV2 = MY_STATIC_ROOT_DEV2
|
||||
|
||||
# путь для sitemap файлов
|
||||
MY_SITEMAP_ROOT_DEV1 = 'M:\\path\\to\\your\\public\\' # Windows (если применимо)
|
||||
MY_SITEMAP_ROOT_DEV2 = '/path/to/your/public/' # Mac/Linux - ИЗМЕНИТЕ!
|
||||
|
||||
# ============================================================================
|
||||
# ПУТИ К ФАЙЛАМ - продакшен
|
||||
# ============================================================================
|
||||
|
||||
MY_MEDIA_ROOT_PROD = '/home/web/oknardia-ru/public/media/' # ЗАПОЛНИТЕ!
|
||||
MY_STATIC_ROOT_PROD = '/home/web/oknardia-ru/public/static' # ЗАПОЛНИТЕ!
|
||||
MY_STATIC_BASE_PATH_PROD = MY_STATIC_ROOT_PROD
|
||||
MY_SITEMAP_ROOT_PROD = '/home/web/oknardia-ru/public/' # ЗАПОЛНИТЕ!
|
||||
|
||||
# ============================================================================
|
||||
# EMAIL - Почтовый сервер (разработка)
|
||||
# ============================================================================
|
||||
|
||||
# Email адреса для разработки
|
||||
MY_EMAIL_DEV = 'dev-email@example.com'
|
||||
MY_EMAIL_FROM_DEV = 'dev-email@example.com'
|
||||
MY_EMAIL_HOST_USER_DEV = 'your-email@smtp.example.com' # ЗАПОЛНИТЕ!
|
||||
MY_EMAIL_HOST_PASSWORD_DEV = 'YOUR_EMAIL_PASSWORD' # ЗАПОЛНИТЕ!
|
||||
MY_EMAIL_HOST_DEV = 'smtp.example.com' # ЗАПОЛНИТЕ! (например: smtp.mail.ru)
|
||||
MY_EMAIL_PORT_DEV = 587 # ЗАПОЛНИТЕ! (обычно 587 или 2525)
|
||||
|
||||
# ============================================================================
|
||||
# EMAIL - Почтовый сервер (продакшен)
|
||||
# ============================================================================
|
||||
|
||||
MY_EMAIL_PROD = MY_EMAIL_DEV
|
||||
MY_EMAIL_FROM_PROD = MY_EMAIL_FROM_DEV
|
||||
MY_EMAIL_HOST_USER_PROD = MY_EMAIL_HOST_USER_DEV # На продакшене используйте env переменные!
|
||||
MY_EMAIL_HOST_PASSWORD_PROD = MY_EMAIL_HOST_PASSWORD_DEV # На продакшене используйте env переменные!
|
||||
MY_EMAIL_HOST_PROD = MY_EMAIL_HOST_DEV
|
||||
MY_EMAIL_PORT_PROD = MY_EMAIL_PORT_DEV
|
||||
|
||||
# ============================================================================
|
||||
# БД MySQL/MariaDB - разработка
|
||||
# ============================================================================
|
||||
|
||||
MY_DATABASE_HOST_DEV1 = 'localhost' # Офисный сервер разработки - ИЗМЕНИТЕ!
|
||||
MY_DATABASE_HOST_DEV2 = 'localhost' # Домашний сервер разработки - ИЗМЕНИТЕ!
|
||||
|
||||
MY_DATABASE_NAME_DEV = 'django_oknardia_dev' # ИЗМЕНИТЕ если нужно
|
||||
MY_DATABASE_PORT_DEV = '3306' # Стандартный порт MySQL
|
||||
|
||||
MY_DATABASE_USER_DEV = 'web' # ИЗМЕНИТЕ если нужно
|
||||
MY_DATABASE_PASSWORD_DEV = 'YOUR_DB_PASSWORD' # ЗАПОЛНИТЕ!
|
||||
|
||||
# ============================================================================
|
||||
# БД MySQL/MariaDB - продакшен
|
||||
# ============================================================================
|
||||
|
||||
MY_DATABASE_HOST_PROD = 'localhost' # ЗАПОЛНИТЕ! (на продакшене)
|
||||
MY_DATABASE_NAME_PROD = 'django_oknardia_prod' # ЗАПОЛНИТЕ!
|
||||
|
||||
MY_DATABASE_PORT_PROD = '3306'
|
||||
MY_DATABASE_USER_PROD = 'web'
|
||||
|
||||
# ВНИМАНИЕ: На продакшене используйте переменные окружения или менеджер секретов!
|
||||
MY_DATABASE_PASSWORD_PROD = '' # ОСТАВЬТЕ ПУСТО! Используйте переменные окружения!
|
||||
|
||||
# ============================================================================
|
||||
# API ключи - Google Captcha
|
||||
# ============================================================================
|
||||
|
||||
# Получите ключи на https://www.google.com/recaptcha/admin
|
||||
# ВАЖНО: Никогда не коммитьте реальные ключи в git!
|
||||
# PRIVATE ключ - это СЕКРЕТ, держите его в безопасности!
|
||||
MY_CAPTCHA_PUBLIC_KEY = 'YOUR_CAPTCHA_PUBLIC_KEY_HERE' # ЗАПОЛНИТЕ!
|
||||
MY_CAPTCHA_PRIVATE_KEY = 'YOUR_CAPTCHA_PRIVATE_KEY_HERE' # ЗАПОЛНИТЕ! (СЕКРЕТ!)
|
||||
|
||||
# ============================================================================
|
||||
# API ключи - Yandex Maps
|
||||
# ============================================================================
|
||||
|
||||
# Получите ключ на https://developer.tech.yandex.ru/
|
||||
MY_YANDEX_MAPS_API_KEY = 'YOUR_YANDEX_MAPS_API_KEY'
|
||||
|
||||
# ============================================================================
|
||||
# uWSGI - Touch-reload файл (для перезагрузки при изменении кода)
|
||||
# ============================================================================
|
||||
|
||||
MY_TOUCH_RELOAD_DEV1 = 'M:\\path\\to\\touch-reload.txt' # Windows (если применимо)
|
||||
MY_TOUCH_RELOAD_DEV2 = '/path/to/logs/touch-reload.txt' # Mac/Linux - ИЗМЕНИТЕ!
|
||||
MY_TOUCH_RELOAD_PROD = '/home/web/oknardia-ru/logs/touch-reload.txt' # ЗАПОЛНИТЕ!
|
||||
|
||||
# ============================================================================
|
||||
# ИНСТРУКЦИЯ ПО ЗАПОЛНЕНИЮ
|
||||
# ============================================================================
|
||||
|
||||
"""
|
||||
1. СКОПИРУЙТЕ этот файл:
|
||||
cp oknardia/oknardia/my_secret.py.template oknardia/oknardia/my_secret.py
|
||||
|
||||
2. ОТРЕДАКТИРУЙТЕ значения, помеченные ИЗМЕНИТЕ! или ЗАПОЛНИТЕ!
|
||||
|
||||
3. УБЕДИТЕСЬ, что мой_secret.py в .gitignore:
|
||||
grep my_secret .gitignore
|
||||
|
||||
4. НИКОГДА не коммитьте my_secret.py в git!
|
||||
|
||||
5. На ПРОДАКШЕНЕ используйте переменные окружения:
|
||||
export DJANGO_SECRET_KEY="..."
|
||||
export DATABASE_PASSWORD="..."
|
||||
и т.д.
|
||||
|
||||
СОВЕТЫ:
|
||||
- Сгенерируйте новый SECRET_KEY с помощью Python:
|
||||
python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())'
|
||||
|
||||
- Используйте менеджер паролей (LastPass, 1Password, Vault) для хранения учетных данных
|
||||
|
||||
- Регулярно меняйте пароли БД и API ключи
|
||||
|
||||
- На продакшене используйте отдельные более сильные пароли
|
||||
"""
|
||||
|
||||
@@ -12,32 +12,49 @@ https://docs.djangoproject.com/en/4.1/ref/settings/
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
from oknardia.my_secret import *
|
||||
import socket
|
||||
import environ
|
||||
|
||||
|
||||
def _env_admins(raw_items: list[str]) -> tuple[tuple[str, str], ...]:
|
||||
# Формат: "Имя1:email1,Имя2:email2"
|
||||
admins: list[tuple[str, str]] = []
|
||||
for item in raw_items:
|
||||
if ":" not in item:
|
||||
continue
|
||||
admin_name, admin_email = item.split(":", maxsplit=1)
|
||||
admin_name = admin_name.strip()
|
||||
admin_email = admin_email.strip()
|
||||
if admin_name and admin_email:
|
||||
admins.append((admin_name, admin_email))
|
||||
return tuple(admins)
|
||||
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
PROJECT_ROOT = BASE_DIR.parent
|
||||
PUBLIC_ROOT = PROJECT_ROOT / 'public'
|
||||
STATIC_SOURCE_ROOT = PUBLIC_ROOT / 'static'
|
||||
|
||||
env = environ.Env()
|
||||
environ.Env.read_env(str(PROJECT_ROOT / '.env'))
|
||||
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = 'django-insecure-pd&1$j6z*1w#(j*16b+(@@#&2)+@x^^ot4)zqt-e67*1+$^qch'
|
||||
SECRET_KEY = env(
|
||||
'DJANGO_SECRET_KEY',
|
||||
default='django-insecure-pd&1$j6z*1w#(j*16b+(@@#&2)+@x^^ot4)zqt-e67*1+$^qch',
|
||||
)
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
# ПРЕДУПРЕЖДЕНИЕ БЕЗОПАСНОСТИ: не работайте в режиме DEBUG в продашене!
|
||||
if socket.gethostname() in MY_HOST_DEV:
|
||||
DEBUG = TEMPLATE_DEBUG = True
|
||||
else:
|
||||
# Все остальные хосты (подразумевается продакшн)
|
||||
DEBUG = TEMPLATE_DEBUG = True
|
||||
# DEBUG = TEMPLATE_DEBUG = False
|
||||
DEBUG = TEMPLATE_DEBUG = env.bool('DEBUG', default=False)
|
||||
|
||||
ALLOWED_HOSTS = MY_ALLOWED_HOSTS
|
||||
ALLOWED_HOSTS = env.list('ALLOWED_HOSTS', default=['127.0.0.1', 'localhost'])
|
||||
|
||||
# Настройки сообщений об ошибках когда все упало и т.п.
|
||||
ADMINS = MY_ADMINS
|
||||
ADMINS = _env_admins(env.list('ADMINS', default=[]))
|
||||
|
||||
|
||||
# Application definition
|
||||
@@ -51,7 +68,7 @@ INSTALLED_APPS = [
|
||||
'django.contrib.staticfiles',
|
||||
|
||||
'django.contrib.humanize',
|
||||
# 'django.contrib.sitemaps',
|
||||
'django.contrib.sitemaps',
|
||||
|
||||
'oknardia.apps.OknardiaConfig',
|
||||
'web.apps.WebConfig',
|
||||
@@ -67,6 +84,13 @@ MIDDLEWARE = [
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
]
|
||||
|
||||
# Разрешенные IP для отладки (нужно для django-debug-toolbar).
|
||||
INTERNAL_IPS = env.list('INTERNAL_IPS', default=['127.0.0.1', 'localhost'])
|
||||
|
||||
if DEBUG:
|
||||
INSTALLED_APPS += ['debug_toolbar']
|
||||
MIDDLEWARE = ['debug_toolbar.middleware.DebugToolbarMiddleware', *MIDDLEWARE]
|
||||
|
||||
ROOT_URLCONF = 'oknardia.urls'
|
||||
|
||||
TEMPLATES = [
|
||||
@@ -115,61 +139,75 @@ DATETIME_FORMAT = 'Y-m-d H:i:s'
|
||||
# Статические файлы (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/4.1/howto/static-files/
|
||||
|
||||
STATIC_URL = 'static/'
|
||||
MEDIA_URL = 'media/'
|
||||
STATIC_URL = '/static/'
|
||||
MEDIA_URL = '/media/'
|
||||
|
||||
|
||||
if socket.gethostname() in MY_HOST_DEV: # DEBUG: заменяем настройки прода, на настройки девопа
|
||||
MEDIA_ROOT = MY_MEDIA_ROOT_DEV1 if socket.gethostname() == MY_HOST_HOME1 else MY_MEDIA_ROOT_DEV2
|
||||
SITEMAP_ROOT = MY_SITEMAP_ROOT_DEV1 if socket.gethostname() == MY_HOST_HOME1 else MY_SITEMAP_ROOT_DEV2
|
||||
# STATIC_ROOT = MY_STATIC_ROOT_DEV1 if socket.gethostname() == MY_HOST_HOME1 else MY_STATIC_ROOT_DEV2
|
||||
STATICFILES_DIRS = [
|
||||
MY_STATIC_ROOT_DEV1 if socket.gethostname() == MY_HOST_HOME1 else MY_STATIC_ROOT_DEV2,
|
||||
]
|
||||
# путь к каталогу static (в эту переменную использовать для указания пути где будут делаться кэш-блоки для шаблонов)
|
||||
STATIC_BASE_PATH = MY_STATIC_BASE_PATH_DEV1 if socket.gethostname() == MY_HOST_HOME1 else MY_STATIC_BASE_PATH_DEV2
|
||||
MEDIA_ROOT = str(PUBLIC_ROOT / 'media')
|
||||
# STATIC_ROOT отделен от исходной статики, чтобы избежать staticfiles.E002.
|
||||
STATIC_ROOT = str(PUBLIC_ROOT / 'static_collected')
|
||||
|
||||
# Базовый URL сайта нужен для абсолютных URL в sitemap.xml.
|
||||
SITE_BASE_URL = env('SITE_BASE_URL', default='https://oknardia.ru').rstrip('/')
|
||||
# Файлы sitemap храним в media-volume, чтобы переживали пересоздание контейнера.
|
||||
SITEMAP_SUBDIR = env('SITEMAP_SUBDIR', default='_serv_sitemap').strip('/ ')
|
||||
SITEMAP_ROOT = str(Path(MEDIA_ROOT) / SITEMAP_SUBDIR)
|
||||
SITEMAP_URL_PREFIX = f"{MEDIA_URL.rstrip('/')}/{SITEMAP_SUBDIR}"
|
||||
SITEMAP_INDEX_URL = f"{SITE_BASE_URL}{SITEMAP_URL_PREFIX}/sitemap.xml"
|
||||
|
||||
# Каталоги, откуда Django читает исходную статику в DEBUG-режиме.
|
||||
STATICFILES_DIRS = [
|
||||
str(STATIC_SOURCE_ROOT)
|
||||
] if STATIC_SOURCE_ROOT.is_dir() else []
|
||||
|
||||
# Путь к каталогу static для генерации кэш-файлов и служебных JS.
|
||||
STATIC_BASE_PATH = str(STATIC_SOURCE_ROOT)
|
||||
|
||||
database_engine = env('DATABASE_ENGINE', default='django.db.backends.sqlite3')
|
||||
if database_engine == 'django.db.backends.sqlite3':
|
||||
# Для SQLite принимаем только имя файла из env и кладем БД в PROJECT_ROOT/database.
|
||||
sqlite_db_filename = Path(env('DATABASE_NAME', default='oknadria.sqlite3')).name
|
||||
sqlite_db_path = PROJECT_ROOT / 'database' / sqlite_db_filename
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': "django.db.backends.mysql",
|
||||
'HOST': MY_DATABASE_HOST_DEV1 if socket.gethostname() == MY_HOST_HOME1 else MY_DATABASE_HOST_DEV2,
|
||||
'PORT': MY_DATABASE_PORT_DEV, # Set to "" for default. Not used with sqlite3.
|
||||
'NAME': MY_DATABASE_NAME_DEV, # Not used with sqlite3.
|
||||
'USER': MY_DATABASE_USER_DEV, # Not used with sqlite3.
|
||||
'PASSWORD': MY_DATABASE_PASSWORD_DEV, # Not used with sqlite3.
|
||||
# 'OPTIONS': { 'autocommit': True, }
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': str(sqlite_db_path),
|
||||
}
|
||||
}
|
||||
TOUCH_RELOAD = MY_TOUCH_RELOAD_DEV1 if socket.gethostname() == MY_HOST_HOME1 else MY_TOUCH_RELOAD_DEV2
|
||||
else:
|
||||
MEDIA_ROOT = MY_MEDIA_ROOT_PROD
|
||||
# STATICFILES_DIRS = [MY_STATIC_ROOT_PROD1, ]
|
||||
STATIC_ROOT = MY_STATIC_ROOT_PROD
|
||||
SITEMAP_ROOT = MY_SITEMAP_ROOT_PROD
|
||||
# путь к каталогу static (в эту переменную использовать для указания пути где будут делаться кэш-блоки для шаблонов)
|
||||
STATIC_BASE_PATH = MY_STATIC_BASE_PATH_PROD
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': "django.db.backends.mysql",
|
||||
'HOST': MY_DATABASE_HOST_PROD, # Set to "" for localhost. Not used with sqlite3.
|
||||
'PORT': MY_DATABASE_PORT_PROD, # Set to "" for default. Not used with sqlite3.
|
||||
'NAME': MY_DATABASE_NAME_PROD, # Not used with sqlite3.
|
||||
'USER': MY_DATABASE_USER_PROD, # Not used with sqlite3.
|
||||
'PASSWORD': MY_DATABASE_PASSWORD_PROD, # Not used with sqlite3.
|
||||
# 'OPTIONS': { 'autocommit': True, }
|
||||
'ENGINE': database_engine,
|
||||
'HOST': env('DATABASE_HOST', default='localhost'),
|
||||
'PORT': env('DATABASE_PORT', default='3306'),
|
||||
'NAME': env('DATABASE_NAME', default=''),
|
||||
'USER': env('DATABASE_USER', default=''),
|
||||
'PASSWORD': env('DATABASE_PASSWORD', default=''),
|
||||
}
|
||||
}
|
||||
TOUCH_RELOAD = MY_TOUCH_RELOAD_PROD
|
||||
|
||||
TOUCH_RELOAD = env('TOUCH_RELOAD', default='')
|
||||
|
||||
#########################################
|
||||
# настройки для почтового сервера (они одинаковые для DEV и PROD)
|
||||
EMAIL_HOST = MY_EMAIL_HOST_DEV
|
||||
EMAIL_PORT = MY_EMAIL_PORT_DEV
|
||||
EMAIL_HOST_USER = MY_EMAIL_HOST_USER_DEV
|
||||
EMAIL_HOST_PASSWORD = MY_EMAIL_HOST_PASSWORD_DEV
|
||||
SERVER_EMAIL = DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
|
||||
EMAIL_USE_TLS = True
|
||||
EMAIL_BACKEND = env(
|
||||
'EMAIL_BACKEND',
|
||||
default='django.core.mail.backends.smtp.EmailBackend',
|
||||
)
|
||||
EMAIL_HOST = env('EMAIL_HOST', default='localhost')
|
||||
EMAIL_PORT = env.int('EMAIL_PORT', default=25)
|
||||
EMAIL_HOST_USER = env('EMAIL_HOST_USER', default='')
|
||||
EMAIL_HOST_PASSWORD = env('EMAIL_HOST_PASSWORD', default='')
|
||||
EMAIL_USE_TLS = env.bool('EMAIL_USE_TLS', default=True)
|
||||
EMAIL_USE_SSL = env.bool('EMAIL_USE_SSL', default=False)
|
||||
DEFAULT_FROM_EMAIL = env('DEFAULT_FROM_EMAIL', default=EMAIL_HOST_USER)
|
||||
SERVER_EMAIL = env('SERVER_EMAIL', default=DEFAULT_FROM_EMAIL)
|
||||
EMAIL_SUBJECT_PREFIX = 'OKNARDIA ERR: ' # префикс для оповещений об ошибках и необработанных исключениях
|
||||
|
||||
SECURE_SSL_REDIRECT = env.bool('SECURE_SSL_REDIRECT', default=False)
|
||||
SESSION_COOKIE_SECURE = env.bool('SESSION_COOKIE_SECURE', default=False)
|
||||
CSRF_COOKIE_SECURE = env.bool('CSRF_COOKIE_SECURE', default=False)
|
||||
|
||||
|
||||
# Default primary key field type
|
||||
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
|
||||
@@ -177,8 +215,8 @@ EMAIL_SUBJECT_PREFIX = 'OKNARDIA ERR: ' # префикс для оповещ
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||
|
||||
# ключи для Google Captha
|
||||
CAPTCHA_PUBLIC_KEY = MY_CAPTCHA_PUBLIC_KEY
|
||||
CAPTCHA_PRIVATE_KEY = MY_CAPTCHA_PRIVATE_KEY
|
||||
CAPTCHA_PUBLIC_KEY = env('CAPTCHA_PUBLIC_KEY', default='')
|
||||
CAPTCHA_PRIVATE_KEY = env('CAPTCHA_PRIVATE_KEY', default='')
|
||||
|
||||
# количество коммерческих предложений во фреме отчета
|
||||
OFFER_PER_FRAME = 5
|
||||
@@ -272,4 +310,4 @@ CATALOG_SORTER_MAGIC_NUMBER_TIZER = 1
|
||||
|
||||
MAX_LEN_RING_LOG_BUFFER = 250 # МАКСИМАЛЬНЫЙ РАЗМЕР КОЛЬЦЕВОГО БУФЕРА
|
||||
|
||||
YANDEX_MAPS_API_KEY = MY_YANDEX_MAPS_API_KEY
|
||||
YANDEX_MAPS_API_KEY = env('YANDEX_MAPS_API_KEY', default='')
|
||||
|
||||
+25
-20
@@ -15,11 +15,11 @@
|
||||
2. Добавьте URL-адрес в urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
from django.contrib import admin
|
||||
from django.urls import path, re_path
|
||||
from django.urls import include, path, re_path
|
||||
from django.conf.urls.static import static
|
||||
from oknardia.settings import *
|
||||
from web import views, autocomplete_addr, user_manager, blog, diagrams, report1, report2, catalog, prices, service
|
||||
|
||||
from web import views, autocomplete_addr, user_manager, blog, diagrams, report1, report2, catalog, prices, service, \
|
||||
catalog_profiles, catalog_series, catalog_openings, catalog_companies
|
||||
|
||||
urlpatterns = [
|
||||
path('admin/', admin.site.urls),
|
||||
@@ -56,23 +56,26 @@ urlpatterns = [
|
||||
re_path(r'^stat/series/geo[/*]$', diagrams.statistic_menu), # дубль для старых ссылок
|
||||
re_path(r'^stat/rating[/*]$', report2.ratings),
|
||||
re_path(r'^stat/rating/profiles_rank[/*]$', report2.profiles_rating),
|
||||
# --- Каталог
|
||||
# --- --- Каталог профилей
|
||||
# --- КАТАЛОГ
|
||||
re_path(r'^catalog[/*]$', catalog.catalog_root),
|
||||
re_path(r'^catalog/profile[/*]$', catalog.catalog_profile),
|
||||
# --- --- КАТАЛОГ ПРОФИЛЕЙ
|
||||
re_path(r'^catalog/profile[/*]$', catalog_profiles.catalog_profile),
|
||||
re_path(r'^catalog/profile/(?P<manufacture_id>\d+)-(?P<manufacture_name>\S*)'
|
||||
r'/(?P<model_id>\d+)-(?P<model_name>\S*)[/*]$', catalog.catalog_profile_model),
|
||||
r'/(?P<model_id>\d+)-(?P<model_name>\S*)[/*]$',
|
||||
catalog_profiles.catalog_profile_model),
|
||||
re_path(r'^catalog/profile/(?P<manufacture_id>\d+)-(?P<manufacture_name>\S*)[/*]$',
|
||||
catalog.catalog_profile_manufacture),
|
||||
catalog_profiles.catalog_profile_manufacture),
|
||||
# --- --- Каталог серий типового строительства
|
||||
re_path(r'^catalog/seria[/*]$', catalog.catalog_seria),
|
||||
re_path(r'^catalog/seria/(?P<seria_name_translit>[^/]*)/all(?P<seria_id>\d+)[/*]$', catalog.catalog_seria_info),
|
||||
re_path(r'^catalog/seria[/*]$', catalog_series.catalog_seria),
|
||||
re_path(r'^catalog/seria/(?P<seria_name_translit>[^/]*)/all(?P<seria_id>\d+)[/*]$',
|
||||
catalog_series.catalog_seria_info),
|
||||
re_path(r'^seria_[^/]*/all(?P<seria_id>\d+)/\S*$', catalog.report_all_info_seria_redirect), # для старых ссылок
|
||||
# --- --- Каталог стандартных проёмов и схем открывания длч типовых серий строительства
|
||||
re_path(r'^catalog/standard_opening[/*]$', catalog.standard_opening),
|
||||
re_path(r'^catalog/standard_opening[/*]$', catalog_openings.standard_opening),
|
||||
# --- --- Каталог производителей окон
|
||||
re_path(r'^catalog/company[/*]$', catalog.catalog_company),
|
||||
re_path(r'^catalog/company/(?P<company_id>\d+)-(?P<company_name_slug>\S*)[/*]$', catalog.catalog_company_detail),
|
||||
re_path(r'^catalog/company[/*]$', catalog_companies.catalog_company),
|
||||
re_path(r'^catalog/company/(?P<company_id>\d+)-(?P<company_name_slug>\S*)[/*]$',
|
||||
catalog_companies.catalog_company_detail),
|
||||
# ЦЕНОВЫЕ ПРЕДЛОЖЕНИЯ
|
||||
# --- Одиночное окно
|
||||
re_path(r'^tsena-odnogo-okna/(?P<win_width_mm>\d+)x(?P<win_height_mm>\d+)mm/tip(?P<win_id>\d+)[/*]$',
|
||||
@@ -96,16 +99,18 @@ urlpatterns = [
|
||||
re_path(r'^service/tmp[/*]$', service.tmp),
|
||||
# --- страничка "нет доступа"
|
||||
re_path(r'^service/not-denice[/*]$', service.not_denice),
|
||||
# --- создание файлов sitemap.xml
|
||||
re_path(r'^service/make_sitemaps[/*]$', service.make_site_maps),
|
||||
re_path(r'^service/make_rating[/*]$', service.make_rating),
|
||||
|
||||
]
|
||||
|
||||
|
||||
if DEBUG:
|
||||
# ___ ____ _ _____ _ _ _____ _
|
||||
# | | | | \ ___| |_ _ _ ___ |_ _|___ ___| | |_ ___ ___ | _ |___ ___ ___| |
|
||||
# |_ | | | | -_| . | | | . | | | | . | . | | . | .'| _| | __| .'| | -_| |
|
||||
# |_| |____/|___|___|___|_ | |_| |___|___|_|___|__,|_| |__| |__,|_|_|___|_|
|
||||
# |___|
|
||||
urlpatterns = [path('__debug__/', include('debug_toolbar.urls')), *urlpatterns]
|
||||
# Медиа-файлы
|
||||
urlpatterns += static(MEDIA_URL, document_root=MEDIA_ROOT)
|
||||
|
||||
# ___ ____ _ _____ _ _ _____ _
|
||||
# | | | | \ ___| |_ _ _ ___ |_ _|___ ___| | |_ ___ ___ | _ |___ ___ ___| |
|
||||
# |_ | | | | -_| . | | | . | | | | . | . | | . | .'| _| | __| .'| | -_| |
|
||||
# |_| |____/|___|___|___|_ | |_| |___|___|_|___|__,|_| |__| |__,|_|_|___|_|
|
||||
# |___|
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
<meta name="generator" content="OKNARDIA 0.3β by Python/Django" />
|
||||
<title>{% block Title %}{% endblock %} : ОКНАРДИЯ</title>
|
||||
<link rel="alternate" href="https://oknardia.ru" hreflang="ru-ru" />
|
||||
<link rel="icon" href="https://oknardia.ru/favicon.svg" type="image/svg+xml ">
|
||||
<link rel="icon" href="https://oknardia.ru/favicon.png" type="image/png">
|
||||
<link rel="icon" href="https://oknardia.ru/favicon.gif" type="image/gif">
|
||||
<link rel="icon" href="https://oknardia.ru/favicon.ico" type="image/x-icon">
|
||||
<link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet" type="text/css" />{# <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" type="text/css" />#}
|
||||
<link href="{% static 'css/bootstrap-theme.min.css' %}" rel="stylesheet" type="text/css" />{# <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" rel="stylesheet" type="text/css" />#}
|
||||
<link href="{% static 'css/oknardia1.css' %}" rel="stylesheet" type="text/css" />{% block Top_CSS1 %}{% endblock %}{% block Top_CSS2 %}{% endblock %}{% block Top_CSS3 %}{% endblock %}
|
||||
@@ -81,7 +85,7 @@
|
||||
{# <!-- Yandex.Metrika counter --> #}(function(d,w,c){(w[c]=w[c]||[]).push(function(){try{w.yaCounter32997984=new Ya.Metrika({id:32997984,clickmap:true,trackLinks:true,accurateTrackBounce:true,webvisor:true,trackHash:true});}catch(e){}});var n=d.getElementsByTagName("script")[0],s=d.createElement("script"),f=function(){n.parentNode.insertBefore(s,n);};s.type="text/javascript";s.async=true;s.src="https://mc.yandex.ru/metrika/watch.js";if(w.opera=="[object Opera]"){d.addEventListener("DOMContentLoaded",f,false);}else{ f();}})(document,window,"yandex_metrika_callbacks");
|
||||
//--></script>{# <!--/LiveInternet--> #}
|
||||
</span>
|
||||
<small>© oknardia.ru, 2015-{% now "Y" %}. <a href="/blogpost/18/Ob-avtorskih-pravah">Все права защищены</a>.<!--- Время отработки скрипта: {{ ticks }}{{ TAU }} сек---></small>
|
||||
<small>© oknardia.ru, 2015-{% now "Y" %}. <a href="/blogpost/18/Ob-avtorskih-pravah">Все права защищены</a>.<!--- Время отработки скрипта: {{ ticks }}{{ TAU }} сек---> {{ ticks }}{{ TAU }} сек </small>
|
||||
</div>
|
||||
</div>{% endblock %}
|
||||
{# ######################################## Нижнее меню-футер КОНЕЦ ######################################## #}
|
||||
|
||||
@@ -5,13 +5,9 @@
|
||||
|
||||
{% block Add_Body_Attribute %} style="padding-top:70px;"{% endblock %}
|
||||
|
||||
{% block Description %}Каталог оконных профилей{% endblock %}
|
||||
{% block Description %}Подберите оконный профиль под свои требования: в каталоге «Окнардии» собраны производители, марки и ключевые характеристики.{% endblock %}
|
||||
|
||||
{% block Keywords %}каталог оконных профилей, каталог производителей оконных профилей, каталог профилей, оконные профили, oknardia, окнардия {{ META_KEYWORDS|default:"" }} {% endblock %}
|
||||
|
||||
{% block Date4Meta %}{{ CATALOG_LAST_UPDATE|date:"c" }}{% endblock %}
|
||||
|
||||
{% block Last4Meta %}{{ CATALOG_LAST_UPDATE|date:"c" }}{% endblock %}
|
||||
{% block Keywords %}оконные профили, каталог профилей, сравнение профилей, производители оконных профилей, характеристики оконных профилей, oknardia {{ META_KEYWORDS|default:"" }} {% endblock %}
|
||||
|
||||
{% block Author4Meta %}: Каталог{% endblock %}
|
||||
|
||||
@@ -27,7 +23,7 @@
|
||||
<li>Оконные профили</li>
|
||||
</ol>
|
||||
<h1>Каталог оконных профилей</h1>
|
||||
<p>Узнать о производителях, познакомиться с детальными характеристики и описаниями оконных профилей можно кликнув по ссылкам. Сейчас в каталоге «Окнардии» представлено {{ CATALOG_MANUFACT_NUM_W }} профилей ({{ CATALOG_PROFILE_NUM }} в базе). Последнее обновление {{ CATALOG_LAST_UPDATE_W }}.</p>
|
||||
<p>Узнать о производителях, познакомиться с детальными характеристики и описаниями оконных профилей можно кликнув по ссылкам. Сейчас в каталоге «Окнардии» представлено {{ CATALOG_MANUFACT_NUM_W }} профилей ({{ CATALOG_PROFILE_NUM }} в базе).</p>
|
||||
</div>
|
||||
</div>{# <!--- Хлебные крошки: КОНЕЦ ---> #}
|
||||
<div class="row">
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,368 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru-RU">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="content-language" content="ru" />
|
||||
<meta http-equiv="Date" content="2023-01-18T00:31:05.856942+03:00" />
|
||||
<meta http-equiv="Last-Modified" content="2023-01-18T00:31:05.857034+03:00" />
|
||||
<meta http-equiv="Expires" content="2023-01-18T00:31:05.857082+03:00" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="Дома серии ПД-4: детальная информация" />
|
||||
<meta name="keywords" content=" ПД-4, серия ПД-4, проект ПД-4, года постройки зданий серии ПД-4, размеры окон в домах серии ПД-4, оконные проемы зданий серии ПД-4, дома серии ПД-4 на карте, установка окон, цены на пластиковые окна" />
|
||||
<meta name="author" content="OKNARDIA.RU" />
|
||||
<meta name="copyright" lang="ru" content="OKNARDIA.RU" />
|
||||
<meta name="robots" content="index,follow" />
|
||||
<meta name="document-state" content="Dynamic" />
|
||||
<meta name="generator" content="OKNARDIA 0.3β by Python/Django" />
|
||||
<title>Дома серии ПД-4 — типовые проёмы, размеры окон, схемы открывания, планировки, здания на карте, история и статистика : ОКНАРДИЯ</title>
|
||||
<link rel="alternate" href="https://oknardia.ru" hreflang="ru-ru" />
|
||||
<link href="/static/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="/static/css/bootstrap-theme.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="/static/css/oknardia1.css" rel="stylesheet" type="text/css" />
|
||||
<script src="/static/js/jquery-2.1.1.min.js" type="text/javascript"></script>
|
||||
<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).load(function () {
|
||||
let images = $('.half');
|
||||
images.each(function (i) {
|
||||
$(this).width($(this).width() / 2);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript">$(document).ready(function(){ $('#login-logout').load('/login-logout' ); })</script>
|
||||
</head>
|
||||
|
||||
<body style="padding-top:70px;">
|
||||
<!--- Контент НАЧАЛО --->
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-11 col-xs-12">
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="/">Главная</a></li>
|
||||
<li><a href="/catalog/">Каталог</a></li>
|
||||
<li><a href="/catalog/seria/">Типовые серии домов</a></li>
|
||||
<li>Серия ПД-4</li>
|
||||
</ol>
|
||||
<h1>СЕРИЯ ПД-4</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-10">
|
||||
<h2 class="header">Дома серии ПД-4: типовые размеры и схемы открывания</h2>
|
||||
</div>
|
||||
<div class="col-lg-12" style="padding:1em 0 0 0;margin-left:-1em">
|
||||
|
||||
|
||||
<div class="win_discr pull-left" id="flap0">
|
||||
<div><img src="/static/img/_flap.cfg/116x142H216WN(G)(L_).png" alt="Окно двустворчатое, балкон для серий ГМС-1, П-44, ПД-4 и КОПЭ. Размер 1160x1420 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое, балкон для серий ГМС-1, П-44, ПД-4 и КОПЭ. Размер 1160x1420 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:134px;min-width:13ex;">
|
||||
<nobr>1160×1420 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markA.svg');"></span></nobr><br />
|
||||
Окно двустворчатое, балкон для серий ГМС-1, П-44, ПД-4 и КОПЭ<br />
|
||||
<a href="/tsena-odnogo-okna/1160x1420mm/tip2">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap1">
|
||||
<div><img src="/static/img/_flap.cfg/067x216H216D-(L).png" alt="Дверь на балкон для серии ГМС-1, П-3, П-42, П-43, П-55 и ПД-4. Размер 670x2160 (Ш х В, мм.). Типовая схема открывания." title="Дверь на балкон для серии ГМС-1, П-3, П-42, П-43, П-55 и ПД-4. Размер 670x2160 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:77px;min-width:13ex;">
|
||||
<nobr>670×2160 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markB.svg');"></span></nobr><br />
|
||||
Дверь на балкон для серии ГМС-1, П-3, П-42, П-43, П-55 и ПД-4<br />
|
||||
<a href="/tsena-odnogo-okna/670x2160mm/tip16">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap2">
|
||||
<div><img src="/static/img/_flap.cfg/116x142H216W-(G_)(L).png" alt="Окно двустворчатое для серии ПД-4. Размер 1160x1420 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое для серии ПД-4. Размер 1160x1420 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:134px;min-width:13ex;">
|
||||
<nobr>1160×1420 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markC.svg');"></span></nobr><br />
|
||||
Окно двустворчатое для серии ПД-4<br />
|
||||
<a href="/tsena-odnogo-okna/1160x1420mm/tip45">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap3">
|
||||
<div><img src="/static/img/_flap.cfg/147x142H216W-(G)(L_).png" alt="Окно двустворчатое для ГМС-1, П-30/44/46/55, ПД-4, 1-504 и КОПЭ. Размер 1470x1420 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое для ГМС-1, П-30/44/46/55, ПД-4, 1-504 и КОПЭ. Размер 1470x1420 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:170px;min-width:13ex;">
|
||||
<nobr>1470×1420 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markD.svg');"></span></nobr><br />
|
||||
Окно двустворчатое для ГМС-1, П-30/44/46/55, ПД-4, 1-504 и КОПЭ<br />
|
||||
<a href="/tsena-odnogo-okna/1470x1420mm/tip1">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap4">
|
||||
<div><img src="/static/img/_flap.cfg/206x142H216W-(G)(G)(L).png" alt="Окно трёхстворчатое для серии КОПЭ, П-55 и ПД-4. Размер 2060x1420 (Ш х В, мм.). Типовая схема открывания." title="Окно трёхстворчатое для серии КОПЭ, П-55 и ПД-4. Размер 2060x1420 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:238px;min-width:13ex;">
|
||||
<nobr>2060×1420 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markE.svg');"></span></nobr><br />
|
||||
Окно трёхстворчатое для серии КОПЭ, П-55 и ПД-4<br />
|
||||
<a href="/tsena-odnogo-okna/2060x1420mm/tip10">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-8 col-xs-12 col-md-offset-1">
|
||||
<h3 class="header">Оконные проёмы в типовых квартирах <nobr>серии ПД-4</nobr></h3>
|
||||
</div>
|
||||
<div class="col-lg-8 col-xs-12 col-md-offset-1">
|
||||
<!--- прешаблон начало ---><table style="padding:2px;">{% for row in TABLE_OF_WINDOWS %}
|
||||
<tr class="tr2">
|
||||
<td>{{ row.APART_NAME|safe }}</td>{% for col in row.WIN_IN_APART %}
|
||||
<td class="cntr">{% if col.WIN_ID %}<nobr title="{{ col.WIN_Q }} × {{ col.WIN_DESCRIPTION }}: {{ col.WIN_WIDTH }}шт.: {{ col.WIN_HEIGHT }} (Ш×В, см.). Схема открывания: {{ col.WIN_FLAPCFG }}">{% for I_II in col.WIN_NUM %}<span style="background-image:url('/static/img/svg/mark{{ I_II }}.svg');"> </span>{% endfor %}</nobr>{% else %}—{% endif %}</td>{% endfor %}
|
||||
<td style="background:#f9f9f9;"><a href="#{{ row.APART_ID }}" class="badge" title="Оконных предложений для квартиры: {{ row.NUM_OFFERS }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small> {{ row.NUM_OFFERS }}</a></td>
|
||||
</tr>{% endfor %}
|
||||
<tr class="trZ">
|
||||
<td style="font-size: xx-small;vertical-align:text-top">© 2015-2023, данные: oknardia.ru</td>{% for i in WIN_OFFER_AND_MERCHANT %}
|
||||
<td class="cntr" style="background:#f9f9f9;"><a href="/tsena-odnogo-okna/{{ i.WIN_W|floatformat:0 }}0x{{ i.WIN_H|floatformat:0 }}0mm/tip{{ i.WIN_ID }}" class="badge" title="Ценовых предложений для окна: {{ i.WIN_OFFER }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small> {{ i.WIN_OFFER }}</a></td>{% endfor %}
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--- прешаблон конец ---></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-9"><a name="s_graph"></a>
|
||||
<h2 class="header">Здания серия ПД-4: ввод в эксплуатацию по годам</h2>
|
||||
</div>
|
||||
<div class="col-md-9 col-md-offset-1" style="height:300px;font-size:large;">
|
||||
|
||||
<script type="text/javascript" src="https://www.google.com/jsapi" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
// google.charts.load('current', {'packages':['bar']});
|
||||
// google.charts.setOnLoadCallback(drawChart);
|
||||
google.load("visualization", "1", {packages:["corechart"]});
|
||||
google.setOnLoadCallback(drawChart);
|
||||
function drawChart() {
|
||||
let data = google.visualization.arrayToDataTable([
|
||||
["Год", "Введено в эксплуатацию", {role:'style'}],
|
||||
["1961",4,"color: #99a899"],
|
||||
["1962",11,"color: #99c499"],
|
||||
["1963",6,"color: #99b099"],
|
||||
["1964",1,"color: #999c99"],
|
||||
["1995",1,"color: #999c99"],
|
||||
["1996",6,"color: #99b099"],
|
||||
["1997",13,"color: #99cc99"],
|
||||
["1998",6,"color: #99b099"],
|
||||
["1999",11,"color: #99c499"],
|
||||
["2000",9,"color: #99bc99"],
|
||||
["2001",8,"color: #99b899"],
|
||||
["2002",6,"color: #99b099"],
|
||||
["2003",6,"color: #99b099"],
|
||||
["2004",5,"color: #99ac99"],
|
||||
["2005",1,"color: #999c99"],
|
||||
["2006",2,"color: #99a099"],
|
||||
["2008",2,"color: #99a099"]
|
||||
]);
|
||||
let view = new google.visualization.DataView(data);
|
||||
view.setColumns([0, 1,
|
||||
{ calc: "stringify",
|
||||
sourceColumn: 1,
|
||||
type: "string",
|
||||
role: "annotation" },
|
||||
2
|
||||
]);
|
||||
let options = {
|
||||
animation:{
|
||||
duration: 1500,
|
||||
easing: 'in',
|
||||
startup: true
|
||||
},
|
||||
backgroundColor: "#EEEEEE",
|
||||
bar: {groupWidth: "76.4%"},
|
||||
chartArea: {left: "2%", top: "5%", width: '96%', height: '85%'},
|
||||
dataOpacity: 0.76,
|
||||
explorer:{
|
||||
maxZoomIn: 0.20,
|
||||
maxZoomOut: 32 },
|
||||
vAxis: {
|
||||
baselineColor:'grey',
|
||||
gridlines:{color: 'silver', count: 7},
|
||||
minorGridlines:{color: '#dddddd', count: 3},
|
||||
textPosition: 'in',
|
||||
textStyle: {fontSize: 10}
|
||||
},
|
||||
hAxis: { textStyle: {fontSize: 10} },
|
||||
isStacked: true,
|
||||
tooltip: {
|
||||
textStyle:{color: 'grey', fontSize: 10 },
|
||||
trigger: 'selection'
|
||||
},
|
||||
annotations: {textStyle: { fontSize: 8, bold: true, color: 'black', opacity: 0.8 }},
|
||||
legend: { position: "none" }
|
||||
};
|
||||
let chart = new google.visualization.ColumnChart(document.getElementById("graph"));
|
||||
chart.draw(data, options);
|
||||
}
|
||||
</script>
|
||||
<div id="graph" style="width:100%;height:100%">
|
||||
<p>Для отображения гистограммы ввода в эксплуатацию зданий серии ПД-4 нужна поддержка SVG.</p>
|
||||
<noscript>
|
||||
<p>Для визуализации отображения картографической информации с помощью Google.Charts нужно включить поддержку JavaScript.</p>
|
||||
</noscript></div>
|
||||
</div>
|
||||
<div class="col-md-9 col-md-offset-1">
|
||||
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-7"><a name="s_map"></a>
|
||||
<h2 class="header">Строения серии ПД-4 на карте</h2>
|
||||
</div>
|
||||
<div class="col-md-7 col-lg-offset-1">
|
||||
<p><small>Чтобы посмотреть цены на установку и замену окон от партнёров «Окнардия» в своей квартире: найдите дом на карте; кликните на него; перейдите по ссылке «Смотреть коммерческие предложения». При необходимости смените типовую планировку квартиры (на странице ценовой выдачи, справа от изображения типовых проёмов и схем открывания).</small></p>
|
||||
<div style="height:350px;">
|
||||
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
let points = [[55.564053,37.570941],[55.562907,37.570366],[55.563656,37.569306],[55.662364,37.779098],[55.748812,37.985073],[55.663486,37.765363],[55.490585,37.297512],[55.663888,37.769397],[55.633760,37.739600],[55.632916,37.738575],[55.632987,37.769558],[55.655437,37.764519],[55.863576,37.432025],[55.864818,37.431154],[55.567667,37.570923],[55.568110,37.571606],[55.568089,37.569701],[55.568354,37.568192],[55.568777,37.568821],[55.568782,37.566880],[55.569011,37.565353],[55.569494,37.566126],[55.569443,37.564168],[55.858074,37.568120],[55.739448,37.853048],[55.739868,37.853874],[55.550723,37.556208],[55.551599,37.556622],[55.550611,37.558167],[55.550101,37.558059],[55.550244,37.559173],[55.550789,37.559056],[55.546190,37.557780],[55.546908,37.558751],[55.548294,37.559451],[55.548660,37.560224],[55.545258,37.557879],[55.546083,37.558805],[55.546699,37.559460],[55.546842,37.560251],[55.736650,37.846760],[55.736883,37.847927],[55.735748,37.847119],[55.843222,37.386903],[55.842464,37.387622],[55.854704,37.360897],[55.855441,37.359504],[55.855896,37.358462],[55.837702,37.390532],[55.838668,37.390415],[55.750707,37.992790],[55.747819,37.988370],[55.750707,37.991775],[55.750727,37.989807],[55.750758,37.988783],[55.750778,37.987777],[55.956965,38.063846],[55.958321,38.062122],[55.922696,37.722361],[55.662699,37.766306],[55.840502,37.527399],[55.840442,37.528424],[55.654625,37.606137],[55.653898,37.606155],[55.840629,37.529852],[55.633932,37.747253],[55.631966,37.768175],[55.863379,37.430714],[55.857235,37.568201],[55.548044,37.560871],[55.854082,37.362136],[59.881525,30.454595],[59.883905,30.487096],[59.882049,30.483602],[59.881313,30.482003],[59.880600,30.480413],[59.879931,30.478858],[59.874110,30.476658],[59.880911,30.469776],[59.878130,30.464234],[59.881214,30.461710],[59.879371,30.463425],[59.881074,30.462859],[59.879827,30.464198],[59.879191,30.464333],[59.879647,30.465240],[59.881498,30.464620],[59.881850,30.465249],[59.879827,30.466273],[59.880017,30.466902],[59.880419,30.467728],[59.880433,30.468645],[59.881728,30.477421],[55.745336,38.023171],[55.746015,38.021311],[55.428066,37.561059],[55.923473,37.724086],[55.924204,37.722397]];
|
||||
let forURL = [386,388,10894,20193,71407,982,2134,12210,12704,12750,12833,12869,13603,13621,14936,14937,14938,14939,14940,14941,14946,14947,14948,15636,22141,22148,26758,26760,26761,26762,26763,26764,26767,26768,26769,26771,26772,26773,26774,26775,27668,27669,27724,32273,32274,32291,32293,32297,32302,32303,71401,71429,71436,71471,71474,71476,80428,80430,97640,983,20787,20788,1110,1111,9538,12718,12830,13625,15635,26770,32285,37770,39797,39801,39810,39815,39819,39829,40580,51926,51929,51930,51931,51934,51936,51937,51939,51941,51942,51943,51948,51953,51978,71533,71542,77732,97641,97647];
|
||||
|
||||
|
||||
ymaps.ready(function () {
|
||||
let myMap = new ymaps.Map('SeriaMap', {
|
||||
center: [55.75, 37.57],
|
||||
zoom: 10,
|
||||
behaviors: ['default', 'scrollZoom'],
|
||||
controls: [ 'rulerControl', 'zoomControl', 'geolocationControl', 'fullscreenControl' ]
|
||||
});
|
||||
// Создадим кластеризатор, вызвав функцию-конструктор.
|
||||
clusterer = new ymaps.Clusterer({
|
||||
preset: 'islands#invertedGrayClusterIcons',
|
||||
groupByCoordinates: false,
|
||||
hasHint: false,
|
||||
viewportMargin: 0,
|
||||
zoomMargin: 16,
|
||||
clusterDisableClickZoom: false,
|
||||
gridSize: 80
|
||||
});
|
||||
geoObjects = [];
|
||||
add_str1 = '<a href="/';
|
||||
add_str2 = '/0/">Смотреть коммерческие предложения</a>';
|
||||
add_str3 = '<b>Здание серии ПД-4</b>';
|
||||
// Данные передаются в конструктор метки.
|
||||
for(var i = 0, len = points.length; i < len; i++) {
|
||||
geoObjects[i] = new ymaps.Placemark( points[i],
|
||||
{ // Содержимое иконки, балуна и хинта.
|
||||
balloonContent: add_str1 + forURL[i] + add_str2,
|
||||
hintContent: add_str3
|
||||
},
|
||||
{ preset:'islands#circleIcon',iconColor: 'silver'} );
|
||||
geoObjects[i].events
|
||||
.add('mouseenter', function (e) {
|
||||
e.get('target').options.set('preset', 'islands#yellowCircleIcon');
|
||||
})
|
||||
.add('mouseleave', function (e) {
|
||||
e.get('target').options.set('preset', 'islands#grayCircleIcon');
|
||||
});
|
||||
}
|
||||
// Добавляем метки в кластеризатор.
|
||||
clusterer.add(geoObjects);
|
||||
myMap.geoObjects.add(clusterer);
|
||||
// позиционирование карты так, чтобы на ней были видны все объекты кластера.
|
||||
myMap.setBounds(clusterer.getBounds(), { checkZoomRange: true });
|
||||
});
|
||||
</script>
|
||||
<div id="SeriaMap" style="height:100%;width:100%;">
|
||||
<noscript>
|
||||
<p>Для отображения картографических данных по серии ПД-4 с помощью «Яндекс.Карт» нужно включить поддержку JavaScript.</p>
|
||||
</noscript>
|
||||
</div></div>
|
||||
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
|
||||
</div>
|
||||
|
||||
<diV class="col-md-4">
|
||||
<h3 class="header">Статистика <nobr>серии ПД-4</nobr></h3>
|
||||
<p>Совокупно во всех зданиях типового проекта:</p>
|
||||
<ul>
|
||||
<li><strong>16 024</strong> квартир.</li>
|
||||
<li>Проживает <strong>14 641</strong> семей <small>(<strong>69 926</strong> человек)</small>.</li>
|
||||
<li><strong>825 653.9 м²</strong> жилых помещений.</li>
|
||||
<li><strong>22 532.1 м²</strong> — муниципальное жильё.</li>
|
||||
<li><strong>28 434.2 м²</strong> занимают государственные и городские службы, учреждения бытового обслуживания, магазины, офисы и тому подобное.</li>
|
||||
<li>Максимальный износ жилого фонда серии ПД-4 — <strong>30.00 %</strong>. Минимальный — <strong>1.40 %</strong>. </li>
|
||||
</ul>
|
||||
</diV>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-lg-offset-8" style="margin-top: 1em;">
|
||||
<h5>Информация о других, отличных от ПД-4, типовых сериях в базе «Окнардия», типовых планировках квартир и оконных проёмах в них, а также рекомендации по замене окон:</h5>
|
||||
<div class="href_d"><span><a href="/catalog/seria/1-335/all210/"><nobr>1-335</nobr></a></span><span><a href="/catalog/seria/1-447/all379/"><nobr>1-447</nobr></a></span><span><a href="/catalog/seria/1-510/all39/"><nobr>1-510</nobr></a></span><span><a href="/catalog/seria/1-511/all100/"><nobr>1-511</nobr></a></span><span><a href="/catalog/seria/1-5155/all41/"><nobr>1-515/5</nobr></a></span><span><a href="/catalog/seria/1-5159/all843/"><nobr>1-515/9</nobr></a></span><span><a href="/catalog/seria/1605/all375/"><nobr>1605</nobr></a></span><span><a href="/catalog/seria/1lg-502/all2420/"><nobr>1ЛГ-502</nobr></a></span><span><a href="/catalog/seria/1lg-504/all2100/"><nobr>1ЛГ-504</nobr></a></span><span><a href="/catalog/seria/1lg-507/all2105/"><nobr>1ЛГ-507</nobr></a></span><span><a href="/catalog/seria/1r-303/all3568/"><nobr>1Р-303</nobr></a></span><span><a href="/catalog/seria/1r-30316/all4080/"><nobr>1Р-303.16</nobr></a></span><span><a href="/catalog/seria/ii-18/all18/"><nobr>II-18</nobr></a></span><span><a href="/catalog/seria/ii-29/all72/"><nobr>II-29</nobr></a></span><span><a href="/catalog/seria/ii-49/all12/"><nobr>II-49</nobr></a></span><span><a href="/catalog/seria/ii-57/all68/"><nobr>II-57</nobr></a></span><span><a href="/catalog/seria/ii-66/all80/"><nobr>II-66</nobr></a></span><span><a href="/catalog/seria/ii-68/all24/"><nobr>II-68</nobr></a></span><span><a href="/catalog/seria/gms-2001/all522/"><nobr>ГМС-2001</nobr></a></span><span><a href="/catalog/seria/i-209a/all44/"><nobr>И-209А</nobr></a></span><span><a href="/catalog/seria/k-7/all19/"><nobr>К-7</nobr></a></span><span><a href="/catalog/seria/kope/all17/"><nobr>КОПЭ</nobr></a></span><span><a href="/catalog/seria/mg-601/all492/"><nobr>МГ-601</nobr></a></span><span><a href="/catalog/seria/p-3/all9/"><nobr>П-3</nobr></a></span><span><a href="/catalog/seria/p-30/all79/"><nobr>П-30</nobr></a></span><span><a href="/catalog/seria/p-43/all178/"><nobr>П-43</nobr></a></span><span><a href="/catalog/seria/p-44/all8/"><nobr>П-44</nobr></a></span><span><a href="/catalog/seria/p-44t/all22/"><nobr>П-44Т</nobr></a></span><span><a href="/catalog/seria/p-46/all29/"><nobr>П-46</nobr></a></span><span><a href="/catalog/seria/p-55/all255/"><nobr>П-55</nobr></a></span><span><a href="/catalog/seria/pd-4/all148/"><nobr>ПД-4</nobr></a></span></div>
|
||||
<p style="text-align:right;padding-top:1em;padding-bottom:1em;"><a href="/stat_all/">Агрегированная информация<br />по типовым сериям домов<br />в базе «Окнардия»</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
{%include "report/report_last_user_visit.html" %}
|
||||
{% include "report/report_log_user_visit.html" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!---/ Контент КОНЕЦ --->
|
||||
|
||||
|
||||
|
||||
<nav class="navbar navbar-fixed-top navbar-default" role="navigation" id="header">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="/"><nobr><img src="/static/img/oknardia_logo.svg" onerror="this.onerror=null;this.src='/static/img/oknardia_logo.gif';this.width=290;this.height=34" title="Перейти на гравную сраницу «Окнардия»" alt="Логотип «Окнардия — оконный агрегатор»" ></nobr></a>
|
||||
</div>
|
||||
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li><a href="/catalog">Каталог</a></li>
|
||||
<li><a href="/stat/rating/">Рейтинги</a></li>
|
||||
<li><a href="/blog">Блог</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" rel="nofollow">О проекте <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="/stat_all">Статистика</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li><a href="/contact">Контакты</a></li>
|
||||
<li><a href="/blogpost/2/My_zhdem_vashi_prajs-listy!">Сотрудничество</a></li>
|
||||
<li><a href="/tariff">Услуги и тарифы</a></li>
|
||||
<!-- li class="divider"></li>
|
||||
<li><a href="#" rel="nofollow">Обратная связь</a></li -->
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown" id="login-logout"><!--- Сюда подгружают AJAX-ом блок login-logout ---><small><br />Авторизации.<noscript style="color:red;">Для авторизации необходимо включить JavaScript.</noscript></small></li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="row panel-footer">
|
||||
<div class="col-xs-12">
|
||||
<span style="top:-200px;left:-8000px;position: absolute;"><script type="text/javascript">
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
ga('create', 'UA-9116991-5', 'auto'); ga('send', 'pageview');
|
||||
var _tmr=_tmr||[];_tmr.push({id:"2018432",type:"pageView",start:(new Date()).getTime()});(function (d,w,id){if(d.getElementById(id))return;var ts=d.createElement("script");ts.type="text/javascript";ts.async=true;ts.id=id;ts.src=(d.location.protocol=="https:"?"https:":"http:")+"//top-fwz1.mail.ru/js/code.js";var f=function(){var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(ts, s);};if(w.opera=="[object Opera]"){ d.addEventListener("DOMContentLoaded",f,false);}else{f();}})(document,window,"topmailru-code");
|
||||
</script><noscript><div style="position:absolute;left:-10000px;">
|
||||
<img src="//top-fwz1.mail.ru/counter?id=2018432;js=na" style="border:0;height:1px;width:1px" alt="" />
|
||||
<img src="//mc.yandex.ru/watch/32997984" style="border:0;height:1px;width:1px" alt="" />
|
||||
</div></noscript>
|
||||
<a target="_blank" href="http://top.mail.ru/jump?from=2018432"><img src="//top-fwz1.mail.ru/counter?id=2018432;t=216;l=1" style="border:0;padding-top:8px;" rel="nofollow" alt="Рейтинг@Mail.ru"></a>
|
||||
<a href="https://metrika.yandex.ru/stat/?id=32997984&from=informer" target="_blank" rel="nofollow"><img src="https://informer.yandex.ru/informer/32997984/3_0_E0E0E0FF_C0C0C0FF_0_pageviews" style="width:88px; height:31px; border:0;" alt="Яндекс.Метрика" title="Яндекс.Метрика: данные за сегодня (просмотры, визиты и уникальные посетители)" onclick="try{Ya.Metrika.informer({i:this,id:32997984,lang:'ru'});return false}catch(e){}" /></a>
|
||||
<span id="rambler"><script id="top100Counter" type="text/javascript" src="//counter.rambler.ru/top100.jcn?3148853"></script><noscript><a href="http://top100.rambler.ru/navi/3148853/"><img src="http://counter.rambler.ru/top100.cnt?3148853" alt="Rambler's Top100" border="0"/></a></noscript></span>
|
||||
<script type="text/javascript"><!--
|
||||
document.write("<a href='//www.liveinternet.ru/click' target=_blank><img src='//counter.yadro.ru/hit?t50.2;r"+escape(document.referrer)+((typeof(screen)=="undefined")?"":";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth?screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+";"+Math.random()+"' alt='' title='LiveInternet' style='border:0;padding-top:8px;'><\/a>");
|
||||
(function(d,w,c){(w[c]=w[c]||[]).push(function(){try{w.yaCounter32997984=new Ya.Metrika({id:32997984,clickmap:true,trackLinks:true,accurateTrackBounce:true,webvisor:true,trackHash:true});}catch(e){}});var n=d.getElementsByTagName("script")[0],s=d.createElement("script"),f=function(){n.parentNode.insertBefore(s,n);};s.type="text/javascript";s.async=true;s.src="https://mc.yandex.ru/metrika/watch.js";if(w.opera=="[object Opera]"){d.addEventListener("DOMContentLoaded",f,false);}else{ f();}})(document,window,"yandex_metrika_callbacks");
|
||||
//--></script>
|
||||
</span>
|
||||
<small>© oknardia.ru, 2015-2023. <a href="/blogpost/18/Ob-avtorskih-pravah">Все права защищены</a>.<!--- Время отработки скрипта: сек---></small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,346 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru-RU">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="content-language" content="ru" />
|
||||
<meta http-equiv="Date" content="2023-01-18T00:30:27.483379+03:00" />
|
||||
<meta http-equiv="Last-Modified" content="2023-01-18T00:30:27.483423+03:00" />
|
||||
<meta http-equiv="Expires" content="2023-01-18T00:30:27.483448+03:00" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="Дома серии К-7: детальная информация" />
|
||||
<meta name="keywords" content=" К-7, серия К-7, проект К-7, года постройки зданий серии К-7, размеры окон в домах серии К-7, оконные проемы зданий серии К-7, дома серии К-7 на карте, установка окон, цены на пластиковые окна" />
|
||||
<meta name="author" content="OKNARDIA.RU" />
|
||||
<meta name="copyright" lang="ru" content="OKNARDIA.RU" />
|
||||
<meta name="robots" content="index,follow" />
|
||||
<meta name="document-state" content="Dynamic" />
|
||||
<meta name="generator" content="OKNARDIA 0.3β by Python/Django" />
|
||||
<title>Дома серии К-7 — типовые проёмы, размеры окон, схемы открывания, планировки, здания на карте, история и статистика : ОКНАРДИЯ</title>
|
||||
<link rel="alternate" href="https://oknardia.ru" hreflang="ru-ru" />
|
||||
<link href="/static/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="/static/css/bootstrap-theme.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="/static/css/oknardia1.css" rel="stylesheet" type="text/css" />
|
||||
<script src="/static/js/jquery-2.1.1.min.js" type="text/javascript"></script>
|
||||
<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).load(function () {
|
||||
let images = $('.half');
|
||||
images.each(function (i) {
|
||||
$(this).width($(this).width() / 2);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript">$(document).ready(function(){ $('#login-logout').load('/login-logout' ); })</script>
|
||||
</head>
|
||||
|
||||
<body style="padding-top:70px;">
|
||||
<!--- Контент НАЧАЛО --->
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-11 col-xs-12">
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="/">Главная</a></li>
|
||||
<li><a href="/catalog/">Каталог</a></li>
|
||||
<li><a href="/catalog/seria/">Типовые серии домов</a></li>
|
||||
<li>Серия К-7</li>
|
||||
</ol>
|
||||
<h1>СЕРИЯ К-7</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-10">
|
||||
<h2 class="header">Дома серии К-7: типовые размеры и схемы открывания</h2>
|
||||
</div>
|
||||
<div class="col-lg-12" style="padding:1em 0 0 0;margin-left:-1em">
|
||||
|
||||
|
||||
<div class="win_discr pull-left" id="flap0">
|
||||
<div><img src="/static/img/_flap.cfg/132x153H153W-(G)(L_).png" alt="Окно двустворчатое для серий II-18, II-68, II-49, К-7 и 1-515/9. Размер 1320x1530 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое для серий II-18, II-68, II-49, К-7 и 1-515/9. Размер 1320x1530 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:215px;min-width:13ex;">
|
||||
<nobr>1320×1530 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markA.svg');"></span></nobr><br />
|
||||
Окно двустворчатое для серий II-18, II-68, II-49, К-7 и 1-515/9<br />
|
||||
<a href="/tsena-odnogo-okna/1320x1530mm/tip23">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap1">
|
||||
<div><img src="/static/img/_flap.cfg/188x153H153W-(G_)(G_)(L).png" alt="Окно трёхстворчатое для серии К9 и 1-515/9Ш. Размер 1880x1530 (Ш х В, мм.). Типовая схема открывания." title="Окно трёхстворчатое для серии К9 и 1-515/9Ш. Размер 1880x1530 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:307px;min-width:13ex;">
|
||||
<nobr>1880×1530 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markB.svg');"></span></nobr><br />
|
||||
Окно трёхстворчатое для серии К9 и 1-515/9Ш<br />
|
||||
<a href="/tsena-odnogo-okna/1880x1530mm/tip38">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-8 col-xs-12 col-md-offset-1">
|
||||
<h3 class="header">Оконные проёмы в типовых квартирах <nobr>серии К-7</nobr></h3>
|
||||
</div>
|
||||
<div class="col-lg-8 col-xs-12 col-md-offset-1">
|
||||
<!--- прешаблон начало ---><table style="padding:2px;">{% for row in TABLE_OF_WINDOWS %}
|
||||
<tr class="tr2">
|
||||
<td>{{ row.APART_NAME|safe }}</td>{% for col in row.WIN_IN_APART %}
|
||||
<td class="cntr">{% if col.WIN_ID %}<nobr title="{{ col.WIN_Q }} × {{ col.WIN_DESCRIPTION }}: {{ col.WIN_WIDTH }}шт.: {{ col.WIN_HEIGHT }} (Ш×В, см.). Схема открывания: {{ col.WIN_FLAPCFG }}">{% for I_II in col.WIN_NUM %}<span style="background-image:url('/static/img/svg/mark{{ I_II }}.svg');"> </span>{% endfor %}</nobr>{% else %}—{% endif %}</td>{% endfor %}
|
||||
<td style="background:#f9f9f9;"><a href="#{{ row.APART_ID }}" class="badge" title="Оконных предложений для квартиры: {{ row.NUM_OFFERS }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small> {{ row.NUM_OFFERS }}</a></td>
|
||||
</tr>{% endfor %}
|
||||
<tr class="trZ">
|
||||
<td style="font-size: xx-small;vertical-align:text-top">© 2015-2023, данные: oknardia.ru</td>{% for i in WIN_OFFER_AND_MERCHANT %}
|
||||
<td class="cntr" style="background:#f9f9f9;"><a href="/tsena-odnogo-okna/{{ i.WIN_W|floatformat:0 }}0x{{ i.WIN_H|floatformat:0 }}0mm/tip{{ i.WIN_ID }}" class="badge" title="Ценовых предложений для окна: {{ i.WIN_OFFER }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small> {{ i.WIN_OFFER }}</a></td>{% endfor %}
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--- прешаблон конец ---></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-9"><a name="s_graph"></a>
|
||||
<h2 class="header">Здания серия К-7: ввод в эксплуатацию по годам</h2>
|
||||
</div>
|
||||
<div class="col-md-9 col-md-offset-1" style="height:300px;font-size:large;">
|
||||
|
||||
<script type="text/javascript" src="https://www.google.com/jsapi" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
// google.charts.load('current', {'packages':['bar']});
|
||||
// google.charts.setOnLoadCallback(drawChart);
|
||||
google.load("visualization", "1", {packages:["corechart"]});
|
||||
google.setOnLoadCallback(drawChart);
|
||||
function drawChart() {
|
||||
let data = google.visualization.arrayToDataTable([
|
||||
["Год", "Введено в эксплуатацию", {role:'style'}],
|
||||
["1926",1,"color: #999a99"],
|
||||
["1929",3,"color: #999c99"],
|
||||
["1959",7,"color: #99a099"],
|
||||
["1960",6,"color: #999f99"],
|
||||
["1961",25,"color: #99b399"],
|
||||
["1962",23,"color: #99b199"],
|
||||
["1963",48,"color: #99cc99"],
|
||||
["1964",36,"color: #99bf99"],
|
||||
["1965",10,"color: #99a399"],
|
||||
["1966",18,"color: #99ac99"],
|
||||
["1967",2,"color: #999b99"],
|
||||
["1976",1,"color: #999a99"],
|
||||
["1978",1,"color: #999a99"],
|
||||
["1984",1,"color: #999a99"],
|
||||
["1989",1,"color: #999a99"],
|
||||
["1991",1,"color: #999a99"],
|
||||
["1996",1,"color: #999a99"],
|
||||
["1998",1,"color: #999a99"],
|
||||
["2000",1,"color: #999a99"],
|
||||
["2003",1,"color: #999a99"],
|
||||
["2004",1,"color: #999a99"],
|
||||
["2010",11,"color: #99a499"]
|
||||
]);
|
||||
let view = new google.visualization.DataView(data);
|
||||
view.setColumns([0, 1,
|
||||
{ calc: "stringify",
|
||||
sourceColumn: 1,
|
||||
type: "string",
|
||||
role: "annotation" },
|
||||
2
|
||||
]);
|
||||
let options = {
|
||||
animation:{
|
||||
duration: 1500,
|
||||
easing: 'in',
|
||||
startup: true
|
||||
},
|
||||
backgroundColor: "#EEEEEE",
|
||||
bar: {groupWidth: "76.4%"},
|
||||
chartArea: {left: "2%", top: "5%", width: '96%', height: '85%'},
|
||||
dataOpacity: 0.76,
|
||||
explorer:{
|
||||
maxZoomIn: 0.20,
|
||||
maxZoomOut: 32 },
|
||||
vAxis: {
|
||||
baselineColor:'grey',
|
||||
gridlines:{color: 'silver', count: 7},
|
||||
minorGridlines:{color: '#dddddd', count: 3},
|
||||
textPosition: 'in',
|
||||
textStyle: {fontSize: 10}
|
||||
},
|
||||
hAxis: { textStyle: {fontSize: 10} },
|
||||
isStacked: true,
|
||||
tooltip: {
|
||||
textStyle:{color: 'grey', fontSize: 10 },
|
||||
trigger: 'selection'
|
||||
},
|
||||
annotations: {textStyle: { fontSize: 8, bold: true, color: 'black', opacity: 0.8 }},
|
||||
legend: { position: "none" }
|
||||
};
|
||||
let chart = new google.visualization.ColumnChart(document.getElementById("graph"));
|
||||
chart.draw(data, options);
|
||||
}
|
||||
</script>
|
||||
<div id="graph" style="width:100%;height:100%">
|
||||
<p>Для отображения гистограммы ввода в эксплуатацию зданий серии К-7 нужна поддержка SVG.</p>
|
||||
<noscript>
|
||||
<p>Для визуализации отображения картографической информации с помощью Google.Charts нужно включить поддержку JavaScript.</p>
|
||||
</noscript></div>
|
||||
</div>
|
||||
<div class="col-md-9 col-md-offset-1">
|
||||
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-7"><a name="s_map"></a>
|
||||
<h2 class="header">Строения серии К-7 на карте</h2>
|
||||
</div>
|
||||
<div class="col-md-7 col-lg-offset-1">
|
||||
<p><small>Чтобы посмотреть цены на установку и замену окон от партнёров «Окнардия» в своей квартире: найдите дом на карте; кликните на него; перейдите по ссылке «Смотреть коммерческие предложения». При необходимости смените типовую планировку квартиры (на странице ценовой выдачи, справа от изображения типовых проёмов и схем открывания).</small></p>
|
||||
<div style="height:350px;">
|
||||
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
let points = [[55.862510,37.560440],[55.861646,37.560170],[55.861863,37.558885],[55.863510,37.559371],[55.872774,37.549642],[55.858518,37.561293],[55.859261,37.561329],[55.860064,37.561419],[55.860009,37.560655],[55.859797,37.559936],[55.851551,37.432007],[55.852435,37.431989],[55.769393,37.475243],[55.769524,37.471560],[55.769524,37.471560],[55.774087,37.462918],[55.775358,37.460951],[55.775798,37.460421],[55.862853,37.558400],[55.863181,37.558885],[55.673610,37.497575],[55.672661,37.495887],[55.788672,37.785557],[55.788692,37.787336],[55.668965,37.510987],[55.668894,37.509514],[55.666096,37.509846],[55.666096,37.509119],[55.666091,37.508409],[55.774482,37.474426],[55.774482,37.474426],[55.774482,37.474426],[55.775322,37.471255],[55.774862,37.471767],[55.774958,37.471102],[55.775039,37.470428],[55.776112,37.462676],[55.776208,37.462002],[55.776310,37.461337],[55.871976,37.641459],[55.871471,37.636176],[55.872062,37.635602],[55.871334,37.634676],[55.871991,37.634865],[55.871920,37.634119],[55.871198,37.633185],[55.871854,37.633365],[55.872087,37.642950],[55.885186,37.656407],[55.885635,37.656047],[55.886347,37.655481],[55.886796,37.655140],[55.884731,37.656766],[55.855138,37.645294],[55.854401,37.644710],[55.855841,37.644980],[55.856326,37.642698],[55.855542,37.642150],[55.855108,37.639635],[55.855108,37.639635],[55.856801,37.640390],[55.856801,37.640390],[55.856331,37.639159],[55.857043,37.638692],[55.880960,37.644513],[55.882707,37.648349],[55.882141,37.649274],[55.883232,37.650020],[55.883035,37.651717],[55.874471,37.627813],[55.874294,37.625837],[55.874865,37.626493],[55.875971,37.626852],[55.875334,37.623465],[55.875031,37.624921],[55.875890,37.625424],[55.874758,37.623061],[55.871723,37.631963],[55.871784,37.632619],[55.878405,37.620061],[55.473265,37.539006],[55.343200,37.638458],[55.343200,37.638458],[55.343200,37.638458],[55.860630,37.473114],[55.865273,37.471372],[55.863121,37.425477],[55.857700,37.425656],[55.857745,37.424147],[55.723100,37.567590],[55.723962,37.568408],[55.723775,37.569009],[55.723212,37.568713],[55.867834,37.673169],[55.867177,37.673268],[55.865945,37.678505],[55.867692,37.674714],[55.822428,37.587290],[55.821897,37.584990],[55.822620,37.584730],[55.823312,37.584182],[55.878243,37.633167],[55.878758,37.628110],[55.878066,37.623232],[55.878152,37.622432],[55.879329,37.621669],[55.878233,37.621651],[55.878314,37.620851],[55.879601,37.639653],[55.772456,37.471821],[55.772548,37.471165],[55.772968,37.473420],[55.773054,37.472791],[55.773570,37.474022],[55.773667,37.473366],[55.773763,37.472710],[55.773763,37.472710],[55.770704,37.470734],[55.770487,37.472827],[55.770704,37.473959],[55.771935,37.471120],[55.771403,37.470877],[55.660800,37.519207],[55.661978,37.514733],[55.661978,37.514733],[55.661978,37.514733],[55.661978,37.514733],[55.661237,37.513422],[55.660937,37.513853],[55.660892,37.514661],[55.875319,37.634407],[55.875511,37.631999],[55.875935,37.635188],[55.882853,37.641144],[55.872127,37.636347],[55.873198,37.635709],[55.874395,37.634766],[55.861444,37.555220],[55.861752,37.556469],[55.854224,37.650091],[55.810840,37.569207],[55.853001,37.422970],[55.853087,37.423761],[55.859499,37.474974],[55.856962,37.477067],[55.858306,37.476878],[55.857068,37.479582],[55.857639,37.480139],[55.859221,37.479573],[55.858488,37.480489],[55.857750,37.481343],[55.821042,37.584586],[55.820329,37.587191],[55.821138,37.585251],[55.821269,37.585880],[55.820430,37.583805],[55.800701,37.727302],[55.796840,37.615345],[55.794836,37.615470],[55.821295,37.582556],[55.821457,37.583230],[55.822068,37.582484],[55.822473,37.580643],[55.822625,37.581298],[55.822776,37.581963],[55.858473,37.559371],[55.859398,37.558472],[55.859600,37.559200],[55.859539,37.557430],[55.859539,37.557430],[55.859539,37.557430],[55.476664,37.295131],[55.476490,37.296209],[55.481087,37.300117],[55.475888,37.295086],[55.672184,37.495033],[55.671712,37.494180],[55.768203,37.711347],[55.870662,37.464625],[55.872157,37.463610],[55.866031,37.472135],[55.858513,37.475010],[55.893243,37.539940],[55.651821,37.553765],[55.805832,37.817492],[55.808245,37.816603],[55.861595,37.555831],[55.673016,37.754556],[55.804941,37.614832],[55.719794,37.802814],[55.717492,37.809614],[59.737400,30.462752],[59.737686,30.462123],[59.736090,30.464405],[59.735813,30.465042],[59.736806,30.462859],[59.737074,30.462231],[59.736108,30.465608],[59.733273,30.466614],[59.734167,30.468070],[59.733273,30.466614],[59.734167,30.468070]];
|
||||
let forURL = [172,173,174,175,217,218,251,255,256,257,1521,1522,2819,2821,2823,2828,2833,2835,3517,3518,6168,6173,6531,6533,6738,6739,6772,6775,6778,6968,6969,6970,6973,6974,6975,6976,6987,6988,6989,8139,8151,8152,8159,8160,8161,8169,8170,8180,8300,8302,8305,8307,8316,9162,9163,9164,9165,9166,9168,9169,9170,9171,9172,9173,9727,9740,9743,9747,9755,9856,9860,9865,9866,9867,9869,9871,9873,9877,9878,9881,9937,10233,10234,10236,12173,12195,13600,14497,14503,15383,15392,15393,15394,20459,20460,20489,20490,20621,20622,20624,20626,20967,20974,20986,20987,20988,20989,20990,20994,21566,21567,21574,21575,21581,21582,21583,21584,21606,21625,21634,21640,21641,21961,22691,22692,22693,22694,22704,22710,22712,24914,24916,24920,24938,24948,24967,24971,26531,26538,26881,28275,28491,28492,28961,28962,28968,28982,28986,28988,28989,28990,29242,29243,29245,29247,29256,29418,30266,30291,30912,30913,30915,30918,30919,30920,31583,31584,31585,31586,31587,31588,2154,2155,2168,2174,6180,6185,19284,7965,7968,12166,28959,15424,22687,23546,23563,26537,27593,30279,29517,29525,45464,45465,45499,45500,45502,45503,45505,45535,45538,45555,45558];
|
||||
|
||||
|
||||
ymaps.ready(function () {
|
||||
let myMap = new ymaps.Map('SeriaMap', {
|
||||
center: [55.75, 37.57],
|
||||
zoom: 10,
|
||||
behaviors: ['default', 'scrollZoom'],
|
||||
controls: [ 'rulerControl', 'zoomControl', 'geolocationControl', 'fullscreenControl' ]
|
||||
});
|
||||
// Создадим кластеризатор, вызвав функцию-конструктор.
|
||||
clusterer = new ymaps.Clusterer({
|
||||
preset: 'islands#invertedGrayClusterIcons',
|
||||
groupByCoordinates: false,
|
||||
hasHint: false,
|
||||
viewportMargin: 0,
|
||||
zoomMargin: 16,
|
||||
clusterDisableClickZoom: false,
|
||||
gridSize: 80
|
||||
});
|
||||
geoObjects = [];
|
||||
add_str1 = '<a href="/';
|
||||
add_str2 = '/0/">Смотреть коммерческие предложения</a>';
|
||||
add_str3 = '<b>Здание серии К-7</b>';
|
||||
// Данные передаются в конструктор метки.
|
||||
for(var i = 0, len = points.length; i < len; i++) {
|
||||
geoObjects[i] = new ymaps.Placemark( points[i],
|
||||
{ // Содержимое иконки, балуна и хинта.
|
||||
balloonContent: add_str1 + forURL[i] + add_str2,
|
||||
hintContent: add_str3
|
||||
},
|
||||
{ preset:'islands#circleIcon',iconColor: 'silver'} );
|
||||
geoObjects[i].events
|
||||
.add('mouseenter', function (e) {
|
||||
e.get('target').options.set('preset', 'islands#yellowCircleIcon');
|
||||
})
|
||||
.add('mouseleave', function (e) {
|
||||
e.get('target').options.set('preset', 'islands#grayCircleIcon');
|
||||
});
|
||||
}
|
||||
// Добавляем метки в кластеризатор.
|
||||
clusterer.add(geoObjects);
|
||||
myMap.geoObjects.add(clusterer);
|
||||
// позиционирование карты так, чтобы на ней были видны все объекты кластера.
|
||||
myMap.setBounds(clusterer.getBounds(), { checkZoomRange: true });
|
||||
});
|
||||
</script>
|
||||
<div id="SeriaMap" style="height:100%;width:100%;">
|
||||
<noscript>
|
||||
<p>Для отображения картографических данных по серии К-7 с помощью «Яндекс.Карт» нужно включить поддержку JavaScript.</p>
|
||||
</noscript>
|
||||
</div></div>
|
||||
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
|
||||
</div>
|
||||
|
||||
<diV class="col-md-4">
|
||||
<h3 class="header">Статистика <nobr>серии К-7</nobr></h3>
|
||||
<p>Совокупно во всех зданиях типового проекта:</p>
|
||||
<ul>
|
||||
<li><strong>19 354</strong> квартир.</li>
|
||||
<li>Проживает <strong>16 839</strong> семей <small>(<strong>82 948</strong> человек)</small>.</li>
|
||||
<li><strong>539 518.2 м²</strong> жилых помещений.</li>
|
||||
<li><strong>93 304.8 м²</strong> — муниципальное жильё.</li>
|
||||
<li><strong>27 709.9 м²</strong> занимают государственные и городские службы, учреждения бытового обслуживания, магазины, офисы и тому подобное.</li>
|
||||
<li>Максимальный износ жилого фонда серии К-7 — <strong>69.00 %</strong>. Минимальный — <strong>4.80 %</strong>. </li>
|
||||
</ul>
|
||||
</diV>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-lg-offset-8" style="margin-top: 1em;">
|
||||
<h5>Информация о других, отличных от К-7, типовых сериях в базе «Окнардия», типовых планировках квартир и оконных проёмах в них, а также рекомендации по замене окон:</h5>
|
||||
<div class="href_d"><span><a href="/catalog/seria/1-335/all210/"><nobr>1-335</nobr></a></span><span><a href="/catalog/seria/1-447/all379/"><nobr>1-447</nobr></a></span><span><a href="/catalog/seria/1-510/all39/"><nobr>1-510</nobr></a></span><span><a href="/catalog/seria/1-511/all100/"><nobr>1-511</nobr></a></span><span><a href="/catalog/seria/1-5155/all41/"><nobr>1-515/5</nobr></a></span><span><a href="/catalog/seria/1-5159/all843/"><nobr>1-515/9</nobr></a></span><span><a href="/catalog/seria/1605/all375/"><nobr>1605</nobr></a></span><span><a href="/catalog/seria/1lg-502/all2420/"><nobr>1ЛГ-502</nobr></a></span><span><a href="/catalog/seria/1lg-504/all2100/"><nobr>1ЛГ-504</nobr></a></span><span><a href="/catalog/seria/1lg-507/all2105/"><nobr>1ЛГ-507</nobr></a></span><span><a href="/catalog/seria/1r-303/all3568/"><nobr>1Р-303</nobr></a></span><span><a href="/catalog/seria/1r-30316/all4080/"><nobr>1Р-303.16</nobr></a></span><span><a href="/catalog/seria/ii-18/all18/"><nobr>II-18</nobr></a></span><span><a href="/catalog/seria/ii-29/all72/"><nobr>II-29</nobr></a></span><span><a href="/catalog/seria/ii-49/all12/"><nobr>II-49</nobr></a></span><span><a href="/catalog/seria/ii-57/all68/"><nobr>II-57</nobr></a></span><span><a href="/catalog/seria/ii-66/all80/"><nobr>II-66</nobr></a></span><span><a href="/catalog/seria/ii-68/all24/"><nobr>II-68</nobr></a></span><span><a href="/catalog/seria/gms-2001/all522/"><nobr>ГМС-2001</nobr></a></span><span><a href="/catalog/seria/i-209a/all44/"><nobr>И-209А</nobr></a></span><span><a href="/catalog/seria/k-7/all19/"><nobr>К-7</nobr></a></span><span><a href="/catalog/seria/kope/all17/"><nobr>КОПЭ</nobr></a></span><span><a href="/catalog/seria/mg-601/all492/"><nobr>МГ-601</nobr></a></span><span><a href="/catalog/seria/p-3/all9/"><nobr>П-3</nobr></a></span><span><a href="/catalog/seria/p-30/all79/"><nobr>П-30</nobr></a></span><span><a href="/catalog/seria/p-43/all178/"><nobr>П-43</nobr></a></span><span><a href="/catalog/seria/p-44/all8/"><nobr>П-44</nobr></a></span><span><a href="/catalog/seria/p-44t/all22/"><nobr>П-44Т</nobr></a></span><span><a href="/catalog/seria/p-46/all29/"><nobr>П-46</nobr></a></span><span><a href="/catalog/seria/p-55/all255/"><nobr>П-55</nobr></a></span><span><a href="/catalog/seria/pd-4/all148/"><nobr>ПД-4</nobr></a></span></div>
|
||||
<p style="text-align:right;padding-top:1em;padding-bottom:1em;"><a href="/stat_all/">Агрегированная информация<br />по типовым сериям домов<br />в базе «Окнардия»</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
{%include "report/report_last_user_visit.html" %}
|
||||
{% include "report/report_log_user_visit.html" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!---/ Контент КОНЕЦ --->
|
||||
|
||||
|
||||
|
||||
<nav class="navbar navbar-fixed-top navbar-default" role="navigation" id="header">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="/"><nobr><img src="/static/img/oknardia_logo.svg" onerror="this.onerror=null;this.src='/static/img/oknardia_logo.gif';this.width=290;this.height=34" title="Перейти на гравную сраницу «Окнардия»" alt="Логотип «Окнардия — оконный агрегатор»" ></nobr></a>
|
||||
</div>
|
||||
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li><a href="/catalog">Каталог</a></li>
|
||||
<li><a href="/stat/rating/">Рейтинги</a></li>
|
||||
<li><a href="/blog">Блог</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" rel="nofollow">О проекте <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="/stat_all">Статистика</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li><a href="/contact">Контакты</a></li>
|
||||
<li><a href="/blogpost/2/My_zhdem_vashi_prajs-listy!">Сотрудничество</a></li>
|
||||
<li><a href="/tariff">Услуги и тарифы</a></li>
|
||||
<!-- li class="divider"></li>
|
||||
<li><a href="#" rel="nofollow">Обратная связь</a></li -->
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown" id="login-logout"><!--- Сюда подгружают AJAX-ом блок login-logout ---><small><br />Авторизации.<noscript style="color:red;">Для авторизации необходимо включить JavaScript.</noscript></small></li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="row panel-footer">
|
||||
<div class="col-xs-12">
|
||||
<span style="top:-200px;left:-8000px;position: absolute;"><script type="text/javascript">
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
ga('create', 'UA-9116991-5', 'auto'); ga('send', 'pageview');
|
||||
var _tmr=_tmr||[];_tmr.push({id:"2018432",type:"pageView",start:(new Date()).getTime()});(function (d,w,id){if(d.getElementById(id))return;var ts=d.createElement("script");ts.type="text/javascript";ts.async=true;ts.id=id;ts.src=(d.location.protocol=="https:"?"https:":"http:")+"//top-fwz1.mail.ru/js/code.js";var f=function(){var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(ts, s);};if(w.opera=="[object Opera]"){ d.addEventListener("DOMContentLoaded",f,false);}else{f();}})(document,window,"topmailru-code");
|
||||
</script><noscript><div style="position:absolute;left:-10000px;">
|
||||
<img src="//top-fwz1.mail.ru/counter?id=2018432;js=na" style="border:0;height:1px;width:1px" alt="" />
|
||||
<img src="//mc.yandex.ru/watch/32997984" style="border:0;height:1px;width:1px" alt="" />
|
||||
</div></noscript>
|
||||
<a target="_blank" href="http://top.mail.ru/jump?from=2018432"><img src="//top-fwz1.mail.ru/counter?id=2018432;t=216;l=1" style="border:0;padding-top:8px;" rel="nofollow" alt="Рейтинг@Mail.ru"></a>
|
||||
<a href="https://metrika.yandex.ru/stat/?id=32997984&from=informer" target="_blank" rel="nofollow"><img src="https://informer.yandex.ru/informer/32997984/3_0_E0E0E0FF_C0C0C0FF_0_pageviews" style="width:88px; height:31px; border:0;" alt="Яндекс.Метрика" title="Яндекс.Метрика: данные за сегодня (просмотры, визиты и уникальные посетители)" onclick="try{Ya.Metrika.informer({i:this,id:32997984,lang:'ru'});return false}catch(e){}" /></a>
|
||||
<span id="rambler"><script id="top100Counter" type="text/javascript" src="//counter.rambler.ru/top100.jcn?3148853"></script><noscript><a href="http://top100.rambler.ru/navi/3148853/"><img src="http://counter.rambler.ru/top100.cnt?3148853" alt="Rambler's Top100" border="0"/></a></noscript></span>
|
||||
<script type="text/javascript"><!--
|
||||
document.write("<a href='//www.liveinternet.ru/click' target=_blank><img src='//counter.yadro.ru/hit?t50.2;r"+escape(document.referrer)+((typeof(screen)=="undefined")?"":";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth?screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+";"+Math.random()+"' alt='' title='LiveInternet' style='border:0;padding-top:8px;'><\/a>");
|
||||
(function(d,w,c){(w[c]=w[c]||[]).push(function(){try{w.yaCounter32997984=new Ya.Metrika({id:32997984,clickmap:true,trackLinks:true,accurateTrackBounce:true,webvisor:true,trackHash:true});}catch(e){}});var n=d.getElementsByTagName("script")[0],s=d.createElement("script"),f=function(){n.parentNode.insertBefore(s,n);};s.type="text/javascript";s.async=true;s.src="https://mc.yandex.ru/metrika/watch.js";if(w.opera=="[object Opera]"){d.addEventListener("DOMContentLoaded",f,false);}else{ f();}})(document,window,"yandex_metrika_callbacks");
|
||||
//--></script>
|
||||
</span>
|
||||
<small>© oknardia.ru, 2015-2023. <a href="/blogpost/18/Ob-avtorskih-pravah">Все права защищены</a>.<!--- Время отработки скрипта: сек---></small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,359 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru-RU">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="content-language" content="ru" />
|
||||
<meta http-equiv="Date" content="2023-01-18T00:28:02.157690+03:00" />
|
||||
<meta http-equiv="Last-Modified" content="2023-01-18T00:28:02.157739+03:00" />
|
||||
<meta http-equiv="Expires" content="2023-01-18T00:28:02.157763+03:00" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="Дома серии 1-335: детальная информация" />
|
||||
<meta name="keywords" content=" 1-335, серия 1-335, проект 1-335, года постройки зданий серии 1-335, размеры окон в домах серии 1-335, оконные проемы зданий серии 1-335, дома серии 1-335 на карте, установка окон, цены на пластиковые окна" />
|
||||
<meta name="author" content="OKNARDIA.RU" />
|
||||
<meta name="copyright" lang="ru" content="OKNARDIA.RU" />
|
||||
<meta name="robots" content="index,follow" />
|
||||
<meta name="document-state" content="Dynamic" />
|
||||
<meta name="generator" content="OKNARDIA 0.3β by Python/Django" />
|
||||
<title>Дома серии 1-335 — типовые проёмы, размеры окон, схемы открывания, планировки, здания на карте, история и статистика : ОКНАРДИЯ</title>
|
||||
<link rel="alternate" href="https://oknardia.ru" hreflang="ru-ru" />
|
||||
<link href="/static/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="/static/css/bootstrap-theme.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="/static/css/oknardia1.css" rel="stylesheet" type="text/css" />
|
||||
<script src="/static/js/jquery-2.1.1.min.js" type="text/javascript"></script>
|
||||
<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).load(function () {
|
||||
let images = $('.half');
|
||||
images.each(function (i) {
|
||||
$(this).width($(this).width() / 2);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript">$(document).ready(function(){ $('#login-logout').load('/login-logout' ); })</script>
|
||||
</head>
|
||||
|
||||
<body style="padding-top:70px;">
|
||||
<!--- Контент НАЧАЛО --->
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-11 col-xs-12">
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="/">Главная</a></li>
|
||||
<li><a href="/catalog/">Каталог</a></li>
|
||||
<li><a href="/catalog/seria/">Типовые серии домов</a></li>
|
||||
<li>Серия 1-335</li>
|
||||
</ol>
|
||||
<h1>СЕРИЯ 1-335</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"><p>Пятиэтажка 1–335 проектировалась Ленинградским Отделением Горстройпроекта (архитекторы Баныкин Б. Н., Артемьева И. Б. и Смирнова Л. А.) и стала одним из первых зданий «полукаркасной» схемы (неполный каркас и навесные панели). Возводилась по всей территории СССР с 1956 года. Последние здания серии сданы в эксплуатацию в 1968 году.</p>
|
||||
<p>Проект 1–335 так и не получил дальнейшей модернизации, <nobr>из-за</nobr> ряда недостатков. Так, профильные навесные бетонные панели толщиной 30 см. приводили к теплопотерям, и замена на керамзитбетонные (40 см.) для регионов с суровым климатом не спасало. Внешняя облицовка утепляющими материалами увеличивала стоимость и эксплуатационные расходы, потому 1–335 возводились только в Ленинграде, где климат мягче.</p>
|
||||
<p>Внешний вид 1–335 не сильно отличается от других панельных зданий того периода. Серию можно узнать по боковому фасаду: без балконов, две панели без окон в центре или по краям. Как и у многих «хрущёвок», серия 1–335 с железной четырёхскатной крышей (поздние модификации строились с плоской крышей без чердаков), секции без лифта (по четыре квартиры: 1-, 2- и <nobr>3-комнатные</nobr>), потолки 255 см., санузер совмещенный.</p>
|
||||
<p>Оконные проемы серии 1–335 на 10–15 см шире чем у других «хрущёвок», но максимум пять этажей подразумевают низкие ветровые нагрузки. Это означает, что при замене окон использование усиленных профилей не обязательно. Кроме того, нецелесообразно использование стеклопакетов с заполнением инертным газом и высоким сопротивлением теплопередаче — утечки тепла через панели сведут на нет их преимущество. Благодаря хорошей вытяжной вентиляции здания можно сэкономить на встраиваемых в окна клапанах <nobr>климат-контроля</nobr>.</p></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-10">
|
||||
<h2 class="header">Дома серии 1-335: типовые размеры и схемы открывания</h2>
|
||||
</div>
|
||||
<div class="col-lg-12" style="padding:1em 0 0 0;margin-left:-1em">
|
||||
|
||||
|
||||
<div class="win_discr pull-left" id="flap0">
|
||||
<div><img src="/static/img/_flap.cfg/126x138H207WN(G)(L).png" alt="Окно двустворчатое «Хрущевка» на балкон (серии 1-335). Размер 1260x1380 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое «Хрущевка» на балкон (серии 1-335). Размер 1260x1380 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:152px;min-width:13ex;">
|
||||
<nobr>1260×1380 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markA.svg');"></span></nobr><br />
|
||||
Окно двустворчатое «Хрущевка» на балкон (серии 1-335)<br />
|
||||
<a href="/tsena-odnogo-okna/1260x1380mm/tip49">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap1">
|
||||
<div><img src="/static/img/_flap.cfg/068x207H207D-(L).png" alt="Дверь на балкон «Хрущевка» (серии 1-335, 507, 510, 511 и 515/5). Размер 680x2070 (Ш х В, мм.). Типовая схема открывания." title="Дверь на балкон «Хрущевка» (серии 1-335, 507, 510, 511 и 515/5). Размер 680x2070 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:82px;min-width:13ex;">
|
||||
<nobr>680×2070 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markB.svg');"></span></nobr><br />
|
||||
Дверь на балкон «Хрущевка» (серии 1-335, 507, 510, 511 и 515/5)<br />
|
||||
<a href="/tsena-odnogo-okna/680x2070mm/tip40">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap2">
|
||||
<div><img src="/static/img/_flap.cfg/128x138H207W-(G)(L).png" alt="Окно двустворчатое «Хрущевка» (серии 1-335). Размер 1280x1380 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое «Хрущевка» (серии 1-335). Размер 1280x1380 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:154px;min-width:13ex;">
|
||||
<nobr>1280×1380 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markC.svg');"></span></nobr><br />
|
||||
Окно двустворчатое «Хрущевка» (серии 1-335)<br />
|
||||
<a href="/tsena-odnogo-okna/1280x1380mm/tip48">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap3">
|
||||
<div><img src="/static/img/_flap.cfg/194x138H207W-(G)(L)(L).png" alt="Окно трёхстворчатое «Хрущевка» (серии 1-335). Размер 1940x1380 (Ш х В, мм.). Типовая схема открывания." title="Окно трёхстворчатое «Хрущевка» (серии 1-335). Размер 1940x1380 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:234px;min-width:13ex;">
|
||||
<nobr>1940×1380 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markD.svg');"></span></nobr><br />
|
||||
Окно трёхстворчатое «Хрущевка» (серии 1-335)<br />
|
||||
<a href="/tsena-odnogo-okna/1940x1380mm/tip47">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-8 col-xs-12 col-md-offset-1">
|
||||
<h3 class="header">Оконные проёмы в типовых квартирах <nobr>серии 1-335</nobr></h3>
|
||||
</div>
|
||||
<div class="col-lg-8 col-xs-12 col-md-offset-1">
|
||||
<!--- прешаблон начало ---><table style="padding:2px;">{% for row in TABLE_OF_WINDOWS %}
|
||||
<tr class="tr2">
|
||||
<td>{{ row.APART_NAME|safe }}</td>{% for col in row.WIN_IN_APART %}
|
||||
<td class="cntr">{% if col.WIN_ID %}<nobr title="{{ col.WIN_Q }} × {{ col.WIN_DESCRIPTION }}: {{ col.WIN_WIDTH }}шт.: {{ col.WIN_HEIGHT }} (Ш×В, см.). Схема открывания: {{ col.WIN_FLAPCFG }}">{% for I_II in col.WIN_NUM %}<span style="background-image:url('/static/img/svg/mark{{ I_II }}.svg');"> </span>{% endfor %}</nobr>{% else %}—{% endif %}</td>{% endfor %}
|
||||
<td style="background:#f9f9f9;"><a href="#{{ row.APART_ID }}" class="badge" title="Оконных предложений для квартиры: {{ row.NUM_OFFERS }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small> {{ row.NUM_OFFERS }}</a></td>
|
||||
</tr>{% endfor %}
|
||||
<tr class="trZ">
|
||||
<td style="font-size: xx-small;vertical-align:text-top">© 2015-2023, данные: oknardia.ru</td>{% for i in WIN_OFFER_AND_MERCHANT %}
|
||||
<td class="cntr" style="background:#f9f9f9;"><a href="/tsena-odnogo-okna/{{ i.WIN_W|floatformat:0 }}0x{{ i.WIN_H|floatformat:0 }}0mm/tip{{ i.WIN_ID }}" class="badge" title="Ценовых предложений для окна: {{ i.WIN_OFFER }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small> {{ i.WIN_OFFER }}</a></td>{% endfor %}
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--- прешаблон конец ---></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-9"><a name="s_graph"></a>
|
||||
<h2 class="header">Здания серия 1-335: ввод в эксплуатацию по годам</h2>
|
||||
</div>
|
||||
<div class="col-md-9 col-md-offset-1" style="height:300px;font-size:large;">
|
||||
|
||||
<script type="text/javascript" src="https://www.google.com/jsapi" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
// google.charts.load('current', {'packages':['bar']});
|
||||
// google.charts.setOnLoadCallback(drawChart);
|
||||
google.load("visualization", "1", {packages:["corechart"]});
|
||||
google.setOnLoadCallback(drawChart);
|
||||
function drawChart() {
|
||||
let data = google.visualization.arrayToDataTable([
|
||||
["Год", "Введено в эксплуатацию", {role:'style'}],
|
||||
["1956",1,"color: #999a99"],
|
||||
["1957",1,"color: #999a99"],
|
||||
["1959",11,"color: #99a499"],
|
||||
["1960",25,"color: #99b299"],
|
||||
["1961",50,"color: #99cc99"],
|
||||
["1962",37,"color: #99be99"],
|
||||
["1963",7,"color: #99a099"],
|
||||
["1964",29,"color: #99b699"],
|
||||
["1965",18,"color: #99ab99"],
|
||||
["1966",20,"color: #99ad99"],
|
||||
["1967",18,"color: #99ab99"],
|
||||
["1968",1,"color: #999a99"],
|
||||
["1969",1,"color: #999a99"],
|
||||
["2000",2,"color: #999b99"]
|
||||
]);
|
||||
let view = new google.visualization.DataView(data);
|
||||
view.setColumns([0, 1,
|
||||
{ calc: "stringify",
|
||||
sourceColumn: 1,
|
||||
type: "string",
|
||||
role: "annotation" },
|
||||
2
|
||||
]);
|
||||
let options = {
|
||||
animation:{
|
||||
duration: 1500,
|
||||
easing: 'in',
|
||||
startup: true
|
||||
},
|
||||
backgroundColor: "#EEEEEE",
|
||||
bar: {groupWidth: "76.4%"},
|
||||
chartArea: {left: "2%", top: "5%", width: '96%', height: '85%'},
|
||||
dataOpacity: 0.76,
|
||||
explorer:{
|
||||
maxZoomIn: 0.20,
|
||||
maxZoomOut: 32 },
|
||||
vAxis: {
|
||||
baselineColor:'grey',
|
||||
gridlines:{color: 'silver', count: 7},
|
||||
minorGridlines:{color: '#dddddd', count: 3},
|
||||
textPosition: 'in',
|
||||
textStyle: {fontSize: 10}
|
||||
},
|
||||
hAxis: { textStyle: {fontSize: 10} },
|
||||
isStacked: true,
|
||||
tooltip: {
|
||||
textStyle:{color: 'grey', fontSize: 10 },
|
||||
trigger: 'selection'
|
||||
},
|
||||
annotations: {textStyle: { fontSize: 8, bold: true, color: 'black', opacity: 0.8 }},
|
||||
legend: { position: "none" }
|
||||
};
|
||||
let chart = new google.visualization.ColumnChart(document.getElementById("graph"));
|
||||
chart.draw(data, options);
|
||||
}
|
||||
</script>
|
||||
<div id="graph" style="width:100%;height:100%">
|
||||
<p>Для отображения гистограммы ввода в эксплуатацию зданий серии 1-335 нужна поддержка SVG.</p>
|
||||
<noscript>
|
||||
<p>Для визуализации отображения картографической информации с помощью Google.Charts нужно включить поддержку JavaScript.</p>
|
||||
</noscript></div>
|
||||
</div>
|
||||
<div class="col-md-9 col-md-offset-1">
|
||||
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-7"><a name="s_map"></a>
|
||||
<h2 class="header">Строения серии 1-335 на карте</h2>
|
||||
</div>
|
||||
<div class="col-md-7 col-lg-offset-1">
|
||||
<p><small>Чтобы посмотреть цены на установку и замену окон от партнёров «Окнардия» в своей квартире: найдите дом на карте; кликните на него; перейдите по ссылке «Смотреть коммерческие предложения». При необходимости смените типовую планировку квартиры (на странице ценовой выдачи, справа от изображения типовых проёмов и схем открывания).</small></p>
|
||||
<div style="height:350px;">
|
||||
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
let points = [[55.797847,37.813495],[55.797857,37.814241],[55.797908,37.818579],[55.797898,37.817825],[55.797888,37.817061],[55.802568,37.813504],[55.802077,37.812534],[55.802103,37.814483],[55.788960,37.786366],[55.819772,37.623492],[55.819793,37.622792],[55.732342,37.425171],[55.787118,37.454672],[55.869617,37.673969],[55.799456,37.812677],[55.799467,37.813441],[55.799477,37.814178],[55.798667,37.814627],[55.798677,37.815310],[55.799527,37.818508],[55.799507,37.817762],[55.799502,37.816998],[55.798692,37.816639],[55.798682,37.815974],[55.796618,37.482897],[60.009534,30.415527],[60.009521,30.417270],[59.988005,30.419004],[59.987839,30.417926],[60.011163,30.432703],[55.802614,37.817430],[55.802143,37.818364],[55.682295,37.745268],[55.874466,37.712605],[60.094954,29.975173],[60.101176,29.978479],[59.928690,30.414494],[59.972613,30.430331],[60.016348,30.369965],[59.922864,30.422193],[60.019298,30.409329],[60.019451,30.408700],[60.019536,30.411467],[60.019212,30.411997],[60.019068,30.412662],[59.925173,30.422687],[59.924050,30.422408],[59.924055,30.423010],[59.922747,30.423298],[59.955512,30.436647],[59.955611,30.435245],[59.955687,30.433637],[59.955773,30.432110],[59.955863,30.430502],[59.966174,30.434886],[59.969912,30.434203],[59.972830,30.434428],[59.972199,30.432640],[59.972186,30.427933],[59.920997,30.423801],[59.921205,30.424474],[59.927017,30.429155],[59.927640,30.431661],[59.928735,30.430251],[60.009215,30.433476],[60.009926,30.432047],[60.017306,30.411871],[60.013564,30.406984],[59.967399,30.433242],[59.969299,30.433071],[59.925398,30.417009],[59.926792,30.418725],[59.926512,30.420396],[59.958363,30.424178],[59.957890,30.426729],[59.957751,30.428247],[59.958647,30.429424],[59.958440,30.430790],[59.958850,30.413210],[55.591447,37.642060],[55.590562,37.642411],[55.681696,37.571857],[55.681427,37.572585],[55.681189,37.573321],[55.674529,37.578594],[55.674184,37.578235],[55.673864,37.577912],[59.932180,30.414656],[59.930304,30.413254],[59.929849,30.414692],[59.930660,30.415105],[59.929366,30.415033],[59.929227,30.417045],[59.929673,30.416560],[59.929799,30.421160],[59.930178,30.423369],[59.930944,30.427942],[59.928181,30.414288],[59.927860,30.415105],[59.927860,30.415105],[59.926990,30.416174],[59.926990,30.416174],[59.925642,30.415851],[59.924339,30.417405],[59.923667,30.418312],[59.922990,30.419273],[59.923410,30.420495],[59.921913,30.420755],[59.922305,30.421986],[59.921971,30.423001],[59.920830,30.422292],[59.932017,30.415348],[59.928519,30.421043],[59.927915,30.420513],[59.930886,30.416183],[59.928009,30.421654],[59.928009,30.421654],[59.927671,30.422004],[59.929344,30.417611],[59.927220,30.421276],[59.927125,30.422579],[59.928627,30.418447],[59.928095,30.418357],[59.926774,30.422983],[59.928460,30.416965],[59.926142,30.422633],[59.927482,30.417764],[59.923775,30.425867],[59.927243,30.419291],[59.927071,30.420252],[59.925777,30.421806],[59.924474,30.423549],[59.923595,30.423612],[59.923707,30.424618],[59.922959,30.423926],[59.922373,30.424295],[59.922900,30.425732],[59.922048,30.426882],[59.982658,30.411673],[59.986596,30.422786],[59.920636,30.423387],[59.921412,30.425112],[59.921813,30.425525],[59.921615,30.426280],[59.923423,30.428131],[59.925196,30.428436],[59.927044,30.427699],[59.926684,30.430421],[59.927247,30.430565],[59.927901,30.428876],[59.927906,30.430340],[59.928573,30.431032],[59.932414,30.322022],[59.932085,30.321725],[59.931544,30.321105],[59.931314,30.320512],[59.933681,30.323207],[59.933510,30.323055],[59.932748,30.322336],[59.924957,30.417162],[59.925087,30.418195],[59.925002,30.420719],[59.926224,30.416857],[59.925547,30.420387],[59.895615,30.422094],[59.895226,30.421016],[59.894450,30.420782],[59.894780,30.419641],[59.973320,30.425301],[59.972181,30.424061],[59.973325,30.428768],[60.017004,30.375435],[60.016780,30.376738],[60.013227,30.402645],[59.965660,30.401774],[60.015597,30.369713],[60.014522,30.369686],[60.014576,30.370477],[60.014248,30.374115],[60.014113,30.374869],[60.013353,30.374762],[59.964332,30.435326],[59.971105,30.433044],[59.974923,30.404226],[59.972839,30.422283],[60.007888,30.431284],[60.009215,30.433476],[60.012210,30.415240],[59.968142,30.435155],[59.958341,30.426020],[59.958602,30.430134],[59.973284,30.432487],[60.016492,30.394228],[60.013771,30.402250],[60.012534,30.405376],[60.016447,30.372911],[59.930403,30.412554],[60.012669,30.403786],[60.010659,30.412644],[60.010717,30.413488],[60.009193,30.419839],[60.009004,30.420477],[60.014009,30.375624],[59.973766,30.404837],[59.973910,30.403687],[59.972762,30.403723],[59.973136,30.404155],[59.973239,30.405655],[59.973816,30.407532],[60.006984,30.429173],[60.007047,30.431544],[60.007663,30.429451],[60.016901,30.373163],[59.955647,30.434464],[59.955818,30.431302],[59.972019,30.406688],[59.984283,30.402600],[59.983671,30.406625],[59.954119,30.433332],[59.954092,30.434086],[55.032480,82.904197]];
|
||||
let forURL = [500,501,506,507,508,1186,1187,1188,6532,10981,10982,15807,15993,19036,23453,23454,23455,23456,23457,23512,23513,23514,23515,23516,25685,42831,42833,47423,47428,53621,1195,1196,5964,19285,36627,36648,40749,42235,42826,43196,43811,43812,43815,43817,43818,44775,44777,44778,44782,44947,44948,44951,44955,44959,44998,45003,45008,45010,47599,48689,48690,48705,48713,48715,53618,53620,54364,54392,54485,54487,54693,54699,54700,56026,56029,56032,56033,56036,56047,9494,9495,17262,17263,17264,18444,18445,18446,38621,40744,40746,40750,40751,40754,40756,40760,40763,40770,43156,43157,43158,43163,43165,43176,43178,43184,43191,43192,43194,43195,43197,43203,44740,44743,44745,44747,44748,44749,44750,44751,44753,44755,44757,44758,44760,44761,44762,44765,44768,44770,44772,44774,44776,44779,44780,44781,44783,44784,44785,46886,47434,48688,48691,48692,48693,48696,48700,48702,48709,48710,48711,48712,48714,49929,49930,49931,49932,49933,49934,49935,54687,54690,54694,54696,54697,40667,40669,40672,40675,42229,51740,42233,42798,42808,42814,43407,44361,44419,44420,44422,44423,44424,44996,45006,50273,51741,53614,53619,54381,54491,56027,56034,42239,42807,42813,42818,42871,43146,42815,42828,42829,42843,42844,44417,46392,46395,46396,46397,46398,50266,53610,53612,53613,42882,44950,44957,46399,46880,46883,47193,47194,58339];
|
||||
|
||||
|
||||
ymaps.ready(function () {
|
||||
let myMap = new ymaps.Map('SeriaMap', {
|
||||
center: [55.75, 37.57],
|
||||
zoom: 10,
|
||||
behaviors: ['default', 'scrollZoom'],
|
||||
controls: [ 'rulerControl', 'zoomControl', 'geolocationControl', 'fullscreenControl' ]
|
||||
});
|
||||
// Создадим кластеризатор, вызвав функцию-конструктор.
|
||||
clusterer = new ymaps.Clusterer({
|
||||
preset: 'islands#invertedGrayClusterIcons',
|
||||
groupByCoordinates: false,
|
||||
hasHint: false,
|
||||
viewportMargin: 0,
|
||||
zoomMargin: 16,
|
||||
clusterDisableClickZoom: false,
|
||||
gridSize: 80
|
||||
});
|
||||
geoObjects = [];
|
||||
add_str1 = '<a href="/';
|
||||
add_str2 = '/0/">Смотреть коммерческие предложения</a>';
|
||||
add_str3 = '<b>Здание серии 1-335</b>';
|
||||
// Данные передаются в конструктор метки.
|
||||
for(var i = 0, len = points.length; i < len; i++) {
|
||||
geoObjects[i] = new ymaps.Placemark( points[i],
|
||||
{ // Содержимое иконки, балуна и хинта.
|
||||
balloonContent: add_str1 + forURL[i] + add_str2,
|
||||
hintContent: add_str3
|
||||
},
|
||||
{ preset:'islands#circleIcon',iconColor: 'silver'} );
|
||||
geoObjects[i].events
|
||||
.add('mouseenter', function (e) {
|
||||
e.get('target').options.set('preset', 'islands#yellowCircleIcon');
|
||||
})
|
||||
.add('mouseleave', function (e) {
|
||||
e.get('target').options.set('preset', 'islands#grayCircleIcon');
|
||||
});
|
||||
}
|
||||
// Добавляем метки в кластеризатор.
|
||||
clusterer.add(geoObjects);
|
||||
myMap.geoObjects.add(clusterer);
|
||||
// позиционирование карты так, чтобы на ней были видны все объекты кластера.
|
||||
myMap.setBounds(clusterer.getBounds(), { checkZoomRange: true });
|
||||
});
|
||||
</script>
|
||||
<div id="SeriaMap" style="height:100%;width:100%;">
|
||||
<noscript>
|
||||
<p>Для отображения картографических данных по серии 1-335 с помощью «Яндекс.Карт» нужно включить поддержку JavaScript.</p>
|
||||
</noscript>
|
||||
</div></div>
|
||||
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
|
||||
</div>
|
||||
|
||||
<diV class="col-md-4">
|
||||
<h3 class="header">Статистика <nobr>серии 1-335</nobr></h3>
|
||||
<p>Совокупно во всех зданиях типового проекта:</p>
|
||||
<ul>
|
||||
<li><strong>19 742</strong> квартир.</li>
|
||||
<li>Проживает <strong>20 521</strong> семей <small>(<strong>98 798</strong> человек)</small>.</li>
|
||||
<li><strong>904 827.7 м²</strong> жилых помещений.</li>
|
||||
<li><strong>6 470.2 м²</strong> — муниципальное жильё.</li>
|
||||
<li><strong>31 829.0 м²</strong> занимают государственные и городские службы, учреждения бытового обслуживания, магазины, офисы и тому подобное.</li>
|
||||
<li>Максимальный износ жилого фонда серии 1-335 — <strong>70.00 %</strong>. Минимальный — <strong>6.00 %</strong>. </li>
|
||||
</ul>
|
||||
</diV>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-lg-offset-8" style="margin-top: 1em;">
|
||||
<h5>Информация о других, отличных от 1-335, типовых сериях в базе «Окнардия», типовых планировках квартир и оконных проёмах в них, а также рекомендации по замене окон:</h5>
|
||||
<div class="href_d"><span><a href="/catalog/seria/1-335/all210/"><nobr>1-335</nobr></a></span><span><a href="/catalog/seria/1-447/all379/"><nobr>1-447</nobr></a></span><span><a href="/catalog/seria/1-510/all39/"><nobr>1-510</nobr></a></span><span><a href="/catalog/seria/1-511/all100/"><nobr>1-511</nobr></a></span><span><a href="/catalog/seria/1-5155/all41/"><nobr>1-515/5</nobr></a></span><span><a href="/catalog/seria/1-5159/all843/"><nobr>1-515/9</nobr></a></span><span><a href="/catalog/seria/1605/all375/"><nobr>1605</nobr></a></span><span><a href="/catalog/seria/1lg-502/all2420/"><nobr>1ЛГ-502</nobr></a></span><span><a href="/catalog/seria/1lg-504/all2100/"><nobr>1ЛГ-504</nobr></a></span><span><a href="/catalog/seria/1lg-507/all2105/"><nobr>1ЛГ-507</nobr></a></span><span><a href="/catalog/seria/1r-303/all3568/"><nobr>1Р-303</nobr></a></span><span><a href="/catalog/seria/1r-30316/all4080/"><nobr>1Р-303.16</nobr></a></span><span><a href="/catalog/seria/ii-18/all18/"><nobr>II-18</nobr></a></span><span><a href="/catalog/seria/ii-29/all72/"><nobr>II-29</nobr></a></span><span><a href="/catalog/seria/ii-49/all12/"><nobr>II-49</nobr></a></span><span><a href="/catalog/seria/ii-57/all68/"><nobr>II-57</nobr></a></span><span><a href="/catalog/seria/ii-66/all80/"><nobr>II-66</nobr></a></span><span><a href="/catalog/seria/ii-68/all24/"><nobr>II-68</nobr></a></span><span><a href="/catalog/seria/gms-2001/all522/"><nobr>ГМС-2001</nobr></a></span><span><a href="/catalog/seria/i-209a/all44/"><nobr>И-209А</nobr></a></span><span><a href="/catalog/seria/k-7/all19/"><nobr>К-7</nobr></a></span><span><a href="/catalog/seria/kope/all17/"><nobr>КОПЭ</nobr></a></span><span><a href="/catalog/seria/mg-601/all492/"><nobr>МГ-601</nobr></a></span><span><a href="/catalog/seria/p-3/all9/"><nobr>П-3</nobr></a></span><span><a href="/catalog/seria/p-30/all79/"><nobr>П-30</nobr></a></span><span><a href="/catalog/seria/p-43/all178/"><nobr>П-43</nobr></a></span><span><a href="/catalog/seria/p-44/all8/"><nobr>П-44</nobr></a></span><span><a href="/catalog/seria/p-44t/all22/"><nobr>П-44Т</nobr></a></span><span><a href="/catalog/seria/p-46/all29/"><nobr>П-46</nobr></a></span><span><a href="/catalog/seria/p-55/all255/"><nobr>П-55</nobr></a></span><span><a href="/catalog/seria/pd-4/all148/"><nobr>ПД-4</nobr></a></span></div>
|
||||
<p style="text-align:right;padding-top:1em;padding-bottom:1em;"><a href="/stat_all/">Агрегированная информация<br />по типовым сериям домов<br />в базе «Окнардия»</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
{%include "report/report_last_user_visit.html" %}
|
||||
{% include "report/report_log_user_visit.html" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!---/ Контент КОНЕЦ --->
|
||||
|
||||
|
||||
|
||||
<nav class="navbar navbar-fixed-top navbar-default" role="navigation" id="header">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="/"><nobr><img src="/static/img/oknardia_logo.svg" onerror="this.onerror=null;this.src='/static/img/oknardia_logo.gif';this.width=290;this.height=34" title="Перейти на гравную сраницу «Окнардия»" alt="Логотип «Окнардия — оконный агрегатор»" ></nobr></a>
|
||||
</div>
|
||||
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li><a href="/catalog">Каталог</a></li>
|
||||
<li><a href="/stat/rating/">Рейтинги</a></li>
|
||||
<li><a href="/blog">Блог</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" rel="nofollow">О проекте <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="/stat_all">Статистика</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li><a href="/contact">Контакты</a></li>
|
||||
<li><a href="/blogpost/2/My_zhdem_vashi_prajs-listy!">Сотрудничество</a></li>
|
||||
<li><a href="/tariff">Услуги и тарифы</a></li>
|
||||
<!-- li class="divider"></li>
|
||||
<li><a href="#" rel="nofollow">Обратная связь</a></li -->
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown" id="login-logout"><!--- Сюда подгружают AJAX-ом блок login-logout ---><small><br />Авторизации.<noscript style="color:red;">Для авторизации необходимо включить JavaScript.</noscript></small></li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="row panel-footer">
|
||||
<div class="col-xs-12">
|
||||
<span style="top:-200px;left:-8000px;position: absolute;"><script type="text/javascript">
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
ga('create', 'UA-9116991-5', 'auto'); ga('send', 'pageview');
|
||||
var _tmr=_tmr||[];_tmr.push({id:"2018432",type:"pageView",start:(new Date()).getTime()});(function (d,w,id){if(d.getElementById(id))return;var ts=d.createElement("script");ts.type="text/javascript";ts.async=true;ts.id=id;ts.src=(d.location.protocol=="https:"?"https:":"http:")+"//top-fwz1.mail.ru/js/code.js";var f=function(){var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(ts, s);};if(w.opera=="[object Opera]"){ d.addEventListener("DOMContentLoaded",f,false);}else{f();}})(document,window,"topmailru-code");
|
||||
</script><noscript><div style="position:absolute;left:-10000px;">
|
||||
<img src="//top-fwz1.mail.ru/counter?id=2018432;js=na" style="border:0;height:1px;width:1px" alt="" />
|
||||
<img src="//mc.yandex.ru/watch/32997984" style="border:0;height:1px;width:1px" alt="" />
|
||||
</div></noscript>
|
||||
<a target="_blank" href="http://top.mail.ru/jump?from=2018432"><img src="//top-fwz1.mail.ru/counter?id=2018432;t=216;l=1" style="border:0;padding-top:8px;" rel="nofollow" alt="Рейтинг@Mail.ru"></a>
|
||||
<a href="https://metrika.yandex.ru/stat/?id=32997984&from=informer" target="_blank" rel="nofollow"><img src="https://informer.yandex.ru/informer/32997984/3_0_E0E0E0FF_C0C0C0FF_0_pageviews" style="width:88px; height:31px; border:0;" alt="Яндекс.Метрика" title="Яндекс.Метрика: данные за сегодня (просмотры, визиты и уникальные посетители)" onclick="try{Ya.Metrika.informer({i:this,id:32997984,lang:'ru'});return false}catch(e){}" /></a>
|
||||
<span id="rambler"><script id="top100Counter" type="text/javascript" src="//counter.rambler.ru/top100.jcn?3148853"></script><noscript><a href="http://top100.rambler.ru/navi/3148853/"><img src="http://counter.rambler.ru/top100.cnt?3148853" alt="Rambler's Top100" border="0"/></a></noscript></span>
|
||||
<script type="text/javascript"><!--
|
||||
document.write("<a href='//www.liveinternet.ru/click' target=_blank><img src='//counter.yadro.ru/hit?t50.2;r"+escape(document.referrer)+((typeof(screen)=="undefined")?"":";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth?screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+";"+Math.random()+"' alt='' title='LiveInternet' style='border:0;padding-top:8px;'><\/a>");
|
||||
(function(d,w,c){(w[c]=w[c]||[]).push(function(){try{w.yaCounter32997984=new Ya.Metrika({id:32997984,clickmap:true,trackLinks:true,accurateTrackBounce:true,webvisor:true,trackHash:true});}catch(e){}});var n=d.getElementsByTagName("script")[0],s=d.createElement("script"),f=function(){n.parentNode.insertBefore(s,n);};s.type="text/javascript";s.async=true;s.src="https://mc.yandex.ru/metrika/watch.js";if(w.opera=="[object Opera]"){d.addEventListener("DOMContentLoaded",f,false);}else{ f();}})(document,window,"yandex_metrika_callbacks");
|
||||
//--></script>
|
||||
</span>
|
||||
<small>© oknardia.ru, 2015-2023. <a href="/blogpost/18/Ob-avtorskih-pravah">Все права защищены</a>.<!--- Время отработки скрипта: сек---></small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,387 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru-RU">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="content-language" content="ru" />
|
||||
<meta http-equiv="Date" content="2023-01-18T00:31:02.370699+03:00" />
|
||||
<meta http-equiv="Last-Modified" content="2023-01-18T00:31:02.370777+03:00" />
|
||||
<meta http-equiv="Expires" content="2023-01-18T00:31:02.370817+03:00" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="Дома серии П-55: детальная информация" />
|
||||
<meta name="keywords" content=" П-55, серия П-55, проект П-55, года постройки зданий серии П-55, размеры окон в домах серии П-55, оконные проемы зданий серии П-55, дома серии П-55 на карте, установка окон, цены на пластиковые окна" />
|
||||
<meta name="author" content="OKNARDIA.RU" />
|
||||
<meta name="copyright" lang="ru" content="OKNARDIA.RU" />
|
||||
<meta name="robots" content="index,follow" />
|
||||
<meta name="document-state" content="Dynamic" />
|
||||
<meta name="generator" content="OKNARDIA 0.3β by Python/Django" />
|
||||
<title>Дома серии П-55 — типовые проёмы, размеры окон, схемы открывания, планировки, здания на карте, история и статистика : ОКНАРДИЯ</title>
|
||||
<link rel="alternate" href="https://oknardia.ru" hreflang="ru-ru" />
|
||||
<link href="/static/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="/static/css/bootstrap-theme.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="/static/css/oknardia1.css" rel="stylesheet" type="text/css" />
|
||||
<script src="/static/js/jquery-2.1.1.min.js" type="text/javascript"></script>
|
||||
<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).load(function () {
|
||||
let images = $('.half');
|
||||
images.each(function (i) {
|
||||
$(this).width($(this).width() / 2);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript">$(document).ready(function(){ $('#login-logout').load('/login-logout' ); })</script>
|
||||
</head>
|
||||
|
||||
<body style="padding-top:70px;">
|
||||
<!--- Контент НАЧАЛО --->
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-11 col-xs-12">
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="/">Главная</a></li>
|
||||
<li><a href="/catalog/">Каталог</a></li>
|
||||
<li><a href="/catalog/seria/">Типовые серии домов</a></li>
|
||||
<li>Серия П-55</li>
|
||||
</ol>
|
||||
<h1>СЕРИЯ П-55</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"><p>Типовой проект жилой серии П-55 <nobr>и П-55М</nobr> проектировался в конце 1970-х как шумозащитный. Размещение домов предполагалось вдоль больших автомагистралей или на границе промышленных зон. Возведением серии занимались в основном ДСК-4 и АО «Моспромстроиматериалов». Повышенная шумоизоляция достигалась благодаря использованию специальных трёхслойных керамзитбетонных панелей и оригинальной планировкой, благодаря которой на неблагоприятную сторону выходили главным образом нежилые помещения. Кроме того, внешний фасад имел минимальное число балконов, таким образом уменьшая проникновение пыли в жилые комнаты.</p>
|
||||
<p>Внешний фасад серии П-55 и П-55М выстраивался уступами, что значительной степени отражало шум. Сверх того, дома серии часто строили в виде Г- и П-образных конструкций и снабжали арками, что повышало защиту дворов. Но даже рядные — обычно двух- и трехсекционные блок-дома — в силу большой высотности<span style="margin-right:0.3em;"> </span><span style="margin-left:-0.3em;">(</span>10−14 этажей) являлись достаточным препятствием для проникновения шума и пыли в дворы, в стороны которых выходили окна жилых комнат и большое число балконов.</p>
|
||||
<p>Являясь поздними<span style="margin-right:0.44em;"> </span><span style="margin-left:-0.44em;">«</span>брежневскими» серией панельного строительства, в П-55 значительное внимание уделялось удобству: в подъездах расположено по два пассажирских лифта, большинство квартир с несколькими балконами, много трёх- и четырёхкомнатных квартир. Кроме того, проект П-55 отличает более высокие чем у предыдущих серий <nobr>потолки<span style="margin-right:0.3em;"> </span><span style="margin-left:-0.3em;">(</span>2 м 65 см)</nobr> и увеличенные размеры ванной и туалетной комнаты. Улучшенная серия П-55М ещё более комфортна: вторые санузлы в трёх- и четырёхкомнатных квартирах; входной блок подъезда и лифт адаптирован для инвалидов-колясочников.</p>
|
||||
<strong><p>В силу расположенности зданий серий П-55 вдоль шумных магистралей и промышленных зон, замена окон в них предполагает установку более качественных, дорогих, но и более защищённых конструкций<span style="margin-right:0.3em;"> </span><span style="margin-left:-0.3em;">(</span>особенно для внешнего фасада). В первую очередь следует отдавать предпочтение предложениям с повышенной шумоизоляцией:</p>
|
||||
<ul><li>двухкамерные стеклопакеты высокой звукоизоляции<span style="margin-right:0.3em;"> </span><span style="margin-left:-0.3em;">(</span>32 дБ и более) с несимметричными камерами или заполненные инертным газом;</li>
|
||||
<li>пятикамерные<span style="margin-right:0.3em;"> </span><span style="margin-left:-0.3em;">(</span>и выше) профили с шумовой защитой на ниже 3-го класса<span style="margin-right:0.3em;"> </span><span style="margin-left:-0.3em;">(</span>коэффициент звукоизоляции от 35 дБ)</li>
|
||||
<li>три и более контура уплотнения.</li></ul></strong></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-10">
|
||||
<h2 class="header">Дома серии П-55: типовые размеры и схемы открывания</h2>
|
||||
</div>
|
||||
<div class="col-lg-12" style="padding:1em 0 0 0;margin-left:-1em">
|
||||
|
||||
|
||||
<div class="win_discr pull-left" id="flap0">
|
||||
<div><img src="/static/img/_flap.cfg/087x142H216WN(G).png" alt="Окно на балкон для серии П-30, П-46 и П-55. Размер 870x1420 (Ш х В, мм.). Типовая схема открывания." title="Окно на балкон для серии П-30, П-46 и П-55. Размер 870x1420 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:100px;min-width:13ex;">
|
||||
<nobr>870×1420 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markA.svg');"></span></nobr><br />
|
||||
Окно на балкон для серии П-30, П-46 и П-55<br />
|
||||
<a href="/tsena-odnogo-okna/870x1420mm/tip12">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap1">
|
||||
<div><img src="/static/img/_flap.cfg/067x216H216D-(L).png" alt="Дверь на балкон для серии ГМС-1, П-3, П-42, П-43, П-55 и ПД-4. Размер 670x2160 (Ш х В, мм.). Типовая схема открывания." title="Дверь на балкон для серии ГМС-1, П-3, П-42, П-43, П-55 и ПД-4. Размер 670x2160 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:77px;min-width:13ex;">
|
||||
<nobr>670×2160 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markB.svg');"></span></nobr><br />
|
||||
Дверь на балкон для серии ГМС-1, П-3, П-42, П-43, П-55 и ПД-4<br />
|
||||
<a href="/tsena-odnogo-okna/670x2160mm/tip16">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap2">
|
||||
<div><img src="/static/img/_flap.cfg/147x142H216W-(G)(L_).png" alt="Окно двустворчатое для ГМС-1, П-30/44/46/55, ПД-4, 1-504 и КОПЭ. Размер 1470x1420 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое для ГМС-1, П-30/44/46/55, ПД-4, 1-504 и КОПЭ. Размер 1470x1420 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:170px;min-width:13ex;">
|
||||
<nobr>1470×1420 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markC.svg');"></span></nobr><br />
|
||||
Окно двустворчатое для ГМС-1, П-30/44/46/55, ПД-4, 1-504 и КОПЭ<br />
|
||||
<a href="/tsena-odnogo-okna/1470x1420mm/tip1">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap3">
|
||||
<div><img src="/static/img/_flap.cfg/206x142H216W-(G)(G)(L).png" alt="Окно трёхстворчатое для серии КОПЭ, П-55 и ПД-4. Размер 2060x1420 (Ш х В, мм.). Типовая схема открывания." title="Окно трёхстворчатое для серии КОПЭ, П-55 и ПД-4. Размер 2060x1420 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:238px;min-width:13ex;">
|
||||
<nobr>2060×1420 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markD.svg');"></span></nobr><br />
|
||||
Окно трёхстворчатое для серии КОПЭ, П-55 и ПД-4<br />
|
||||
<a href="/tsena-odnogo-okna/2060x1420mm/tip10">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-8 col-xs-12 col-md-offset-1">
|
||||
<h3 class="header">Оконные проёмы в типовых квартирах <nobr>серии П-55</nobr></h3>
|
||||
</div>
|
||||
<div class="col-lg-8 col-xs-12 col-md-offset-1">
|
||||
<!--- прешаблон начало ---><table style="padding:2px;">{% for row in TABLE_OF_WINDOWS %}
|
||||
<tr class="tr2">
|
||||
<td>{{ row.APART_NAME|safe }}</td>{% for col in row.WIN_IN_APART %}
|
||||
<td class="cntr">{% if col.WIN_ID %}<nobr title="{{ col.WIN_Q }} × {{ col.WIN_DESCRIPTION }}: {{ col.WIN_WIDTH }}шт.: {{ col.WIN_HEIGHT }} (Ш×В, см.). Схема открывания: {{ col.WIN_FLAPCFG }}">{% for I_II in col.WIN_NUM %}<span style="background-image:url('/static/img/svg/mark{{ I_II }}.svg');"> </span>{% endfor %}</nobr>{% else %}—{% endif %}</td>{% endfor %}
|
||||
<td style="background:#f9f9f9;"><a href="#{{ row.APART_ID }}" class="badge" title="Оконных предложений для квартиры: {{ row.NUM_OFFERS }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small> {{ row.NUM_OFFERS }}</a></td>
|
||||
</tr>{% endfor %}
|
||||
<tr class="trZ">
|
||||
<td style="font-size: xx-small;vertical-align:text-top">© 2015-2023, данные: oknardia.ru</td>{% for i in WIN_OFFER_AND_MERCHANT %}
|
||||
<td class="cntr" style="background:#f9f9f9;"><a href="/tsena-odnogo-okna/{{ i.WIN_W|floatformat:0 }}0x{{ i.WIN_H|floatformat:0 }}0mm/tip{{ i.WIN_ID }}" class="badge" title="Ценовых предложений для окна: {{ i.WIN_OFFER }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small> {{ i.WIN_OFFER }}</a></td>{% endfor %}
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--- прешаблон конец ---></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-9"><a name="s_graph"></a>
|
||||
<h2 class="header">Здания серия П-55: ввод в эксплуатацию по годам</h2>
|
||||
</div>
|
||||
<div class="col-md-9 col-md-offset-1" style="height:300px;font-size:large;">
|
||||
|
||||
<script type="text/javascript" src="https://www.google.com/jsapi" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
// google.charts.load('current', {'packages':['bar']});
|
||||
// google.charts.setOnLoadCallback(drawChart);
|
||||
google.load("visualization", "1", {packages:["corechart"]});
|
||||
google.setOnLoadCallback(drawChart);
|
||||
function drawChart() {
|
||||
let data = google.visualization.arrayToDataTable([
|
||||
["Год", "Введено в эксплуатацию", {role:'style'}],
|
||||
["1911",1,"color: #999b99"],
|
||||
["1926",1,"color: #999b99"],
|
||||
["1938",1,"color: #999b99"],
|
||||
["1958",1,"color: #999b99"],
|
||||
["1959",1,"color: #999b99"],
|
||||
["1960",1,"color: #999b99"],
|
||||
["1961",1,"color: #999b99"],
|
||||
["1965",1,"color: #999b99"],
|
||||
["1966",1,"color: #999b99"],
|
||||
["1967",2,"color: #999d99"],
|
||||
["1972",1,"color: #999b99"],
|
||||
["1981",9,"color: #99ac99"],
|
||||
["1982",4,"color: #99a199"],
|
||||
["1983",7,"color: #99a899"],
|
||||
["1984",8,"color: #99aa99"],
|
||||
["1985",6,"color: #99a699"],
|
||||
["1986",5,"color: #99a499"],
|
||||
["1987",12,"color: #99b399"],
|
||||
["1988",5,"color: #99a499"],
|
||||
["1989",7,"color: #99a899"],
|
||||
["1990",5,"color: #99a499"],
|
||||
["1991",8,"color: #99aa99"],
|
||||
["1992",13,"color: #99b599"],
|
||||
["1993",8,"color: #99aa99"],
|
||||
["1994",16,"color: #99bc99"],
|
||||
["1995",23,"color: #99cc99"],
|
||||
["1996",4,"color: #99a199"],
|
||||
["1997",10,"color: #99af99"],
|
||||
["1998",2,"color: #999d99"],
|
||||
["1999",4,"color: #99a199"],
|
||||
["2000",4,"color: #99a199"],
|
||||
["2001",3,"color: #999f99"],
|
||||
["2002",3,"color: #999f99"],
|
||||
["2003",4,"color: #99a199"],
|
||||
["2004",4,"color: #99a199"],
|
||||
["2005",2,"color: #999d99"],
|
||||
["2006",5,"color: #99a499"],
|
||||
["2009",1,"color: #999b99"],
|
||||
["2011",1,"color: #999b99"]
|
||||
]);
|
||||
let view = new google.visualization.DataView(data);
|
||||
view.setColumns([0, 1,
|
||||
{ calc: "stringify",
|
||||
sourceColumn: 1,
|
||||
type: "string",
|
||||
role: "annotation" },
|
||||
2
|
||||
]);
|
||||
let options = {
|
||||
animation:{
|
||||
duration: 1500,
|
||||
easing: 'in',
|
||||
startup: true
|
||||
},
|
||||
backgroundColor: "#EEEEEE",
|
||||
bar: {groupWidth: "76.4%"},
|
||||
chartArea: {left: "2%", top: "5%", width: '96%', height: '85%'},
|
||||
dataOpacity: 0.76,
|
||||
explorer:{
|
||||
maxZoomIn: 0.20,
|
||||
maxZoomOut: 32 },
|
||||
vAxis: {
|
||||
baselineColor:'grey',
|
||||
gridlines:{color: 'silver', count: 7},
|
||||
minorGridlines:{color: '#dddddd', count: 3},
|
||||
textPosition: 'in',
|
||||
textStyle: {fontSize: 10}
|
||||
},
|
||||
hAxis: { textStyle: {fontSize: 10} },
|
||||
isStacked: true,
|
||||
tooltip: {
|
||||
textStyle:{color: 'grey', fontSize: 10 },
|
||||
trigger: 'selection'
|
||||
},
|
||||
annotations: {textStyle: { fontSize: 8, bold: true, color: 'black', opacity: 0.8 }},
|
||||
legend: { position: "none" }
|
||||
};
|
||||
let chart = new google.visualization.ColumnChart(document.getElementById("graph"));
|
||||
chart.draw(data, options);
|
||||
}
|
||||
</script>
|
||||
<div id="graph" style="width:100%;height:100%">
|
||||
<p>Для отображения гистограммы ввода в эксплуатацию зданий серии П-55 нужна поддержка SVG.</p>
|
||||
<noscript>
|
||||
<p>Для визуализации отображения картографической информации с помощью Google.Charts нужно включить поддержку JavaScript.</p>
|
||||
</noscript></div>
|
||||
</div>
|
||||
<div class="col-md-9 col-md-offset-1">
|
||||
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-7"><a name="s_map"></a>
|
||||
<h2 class="header">Строения серии П-55 на карте</h2>
|
||||
</div>
|
||||
<div class="col-md-7 col-lg-offset-1">
|
||||
<p><small>Чтобы посмотреть цены на установку и замену окон от партнёров «Окнардия» в своей квартире: найдите дом на карте; кликните на него; перейдите по ссылке «Смотреть коммерческие предложения». При необходимости смените типовую планировку квартиры (на странице ценовой выдачи, справа от изображения типовых проёмов и схем открывания).</small></p>
|
||||
<div style="height:350px;">
|
||||
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
let points = [[55.984295,37.165136],[55.988117,37.157159],[55.700628,37.851754],[55.699218,37.854449],[55.775322,37.489850],[55.758737,37.820825],[55.758311,37.820502],[55.747844,37.817313],[55.870950,37.569135],[55.872885,37.568309],[55.874804,37.567536],[55.876046,37.566916],[55.877617,37.566368],[55.878692,37.566162],[55.876748,37.709488],[55.682234,37.855581],[55.545992,37.529852],[55.630944,37.479906],[55.629450,37.478127],[55.628647,37.475531],[55.543516,37.511544],[55.662273,37.532816],[55.661877,37.529807],[55.636356,37.747639],[55.634237,37.748601],[55.542202,37.512640],[55.686127,37.920871],[55.686051,37.857953],[55.683011,37.854404],[55.681250,37.852275],[55.852834,37.438071],[55.879662,37.571597],[55.806287,37.417994],[55.826068,37.807458],[55.636717,37.671166],[55.637088,37.667519],[55.637347,37.663836],[55.637459,37.660575],[55.636255,37.678649],[55.636448,37.675648],[55.864293,37.592258],[55.865621,37.593587],[55.795089,37.574022],[55.794953,37.572288],[55.587031,37.674777],[55.624281,37.664958],[55.623722,37.665884],[55.652105,37.744037],[55.724089,37.621390],[55.724900,37.621696],[55.724829,37.623151],[55.728322,37.622504],[55.722294,37.621534],[55.721265,37.623196],[55.726583,37.622064],[55.878117,37.698906],[55.877041,37.697783],[55.536405,37.580526],[55.537928,37.580921],[55.539574,37.581307],[55.772193,37.489571],[55.711584,37.755302],[55.712431,37.758554],[55.710788,37.752050],[55.742787,37.403621],[55.889386,37.675532],[55.890643,37.675163],[55.892117,37.674813],[55.859256,37.602058],[55.745407,37.785638],[55.703175,37.845547],[55.872546,37.590515],[55.846517,37.454753],[55.862878,37.447431],[55.865354,37.446470],[55.824187,37.803874],[55.824723,37.804790],[55.825285,37.805814],[55.878814,37.700882],[55.871147,37.590416],[55.717523,37.407295],[55.822837,37.757260],[55.823798,37.758275],[55.824026,37.759300],[55.741070,37.432232],[55.854517,37.683060],[55.879435,37.723115],[55.852501,37.680320],[55.784916,37.447917],[55.786465,37.447935],[55.856432,37.449641],[55.858554,37.448833],[55.800691,37.571704],[55.801283,37.571659],[55.801374,37.570330],[55.802664,37.569512],[55.802422,37.568713],[55.687066,37.566970],[55.682610,37.453765],[55.841134,37.527768],[55.841311,37.529151],[55.707912,37.481460],[55.706944,37.481864],[55.705858,37.480750],[55.705387,37.479950],[55.721128,37.567087],[55.822149,37.512074],[55.737461,37.584631],[55.724778,37.567069],[55.869849,37.660314],[55.828142,37.583661],[55.827100,37.585278],[55.826159,37.586778],[55.877304,37.679673],[55.875324,37.674535],[55.682305,37.454654],[55.681828,37.453693],[55.775251,37.642195],[55.788196,37.615066],[55.671747,37.746157],[55.703946,37.845098],[55.702368,37.848466],[55.545997,37.531927],[55.864783,37.475755],[55.689583,37.860477],[55.687731,37.859345],[55.567519,37.566961],[55.567519,37.566961],[55.567219,37.569171],[55.573831,37.582071],[55.577907,37.576843],[55.578503,37.574004],[55.578528,37.572603],[55.568313,37.587632],[55.569286,37.583472],[55.742874,37.852545],[55.742417,37.855734],[55.742990,37.858141],[55.743036,37.859111],[55.743406,37.862354],[55.744556,37.868014],[55.744733,37.869460],[55.745022,37.870430],[55.745448,37.872721],[55.745909,37.875056],[55.589274,37.640659],[55.648062,37.470042],[55.664218,37.747217],[55.668198,37.764007],[55.687335,37.564123],[55.677712,37.444440],[55.719906,37.412056],[55.852192,37.438206],[55.673184,37.816828],[55.865793,37.598250],[55.867667,37.592258],[55.862439,37.608859],[55.873541,37.705095],[55.683133,37.585449],[55.674199,37.748358],[55.673879,37.749508],[55.893970,37.542024],[55.875087,37.676205],[55.731881,37.589743],[55.830407,37.580104],[55.865384,37.679026],[55.676834,37.444826],[55.651242,37.725298],[55.869071,37.443488],[55.764420,37.702706],[55.740700,37.847990],[55.798303,37.402875],[55.798141,37.396497],[55.707781,37.742869],[55.707187,37.741360],[55.706776,37.740354],[55.718654,37.511275],[55.859670,37.499839],[55.826832,37.825290],[55.806125,37.614644],[55.539487,37.532187],[55.535121,37.517752],[55.535473,37.514967],[55.892345,37.541395],[55.664136,37.293927],[55.662928,37.291098],[55.896357,37.542356],[60.004600,30.452798],[60.004942,30.453840],[59.955741,30.428238],[59.963917,30.303004],[60.009008,30.432595],[55.749258,38.000147],[55.408900,37.559936],[55.681646,37.866082]];
|
||||
let forURL = [1660,1663,6878,6879,6944,7456,7459,7470,8401,8403,8405,8409,8410,8411,9800,10490,10617,10839,10843,10848,11079,11114,11116,12716,12717,13016,13937,14399,14402,14407,14477,16716,16808,16943,16956,16974,16975,16984,16987,16999,17030,17033,17252,17254,19136,19303,19305,19398,19447,19448,19449,19450,19451,19455,19460,19590,19591,20434,20435,20436,20862,22802,22809,22843,23073,23107,23108,23109,23247,24241,25175,25787,26358,26397,26415,28657,28658,28659,29699,31165,32025,32105,32106,32107,32336,32752,32763,32776,2947,2951,26383,29217,3652,3653,3654,3655,3656,17278,4481,9536,9537,13347,13348,13349,13350,15973,16379,16453,17771,20473,20605,20607,20609,23111,23114,23272,25089,27185,28382,5961,6882,6883,10615,12184,14388,14391,14913,14914,14951,25727,27337,27343,27344,27366,27369,27692,27699,27702,27703,27706,27709,27710,27711,27713,27716,9481,10741,13453,13468,16493,21660,32013,14480,14676,15150,15166,15154,23337,15277,18265,18273,31484,19056,19361,20614,26023,23287,24133,26427,27086,27682,27903,27913,28142,28150,28148,28641,28969,29377,30281,30664,30689,30692,31476,101581,101583,31489,43357,43358,47186,52972,53615,71678,77269,94744];
|
||||
|
||||
|
||||
ymaps.ready(function () {
|
||||
let myMap = new ymaps.Map('SeriaMap', {
|
||||
center: [55.75, 37.57],
|
||||
zoom: 10,
|
||||
behaviors: ['default', 'scrollZoom'],
|
||||
controls: [ 'rulerControl', 'zoomControl', 'geolocationControl', 'fullscreenControl' ]
|
||||
});
|
||||
// Создадим кластеризатор, вызвав функцию-конструктор.
|
||||
clusterer = new ymaps.Clusterer({
|
||||
preset: 'islands#invertedGrayClusterIcons',
|
||||
groupByCoordinates: false,
|
||||
hasHint: false,
|
||||
viewportMargin: 0,
|
||||
zoomMargin: 16,
|
||||
clusterDisableClickZoom: false,
|
||||
gridSize: 80
|
||||
});
|
||||
geoObjects = [];
|
||||
add_str1 = '<a href="/';
|
||||
add_str2 = '/0/">Смотреть коммерческие предложения</a>';
|
||||
add_str3 = '<b>Здание серии П-55</b>';
|
||||
// Данные передаются в конструктор метки.
|
||||
for(var i = 0, len = points.length; i < len; i++) {
|
||||
geoObjects[i] = new ymaps.Placemark( points[i],
|
||||
{ // Содержимое иконки, балуна и хинта.
|
||||
balloonContent: add_str1 + forURL[i] + add_str2,
|
||||
hintContent: add_str3
|
||||
},
|
||||
{ preset:'islands#circleIcon',iconColor: 'silver'} );
|
||||
geoObjects[i].events
|
||||
.add('mouseenter', function (e) {
|
||||
e.get('target').options.set('preset', 'islands#yellowCircleIcon');
|
||||
})
|
||||
.add('mouseleave', function (e) {
|
||||
e.get('target').options.set('preset', 'islands#grayCircleIcon');
|
||||
});
|
||||
}
|
||||
// Добавляем метки в кластеризатор.
|
||||
clusterer.add(geoObjects);
|
||||
myMap.geoObjects.add(clusterer);
|
||||
// позиционирование карты так, чтобы на ней были видны все объекты кластера.
|
||||
myMap.setBounds(clusterer.getBounds(), { checkZoomRange: true });
|
||||
});
|
||||
</script>
|
||||
<div id="SeriaMap" style="height:100%;width:100%;">
|
||||
<noscript>
|
||||
<p>Для отображения картографических данных по серии П-55 с помощью «Яндекс.Карт» нужно включить поддержку JavaScript.</p>
|
||||
</noscript>
|
||||
</div></div>
|
||||
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
|
||||
</div>
|
||||
|
||||
<diV class="col-md-4">
|
||||
<h3 class="header">Статистика <nobr>серии П-55</nobr></h3>
|
||||
<p>Совокупно во всех зданиях типового проекта:</p>
|
||||
<ul>
|
||||
<li><strong>26 772</strong> квартир.</li>
|
||||
<li>Проживает <strong>31 072</strong> семей <small>(<strong>171 092</strong> человек)</small>.</li>
|
||||
<li><strong>1 724 085.9 м²</strong> жилых помещений.</li>
|
||||
<li><strong>232 384.8 м²</strong> — муниципальное жильё.</li>
|
||||
<li><strong>70 828.3 м²</strong> занимают государственные и городские службы, учреждения бытового обслуживания, магазины, офисы и тому подобное.</li>
|
||||
<li>Максимальный износ жилого фонда серии П-55 — <strong>60.80 %</strong>. Минимальный — <strong>1.00 %</strong>. </li>
|
||||
</ul>
|
||||
</diV>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-lg-offset-8" style="margin-top: 1em;">
|
||||
<h5>Информация о других, отличных от П-55, типовых сериях в базе «Окнардия», типовых планировках квартир и оконных проёмах в них, а также рекомендации по замене окон:</h5>
|
||||
<div class="href_d"><span><a href="/catalog/seria/1-335/all210/"><nobr>1-335</nobr></a></span><span><a href="/catalog/seria/1-447/all379/"><nobr>1-447</nobr></a></span><span><a href="/catalog/seria/1-510/all39/"><nobr>1-510</nobr></a></span><span><a href="/catalog/seria/1-511/all100/"><nobr>1-511</nobr></a></span><span><a href="/catalog/seria/1-5155/all41/"><nobr>1-515/5</nobr></a></span><span><a href="/catalog/seria/1-5159/all843/"><nobr>1-515/9</nobr></a></span><span><a href="/catalog/seria/1605/all375/"><nobr>1605</nobr></a></span><span><a href="/catalog/seria/1lg-502/all2420/"><nobr>1ЛГ-502</nobr></a></span><span><a href="/catalog/seria/1lg-504/all2100/"><nobr>1ЛГ-504</nobr></a></span><span><a href="/catalog/seria/1lg-507/all2105/"><nobr>1ЛГ-507</nobr></a></span><span><a href="/catalog/seria/1r-303/all3568/"><nobr>1Р-303</nobr></a></span><span><a href="/catalog/seria/1r-30316/all4080/"><nobr>1Р-303.16</nobr></a></span><span><a href="/catalog/seria/ii-18/all18/"><nobr>II-18</nobr></a></span><span><a href="/catalog/seria/ii-29/all72/"><nobr>II-29</nobr></a></span><span><a href="/catalog/seria/ii-49/all12/"><nobr>II-49</nobr></a></span><span><a href="/catalog/seria/ii-57/all68/"><nobr>II-57</nobr></a></span><span><a href="/catalog/seria/ii-66/all80/"><nobr>II-66</nobr></a></span><span><a href="/catalog/seria/ii-68/all24/"><nobr>II-68</nobr></a></span><span><a href="/catalog/seria/gms-2001/all522/"><nobr>ГМС-2001</nobr></a></span><span><a href="/catalog/seria/i-209a/all44/"><nobr>И-209А</nobr></a></span><span><a href="/catalog/seria/k-7/all19/"><nobr>К-7</nobr></a></span><span><a href="/catalog/seria/kope/all17/"><nobr>КОПЭ</nobr></a></span><span><a href="/catalog/seria/mg-601/all492/"><nobr>МГ-601</nobr></a></span><span><a href="/catalog/seria/p-3/all9/"><nobr>П-3</nobr></a></span><span><a href="/catalog/seria/p-30/all79/"><nobr>П-30</nobr></a></span><span><a href="/catalog/seria/p-43/all178/"><nobr>П-43</nobr></a></span><span><a href="/catalog/seria/p-44/all8/"><nobr>П-44</nobr></a></span><span><a href="/catalog/seria/p-44t/all22/"><nobr>П-44Т</nobr></a></span><span><a href="/catalog/seria/p-46/all29/"><nobr>П-46</nobr></a></span><span><a href="/catalog/seria/p-55/all255/"><nobr>П-55</nobr></a></span><span><a href="/catalog/seria/pd-4/all148/"><nobr>ПД-4</nobr></a></span></div>
|
||||
<p style="text-align:right;padding-top:1em;padding-bottom:1em;"><a href="/stat_all/">Агрегированная информация<br />по типовым сериям домов<br />в базе «Окнардия»</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
{%include "report/report_last_user_visit.html" %}
|
||||
{% include "report/report_log_user_visit.html" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!---/ Контент КОНЕЦ --->
|
||||
|
||||
|
||||
|
||||
<nav class="navbar navbar-fixed-top navbar-default" role="navigation" id="header">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="/"><nobr><img src="/static/img/oknardia_logo.svg" onerror="this.onerror=null;this.src='/static/img/oknardia_logo.gif';this.width=290;this.height=34" title="Перейти на гравную сраницу «Окнардия»" alt="Логотип «Окнардия — оконный агрегатор»" ></nobr></a>
|
||||
</div>
|
||||
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li><a href="/catalog">Каталог</a></li>
|
||||
<li><a href="/stat/rating/">Рейтинги</a></li>
|
||||
<li><a href="/blog">Блог</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" rel="nofollow">О проекте <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="/stat_all">Статистика</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li><a href="/contact">Контакты</a></li>
|
||||
<li><a href="/blogpost/2/My_zhdem_vashi_prajs-listy!">Сотрудничество</a></li>
|
||||
<li><a href="/tariff">Услуги и тарифы</a></li>
|
||||
<!-- li class="divider"></li>
|
||||
<li><a href="#" rel="nofollow">Обратная связь</a></li -->
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown" id="login-logout"><!--- Сюда подгружают AJAX-ом блок login-logout ---><small><br />Авторизации.<noscript style="color:red;">Для авторизации необходимо включить JavaScript.</noscript></small></li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="row panel-footer">
|
||||
<div class="col-xs-12">
|
||||
<span style="top:-200px;left:-8000px;position: absolute;"><script type="text/javascript">
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
ga('create', 'UA-9116991-5', 'auto'); ga('send', 'pageview');
|
||||
var _tmr=_tmr||[];_tmr.push({id:"2018432",type:"pageView",start:(new Date()).getTime()});(function (d,w,id){if(d.getElementById(id))return;var ts=d.createElement("script");ts.type="text/javascript";ts.async=true;ts.id=id;ts.src=(d.location.protocol=="https:"?"https:":"http:")+"//top-fwz1.mail.ru/js/code.js";var f=function(){var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(ts, s);};if(w.opera=="[object Opera]"){ d.addEventListener("DOMContentLoaded",f,false);}else{f();}})(document,window,"topmailru-code");
|
||||
</script><noscript><div style="position:absolute;left:-10000px;">
|
||||
<img src="//top-fwz1.mail.ru/counter?id=2018432;js=na" style="border:0;height:1px;width:1px" alt="" />
|
||||
<img src="//mc.yandex.ru/watch/32997984" style="border:0;height:1px;width:1px" alt="" />
|
||||
</div></noscript>
|
||||
<a target="_blank" href="http://top.mail.ru/jump?from=2018432"><img src="//top-fwz1.mail.ru/counter?id=2018432;t=216;l=1" style="border:0;padding-top:8px;" rel="nofollow" alt="Рейтинг@Mail.ru"></a>
|
||||
<a href="https://metrika.yandex.ru/stat/?id=32997984&from=informer" target="_blank" rel="nofollow"><img src="https://informer.yandex.ru/informer/32997984/3_0_E0E0E0FF_C0C0C0FF_0_pageviews" style="width:88px; height:31px; border:0;" alt="Яндекс.Метрика" title="Яндекс.Метрика: данные за сегодня (просмотры, визиты и уникальные посетители)" onclick="try{Ya.Metrika.informer({i:this,id:32997984,lang:'ru'});return false}catch(e){}" /></a>
|
||||
<span id="rambler"><script id="top100Counter" type="text/javascript" src="//counter.rambler.ru/top100.jcn?3148853"></script><noscript><a href="http://top100.rambler.ru/navi/3148853/"><img src="http://counter.rambler.ru/top100.cnt?3148853" alt="Rambler's Top100" border="0"/></a></noscript></span>
|
||||
<script type="text/javascript"><!--
|
||||
document.write("<a href='//www.liveinternet.ru/click' target=_blank><img src='//counter.yadro.ru/hit?t50.2;r"+escape(document.referrer)+((typeof(screen)=="undefined")?"":";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth?screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+";"+Math.random()+"' alt='' title='LiveInternet' style='border:0;padding-top:8px;'><\/a>");
|
||||
(function(d,w,c){(w[c]=w[c]||[]).push(function(){try{w.yaCounter32997984=new Ya.Metrika({id:32997984,clickmap:true,trackLinks:true,accurateTrackBounce:true,webvisor:true,trackHash:true});}catch(e){}});var n=d.getElementsByTagName("script")[0],s=d.createElement("script"),f=function(){n.parentNode.insertBefore(s,n);};s.type="text/javascript";s.async=true;s.src="https://mc.yandex.ru/metrika/watch.js";if(w.opera=="[object Opera]"){d.addEventListener("DOMContentLoaded",f,false);}else{ f();}})(document,window,"yandex_metrika_callbacks");
|
||||
//--></script>
|
||||
</span>
|
||||
<small>© oknardia.ru, 2015-2023. <a href="/blogpost/18/Ob-avtorskih-pravah">Все права защищены</a>.<!--- Время отработки скрипта: сек---></small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,368 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru-RU">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="content-language" content="ru" />
|
||||
<meta http-equiv="Date" content="2023-01-18T00:29:49.428154+03:00" />
|
||||
<meta http-equiv="Last-Modified" content="2023-01-18T00:29:49.428202+03:00" />
|
||||
<meta http-equiv="Expires" content="2023-01-18T00:29:49.428224+03:00" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="Дома серии 1Р-303: детальная информация" />
|
||||
<meta name="keywords" content=" 1Р-303, серия 1Р-303, проект 1Р-303, года постройки зданий серии 1Р-303, размеры окон в домах серии 1Р-303, оконные проемы зданий серии 1Р-303, дома серии 1Р-303 на карте, установка окон, цены на пластиковые окна" />
|
||||
<meta name="author" content="OKNARDIA.RU" />
|
||||
<meta name="copyright" lang="ru" content="OKNARDIA.RU" />
|
||||
<meta name="robots" content="index,follow" />
|
||||
<meta name="document-state" content="Dynamic" />
|
||||
<meta name="generator" content="OKNARDIA 0.3β by Python/Django" />
|
||||
<title>Дома серии 1Р-303 — типовые проёмы, размеры окон, схемы открывания, планировки, здания на карте, история и статистика : ОКНАРДИЯ</title>
|
||||
<link rel="alternate" href="https://oknardia.ru" hreflang="ru-ru" />
|
||||
<link href="/static/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="/static/css/bootstrap-theme.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="/static/css/oknardia1.css" rel="stylesheet" type="text/css" />
|
||||
<script src="/static/js/jquery-2.1.1.min.js" type="text/javascript"></script>
|
||||
<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).load(function () {
|
||||
let images = $('.half');
|
||||
images.each(function (i) {
|
||||
$(this).width($(this).width() / 2);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript">$(document).ready(function(){ $('#login-logout').load('/login-logout' ); })</script>
|
||||
</head>
|
||||
|
||||
<body style="padding-top:70px;">
|
||||
<!--- Контент НАЧАЛО --->
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-11 col-xs-12">
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="/">Главная</a></li>
|
||||
<li><a href="/catalog/">Каталог</a></li>
|
||||
<li><a href="/catalog/seria/">Типовые серии домов</a></li>
|
||||
<li>Серия 1Р-303</li>
|
||||
</ol>
|
||||
<h1>СЕРИЯ 1Р-303</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-10">
|
||||
<h2 class="header">Дома серии 1Р-303: типовые размеры и схемы открывания</h2>
|
||||
</div>
|
||||
<div class="col-lg-12" style="padding:1em 0 0 0;margin-left:-1em">
|
||||
|
||||
|
||||
<div class="win_discr pull-left" id="flap0">
|
||||
<div><img src="/static/img/_flap.cfg/062x132H210WN(G).png" alt="Окно одностворчатое на балкон для серии 1P-303. Размер 620x1320 (Ш х В, мм.). Типовая схема открывания." title="Окно одностворчатое на балкон для серии 1P-303. Размер 620x1320 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:73px;min-width:13ex;">
|
||||
<nobr>620×1320 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markA.svg');"></span></nobr><br />
|
||||
Окно одностворчатое на балкон для серии 1P-303<br />
|
||||
<a href="/tsena-odnogo-okna/620x1320mm/tip73">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap1">
|
||||
<div><img src="/static/img/_flap.cfg/120x132H210WN(G)(L_).png" alt="Окно двустворчатое на балкон для серии 1P-303. Размер 1200x1320 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое на балкон для серии 1P-303. Размер 1200x1320 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:142px;min-width:13ex;">
|
||||
<nobr>1200×1320 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markB.svg');"></span></nobr><br />
|
||||
Окно двустворчатое на балкон для серии 1P-303<br />
|
||||
<a href="/tsena-odnogo-okna/1200x1320mm/tip74">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap2">
|
||||
<div><img src="/static/img/_flap.cfg/068x210H210D-(G).png" alt="Дверь на балкон для серий 1P-303, 1P-303.16 и 1ЛГ-504. Размер 680x2100 (Ш х В, мм.). Типовая схема открывания." title="Дверь на балкон для серий 1P-303, 1P-303.16 и 1ЛГ-504. Размер 680x2100 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:80px;min-width:13ex;">
|
||||
<nobr>680×2100 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markC.svg');"></span></nobr><br />
|
||||
Дверь на балкон для серий 1P-303, 1P-303.16 и 1ЛГ-504<br />
|
||||
<a href="/tsena-odnogo-okna/680x2100mm/tip77">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap3">
|
||||
<div><img src="/static/img/_flap.cfg/128x132H210W-(G)(L).png" alt="Окно двустворчатое для серии МГ-601 и 1P-303. Размер 1280x1320 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое для серии МГ-601 и 1P-303. Размер 1280x1320 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:152px;min-width:13ex;">
|
||||
<nobr>1280×1320 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markD.svg');"></span></nobr><br />
|
||||
Окно двустворчатое для серии МГ-601 и 1P-303<br />
|
||||
<a href="/tsena-odnogo-okna/1280x1320mm/tip52">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap4">
|
||||
<div><img src="/static/img/_flap.cfg/186x132H210W-(G)(L_)(L).png" alt="Окно трёхстворчатое для серии 1P-303. Размер 1860x1320 (Ш х В, мм.). Типовая схема открывания." title="Окно трёхстворчатое для серии 1P-303. Размер 1860x1320 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:221px;min-width:13ex;">
|
||||
<nobr>1860×1320 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markE.svg');"></span></nobr><br />
|
||||
Окно трёхстворчатое для серии 1P-303<br />
|
||||
<a href="/tsena-odnogo-okna/1860x1320mm/tip72">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-8 col-xs-12 col-md-offset-1">
|
||||
<h3 class="header">Оконные проёмы в типовых квартирах <nobr>серии 1Р-303</nobr></h3>
|
||||
</div>
|
||||
<div class="col-lg-8 col-xs-12 col-md-offset-1">
|
||||
<!--- прешаблон начало ---><table style="padding:2px;">{% for row in TABLE_OF_WINDOWS %}
|
||||
<tr class="tr2">
|
||||
<td>{{ row.APART_NAME|safe }}</td>{% for col in row.WIN_IN_APART %}
|
||||
<td class="cntr">{% if col.WIN_ID %}<nobr title="{{ col.WIN_Q }} × {{ col.WIN_DESCRIPTION }}: {{ col.WIN_WIDTH }}шт.: {{ col.WIN_HEIGHT }} (Ш×В, см.). Схема открывания: {{ col.WIN_FLAPCFG }}">{% for I_II in col.WIN_NUM %}<span style="background-image:url('/static/img/svg/mark{{ I_II }}.svg');"> </span>{% endfor %}</nobr>{% else %}—{% endif %}</td>{% endfor %}
|
||||
<td style="background:#f9f9f9;"><a href="#{{ row.APART_ID }}" class="badge" title="Оконных предложений для квартиры: {{ row.NUM_OFFERS }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small> {{ row.NUM_OFFERS }}</a></td>
|
||||
</tr>{% endfor %}
|
||||
<tr class="trZ">
|
||||
<td style="font-size: xx-small;vertical-align:text-top">© 2015-2023, данные: oknardia.ru</td>{% for i in WIN_OFFER_AND_MERCHANT %}
|
||||
<td class="cntr" style="background:#f9f9f9;"><a href="/tsena-odnogo-okna/{{ i.WIN_W|floatformat:0 }}0x{{ i.WIN_H|floatformat:0 }}0mm/tip{{ i.WIN_ID }}" class="badge" title="Ценовых предложений для окна: {{ i.WIN_OFFER }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small> {{ i.WIN_OFFER }}</a></td>{% endfor %}
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--- прешаблон конец ---></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-9"><a name="s_graph"></a>
|
||||
<h2 class="header">Здания серия 1Р-303: ввод в эксплуатацию по годам</h2>
|
||||
</div>
|
||||
<div class="col-md-9 col-md-offset-1" style="height:300px;font-size:large;">
|
||||
|
||||
<script type="text/javascript" src="https://www.google.com/jsapi" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
// google.charts.load('current', {'packages':['bar']});
|
||||
// google.charts.setOnLoadCallback(drawChart);
|
||||
google.load("visualization", "1", {packages:["corechart"]});
|
||||
google.setOnLoadCallback(drawChart);
|
||||
function drawChart() {
|
||||
let data = google.visualization.arrayToDataTable([
|
||||
["Год", "Введено в эксплуатацию", {role:'style'}],
|
||||
["1960",2,"color: #999e99"],
|
||||
["1964",6,"color: #99aa99"],
|
||||
["1965",6,"color: #99aa99"],
|
||||
["1966",5,"color: #99a799"],
|
||||
["1967",5,"color: #99a799"],
|
||||
["1968",7,"color: #99ac99"],
|
||||
["1969",6,"color: #99aa99"],
|
||||
["1970",7,"color: #99ac99"],
|
||||
["1971",10,"color: #99b599"],
|
||||
["1972",7,"color: #99ac99"],
|
||||
["1973",11,"color: #99b899"],
|
||||
["1974",11,"color: #99b899"],
|
||||
["1975",5,"color: #99a799"],
|
||||
["1976",8,"color: #99af99"],
|
||||
["1977",3,"color: #99a199"],
|
||||
["1978",5,"color: #99a799"],
|
||||
["1979",2,"color: #999e99"]
|
||||
]);
|
||||
let view = new google.visualization.DataView(data);
|
||||
view.setColumns([0, 1,
|
||||
{ calc: "stringify",
|
||||
sourceColumn: 1,
|
||||
type: "string",
|
||||
role: "annotation" },
|
||||
2
|
||||
]);
|
||||
let options = {
|
||||
animation:{
|
||||
duration: 1500,
|
||||
easing: 'in',
|
||||
startup: true
|
||||
},
|
||||
backgroundColor: "#EEEEEE",
|
||||
bar: {groupWidth: "76.4%"},
|
||||
chartArea: {left: "2%", top: "5%", width: '96%', height: '85%'},
|
||||
dataOpacity: 0.76,
|
||||
explorer:{
|
||||
maxZoomIn: 0.20,
|
||||
maxZoomOut: 32 },
|
||||
vAxis: {
|
||||
baselineColor:'grey',
|
||||
gridlines:{color: 'silver', count: 7},
|
||||
minorGridlines:{color: '#dddddd', count: 3},
|
||||
textPosition: 'in',
|
||||
textStyle: {fontSize: 10}
|
||||
},
|
||||
hAxis: { textStyle: {fontSize: 10} },
|
||||
isStacked: true,
|
||||
tooltip: {
|
||||
textStyle:{color: 'grey', fontSize: 10 },
|
||||
trigger: 'selection'
|
||||
},
|
||||
annotations: {textStyle: { fontSize: 8, bold: true, color: 'black', opacity: 0.8 }},
|
||||
legend: { position: "none" }
|
||||
};
|
||||
let chart = new google.visualization.ColumnChart(document.getElementById("graph"));
|
||||
chart.draw(data, options);
|
||||
}
|
||||
</script>
|
||||
<div id="graph" style="width:100%;height:100%">
|
||||
<p>Для отображения гистограммы ввода в эксплуатацию зданий серии 1Р-303 нужна поддержка SVG.</p>
|
||||
<noscript>
|
||||
<p>Для визуализации отображения картографической информации с помощью Google.Charts нужно включить поддержку JavaScript.</p>
|
||||
</noscript></div>
|
||||
</div>
|
||||
<div class="col-md-9 col-md-offset-1">
|
||||
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-7"><a name="s_map"></a>
|
||||
<h2 class="header">Строения серии 1Р-303 на карте</h2>
|
||||
</div>
|
||||
<div class="col-md-7 col-lg-offset-1">
|
||||
<p><small>Чтобы посмотреть цены на установку и замену окон от партнёров «Окнардия» в своей квартире: найдите дом на карте; кликните на него; перейдите по ссылке «Смотреть коммерческие предложения». При необходимости смените типовую планировку квартиры (на странице ценовой выдачи, справа от изображения типовых проёмов и схем открывания).</small></p>
|
||||
<div style="height:350px;">
|
||||
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
let points = [[55.476082,37.305048],[55.474919,37.303701],[56.014202,37.467644],[56.015701,37.463933],[56.014806,37.462900],[56.015877,37.462712],[56.015228,37.462505],[56.014705,37.462029],[56.014594,37.466772],[56.014947,37.465604],[55.650785,37.407268],[55.790762,37.966235],[55.790534,37.968886],[55.792706,37.960441],[55.791425,37.960414],[55.791218,37.961052],[55.791946,37.962445],[55.792792,37.964448],[55.791987,37.965616],[55.793288,37.968957],[55.893480,37.451088],[55.893415,37.450072],[56.369417,37.531586],[56.365553,37.532717],[56.369177,37.539958],[56.364486,37.532484],[56.364815,37.533086],[56.363892,37.534029],[56.364002,37.534981],[56.365523,37.539266],[56.366206,37.539724],[56.348422,37.524992],[56.348422,37.524992],[56.348422,37.524992],[56.348422,37.524992],[56.348422,37.524992],[56.348422,37.524992],[56.348422,37.524992],[56.348422,37.524992],[56.348422,37.524992],[56.348422,37.524992],[56.348422,37.524992],[56.354193,37.549983],[56.341488,37.519647],[56.341318,37.520716],[56.341099,37.521776],[56.334408,37.535655],[56.334752,37.536526],[56.338509,37.546956],[56.336987,37.546911],[56.336423,37.545968],[56.337806,37.548061],[56.338444,37.547630],[56.337875,37.547288],[56.338130,37.548869],[56.341064,37.547270],[56.337257,37.552193],[56.337027,37.549327],[56.339682,37.544962],[56.338404,37.519126],[56.337716,37.515111],[56.340161,37.536212],[56.339732,37.538296],[56.355894,37.527741],[56.341702,37.518533],[56.339382,37.518785],[56.284079,37.486760],[56.283480,37.488269],[56.283405,37.487640],[55.939802,36.710148],[55.939958,36.711603],[55.939303,36.711828],[55.939504,36.712574],[55.940427,36.712583],[55.939313,36.709169],[55.938632,36.709421],[55.938859,36.710157],[55.906471,37.729997],[55.904195,37.726574],[55.901031,37.723825],[55.900153,37.722837],[55.899320,37.721840],[55.898492,37.722828],[55.906592,37.728649],[55.892092,37.715695],[55.892274,37.714923],[55.943240,37.777158],[55.907460,37.728631],[55.909060,37.725200],[55.908439,37.723690],[55.905719,37.731874],[55.906254,37.730940],[55.891850,37.716576],[56.458328,38.093087],[56.738616,37.532969],[56.738611,37.531631],[56.739031,37.530948],[56.739322,37.528172],[56.739994,37.528684],[56.741134,37.529376],[56.741573,37.529484],[56.742773,37.529430],[56.742462,37.538341],[56.725561,37.516126],[56.738942,37.528936],[56.740749,37.528531],[55.694885,37.750963],[56.047650,37.481855],[56.047042,37.481271],[56.046509,37.480256],[56.048329,37.482232],[56.047243,37.480714],[56.048053,37.482798],[56.046771,37.481729],[56.367946,37.536634],[56.319774,36.760005],[56.365069,37.538224],[56.366410,37.538898],[55.939857,36.713346],[55.942086,36.712133],[55.941556,36.712259],[55.941344,36.711630],[55.941133,36.710984],[55.939207,36.710957]];
|
||||
let forURL = [2259,2263,75796,75797,75800,75802,75803,75804,75805,75807,14599,69570,69573,69963,69965,69966,69967,69968,69973,69976,81184,81199,86240,86246,86252,86260,86267,86272,86273,86275,86276,86283,86288,86290,86295,86296,86297,86299,86300,86301,86302,86304,86429,86449,86450,86451,86469,86470,86533,86540,86542,86544,86545,86546,86549,86550,86552,86554,86569,86570,86585,86595,86596,86613,86631,86677,86778,86779,86780,89386,89390,89391,89392,89394,89413,89414,89415,97269,97278,97290,97294,97298,97299,97308,97703,97704,98024,98059,98068,98069,98076,98079,98090,109134,111240,111241,111242,111247,111248,111249,111252,111257,111266,111302,114852,114853,114854,83160,83161,83162,83167,83169,83175,83176,86243,91347,86274,86277,89393,89395,89396,89397,89398,89416];
|
||||
|
||||
|
||||
ymaps.ready(function () {
|
||||
let myMap = new ymaps.Map('SeriaMap', {
|
||||
center: [55.75, 37.57],
|
||||
zoom: 10,
|
||||
behaviors: ['default', 'scrollZoom'],
|
||||
controls: [ 'rulerControl', 'zoomControl', 'geolocationControl', 'fullscreenControl' ]
|
||||
});
|
||||
// Создадим кластеризатор, вызвав функцию-конструктор.
|
||||
clusterer = new ymaps.Clusterer({
|
||||
preset: 'islands#invertedGrayClusterIcons',
|
||||
groupByCoordinates: false,
|
||||
hasHint: false,
|
||||
viewportMargin: 0,
|
||||
zoomMargin: 16,
|
||||
clusterDisableClickZoom: false,
|
||||
gridSize: 80
|
||||
});
|
||||
geoObjects = [];
|
||||
add_str1 = '<a href="/';
|
||||
add_str2 = '/0/">Смотреть коммерческие предложения</a>';
|
||||
add_str3 = '<b>Здание серии 1Р-303</b>';
|
||||
// Данные передаются в конструктор метки.
|
||||
for(var i = 0, len = points.length; i < len; i++) {
|
||||
geoObjects[i] = new ymaps.Placemark( points[i],
|
||||
{ // Содержимое иконки, балуна и хинта.
|
||||
balloonContent: add_str1 + forURL[i] + add_str2,
|
||||
hintContent: add_str3
|
||||
},
|
||||
{ preset:'islands#circleIcon',iconColor: 'silver'} );
|
||||
geoObjects[i].events
|
||||
.add('mouseenter', function (e) {
|
||||
e.get('target').options.set('preset', 'islands#yellowCircleIcon');
|
||||
})
|
||||
.add('mouseleave', function (e) {
|
||||
e.get('target').options.set('preset', 'islands#grayCircleIcon');
|
||||
});
|
||||
}
|
||||
// Добавляем метки в кластеризатор.
|
||||
clusterer.add(geoObjects);
|
||||
myMap.geoObjects.add(clusterer);
|
||||
// позиционирование карты так, чтобы на ней были видны все объекты кластера.
|
||||
myMap.setBounds(clusterer.getBounds(), { checkZoomRange: true });
|
||||
});
|
||||
</script>
|
||||
<div id="SeriaMap" style="height:100%;width:100%;">
|
||||
<noscript>
|
||||
<p>Для отображения картографических данных по серии 1Р-303 с помощью «Яндекс.Карт» нужно включить поддержку JavaScript.</p>
|
||||
</noscript>
|
||||
</div></div>
|
||||
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
|
||||
</div>
|
||||
|
||||
<diV class="col-md-4">
|
||||
<h3 class="header">Статистика <nobr>серии 1Р-303</nobr></h3>
|
||||
<p>Совокупно во всех зданиях типового проекта:</p>
|
||||
<ul>
|
||||
<li><strong>7 899</strong> квартир.</li>
|
||||
<li>Проживает <strong>9 247</strong> семей <small>(<strong>45 176</strong> человек)</small>.</li>
|
||||
<li><strong>345 222.8 м²</strong> жилых помещений.</li>
|
||||
<li><strong>64 146.2 м²</strong> — муниципальное жильё.</li>
|
||||
<li><strong>0.0 м²</strong> занимают государственные и городские службы, учреждения бытового обслуживания, магазины, офисы и тому подобное.</li>
|
||||
<li>Максимальный износ жилого фонда серии 1Р-303 — <strong>60.00 %</strong>. Минимальный — <strong>10.00 %</strong>. </li>
|
||||
</ul>
|
||||
</diV>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-lg-offset-8" style="margin-top: 1em;">
|
||||
<h5>Информация о других, отличных от 1Р-303, типовых сериях в базе «Окнардия», типовых планировках квартир и оконных проёмах в них, а также рекомендации по замене окон:</h5>
|
||||
<div class="href_d"><span><a href="/catalog/seria/1-335/all210/"><nobr>1-335</nobr></a></span><span><a href="/catalog/seria/1-447/all379/"><nobr>1-447</nobr></a></span><span><a href="/catalog/seria/1-510/all39/"><nobr>1-510</nobr></a></span><span><a href="/catalog/seria/1-511/all100/"><nobr>1-511</nobr></a></span><span><a href="/catalog/seria/1-5155/all41/"><nobr>1-515/5</nobr></a></span><span><a href="/catalog/seria/1-5159/all843/"><nobr>1-515/9</nobr></a></span><span><a href="/catalog/seria/1605/all375/"><nobr>1605</nobr></a></span><span><a href="/catalog/seria/1lg-502/all2420/"><nobr>1ЛГ-502</nobr></a></span><span><a href="/catalog/seria/1lg-504/all2100/"><nobr>1ЛГ-504</nobr></a></span><span><a href="/catalog/seria/1lg-507/all2105/"><nobr>1ЛГ-507</nobr></a></span><span><a href="/catalog/seria/1r-303/all3568/"><nobr>1Р-303</nobr></a></span><span><a href="/catalog/seria/1r-30316/all4080/"><nobr>1Р-303.16</nobr></a></span><span><a href="/catalog/seria/ii-18/all18/"><nobr>II-18</nobr></a></span><span><a href="/catalog/seria/ii-29/all72/"><nobr>II-29</nobr></a></span><span><a href="/catalog/seria/ii-49/all12/"><nobr>II-49</nobr></a></span><span><a href="/catalog/seria/ii-57/all68/"><nobr>II-57</nobr></a></span><span><a href="/catalog/seria/ii-66/all80/"><nobr>II-66</nobr></a></span><span><a href="/catalog/seria/ii-68/all24/"><nobr>II-68</nobr></a></span><span><a href="/catalog/seria/gms-2001/all522/"><nobr>ГМС-2001</nobr></a></span><span><a href="/catalog/seria/i-209a/all44/"><nobr>И-209А</nobr></a></span><span><a href="/catalog/seria/k-7/all19/"><nobr>К-7</nobr></a></span><span><a href="/catalog/seria/kope/all17/"><nobr>КОПЭ</nobr></a></span><span><a href="/catalog/seria/mg-601/all492/"><nobr>МГ-601</nobr></a></span><span><a href="/catalog/seria/p-3/all9/"><nobr>П-3</nobr></a></span><span><a href="/catalog/seria/p-30/all79/"><nobr>П-30</nobr></a></span><span><a href="/catalog/seria/p-43/all178/"><nobr>П-43</nobr></a></span><span><a href="/catalog/seria/p-44/all8/"><nobr>П-44</nobr></a></span><span><a href="/catalog/seria/p-44t/all22/"><nobr>П-44Т</nobr></a></span><span><a href="/catalog/seria/p-46/all29/"><nobr>П-46</nobr></a></span><span><a href="/catalog/seria/p-55/all255/"><nobr>П-55</nobr></a></span><span><a href="/catalog/seria/pd-4/all148/"><nobr>ПД-4</nobr></a></span></div>
|
||||
<p style="text-align:right;padding-top:1em;padding-bottom:1em;"><a href="/stat_all/">Агрегированная информация<br />по типовым сериям домов<br />в базе «Окнардия»</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
{%include "report/report_last_user_visit.html" %}
|
||||
{% include "report/report_log_user_visit.html" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!---/ Контент КОНЕЦ --->
|
||||
|
||||
|
||||
|
||||
<nav class="navbar navbar-fixed-top navbar-default" role="navigation" id="header">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="/"><nobr><img src="/static/img/oknardia_logo.svg" onerror="this.onerror=null;this.src='/static/img/oknardia_logo.gif';this.width=290;this.height=34" title="Перейти на гравную сраницу «Окнардия»" alt="Логотип «Окнардия — оконный агрегатор»" ></nobr></a>
|
||||
</div>
|
||||
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li><a href="/catalog">Каталог</a></li>
|
||||
<li><a href="/stat/rating/">Рейтинги</a></li>
|
||||
<li><a href="/blog">Блог</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" rel="nofollow">О проекте <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="/stat_all">Статистика</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li><a href="/contact">Контакты</a></li>
|
||||
<li><a href="/blogpost/2/My_zhdem_vashi_prajs-listy!">Сотрудничество</a></li>
|
||||
<li><a href="/tariff">Услуги и тарифы</a></li>
|
||||
<!-- li class="divider"></li>
|
||||
<li><a href="#" rel="nofollow">Обратная связь</a></li -->
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown" id="login-logout"><!--- Сюда подгружают AJAX-ом блок login-logout ---><small><br />Авторизации.<noscript style="color:red;">Для авторизации необходимо включить JavaScript.</noscript></small></li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="row panel-footer">
|
||||
<div class="col-xs-12">
|
||||
<span style="top:-200px;left:-8000px;position: absolute;"><script type="text/javascript">
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
ga('create', 'UA-9116991-5', 'auto'); ga('send', 'pageview');
|
||||
var _tmr=_tmr||[];_tmr.push({id:"2018432",type:"pageView",start:(new Date()).getTime()});(function (d,w,id){if(d.getElementById(id))return;var ts=d.createElement("script");ts.type="text/javascript";ts.async=true;ts.id=id;ts.src=(d.location.protocol=="https:"?"https:":"http:")+"//top-fwz1.mail.ru/js/code.js";var f=function(){var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(ts, s);};if(w.opera=="[object Opera]"){ d.addEventListener("DOMContentLoaded",f,false);}else{f();}})(document,window,"topmailru-code");
|
||||
</script><noscript><div style="position:absolute;left:-10000px;">
|
||||
<img src="//top-fwz1.mail.ru/counter?id=2018432;js=na" style="border:0;height:1px;width:1px" alt="" />
|
||||
<img src="//mc.yandex.ru/watch/32997984" style="border:0;height:1px;width:1px" alt="" />
|
||||
</div></noscript>
|
||||
<a target="_blank" href="http://top.mail.ru/jump?from=2018432"><img src="//top-fwz1.mail.ru/counter?id=2018432;t=216;l=1" style="border:0;padding-top:8px;" rel="nofollow" alt="Рейтинг@Mail.ru"></a>
|
||||
<a href="https://metrika.yandex.ru/stat/?id=32997984&from=informer" target="_blank" rel="nofollow"><img src="https://informer.yandex.ru/informer/32997984/3_0_E0E0E0FF_C0C0C0FF_0_pageviews" style="width:88px; height:31px; border:0;" alt="Яндекс.Метрика" title="Яндекс.Метрика: данные за сегодня (просмотры, визиты и уникальные посетители)" onclick="try{Ya.Metrika.informer({i:this,id:32997984,lang:'ru'});return false}catch(e){}" /></a>
|
||||
<span id="rambler"><script id="top100Counter" type="text/javascript" src="//counter.rambler.ru/top100.jcn?3148853"></script><noscript><a href="http://top100.rambler.ru/navi/3148853/"><img src="http://counter.rambler.ru/top100.cnt?3148853" alt="Rambler's Top100" border="0"/></a></noscript></span>
|
||||
<script type="text/javascript"><!--
|
||||
document.write("<a href='//www.liveinternet.ru/click' target=_blank><img src='//counter.yadro.ru/hit?t50.2;r"+escape(document.referrer)+((typeof(screen)=="undefined")?"":";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth?screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+";"+Math.random()+"' alt='' title='LiveInternet' style='border:0;padding-top:8px;'><\/a>");
|
||||
(function(d,w,c){(w[c]=w[c]||[]).push(function(){try{w.yaCounter32997984=new Ya.Metrika({id:32997984,clickmap:true,trackLinks:true,accurateTrackBounce:true,webvisor:true,trackHash:true});}catch(e){}});var n=d.getElementsByTagName("script")[0],s=d.createElement("script"),f=function(){n.parentNode.insertBefore(s,n);};s.type="text/javascript";s.async=true;s.src="https://mc.yandex.ru/metrika/watch.js";if(w.opera=="[object Opera]"){d.addEventListener("DOMContentLoaded",f,false);}else{ f();}})(document,window,"yandex_metrika_callbacks");
|
||||
//--></script>
|
||||
</span>
|
||||
<small>© oknardia.ru, 2015-2023. <a href="/blogpost/18/Ob-avtorskih-pravah">Все права защищены</a>.<!--- Время отработки скрипта: сек---></small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,379 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru-RU">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="content-language" content="ru" />
|
||||
<meta http-equiv="Date" content="2023-01-18T00:30:35.978140+03:00" />
|
||||
<meta http-equiv="Last-Modified" content="2023-01-18T00:30:35.978187+03:00" />
|
||||
<meta http-equiv="Expires" content="2023-01-18T00:30:35.978209+03:00" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="Дома серии МГ-601: детальная информация" />
|
||||
<meta name="keywords" content=" МГ-601, серия МГ-601, проект МГ-601, года постройки зданий серии МГ-601, размеры окон в домах серии МГ-601, оконные проемы зданий серии МГ-601, дома серии МГ-601 на карте, установка окон, цены на пластиковые окна" />
|
||||
<meta name="author" content="OKNARDIA.RU" />
|
||||
<meta name="copyright" lang="ru" content="OKNARDIA.RU" />
|
||||
<meta name="robots" content="index,follow" />
|
||||
<meta name="document-state" content="Dynamic" />
|
||||
<meta name="generator" content="OKNARDIA 0.3β by Python/Django" />
|
||||
<title>Дома серии МГ-601 — типовые проёмы, размеры окон, схемы открывания, планировки, здания на карте, история и статистика : ОКНАРДИЯ</title>
|
||||
<link rel="alternate" href="https://oknardia.ru" hreflang="ru-ru" />
|
||||
<link href="/static/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="/static/css/bootstrap-theme.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="/static/css/oknardia1.css" rel="stylesheet" type="text/css" />
|
||||
<script src="/static/js/jquery-2.1.1.min.js" type="text/javascript"></script>
|
||||
<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).load(function () {
|
||||
let images = $('.half');
|
||||
images.each(function (i) {
|
||||
$(this).width($(this).width() / 2);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript">$(document).ready(function(){ $('#login-logout').load('/login-logout' ); })</script>
|
||||
</head>
|
||||
|
||||
<body style="padding-top:70px;">
|
||||
<!--- Контент НАЧАЛО --->
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-11 col-xs-12">
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="/">Главная</a></li>
|
||||
<li><a href="/catalog/">Каталог</a></li>
|
||||
<li><a href="/catalog/seria/">Типовые серии домов</a></li>
|
||||
<li>Серия МГ-601</li>
|
||||
</ol>
|
||||
<h1>СЕРИЯ МГ-601</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-10">
|
||||
<h2 class="header">Дома серии МГ-601: типовые размеры и схемы открывания</h2>
|
||||
</div>
|
||||
<div class="col-lg-12" style="padding:1em 0 0 0;margin-left:-1em">
|
||||
|
||||
|
||||
<div class="win_discr pull-left" id="flap0">
|
||||
<div><img src="/static/img/_flap.cfg/117x132H225WN(G).png" alt="Окно одностворчатое, балкон для серии МГ-601. Размер 1170x1320 (Ш х В, мм.). Типовая схема открывания." title="Окно одностворчатое, балкон для серии МГ-601. Размер 1170x1320 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:130px;min-width:13ex;">
|
||||
<nobr>1170×1320 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markA.svg');"></span></nobr><br />
|
||||
Окно одностворчатое, балкон для серии МГ-601<br />
|
||||
<a href="/tsena-odnogo-okna/1170x1320mm/tip53">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap1">
|
||||
<div><img src="/static/img/_flap.cfg/167x132H225WN(G)(L)(L).png" alt="Окно трёхстворчатое, балкон для серии МГ-601. Размер 1670x1320 (Ш х В, мм.). Типовая схема открывания." title="Окно трёхстворчатое, балкон для серии МГ-601. Размер 1670x1320 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:185px;min-width:13ex;">
|
||||
<nobr>1670×1320 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markB.svg');"></span></nobr><br />
|
||||
Окно трёхстворчатое, балкон для серии МГ-601<br />
|
||||
<a href="/tsena-odnogo-okna/1670x1320mm/tip54">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap2">
|
||||
<div><img src="/static/img/_flap.cfg/082x225H225D-(L).png" alt="Дверь на балкон для серии II-68 и МГ-601. Размер 820x2250 (Ш х В, мм.). Типовая схема открывания." title="Дверь на балкон для серии II-68 и МГ-601. Размер 820x2250 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:91px;min-width:13ex;">
|
||||
<nobr>820×2250 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markC.svg');"></span></nobr><br />
|
||||
Дверь на балкон для серии II-68 и МГ-601<br />
|
||||
<a href="/tsena-odnogo-okna/820x2250mm/tip19">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap3">
|
||||
<div><img src="/static/img/_flap.cfg/128x132H225W-(G)(L).png" alt="Окно двустворчатое для серии МГ-601 и 1P-303. Размер 1280x1320 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое для серии МГ-601 и 1P-303. Размер 1280x1320 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:142px;min-width:13ex;">
|
||||
<nobr>1280×1320 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markD.svg');"></span></nobr><br />
|
||||
Окно двустворчатое для серии МГ-601 и 1P-303<br />
|
||||
<a href="/tsena-odnogo-okna/1280x1320mm/tip52">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap4">
|
||||
<div><img src="/static/img/_flap.cfg/194x132H225W-(G)(L)(L).png" alt="Окно трёхстворчатое для серии МГ-601. Размер 1940x1320 (Ш х В, мм.). Типовая схема открывания." title="Окно трёхстворчатое для серии МГ-601. Размер 1940x1320 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:215px;min-width:13ex;">
|
||||
<nobr>1940×1320 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markE.svg');"></span></nobr><br />
|
||||
Окно трёхстворчатое для серии МГ-601<br />
|
||||
<a href="/tsena-odnogo-okna/1940x1320mm/tip51">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap5">
|
||||
<div><img src="/static/img/_flap.cfg/258x132H225W-(G)(L)(G)(L).png" alt="Окно четырёхстворчатое для серии МГ-601. Размер 2580x1320 (Ш х В, мм.). Типовая схема открывания." title="Окно четырёхстворчатое для серии МГ-601. Размер 2580x1320 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:286px;min-width:13ex;">
|
||||
<nobr>2580×1320 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markF.svg');"></span></nobr><br />
|
||||
Окно четырёхстворчатое для серии МГ-601<br />
|
||||
<a href="/tsena-odnogo-okna/2580x1320mm/tip50">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-8 col-xs-12 col-md-offset-1">
|
||||
<h3 class="header">Оконные проёмы в типовых квартирах <nobr>серии МГ-601</nobr></h3>
|
||||
</div>
|
||||
<div class="col-lg-8 col-xs-12 col-md-offset-1">
|
||||
<!--- прешаблон начало ---><table style="padding:2px;">{% for row in TABLE_OF_WINDOWS %}
|
||||
<tr class="tr2">
|
||||
<td>{{ row.APART_NAME|safe }}</td>{% for col in row.WIN_IN_APART %}
|
||||
<td class="cntr">{% if col.WIN_ID %}<nobr title="{{ col.WIN_Q }} × {{ col.WIN_DESCRIPTION }}: {{ col.WIN_WIDTH }}шт.: {{ col.WIN_HEIGHT }} (Ш×В, см.). Схема открывания: {{ col.WIN_FLAPCFG }}">{% for I_II in col.WIN_NUM %}<span style="background-image:url('/static/img/svg/mark{{ I_II }}.svg');"> </span>{% endfor %}</nobr>{% else %}—{% endif %}</td>{% endfor %}
|
||||
<td style="background:#f9f9f9;"><a href="#{{ row.APART_ID }}" class="badge" title="Оконных предложений для квартиры: {{ row.NUM_OFFERS }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small> {{ row.NUM_OFFERS }}</a></td>
|
||||
</tr>{% endfor %}
|
||||
<tr class="trZ">
|
||||
<td style="font-size: xx-small;vertical-align:text-top">© 2015-2023, данные: oknardia.ru</td>{% for i in WIN_OFFER_AND_MERCHANT %}
|
||||
<td class="cntr" style="background:#f9f9f9;"><a href="/tsena-odnogo-okna/{{ i.WIN_W|floatformat:0 }}0x{{ i.WIN_H|floatformat:0 }}0mm/tip{{ i.WIN_ID }}" class="badge" title="Ценовых предложений для окна: {{ i.WIN_OFFER }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small> {{ i.WIN_OFFER }}</a></td>{% endfor %}
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--- прешаблон конец ---></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-9"><a name="s_graph"></a>
|
||||
<h2 class="header">Здания серия МГ-601: ввод в эксплуатацию по годам</h2>
|
||||
</div>
|
||||
<div class="col-md-9 col-md-offset-1" style="height:300px;font-size:large;">
|
||||
|
||||
<script type="text/javascript" src="https://www.google.com/jsapi" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
// google.charts.load('current', {'packages':['bar']});
|
||||
// google.charts.setOnLoadCallback(drawChart);
|
||||
google.load("visualization", "1", {packages:["corechart"]});
|
||||
google.setOnLoadCallback(drawChart);
|
||||
function drawChart() {
|
||||
let data = google.visualization.arrayToDataTable([
|
||||
["Год", "Введено в эксплуатацию", {role:'style'}],
|
||||
["1963",2,"color: #99a099"],
|
||||
["1964",1,"color: #999c99"],
|
||||
["1965",1,"color: #999c99"],
|
||||
["1966",4,"color: #99a799"],
|
||||
["1967",9,"color: #99b999"],
|
||||
["1968",7,"color: #99b299"],
|
||||
["1969",12,"color: #99c499"],
|
||||
["1970",10,"color: #99bd99"],
|
||||
["1971",13,"color: #99c899"],
|
||||
["1972",14,"color: #99cc99"],
|
||||
["1973",8,"color: #99b699"],
|
||||
["1974",3,"color: #99a399"],
|
||||
["1975",6,"color: #99ae99"],
|
||||
["1976",4,"color: #99a799"],
|
||||
["1977",1,"color: #999c99"],
|
||||
["1978",1,"color: #999c99"],
|
||||
["1979",3,"color: #99a399"],
|
||||
["1988",1,"color: #999c99"],
|
||||
["1993",1,"color: #999c99"]
|
||||
]);
|
||||
let view = new google.visualization.DataView(data);
|
||||
view.setColumns([0, 1,
|
||||
{ calc: "stringify",
|
||||
sourceColumn: 1,
|
||||
type: "string",
|
||||
role: "annotation" },
|
||||
2
|
||||
]);
|
||||
let options = {
|
||||
animation:{
|
||||
duration: 1500,
|
||||
easing: 'in',
|
||||
startup: true
|
||||
},
|
||||
backgroundColor: "#EEEEEE",
|
||||
bar: {groupWidth: "76.4%"},
|
||||
chartArea: {left: "2%", top: "5%", width: '96%', height: '85%'},
|
||||
dataOpacity: 0.76,
|
||||
explorer:{
|
||||
maxZoomIn: 0.20,
|
||||
maxZoomOut: 32 },
|
||||
vAxis: {
|
||||
baselineColor:'grey',
|
||||
gridlines:{color: 'silver', count: 7},
|
||||
minorGridlines:{color: '#dddddd', count: 3},
|
||||
textPosition: 'in',
|
||||
textStyle: {fontSize: 10}
|
||||
},
|
||||
hAxis: { textStyle: {fontSize: 10} },
|
||||
isStacked: true,
|
||||
tooltip: {
|
||||
textStyle:{color: 'grey', fontSize: 10 },
|
||||
trigger: 'selection'
|
||||
},
|
||||
annotations: {textStyle: { fontSize: 8, bold: true, color: 'black', opacity: 0.8 }},
|
||||
legend: { position: "none" }
|
||||
};
|
||||
let chart = new google.visualization.ColumnChart(document.getElementById("graph"));
|
||||
chart.draw(data, options);
|
||||
}
|
||||
</script>
|
||||
<div id="graph" style="width:100%;height:100%">
|
||||
<p>Для отображения гистограммы ввода в эксплуатацию зданий серии МГ-601 нужна поддержка SVG.</p>
|
||||
<noscript>
|
||||
<p>Для визуализации отображения картографической информации с помощью Google.Charts нужно включить поддержку JavaScript.</p>
|
||||
</noscript></div>
|
||||
</div>
|
||||
<div class="col-md-9 col-md-offset-1">
|
||||
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-7"><a name="s_map"></a>
|
||||
<h2 class="header">Строения серии МГ-601 на карте</h2>
|
||||
</div>
|
||||
<div class="col-md-7 col-lg-offset-1">
|
||||
<p><small>Чтобы посмотреть цены на установку и замену окон от партнёров «Окнардия» в своей квартире: найдите дом на карте; кликните на него; перейдите по ссылке «Смотреть коммерческие предложения». При необходимости смените типовую планировку квартиры (на странице ценовой выдачи, справа от изображения типовых проёмов и схем открывания).</small></p>
|
||||
<div style="height:350px;">
|
||||
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
let points = [[55.725919,37.465919],[55.725189,37.461885],[55.726644,37.469791],[55.746056,37.593542],[55.658830,37.497701],[55.659302,37.497153],[55.658820,37.496587],[55.659277,37.496057],[55.660815,37.487236],[55.657545,37.492994],[55.658865,37.490182],[55.660754,37.493021],[55.728327,37.520752],[55.749288,37.793894],[55.749623,37.793480],[55.750175,37.796490],[55.749841,37.796903],[55.748432,37.787004],[55.748098,37.787408],[55.681316,37.665857],[55.679138,37.665444],[55.674534,37.500576],[55.673854,37.499291],[55.673169,37.498016],[55.671727,37.495455],[55.668295,37.514607],[55.667213,37.513008],[55.666142,37.511356],[55.669366,37.516215],[55.753139,37.823772],[55.753022,37.824553],[55.775510,37.685988],[55.767681,37.666917],[55.749035,37.790318],[55.748706,37.790714],[55.709906,37.503846],[55.709429,37.502983],[55.708942,37.502148],[55.778669,37.476249],[55.680559,37.671399],[55.702495,37.669881],[55.675687,37.664824],[55.674306,37.665147],[55.675017,37.664985],[55.672422,37.496731],[55.670448,37.517761],[55.652415,37.598851],[55.651572,37.598878],[55.776391,37.687659],[55.710748,37.393542],[55.711072,37.394530],[55.711600,37.395697],[55.709186,37.475962],[55.630878,37.599552],[55.630583,37.598330],[55.709617,37.474695],[55.708668,37.474264],[55.703160,37.469719],[55.702652,37.467958],[55.703454,37.468021],[55.704681,37.460610],[55.705239,37.461499],[55.705767,37.460161],[55.704641,37.476717],[55.705138,37.475423],[55.704037,37.474794],[55.707537,37.467069],[55.706756,37.466027],[55.707755,37.465640],[55.857523,37.496345],[55.858710,37.494602],[55.855487,37.498276],[55.855775,37.497791],[55.856361,37.502444],[55.856790,37.502381],[55.857468,37.507574],[55.857705,37.506927],[55.658982,37.512559],[55.658413,37.513125],[55.658520,37.515039],[55.658048,37.514607],[55.656204,37.516144],[55.655742,37.515802],[55.859069,37.505651],[55.859281,37.504987],[55.859888,37.498716],[55.858347,37.500702],[55.860741,37.502992],[55.860524,37.503630],[55.653903,37.559541],[55.654295,37.559415],[55.637266,37.512793],[55.859413,37.498797],[55.797260,37.725217],[55.797776,37.728263],[55.796719,37.721993],[55.619411,37.592240],[55.691232,37.590874],[55.691775,37.590758],[59.829739,30.332676],[60.013344,30.260388]];
|
||||
let forURL = [1239,1241,1246,3593,6780,6781,6782,6783,10315,10329,10341,10344,4321,12895,12896,12899,12900,13783,13784,6001,6002,6151,6162,6169,6181,6727,6737,6752,6869,7715,7716,11833,11972,12890,12891,21132,21133,21134,21596,27608,28404,6005,6013,6008,6174,6864,10704,10706,11836,12123,12124,12125,13388,30064,30065,13390,13391,20280,20282,20283,20295,20296,20297,20304,20305,20307,21687,21688,21689,19472,19475,19480,19483,29155,29156,29160,29161,22667,22670,22671,22675,22680,22681,22984,22985,28966,28972,28981,28984,29498,29500,23149,28964,29820,29824,29892,29980,30228,30229,40658,41168];
|
||||
|
||||
|
||||
ymaps.ready(function () {
|
||||
let myMap = new ymaps.Map('SeriaMap', {
|
||||
center: [55.75, 37.57],
|
||||
zoom: 10,
|
||||
behaviors: ['default', 'scrollZoom'],
|
||||
controls: [ 'rulerControl', 'zoomControl', 'geolocationControl', 'fullscreenControl' ]
|
||||
});
|
||||
// Создадим кластеризатор, вызвав функцию-конструктор.
|
||||
clusterer = new ymaps.Clusterer({
|
||||
preset: 'islands#invertedGrayClusterIcons',
|
||||
groupByCoordinates: false,
|
||||
hasHint: false,
|
||||
viewportMargin: 0,
|
||||
zoomMargin: 16,
|
||||
clusterDisableClickZoom: false,
|
||||
gridSize: 80
|
||||
});
|
||||
geoObjects = [];
|
||||
add_str1 = '<a href="/';
|
||||
add_str2 = '/0/">Смотреть коммерческие предложения</a>';
|
||||
add_str3 = '<b>Здание серии МГ-601</b>';
|
||||
// Данные передаются в конструктор метки.
|
||||
for(var i = 0, len = points.length; i < len; i++) {
|
||||
geoObjects[i] = new ymaps.Placemark( points[i],
|
||||
{ // Содержимое иконки, балуна и хинта.
|
||||
balloonContent: add_str1 + forURL[i] + add_str2,
|
||||
hintContent: add_str3
|
||||
},
|
||||
{ preset:'islands#circleIcon',iconColor: 'silver'} );
|
||||
geoObjects[i].events
|
||||
.add('mouseenter', function (e) {
|
||||
e.get('target').options.set('preset', 'islands#yellowCircleIcon');
|
||||
})
|
||||
.add('mouseleave', function (e) {
|
||||
e.get('target').options.set('preset', 'islands#grayCircleIcon');
|
||||
});
|
||||
}
|
||||
// Добавляем метки в кластеризатор.
|
||||
clusterer.add(geoObjects);
|
||||
myMap.geoObjects.add(clusterer);
|
||||
// позиционирование карты так, чтобы на ней были видны все объекты кластера.
|
||||
myMap.setBounds(clusterer.getBounds(), { checkZoomRange: true });
|
||||
});
|
||||
</script>
|
||||
<div id="SeriaMap" style="height:100%;width:100%;">
|
||||
<noscript>
|
||||
<p>Для отображения картографических данных по серии МГ-601 с помощью «Яндекс.Карт» нужно включить поддержку JavaScript.</p>
|
||||
</noscript>
|
||||
</div></div>
|
||||
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
|
||||
</div>
|
||||
|
||||
<diV class="col-md-4">
|
||||
<h3 class="header">Статистика <nobr>серии МГ-601</nobr></h3>
|
||||
<p>Совокупно во всех зданиях типового проекта:</p>
|
||||
<ul>
|
||||
<li><strong>13 011</strong> квартир.</li>
|
||||
<li>Проживает <strong>13 342</strong> семей <small>(<strong>57 998</strong> человек)</small>.</li>
|
||||
<li><strong>654 281.7 м²</strong> жилых помещений.</li>
|
||||
<li><strong>89 075.3 м²</strong> — муниципальное жильё.</li>
|
||||
<li><strong>22 511.2 м²</strong> занимают государственные и городские службы, учреждения бытового обслуживания, магазины, офисы и тому подобное.</li>
|
||||
<li>Максимальный износ жилого фонда серии МГ-601 — <strong>42.00 %</strong>. Минимальный — <strong>14.00 %</strong>. </li>
|
||||
</ul>
|
||||
</diV>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-lg-offset-8" style="margin-top: 1em;">
|
||||
<h5>Информация о других, отличных от МГ-601, типовых сериях в базе «Окнардия», типовых планировках квартир и оконных проёмах в них, а также рекомендации по замене окон:</h5>
|
||||
<div class="href_d"><span><a href="/catalog/seria/1-335/all210/"><nobr>1-335</nobr></a></span><span><a href="/catalog/seria/1-447/all379/"><nobr>1-447</nobr></a></span><span><a href="/catalog/seria/1-510/all39/"><nobr>1-510</nobr></a></span><span><a href="/catalog/seria/1-511/all100/"><nobr>1-511</nobr></a></span><span><a href="/catalog/seria/1-5155/all41/"><nobr>1-515/5</nobr></a></span><span><a href="/catalog/seria/1-5159/all843/"><nobr>1-515/9</nobr></a></span><span><a href="/catalog/seria/1605/all375/"><nobr>1605</nobr></a></span><span><a href="/catalog/seria/1lg-502/all2420/"><nobr>1ЛГ-502</nobr></a></span><span><a href="/catalog/seria/1lg-504/all2100/"><nobr>1ЛГ-504</nobr></a></span><span><a href="/catalog/seria/1lg-507/all2105/"><nobr>1ЛГ-507</nobr></a></span><span><a href="/catalog/seria/1r-303/all3568/"><nobr>1Р-303</nobr></a></span><span><a href="/catalog/seria/1r-30316/all4080/"><nobr>1Р-303.16</nobr></a></span><span><a href="/catalog/seria/ii-18/all18/"><nobr>II-18</nobr></a></span><span><a href="/catalog/seria/ii-29/all72/"><nobr>II-29</nobr></a></span><span><a href="/catalog/seria/ii-49/all12/"><nobr>II-49</nobr></a></span><span><a href="/catalog/seria/ii-57/all68/"><nobr>II-57</nobr></a></span><span><a href="/catalog/seria/ii-66/all80/"><nobr>II-66</nobr></a></span><span><a href="/catalog/seria/ii-68/all24/"><nobr>II-68</nobr></a></span><span><a href="/catalog/seria/gms-2001/all522/"><nobr>ГМС-2001</nobr></a></span><span><a href="/catalog/seria/i-209a/all44/"><nobr>И-209А</nobr></a></span><span><a href="/catalog/seria/k-7/all19/"><nobr>К-7</nobr></a></span><span><a href="/catalog/seria/kope/all17/"><nobr>КОПЭ</nobr></a></span><span><a href="/catalog/seria/mg-601/all492/"><nobr>МГ-601</nobr></a></span><span><a href="/catalog/seria/p-3/all9/"><nobr>П-3</nobr></a></span><span><a href="/catalog/seria/p-30/all79/"><nobr>П-30</nobr></a></span><span><a href="/catalog/seria/p-43/all178/"><nobr>П-43</nobr></a></span><span><a href="/catalog/seria/p-44/all8/"><nobr>П-44</nobr></a></span><span><a href="/catalog/seria/p-44t/all22/"><nobr>П-44Т</nobr></a></span><span><a href="/catalog/seria/p-46/all29/"><nobr>П-46</nobr></a></span><span><a href="/catalog/seria/p-55/all255/"><nobr>П-55</nobr></a></span><span><a href="/catalog/seria/pd-4/all148/"><nobr>ПД-4</nobr></a></span></div>
|
||||
<p style="text-align:right;padding-top:1em;padding-bottom:1em;"><a href="/stat_all/">Агрегированная информация<br />по типовым сериям домов<br />в базе «Окнардия»</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
{%include "report/report_last_user_visit.html" %}
|
||||
{% include "report/report_log_user_visit.html" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!---/ Контент КОНЕЦ --->
|
||||
|
||||
|
||||
|
||||
<nav class="navbar navbar-fixed-top navbar-default" role="navigation" id="header">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="/"><nobr><img src="/static/img/oknardia_logo.svg" onerror="this.onerror=null;this.src='/static/img/oknardia_logo.gif';this.width=290;this.height=34" title="Перейти на гравную сраницу «Окнардия»" alt="Логотип «Окнардия — оконный агрегатор»" ></nobr></a>
|
||||
</div>
|
||||
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li><a href="/catalog">Каталог</a></li>
|
||||
<li><a href="/stat/rating/">Рейтинги</a></li>
|
||||
<li><a href="/blog">Блог</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" rel="nofollow">О проекте <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="/stat_all">Статистика</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li><a href="/contact">Контакты</a></li>
|
||||
<li><a href="/blogpost/2/My_zhdem_vashi_prajs-listy!">Сотрудничество</a></li>
|
||||
<li><a href="/tariff">Услуги и тарифы</a></li>
|
||||
<!-- li class="divider"></li>
|
||||
<li><a href="#" rel="nofollow">Обратная связь</a></li -->
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown" id="login-logout"><!--- Сюда подгружают AJAX-ом блок login-logout ---><small><br />Авторизации.<noscript style="color:red;">Для авторизации необходимо включить JavaScript.</noscript></small></li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="row panel-footer">
|
||||
<div class="col-xs-12">
|
||||
<span style="top:-200px;left:-8000px;position: absolute;"><script type="text/javascript">
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
ga('create', 'UA-9116991-5', 'auto'); ga('send', 'pageview');
|
||||
var _tmr=_tmr||[];_tmr.push({id:"2018432",type:"pageView",start:(new Date()).getTime()});(function (d,w,id){if(d.getElementById(id))return;var ts=d.createElement("script");ts.type="text/javascript";ts.async=true;ts.id=id;ts.src=(d.location.protocol=="https:"?"https:":"http:")+"//top-fwz1.mail.ru/js/code.js";var f=function(){var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(ts, s);};if(w.opera=="[object Opera]"){ d.addEventListener("DOMContentLoaded",f,false);}else{f();}})(document,window,"topmailru-code");
|
||||
</script><noscript><div style="position:absolute;left:-10000px;">
|
||||
<img src="//top-fwz1.mail.ru/counter?id=2018432;js=na" style="border:0;height:1px;width:1px" alt="" />
|
||||
<img src="//mc.yandex.ru/watch/32997984" style="border:0;height:1px;width:1px" alt="" />
|
||||
</div></noscript>
|
||||
<a target="_blank" href="http://top.mail.ru/jump?from=2018432"><img src="//top-fwz1.mail.ru/counter?id=2018432;t=216;l=1" style="border:0;padding-top:8px;" rel="nofollow" alt="Рейтинг@Mail.ru"></a>
|
||||
<a href="https://metrika.yandex.ru/stat/?id=32997984&from=informer" target="_blank" rel="nofollow"><img src="https://informer.yandex.ru/informer/32997984/3_0_E0E0E0FF_C0C0C0FF_0_pageviews" style="width:88px; height:31px; border:0;" alt="Яндекс.Метрика" title="Яндекс.Метрика: данные за сегодня (просмотры, визиты и уникальные посетители)" onclick="try{Ya.Metrika.informer({i:this,id:32997984,lang:'ru'});return false}catch(e){}" /></a>
|
||||
<span id="rambler"><script id="top100Counter" type="text/javascript" src="//counter.rambler.ru/top100.jcn?3148853"></script><noscript><a href="http://top100.rambler.ru/navi/3148853/"><img src="http://counter.rambler.ru/top100.cnt?3148853" alt="Rambler's Top100" border="0"/></a></noscript></span>
|
||||
<script type="text/javascript"><!--
|
||||
document.write("<a href='//www.liveinternet.ru/click' target=_blank><img src='//counter.yadro.ru/hit?t50.2;r"+escape(document.referrer)+((typeof(screen)=="undefined")?"":";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth?screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+";"+Math.random()+"' alt='' title='LiveInternet' style='border:0;padding-top:8px;'><\/a>");
|
||||
(function(d,w,c){(w[c]=w[c]||[]).push(function(){try{w.yaCounter32997984=new Ya.Metrika({id:32997984,clickmap:true,trackLinks:true,accurateTrackBounce:true,webvisor:true,trackHash:true});}catch(e){}});var n=d.getElementsByTagName("script")[0],s=d.createElement("script"),f=function(){n.parentNode.insertBefore(s,n);};s.type="text/javascript";s.async=true;s.src="https://mc.yandex.ru/metrika/watch.js";if(w.opera=="[object Opera]"){d.addEventListener("DOMContentLoaded",f,false);}else{ f();}})(document,window,"yandex_metrika_callbacks");
|
||||
//--></script>
|
||||
</span>
|
||||
<small>© oknardia.ru, 2015-2023. <a href="/blogpost/18/Ob-avtorskih-pravah">Все права защищены</a>.<!--- Время отработки скрипта: сек---></small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,362 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru-RU">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="content-language" content="ru" />
|
||||
<meta http-equiv="Date" content="2023-01-18T00:30:12.705452+03:00" />
|
||||
<meta http-equiv="Last-Modified" content="2023-01-18T00:30:12.705501+03:00" />
|
||||
<meta http-equiv="Expires" content="2023-01-18T00:30:12.705527+03:00" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="Дома серии ГМС-2001: детальная информация" />
|
||||
<meta name="keywords" content=" ГМС-2001, серия ГМС-2001, проект ГМС-2001, года постройки зданий серии ГМС-2001, размеры окон в домах серии ГМС-2001, оконные проемы зданий серии ГМС-2001, дома серии ГМС-2001 на карте, установка окон, цены на пластиковые окна" />
|
||||
<meta name="author" content="OKNARDIA.RU" />
|
||||
<meta name="copyright" lang="ru" content="OKNARDIA.RU" />
|
||||
<meta name="robots" content="index,follow" />
|
||||
<meta name="document-state" content="Dynamic" />
|
||||
<meta name="generator" content="OKNARDIA 0.3β by Python/Django" />
|
||||
<title>Дома серии ГМС-2001 — типовые проёмы, размеры окон, схемы открывания, планировки, здания на карте, история и статистика : ОКНАРДИЯ</title>
|
||||
<link rel="alternate" href="https://oknardia.ru" hreflang="ru-ru" />
|
||||
<link href="/static/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="/static/css/bootstrap-theme.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="/static/css/oknardia1.css" rel="stylesheet" type="text/css" />
|
||||
<script src="/static/js/jquery-2.1.1.min.js" type="text/javascript"></script>
|
||||
<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).load(function () {
|
||||
let images = $('.half');
|
||||
images.each(function (i) {
|
||||
$(this).width($(this).width() / 2);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript">$(document).ready(function(){ $('#login-logout').load('/login-logout' ); })</script>
|
||||
</head>
|
||||
|
||||
<body style="padding-top:70px;">
|
||||
<!--- Контент НАЧАЛО --->
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-11 col-xs-12">
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="/">Главная</a></li>
|
||||
<li><a href="/catalog/">Каталог</a></li>
|
||||
<li><a href="/catalog/seria/">Типовые серии домов</a></li>
|
||||
<li>Серия ГМС-2001</li>
|
||||
</ol>
|
||||
<h1>СЕРИЯ ГМС-2001</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-10">
|
||||
<h2 class="header">Дома серии ГМС-2001: типовые размеры и схемы открывания</h2>
|
||||
</div>
|
||||
<div class="col-lg-12" style="padding:1em 0 0 0;margin-left:-1em">
|
||||
|
||||
|
||||
<div class="win_discr pull-left" id="flap0">
|
||||
<div><img src="/static/img/_flap.cfg/116x142H216WN(G)(L_).png" alt="Окно двустворчатое, балкон для серий ГМС-1, П-44, ПД-4 и КОПЭ. Размер 1160x1420 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое, балкон для серий ГМС-1, П-44, ПД-4 и КОПЭ. Размер 1160x1420 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:134px;min-width:13ex;">
|
||||
<nobr>1160×1420 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markA.svg');"></span></nobr><br />
|
||||
Окно двустворчатое, балкон для серий ГМС-1, П-44, ПД-4 и КОПЭ<br />
|
||||
<a href="/tsena-odnogo-okna/1160x1420mm/tip2">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap1">
|
||||
<div><img src="/static/img/_flap.cfg/146x142H216WN(G)(L_).png" alt="Окно двустворчатое, балкон для серии КОПЭ и П-44T. Размер 1460x1420 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое, балкон для серии КОПЭ и П-44T. Размер 1460x1420 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:168px;min-width:13ex;">
|
||||
<nobr>1460×1420 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markB.svg');"></span></nobr><br />
|
||||
Окно двустворчатое, балкон для серии КОПЭ и П-44T<br />
|
||||
<a href="/tsena-odnogo-okna/1460x1420mm/tip8">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap2">
|
||||
<div><img src="/static/img/_flap.cfg/067x216H216D-(L).png" alt="Дверь на балкон для серии ГМС-1, П-3, П-42, П-43, П-55 и ПД-4. Размер 670x2160 (Ш х В, мм.). Типовая схема открывания." title="Дверь на балкон для серии ГМС-1, П-3, П-42, П-43, П-55 и ПД-4. Размер 670x2160 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:77px;min-width:13ex;">
|
||||
<nobr>670×2160 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markC.svg');"></span></nobr><br />
|
||||
Дверь на балкон для серии ГМС-1, П-3, П-42, П-43, П-55 и ПД-4<br />
|
||||
<a href="/tsena-odnogo-okna/670x2160mm/tip16">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap3">
|
||||
<div><img src="/static/img/_flap.cfg/077x142H216W-(G).png" alt="Окно одностворчатое для серий ГМС-1. Размер 770x1420 (Ш х В, мм.). Типовая схема открывания." title="Окно одностворчатое для серий ГМС-1. Размер 770x1420 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:89px;min-width:13ex;">
|
||||
<nobr>770×1420 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markD.svg');"></span></nobr><br />
|
||||
Окно одностворчатое для серий ГМС-1<br />
|
||||
<a href="/tsena-odnogo-okna/770x1420mm/tip46">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap4">
|
||||
<div><img src="/static/img/_flap.cfg/147x142H216W-(G)(L_).png" alt="Окно двустворчатое для ГМС-1, П-30/44/46/55, ПД-4, 1-504 и КОПЭ. Размер 1470x1420 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое для ГМС-1, П-30/44/46/55, ПД-4, 1-504 и КОПЭ. Размер 1470x1420 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:170px;min-width:13ex;">
|
||||
<nobr>1470×1420 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markE.svg');"></span></nobr><br />
|
||||
Окно двустворчатое для ГМС-1, П-30/44/46/55, ПД-4, 1-504 и КОПЭ<br />
|
||||
<a href="/tsena-odnogo-okna/1470x1420mm/tip1">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-8 col-xs-12 col-md-offset-1">
|
||||
<h3 class="header">Оконные проёмы в типовых квартирах <nobr>серии ГМС-2001</nobr></h3>
|
||||
</div>
|
||||
<div class="col-lg-8 col-xs-12 col-md-offset-1">
|
||||
<!--- прешаблон начало ---><table style="padding:2px;">{% for row in TABLE_OF_WINDOWS %}
|
||||
<tr class="tr2">
|
||||
<td>{{ row.APART_NAME|safe }}</td>{% for col in row.WIN_IN_APART %}
|
||||
<td class="cntr">{% if col.WIN_ID %}<nobr title="{{ col.WIN_Q }} × {{ col.WIN_DESCRIPTION }}: {{ col.WIN_WIDTH }}шт.: {{ col.WIN_HEIGHT }} (Ш×В, см.). Схема открывания: {{ col.WIN_FLAPCFG }}">{% for I_II in col.WIN_NUM %}<span style="background-image:url('/static/img/svg/mark{{ I_II }}.svg');"> </span>{% endfor %}</nobr>{% else %}—{% endif %}</td>{% endfor %}
|
||||
<td style="background:#f9f9f9;"><a href="#{{ row.APART_ID }}" class="badge" title="Оконных предложений для квартиры: {{ row.NUM_OFFERS }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small> {{ row.NUM_OFFERS }}</a></td>
|
||||
</tr>{% endfor %}
|
||||
<tr class="trZ">
|
||||
<td style="font-size: xx-small;vertical-align:text-top">© 2015-2023, данные: oknardia.ru</td>{% for i in WIN_OFFER_AND_MERCHANT %}
|
||||
<td class="cntr" style="background:#f9f9f9;"><a href="/tsena-odnogo-okna/{{ i.WIN_W|floatformat:0 }}0x{{ i.WIN_H|floatformat:0 }}0mm/tip{{ i.WIN_ID }}" class="badge" title="Ценовых предложений для окна: {{ i.WIN_OFFER }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small> {{ i.WIN_OFFER }}</a></td>{% endfor %}
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--- прешаблон конец ---></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-9"><a name="s_graph"></a>
|
||||
<h2 class="header">Здания серия ГМС-2001: ввод в эксплуатацию по годам</h2>
|
||||
</div>
|
||||
<div class="col-md-9 col-md-offset-1" style="height:300px;font-size:large;">
|
||||
|
||||
<script type="text/javascript" src="https://www.google.com/jsapi" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
// google.charts.load('current', {'packages':['bar']});
|
||||
// google.charts.setOnLoadCallback(drawChart);
|
||||
google.load("visualization", "1", {packages:["corechart"]});
|
||||
google.setOnLoadCallback(drawChart);
|
||||
function drawChart() {
|
||||
let data = google.visualization.arrayToDataTable([
|
||||
["Год", "Введено в эксплуатацию", {role:'style'}],
|
||||
["2003",5,"color: #99ae99"],
|
||||
["2004",7,"color: #99b699"],
|
||||
["2005",6,"color: #99b299"],
|
||||
["2006",5,"color: #99ae99"],
|
||||
["2007",5,"color: #99ae99"],
|
||||
["2008",8,"color: #99bb99"],
|
||||
["2009",12,"color: #99cc99"],
|
||||
["2010",8,"color: #99bb99"],
|
||||
["2011",10,"color: #99c399"],
|
||||
["2012",2,"color: #99a199"],
|
||||
["2013",3,"color: #99a599"]
|
||||
]);
|
||||
let view = new google.visualization.DataView(data);
|
||||
view.setColumns([0, 1,
|
||||
{ calc: "stringify",
|
||||
sourceColumn: 1,
|
||||
type: "string",
|
||||
role: "annotation" },
|
||||
2
|
||||
]);
|
||||
let options = {
|
||||
animation:{
|
||||
duration: 1500,
|
||||
easing: 'in',
|
||||
startup: true
|
||||
},
|
||||
backgroundColor: "#EEEEEE",
|
||||
bar: {groupWidth: "76.4%"},
|
||||
chartArea: {left: "2%", top: "5%", width: '96%', height: '85%'},
|
||||
dataOpacity: 0.76,
|
||||
explorer:{
|
||||
maxZoomIn: 0.20,
|
||||
maxZoomOut: 32 },
|
||||
vAxis: {
|
||||
baselineColor:'grey',
|
||||
gridlines:{color: 'silver', count: 7},
|
||||
minorGridlines:{color: '#dddddd', count: 3},
|
||||
textPosition: 'in',
|
||||
textStyle: {fontSize: 10}
|
||||
},
|
||||
hAxis: { textStyle: {fontSize: 10} },
|
||||
isStacked: true,
|
||||
tooltip: {
|
||||
textStyle:{color: 'grey', fontSize: 10 },
|
||||
trigger: 'selection'
|
||||
},
|
||||
annotations: {textStyle: { fontSize: 8, bold: true, color: 'black', opacity: 0.8 }},
|
||||
legend: { position: "none" }
|
||||
};
|
||||
let chart = new google.visualization.ColumnChart(document.getElementById("graph"));
|
||||
chart.draw(data, options);
|
||||
}
|
||||
</script>
|
||||
<div id="graph" style="width:100%;height:100%">
|
||||
<p>Для отображения гистограммы ввода в эксплуатацию зданий серии ГМС-2001 нужна поддержка SVG.</p>
|
||||
<noscript>
|
||||
<p>Для визуализации отображения картографической информации с помощью Google.Charts нужно включить поддержку JavaScript.</p>
|
||||
</noscript></div>
|
||||
</div>
|
||||
<div class="col-md-9 col-md-offset-1">
|
||||
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-7"><a name="s_map"></a>
|
||||
<h2 class="header">Строения серии ГМС-2001 на карте</h2>
|
||||
</div>
|
||||
<div class="col-md-7 col-lg-offset-1">
|
||||
<p><small>Чтобы посмотреть цены на установку и замену окон от партнёров «Окнардия» в своей квартире: найдите дом на карте; кликните на него; перейдите по ссылке «Смотреть коммерческие предложения». При необходимости смените типовую планировку квартиры (на странице ценовой выдачи, справа от изображения типовых проёмов и схем открывания).</small></p>
|
||||
<div style="height:350px;">
|
||||
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
let points = [[55.820182,37.873143],[55.698203,37.914915],[55.698903,37.915831],[55.700735,37.917484],[55.658068,37.602067],[55.842302,37.550890],[55.843555,37.553073],[55.844667,37.556208],[55.845213,37.556235],[55.866031,37.472135],[55.866389,37.473168],[55.682468,37.928318],[55.713537,37.402794],[55.714090,37.401662],[55.713922,37.400719],[55.872097,37.558526],[55.876496,37.485969],[55.877157,37.485807],[55.544290,37.565380],[55.544036,37.566072],[55.844177,37.548896],[55.841807,37.549597],[55.670153,37.791145],[55.669650,37.790507],[55.505159,37.576492],[55.671153,37.791944],[55.672326,37.794379],[55.681128,37.924230],[55.681275,37.926862],[55.532029,37.502786],[55.701815,37.915382],[55.700826,37.914367],[55.712964,37.894020],[55.714247,37.887875],[55.922404,37.542599],[55.923392,37.543120],[55.927694,37.545276],[55.928718,37.544009],[55.926469,37.540138],[55.419136,37.495123],[55.417526,37.496758],[55.421987,37.483211],[55.421767,37.482178],[55.421118,37.481639],[55.415324,37.481001],[55.415027,37.483930],[55.414910,37.481819],[55.833461,37.286840],[55.833137,37.285295],[55.832586,37.288142],[55.878248,37.509478],[55.879571,37.511212],[55.826584,37.593650],[55.827530,37.593605],[55.827408,37.595330],[55.713755,37.889762],[55.668655,37.789914],[55.713136,37.891657],[55.745042,37.986313],[55.745068,37.983321],[55.744835,37.984884],[55.743603,37.985630],[55.742585,37.985073],[55.744110,37.982782],[55.416887,37.480939],[55.416346,37.480678],[55.415860,37.481208],[55.418252,37.499480],[55.419008,37.498959],[55.419861,37.498788],[55.420219,37.497683]];
|
||||
let forURL = [3325,6419,6425,6428,10726,11198,11201,11208,11209,12167,12171,13930,14103,14118,14119,15680,15777,15778,16681,16682,19168,19173,19733,19734,20017,20210,20211,21700,21701,23098,25893,25915,26433,26444,31497,31499,31503,31504,31509,77303,77304,77322,77324,77325,77340,77500,77501,92345,92346,92348,11723,11724,19721,19722,19723,26448,20206,26450,71418,71419,71420,71421,71422,71423,77333,77336,77338,78458,78459,78473,78474];
|
||||
|
||||
|
||||
ymaps.ready(function () {
|
||||
let myMap = new ymaps.Map('SeriaMap', {
|
||||
center: [55.75, 37.57],
|
||||
zoom: 10,
|
||||
behaviors: ['default', 'scrollZoom'],
|
||||
controls: [ 'rulerControl', 'zoomControl', 'geolocationControl', 'fullscreenControl' ]
|
||||
});
|
||||
// Создадим кластеризатор, вызвав функцию-конструктор.
|
||||
clusterer = new ymaps.Clusterer({
|
||||
preset: 'islands#invertedGrayClusterIcons',
|
||||
groupByCoordinates: false,
|
||||
hasHint: false,
|
||||
viewportMargin: 0,
|
||||
zoomMargin: 16,
|
||||
clusterDisableClickZoom: false,
|
||||
gridSize: 80
|
||||
});
|
||||
geoObjects = [];
|
||||
add_str1 = '<a href="/';
|
||||
add_str2 = '/0/">Смотреть коммерческие предложения</a>';
|
||||
add_str3 = '<b>Здание серии ГМС-2001</b>';
|
||||
// Данные передаются в конструктор метки.
|
||||
for(var i = 0, len = points.length; i < len; i++) {
|
||||
geoObjects[i] = new ymaps.Placemark( points[i],
|
||||
{ // Содержимое иконки, балуна и хинта.
|
||||
balloonContent: add_str1 + forURL[i] + add_str2,
|
||||
hintContent: add_str3
|
||||
},
|
||||
{ preset:'islands#circleIcon',iconColor: 'silver'} );
|
||||
geoObjects[i].events
|
||||
.add('mouseenter', function (e) {
|
||||
e.get('target').options.set('preset', 'islands#yellowCircleIcon');
|
||||
})
|
||||
.add('mouseleave', function (e) {
|
||||
e.get('target').options.set('preset', 'islands#grayCircleIcon');
|
||||
});
|
||||
}
|
||||
// Добавляем метки в кластеризатор.
|
||||
clusterer.add(geoObjects);
|
||||
myMap.geoObjects.add(clusterer);
|
||||
// позиционирование карты так, чтобы на ней были видны все объекты кластера.
|
||||
myMap.setBounds(clusterer.getBounds(), { checkZoomRange: true });
|
||||
});
|
||||
</script>
|
||||
<div id="SeriaMap" style="height:100%;width:100%;">
|
||||
<noscript>
|
||||
<p>Для отображения картографических данных по серии ГМС-2001 с помощью «Яндекс.Карт» нужно включить поддержку JavaScript.</p>
|
||||
</noscript>
|
||||
</div></div>
|
||||
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
|
||||
</div>
|
||||
|
||||
<diV class="col-md-4">
|
||||
<h3 class="header">Статистика <nobr>серии ГМС-2001</nobr></h3>
|
||||
<p>Совокупно во всех зданиях типового проекта:</p>
|
||||
<ul>
|
||||
<li><strong>12 585</strong> квартир.</li>
|
||||
<li>Проживает <strong>18 198</strong> семей <small>(<strong>64 618</strong> человек)</small>.</li>
|
||||
<li><strong>862 529.2 м²</strong> жилых помещений.</li>
|
||||
<li><strong>188 963.6 м²</strong> — муниципальное жильё.</li>
|
||||
<li><strong>28 750.5 м²</strong> занимают государственные и городские службы, учреждения бытового обслуживания, магазины, офисы и тому подобное.</li>
|
||||
<li>Максимальный износ жилого фонда серии ГМС-2001 — <strong>8.10 %</strong>. Минимальный — <strong>1.00 %</strong>. </li>
|
||||
</ul>
|
||||
</diV>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-lg-offset-8" style="margin-top: 1em;">
|
||||
<h5>Информация о других, отличных от ГМС-2001, типовых сериях в базе «Окнардия», типовых планировках квартир и оконных проёмах в них, а также рекомендации по замене окон:</h5>
|
||||
<div class="href_d"><span><a href="/catalog/seria/1-335/all210/"><nobr>1-335</nobr></a></span><span><a href="/catalog/seria/1-447/all379/"><nobr>1-447</nobr></a></span><span><a href="/catalog/seria/1-510/all39/"><nobr>1-510</nobr></a></span><span><a href="/catalog/seria/1-511/all100/"><nobr>1-511</nobr></a></span><span><a href="/catalog/seria/1-5155/all41/"><nobr>1-515/5</nobr></a></span><span><a href="/catalog/seria/1-5159/all843/"><nobr>1-515/9</nobr></a></span><span><a href="/catalog/seria/1605/all375/"><nobr>1605</nobr></a></span><span><a href="/catalog/seria/1lg-502/all2420/"><nobr>1ЛГ-502</nobr></a></span><span><a href="/catalog/seria/1lg-504/all2100/"><nobr>1ЛГ-504</nobr></a></span><span><a href="/catalog/seria/1lg-507/all2105/"><nobr>1ЛГ-507</nobr></a></span><span><a href="/catalog/seria/1r-303/all3568/"><nobr>1Р-303</nobr></a></span><span><a href="/catalog/seria/1r-30316/all4080/"><nobr>1Р-303.16</nobr></a></span><span><a href="/catalog/seria/ii-18/all18/"><nobr>II-18</nobr></a></span><span><a href="/catalog/seria/ii-29/all72/"><nobr>II-29</nobr></a></span><span><a href="/catalog/seria/ii-49/all12/"><nobr>II-49</nobr></a></span><span><a href="/catalog/seria/ii-57/all68/"><nobr>II-57</nobr></a></span><span><a href="/catalog/seria/ii-66/all80/"><nobr>II-66</nobr></a></span><span><a href="/catalog/seria/ii-68/all24/"><nobr>II-68</nobr></a></span><span><a href="/catalog/seria/gms-2001/all522/"><nobr>ГМС-2001</nobr></a></span><span><a href="/catalog/seria/i-209a/all44/"><nobr>И-209А</nobr></a></span><span><a href="/catalog/seria/k-7/all19/"><nobr>К-7</nobr></a></span><span><a href="/catalog/seria/kope/all17/"><nobr>КОПЭ</nobr></a></span><span><a href="/catalog/seria/mg-601/all492/"><nobr>МГ-601</nobr></a></span><span><a href="/catalog/seria/p-3/all9/"><nobr>П-3</nobr></a></span><span><a href="/catalog/seria/p-30/all79/"><nobr>П-30</nobr></a></span><span><a href="/catalog/seria/p-43/all178/"><nobr>П-43</nobr></a></span><span><a href="/catalog/seria/p-44/all8/"><nobr>П-44</nobr></a></span><span><a href="/catalog/seria/p-44t/all22/"><nobr>П-44Т</nobr></a></span><span><a href="/catalog/seria/p-46/all29/"><nobr>П-46</nobr></a></span><span><a href="/catalog/seria/p-55/all255/"><nobr>П-55</nobr></a></span><span><a href="/catalog/seria/pd-4/all148/"><nobr>ПД-4</nobr></a></span></div>
|
||||
<p style="text-align:right;padding-top:1em;padding-bottom:1em;"><a href="/stat_all/">Агрегированная информация<br />по типовым сериям домов<br />в базе «Окнардия»</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
{%include "report/report_last_user_visit.html" %}
|
||||
{% include "report/report_log_user_visit.html" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!---/ Контент КОНЕЦ --->
|
||||
|
||||
|
||||
|
||||
<nav class="navbar navbar-fixed-top navbar-default" role="navigation" id="header">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="/"><nobr><img src="/static/img/oknardia_logo.svg" onerror="this.onerror=null;this.src='/static/img/oknardia_logo.gif';this.width=290;this.height=34" title="Перейти на гравную сраницу «Окнардия»" alt="Логотип «Окнардия — оконный агрегатор»" ></nobr></a>
|
||||
</div>
|
||||
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li><a href="/catalog">Каталог</a></li>
|
||||
<li><a href="/stat/rating/">Рейтинги</a></li>
|
||||
<li><a href="/blog">Блог</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" rel="nofollow">О проекте <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="/stat_all">Статистика</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li><a href="/contact">Контакты</a></li>
|
||||
<li><a href="/blogpost/2/My_zhdem_vashi_prajs-listy!">Сотрудничество</a></li>
|
||||
<li><a href="/tariff">Услуги и тарифы</a></li>
|
||||
<!-- li class="divider"></li>
|
||||
<li><a href="#" rel="nofollow">Обратная связь</a></li -->
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown" id="login-logout"><!--- Сюда подгружают AJAX-ом блок login-logout ---><small><br />Авторизации.<noscript style="color:red;">Для авторизации необходимо включить JavaScript.</noscript></small></li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="row panel-footer">
|
||||
<div class="col-xs-12">
|
||||
<span style="top:-200px;left:-8000px;position: absolute;"><script type="text/javascript">
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
ga('create', 'UA-9116991-5', 'auto'); ga('send', 'pageview');
|
||||
var _tmr=_tmr||[];_tmr.push({id:"2018432",type:"pageView",start:(new Date()).getTime()});(function (d,w,id){if(d.getElementById(id))return;var ts=d.createElement("script");ts.type="text/javascript";ts.async=true;ts.id=id;ts.src=(d.location.protocol=="https:"?"https:":"http:")+"//top-fwz1.mail.ru/js/code.js";var f=function(){var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(ts, s);};if(w.opera=="[object Opera]"){ d.addEventListener("DOMContentLoaded",f,false);}else{f();}})(document,window,"topmailru-code");
|
||||
</script><noscript><div style="position:absolute;left:-10000px;">
|
||||
<img src="//top-fwz1.mail.ru/counter?id=2018432;js=na" style="border:0;height:1px;width:1px" alt="" />
|
||||
<img src="//mc.yandex.ru/watch/32997984" style="border:0;height:1px;width:1px" alt="" />
|
||||
</div></noscript>
|
||||
<a target="_blank" href="http://top.mail.ru/jump?from=2018432"><img src="//top-fwz1.mail.ru/counter?id=2018432;t=216;l=1" style="border:0;padding-top:8px;" rel="nofollow" alt="Рейтинг@Mail.ru"></a>
|
||||
<a href="https://metrika.yandex.ru/stat/?id=32997984&from=informer" target="_blank" rel="nofollow"><img src="https://informer.yandex.ru/informer/32997984/3_0_E0E0E0FF_C0C0C0FF_0_pageviews" style="width:88px; height:31px; border:0;" alt="Яндекс.Метрика" title="Яндекс.Метрика: данные за сегодня (просмотры, визиты и уникальные посетители)" onclick="try{Ya.Metrika.informer({i:this,id:32997984,lang:'ru'});return false}catch(e){}" /></a>
|
||||
<span id="rambler"><script id="top100Counter" type="text/javascript" src="//counter.rambler.ru/top100.jcn?3148853"></script><noscript><a href="http://top100.rambler.ru/navi/3148853/"><img src="http://counter.rambler.ru/top100.cnt?3148853" alt="Rambler's Top100" border="0"/></a></noscript></span>
|
||||
<script type="text/javascript"><!--
|
||||
document.write("<a href='//www.liveinternet.ru/click' target=_blank><img src='//counter.yadro.ru/hit?t50.2;r"+escape(document.referrer)+((typeof(screen)=="undefined")?"":";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth?screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+";"+Math.random()+"' alt='' title='LiveInternet' style='border:0;padding-top:8px;'><\/a>");
|
||||
(function(d,w,c){(w[c]=w[c]||[]).push(function(){try{w.yaCounter32997984=new Ya.Metrika({id:32997984,clickmap:true,trackLinks:true,accurateTrackBounce:true,webvisor:true,trackHash:true});}catch(e){}});var n=d.getElementsByTagName("script")[0],s=d.createElement("script"),f=function(){n.parentNode.insertBefore(s,n);};s.type="text/javascript";s.async=true;s.src="https://mc.yandex.ru/metrika/watch.js";if(w.opera=="[object Opera]"){d.addEventListener("DOMContentLoaded",f,false);}else{ f();}})(document,window,"yandex_metrika_callbacks");
|
||||
//--></script>
|
||||
</span>
|
||||
<small>© oknardia.ru, 2015-2023. <a href="/blogpost/18/Ob-avtorskih-pravah">Все права защищены</a>.<!--- Время отработки скрипта: сек---></small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,357 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru-RU">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="content-language" content="ru" />
|
||||
<meta http-equiv="Date" content="2023-01-18T00:30:08.002217+03:00" />
|
||||
<meta http-equiv="Last-Modified" content="2023-01-18T00:30:08.002293+03:00" />
|
||||
<meta http-equiv="Expires" content="2023-01-18T00:30:08.002332+03:00" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="Дома серии II-66: детальная информация" />
|
||||
<meta name="keywords" content=" II-66, серия II-66, проект II-66, года постройки зданий серии II-66, размеры окон в домах серии II-66, оконные проемы зданий серии II-66, дома серии II-66 на карте, установка окон, цены на пластиковые окна" />
|
||||
<meta name="author" content="OKNARDIA.RU" />
|
||||
<meta name="copyright" lang="ru" content="OKNARDIA.RU" />
|
||||
<meta name="robots" content="index,follow" />
|
||||
<meta name="document-state" content="Dynamic" />
|
||||
<meta name="generator" content="OKNARDIA 0.3β by Python/Django" />
|
||||
<title>Дома серии II-66 — типовые проёмы, размеры окон, схемы открывания, планировки, здания на карте, история и статистика : ОКНАРДИЯ</title>
|
||||
<link rel="alternate" href="https://oknardia.ru" hreflang="ru-ru" />
|
||||
<link href="/static/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="/static/css/bootstrap-theme.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="/static/css/oknardia1.css" rel="stylesheet" type="text/css" />
|
||||
<script src="/static/js/jquery-2.1.1.min.js" type="text/javascript"></script>
|
||||
<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).load(function () {
|
||||
let images = $('.half');
|
||||
images.each(function (i) {
|
||||
$(this).width($(this).width() / 2);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript">$(document).ready(function(){ $('#login-logout').load('/login-logout' ); })</script>
|
||||
</head>
|
||||
|
||||
<body style="padding-top:70px;">
|
||||
<!--- Контент НАЧАЛО --->
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-11 col-xs-12">
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="/">Главная</a></li>
|
||||
<li><a href="/catalog/">Каталог</a></li>
|
||||
<li><a href="/catalog/seria/">Типовые серии домов</a></li>
|
||||
<li>Серия II-66</li>
|
||||
</ol>
|
||||
<h1>СЕРИЯ II-66</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-10">
|
||||
<h2 class="header">Дома серии II-66: типовые размеры и схемы открывания</h2>
|
||||
</div>
|
||||
<div class="col-lg-12" style="padding:1em 0 0 0;margin-left:-1em">
|
||||
|
||||
|
||||
<div class="win_discr pull-left" id="flap0">
|
||||
<div><img src="/static/img/_flap.cfg/137x154H222WN(G)(L_).png" alt="Окно двустворчатое, балкон, для серий II-66. Размер 1370x1540 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое, балкон, для серий II-66. Размер 1370x1540 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:154px;min-width:13ex;">
|
||||
<nobr>1370×1540 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markA.svg');"></span></nobr><br />
|
||||
Окно двустворчатое, балкон, для серий II-66<br />
|
||||
<a href="/tsena-odnogo-okna/1370x1540mm/tip56">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap1">
|
||||
<div><img src="/static/img/_flap.cfg/068x222H222D-(L).png" alt="Дверь на балкон для серии 1-447, 1-464, 1-605 и II-66. Размер 680x2220 (Ш х В, мм.). Типовая схема открывания." title="Дверь на балкон для серии 1-447, 1-464, 1-605 и II-66. Размер 680x2220 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:76px;min-width:13ex;">
|
||||
<nobr>680×2220 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markB.svg');"></span></nobr><br />
|
||||
Дверь на балкон для серии 1-447, 1-464, 1-605 и II-66<br />
|
||||
<a href="/tsena-odnogo-okna/680x2220mm/tip32">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap2">
|
||||
<div><img src="/static/img/_flap.cfg/127x154H222W-(G_)(L).png" alt="Окно двустворчатое для серии II-66. Размер 1270x1540 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое для серии II-66. Размер 1270x1540 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:143px;min-width:13ex;">
|
||||
<nobr>1270×1540 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markC.svg');"></span></nobr><br />
|
||||
Окно двустворчатое для серии II-66<br />
|
||||
<a href="/tsena-odnogo-okna/1270x1540mm/tip55">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-8 col-xs-12 col-md-offset-1">
|
||||
<h3 class="header">Оконные проёмы в типовых квартирах <nobr>серии II-66</nobr></h3>
|
||||
</div>
|
||||
<div class="col-lg-8 col-xs-12 col-md-offset-1">
|
||||
<!--- прешаблон начало ---><table style="padding:2px;">{% for row in TABLE_OF_WINDOWS %}
|
||||
<tr class="tr2">
|
||||
<td>{{ row.APART_NAME|safe }}</td>{% for col in row.WIN_IN_APART %}
|
||||
<td class="cntr">{% if col.WIN_ID %}<nobr title="{{ col.WIN_Q }} × {{ col.WIN_DESCRIPTION }}: {{ col.WIN_WIDTH }}шт.: {{ col.WIN_HEIGHT }} (Ш×В, см.). Схема открывания: {{ col.WIN_FLAPCFG }}">{% for I_II in col.WIN_NUM %}<span style="background-image:url('/static/img/svg/mark{{ I_II }}.svg');"> </span>{% endfor %}</nobr>{% else %}—{% endif %}</td>{% endfor %}
|
||||
<td style="background:#f9f9f9;"><a href="#{{ row.APART_ID }}" class="badge" title="Оконных предложений для квартиры: {{ row.NUM_OFFERS }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small> {{ row.NUM_OFFERS }}</a></td>
|
||||
</tr>{% endfor %}
|
||||
<tr class="trZ">
|
||||
<td style="font-size: xx-small;vertical-align:text-top">© 2015-2023, данные: oknardia.ru</td>{% for i in WIN_OFFER_AND_MERCHANT %}
|
||||
<td class="cntr" style="background:#f9f9f9;"><a href="/tsena-odnogo-okna/{{ i.WIN_W|floatformat:0 }}0x{{ i.WIN_H|floatformat:0 }}0mm/tip{{ i.WIN_ID }}" class="badge" title="Ценовых предложений для окна: {{ i.WIN_OFFER }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small> {{ i.WIN_OFFER }}</a></td>{% endfor %}
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--- прешаблон конец ---></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-9"><a name="s_graph"></a>
|
||||
<h2 class="header">Здания серия II-66: ввод в эксплуатацию по годам</h2>
|
||||
</div>
|
||||
<div class="col-md-9 col-md-offset-1" style="height:300px;font-size:large;">
|
||||
|
||||
<script type="text/javascript" src="https://www.google.com/jsapi" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
// google.charts.load('current', {'packages':['bar']});
|
||||
// google.charts.setOnLoadCallback(drawChart);
|
||||
google.load("visualization", "1", {packages:["corechart"]});
|
||||
google.setOnLoadCallback(drawChart);
|
||||
function drawChart() {
|
||||
let data = google.visualization.arrayToDataTable([
|
||||
["Год", "Введено в эксплуатацию", {role:'style'}],
|
||||
["1971",1,"color: #999f99"],
|
||||
["1972",1,"color: #999f99"],
|
||||
["1973",1,"color: #999f99"],
|
||||
["1974",1,"color: #999f99"],
|
||||
["1975",3,"color: #99ac99"],
|
||||
["1976",2,"color: #99a599"],
|
||||
["1978",2,"color: #99a599"],
|
||||
["1979",3,"color: #99ac99"],
|
||||
["1980",3,"color: #99ac99"],
|
||||
["1981",8,"color: #99cc99"],
|
||||
["1982",6,"color: #99bf99"],
|
||||
["1983",8,"color: #99cc99"],
|
||||
["1984",6,"color: #99bf99"],
|
||||
["1985",3,"color: #99ac99"],
|
||||
["1986",2,"color: #99a599"],
|
||||
["1987",7,"color: #99c599"],
|
||||
["1988",1,"color: #999f99"],
|
||||
["1989",2,"color: #99a599"],
|
||||
["1990",2,"color: #99a599"],
|
||||
["1991",1,"color: #999f99"],
|
||||
["1994",2,"color: #99a599"],
|
||||
["1995",1,"color: #999f99"],
|
||||
["1998",1,"color: #999f99"],
|
||||
["2005",1,"color: #999f99"]
|
||||
]);
|
||||
let view = new google.visualization.DataView(data);
|
||||
view.setColumns([0, 1,
|
||||
{ calc: "stringify",
|
||||
sourceColumn: 1,
|
||||
type: "string",
|
||||
role: "annotation" },
|
||||
2
|
||||
]);
|
||||
let options = {
|
||||
animation:{
|
||||
duration: 1500,
|
||||
easing: 'in',
|
||||
startup: true
|
||||
},
|
||||
backgroundColor: "#EEEEEE",
|
||||
bar: {groupWidth: "76.4%"},
|
||||
chartArea: {left: "2%", top: "5%", width: '96%', height: '85%'},
|
||||
dataOpacity: 0.76,
|
||||
explorer:{
|
||||
maxZoomIn: 0.20,
|
||||
maxZoomOut: 32 },
|
||||
vAxis: {
|
||||
baselineColor:'grey',
|
||||
gridlines:{color: 'silver', count: 7},
|
||||
minorGridlines:{color: '#dddddd', count: 3},
|
||||
textPosition: 'in',
|
||||
textStyle: {fontSize: 10}
|
||||
},
|
||||
hAxis: { textStyle: {fontSize: 10} },
|
||||
isStacked: true,
|
||||
tooltip: {
|
||||
textStyle:{color: 'grey', fontSize: 10 },
|
||||
trigger: 'selection'
|
||||
},
|
||||
annotations: {textStyle: { fontSize: 8, bold: true, color: 'black', opacity: 0.8 }},
|
||||
legend: { position: "none" }
|
||||
};
|
||||
let chart = new google.visualization.ColumnChart(document.getElementById("graph"));
|
||||
chart.draw(data, options);
|
||||
}
|
||||
</script>
|
||||
<div id="graph" style="width:100%;height:100%">
|
||||
<p>Для отображения гистограммы ввода в эксплуатацию зданий серии II-66 нужна поддержка SVG.</p>
|
||||
<noscript>
|
||||
<p>Для визуализации отображения картографической информации с помощью Google.Charts нужно включить поддержку JavaScript.</p>
|
||||
</noscript></div>
|
||||
</div>
|
||||
<div class="col-md-9 col-md-offset-1">
|
||||
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-7"><a name="s_map"></a>
|
||||
<h2 class="header">Строения серии II-66 на карте</h2>
|
||||
</div>
|
||||
<div class="col-md-7 col-lg-offset-1">
|
||||
<p><small>Чтобы посмотреть цены на установку и замену окон от партнёров «Окнардия» в своей квартире: найдите дом на карте; кликните на него; перейдите по ссылке «Смотреть коммерческие предложения». При необходимости смените типовую планировку квартиры (на странице ценовой выдачи, справа от изображения типовых проёмов и схем открывания).</small></p>
|
||||
<div style="height:350px;">
|
||||
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
let points = [[55.895298,37.535026],[55.591986,37.669953],[55.771925,37.572369],[55.770071,37.572980],[55.770218,37.573546],[55.588415,37.669046],[55.588349,37.670034],[55.814113,37.967547],[55.814548,37.968355],[55.627768,37.864780],[55.627961,37.863504],[55.939807,37.497836],[55.431238,37.505876],[55.431856,37.506235],[55.432490,37.506415],[55.891042,37.410421],[55.890487,37.410879],[55.889876,37.411364],[55.890275,37.482358],[55.882444,37.417769],[55.883080,37.416844],[55.881172,37.419682],[55.881798,37.418721],[55.892642,37.365272],[55.815696,37.314526],[55.815362,37.314050],[55.814973,37.313618],[55.825679,37.314732],[55.826862,37.312819],[55.828061,37.310663],[55.824445,37.316825],[55.678352,37.880779],[55.675737,37.870376],[55.692064,37.888989],[55.905169,37.727724],[55.899239,37.716468],[55.899668,37.716333],[55.915251,37.773385],[55.915659,37.773340],[55.921365,37.784964],[55.925021,37.766747],[55.925354,37.766612],[55.923917,37.761330],[55.922399,37.789743],[55.923554,37.719459],[55.924159,37.720672],[55.917127,37.745349],[55.917647,37.744459],[55.905951,37.716459],[55.905003,37.715381],[55.903474,37.711707],[55.912783,37.750119],[55.914156,37.751376],[55.912748,37.718830],[55.912143,37.717752],[55.911568,37.716692],[55.913798,37.720807],[55.913338,37.719873],[55.677951,37.257680],[55.677605,37.258237],[55.676189,37.259297],[56.037503,37.245948],[56.037227,37.245867],[54.884239,38.060774],[54.884239,38.060774],[54.884514,38.090437],[54.879645,38.062876],[54.879422,38.066514],[54.879479,38.065275],[54.884327,38.062059],[55.907753,37.719019],[55.906920,37.717573],[55.903474,37.711707],[55.914862,37.752032]];
|
||||
let forURL = [564,12389,15033,15035,15036,18916,18917,69404,69410,70384,70385,70734,77137,77138,77140,80836,80837,80848,80997,81148,81149,81173,81180,81484,92491,92492,92493,92503,92507,92516,92537,94721,94725,95117,97275,97345,97346,97412,97413,97447,97564,97565,97570,97612,97648,97649,97660,97662,97763,97765,97770,98136,98139,98192,98197,98198,98236,98237,101184,101186,101187,110400,110401,110566,110567,110765,110772,110775,110777,110818,114847,114848,114849,114850];
|
||||
|
||||
|
||||
ymaps.ready(function () {
|
||||
let myMap = new ymaps.Map('SeriaMap', {
|
||||
center: [55.75, 37.57],
|
||||
zoom: 10,
|
||||
behaviors: ['default', 'scrollZoom'],
|
||||
controls: [ 'rulerControl', 'zoomControl', 'geolocationControl', 'fullscreenControl' ]
|
||||
});
|
||||
// Создадим кластеризатор, вызвав функцию-конструктор.
|
||||
clusterer = new ymaps.Clusterer({
|
||||
preset: 'islands#invertedGrayClusterIcons',
|
||||
groupByCoordinates: false,
|
||||
hasHint: false,
|
||||
viewportMargin: 0,
|
||||
zoomMargin: 16,
|
||||
clusterDisableClickZoom: false,
|
||||
gridSize: 80
|
||||
});
|
||||
geoObjects = [];
|
||||
add_str1 = '<a href="/';
|
||||
add_str2 = '/0/">Смотреть коммерческие предложения</a>';
|
||||
add_str3 = '<b>Здание серии II-66</b>';
|
||||
// Данные передаются в конструктор метки.
|
||||
for(var i = 0, len = points.length; i < len; i++) {
|
||||
geoObjects[i] = new ymaps.Placemark( points[i],
|
||||
{ // Содержимое иконки, балуна и хинта.
|
||||
balloonContent: add_str1 + forURL[i] + add_str2,
|
||||
hintContent: add_str3
|
||||
},
|
||||
{ preset:'islands#circleIcon',iconColor: 'silver'} );
|
||||
geoObjects[i].events
|
||||
.add('mouseenter', function (e) {
|
||||
e.get('target').options.set('preset', 'islands#yellowCircleIcon');
|
||||
})
|
||||
.add('mouseleave', function (e) {
|
||||
e.get('target').options.set('preset', 'islands#grayCircleIcon');
|
||||
});
|
||||
}
|
||||
// Добавляем метки в кластеризатор.
|
||||
clusterer.add(geoObjects);
|
||||
myMap.geoObjects.add(clusterer);
|
||||
// позиционирование карты так, чтобы на ней были видны все объекты кластера.
|
||||
myMap.setBounds(clusterer.getBounds(), { checkZoomRange: true });
|
||||
});
|
||||
</script>
|
||||
<div id="SeriaMap" style="height:100%;width:100%;">
|
||||
<noscript>
|
||||
<p>Для отображения картографических данных по серии II-66 с помощью «Яндекс.Карт» нужно включить поддержку JavaScript.</p>
|
||||
</noscript>
|
||||
</div></div>
|
||||
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
|
||||
</div>
|
||||
|
||||
<diV class="col-md-4">
|
||||
<h3 class="header">Статистика <nobr>серии II-66</nobr></h3>
|
||||
<p>Совокупно во всех зданиях типового проекта:</p>
|
||||
<ul>
|
||||
<li><strong>4 295</strong> квартир.</li>
|
||||
<li>Проживает <strong>5 432</strong> семей <small>(<strong>28 954</strong> человек)</small>.</li>
|
||||
<li><strong>239 948.6 м²</strong> жилых помещений.</li>
|
||||
<li><strong>19 670.9 м²</strong> — муниципальное жильё.</li>
|
||||
<li><strong>0.0 м²</strong> занимают государственные и городские службы, учреждения бытового обслуживания, магазины, офисы и тому подобное.</li>
|
||||
<li>Максимальный износ жилого фонда серии II-66 — <strong>40.00 %</strong>. Минимальный — <strong>3.00 %</strong>. </li>
|
||||
</ul>
|
||||
</diV>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-lg-offset-8" style="margin-top: 1em;">
|
||||
<h5>Информация о других, отличных от II-66, типовых сериях в базе «Окнардия», типовых планировках квартир и оконных проёмах в них, а также рекомендации по замене окон:</h5>
|
||||
<div class="href_d"><span><a href="/catalog/seria/1-335/all210/"><nobr>1-335</nobr></a></span><span><a href="/catalog/seria/1-447/all379/"><nobr>1-447</nobr></a></span><span><a href="/catalog/seria/1-510/all39/"><nobr>1-510</nobr></a></span><span><a href="/catalog/seria/1-511/all100/"><nobr>1-511</nobr></a></span><span><a href="/catalog/seria/1-5155/all41/"><nobr>1-515/5</nobr></a></span><span><a href="/catalog/seria/1-5159/all843/"><nobr>1-515/9</nobr></a></span><span><a href="/catalog/seria/1605/all375/"><nobr>1605</nobr></a></span><span><a href="/catalog/seria/1lg-502/all2420/"><nobr>1ЛГ-502</nobr></a></span><span><a href="/catalog/seria/1lg-504/all2100/"><nobr>1ЛГ-504</nobr></a></span><span><a href="/catalog/seria/1lg-507/all2105/"><nobr>1ЛГ-507</nobr></a></span><span><a href="/catalog/seria/1r-303/all3568/"><nobr>1Р-303</nobr></a></span><span><a href="/catalog/seria/1r-30316/all4080/"><nobr>1Р-303.16</nobr></a></span><span><a href="/catalog/seria/ii-18/all18/"><nobr>II-18</nobr></a></span><span><a href="/catalog/seria/ii-29/all72/"><nobr>II-29</nobr></a></span><span><a href="/catalog/seria/ii-49/all12/"><nobr>II-49</nobr></a></span><span><a href="/catalog/seria/ii-57/all68/"><nobr>II-57</nobr></a></span><span><a href="/catalog/seria/ii-66/all80/"><nobr>II-66</nobr></a></span><span><a href="/catalog/seria/ii-68/all24/"><nobr>II-68</nobr></a></span><span><a href="/catalog/seria/gms-2001/all522/"><nobr>ГМС-2001</nobr></a></span><span><a href="/catalog/seria/i-209a/all44/"><nobr>И-209А</nobr></a></span><span><a href="/catalog/seria/k-7/all19/"><nobr>К-7</nobr></a></span><span><a href="/catalog/seria/kope/all17/"><nobr>КОПЭ</nobr></a></span><span><a href="/catalog/seria/mg-601/all492/"><nobr>МГ-601</nobr></a></span><span><a href="/catalog/seria/p-3/all9/"><nobr>П-3</nobr></a></span><span><a href="/catalog/seria/p-30/all79/"><nobr>П-30</nobr></a></span><span><a href="/catalog/seria/p-43/all178/"><nobr>П-43</nobr></a></span><span><a href="/catalog/seria/p-44/all8/"><nobr>П-44</nobr></a></span><span><a href="/catalog/seria/p-44t/all22/"><nobr>П-44Т</nobr></a></span><span><a href="/catalog/seria/p-46/all29/"><nobr>П-46</nobr></a></span><span><a href="/catalog/seria/p-55/all255/"><nobr>П-55</nobr></a></span><span><a href="/catalog/seria/pd-4/all148/"><nobr>ПД-4</nobr></a></span></div>
|
||||
<p style="text-align:right;padding-top:1em;padding-bottom:1em;"><a href="/stat_all/">Агрегированная информация<br />по типовым сериям домов<br />в базе «Окнардия»</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
{%include "report/report_last_user_visit.html" %}
|
||||
{% include "report/report_log_user_visit.html" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!---/ Контент КОНЕЦ --->
|
||||
|
||||
|
||||
|
||||
<nav class="navbar navbar-fixed-top navbar-default" role="navigation" id="header">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="/"><nobr><img src="/static/img/oknardia_logo.svg" onerror="this.onerror=null;this.src='/static/img/oknardia_logo.gif';this.width=290;this.height=34" title="Перейти на гравную сраницу «Окнардия»" alt="Логотип «Окнардия — оконный агрегатор»" ></nobr></a>
|
||||
</div>
|
||||
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li><a href="/catalog">Каталог</a></li>
|
||||
<li><a href="/stat/rating/">Рейтинги</a></li>
|
||||
<li><a href="/blog">Блог</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" rel="nofollow">О проекте <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="/stat_all">Статистика</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li><a href="/contact">Контакты</a></li>
|
||||
<li><a href="/blogpost/2/My_zhdem_vashi_prajs-listy!">Сотрудничество</a></li>
|
||||
<li><a href="/tariff">Услуги и тарифы</a></li>
|
||||
<!-- li class="divider"></li>
|
||||
<li><a href="#" rel="nofollow">Обратная связь</a></li -->
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown" id="login-logout"><!--- Сюда подгружают AJAX-ом блок login-logout ---><small><br />Авторизации.<noscript style="color:red;">Для авторизации необходимо включить JavaScript.</noscript></small></li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="row panel-footer">
|
||||
<div class="col-xs-12">
|
||||
<span style="top:-200px;left:-8000px;position: absolute;"><script type="text/javascript">
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
ga('create', 'UA-9116991-5', 'auto'); ga('send', 'pageview');
|
||||
var _tmr=_tmr||[];_tmr.push({id:"2018432",type:"pageView",start:(new Date()).getTime()});(function (d,w,id){if(d.getElementById(id))return;var ts=d.createElement("script");ts.type="text/javascript";ts.async=true;ts.id=id;ts.src=(d.location.protocol=="https:"?"https:":"http:")+"//top-fwz1.mail.ru/js/code.js";var f=function(){var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(ts, s);};if(w.opera=="[object Opera]"){ d.addEventListener("DOMContentLoaded",f,false);}else{f();}})(document,window,"topmailru-code");
|
||||
</script><noscript><div style="position:absolute;left:-10000px;">
|
||||
<img src="//top-fwz1.mail.ru/counter?id=2018432;js=na" style="border:0;height:1px;width:1px" alt="" />
|
||||
<img src="//mc.yandex.ru/watch/32997984" style="border:0;height:1px;width:1px" alt="" />
|
||||
</div></noscript>
|
||||
<a target="_blank" href="http://top.mail.ru/jump?from=2018432"><img src="//top-fwz1.mail.ru/counter?id=2018432;t=216;l=1" style="border:0;padding-top:8px;" rel="nofollow" alt="Рейтинг@Mail.ru"></a>
|
||||
<a href="https://metrika.yandex.ru/stat/?id=32997984&from=informer" target="_blank" rel="nofollow"><img src="https://informer.yandex.ru/informer/32997984/3_0_E0E0E0FF_C0C0C0FF_0_pageviews" style="width:88px; height:31px; border:0;" alt="Яндекс.Метрика" title="Яндекс.Метрика: данные за сегодня (просмотры, визиты и уникальные посетители)" onclick="try{Ya.Metrika.informer({i:this,id:32997984,lang:'ru'});return false}catch(e){}" /></a>
|
||||
<span id="rambler"><script id="top100Counter" type="text/javascript" src="//counter.rambler.ru/top100.jcn?3148853"></script><noscript><a href="http://top100.rambler.ru/navi/3148853/"><img src="http://counter.rambler.ru/top100.cnt?3148853" alt="Rambler's Top100" border="0"/></a></noscript></span>
|
||||
<script type="text/javascript"><!--
|
||||
document.write("<a href='//www.liveinternet.ru/click' target=_blank><img src='//counter.yadro.ru/hit?t50.2;r"+escape(document.referrer)+((typeof(screen)=="undefined")?"":";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth?screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+";"+Math.random()+"' alt='' title='LiveInternet' style='border:0;padding-top:8px;'><\/a>");
|
||||
(function(d,w,c){(w[c]=w[c]||[]).push(function(){try{w.yaCounter32997984=new Ya.Metrika({id:32997984,clickmap:true,trackLinks:true,accurateTrackBounce:true,webvisor:true,trackHash:true});}catch(e){}});var n=d.getElementsByTagName("script")[0],s=d.createElement("script"),f=function(){n.parentNode.insertBefore(s,n);};s.type="text/javascript";s.async=true;s.src="https://mc.yandex.ru/metrika/watch.js";if(w.opera=="[object Opera]"){d.addEventListener("DOMContentLoaded",f,false);}else{ f();}})(document,window,"yandex_metrika_callbacks");
|
||||
//--></script>
|
||||
</span>
|
||||
<small>© oknardia.ru, 2015-2023. <a href="/blogpost/18/Ob-avtorskih-pravah">Все права защищены</a>.<!--- Время отработки скрипта: сек---></small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,382 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru-RU">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="content-language" content="ru" />
|
||||
<meta http-equiv="Date" content="2023-01-18T00:29:30.132829+03:00" />
|
||||
<meta http-equiv="Last-Modified" content="2023-01-18T00:29:30.133023+03:00" />
|
||||
<meta http-equiv="Expires" content="2023-01-18T00:29:30.133044+03:00" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="Дома серии 1-515/9: детальная информация" />
|
||||
<meta name="keywords" content=" 1-515/9, серия 1-515/9, проект 1-515/9, года постройки зданий серии 1-515/9, размеры окон в домах серии 1-515/9, оконные проемы зданий серии 1-515/9, дома серии 1-515/9 на карте, установка окон, цены на пластиковые окна" />
|
||||
<meta name="author" content="OKNARDIA.RU" />
|
||||
<meta name="copyright" lang="ru" content="OKNARDIA.RU" />
|
||||
<meta name="robots" content="index,follow" />
|
||||
<meta name="document-state" content="Dynamic" />
|
||||
<meta name="generator" content="OKNARDIA 0.3β by Python/Django" />
|
||||
<title>Дома серии 1-515/9 — типовые проёмы, размеры окон, схемы открывания, планировки, здания на карте, история и статистика : ОКНАРДИЯ</title>
|
||||
<link rel="alternate" href="https://oknardia.ru" hreflang="ru-ru" />
|
||||
<link href="/static/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="/static/css/bootstrap-theme.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="/static/css/oknardia1.css" rel="stylesheet" type="text/css" />
|
||||
<script src="/static/js/jquery-2.1.1.min.js" type="text/javascript"></script>
|
||||
<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).load(function () {
|
||||
let images = $('.half');
|
||||
images.each(function (i) {
|
||||
$(this).width($(this).width() / 2);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript">$(document).ready(function(){ $('#login-logout').load('/login-logout' ); })</script>
|
||||
</head>
|
||||
|
||||
<body style="padding-top:70px;">
|
||||
<!--- Контент НАЧАЛО --->
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-11 col-xs-12">
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="/">Главная</a></li>
|
||||
<li><a href="/catalog/">Каталог</a></li>
|
||||
<li><a href="/catalog/seria/">Типовые серии домов</a></li>
|
||||
<li>Серия 1-515/9</li>
|
||||
</ol>
|
||||
<h1>СЕРИЯ 1-515/9</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12"></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-10">
|
||||
<h2 class="header">Дома серии 1-515/9: типовые размеры и схемы открывания</h2>
|
||||
</div>
|
||||
<div class="col-lg-12" style="padding:1em 0 0 0;margin-left:-1em">
|
||||
|
||||
|
||||
<div class="win_discr pull-left" id="flap0">
|
||||
<div><img src="/static/img/_flap.cfg/073x153H225WN(G).png" alt="Окно на балкон/лоджию для серии 1-515/9Ш и И-209А. Размер 730x1530 (Ш х В, мм.). Типовая схема открывания." title="Окно на балкон/лоджию для серии 1-515/9Ш и И-209А. Размер 730x1530 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:81px;min-width:13ex;">
|
||||
<nobr>730×1530 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markA.svg');"></span></nobr><br />
|
||||
Окно на балкон/лоджию для серии 1-515/9Ш и И-209А<br />
|
||||
<a href="/tsena-odnogo-okna/730x1530mm/tip36">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap1">
|
||||
<div><img src="/static/img/_flap.cfg/132x153H225WN(G)(L_).png" alt="Окно двустворчатое, балкон, для серий II-18, II-68 и 1-515/9. Размер 1320x1530 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое, балкон, для серий II-18, II-68 и 1-515/9. Размер 1320x1530 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:146px;min-width:13ex;">
|
||||
<nobr>1320×1530 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markB.svg');"></span></nobr><br />
|
||||
Окно двустворчатое, балкон, для серий II-18, II-68 и 1-515/9<br />
|
||||
<a href="/tsena-odnogo-okna/1320x1530mm/tip22">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap2">
|
||||
<div><img src="/static/img/_flap.cfg/076x225H225D-(L).png" alt="Дверь на балкон/лоджию для серии II-18, II-57, И-209А и 1-515/9. Размер 760x2250 (Ш х В, мм.). Типовая схема открывания." title="Дверь на балкон/лоджию для серии II-18, II-57, И-209А и 1-515/9. Размер 760x2250 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:84px;min-width:13ex;">
|
||||
<nobr>760×2250 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markC.svg');"></span></nobr><br />
|
||||
Дверь на балкон/лоджию для серии II-18, II-57, И-209А и 1-515/9<br />
|
||||
<a href="/tsena-odnogo-okna/760x2250mm/tip37">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap3">
|
||||
<div><img src="/static/img/_flap.cfg/132x153H225W-(G)(L_).png" alt="Окно двустворчатое для серий II-18, II-68, II-49, К-7 и 1-515/9. Размер 1320x1530 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое для серий II-18, II-68, II-49, К-7 и 1-515/9. Размер 1320x1530 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:146px;min-width:13ex;">
|
||||
<nobr>1320×1530 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markD.svg');"></span></nobr><br />
|
||||
Окно двустворчатое для серий II-18, II-68, II-49, К-7 и 1-515/9<br />
|
||||
<a href="/tsena-odnogo-okna/1320x1530mm/tip23">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap4">
|
||||
<div><img src="/static/img/_flap.cfg/149x113H225W-(G)(L).png" alt="Окно двустворчатое, кухня для серии 1-515/9. Размер 1490x1130 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое, кухня для серии 1-515/9. Размер 1490x1130 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:165px;min-width:13ex;">
|
||||
<nobr>1490×1130 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markE.svg');"></span></nobr><br />
|
||||
Окно двустворчатое, кухня для серии 1-515/9<br />
|
||||
<a href="/tsena-odnogo-okna/1490x1130mm/tip35">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="win_discr pull-left" id="flap5">
|
||||
<div><img src="/static/img/_flap.cfg/188x153H225W-(G_)(G_)(L).png" alt="Окно трёхстворчатое для серии К9 и 1-515/9Ш. Размер 1880x1530 (Ш х В, мм.). Типовая схема открывания." title="Окно трёхстворчатое для серии К9 и 1-515/9Ш. Размер 1880x1530 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
|
||||
<div class="caption" style="width:208px;min-width:13ex;">
|
||||
<nobr>1880×1530 мм.</nobr><br />
|
||||
<nobr><b>1 шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markF.svg');"></span></nobr><br />
|
||||
Окно трёхстворчатое для серии К9 и 1-515/9Ш<br />
|
||||
<a href="/tsena-odnogo-okna/1880x1530mm/tip38">цены только этого типового окна</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-8 col-xs-12 col-md-offset-1">
|
||||
<h3 class="header">Оконные проёмы в типовых квартирах <nobr>серии 1-515/9</nobr></h3>
|
||||
</div>
|
||||
<div class="col-lg-8 col-xs-12 col-md-offset-1">
|
||||
<!--- прешаблон начало ---><table style="padding:2px;">{% for row in TABLE_OF_WINDOWS %}
|
||||
<tr class="tr2">
|
||||
<td>{{ row.APART_NAME|safe }}</td>{% for col in row.WIN_IN_APART %}
|
||||
<td class="cntr">{% if col.WIN_ID %}<nobr title="{{ col.WIN_Q }} × {{ col.WIN_DESCRIPTION }}: {{ col.WIN_WIDTH }}шт.: {{ col.WIN_HEIGHT }} (Ш×В, см.). Схема открывания: {{ col.WIN_FLAPCFG }}">{% for I_II in col.WIN_NUM %}<span style="background-image:url('/static/img/svg/mark{{ I_II }}.svg');"> </span>{% endfor %}</nobr>{% else %}—{% endif %}</td>{% endfor %}
|
||||
<td style="background:#f9f9f9;"><a href="#{{ row.APART_ID }}" class="badge" title="Оконных предложений для квартиры: {{ row.NUM_OFFERS }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small> {{ row.NUM_OFFERS }}</a></td>
|
||||
</tr>{% endfor %}
|
||||
<tr class="trZ">
|
||||
<td style="font-size: xx-small;vertical-align:text-top">© 2015-2023, данные: oknardia.ru</td>{% for i in WIN_OFFER_AND_MERCHANT %}
|
||||
<td class="cntr" style="background:#f9f9f9;"><a href="/tsena-odnogo-okna/{{ i.WIN_W|floatformat:0 }}0x{{ i.WIN_H|floatformat:0 }}0mm/tip{{ i.WIN_ID }}" class="badge" title="Ценовых предложений для окна: {{ i.WIN_OFFER }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small> {{ i.WIN_OFFER }}</a></td>{% endfor %}
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--- прешаблон конец ---></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-9"><a name="s_graph"></a>
|
||||
<h2 class="header">Здания серия 1-515/9: ввод в эксплуатацию по годам</h2>
|
||||
</div>
|
||||
<div class="col-md-9 col-md-offset-1" style="height:300px;font-size:large;">
|
||||
|
||||
<script type="text/javascript" src="https://www.google.com/jsapi" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
// google.charts.load('current', {'packages':['bar']});
|
||||
// google.charts.setOnLoadCallback(drawChart);
|
||||
google.load("visualization", "1", {packages:["corechart"]});
|
||||
google.setOnLoadCallback(drawChart);
|
||||
function drawChart() {
|
||||
let data = google.visualization.arrayToDataTable([
|
||||
["Год", "Введено в эксплуатацию", {role:'style'}],
|
||||
["1968",4,"color: #99a799"],
|
||||
["1969",11,"color: #99c199"],
|
||||
["1970",8,"color: #99b699"],
|
||||
["1971",6,"color: #99ae99"],
|
||||
["1972",7,"color: #99b299"],
|
||||
["1973",14,"color: #99cc99"],
|
||||
["1974",11,"color: #99c199"],
|
||||
["1975",9,"color: #99b999"],
|
||||
["1976",5,"color: #99ab99"],
|
||||
["1977",4,"color: #99a799"],
|
||||
["1978",3,"color: #99a399"],
|
||||
["1979",7,"color: #99b299"],
|
||||
["1980",1,"color: #999c99"],
|
||||
["1981",7,"color: #99b299"],
|
||||
["1982",2,"color: #99a099"],
|
||||
["1984",1,"color: #999c99"],
|
||||
["1985",1,"color: #999c99"],
|
||||
["1986",1,"color: #999c99"],
|
||||
["1987",1,"color: #999c99"],
|
||||
["1989",1,"color: #999c99"],
|
||||
["1990",1,"color: #999c99"],
|
||||
["1993",1,"color: #999c99"]
|
||||
]);
|
||||
let view = new google.visualization.DataView(data);
|
||||
view.setColumns([0, 1,
|
||||
{ calc: "stringify",
|
||||
sourceColumn: 1,
|
||||
type: "string",
|
||||
role: "annotation" },
|
||||
2
|
||||
]);
|
||||
let options = {
|
||||
animation:{
|
||||
duration: 1500,
|
||||
easing: 'in',
|
||||
startup: true
|
||||
},
|
||||
backgroundColor: "#EEEEEE",
|
||||
bar: {groupWidth: "76.4%"},
|
||||
chartArea: {left: "2%", top: "5%", width: '96%', height: '85%'},
|
||||
dataOpacity: 0.76,
|
||||
explorer:{
|
||||
maxZoomIn: 0.20,
|
||||
maxZoomOut: 32 },
|
||||
vAxis: {
|
||||
baselineColor:'grey',
|
||||
gridlines:{color: 'silver', count: 7},
|
||||
minorGridlines:{color: '#dddddd', count: 3},
|
||||
textPosition: 'in',
|
||||
textStyle: {fontSize: 10}
|
||||
},
|
||||
hAxis: { textStyle: {fontSize: 10} },
|
||||
isStacked: true,
|
||||
tooltip: {
|
||||
textStyle:{color: 'grey', fontSize: 10 },
|
||||
trigger: 'selection'
|
||||
},
|
||||
annotations: {textStyle: { fontSize: 8, bold: true, color: 'black', opacity: 0.8 }},
|
||||
legend: { position: "none" }
|
||||
};
|
||||
let chart = new google.visualization.ColumnChart(document.getElementById("graph"));
|
||||
chart.draw(data, options);
|
||||
}
|
||||
</script>
|
||||
<div id="graph" style="width:100%;height:100%">
|
||||
<p>Для отображения гистограммы ввода в эксплуатацию зданий серии 1-515/9 нужна поддержка SVG.</p>
|
||||
<noscript>
|
||||
<p>Для визуализации отображения картографической информации с помощью Google.Charts нужно включить поддержку JavaScript.</p>
|
||||
</noscript></div>
|
||||
</div>
|
||||
<div class="col-md-9 col-md-offset-1">
|
||||
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-7"><a name="s_map"></a>
|
||||
<h2 class="header">Строения серии 1-515/9 на карте</h2>
|
||||
</div>
|
||||
<div class="col-md-7 col-lg-offset-1">
|
||||
<p><small>Чтобы посмотреть цены на установку и замену окон от партнёров «Окнардия» в своей квартире: найдите дом на карте; кликните на него; перейдите по ссылке «Смотреть коммерческие предложения». При необходимости смените типовую планировку квартиры (на странице ценовой выдачи, справа от изображения типовых проёмов и схем открывания).</small></p>
|
||||
<div style="height:350px;">
|
||||
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
let points = [[55.706944,37.827266],[55.621470,37.597926],[56.121496,37.057958],[55.868299,37.618947],[55.935370,37.549444],[56.006507,37.792510],[55.676448,37.745322],[55.675418,37.745295],[55.839673,37.418128],[55.840674,37.419539],[55.755824,37.826422],[55.756158,37.828739],[55.586390,37.664348],[55.585911,37.664860],[55.579556,37.666126],[55.589376,37.642123],[55.869455,37.442428],[55.875935,37.646274],[55.873142,37.647100],[55.872784,37.612829],[55.874067,37.623196],[55.873461,37.626070],[55.670031,37.649741],[55.668701,37.649418],[55.580034,37.663530],[55.680098,37.646786],[55.608287,37.707063],[55.607595,37.707000],[55.705102,37.792016],[55.612263,37.702715],[55.679164,37.759380],[55.714729,37.734425],[55.902374,37.711374],[55.902318,37.707575],[56.395522,37.994892],[56.395307,37.993257],[56.395063,37.991793],[55.585438,37.665390],[55.584451,37.667267],[55.599524,37.654107],[55.579811,37.664833],[55.583749,37.666459],[55.663984,37.743768],[55.861767,37.427920],[55.718334,37.731946],[55.620886,37.601627],[55.621292,37.600495],[55.874309,37.557367],[55.591299,37.661823],[55.619335,37.604232],[55.676149,37.743813],[55.677732,37.757620],[55.678336,37.758150],[55.678595,37.767016],[55.675636,37.747756],[55.795256,37.686204],[55.744865,37.993607],[55.745787,38.006606],[56.015017,37.460762],[55.715256,37.729484],[55.715576,37.730697],[55.715890,37.731775],[55.716711,37.732027],[55.695225,37.742106],[55.580854,37.666126],[55.757207,37.834354],[55.753767,37.834174],[55.753757,37.835144],[55.753737,37.836106],[55.757197,37.835324],[55.757182,37.836276],[55.755601,37.834273],[55.755581,37.835234],[55.755566,37.836195],[55.751898,37.835099],[55.779580,37.477759],[55.679560,37.758626],[55.678930,37.758383],[55.678570,37.759147],[55.678174,37.759030],[55.680153,37.759704],[55.747692,38.004980],[55.715515,37.734156],[55.872410,37.467751],[55.680270,37.766729],[55.883929,37.535188],[55.876789,37.535448],[55.878839,37.534739],[55.750976,37.834300],[55.766400,37.714222],[55.678580,37.673268],[55.873577,37.652157],[55.704621,37.738054],[55.666924,37.571408],[55.667396,37.574435],[55.826215,37.751287],[55.678692,37.680616],[55.876688,37.556846],[55.824243,37.808006],[55.795393,37.973709],[55.704854,37.362819],[55.666381,37.290774],[55.666452,37.289418],[55.666457,37.287891],[55.705092,37.365361],[56.121496,37.057958],[56.121496,37.057958]];
|
||||
let forURL = [1058,15349,110408,1076,2725,3340,5957,5958,9077,9078,9183,9186,12400,12402,20810,9480,26428,9706,9752,9824,9854,9889,10984,10988,20808,21377,896,897,11095,15446,22449,26285,97772,98224,114886,114887,114888,12404,12409,17059,20809,12410,13444,13597,14855,15344,15345,15685,17057,17349,18206,18221,22427,18230,18262,23260,71398,71741,75466,19434,19436,19438,19439,19607,20811,21004,21021,21022,21023,21005,21006,21010,21011,21012,21032,21599,22423,22424,22425,22428,22445,71590,26286,26855,26917,27148,27161,27166,27293,27443,27607,27741,28186,29616,29641,32103,593,15687,16936,69952,102416,101316,101317,101318,102399,110409,110410];
|
||||
|
||||
|
||||
ymaps.ready(function () {
|
||||
let myMap = new ymaps.Map('SeriaMap', {
|
||||
center: [55.75, 37.57],
|
||||
zoom: 10,
|
||||
behaviors: ['default', 'scrollZoom'],
|
||||
controls: [ 'rulerControl', 'zoomControl', 'geolocationControl', 'fullscreenControl' ]
|
||||
});
|
||||
// Создадим кластеризатор, вызвав функцию-конструктор.
|
||||
clusterer = new ymaps.Clusterer({
|
||||
preset: 'islands#invertedGrayClusterIcons',
|
||||
groupByCoordinates: false,
|
||||
hasHint: false,
|
||||
viewportMargin: 0,
|
||||
zoomMargin: 16,
|
||||
clusterDisableClickZoom: false,
|
||||
gridSize: 80
|
||||
});
|
||||
geoObjects = [];
|
||||
add_str1 = '<a href="/';
|
||||
add_str2 = '/0/">Смотреть коммерческие предложения</a>';
|
||||
add_str3 = '<b>Здание серии 1-515/9</b>';
|
||||
// Данные передаются в конструктор метки.
|
||||
for(var i = 0, len = points.length; i < len; i++) {
|
||||
geoObjects[i] = new ymaps.Placemark( points[i],
|
||||
{ // Содержимое иконки, балуна и хинта.
|
||||
balloonContent: add_str1 + forURL[i] + add_str2,
|
||||
hintContent: add_str3
|
||||
},
|
||||
{ preset:'islands#circleIcon',iconColor: 'silver'} );
|
||||
geoObjects[i].events
|
||||
.add('mouseenter', function (e) {
|
||||
e.get('target').options.set('preset', 'islands#yellowCircleIcon');
|
||||
})
|
||||
.add('mouseleave', function (e) {
|
||||
e.get('target').options.set('preset', 'islands#grayCircleIcon');
|
||||
});
|
||||
}
|
||||
// Добавляем метки в кластеризатор.
|
||||
clusterer.add(geoObjects);
|
||||
myMap.geoObjects.add(clusterer);
|
||||
// позиционирование карты так, чтобы на ней были видны все объекты кластера.
|
||||
myMap.setBounds(clusterer.getBounds(), { checkZoomRange: true });
|
||||
});
|
||||
</script>
|
||||
<div id="SeriaMap" style="height:100%;width:100%;">
|
||||
<noscript>
|
||||
<p>Для отображения картографических данных по серии 1-515/9 с помощью «Яндекс.Карт» нужно включить поддержку JavaScript.</p>
|
||||
</noscript>
|
||||
</div></div>
|
||||
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
|
||||
</div>
|
||||
|
||||
<diV class="col-md-4">
|
||||
<h3 class="header">Статистика <nobr>серии 1-515/9</nobr></h3>
|
||||
<p>Совокупно во всех зданиях типового проекта:</p>
|
||||
<ul>
|
||||
<li><strong>9 781</strong> квартир.</li>
|
||||
<li>Проживает <strong>18 646</strong> семей <small>(<strong>85 972</strong> человек)</small>.</li>
|
||||
<li><strong>760 689.2 м²</strong> жилых помещений.</li>
|
||||
<li><strong>68 401.4 м²</strong> — муниципальное жильё.</li>
|
||||
<li><strong>43 667.6 м²</strong> занимают государственные и городские службы, учреждения бытового обслуживания, магазины, офисы и тому подобное.</li>
|
||||
<li>Максимальный износ жилого фонда серии 1-515/9 — <strong>46.00 %</strong>. Минимальный — <strong>10.00 %</strong>. </li>
|
||||
</ul>
|
||||
</diV>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-lg-offset-8" style="margin-top: 1em;">
|
||||
<h5>Информация о других, отличных от 1-515/9, типовых сериях в базе «Окнардия», типовых планировках квартир и оконных проёмах в них, а также рекомендации по замене окон:</h5>
|
||||
<div class="href_d"><span><a href="/catalog/seria/1-335/all210/"><nobr>1-335</nobr></a></span><span><a href="/catalog/seria/1-447/all379/"><nobr>1-447</nobr></a></span><span><a href="/catalog/seria/1-510/all39/"><nobr>1-510</nobr></a></span><span><a href="/catalog/seria/1-511/all100/"><nobr>1-511</nobr></a></span><span><a href="/catalog/seria/1-5155/all41/"><nobr>1-515/5</nobr></a></span><span><a href="/catalog/seria/1-5159/all843/"><nobr>1-515/9</nobr></a></span><span><a href="/catalog/seria/1605/all375/"><nobr>1605</nobr></a></span><span><a href="/catalog/seria/1lg-502/all2420/"><nobr>1ЛГ-502</nobr></a></span><span><a href="/catalog/seria/1lg-504/all2100/"><nobr>1ЛГ-504</nobr></a></span><span><a href="/catalog/seria/1lg-507/all2105/"><nobr>1ЛГ-507</nobr></a></span><span><a href="/catalog/seria/1r-303/all3568/"><nobr>1Р-303</nobr></a></span><span><a href="/catalog/seria/1r-30316/all4080/"><nobr>1Р-303.16</nobr></a></span><span><a href="/catalog/seria/ii-18/all18/"><nobr>II-18</nobr></a></span><span><a href="/catalog/seria/ii-29/all72/"><nobr>II-29</nobr></a></span><span><a href="/catalog/seria/ii-49/all12/"><nobr>II-49</nobr></a></span><span><a href="/catalog/seria/ii-57/all68/"><nobr>II-57</nobr></a></span><span><a href="/catalog/seria/ii-66/all80/"><nobr>II-66</nobr></a></span><span><a href="/catalog/seria/ii-68/all24/"><nobr>II-68</nobr></a></span><span><a href="/catalog/seria/gms-2001/all522/"><nobr>ГМС-2001</nobr></a></span><span><a href="/catalog/seria/i-209a/all44/"><nobr>И-209А</nobr></a></span><span><a href="/catalog/seria/k-7/all19/"><nobr>К-7</nobr></a></span><span><a href="/catalog/seria/kope/all17/"><nobr>КОПЭ</nobr></a></span><span><a href="/catalog/seria/mg-601/all492/"><nobr>МГ-601</nobr></a></span><span><a href="/catalog/seria/p-3/all9/"><nobr>П-3</nobr></a></span><span><a href="/catalog/seria/p-30/all79/"><nobr>П-30</nobr></a></span><span><a href="/catalog/seria/p-43/all178/"><nobr>П-43</nobr></a></span><span><a href="/catalog/seria/p-44/all8/"><nobr>П-44</nobr></a></span><span><a href="/catalog/seria/p-44t/all22/"><nobr>П-44Т</nobr></a></span><span><a href="/catalog/seria/p-46/all29/"><nobr>П-46</nobr></a></span><span><a href="/catalog/seria/p-55/all255/"><nobr>П-55</nobr></a></span><span><a href="/catalog/seria/pd-4/all148/"><nobr>ПД-4</nobr></a></span></div>
|
||||
<p style="text-align:right;padding-top:1em;padding-bottom:1em;"><a href="/stat_all/">Агрегированная информация<br />по типовым сериям домов<br />в базе «Окнардия»</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
{%include "report/report_last_user_visit.html" %}
|
||||
{% include "report/report_log_user_visit.html" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!---/ Контент КОНЕЦ --->
|
||||
|
||||
|
||||
|
||||
<nav class="navbar navbar-fixed-top navbar-default" role="navigation" id="header">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="/"><nobr><img src="/static/img/oknardia_logo.svg" onerror="this.onerror=null;this.src='/static/img/oknardia_logo.gif';this.width=290;this.height=34" title="Перейти на гравную сраницу «Окнардия»" alt="Логотип «Окнардия — оконный агрегатор»" ></nobr></a>
|
||||
</div>
|
||||
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li><a href="/catalog">Каталог</a></li>
|
||||
<li><a href="/stat/rating/">Рейтинги</a></li>
|
||||
<li><a href="/blog">Блог</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" rel="nofollow">О проекте <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="/stat_all">Статистика</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li><a href="/contact">Контакты</a></li>
|
||||
<li><a href="/blogpost/2/My_zhdem_vashi_prajs-listy!">Сотрудничество</a></li>
|
||||
<li><a href="/tariff">Услуги и тарифы</a></li>
|
||||
<!-- li class="divider"></li>
|
||||
<li><a href="#" rel="nofollow">Обратная связь</a></li -->
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown" id="login-logout"><!--- Сюда подгружают AJAX-ом блок login-logout ---><small><br />Авторизации.<noscript style="color:red;">Для авторизации необходимо включить JavaScript.</noscript></small></li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="row panel-footer">
|
||||
<div class="col-xs-12">
|
||||
<span style="top:-200px;left:-8000px;position: absolute;"><script type="text/javascript">
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
ga('create', 'UA-9116991-5', 'auto'); ga('send', 'pageview');
|
||||
var _tmr=_tmr||[];_tmr.push({id:"2018432",type:"pageView",start:(new Date()).getTime()});(function (d,w,id){if(d.getElementById(id))return;var ts=d.createElement("script");ts.type="text/javascript";ts.async=true;ts.id=id;ts.src=(d.location.protocol=="https:"?"https:":"http:")+"//top-fwz1.mail.ru/js/code.js";var f=function(){var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(ts, s);};if(w.opera=="[object Opera]"){ d.addEventListener("DOMContentLoaded",f,false);}else{f();}})(document,window,"topmailru-code");
|
||||
</script><noscript><div style="position:absolute;left:-10000px;">
|
||||
<img src="//top-fwz1.mail.ru/counter?id=2018432;js=na" style="border:0;height:1px;width:1px" alt="" />
|
||||
<img src="//mc.yandex.ru/watch/32997984" style="border:0;height:1px;width:1px" alt="" />
|
||||
</div></noscript>
|
||||
<a target="_blank" href="http://top.mail.ru/jump?from=2018432"><img src="//top-fwz1.mail.ru/counter?id=2018432;t=216;l=1" style="border:0;padding-top:8px;" rel="nofollow" alt="Рейтинг@Mail.ru"></a>
|
||||
<a href="https://metrika.yandex.ru/stat/?id=32997984&from=informer" target="_blank" rel="nofollow"><img src="https://informer.yandex.ru/informer/32997984/3_0_E0E0E0FF_C0C0C0FF_0_pageviews" style="width:88px; height:31px; border:0;" alt="Яндекс.Метрика" title="Яндекс.Метрика: данные за сегодня (просмотры, визиты и уникальные посетители)" onclick="try{Ya.Metrika.informer({i:this,id:32997984,lang:'ru'});return false}catch(e){}" /></a>
|
||||
<span id="rambler"><script id="top100Counter" type="text/javascript" src="//counter.rambler.ru/top100.jcn?3148853"></script><noscript><a href="http://top100.rambler.ru/navi/3148853/"><img src="http://counter.rambler.ru/top100.cnt?3148853" alt="Rambler's Top100" border="0"/></a></noscript></span>
|
||||
<script type="text/javascript"><!--
|
||||
document.write("<a href='//www.liveinternet.ru/click' target=_blank><img src='//counter.yadro.ru/hit?t50.2;r"+escape(document.referrer)+((typeof(screen)=="undefined")?"":";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth?screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+";"+Math.random()+"' alt='' title='LiveInternet' style='border:0;padding-top:8px;'><\/a>");
|
||||
(function(d,w,c){(w[c]=w[c]||[]).push(function(){try{w.yaCounter32997984=new Ya.Metrika({id:32997984,clickmap:true,trackLinks:true,accurateTrackBounce:true,webvisor:true,trackHash:true});}catch(e){}});var n=d.getElementsByTagName("script")[0],s=d.createElement("script"),f=function(){n.parentNode.insertBefore(s,n);};s.type="text/javascript";s.async=true;s.src="https://mc.yandex.ru/metrika/watch.js";if(w.opera=="[object Opera]"){d.addEventListener("DOMContentLoaded",f,false);}else{ f();}})(document,window,"yandex_metrika_callbacks");
|
||||
//--></script>
|
||||
</span>
|
||||
<small>© oknardia.ru, 2015-2023. <a href="/blogpost/18/Ob-avtorskih-pravah">Все права защищены</a>.<!--- Время отработки скрипта: сек---></small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -12,7 +12,6 @@
|
||||
<ul>
|
||||
<li><b><a href="/service/tmp">Страница для тестирования верстки текста в блоге</a></b></li>
|
||||
</ul><ul>
|
||||
<li><b><a href="/service/make_sitemaps">Пересоздать файлы sitemaps.xml</a></b> (исполняется около 10 минут)</li>
|
||||
<li><a href="/service/make_JavaScripts4maps">Пересоздать JavaScript для карт на основе API Яндекс.Крат</a> (исполняется около 1 минуты)</li>
|
||||
<li><a href="/service/make_SeriaInfoRoot">Построить id корневых серий</a> (исполняется около 1 часа)</li>
|
||||
</ul><ul>
|
||||
@@ -20,7 +19,7 @@
|
||||
</ul><ul>
|
||||
<li><a href="/service/make_FillGeoCode">Добавить GeoCode для адресов где его нет</a></li>
|
||||
</ul><ul>
|
||||
<li><a href="/service/make_Rating">Пересчитать рейтинги Профилей</a></li>
|
||||
<li><b><a href="/service/make_rating">Пересчитать рейтинги Профилей</a></b></li>
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
|
||||
@@ -201,7 +201,7 @@ def make_big_img_win_flap(img_file_name_with_path: str, width: int, height: int,
|
||||
# height_door = int(height_door)
|
||||
# создаем картинку с нужными размерами
|
||||
img = Image.new("RGBA", (int(width * PICT_H / height_max), PICT_H), (255, 255, 255, 0))
|
||||
print(img_file_name_with_path)
|
||||
# print(img_file_name_with_path)
|
||||
# находим крайние точки периметра (если окно -- выравнено вверх; если дверь -- вниз)
|
||||
top = 0
|
||||
left = 0
|
||||
@@ -592,5 +592,5 @@ def touch_reload_wsgi(s: str = ''):
|
||||
:return: None
|
||||
"""
|
||||
with open(TOUCH_RELOAD, 'a', encoding="utf-8") as f:
|
||||
f.write(f'\nreload wsgi by cash-template {s}'
|
||||
f' {django.utils.dateformat.format(django.utils.timezone.now(), "Y-m-d H:i:s")}')
|
||||
f.write(f'\nreload wsgi by cash-template - {s} - '
|
||||
f'{django.utils.dateformat.format(django.utils.timezone.now(), "Y-m-d H:i:s")}')
|
||||
|
||||
+3
-1013
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,161 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from django.shortcuts import render, redirect
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from django.utils import timezone
|
||||
from oknardia.models import (
|
||||
MerchantBrand,
|
||||
)
|
||||
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 get_rating_set_for_stars
|
||||
import django.utils.dateformat
|
||||
import time
|
||||
import random
|
||||
import re
|
||||
import pytils
|
||||
|
||||
|
||||
def catalog_company(request: HttpRequest) -> HttpResponse:
|
||||
time_start = time.perf_counter()
|
||||
to_template = {} # словарь, для передачи шаблону
|
||||
q_company = MerchantBrand.objects.raw('SELECT'
|
||||
' oknardia_merchantbrand.id,'
|
||||
' oknardia_merchantbrand.sMerchantName,'
|
||||
' oknardia_merchantbrand.pMerchantLogo,'
|
||||
' oknardia_merchantbrand.sMerchantMainURL,'
|
||||
' COUNT(oknardia_priceoffer.id) AS NumOffers,'
|
||||
' AVG(oknardia_priceoffer.fOfferPrice) AS PriceAVG,'
|
||||
' MAX(oknardia_priceoffer.dOfferModify) AS lastUpdate,'
|
||||
' Q.NumSets,'
|
||||
' Q.RatingAVG,'
|
||||
' 1 AS STARS '
|
||||
'FROM (SELECT'
|
||||
' COUNT(oknardia_setkit.sSetName) AS NumSets,'
|
||||
' oknardia_merchantoffice.kMerchantName_id AS Q_ID,'
|
||||
' AVG(oknardia_setkit.fSetRating) AS RatingAVG'
|
||||
' FROM oknardia_merchantoffice'
|
||||
' INNER JOIN oknardia_ouruser'
|
||||
' ON oknardia_ouruser.kMerchantOffice_id = oknardia_merchantoffice.id'
|
||||
' INNER JOIN oknardia_setkit'
|
||||
' ON oknardia_setkit.kSet2User_id = oknardia_ouruser.id'
|
||||
' GROUP BY oknardia_merchantoffice.id,'
|
||||
' oknardia_merchantoffice.kMerchantName_id) AS Q,'
|
||||
' oknardia_ouruser'
|
||||
' INNER JOIN oknardia_merchantoffice'
|
||||
' ON oknardia_ouruser.kMerchantOffice_id = oknardia_merchantoffice.id'
|
||||
' INNER JOIN oknardia_priceoffer'
|
||||
' ON oknardia_priceoffer.kOfferFromUser_id = oknardia_ouruser.id'
|
||||
' INNER JOIN oknardia_merchantbrand'
|
||||
' ON oknardia_merchantoffice.kMerchantName_id = oknardia_merchantbrand.id'
|
||||
' WHERE Q_ID = oknardia_merchantoffice.kMerchantName_id '
|
||||
'GROUP BY oknardia_merchantoffice.kMerchantName_id '
|
||||
'ORDER BY Q.RatingAVG DESC;')
|
||||
list_company = list(q_company)
|
||||
for i in list_company:
|
||||
i.STARS = get_rating_set_for_stars(i.RatingAVG)
|
||||
i.NumSets = pytils.numeral.get_plural(i.NumSets, u"оконный набор, оконных набора, оконных наборов")
|
||||
i.NumOffers = pytils.numeral.get_plural(i.NumOffers, u"вариант, варианта, вариантов")
|
||||
i.lastUpdate = pytils.dt.distance_of_time_in_words(int(django.utils.dateformat.format(i.lastUpdate, 'U')))
|
||||
i.sMerchantMainURL = pytils.translit.slugify(i.sMerchantName)
|
||||
# print("NAME:", i.sMerchantName, "\tNumSets:", i.NumSets, "\tNumOffers:", i.NumOffers,
|
||||
# "\t:AverageRating:", i.RatingAVG, "\tAveragePrice:", i.PriceAVG, "\tSTARS:", i.STARS)
|
||||
to_template.update({
|
||||
'COMPANIES': list_company,
|
||||
# получаем последние визиты клиента через куки
|
||||
'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.perf_counter() - time_start)
|
||||
})
|
||||
return render(request, "catalog/catalog_company.html", to_template)
|
||||
|
||||
|
||||
def catalog_company_detail(request: HttpRequest, company_id: str, company_name_slug: str) -> HttpResponse:
|
||||
time_start = time.perf_counter()
|
||||
to_template = {} # словарь, для передачи шаблону
|
||||
company_id = int(company_id)
|
||||
q_by_id = MerchantBrand.objects.get(id=company_id)
|
||||
if pytils.translit.slugify(q_by_id.sMerchantName) != company_name_slug:
|
||||
return redirect('/catalog/company/%d-%s' % (company_id, pytils.translit.slugify(q_by_id.sMerchantName)))
|
||||
to_template.update({'COMPANY': q_by_id.sMerchantName})
|
||||
to_template.update({'COMPANY_ID': company_id})
|
||||
to_template.update({'COMPANY_T': company_name_slug})
|
||||
list_not = [u"нет", u"—", ""]
|
||||
to_template.update({'LIST_NOT': list_not})
|
||||
q_sets = MerchantBrand.objects.raw(f"SELECT"
|
||||
f" COUNT(oknardia_priceoffer.id) AS NumOffers,"
|
||||
f" AVG(oknardia_priceoffer.fOfferPrice) AS priceAVG,"
|
||||
f" MAX(oknardia_priceoffer.dOfferModify) AS lastUpdate,"
|
||||
f" MIN(oknardia_priceoffer.dOfferCreate) AS earlyCreation,"
|
||||
f" oknardia_merchantbrand.*,"
|
||||
f" oknardia_merchantoffice.*,"
|
||||
f" oknardia_merchantoffice.id AS idMERCH,"
|
||||
f" oknardia_setkit.*,"
|
||||
f" oknardia_setkit.id AS idSET,"
|
||||
f" oknardia_pvcprofiles.*,"
|
||||
f" oknardia_pvcprofiles.id AS idPVC,"
|
||||
f" oknardia_glazing.*, "
|
||||
f" oknardia_glazing.id AS idGLAZ "
|
||||
f"FROM oknardia_ouruser"
|
||||
f" INNER JOIN oknardia_merchantoffice"
|
||||
f" ON oknardia_ouruser.kMerchantOffice_id = oknardia_merchantoffice.id"
|
||||
f" INNER JOIN oknardia_merchantbrand"
|
||||
f" ON oknardia_merchantoffice.kMerchantName_id = oknardia_merchantbrand.id"
|
||||
f" INNER JOIN oknardia_setkit"
|
||||
f" ON oknardia_setkit.kSet2User_id = oknardia_ouruser.id"
|
||||
f" INNER JOIN oknardia_priceoffer"
|
||||
f" ON oknardia_priceoffer.kOffer2SetKit_id = oknardia_setkit.id"
|
||||
f" INNER JOIN oknardia_pvcprofiles"
|
||||
f" ON oknardia_setkit.kSet2PVCprofiles_id = oknardia_pvcprofiles.id"
|
||||
f" INNER JOIN oknardia_glazing"
|
||||
f" ON oknardia_setkit.kSet2Glazing_id = oknardia_glazing.id "
|
||||
f"WHERE oknardia_merchantbrand.id = {company_id} "
|
||||
f"AND oknardia_priceoffer.sOfferActive = TRUE "
|
||||
f"GROUP BY oknardia_merchantoffice.id,"
|
||||
f" oknardia_setkit.id,"
|
||||
f" oknardia_setkit.fSetRating "
|
||||
f"ORDER BY oknardia_setkit.fSetRating DESC;")
|
||||
list_sets = list(q_sets)
|
||||
for i in list_sets:
|
||||
i.sMerchantMainURL = {"URL": i.sMerchantMainURL,
|
||||
"URL_VIEW": re.sub(r"(?:^http://|^https://|/$|www\.)", "", i.sMerchantMainURL)}
|
||||
k = random.randint(1, int(len(i.sOfficeEmails)/2) - 1)
|
||||
i.sOfficeEmails = [i.sOfficeEmails[0:k], i.sOfficeEmails[k:-k], i.sOfficeEmails[-k:]]
|
||||
to_template.update({'IMG_FOR_BLOG': i.pMerchantLogo})
|
||||
i.fSetRating = {"RATING": i.fSetRating,
|
||||
"STARS": get_rating_set_for_stars(i.fSetRating)}
|
||||
i.lastUpdate = pytils.dt.distance_of_time_in_words(int(django.utils.dateformat.format(i.lastUpdate, 'U')))
|
||||
i.earlyCreation = pytils.dt.distance_of_time_in_words(int(django.utils.dateformat.format(i.earlyCreation, 'U')))
|
||||
i.sProfileName = {"NAME": i.sProfileName,
|
||||
"NAME_T": pytils.translit.slugify(i.sProfileName)}
|
||||
i.sProfileManufacturer = {"NAME": i.sProfileManufacturer,
|
||||
"NAME_T": pytils.translit.slugify(i.sProfileManufacturer)}
|
||||
i.fProfileSeals = pytils.numeral.sum_string(i.fProfileSeals, pytils.numeral.MALE, u"контур, контура, контуров")
|
||||
if i.sSetImplementCatch.lower() in list_not:
|
||||
i.sSetImplementCatch = ""
|
||||
if i.sSetClimateControl.lower() in list_not:
|
||||
i.sSetClimateControl = ""
|
||||
if len(i.sProfileReinforcement) > 0:
|
||||
i.sProfileReinforcement = i.sProfileReinforcement[0].lower()+i.sProfileReinforcement[1:]
|
||||
if len(i.sSetSill) > 0:
|
||||
i.sSetSill = i.sSetSill[0].lower()+i.sSetSill[1:]
|
||||
if len(i.sSetPanes) > 0:
|
||||
i.sSetPanes = i.sSetPanes[0].lower()+i.sSetPanes[1:]
|
||||
if len(i.sSetSlope) > 0:
|
||||
i.sSetSlope = i.sSetSlope[0].lower()+i.sSetSlope[1:]
|
||||
if len(i.sSetUninstallInstall) > 0:
|
||||
i.sSetUninstallInstall = i.sSetUninstallInstall[0].lower()+i.sSetUninstallInstall[1:]
|
||||
if len(i.sSetDelivery) > 0:
|
||||
i.sSetDelivery = i.sSetDelivery[0].lower()+i.sSetDelivery[1:]
|
||||
if len(i.sSetOtherConditions) > 0:
|
||||
i.sSetOtherConditions = i.sSetOtherConditions[0].lower()+i.sSetOtherConditions[1:]
|
||||
to_template.update({
|
||||
'SETS': list_sets,
|
||||
# получаем последние визиты клиента через куки
|
||||
'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.perf_counter() - time_start)
|
||||
})
|
||||
return render(request, "catalog/catalog_company_detail.html", to_template)
|
||||
@@ -0,0 +1,82 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from django.shortcuts import render
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from oknardia.models import (
|
||||
Seria_Info,
|
||||
Win_MountDim,
|
||||
)
|
||||
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 get_flaps_for_mini_pictures
|
||||
import time
|
||||
import pytils
|
||||
|
||||
def standard_opening(request: HttpRequest) -> HttpResponse:
|
||||
time_start = time.perf_counter()
|
||||
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 = get_flaps_for_mini_pictures(i.sFlapConfig)
|
||||
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.perf_counter() - time_start)
|
||||
})
|
||||
return render(request, "catalog/catalog_standard_opening.html", to_template)
|
||||
|
||||
@@ -0,0 +1,356 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from datetime import datetime
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.db.models import Count
|
||||
from django.shortcuts import render, redirect
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from oknardia.settings import *
|
||||
from oknardia.models import Catalog2Profile, PVCprofiles, PriceOffer
|
||||
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
|
||||
import time
|
||||
import json
|
||||
import re
|
||||
import pytils
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Модульные хелперы, общие для всех вьюх этого файла
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def make_slug(value: str) -> str:
|
||||
"""Транслитерирует строку в slug (pytils)."""
|
||||
return pytils.translit.slugify(value).lower()
|
||||
|
||||
|
||||
def _merchant_row_to_dict(row: dict) -> dict:
|
||||
"""Преобразует ORM-строку с данными партнёра в словарь для шаблона."""
|
||||
merchant_name = row["kOffer2SetKit__kSet2User__kMerchantOffice__kMerchantName__sMerchantName"]
|
||||
return {
|
||||
"MERCHANT_ID": row["kOffer2SetKit__kSet2User__kMerchantOffice__kMerchantName__id"],
|
||||
"MERCHANT_NAME": merchant_name,
|
||||
"MERCHANT_NAME_T": make_slug(merchant_name),
|
||||
"MERCHANT_LOGO_URL": row["kOffer2SetKit__kSet2User__kMerchantOffice__kMerchantName__pMerchantLogo"],
|
||||
"MERCHANT_OFFERS": row["offers_by_merchant"],
|
||||
}
|
||||
|
||||
|
||||
def _profile_row_to_dict(profile: dict) -> dict:
|
||||
"""Преобразует ORM-строку профиля в словарь для шаблона."""
|
||||
return {
|
||||
"PROFILE_NAME": profile["sProfileBriefDescription"],
|
||||
"PROFILE_ID": profile["id"],
|
||||
"PROFILE_URL": make_slug(profile["sProfileName"]),
|
||||
"PROFILE_RATING": profile["fProfileRating"],
|
||||
"PROFILE_RATING_STARS": get_rating_set_for_stars(profile["fProfileRating"]),
|
||||
}
|
||||
|
||||
|
||||
def _append_visit_context(to_template: dict, request: HttpRequest, time_start: float) -> None:
|
||||
"""Дописывает в контекст стандартный хвост: визиты и время выполнения."""
|
||||
to_template.update({
|
||||
'LAST_VISIT': get_last_user_visit_list(get_last_user_visit_cookies(request)[:3]),
|
||||
'LOG_VISIT': get_last_all_user_visit_list(),
|
||||
'ticks': float(time.perf_counter() - time_start),
|
||||
})
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def catalog_profile(request: HttpRequest) -> HttpResponse:
|
||||
"""
|
||||
КАТАЛОГ ПРОФИЛЕЙ: страница со списком производителей и моделей (марками) профилей
|
||||
|
||||
:param request: HttpRequest -- входящий http-запрос
|
||||
:return response: HttpResponse -- исходящий http-ответ
|
||||
"""
|
||||
time_start = time.perf_counter()
|
||||
# Берём только те поля, которые реально нужны для построения страницы каталога.
|
||||
# Это позволяет не тащить лишние данные из БД и сразу работать с простыми словарями.
|
||||
profile_rows = list(
|
||||
PVCprofiles.objects.values(
|
||||
"id",
|
||||
"sProfileName",
|
||||
"sProfileBriefDescription",
|
||||
"sProfileManufacturer",
|
||||
).order_by("sProfileManufacturer", "sProfileBriefDescription")
|
||||
)
|
||||
profile_count = len(profile_rows)
|
||||
# В этом контексте смешанные типы значений (str/int/list/float), поэтому задаём общий тип явно.
|
||||
to_template: dict[str, object] = {
|
||||
'CATALOG_PROFILE_NUM': pytils.numeral.get_plural(profile_count, "профиль,профиля,профилей")
|
||||
}
|
||||
|
||||
list_profile_manufactures = []
|
||||
tmp_profile_manufacture = ""
|
||||
for profile in profile_rows:
|
||||
if profile["sProfileManufacturer"] == "":
|
||||
# Пустой производитель в каталоге только мешает: не создаём для него отдельную группу.
|
||||
continue
|
||||
|
||||
if tmp_profile_manufacture != profile["sProfileManufacturer"]:
|
||||
# Новый производитель — открываем новую группу карточек.
|
||||
tmp_profile_manufacture = profile["sProfileManufacturer"]
|
||||
list_profile_manufactures.append({
|
||||
"PROF_MAN_ID": profile["id"],
|
||||
"PROF_MAN": profile["sProfileManufacturer"],
|
||||
"PROF_MAN_T": make_slug(profile["sProfileManufacturer"]),
|
||||
"PROF_MAN_LIST": [{
|
||||
"PROF_NAME_ID": profile["id"],
|
||||
"PROF_NAME": profile["sProfileBriefDescription"],
|
||||
"PROF_NAME_T": make_slug(profile["sProfileName"]),
|
||||
}]
|
||||
})
|
||||
else:
|
||||
# Если производитель уже встречался, просто дописываем новую модель в его список.
|
||||
list_profile_manufactures[-1]["PROF_MAN_LIST"].append({
|
||||
"PROF_NAME_ID": profile["id"],
|
||||
"PROF_NAME": profile["sProfileBriefDescription"],
|
||||
"PROF_NAME_T": make_slug(profile["sProfileName"]),
|
||||
})
|
||||
|
||||
to_template.update({
|
||||
'CATALOG_PROFILE_MAN1_NAME2': list_profile_manufactures,
|
||||
'CATALOG_MANUFACT_NUM': len(list_profile_manufactures),
|
||||
'CATALOG_MANUFACT_NUM_W':
|
||||
pytils.numeral.sum_string(len(list_profile_manufactures), pytils.numeral.MALE, ("производитель",
|
||||
"производителя",
|
||||
"производителей")),
|
||||
})
|
||||
_append_visit_context(to_template, request, time_start)
|
||||
return render(request, "catalog/catalog_of_profiles.html", to_template)
|
||||
|
||||
|
||||
def catalog_profile_model(request: HttpRequest, manufacture_id: int, manufacture_name: str,
|
||||
model_id: int, model_name: str) -> HttpResponse:
|
||||
"""
|
||||
КАТАЛОГ ПРОФИЛЕЙ: страница с описанием марки профиля
|
||||
|
||||
:param request: HttpRequest -- входящий http-запрос
|
||||
:param manufacture_id: id профиля. Предполагается, что это первый id при сортировке по sProfileBriefDescription
|
||||
:param manufacture_name: название производителя (транслитерированное pytils.translit.slugify())
|
||||
:param model_id: id модели (марки) профиля
|
||||
:param model_name: модель (марка) профиля (транслитерированное pytils.translit.slugify(sProfileName))
|
||||
:return response: HttpResponse -- исходящий http-ответ
|
||||
"""
|
||||
time_start = time.perf_counter()
|
||||
manufacture_id = int(manufacture_id)
|
||||
model_id = int(model_id)
|
||||
q_pvc_by_id = PVCprofiles.objects.get(id=model_id)
|
||||
manufacturer_slug = pytils.translit.slugify(q_pvc_by_id.sProfileManufacturer)
|
||||
model_slug = pytils.translit.slugify(q_pvc_by_id.sProfileName)
|
||||
if manufacturer_slug != manufacture_name \
|
||||
or model_slug != model_name \
|
||||
or manufacture_id != model_id:
|
||||
return redirect(f"/catalog/profile/{model_id}-{manufacturer_slug}/"
|
||||
f"{model_id}-{model_slug}")
|
||||
|
||||
# Локальные помощники держат вьюху короче и не размазывают однотипную логику по коду.
|
||||
def build_other_list(value: str) -> list[str]:
|
||||
# Убираем пустые куски, чтобы не плодить «пустые» характеристики в шаблоне.
|
||||
result = []
|
||||
for chunk in (part.strip() for part in value.split(";")):
|
||||
if not chunk:
|
||||
continue
|
||||
if ":" in chunk:
|
||||
head, tail = chunk.split(":", 1)
|
||||
result.append(f"<b>{head.strip()}:</b>{tail.strip()}")
|
||||
else:
|
||||
result.append(f"<b>{chunk}</b>")
|
||||
return result
|
||||
|
||||
def update_pub_dat(current_pub_dat: datetime | None, candidate_pub_dat: datetime | None) -> datetime | None:
|
||||
# На странице оставляем дату публикации/обновления только если она реально новее карточки профиля.
|
||||
if candidate_pub_dat is None:
|
||||
return current_pub_dat
|
||||
if current_pub_dat is None or candidate_pub_dat.replace(tzinfo=None) > current_pub_dat.replace(tzinfo=None):
|
||||
return candidate_pub_dat
|
||||
return current_pub_dat
|
||||
|
||||
def apply_rating_colors(rating: dict, rating_pairs: tuple[tuple[str, str], ...], multiplier: int,
|
||||
gray: bool = False) -> None:
|
||||
# Один маленький helper вместо россыпи почти одинаковых строк: меняется только множитель и формат RGB.
|
||||
for rating_key, template_key in rating_pairs:
|
||||
color = int(255 - rating[rating_key] * multiplier)
|
||||
if gray:
|
||||
to_template[template_key] = f"{color},{color},{color}"
|
||||
else:
|
||||
to_template[template_key] = f"{color},255,{color}"
|
||||
|
||||
to_template: dict[str, object] = {"CATALOG_MODEL": q_pvc_by_id,
|
||||
"CATALOG_MAN2URL": manufacture_name,
|
||||
"CATALOG_URL": f"{manufacture_id}-{manufacture_name}",
|
||||
"CATALOG_URL2": f"{manufacture_id}-{manufacture_name}/{model_id}-{model_name}",
|
||||
"PROFILE_RATING_STARS": get_rating_set_for_stars(q_pvc_by_id.fProfileRating)}
|
||||
try:
|
||||
got_json = json.loads(q_pvc_by_id.sProfileDescription)
|
||||
# раскрашиваем кружочки рейтинга напротив характеристик профиля
|
||||
rating_pairs = (
|
||||
(RANK_PVCP_CAMERAS_NUM_NAME, "RANK_PVCP_CAMERAS_COLOR"),
|
||||
(RANK_PVCP_SEALS_NAME, "RANK_PVCP_SEALS_COLOR"),
|
||||
(RANK_PVCP_THICKNESS_NAME, "RANK_PVCP_THICKNESS_COLOR"),
|
||||
(RANK_PVCP_G_THICKNESS_NAME, "RANK_PVCP_G_THICKNESS_COLOR"),
|
||||
(RANK_PVCP_RABBET_NAME, "RANK_PVCP_RABBET_COLOR"),
|
||||
(RANK_PVCP_HEAT_TRANSFER_NAME, "RANK_PVCP_HEAT_TRANSFER_COLOR"),
|
||||
(RANK_PVCP_SOUNDPROOFING_NAME, "RANK_PVCP_SOUNDPROOFING_COLOR"),
|
||||
(RANK_PVCP_HEIGHT_NAME, "RANK_PVCP_HEIGHT_COLOR"),
|
||||
)
|
||||
if KEY_RATING in got_json:
|
||||
# кружочки зелёные
|
||||
apply_rating_colors(got_json[KEY_RATING], rating_pairs, 255)
|
||||
elif KEY_RATING_VIRTUAL in got_json:
|
||||
# кружочки серые
|
||||
apply_rating_colors(got_json[KEY_RATING_VIRTUAL], rating_pairs, 64, gray=True)
|
||||
else:
|
||||
pass
|
||||
if KEY_HTML in got_json:
|
||||
to_template.update({"EXTRA_INFO": got_json[KEY_HTML]})
|
||||
except (TypeError, ValueError, KeyError):
|
||||
pass
|
||||
to_template.update({"LIST_OTHER": build_other_list(q_pvc_by_id.sProfileOther)})
|
||||
# Партнёров считаем через ORM: так код проще читать и легче переносить между СУБД.
|
||||
q_merchant = (
|
||||
PriceOffer.objects.filter(
|
||||
kOffer2SetKit__kSet2PVCprofiles_id=model_id,
|
||||
sOfferActive=True,
|
||||
)
|
||||
.values(
|
||||
"kOffer2SetKit__kSet2User__kMerchantOffice__kMerchantName__id",
|
||||
"kOffer2SetKit__kSet2User__kMerchantOffice__kMerchantName__sMerchantName",
|
||||
"kOffer2SetKit__kSet2User__kMerchantOffice__kMerchantName__pMerchantLogo",
|
||||
)
|
||||
.annotate(offers_by_merchant=Count("id"))
|
||||
.order_by("-offers_by_merchant", "kOffer2SetKit__kSet2User__kMerchantOffice__kMerchantName__sMerchantName")
|
||||
)
|
||||
to_template.update({'MERCHANTS': [_merchant_row_to_dict(row) for row in q_merchant]})
|
||||
# Близкие профили этого же производителя нужны для быстрых переходов по карточкам.
|
||||
q_profiles = (
|
||||
PVCprofiles.objects.filter(sProfileManufacturer=q_pvc_by_id.sProfileManufacturer)
|
||||
.exclude(id=model_id)
|
||||
.values("id", "fProfileRating", "sProfileBriefDescription", "sProfileName")
|
||||
.order_by("fProfileRating")
|
||||
)
|
||||
to_template.update({'PROFILES': [_profile_row_to_dict(profile) for profile in q_profiles]})
|
||||
# Описание профиля берём через связку каталог -> блог: это один ORM-запрос вместо сырого SQL.
|
||||
q_profiles_detail = (
|
||||
Catalog2Profile.objects.filter(
|
||||
kProfile_id=model_id,
|
||||
sCatalogCardType=CATALOG_RECORD_FOR_PROFILE_MODEL,
|
||||
kBlogCatalog__isnull=False,
|
||||
)
|
||||
.select_related("kBlogCatalog")
|
||||
.order_by("kBlogCatalog__iCatalogSort")
|
||||
)
|
||||
profile_blog_posts = [row.kBlogCatalog for row in q_profiles_detail if row.kBlogCatalog is not None]
|
||||
to_template.update({'PROFILE_DETAIL': profile_blog_posts})
|
||||
# Картинка и дата публикации для meta-тегов берутся из связанного блога, если он есть.
|
||||
if profile_blog_posts:
|
||||
for blog_post in profile_blog_posts:
|
||||
if blog_post.sImgForBlogSocial:
|
||||
to_template['IMG_FOR_BLOG'] = blog_post.sImgForBlogSocial
|
||||
break
|
||||
|
||||
pub_dat: datetime = q_pvc_by_id.dProfileModify
|
||||
if profile_blog_posts:
|
||||
profile_blog_dat: datetime | None = max((post.dPostDataModify for post in profile_blog_posts), default=pub_dat)
|
||||
pub_dat = update_pub_dat(pub_dat, profile_blog_dat) or pub_dat
|
||||
to_template['PUB_DAT'] = pub_dat
|
||||
_append_visit_context(to_template, request, time_start)
|
||||
return render(request, "catalog/catalog_of_profiles_model.html", to_template)
|
||||
|
||||
|
||||
def catalog_profile_manufacture(request: HttpRequest, manufacture_id: int, manufacture_name: str) -> HttpResponse:
|
||||
"""
|
||||
КАТАЛОГ ПРОФИЛЕЙ: страница с описанием производителя профилей и списком марки производимых им профилей
|
||||
|
||||
:param request: HttpRequest -- входящий http-запрос
|
||||
:param manufacture_id: id профиля. Предполагается, что это первый id при сортировке по sProfileBriefDescription
|
||||
:param manufacture_name: название производителя (транслитерированное pytils.translit.slugify())
|
||||
:return response: HttpResponse -- исходящий http-ответ
|
||||
"""
|
||||
time_start = time.perf_counter()
|
||||
manufacture_id = int(manufacture_id)
|
||||
q_pvc_by_id = PVCprofiles.objects.get(id=manufacture_id)
|
||||
if pytils.translit.slugify(q_pvc_by_id.sProfileManufacturer) != manufacture_name:
|
||||
return redirect(f'/catalog/profile/{manufacture_id}-'
|
||||
f'{pytils.translit.slugify(q_pvc_by_id.sProfileManufacturer)}')
|
||||
else:
|
||||
q_pvc_by_id = PVCprofiles.objects.order_by('id') \
|
||||
.filter(sProfileManufacturer=q_pvc_by_id.sProfileManufacturer).first()
|
||||
if q_pvc_by_id.id != manufacture_id:
|
||||
return redirect(f'/catalog/profile/{q_pvc_by_id.id}-'
|
||||
f'{pytils.translit.slugify(q_pvc_by_id.sProfileManufacturer)}')
|
||||
to_template: dict[str, object] = {'CATALOG_MANUFACT': q_pvc_by_id.sProfileManufacturer,
|
||||
'CATALOG_MAN2URL': manufacture_name,
|
||||
'CATALOG_URL': f"{manufacture_id}-{manufacture_name}"}
|
||||
try:
|
||||
# Получаем статью-описание производителя через Catalog2Profile → BlogPosts.
|
||||
# GROUP BY из оригинального SQL здесь не нужен: нас устраивает любая первая запись.
|
||||
catalog_entry = (
|
||||
Catalog2Profile.objects.filter(
|
||||
kProfile__sProfileManufacturer=q_pvc_by_id.sProfileManufacturer,
|
||||
sCatalogCardType=CATALOG_RECORD_FOR_PROFILE_MANUFACTURER,
|
||||
kBlogCatalog__bCatalog=True,
|
||||
)
|
||||
.select_related("kBlogCatalog")
|
||||
.first()
|
||||
)
|
||||
if catalog_entry is None or catalog_entry.kBlogCatalog is None:
|
||||
raise ObjectDoesNotExist
|
||||
manufacture_description = catalog_entry.kBlogCatalog
|
||||
to_template.update({'PUB_DAT': manufacture_description.dPostDataModify})
|
||||
if PATH_FOR_IMG_BLOG in (manufacture_description.sImgForBlogSocial or ""):
|
||||
to_template.update({'IMG_FOR_BLOG': manufacture_description.sImgForBlogSocial})
|
||||
content = re.sub(r'<cut[\s\S]*>', '', manufacture_description.sPostContent, 0, re.IGNORECASE)
|
||||
to_template.update({'HEADER': manufacture_description.sPostHeader, 'CONTENT': content})
|
||||
to_template.update({'TIZER': re.sub(
|
||||
r'<script[\s\S]*?</script>|<style[\s\S]*?</style>|<iframe[\s\S]*?</iframe>',
|
||||
'', content, 0, re.IGNORECASE,
|
||||
)})
|
||||
except (ObjectDoesNotExist, IndexError, TypeError, KeyError):
|
||||
pass
|
||||
|
||||
# Список всех профилей этого производителя для навигации по карточкам.
|
||||
q_profiles = (
|
||||
PVCprofiles.objects.filter(sProfileManufacturer=q_pvc_by_id.sProfileManufacturer)
|
||||
.values("id", "fProfileRating", "sProfileBriefDescription", "sProfileName")
|
||||
.order_by("fProfileRating")
|
||||
)
|
||||
to_template.update({'PROFILES': [_profile_row_to_dict(p) for p in q_profiles]})
|
||||
|
||||
try:
|
||||
# Доля предложений этого производителя относительно всех предложений в базе.
|
||||
offers_by_manufacture = PriceOffer.objects.filter(
|
||||
kOffer2SetKit__kSet2PVCprofiles__sProfileManufacturer=q_pvc_by_id.sProfileManufacturer,
|
||||
).count()
|
||||
total_offers = PriceOffer.objects.count()
|
||||
offers_other = total_offers - offers_by_manufacture
|
||||
to_template.update({
|
||||
'OFFERS_BY_MAUFACTURE': offers_by_manufacture,
|
||||
'OFFERS_OTHER': offers_other,
|
||||
'OFFERS_ANGLE': 90 + 180 * normalize(offers_by_manufacture, total_offers),
|
||||
})
|
||||
if offers_by_manufacture > 0:
|
||||
# Партнёры, у которых есть предложения с профилями этого производителя.
|
||||
q_merchant = (
|
||||
PriceOffer.objects.filter(
|
||||
kOffer2SetKit__kSet2PVCprofiles__sProfileManufacturer=q_pvc_by_id.sProfileManufacturer,
|
||||
)
|
||||
.values(
|
||||
"kOffer2SetKit__kSet2User__kMerchantOffice__kMerchantName__id",
|
||||
"kOffer2SetKit__kSet2User__kMerchantOffice__kMerchantName__sMerchantName",
|
||||
"kOffer2SetKit__kSet2User__kMerchantOffice__kMerchantName__pMerchantLogo",
|
||||
)
|
||||
.annotate(offers_by_merchant=Count("id"))
|
||||
.order_by(
|
||||
"-offers_by_merchant",
|
||||
"kOffer2SetKit__kSet2User__kMerchantOffice__kMerchantName__sMerchantName",
|
||||
)
|
||||
)
|
||||
to_template.update({'MERCHANTS': [_merchant_row_to_dict(row) for row in q_merchant]})
|
||||
except (ObjectDoesNotExist, IndexError, TypeError):
|
||||
pass
|
||||
_append_visit_context(to_template, request, time_start)
|
||||
return render(request, "catalog/catalog_of_profiles_manufacture.html", to_template)
|
||||
|
||||
@@ -0,0 +1,404 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.shortcuts import render, redirect
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from django.template.loader import render_to_string
|
||||
from oknardia.settings import *
|
||||
from oknardia.models import (
|
||||
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 get_flaps_for_big_pictures, touch_reload_wsgi
|
||||
import time
|
||||
import os
|
||||
import math
|
||||
import pytils
|
||||
|
||||
# Каталог типовых серий зданий (пока переадресация)
|
||||
def catalog_seria(request: HttpRequest) -> HttpResponse:
|
||||
"""
|
||||
КАТАЛОГ ТИПОВЫЙ СЕРИЙ: страница со всеми сериями зданий в базе окнардии
|
||||
|
||||
:param request: HttpRequest -- входящий http-запрос
|
||||
:return response: HttpResponse -- исходящий http-ответ
|
||||
"""
|
||||
time_start = time.perf_counter()
|
||||
try:
|
||||
q_seria = Seria_Info.objects.raw('SELECT'
|
||||
' oknardia_seria_info.id,'
|
||||
' oknardia_seria_info.sURL2IMG,'
|
||||
' oknardia_seria_info.sName '
|
||||
'FROM oknardia_seria_info '
|
||||
'WHERE oknardia_seria_info.id = oknardia_seria_info.kRoot_id '
|
||||
'ORDER BY oknardia_seria_info.sName;')
|
||||
list_seria = []
|
||||
for i in q_seria:
|
||||
list_seria.append({
|
||||
"ID": i.id,
|
||||
"URL": i.sURL2IMG,
|
||||
"NAME": i.sName,
|
||||
"NAME_T": pytils.translit.slugify(i.sName)
|
||||
})
|
||||
to_template = {'SERIAS': list_seria}
|
||||
except (ObjectDoesNotExist,):
|
||||
to_template = {}
|
||||
to_template.update({
|
||||
# получаем последние визиты клиента через куки
|
||||
'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.perf_counter() - time_start)
|
||||
})
|
||||
return render(request, "catalog/catalog_seria.html", to_template)
|
||||
|
||||
|
||||
def catalog_seria_info(request: HttpRequest, seria_name_translit: None, seria_id: int = 843) -> HttpResponse:
|
||||
"""
|
||||
КАТАЛОГ ТИПОВЫЙ СЕРИЙ: страница детальной информацией по серии зданий
|
||||
|
||||
:param request: HttpRequest -- входящий http-запрос
|
||||
:param seria_name_translit: str -- имя серии здания (транслитерированное pytils.translit.slugify())
|
||||
:param seria_id: int -- id серии
|
||||
:return response: HttpResponse -- исходящий http-ответ
|
||||
"""
|
||||
time_start = time.perf_counter()
|
||||
msg = ""
|
||||
try:
|
||||
seria_id = int(seria_id)
|
||||
q_seria = Seria_Info.objects.get(id=seria_id)
|
||||
if q_seria.id != q_seria.kRoot_id or seria_name_translit != pytils.translit.slugify(q_seria.sName):
|
||||
return redirect(f"/catalog/seria/{pytils.translit.slugify(q_seria.sName)}/all{seria_id}")
|
||||
except(ObjectDoesNotExist, ValueError,):
|
||||
return redirect("/catalog/")
|
||||
# если есть "облегченный" шаблон с частичным пре-рендером, то используем его.
|
||||
light_template = f"{PATH_FOR_SERIA_INFO_HTML_INCLUDE}{str(seria_id)}_id.html"
|
||||
light_template_w_path = f"{TEMPLATES[0]['DIRS'][0]}/{light_template}"
|
||||
# print(f"{TEMPLATES[0]['DIRS'][0]}/{light_template}")
|
||||
# print(light_template_w_path)
|
||||
# print(light_template_w_path)
|
||||
if os.path.isfile(light_template_w_path):
|
||||
is_hard_template = False
|
||||
else:
|
||||
is_hard_template = True
|
||||
to_template = {}
|
||||
# получаем проемы использующиеся в данной серии домов
|
||||
q_windows_in_seria = Win_MountDim.objects.raw(
|
||||
f"SELECT DISTINCT"
|
||||
f" oknardia_win_mountdim.iWinWidth, oknardia_win_mountdim.iWinHight,"
|
||||
f" oknardia_win_mountdim.sDescripion, oknardia_win_mountdim.bIsDoor,"
|
||||
f" oknardia_win_mountdim.bIsNearDoor, oknardia_win_mountdim.sFlapConfig,"
|
||||
f" oknardia_win_mountdim.iWinDepth, oknardia_win_mountdim.id,"
|
||||
f" 1 AS iQuantity "
|
||||
f"FROM oknardia_mountdim2apartment"
|
||||
f" INNER JOIN oknardia_win_mountdim"
|
||||
f" ON oknardia_mountdim2apartment.kMountDim_id = oknardia_win_mountdim.id"
|
||||
f" INNER JOIN oknardia_apartment_type"
|
||||
f" ON oknardia_mountdim2apartment.kApartment_id = oknardia_apartment_type.id "
|
||||
f"WHERE oknardia_apartment_type.kSeria_id = {seria_id}"
|
||||
f" ORDER BY oknardia_win_mountdim.bIsNearDoor DESC,"
|
||||
f" oknardia_win_mountdim.bIsDoor DESC,"
|
||||
f" oknardia_win_mountdim.iWinWidth,"
|
||||
f" oknardia_win_mountdim.iWinHight DESC;")
|
||||
if is_hard_template:
|
||||
# Получаем данные для отрисовки больших картинок с проёмами и передаём в "тяжёлый" шаблон
|
||||
to_template.update(get_flaps_for_big_pictures(q_windows_in_seria))
|
||||
# формируем строку для включения в SQL-запрос вида "(2,8,16,46,1)"
|
||||
str_for_sql_in = "("
|
||||
for count in q_windows_in_seria:
|
||||
str_for_sql_in += str(count.id) + ","
|
||||
str_for_sql_in = str_for_sql_in[:-1] + ")"
|
||||
# print StringForSqlIN
|
||||
# Получаем данные для таблички Окон по типам квартирах в серии дома
|
||||
# " IFNULL(oknardia_mountdim2apartment.iQuantity, 0) AS iQuantity," \
|
||||
# tStart2 = time.perf_counter() # замер времени
|
||||
q_win_in_apartment_in_seria = Win_MountDim.objects.raw(
|
||||
f"SELECT"
|
||||
f" oknardia_win_mountdim.id,"
|
||||
f" oknardia_apartment_type.sNameApartment,"
|
||||
f" oknardia_win_mountdim.iWinWidth,"
|
||||
f" oknardia_win_mountdim.iWinHight,"
|
||||
f" oknardia_apartment_type.id AS id_apart,"
|
||||
f" IFNULL(oknardia_mountdim2apartment.iQuantity, 0) AS iQuantity,"
|
||||
f" COUNT(oknardia_priceoffer.id) AS NumOffers "
|
||||
f"FROM oknardia_apartment_type"
|
||||
f" INNER JOIN oknardia_win_mountdim"
|
||||
f" LEFT OUTER JOIN oknardia_mountdim2apartment"
|
||||
f" ON oknardia_mountdim2apartment.kMountDim_id = oknardia_win_mountdim.id"
|
||||
f" AND oknardia_mountdim2apartment.kApartment_id = oknardia_apartment_type.id"
|
||||
f" LEFT OUTER JOIN oknardia_priceoffer"
|
||||
f" ON oknardia_priceoffer.kOffer2MountDim_id = oknardia_win_mountdim.id"
|
||||
f" LEFT OUTER JOIN oknardia_ouruser"
|
||||
f" ON oknardia_ouruser.id = oknardia_priceoffer.kOfferFromUser_id "
|
||||
f"WHERE oknardia_apartment_type.kSeria_id = {seria_id} "
|
||||
f"AND oknardia_win_mountdim.id IN {str_for_sql_in} "
|
||||
f"GROUP BY oknardia_apartment_type.id,"
|
||||
f" oknardia_apartment_type.sNameApartment,"
|
||||
f" oknardia_win_mountdim.id,"
|
||||
f" oknardia_mountdim2apartment.iQuantity "
|
||||
f"ORDER BY oknardia_apartment_type.iSort,"
|
||||
f" oknardia_win_mountdim.bIsNearDoor DESC,"
|
||||
f" oknardia_win_mountdim.bIsDoor DESC,"
|
||||
f" oknardia_win_mountdim.iWinWidth,"
|
||||
f" oknardia_win_mountdim.iWinHight DESC;")
|
||||
list_win_in_seria = list(q_windows_in_seria)
|
||||
total_column = len(list_win_in_seria) - 1
|
||||
count_column = 0
|
||||
min_offer_in_row = 1000000000
|
||||
table_of_win_in_seria_by_apartmment = []
|
||||
row_for_table = []
|
||||
offer_and_merchant_per_win = [
|
||||
{
|
||||
"WIN_OFFER": 0,
|
||||
"WIN_MERCHANT": 0,
|
||||
"WIN_W": list_win_in_seria[i].iWinWidth,
|
||||
"WIN_H": list_win_in_seria[i].iWinHight,
|
||||
"WIN_ID": list_win_in_seria[i].id
|
||||
} for i in range(total_column + 1)]
|
||||
for count in q_win_in_apartment_in_seria:
|
||||
if count.iQuantity != 0:
|
||||
row_for_table.append({
|
||||
"WIN_NUM": [chr(65 + count_column)],
|
||||
"WIN_Q": count.iQuantity,
|
||||
"WIN_ID": count.id,
|
||||
"WIN_WIDTH": list_win_in_seria[count_column].iWinWidth,
|
||||
"WIN_HEIGHT": list_win_in_seria[count_column].iWinHight,
|
||||
"WIN_DESCRIPTION": list_win_in_seria[count_column].sDescripion,
|
||||
"WIN_FLAPCFG": list_win_in_seria[count_column].sFlapConfig
|
||||
})
|
||||
if min_offer_in_row > count.NumOffers:
|
||||
min_offer_in_row = count.NumOffers
|
||||
if offer_and_merchant_per_win[count_column]["WIN_OFFER"] < count.NumOffers:
|
||||
offer_and_merchant_per_win[count_column]["WIN_OFFER"] = count.NumOffers
|
||||
else:
|
||||
row_for_table.append({"WIN_NUM": "—"})
|
||||
if count_column < total_column:
|
||||
count_column += 1
|
||||
else:
|
||||
# print row_for_table
|
||||
table_of_win_in_seria_by_apartmment.append({"WIN_IN_APART": row_for_table,
|
||||
"APART_NAME": count.sNameApartment,
|
||||
"APART_ID": count.id_apart,
|
||||
"NUM_OFFERS": min_offer_in_row})
|
||||
count_column = 0
|
||||
min_offer_in_row = 10000
|
||||
row_for_table = []
|
||||
# print(table_of_win_in_seria_by_apartmment)
|
||||
# print(f"==============>{float(time.perf_counter()-tStart2)}<==============")
|
||||
# print NumOffersPerColumn, NumMerchantPerColumn
|
||||
to_template.update({"WIN_OFFER_AND_MERCHANT": offer_and_merchant_per_win,
|
||||
"TABLE_OF_WINDOWS": table_of_win_in_seria_by_apartmment})
|
||||
# для "тяжелого шаблона" получаем навигацию страницы, данные для карты и графика ввода в эксплуатацию
|
||||
if is_hard_template:
|
||||
# если вызывается "тяжелый" шаблон, то нужно подготовить тяжелые данные для построения навигации
|
||||
seria_id, for_seria_nav = seria_nav(seria_id)
|
||||
to_template.update(for_seria_nav) # данные для навигации по сериям
|
||||
to_template.update(seria_info_year(seria_id)) # данные для графика ввода зданий серии в эксплуатацию
|
||||
to_template.update(seria_info_geo_code(seria_id)) # данные для карты
|
||||
# т.к. обрабатывается "тяжелый шаблон" надо создать "легкий шаблон"
|
||||
# для его использования в будущем.
|
||||
string_prerender = render_to_string("seria_info/all_seria_info_pre_light.html", to_template)
|
||||
file = open(light_template_w_path, 'w')
|
||||
# file.write(AA.encode('utf-8'))
|
||||
file.write(string_prerender)
|
||||
file.close()
|
||||
touch_reload_wsgi(light_template_w_path)
|
||||
else:
|
||||
seria_name = Seria_Info.objects.get(id=seria_id).sName
|
||||
to_template.update({'THIS_SERIA_NAME': seria_name})
|
||||
|
||||
# to_template.update({'LOG_VISIT': GetLastAllUserVisitSeriaList(SeriaName),
|
||||
# 'ticks': float(time.perf_counter()-time_start)})
|
||||
to_template.update({
|
||||
# получаем последние визиты клиента через куки
|
||||
'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.perf_counter() - time_start)
|
||||
})
|
||||
return render(request, light_template, to_template)
|
||||
|
||||
|
||||
def seria_nav(seria_id: int = 12) -> (int, dict):
|
||||
"""
|
||||
Возвращает корректный seria_id и кортеж для построения навигации по сериям дома
|
||||
|
||||
:param seria_id: id серии
|
||||
:return:
|
||||
"""
|
||||
q_seria = Seria_Info.objects.raw(
|
||||
'SELECT oknardia_seria_info.id,'
|
||||
' oknardia_seria_info.sName,'
|
||||
' oknardia_seria_info.sSeriaDescription,'
|
||||
' oknardia_seria_info.kRoot_id,'
|
||||
' oknardia_seria_info.kParent_id '
|
||||
'FROM oknardia_seria_info '
|
||||
'WHERE oknardia_seria_info.id = oknardia_seria_info.kRoot_id '
|
||||
'ORDER BY oknardia_seria_info.sName;')
|
||||
error_seria = True
|
||||
for count_seria in q_seria:
|
||||
if count_seria.id == int(seria_id):
|
||||
error_seria = False
|
||||
break
|
||||
if error_seria:
|
||||
# Ошибочный seria_id. Такой базовой серии нет и надо ее найти.
|
||||
try:
|
||||
query = Seria_Info.objects.get(id=int(seria_id))
|
||||
if query.kRoot_id is not None:
|
||||
# базовая серия прописана в kRoot_id
|
||||
seria_id = query.kRoot_id
|
||||
else:
|
||||
# == корневой нет
|
||||
# == ищем методом наименьших расстояний"
|
||||
min_min = 100000000
|
||||
min_id = seria_id
|
||||
for count_seria in q_seria:
|
||||
if math.fabs(int(seria_id) - count_seria.id) < min_min:
|
||||
min_min = math.fabs(int(seria_id) - count_seria.id)
|
||||
min_id = count_seria.id
|
||||
seria_id = min_id
|
||||
except ObjectDoesNotExist:
|
||||
seria_id = q_seria[0].id
|
||||
# print(f"-->{seria_id}<--")
|
||||
return all_seria_nav(seria_id, q_seria)
|
||||
|
||||
|
||||
def all_seria_nav(seria_id: int, q_seria) -> (int, dict):
|
||||
seria_nav_dim = []
|
||||
this_return = {}
|
||||
for count_seria in q_seria:
|
||||
one_seria = {}
|
||||
one_seria.update({"SERIA_R": count_seria.sName, "ID2URL": count_seria.id})
|
||||
if count_seria.id == seria_id:
|
||||
this_return.update({"THIS_SERIA_NAME": count_seria.sName,
|
||||
"THIS_SERIA_DESCRIPTION": count_seria.sSeriaDescription})
|
||||
# one_seria.update({"SERIA_L": ""})
|
||||
one_seria.update({"SERIA_L": pytils.translit.slugify(count_seria.sName)})
|
||||
else:
|
||||
one_seria.update({"SERIA_L": pytils.translit.slugify(count_seria.sName)})
|
||||
seria_nav_dim.append(one_seria)
|
||||
this_return.update({"SERIA_NAV_DIM": seria_nav_dim})
|
||||
return seria_id, this_return
|
||||
|
||||
|
||||
def seria_info_year(seria_id: int = 12) -> dict:
|
||||
""" Возвращает данные для графика распределения сдачи серии в эксплуатацию
|
||||
|
||||
:param seria_id: int -- id серии для которой нужно получить данные
|
||||
:return: dict -- данные для графика распределения сдачи серии в эксплуатацию типа:
|
||||
{"DATA4GRAPH": [{'YEAR': 1997, 'NUMS': 1, 'CLRS': '99'},
|
||||
{'YEAR': 1998, 'NUMS': 15, 'CLRS': 'сс'},
|
||||
{'YEAR': 1998, 'NUMS': 10, 'CLRS': 'a9'}
|
||||
]
|
||||
}
|
||||
"""
|
||||
seria_in_years = []
|
||||
query = Seria_Info.objects.raw(
|
||||
f"SELECT oknardia_building_info.iCommissioning_year as id,"
|
||||
f" COUNT(oknardia_building_info.iCommissioning_year) AS NumInYear "
|
||||
f"FROM oknardia_building_info"
|
||||
f" INNER JOIN oknardia_seria_info"
|
||||
f" ON oknardia_building_info.kSeria_Link_id = oknardia_seria_info.id "
|
||||
f"WHERE oknardia_seria_info.kRoot_id = {seria_id} "
|
||||
f"GROUP BY oknardia_building_info.iCommissioning_year;"
|
||||
)
|
||||
max_per_year = 0
|
||||
graph_color_light = 0xCC # самый светлый цвет на графике (максимальное значение)
|
||||
graph_color_dark = 0x99 # самый темный цвет на графике (минимальное значение)
|
||||
for YearCount in query:
|
||||
if int(YearCount.NumInYear) > max_per_year:
|
||||
max_per_year = int(YearCount.NumInYear)
|
||||
# print("max", MaxPerYear)
|
||||
for YearCount in query:
|
||||
data_of_year = {}
|
||||
try:
|
||||
data_of_year.update({
|
||||
"YEAR": int(YearCount.id),
|
||||
"NUMS": YearCount.NumInYear,
|
||||
"CLRS": str(hex(int(graph_color_dark + YearCount.NumInYear * (
|
||||
graph_color_light - graph_color_dark) / max_per_year)))[2:]
|
||||
})
|
||||
except ValueError:
|
||||
continue
|
||||
seria_in_years.append(data_of_year)
|
||||
# print(seria_in_years)
|
||||
return {"DATA4GRAPH": seria_in_years}
|
||||
|
||||
|
||||
def seria_info_geo_code(seria_id: str = '12') -> dict:
|
||||
""" Возвращает массив геокоординат зданий одной серии
|
||||
|
||||
:param seria_id: str -- id серии для которой нужно получить данные
|
||||
:return: dict -- массив геокоординат зданий серии
|
||||
"""
|
||||
data_return = {}
|
||||
seria_to_geo = []
|
||||
municipal_m2 = 0 # муниципальный фонд (кв.м)
|
||||
residential_m2 = 0 # жилой фонд (кв.м)
|
||||
government_m2 = 0 # государственные учреждения занимают (кв.м.)
|
||||
residents = 0 # количество жильцов
|
||||
apartments = 0 # число квартиры
|
||||
accounts = 0 # количество лицевых счетов
|
||||
condition_max = 0 # максимальное значение показателя состояния здания
|
||||
condition_min = 1000000 # минимальное значение показателя состояния здания
|
||||
query = Building_Info.objects.raw(
|
||||
f"SELECT"
|
||||
f" oknardia_building_info.id,"
|
||||
f" oknardia_seria_info.kRoot_id as SerId,"
|
||||
f" oknardia_building_info.sAddress,"
|
||||
f" oknardia_building_info.fResidential_Area,"
|
||||
f" oknardia_building_info.fMunicipal_Area,"
|
||||
f" oknardia_building_info.fGovernment_Area,"
|
||||
f" oknardia_building_info.iNum_Residents,"
|
||||
f" oknardia_building_info.iNum_Apartments,"
|
||||
f" oknardia_building_info.iNum_Accounts,"
|
||||
f" oknardia_building_info.fCondition_House,"
|
||||
f" oknardia_building_info.fGeoCode_Latitude,"
|
||||
f" oknardia_building_info.fGeoCode_Longitude "
|
||||
f"FROM oknardia_building_info"
|
||||
f" INNER JOIN oknardia_seria_info"
|
||||
f" ON oknardia_building_info.kSeria_Link_id = oknardia_seria_info.id "
|
||||
f"WHERE oknardia_seria_info.kRoot_id IN ({seria_id});"
|
||||
)
|
||||
for count in query:
|
||||
if int(count.fGeoCode_Latitude) != 0 and int(count.fGeoCode_Longitude) != 0:
|
||||
seria_to_geo.append({"LATITUDE": count.fGeoCode_Latitude,
|
||||
"LONGITUDE": count.fGeoCode_Longitude,
|
||||
"ADDR_ID": count.id,
|
||||
"ADDR_LAT": pytils.translit.slugify(count.sAddress),
|
||||
"ADDR_RUS": count.sAddress,
|
||||
"SER_ID": count.SerId
|
||||
})
|
||||
if count.fMunicipal_Area > 0:
|
||||
municipal_m2 += count.fMunicipal_Area
|
||||
if count.fResidential_Area > 0:
|
||||
residential_m2 += count.fResidential_Area
|
||||
if count.fGovernment_Area > 0:
|
||||
government_m2 += count.fGovernment_Area
|
||||
if count.iNum_Residents > 0:
|
||||
residents += count.iNum_Residents
|
||||
if count.iNum_Residents > 0:
|
||||
residents += count.iNum_Residents
|
||||
if count.iNum_Apartments > 0:
|
||||
apartments += count.iNum_Apartments
|
||||
if count.iNum_Accounts > 0:
|
||||
accounts += count.iNum_Accounts
|
||||
if count.fCondition_House > 0:
|
||||
if count.fCondition_House > condition_max:
|
||||
condition_max = count.fCondition_House
|
||||
if count.fCondition_House < condition_min:
|
||||
condition_min = count.fCondition_House
|
||||
data_return.update({"DATA4GEO": seria_to_geo,
|
||||
"MUNICIPAL_M2": municipal_m2,
|
||||
"RESIDENTIAL_M2": residential_m2,
|
||||
"GOVERNMENT_M2": government_m2,
|
||||
"RESIDENTS": residents,
|
||||
"APARTMENTS": apartments,
|
||||
"ACCOUNTS": accounts,
|
||||
"CONDITION_MAX": condition_max,
|
||||
"CONDITION_MIN": condition_min})
|
||||
# print(seria_to_geo)
|
||||
return data_return
|
||||
@@ -5,7 +5,7 @@ from django.core.exceptions import ObjectDoesNotExist
|
||||
from time import time
|
||||
from oknardia.settings import *
|
||||
from oknardia.models import Seria_Info
|
||||
from web.catalog import all_seria_nav
|
||||
from web.catalog_series import all_seria_nav
|
||||
# from oknardia.catalog import all_seria_nav
|
||||
import math
|
||||
import os
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
@@ -0,0 +1,612 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
"""
|
||||
Команда генерации sitemap-файлов проекта.
|
||||
|
||||
Почему реализовано именно так:
|
||||
- Генерация выполняется оффлайн (через management command), чтобы не нагружать веб-запросы.
|
||||
- На выходе всегда создаются статические XML-файлы, которые потом отдает Nginx/прокси.
|
||||
- URL-источники описаны через Django Sitemap API (классы Sitemap), но рендер XML
|
||||
контролируем самостоятельно для точного управления лимитами размера/количества.
|
||||
"""
|
||||
|
||||
from collections import defaultdict
|
||||
from dataclasses import dataclass
|
||||
from datetime import date, datetime
|
||||
from itertools import combinations
|
||||
from pathlib import Path
|
||||
from typing import Iterable
|
||||
from xml.etree import ElementTree as ET
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.sitemaps import Sitemap
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from django.db.models import Count, F, Max, Min
|
||||
from django.utils import timezone
|
||||
|
||||
from oknardia.models import (
|
||||
Apartment_Type,
|
||||
BlogPosts,
|
||||
Building_Info,
|
||||
MerchantBrand,
|
||||
PriceOffer,
|
||||
PVCprofiles,
|
||||
Seria_Info,
|
||||
SetKit,
|
||||
Win_MountDim,
|
||||
)
|
||||
import pytils
|
||||
|
||||
|
||||
# Namespace схемы sitemap.xml по стандарту sitemaps.org.
|
||||
SITEMAP_XMLNS = "http://www.sitemaps.org/schemas/sitemap/0.9"
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
class SitemapBuildResult:
|
||||
"""Итог генерации sitemap для удобного вывода в CLI и web-обертках."""
|
||||
|
||||
# Общее число URL, записанных во все sitemap-файлы.
|
||||
total_urls: int
|
||||
# Количество созданных файлов (1 = только sitemap.xml, >1 = sitemapindex + sitemapNNNN.xml).
|
||||
files_count: int
|
||||
# Время выполнения генерации в секундах.
|
||||
elapsed_seconds: float
|
||||
# Физический каталог, куда записаны файлы.
|
||||
output_dir: Path
|
||||
|
||||
|
||||
def _as_sitemap_date(value: date | datetime | None) -> str:
|
||||
"""
|
||||
Приводит дату/время к формату `YYYY-MM-DD`.
|
||||
|
||||
Для sitemap нам не нужна точность до секунд: поисковикам достаточно даты.
|
||||
Если значение не передано, используем текущую локальную дату.
|
||||
"""
|
||||
if value is None:
|
||||
return timezone.localdate().isoformat()
|
||||
if isinstance(value, datetime):
|
||||
return value.date().isoformat()
|
||||
return value.isoformat()
|
||||
|
||||
|
||||
class SingleWindowSitemap(Sitemap):
|
||||
"""Источник URL для страниц цен одного проёма (/tsena-odnogo-okna/...)."""
|
||||
|
||||
changefreq = "weekly"
|
||||
priority = 0.5
|
||||
|
||||
def __init__(self, lastmod_value: datetime):
|
||||
# Один timestamp на весь прогон: так проще сравнивать выпуски sitemap.
|
||||
self.lastmod_value = lastmod_value
|
||||
|
||||
def items(self):
|
||||
# Берем только те монтажные размеры, где есть реальные офферы.
|
||||
# Сортировка по числу офферов повторяет историческую логику из raw SQL.
|
||||
mount_ids = (
|
||||
PriceOffer.objects.values("kOffer2MountDim_id")
|
||||
.annotate(num_offer=Count("id"))
|
||||
.order_by("num_offer", "kOffer2MountDim_id")
|
||||
.values_list("kOffer2MountDim_id", flat=True)
|
||||
)
|
||||
# Возвращаем сами объекты Win_MountDim, чтобы location() строил URL без доп. запросов.
|
||||
return Win_MountDim.objects.filter(id__in=mount_ids).only("id", "iWinWidth", "iWinHight")
|
||||
|
||||
def location(self, item: Win_MountDim) -> str:
|
||||
# В БД размеры в см (Decimal с 1 знаком). В URL исторически используются мм,
|
||||
# поэтому умножаем на 10 и приводим к int.
|
||||
width_mm = int(float(item.iWinWidth) * 10)
|
||||
height_mm = int(float(item.iWinHight) * 10)
|
||||
return f"/tsena-odnogo-okna/{width_mm}x{height_mm}mm/tip{item.id}"
|
||||
|
||||
def lastmod(self, item: Win_MountDim) -> datetime:
|
||||
return self.lastmod_value
|
||||
|
||||
|
||||
class BuildingOffersSitemap(Sitemap):
|
||||
"""Источник URL для страниц ценовой выдачи по адресам (/{build_id}/{apart_id}/{slug})."""
|
||||
|
||||
changefreq = "weekly"
|
||||
priority = 0.5
|
||||
|
||||
def __init__(self, lastmod_value: datetime):
|
||||
self.lastmod_value = lastmod_value
|
||||
|
||||
def items(self):
|
||||
# Получаем здания только с валидной привязкой к корневой серии.
|
||||
buildings = list(
|
||||
Building_Info.objects.filter(kSeria_Link__kRoot__isnull=False)
|
||||
.select_related("kSeria_Link__kRoot")
|
||||
.only("id", "sAddress", "kSeria_Link__kRoot")
|
||||
.order_by("id")
|
||||
)
|
||||
|
||||
# Для каждой корневой серии нужен список типов квартир, чтобы собрать итоговые URL.
|
||||
root_ids = {
|
||||
building.kSeria_Link.kRoot_id
|
||||
for building in buildings
|
||||
if building.kSeria_Link_id and building.kSeria_Link.kRoot_id
|
||||
}
|
||||
apartments_by_root: dict[int, list[int]] = defaultdict(list)
|
||||
for root_id, apart_id in Apartment_Type.objects.filter(kSeria_id__in=root_ids).values_list("kSeria_id", "id"):
|
||||
apartments_by_root[root_id].append(apart_id)
|
||||
|
||||
# Генерируем декартово произведение: здание x квартиры его корневой серии.
|
||||
for building in buildings:
|
||||
root_id = building.kSeria_Link.kRoot_id if building.kSeria_Link_id else None
|
||||
if not root_id:
|
||||
continue
|
||||
for apart_id in apartments_by_root.get(root_id, []):
|
||||
yield (building.id, apart_id, pytils.translit.slugify(building.sAddress))
|
||||
|
||||
def location(self, item: tuple[int, int, str]) -> str:
|
||||
build_id, apart_id, slug = item
|
||||
return f"/{build_id}/{apart_id}/{slug}"
|
||||
|
||||
def lastmod(self, item: tuple[int, int, str]) -> datetime:
|
||||
return self.lastmod_value
|
||||
|
||||
|
||||
class CompareOffersSitemap(Sitemap):
|
||||
"""Источник URL для страниц сравнения наборов (/compare_offers/1,2,3...)."""
|
||||
|
||||
# Для compare-страниц изменения редки, поэтому просим роботов не дергать их часто.
|
||||
changefreq = "monthly"
|
||||
priority = 0.35
|
||||
|
||||
def __init__(self, lastmod_value: datetime, min_depth: int = 2, max_depth: int = 4):
|
||||
self.lastmod_value = lastmod_value
|
||||
# Жестко ограничиваем глубину до 2..4, чтобы не получить комбинаторный взрыв.
|
||||
self.min_depth = max(2, min_depth)
|
||||
self.max_depth = min(4, max_depth)
|
||||
|
||||
def items(self):
|
||||
# Берем только активные наборы и строим combinations без повторов/перестановок.
|
||||
set_ids = list(SetKit.objects.filter(sSetActive=True).order_by("id").values_list("id", flat=True))
|
||||
for depth in range(self.min_depth, self.max_depth + 1):
|
||||
for combo in combinations(set_ids, depth):
|
||||
# Формат URL-параметра должен остаться историческим: "1,2,3".
|
||||
yield ",".join(str(item) for item in combo)
|
||||
|
||||
def location(self, item: str) -> str:
|
||||
return f"/compare_offers/{item}"
|
||||
|
||||
def lastmod(self, item: str) -> datetime:
|
||||
return self.lastmod_value
|
||||
|
||||
|
||||
class StaticPagesSitemap(Sitemap):
|
||||
"""Набор важных статических/обзорных страниц, которые не требуют отдельной модели."""
|
||||
|
||||
def __init__(self, items: list[dict]):
|
||||
self._items = items
|
||||
|
||||
def items(self):
|
||||
return self._items
|
||||
|
||||
def location(self, item: dict) -> str:
|
||||
return item["loc"]
|
||||
|
||||
def lastmod(self, item: dict) -> date | datetime | None:
|
||||
return item.get("lastmod")
|
||||
|
||||
def changefreq(self, item: dict) -> str:
|
||||
return item.get("changefreq", "weekly")
|
||||
|
||||
def priority(self, item: dict) -> float:
|
||||
return float(item.get("priority", 0.5))
|
||||
|
||||
|
||||
class BlogListSitemap(Sitemap):
|
||||
"""Страницы пагинации блога: /blog/P0, /blog/P1, ..."""
|
||||
|
||||
changefreq = "weekly"
|
||||
priority = 0.82
|
||||
|
||||
def __init__(self, lastmod_value: date | datetime | None):
|
||||
self.lastmod_value = lastmod_value
|
||||
|
||||
def items(self):
|
||||
posts_qs = BlogPosts.objects.filter(
|
||||
dPostDataBegin__lte=timezone.now(),
|
||||
bPublished=True,
|
||||
bArchive=False,
|
||||
)
|
||||
total_posts = posts_qs.count()
|
||||
if total_posts == 0:
|
||||
return []
|
||||
pages_total = (total_posts - 1) // settings.NUM_BLOG_TIZER_IN_PAGE + 1
|
||||
return list(range(pages_total))
|
||||
|
||||
def location(self, item: int) -> str:
|
||||
return f"/blog/P{item}"
|
||||
|
||||
def lastmod(self, item: int) -> date | datetime | None:
|
||||
return self.lastmod_value
|
||||
|
||||
|
||||
class BlogPostSitemap(Sitemap):
|
||||
"""Публичные посты блога в каноническом URL без page_back."""
|
||||
|
||||
changefreq = "monthly"
|
||||
priority = 0.90
|
||||
|
||||
def items(self):
|
||||
return BlogPosts.objects.filter(
|
||||
dPostDataBegin__lte=timezone.now(),
|
||||
bPublished=True,
|
||||
bArchive=False,
|
||||
).only("id", "sPostHeader", "dPostDataModify")
|
||||
|
||||
def location(self, item: BlogPosts) -> str:
|
||||
return f"/blogpost/{item.id}/{pytils.translit.slugify(item.sPostHeader).lower()}"
|
||||
|
||||
def lastmod(self, item: BlogPosts) -> date | datetime | None:
|
||||
return item.dPostDataModify
|
||||
|
||||
|
||||
class ProfileManufactureSitemap(Sitemap):
|
||||
"""Страницы производителей профилей: /catalog/profile/{id}-{manufacturer}."""
|
||||
|
||||
changefreq = "monthly"
|
||||
priority = 0.92
|
||||
|
||||
def items(self):
|
||||
return list(
|
||||
PVCprofiles.objects.values("sProfileManufacturer")
|
||||
.annotate(first_id=Min("id"), lastmod=Max("dProfileModify"))
|
||||
.order_by("sProfileManufacturer")
|
||||
)
|
||||
|
||||
def location(self, item: dict) -> str:
|
||||
manufacturer_slug = pytils.translit.slugify(item["sProfileManufacturer"]).lower()
|
||||
return f"/catalog/profile/{item['first_id']}-{manufacturer_slug}"
|
||||
|
||||
def lastmod(self, item: dict) -> date | datetime | None:
|
||||
return item.get("lastmod")
|
||||
|
||||
|
||||
class ProfileModelSitemap(Sitemap):
|
||||
"""Карточки конкретных профильных систем."""
|
||||
|
||||
changefreq = "monthly"
|
||||
priority = 0.94
|
||||
|
||||
def items(self):
|
||||
return PVCprofiles.objects.only("id", "sProfileManufacturer", "sProfileName", "dProfileModify")
|
||||
|
||||
def location(self, item: PVCprofiles) -> str:
|
||||
manufacturer_slug = pytils.translit.slugify(item.sProfileManufacturer).lower()
|
||||
model_slug = pytils.translit.slugify(item.sProfileName).lower()
|
||||
# Исторически канонический URL использует id модели и в сегменте manufacturer_id, и в segment model_id.
|
||||
return f"/catalog/profile/{item.id}-{manufacturer_slug}/{item.id}-{model_slug}"
|
||||
|
||||
def lastmod(self, item: PVCprofiles) -> date | datetime | None:
|
||||
return item.dProfileModify
|
||||
|
||||
|
||||
class SeriaDetailSitemap(Sitemap):
|
||||
"""Страницы типовых серий домов — это одни из самых важных SEO-страниц проекта."""
|
||||
|
||||
changefreq = "monthly"
|
||||
priority = 0.97
|
||||
|
||||
def items(self):
|
||||
return Seria_Info.objects.filter(id__isnull=False, kRoot_id__isnull=False, id=F("kRoot_id")).only(
|
||||
"id", "sName", "dSeriaInfoModify"
|
||||
)
|
||||
|
||||
def location(self, item: Seria_Info) -> str:
|
||||
return f"/catalog/seria/{pytils.translit.slugify(item.sName).lower()}/all{item.id}"
|
||||
|
||||
def lastmod(self, item: Seria_Info) -> date | datetime | None:
|
||||
return item.dSeriaInfoModify
|
||||
|
||||
|
||||
class CompanyDetailSitemap(Sitemap):
|
||||
"""Страницы брендов/производителей оконных компаний."""
|
||||
|
||||
changefreq = "monthly"
|
||||
priority = 0.91
|
||||
|
||||
def items(self):
|
||||
return list(
|
||||
MerchantBrand.objects.annotate(
|
||||
last_offer_modify=Max("merchantoffice__ouruser__setkit__priceoffer__dOfferModify"),
|
||||
last_office_modify=Max("merchantoffice__dOfficeDataModify"),
|
||||
).only("id", "sMerchantName")
|
||||
)
|
||||
|
||||
def location(self, item: MerchantBrand) -> str:
|
||||
return f"/catalog/company/{item.id}-{pytils.translit.slugify(item.sMerchantName).lower()}"
|
||||
|
||||
def lastmod(self, item: MerchantBrand) -> date | datetime | None:
|
||||
return getattr(item, "last_offer_modify", None) or getattr(item, "last_office_modify", None)
|
||||
|
||||
|
||||
class SitemapXmlWriter:
|
||||
"""
|
||||
Низкоуровневый писатель XML.
|
||||
|
||||
Делит URL на несколько файлов по двум условиям:
|
||||
- число URL в файле;
|
||||
- приблизительный размер файла в байтах.
|
||||
|
||||
Если chunk-файлов больше одного, создается sitemapindex (sitemap.xml),
|
||||
который перечисляет sitemap0000.xml, sitemap0001.xml и т.д.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
output_dir: Path,
|
||||
public_base_url: str,
|
||||
max_items: int,
|
||||
max_file_size: int,
|
||||
max_files_qty: int,
|
||||
):
|
||||
self.output_dir = output_dir
|
||||
# Публичный URL-префикс для ссылок в sitemapindex.
|
||||
self.public_base_url = public_base_url.rstrip("/")
|
||||
self.max_items = max_items
|
||||
self.max_file_size = max_file_size
|
||||
self.max_files_qty = max_files_qty
|
||||
|
||||
self.total_urls = 0
|
||||
self.chunk_files: list[str] = []
|
||||
self.current_urls: list[ET.Element] = []
|
||||
# Небольшой стартовый запас размера на корневые XML-теги.
|
||||
self.current_size = 128
|
||||
|
||||
def cleanup_old(self) -> None:
|
||||
# Перед генерацией удаляем старые sitemap*.xml, чтобы не оставить устаревшие куски.
|
||||
self.output_dir.mkdir(parents=True, exist_ok=True)
|
||||
for file_path in self.output_dir.glob("sitemap*.xml"):
|
||||
file_path.unlink(missing_ok=True)
|
||||
|
||||
def add_url(self, loc: str, lastmod: datetime, changefreq: str, priority: float) -> None:
|
||||
# Собираем XML-элемент URL и оцениваем его вклад в размер файла.
|
||||
url_element = self._build_url_element(loc=loc, lastmod=lastmod, changefreq=changefreq, priority=priority)
|
||||
url_size = len(ET.tostring(url_element, encoding="utf-8"))
|
||||
|
||||
need_flush = False
|
||||
if self.current_urls:
|
||||
# Лимиты применяем только если файл уже что-то содержит:
|
||||
# так мы гарантируем, что хотя бы один URL всегда будет записан.
|
||||
if len(self.current_urls) >= self.max_items:
|
||||
need_flush = True
|
||||
elif self.current_size + url_size > self.max_file_size:
|
||||
need_flush = True
|
||||
|
||||
if need_flush:
|
||||
self._flush_chunk()
|
||||
|
||||
self.current_urls.append(url_element)
|
||||
self.current_size += url_size
|
||||
self.total_urls += 1
|
||||
|
||||
def finalize(self, generated_at: datetime) -> int:
|
||||
# Если уже были chunk-файлы, значит итог должен быть в формате sitemapindex.
|
||||
if self.chunk_files:
|
||||
self._flush_chunk()
|
||||
self._write_sitemap_index(generated_at)
|
||||
return len(self.chunk_files)
|
||||
|
||||
# Иначе пишем единый sitemap.xml с URLSet.
|
||||
self._write_single_sitemap()
|
||||
return 1
|
||||
|
||||
def _flush_chunk(self) -> None:
|
||||
if not self.current_urls:
|
||||
return
|
||||
|
||||
chunk_idx = len(self.chunk_files)
|
||||
if chunk_idx >= self.max_files_qty:
|
||||
raise RuntimeError(
|
||||
"Превышено максимальное количество sitemap-файлов. "
|
||||
f"Текущий лимит: {self.max_files_qty}."
|
||||
)
|
||||
|
||||
file_name = f"sitemap{chunk_idx:04d}.xml"
|
||||
self._write_urlset(self.output_dir / file_name, self.current_urls)
|
||||
self.chunk_files.append(file_name)
|
||||
|
||||
# Сбрасываем буфер для следующего chunk-файла.
|
||||
self.current_urls = []
|
||||
self.current_size = 128
|
||||
|
||||
def _write_single_sitemap(self) -> None:
|
||||
self._write_urlset(self.output_dir / "sitemap.xml", self.current_urls)
|
||||
self.current_urls = []
|
||||
self.current_size = 128
|
||||
|
||||
def _write_sitemap_index(self, generated_at: datetime) -> None:
|
||||
root = ET.Element("sitemapindex", xmlns=SITEMAP_XMLNS)
|
||||
for file_name in self.chunk_files:
|
||||
sitemap_element = ET.SubElement(root, "sitemap")
|
||||
ET.SubElement(sitemap_element, "loc").text = f"{self.public_base_url}/{file_name}"
|
||||
ET.SubElement(sitemap_element, "lastmod").text = _as_sitemap_date(generated_at)
|
||||
|
||||
xml_bytes = ET.tostring(root, encoding="utf-8", xml_declaration=True)
|
||||
(self.output_dir / "sitemap.xml").write_bytes(xml_bytes)
|
||||
|
||||
@staticmethod
|
||||
def _write_urlset(file_path: Path, urls: Iterable[ET.Element]) -> None:
|
||||
root = ET.Element("urlset", xmlns=SITEMAP_XMLNS)
|
||||
for url in urls:
|
||||
root.append(url)
|
||||
xml_bytes = ET.tostring(root, encoding="utf-8", xml_declaration=True)
|
||||
file_path.write_bytes(xml_bytes)
|
||||
|
||||
@staticmethod
|
||||
def _build_url_element(loc: str, lastmod: datetime, changefreq: str, priority: float) -> ET.Element:
|
||||
element = ET.Element("url")
|
||||
ET.SubElement(element, "loc").text = loc
|
||||
ET.SubElement(element, "lastmod").text = _as_sitemap_date(lastmod)
|
||||
ET.SubElement(element, "changefreq").text = changefreq
|
||||
ET.SubElement(element, "priority").text = f"{priority:.2f}"
|
||||
return element
|
||||
|
||||
|
||||
def build_sitemaps(
|
||||
output_dir: Path,
|
||||
site_base_url: str,
|
||||
sitemap_url_prefix: str,
|
||||
max_items: int,
|
||||
max_file_size: int,
|
||||
max_files_qty: int,
|
||||
compare_min_depth: int = 2,
|
||||
compare_max_depth: int = 4,
|
||||
) -> SitemapBuildResult:
|
||||
"""Оркестратор полного прогона сборки sitemap-файлов."""
|
||||
time_start = timezone.now()
|
||||
generated_at = timezone.now()
|
||||
compare_lastmod = generated_at.date().replace(day=1)
|
||||
latest_blog_modify = BlogPosts.objects.filter(
|
||||
dPostDataBegin__lte=timezone.now(),
|
||||
bPublished=True,
|
||||
bArchive=False,
|
||||
).aggregate(lastmod=Max("dPostDataModify"))["lastmod"]
|
||||
latest_profile_modify = PVCprofiles.objects.aggregate(lastmod=Max("dProfileModify"))["lastmod"]
|
||||
latest_seria_modify = Seria_Info.objects.aggregate(lastmod=Max("dSeriaInfoModify"))["lastmod"]
|
||||
latest_company_modify = MerchantBrand.objects.annotate(
|
||||
last_offer_modify=Max("merchantoffice__ouruser__setkit__priceoffer__dOfferModify"),
|
||||
last_office_modify=Max("merchantoffice__dOfficeDataModify"),
|
||||
).aggregate(lastmod=Max("last_offer_modify"), lastmod_office=Max("last_office_modify"))
|
||||
latest_company_date = latest_company_modify.get("lastmod") or latest_company_modify.get("lastmod_office")
|
||||
|
||||
base_url = site_base_url.rstrip("/")
|
||||
url_prefix = sitemap_url_prefix.strip("/")
|
||||
public_sitemap_base = f"{base_url}/{url_prefix}" if url_prefix else base_url
|
||||
|
||||
writer = SitemapXmlWriter(
|
||||
output_dir=output_dir,
|
||||
public_base_url=public_sitemap_base,
|
||||
max_items=max_items,
|
||||
max_file_size=max_file_size,
|
||||
max_files_qty=max_files_qty,
|
||||
)
|
||||
writer.cleanup_old()
|
||||
|
||||
# Источники URL. Порядок можно менять, если нужно управлять наполнением chunk-файлов.
|
||||
sitemaps = [
|
||||
StaticPagesSitemap(
|
||||
items=[
|
||||
{"loc": "/", "lastmod": generated_at, "changefreq": "weekly", "priority": 1.00},
|
||||
{"loc": "/catalog", "lastmod": generated_at, "changefreq": "weekly", "priority": 0.88},
|
||||
{"loc": "/catalog/profile", "lastmod": latest_profile_modify, "changefreq": "weekly", "priority": 0.92},
|
||||
{"loc": "/catalog/seria", "lastmod": latest_seria_modify, "changefreq": "weekly", "priority": 0.95},
|
||||
{"loc": "/catalog/standard_opening", "lastmod": latest_seria_modify, "changefreq": "monthly", "priority": 0.86},
|
||||
{"loc": "/catalog/company", "lastmod": latest_company_date, "changefreq": "weekly", "priority": 0.90},
|
||||
{"loc": "/stat/rating/profiles_rank", "lastmod": latest_profile_modify, "changefreq": "monthly", "priority": 0.76},
|
||||
]
|
||||
),
|
||||
BlogListSitemap(lastmod_value=latest_blog_modify),
|
||||
BlogPostSitemap(),
|
||||
ProfileManufactureSitemap(),
|
||||
ProfileModelSitemap(),
|
||||
SeriaDetailSitemap(),
|
||||
CompanyDetailSitemap(),
|
||||
SingleWindowSitemap(lastmod_value=generated_at),
|
||||
BuildingOffersSitemap(lastmod_value=generated_at),
|
||||
CompareOffersSitemap(
|
||||
lastmod_value=compare_lastmod,
|
||||
min_depth=compare_min_depth,
|
||||
max_depth=compare_max_depth,
|
||||
),
|
||||
]
|
||||
|
||||
for sitemap in sitemaps:
|
||||
for item in sitemap.items():
|
||||
location = sitemap.location(item)
|
||||
lastmod = sitemap.lastmod(item)
|
||||
if not location.startswith("/"):
|
||||
location = f"/{location}"
|
||||
sitemap_changefreq = sitemap.changefreq(item) if callable(getattr(sitemap, "changefreq", None)) else str(sitemap.changefreq)
|
||||
sitemap_priority = sitemap.priority(item) if callable(getattr(sitemap, "priority", None)) else float(sitemap.priority)
|
||||
writer.add_url(
|
||||
loc=f"{base_url}{location}",
|
||||
lastmod=lastmod,
|
||||
changefreq=sitemap_changefreq,
|
||||
priority=sitemap_priority,
|
||||
)
|
||||
|
||||
files_count = writer.finalize(generated_at=generated_at)
|
||||
elapsed = (timezone.now() - time_start).total_seconds()
|
||||
return SitemapBuildResult(
|
||||
total_urls=writer.total_urls,
|
||||
files_count=files_count,
|
||||
elapsed_seconds=elapsed,
|
||||
output_dir=output_dir,
|
||||
)
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Генерирует sitemap.xml и sitemapNNNN.xml в файловый кэш."
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
"--compare-min-depth",
|
||||
type=int,
|
||||
default=2,
|
||||
help="Минимальная глубина комбинаций compare_offers (по умолчанию 2).",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--compare-max-depth",
|
||||
type=int,
|
||||
default=4,
|
||||
help="Максимальная глубина комбинаций compare_offers (по умолчанию 4).",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--max-items",
|
||||
type=int,
|
||||
default=40000,
|
||||
help="Максимум URL в одном sitemap-файле (по умолчанию 40000).",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--max-file-size",
|
||||
type=int,
|
||||
default=5242880,
|
||||
help="Максимальный размер sitemap-файла в байтах (по умолчанию 5242880).",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--max-files-qty",
|
||||
type=int,
|
||||
default=998,
|
||||
help="Максимум вложенных sitemap-файлов (по умолчанию 998).",
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
# Валидация глубины compare перед запуском тяжелой части генерации.
|
||||
compare_min_depth = options["compare_min_depth"]
|
||||
compare_max_depth = options["compare_max_depth"]
|
||||
if compare_min_depth > compare_max_depth:
|
||||
raise CommandError("--compare-min-depth не может быть больше --compare-max-depth")
|
||||
|
||||
result = build_sitemaps(
|
||||
output_dir=Path(settings.SITEMAP_ROOT),
|
||||
site_base_url=settings.SITE_BASE_URL,
|
||||
sitemap_url_prefix=settings.SITEMAP_URL_PREFIX,
|
||||
max_items=options["max_items"],
|
||||
max_file_size=options["max_file_size"],
|
||||
max_files_qty=options["max_files_qty"],
|
||||
compare_min_depth=compare_min_depth,
|
||||
compare_max_depth=compare_max_depth,
|
||||
)
|
||||
|
||||
# Человекочитаемый отчет для логов CI/CD и контейнерных entrypoint-скриптов.
|
||||
if result.files_count == 1:
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS(
|
||||
f"Создан единственный sitemap.xml. URL-ов: {result.total_urls}. "
|
||||
f"Время: {result.elapsed_seconds:.2f} сек."
|
||||
)
|
||||
)
|
||||
else:
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS(
|
||||
f"Создан каскад sitemap. Файлов: {result.files_count}. URL-ов: {result.total_urls}. "
|
||||
f"Время: {result.elapsed_seconds:.2f} сек."
|
||||
)
|
||||
)
|
||||
|
||||
+15
-12
@@ -325,7 +325,7 @@ def report_one_win_price(request: HttpRequest, win_width_mm: str = '670', win_he
|
||||
:param win_id: str -- ID проема (см. таблицу oknardia_win_mountdim)
|
||||
:return response: HttpResponse -- исходящий http-ответ
|
||||
"""
|
||||
time_start = time.time()
|
||||
time_start = time.perf_counter()
|
||||
to_template = {}
|
||||
try:
|
||||
# т.к. для вызова GetFlapDim4BigPictures нужно иметь внутри queryset поле iQuantity нельзя использовать
|
||||
@@ -439,7 +439,7 @@ def report_one_win_price(request: HttpRequest, win_width_mm: str = '670', win_he
|
||||
# получаем последние визиты всех посетителей из базы
|
||||
# id2log, log_visit = get_last_all_user_visit_list()
|
||||
'LOG_VISIT': get_last_all_user_visit_list(),
|
||||
'ticks': float(time.time() - time_start)
|
||||
'ticks': float(time.perf_counter() - time_start)
|
||||
})
|
||||
return render(request, "price/price_offers_for_one_window.html", to_template)
|
||||
|
||||
@@ -452,11 +452,11 @@ def next_one_win_price(request: HttpRequest, win_id='16', frame_begin_n="0"):
|
||||
:param frame_begin_n: str -- Номер записи с которой начинается фрейм с ценами
|
||||
:return: HttpResponse --
|
||||
"""
|
||||
time_start = time.time()
|
||||
time_start = time.perf_counter()
|
||||
to_template = report_price_frame(0, 1, 0, 0, int(frame_begin_n), 0, int(win_id))
|
||||
to_template.update({'MOUNT_DIM_PER_OFFER': 1,
|
||||
'WIN_ID': int(win_id),
|
||||
'ticks': float(time.time() - time_start)})
|
||||
'ticks': float(time.perf_counter() - time_start)})
|
||||
return render(request, "price/price_offers_for_one_window_frame.html", to_template)
|
||||
|
||||
|
||||
@@ -470,7 +470,7 @@ def report_price(request: HttpRequest, build_id: str = "22427", apart_id: str =
|
||||
:param slug: str - slug адреса здания
|
||||
:return: response: HttpResponse
|
||||
"""
|
||||
time_start = time.time()
|
||||
time_start = time.perf_counter()
|
||||
msg = ""
|
||||
to_template = {}
|
||||
try:
|
||||
@@ -644,7 +644,10 @@ def report_price(request: HttpRequest, build_id: str = "22427", apart_id: str =
|
||||
|
||||
# получаем последние визиты всех посетителей из базы
|
||||
log_visit = get_last_all_user_visit_list()
|
||||
id_last_visit_log = log_visit[0]['id'] + 1
|
||||
if log_visit[0]['id'] is not None:
|
||||
id_last_visit_log = log_visit[0]['id'] + 1
|
||||
else:
|
||||
id_last_visit_log = 1
|
||||
# print("id_last_visit_log:", id_last_visit_log)
|
||||
to_template.update({'LOG_VISIT': log_visit})
|
||||
if id_last_visit_log > MAX_LEN_RING_LOG_BUFFER: # максимальный размер циклического буфера
|
||||
@@ -654,14 +657,14 @@ def report_price(request: HttpRequest, build_id: str = "22427", apart_id: str =
|
||||
log_entry.sLogAddress = to_template["ADDRESS"]
|
||||
log_entry.sLogNameApartment = to_template["APART"]
|
||||
log_entry.sLogURL = f"/{build_id}/{apart_id}/{to_template['ADDRESS_T']}"
|
||||
log_entry.dLogVisitTime = time.time()
|
||||
log_entry.dLogVisitTime = time.perf_counter()
|
||||
log_entry.save() # UPDATE
|
||||
except ObjectDoesNotExist:
|
||||
log_entry = LogVisitPriceReport(
|
||||
sLogAddress=to_template["ADDRESS"],
|
||||
sLogNameApartment=to_template["APART"],
|
||||
sLogURL=f"/{build_id}/{apart_id}/{to_template['ADDRESS_T']}",
|
||||
dLogVisitTime=time.time()
|
||||
dLogVisitTime=time.perf_counter()
|
||||
)
|
||||
log_entry.save() # INSERT
|
||||
|
||||
@@ -673,11 +676,11 @@ def report_price(request: HttpRequest, build_id: str = "22427", apart_id: str =
|
||||
"LastURL": f"/{build_id}/{apart_id}/{to_template['ADDRESS_T']}",
|
||||
"LastAddress": to_template["ADDRESS"],
|
||||
"LastApart": to_template["APART"],
|
||||
"Time": time.time()}
|
||||
"Time": time.perf_counter()}
|
||||
last_visit.insert(0, Item) # Добавляем текущий Item в начало
|
||||
last_visit = json.dumps(last_visit[:3]) # упаковываем json без пробелов (три записи)
|
||||
# print u"сейчас запишем вот эту куку:", LastVisit
|
||||
to_template.update({'ticks': float(time.time() - time_start)})
|
||||
to_template.update({'ticks': float(time.perf_counter() - time_start)})
|
||||
response = render(request, "price/price_list.html", to_template)
|
||||
response.set_cookie("LastVisit", last_visit, max_age=7862400) # ставим или перезаписываем куки (91 день)
|
||||
return response
|
||||
@@ -699,7 +702,7 @@ def next_price_frame(request: HttpRequest, apart_id: str = "1", mount_dim_per_o
|
||||
:param frame_begin_n: str -- Номер записи с которой начинается фрейм с ценами
|
||||
:return: HttpResponse -- HTTP-ответ
|
||||
"""
|
||||
time_start = time.time()
|
||||
time_start = time.perf_counter()
|
||||
# получаем данные для фрейма ценовых предложений
|
||||
price_frame = report_price_frame(int(apart_id), int(mount_dim_per_offer), float(address_longitude),
|
||||
float(address_latitude), int(frame_begin_n))
|
||||
@@ -708,5 +711,5 @@ def next_price_frame(request: HttpRequest, apart_id: str = "1", mount_dim_per_o
|
||||
'MOUNT_DIM_PER_OFFER': mount_dim_per_offer,
|
||||
'ADDRESS_LAT': address_latitude,
|
||||
'ADDRESS_LON': address_longitude,
|
||||
'ticks': float(time.time() - time_start)})
|
||||
'ticks': float(time.perf_counter() - time_start)})
|
||||
return render(request, "price/price_list_frame.html", to_template)
|
||||
|
||||
@@ -80,7 +80,7 @@ def compare_offers(request: HttpRequest, to_compare: str = "1,2") -> HttpRespons
|
||||
:param to_compare: str -- список ,через запятую, id оконных наборов (Set) для сравнения
|
||||
:return: HttpResponse --
|
||||
"""
|
||||
time_start = time.time()
|
||||
time_start = time.perf_counter()
|
||||
to_template = {}
|
||||
try:
|
||||
# Этот блок нужен для 302-переадресации, когда разные URL отдают одинаковые страницы.
|
||||
@@ -539,7 +539,7 @@ def compare_offers(request: HttpRequest, to_compare: str = "1,2") -> HttpRespons
|
||||
# получаем последние визиты всех посетителей из базы
|
||||
# id2log, log_visit = get_last_all_user_visit_list()
|
||||
'LOG_VISIT': get_last_all_user_visit_list(),
|
||||
'ticks': float(time.time() - time_start)
|
||||
'ticks': float(time.perf_counter() - time_start)
|
||||
})
|
||||
return render(request, "report/report_compare_set.html", to_template)
|
||||
|
||||
@@ -551,7 +551,7 @@ def show_rating_components(request: HttpRequest, win_set: str = "1") -> HttpResp
|
||||
:param win_set: str -- id оконного набора, для которого показать состав рейтинга
|
||||
:return: HttpResponse --
|
||||
"""
|
||||
time_start = time.time()
|
||||
time_start = time.perf_counter()
|
||||
to_template = {}
|
||||
try:
|
||||
win_set = int(win_set)
|
||||
@@ -596,5 +596,5 @@ def show_rating_components(request: HttpRequest, win_set: str = "1") -> HttpResp
|
||||
"коммерческое предложение, коммерческих предложения,"
|
||||
" коммерческих предложений"),
|
||||
'TEST': win_set,
|
||||
'ticks': float(time.time() - time_start)})
|
||||
'ticks': float(time.perf_counter() - time_start)})
|
||||
return render(request, "report/show_rating_components.html", to_template)
|
||||
|
||||
+325
-181
@@ -7,8 +7,6 @@ import django.utils.dateformat
|
||||
import django.utils.timezone
|
||||
from oknardia.settings import *
|
||||
import time
|
||||
import random
|
||||
import pytils
|
||||
|
||||
|
||||
# Главная страница для вызова служебных процедур.
|
||||
@@ -18,18 +16,18 @@ def service(request: HttpRequest) -> HttpResponse:
|
||||
:param request: HttpRequest
|
||||
:return: HttpResponse
|
||||
"""
|
||||
time_start = time.time()
|
||||
time_start = time.perf_counter()
|
||||
# проверка на аутентификацию
|
||||
print(request.user.is_authenticated)
|
||||
# print(request.user.is_authenticated)
|
||||
if not request.user.is_authenticated:
|
||||
return redirect("/service/not-denice")
|
||||
return render(request, "service/index.html", {'ticks': float(time.time()-time_start)})
|
||||
return render(request, "service/index.html", {'ticks': float(time.perf_counter()-time_start)})
|
||||
|
||||
|
||||
# страничка, на которую переадресует служебный интерфейс, если нет аутентификации.
|
||||
def not_denice(request):
|
||||
time_start = time.time()
|
||||
return render(request, "service/not_denice.html", {'ticks': float(time.time()-time_start)})
|
||||
time_start = time.perf_counter()
|
||||
return render(request, "service/not_denice.html", {'ticks': float(time.perf_counter()-time_start)})
|
||||
|
||||
|
||||
def tmp(request: HttpRequest) -> HttpResponse:
|
||||
@@ -38,187 +36,333 @@ def tmp(request: HttpRequest) -> HttpResponse:
|
||||
:param request:
|
||||
:return:
|
||||
"""
|
||||
t_start = time.time()
|
||||
return render(request, "service/tmp.html", {'TAU': float(time.time()-t_start)})
|
||||
t_start = time.perf_counter()
|
||||
return render(request, "service/tmp.html", {'TAU': float(time.perf_counter()-t_start)})
|
||||
|
||||
|
||||
SITEMAP_MAX_ITEM = 40000 # максимальное число URL-ов в sitemap.xml -- 50000
|
||||
SITEMAP_MAX_FILE_SIZE = 5242880 # максимальный размер файла sitemap.xml -- 10Mb (10485760 байт)
|
||||
SITEMAP_MAX_FILES_QTY = 998 # максимальный число вложенных sitemap.xml -- 1000
|
||||
|
||||
|
||||
def str_time() -> str:
|
||||
""" Возвращает текущее время в ISO 8601 со смещением от текущего часового пояса
|
||||
def make_rating(request: HttpRequest) -> HttpResponse:
|
||||
"""
|
||||
return django.utils.dateformat.format(django.utils.timezone.now(), 'c')
|
||||
Вычисляем (каждый раз заново) рейтинги оконных профилей, стеклопакетов и оконных наборов.
|
||||
Вычисление базируется на ренкинге. В базовом ренкинге участвуют только стеклопакеты и профиля
|
||||
присутствующие в коммерческих предложениях размещенных в ОКНАРДИИ.
|
||||
|
||||
Ренкинг профилей: Для получения ранка вся совокупность профилей из коммерческих предложений сортируется
|
||||
по тому или иному признаку (характеристике). Каждому профилю присваивается ранк, который вычисляется как
|
||||
весу той или иной характеристики и порядковому номеру профиля в сортированному по этому признаку
|
||||
(характеристике) в списке.
|
||||
|
||||
def make_site_maps (request: HttpRequest) -> HttpResponse:
|
||||
"""Функция создания sitemap.xml ... периодически надо вызывать через crone
|
||||
ВНИМАНИЕ ТЕХНИЧЕСКИЙ ДОЛГ:
|
||||
Система ренкинга разрабатывалась когда в базе было уже достаточно предложений. Возможно, если
|
||||
объектов ренкинга будет мало что-то не сработает. И выдаст ошибку.
|
||||
|
||||
:param request: request
|
||||
:return: HttpResponse ( msg )
|
||||
:param request: HttpRequest -- запрос
|
||||
:return: HttpResponse -- ответ
|
||||
"""
|
||||
time_start = time.perf_counter()
|
||||
msg = ""
|
||||
time_start = time.time()
|
||||
count_total_item = 0
|
||||
count_item_per_file = 0
|
||||
count_file = 0
|
||||
# форматирование даты-времени в ISO 8601 со смещением от текущего часового пояса
|
||||
# str_time = django.utils.dateformat.format(django.utils.timezone.now(), 'c') # форматирование даты в ISO 8601
|
||||
# ПОЛУЧАЕМ ВСЕ СТРАНИЧКИ С ЦЕНАМИ ДЛЯ ОДИНОЧНОГО ПРОЕМА
|
||||
q1 = Win_MountDim.objects.raw("SELECT"
|
||||
" oknardia_win_mountdim.iWinWidth,"
|
||||
" oknardia_win_mountdim.iWinHight,"
|
||||
" oknardia_win_mountdim.id,"
|
||||
" COUNT(oknardia_priceoffer.kOffer2MountDim_id) AS NumOffer,"
|
||||
" oknardia_win_mountdim.sFlapConfig "
|
||||
"FROM oknardia_priceoffer"
|
||||
" INNER JOIN oknardia_win_mountdim"
|
||||
" ON oknardia_priceoffer.kOffer2MountDim_id = oknardia_win_mountdim.id "
|
||||
"GROUP BY oknardia_win_mountdim.id,"
|
||||
" oknardia_win_mountdim.iWinWidth,"
|
||||
" oknardia_win_mountdim.iWinHight,"
|
||||
" oknardia_win_mountdim.sFlapConfig "
|
||||
"ORDER BY COUNT(oknardia_priceoffer.kOffer2MountDim_id);")
|
||||
for i in q1:
|
||||
msg += f" <url>\n" \
|
||||
f" <loc>https://oknardia.ru/tsena-odnogo-okna/{int(i.iWinWidth*10)}x{int(i.iWinHight*10)}mm/tip{i.id}</loc>\n"\
|
||||
f" <lastmod>{str_time()}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.5</priority>\n" \
|
||||
f" </url>\n"
|
||||
count_total_item += 1
|
||||
# print "~~~> ", countTotalItem, " ::: /compare_offers/", Count
|
||||
count_item_per_file += 1
|
||||
if (count_item_per_file > SITEMAP_MAX_ITEM) or (len(msg) > SITEMAP_MAX_FILE_SIZE):
|
||||
# Файл sitemap.xml заполнен... нужно записать и продолжить записывать в следующем
|
||||
msg = f"<?xml version='1.0' encoding='UTF-8'?>" \
|
||||
f"<urlset xmlns='http://www.sitemaps.org/schemas/sitemap/0.9'>\n{msg}</urlset>"
|
||||
with open(f"{SITEMAP_ROOT}sitemap{count_file:04d}.xml", "w", encoding="utf-8") as f:
|
||||
f.write(msg)
|
||||
count_item_per_file = 0
|
||||
count_file += 1 # счетчик файлов
|
||||
if count_file > SITEMAP_MAX_FILES_QTY: # максимально число файлов SITEMAP_MAX_FILES_QTY
|
||||
break
|
||||
msg = "" # обнулить буфер для записи файла
|
||||
# ВСЕ СТРАНИЧКИ С ЦЕНОВЫМИ ПРЕДЛОЖЕНИЯМИ ПО АДРЕСАМ
|
||||
q1 = Building_Info.objects.raw(
|
||||
"SELECT DISTINCT oknardia_building_info.sAddress, oknardia_building_info.id as id,"
|
||||
" oknardia_apartment_type.id AS ap_id "
|
||||
"FROM oknardia_building_info"
|
||||
" INNER JOIN oknardia_seria_info"
|
||||
" ON oknardia_building_info.kSeria_Link_id = oknardia_seria_info.id"
|
||||
" INNER JOIN oknardia_apartment_type"
|
||||
" ON oknardia_apartment_type.kSeria_id = oknardia_seria_info.kRoot_id "
|
||||
"ORDER BY oknardia_building_info.id;")
|
||||
list_build = list(q1)
|
||||
random.shuffle(list_build) # перемешиваем случайным образом, чтобы поисковики видели изменения sitemap
|
||||
for i in list_build:
|
||||
msg += f" <url>\n <loc>https://oknardia.ru/{i.id}/{i.ap_id}/{pytils.translit.slugify(i.sAddress)}</loc>\n" \
|
||||
f" <lastmod>{str_time()}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.5</priority>\n" \
|
||||
f" </url>\n"
|
||||
count_total_item += 1
|
||||
# print("===> ", count_total_item, " ::: ", i.id, '/', i.ap_id, '/', pytils.translit.slugify(i.sAddress), sep="")
|
||||
count_item_per_file += 1
|
||||
if (count_item_per_file > SITEMAP_MAX_ITEM) or (len(msg) > SITEMAP_MAX_FILE_SIZE):
|
||||
# Файл sitemap.xml заполнен... нужно записать и продолжить записывать в следующем
|
||||
msg = f"<?xml version='1.0' encoding='UTF-8'?>\n" \
|
||||
f"<urlset xmlns='http://www.sitemaps.org/schemas/sitemap/0.9'>\n{msg}</urlset>"
|
||||
with open(f"{SITEMAP_ROOT}sitemap{count_file:04d}.xml", "w", encoding="utf-8") as f:
|
||||
f.write(msg)
|
||||
count_item_per_file = 0
|
||||
count_file += 1 # счетчик файлов
|
||||
if count_file > SITEMAP_MAX_FILES_QTY: # максимально число файлов SITEMAP_MAX_FILES_QTY
|
||||
break
|
||||
msg = "" # обнулить буфер для записи файла
|
||||
|
||||
# ДОБАВЛЯЕМ В SITEMAP ВСЕ СТРАНИЧКИ СО СРВНЕНИЕМ НАБОРОВ
|
||||
dim_comp = compare()
|
||||
random.shuffle(dim_comp)
|
||||
for i in dim_comp:
|
||||
msg += f" <url>\n <loc>https://oknardia.ru/compare_offers/{i}</loc>\n <lastmod>{str_time()}</lastmod>\n" \
|
||||
f" <changefreq>weekly</changefreq>\n <priority>0.45</priority>\n </url>\n"
|
||||
count_total_item += 1
|
||||
count_item_per_file += 1
|
||||
if (count_item_per_file > SITEMAP_MAX_ITEM) or (len(msg) > SITEMAP_MAX_FILE_SIZE):
|
||||
# Файл sitemap.xml заполнен... нужно записать и продолжить записывать в следующем
|
||||
msg = f"<?xml version='1.0' encoding='UTF-8'?>\n" \
|
||||
f"<urlset xmlns='http://www.sitemaps.org/schemas/sitemap/0.9'>\n{msg}</urlset>"
|
||||
with open(f"{SITEMAP_ROOT}sitemap{count_file:04d}.xml", "w", encoding="utf-8") as f:
|
||||
f.write(msg)
|
||||
count_item_per_file = 0
|
||||
count_file += 1 # счетчик файлов
|
||||
msg = "" # обнулить буфер для записи файла
|
||||
if count_file > SITEMAP_MAX_FILES_QTY: # максимально число файлов SITEMAP_MAX_FILES_QTY
|
||||
break
|
||||
|
||||
# ЗАВЕРШАЕМ
|
||||
if count_file == 0:
|
||||
# Все ссылки уместились в один sitemap.xml... просто его записать
|
||||
with open(f"{SITEMAP_ROOT}sitemap.xml", "w", encoding="utf-8") as f:
|
||||
f.write(f"<?xml version='1.0' encoding='UTF-8'?>\n"
|
||||
f"<urlset xmlns='http://www.sitemaps.org/schemas/sitemap/0.9'>\n{msg}</urlset>")
|
||||
print(SITEMAP_ROOT)
|
||||
msg = f"Создан единственный sitemap.xml\nВсего ссылок: {count_total_item:06d}"
|
||||
else:
|
||||
# Файлов sitemap.xml много.
|
||||
# Создаем завершающий файл sitemap
|
||||
with open(f"{SITEMAP_ROOT}sitemap{count_file:04d}.xml", "w", encoding="utf-8") as f:
|
||||
f.write(f"<?xml version='1.0' encoding='UTF-8'?>\n<urlset "
|
||||
f"xmlns='http://www.sitemaps.org/schemas/sitemap/0.9'>\n{msg}</urlset>")
|
||||
# Создаём объединяющий sitemap.xml с перечислением всего множества sitemap-файлов...
|
||||
msg = "<?xml version='1.0' encoding='UTF-8'?>\n" \
|
||||
"<sitemapindex xmlns='http://www.sitemaps.org/schemas/sitemap/0.9'>\n"
|
||||
for i in range(0, count_file+1):
|
||||
msg += f" <sitemap>\n <loc>https://oknardia.ru/sitemap{i:04d}.xml</loc>\n" \
|
||||
f" <lastmod>{str_time()}</lastmod>\n </sitemap>\n"
|
||||
msg += u"</sitemapindex>"
|
||||
with open(f"{SITEMAP_ROOT}sitemap.xml", "w", encoding="utf-8") as f:
|
||||
f.write(msg)
|
||||
msg = f"Создан каскадный sitemap.xml\nВсего вложенных файлов: {count_file+1:04d}\n" \
|
||||
f"Всего ссылок: {count_total_item:08d}"
|
||||
print(msg)
|
||||
return HttpResponse(f"<pre>{msg}\n\nвремя выполнения: {float(time.time()-time_start)} сек.</pre>")
|
||||
|
||||
|
||||
def compare() -> list:
|
||||
""" Возвращает список сравнения из всех возможных вариантов сравнения оконных наборов (из доступных в базе)
|
||||
|
||||
:return: список сравнения
|
||||
"""
|
||||
q_set_kit = SetKit.objects.raw('SELECT oknardia_setkit.id, oknardia_setkit.sSetActive '
|
||||
'FROM oknardia_setkit '
|
||||
'WHERE oknardia_setkit.sSetActive = TRUE')
|
||||
count = 0
|
||||
dim_comp = []
|
||||
l_set_kit = list(q_set_kit)
|
||||
for i1 in l_set_kit:
|
||||
for i2 in l_set_kit:
|
||||
if i1.id >= i2.id:
|
||||
continue
|
||||
dim_comp.append(f"{i1.id},{i2.id}")
|
||||
count += 1
|
||||
for i3 in l_set_kit:
|
||||
if i2.id >= i3.id:
|
||||
# ВЫЧИСЛЯЕМ РЕЙТИНГ ПРОФИЛЕЙ
|
||||
# устанавливаем рейтинг всех профилей в базе в ноль
|
||||
profile_all_num = PVCprofiles.objects.all().update(fProfileRating=0.0)
|
||||
to_template = {'NUM_PROFILE_TOTAL': profile_all_num} # засовываем данные в шаблон
|
||||
q = PVCprofiles.objects.raw("SELECT"
|
||||
" oknardia_pvcprofiles.*,"
|
||||
" COUNT(oknardia_priceoffer.id) AS NumOffer "
|
||||
"FROM oknardia_setkit"
|
||||
" INNER JOIN oknardia_priceoffer"
|
||||
" ON oknardia_setkit.id = oknardia_priceoffer.kOffer2SetKit_id"
|
||||
" RIGHT OUTER JOIN oknardia_pvcprofiles"
|
||||
" ON oknardia_setkit.kSet2PVCprofiles_id = oknardia_pvcprofiles.id "
|
||||
"GROUP BY oknardia_pvcprofiles.id;")
|
||||
profile_use_list = list(q)
|
||||
# получаем словарь из RawQuerySet
|
||||
PVC_Dictionary = Prepare_PVC_Dictionary(profile_use_list)
|
||||
# получаем рейтинги
|
||||
dim, PVC_Dictionary = RankingPVC(PVC_Dictionary)
|
||||
to_template.update(dim) # засовываем данные в шаблон
|
||||
# сортируем по полученному рейтингу
|
||||
PVC_Dictionary = sorted(PVC_Dictionary, key=lambda item: item["TmpRating"])
|
||||
# print u"РЕЙТИНГИ ПРОФИЛЕЙ IN USE"
|
||||
# найдем минимальный и максимальный ранкинг для последующей нормализации
|
||||
NumMaxRank = 0
|
||||
NumMinRank = -1
|
||||
j = 0
|
||||
for i in PVC_Dictionary:
|
||||
if i["NumOffer"] != 0:
|
||||
NumMaxRank = j
|
||||
if NumMinRank == -1:
|
||||
NumMinRank = j
|
||||
j += 1
|
||||
j = 0
|
||||
for i in PVC_Dictionary:
|
||||
obj = PVCprofiles.objects.get(id=i["id"])
|
||||
try:
|
||||
GettedJSON = json.loads(obj.sProfileDescription)
|
||||
except:
|
||||
GettedJSON = {}
|
||||
if i["NumOffer"] != 0:
|
||||
try: del GettedJSON[KEY_RATING_VIRTUAL]
|
||||
except: pass
|
||||
GettedJSON[KEY_RATING] = i["RatingConsist"]
|
||||
# GettedJSON.update({KEY_RATING:i["RatingConsist"]})
|
||||
else:
|
||||
try: del GettedJSON[KEY_RATING]
|
||||
except: pass
|
||||
GettedJSON[KEY_RATING_VIRTUAL] = i["RatingConsist"]
|
||||
# GettedJSON.update({KEY_RATING_VIRTUAL:i["RatingConsist"]})
|
||||
obj.sProfileDescription = json.dumps(GettedJSON,
|
||||
separators=(",",":"),
|
||||
sort_keys=True,
|
||||
encoding="utf-8",
|
||||
ensure_ascii=False)
|
||||
if j <= NumMaxRank:
|
||||
obj.fProfileRating = Normalize(i["TmpRating"],PVC_Dictionary[NumMaxRank]["TmpRating"]) * (RARING_PVC_PROFILE_MAX-RARING_PVC_PROFILE_MIN) + RARING_PVC_PROFILE_MIN
|
||||
else:
|
||||
obj.fProfileRating = 5.0
|
||||
# print "id_PVC:", i["id"], u"\tΣ:", obj.fProfileRating, u"\tСостав:",
|
||||
# print json.dumps(i["RatingConsist"], separators=(",",":"), encoding="utf-8", ensure_ascii=False)
|
||||
obj.save()
|
||||
j += 1
|
||||
# вычисляем рейтинги стеклопакетоа
|
||||
# ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░
|
||||
# устанавливаем рейтинг всех стеклопакетоа в базе в ноль
|
||||
GlazingAllNum = Glazing.objects.all().update(fGlazingRating=0.0)
|
||||
to_template.update({'NUM_GLAZING_TOTAL':GlazingAllNum}) # засовываем данные в шаблон
|
||||
q = Glazing.objects.raw("SELECT"
|
||||
" oknardia_glazing.*,"
|
||||
" COUNT(oknardia_priceoffer.id) AS NumOffer "
|
||||
"FROM oknardia_setkit"
|
||||
" INNER JOIN oknardia_priceoffer"
|
||||
" ON oknardia_priceoffer.kOffer2SetKit_id = oknardia_setkit.id"
|
||||
" INNER JOIN oknardia_glazing"
|
||||
" ON oknardia_setkit.kSet2Glazing_id = oknardia_glazing.id "
|
||||
"GROUP BY oknardia_glazing.id;")
|
||||
GlazingUseList = list(q)
|
||||
# получаем словарь из RawQuerySet
|
||||
GLAZ_Dictionary = Prepare_GLAZ_Dictionary(GlazingUseList)
|
||||
# получаем рейтинги
|
||||
dim, GLAZ_Dictionary = RankingGlazing(GLAZ_Dictionary)
|
||||
to_template.update(dim) # засовываем данные в шаблон
|
||||
# сортируем по полученному рейтингу
|
||||
GLAZ_Dictionary = sorted(GLAZ_Dictionary, key=lambda item: item["TmpRating"])
|
||||
# print u"РЕЙТИНГИ СТЕКЛОПАКЕТОВ IN USE"
|
||||
for i in GLAZ_Dictionary:
|
||||
obj = Glazing.objects.get(id=i["id"])
|
||||
obj.fGlazingRating = Normalize(i["TmpRating"], ValMax=GLAZ_Dictionary[-1]["TmpRating"]) * (RARING_GLAZING_MAX-RARING_GLAZING_MIN) + RARING_GLAZING_MIN
|
||||
try:
|
||||
GettedJSON = json.loads(obj.sGlazingDescription)
|
||||
except:
|
||||
GettedJSON = {}
|
||||
try: del GettedJSON[KEY_RATING_VIRTUAL]
|
||||
except: pass
|
||||
GettedJSON.update({KEY_RATING:i["RatingConsist"]})
|
||||
obj.sGlazingDescription = json.dumps(GettedJSON,
|
||||
separators=(",",":"),
|
||||
sort_keys=True,
|
||||
encoding="utf-8",
|
||||
ensure_ascii=False)
|
||||
# print u"id:",i["id"], u"\tRank:", i["TmpRating"], u"\rate:", obj.fGlazingRating, u"\tGLAZ:", i["sGlazingMark"]
|
||||
obj.save()
|
||||
# получаем все стеклопакеты, чтобы забацать рейтинг и для тех, которые есть в каталоге но нет в КП
|
||||
q = Glazing.objects.raw("SELECT oknardia_glazing.* "
|
||||
"FROM oknardia_glazing;")
|
||||
GlazingAllList = list(q)
|
||||
# получаем словарь из RawQuerySet
|
||||
GLAZ_Dictionary = Prepare_GLAZ_Dictionary(GlazingAllList)
|
||||
# получаем рейтинги
|
||||
dim, GLAZ_Dictionary = RankingGlazing(GLAZ_Dictionary)
|
||||
GLAZ_Dictionary = sorted(GLAZ_Dictionary, key=lambda item: item["TmpRating"])
|
||||
if GlazingAllNum > len(GlazingUseList):
|
||||
CutStartIndex = -1
|
||||
CutStartRatingValue = 0.
|
||||
CutEndIndex = -1
|
||||
CutEndRatingValue = 0.
|
||||
for i in range(0, GlazingAllNum):
|
||||
# print i, GLAZ_Dictionary[i]["id"], u"\trank --> ", GLAZ_Dictionary[i]["TmpRating"], "\t(",
|
||||
# print GLAZ_Dictionary[i]["fGlazingRating"], ")\tFormulaGLAZING:", GLAZ_Dictionary[i]["sGlazingMark"]
|
||||
if GLAZ_Dictionary[i]["fGlazingRating"] != 0.:
|
||||
# нашли конец следующего отрезка, нужно отрезок переопределить
|
||||
CutStartRatingValue = CutEndRatingValue
|
||||
CutStartIndex = CutEndIndex
|
||||
CutEndRatingValue = GLAZ_Dictionary[i]["fGlazingRating"]
|
||||
CutEndIndex = i
|
||||
if CutEndIndex == 0:
|
||||
continue
|
||||
dim_comp.append(f"{i1.id},{i2.id},{i3.id}")
|
||||
count += 1
|
||||
for i4 in l_set_kit:
|
||||
if i3.id >= i4.id:
|
||||
continue
|
||||
dim_comp.append(f"{i1.id},{i2.id},{i3.id},{i4.id}")
|
||||
count += 1
|
||||
for i5 in l_set_kit:
|
||||
if i4.id >= i5.id:
|
||||
continue
|
||||
dim_comp.append(f"{i1.id},{i2.id},{i3.id},{i4.id},{i5.id}")
|
||||
count += 1
|
||||
for i6 in l_set_kit:
|
||||
if i5.id >= i6.id:
|
||||
continue
|
||||
dim_comp.append(f"{i1.id},{i2.id},{i3.id},{i4.id},{i5.id},{i6.id}")
|
||||
count += 1
|
||||
# random.shuffle(dim_comp)
|
||||
# for i1 in dim_comp:
|
||||
# print(i1)
|
||||
# print(f"---------------{count}---------------")
|
||||
return dim_comp
|
||||
else:
|
||||
# надо перебрать все объекты внутри отрезка
|
||||
for j in range(CutStartIndex+1, CutEndIndex):
|
||||
# и пересчитать рейтинги внутри этого, нового отрезка
|
||||
GLAZ_Dictionary[j]["fGlazingRating"] = CutStartRatingValue + (GLAZ_Dictionary[j]["TmpRating"]-GLAZ_Dictionary[CutStartIndex]["TmpRating"])*((CutEndRatingValue-CutStartRatingValue)/(GLAZ_Dictionary[CutEndIndex]["TmpRating"]-GLAZ_Dictionary[CutStartIndex]["TmpRating"]))
|
||||
# print j, GLAZ_Dictionary[j]["id"], u"\trank >>> ", GLAZ_Dictionary[j]["TmpRating"], "\t(",
|
||||
# print GLAZ_Dictionary[j]["fGlazingRating"], ")\tFormulaGLAZING:", GLAZ_Dictionary[j]["sGlazingMark"]
|
||||
# и записать этот рейтинг в базу
|
||||
obj = Glazing.objects.get(id=GLAZ_Dictionary[j]["id"])
|
||||
obj.fGlazingRating = GLAZ_Dictionary[j]["fGlazingRating"]
|
||||
try:
|
||||
GettedJSON = json.loads(obj.sGlazingDescription)
|
||||
except:
|
||||
GettedJSON = {}
|
||||
try: del GettedJSON[KEY_RATING]
|
||||
except: pass
|
||||
GettedJSON.update({KEY_RATING_VIRTUAL:GLAZ_Dictionary[j]["RatingConsist"]})
|
||||
obj.sGlazingDescription = json.dumps(GettedJSON,
|
||||
separators=(",",":"),
|
||||
sort_keys=True,
|
||||
encoding="utf-8",
|
||||
ensure_ascii=False)
|
||||
obj.save()
|
||||
for j in range(CutEndIndex+1, GlazingAllNum):
|
||||
# пересчитать рейтинги хвоста (для отрезка после последнего отрейтингованного)
|
||||
# внимание это код не для работы со словарями. при ревизии переделать GlazingAllList[j].fGlazingRating = CutStartRatingValue + (GlazingAllList[j].TmpRating-GlazingAllList[CutStartIndex].TmpRating)*((CutEndRatingValue-CutStartRatingValue)/(GlazingAllList[CutEndIndex].TmpRating-GlazingAllList[CutStartIndex].TmpRating))
|
||||
GLAZ_Dictionary[j]["fGlazingRating"] = RARING_GLAZING_MAX # т.к. для виртуальный рейтинг иногда снижается, то ставим 5*
|
||||
# и записать этот рейтинг в базу
|
||||
obj = Glazing.objects.get(id=GLAZ_Dictionary[j]["id"])
|
||||
obj.fGlazingRating = GLAZ_Dictionary[j]["fGlazingRating"]
|
||||
try:
|
||||
GettedJSON = json.loads(obj.sGlazingDescription)
|
||||
except:
|
||||
GettedJSON = {}
|
||||
try: del GettedJSON[KEY_RATING]
|
||||
except: pass
|
||||
GettedJSON.update({KEY_RATING_VIRTUAL:GLAZ_Dictionary[j]["RatingConsist"]})
|
||||
obj.sGlazingDescription = json.dumps(GettedJSON,
|
||||
separators=(",",":"),
|
||||
sort_keys=True,
|
||||
encoding="utf-8",
|
||||
ensure_ascii=False)
|
||||
|
||||
obj.save()
|
||||
# вычисляем рейтинги наборов (стеклопакет + профиль + сопутсвующие услуги т.п.
|
||||
# ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░
|
||||
# устанавливаем рейтинг всех наборов в базе в ноль
|
||||
SetAllNum = SetKit.objects.all().update(fSetRating=0.0)
|
||||
to_template.update({'NUM_SET_TOTAL':SetAllNum}) # засовываем данные в шаблон
|
||||
q = SetKit.objects.raw("SELECT"
|
||||
" COUNT(oknardia_priceoffer.id) AS NumOffer,"
|
||||
" MAX(oknardia_priceoffer.dOfferModify) AS dModify,"
|
||||
" oknardia_pvcprofiles.fProfileRating,"
|
||||
" oknardia_glazing.fGlazingRating,"
|
||||
" oknardia_setkit.*,"
|
||||
" oknardia_merchantoffice.sOfficeDiscountMetaFormula "
|
||||
"FROM oknardia_setkit"
|
||||
" INNER JOIN oknardia_priceoffer"
|
||||
" ON oknardia_priceoffer.kOffer2SetKit_id = oknardia_setkit.id"
|
||||
" INNER JOIN oknardia_glazing"
|
||||
" ON oknardia_setkit.kSet2Glazing_id = oknardia_glazing.id"
|
||||
" INNER JOIN oknardia_pvcprofiles"
|
||||
" ON oknardia_pvcprofiles.id = oknardia_setkit.kSet2PVCprofiles_id "
|
||||
" INNER JOIN oknardia_ouruser"
|
||||
" ON oknardia_setkit.kSet2User_id = oknardia_ouruser.id"
|
||||
" INNER JOIN oknardia_merchantoffice"
|
||||
" ON oknardia_ouruser.kMerchantOffice_id = oknardia_merchantoffice.id "
|
||||
"WHERE oknardia_setkit.sSetActive = TRUE "
|
||||
"GROUP BY oknardia_pvcprofiles.fProfileRating,"
|
||||
" oknardia_glazing.fGlazingRating,"
|
||||
" oknardia_merchantoffice.sOfficeDiscountMetaFormula,"
|
||||
" oknardia_setkit.sSetActive, oknardia_setkit.id "
|
||||
"ORDER BY MAX(oknardia_priceoffer.dOfferModify);")
|
||||
# q = SetKit.objects.order_by("dModify")
|
||||
SetUseList = list(q)
|
||||
to_template.update({'NUM_SET': len(SetUseList) })
|
||||
SetDictionary = []
|
||||
# Превратим RawQuerySet в массив словарей (почти JSON). Так получится избежать "макаронного кода".
|
||||
# Заодно переопределяем для правильного ранжирования некоторые параметры из строк в цифры.
|
||||
for i in range(0,len(SetUseList)):
|
||||
SetDictionary.append(q[i].__dict__)
|
||||
if SetDictionary[i]["sSetSill"].lower() in [u"нет",u"-",u"—",""," "]:
|
||||
SetDictionary[i]["sSetSill"] = 0 # Подоконника нет
|
||||
else: SetDictionary[i]["sSetSill"] = 1 # Подоконник есть
|
||||
if SetDictionary[i]["sSetPanes"].lower() in [u"нет",u"-",u"—",""," "]:
|
||||
SetDictionary[i]["sSetPanes"] = 0 # Водоотлив нет
|
||||
else: SetDictionary[i]["sSetPanes"] = 1 # Водоотлив есть
|
||||
if SetDictionary[i]["sSetSlope"].lower() in [u"нет",u"-",u"—",""," "]:
|
||||
SetDictionary[i]["sSetSlope"] = 0 # Откос нет
|
||||
else: SetDictionary[i]["sSetSlope"] = 1 # Откос есть
|
||||
if SetDictionary[i]["sSetClimateControl"].lower() in [u"нет",u"-",u"—",""," "]:
|
||||
SetDictionary[i]["sSetClimateControl"] = 0 # Климат-контроль нет
|
||||
else: SetDictionary[i]["sSetClimateControl"] = 1 # Климат-контроль есть
|
||||
try:
|
||||
# print eval(SetDictionary[i]["sOfficeDiscountMetaFormula"])[KEY_DICSOUNT].keys()
|
||||
# print max(eval(SetDictionary[i]["sOfficeDiscountMetaFormula"])[KEY_DICSOUNT].values())
|
||||
SetDictionary[i].update({"DiscountMax": max(eval(SetDictionary[i]["sOfficeDiscountMetaFormula"])[KEY_DICSOUNT].values())})
|
||||
SetDictionary[i]["sOfficeDiscountMetaFormula"] = len(eval(SetDictionary[i]["sOfficeDiscountMetaFormula"])[KEY_DICSOUNT].keys())
|
||||
except:
|
||||
SetDictionary[i].update({"DiscountMax": 0})
|
||||
SetDictionary[i]["sOfficeDiscountMetaFormula"] = 0
|
||||
# Отранжируем наборы по параметру "дата последнего обновления цены" -- ПО ВОЗРАСТАНИЮ
|
||||
SetDictionary, MaxRank = GetRank(SetDictionary, "dModify", key_weight=RANK_STEP_SET_MODIFY,
|
||||
rank_name=u"Актуальность", revers=False)
|
||||
to_template.update({'S_Modify_Step': RANK_STEP_SET_MODIFY })
|
||||
to_template.update({'S_Modify_MaxRank': MaxRank })
|
||||
# Отранжируем наборы по параметру "доставка включена в стоимость" -- ПО ВОЗРАСТАНИЮ
|
||||
SetDictionary, MaxRank = GetRank(SetDictionary, "bSetDelivery", key_weight=RANK_STEP_SET_DELIVERY,
|
||||
rank_name=u"Доставка", revers=False)
|
||||
to_template.update({'S_Delivery_Step': RANK_STEP_SET_DELIVERY })
|
||||
to_template.update({'S_Delivery_MaxRank': MaxRank })
|
||||
# Отранжируем наборы по параметру Демонтаж/Монтаж" -- ПО ВОЗРАСТАНИЮ
|
||||
SetDictionary, MaxRank = GetRank(SetDictionary, "bSetUninstallInstall", key_weight=RANK_STEP_SET_UNINSTALL_INSTALL,
|
||||
rank_name=u"Монтаж")
|
||||
to_template.update({'S_UninstallInstall_Step': RANK_STEP_SET_UNINSTALL_INSTALL })
|
||||
to_template.update({'S_UninstallInstall_MaxRank': MaxRank })
|
||||
# Отранжируем наборы по параметру Подоконник" -- ПО ВОЗРАСТАНИЮ
|
||||
SetDictionary, MaxRank = GetRank(SetDictionary, "sSetSill", key_weight=RANK_STEP_SET_SILL,
|
||||
rank_name=u"Подоконник")
|
||||
to_template.update({'S_Sill_Step': RANK_STEP_SET_SILL })
|
||||
to_template.update({'S_Sill_MaxRank': MaxRank })
|
||||
# Отранжируем наборы по параметру Водоотлив" -- ПО ВОЗРАСТАНИЮ
|
||||
SetDictionary, MaxRank = GetRank(SetDictionary, "sSetPanes", key_weight=RANK_STEP_SET_PANES,
|
||||
rank_name=u"Водоотлив")
|
||||
to_template.update({'S_Panes_Step': RANK_STEP_SET_PANES })
|
||||
to_template.update({'S_Panes_MaxRank': MaxRank })
|
||||
# Отранжируем наборы по параметру Откос" -- ПО ВОЗРАСТАНИЮ
|
||||
SetDictionary, MaxRank = GetRank(SetDictionary, "sSetSlope", key_weight=RANK_STEP_SET_SLOPE,
|
||||
rank_name=u"Откос")
|
||||
to_template.update({'S_Slope_Step': RANK_STEP_SET_SLOPE })
|
||||
to_template.update({'S_Slope_MaxRank': MaxRank })
|
||||
# Отранжируем наборы по параметру Климат-контроль" -- ПО ВОЗРАСТАНИЮ
|
||||
SetDictionary, MaxRank = GetRank(SetDictionary, "sSetClimateControl", key_weight=RANK_STEP_SET_CLIMATE_CONTROL,
|
||||
rank_name=u"Климат-контроль")
|
||||
to_template.update({'S_ClimateControl_Step': RANK_STEP_SET_CLIMATE_CONTROL })
|
||||
to_template.update({'S_ClimateControl_MaxRank': MaxRank })
|
||||
# Отранжируем наборы по параметру Число предложений -- ПО ВОЗРАСТАНИЮ
|
||||
SetDictionary, MaxRank = GetRank(SetDictionary, "NumOffer", key_weight=RANK_STEP_SET_NUM_OFFER,
|
||||
rank_name=u"Число предложений")
|
||||
to_template.update({'S_NumOffer_Step': RANK_STEP_SET_NUM_OFFER })
|
||||
to_template.update({'S_NumOffer_MaxRank': MaxRank })
|
||||
# Отранжируем наборы по параметру Гибкие скидки -- ПО ВОЗРАСТАНИЮ
|
||||
SetDictionary, MaxRank = GetRank(SetDictionary, "sOfficeDiscountMetaFormula", key_weight=RANK_STEP_DISCOUNT_FLEX,
|
||||
rank_name=u"Гибкость скидок")
|
||||
to_template.update({'S_DiscountFlex_Step': RANK_STEP_DISCOUNT_FLEX })
|
||||
to_template.update({'S_DiscountFlex_MaxRank': MaxRank })
|
||||
# Отранжируем наборы по параметру Гибкие скидки -- ПО ВОЗРАСТАНИЮ
|
||||
SetDictionary, MaxRank = GetRank(SetDictionary, "DiscountMax", key_weight=RANK_STEP_DISCOUNT_MAX,
|
||||
rank_name=u"Размеры скидок")
|
||||
to_template.update({'S_DiscountMax_Step': RANK_STEP_DISCOUNT_MAX })
|
||||
to_template.update({'S_DiscountMax_MaxRank': MaxRank })
|
||||
# расчитываем обзий рейтинг наборов и записываем в базу
|
||||
SetDictionary = sorted(SetDictionary, key=lambda item: item["TmpRating"])
|
||||
# print u"РЕЙТИНГИ НАБОРОВ"
|
||||
for i in SetDictionary:
|
||||
obj = SetKit.objects.get(id=i["id"])
|
||||
try:
|
||||
GettedJSON = json.loads(obj.sSetDescription)
|
||||
except:
|
||||
GettedJSON = {}
|
||||
# нормализованный рейтинг сета
|
||||
# print GettedJSON
|
||||
k1 = Normalize(i["TmpRating"], SetDictionary[-1]["TmpRating"] )*(RARING_SET_MAX-RARING_WEIGHT_PVC_PROFILE_IN_SET-RARING_WEIGHT_GLAZING_IN_SET-RARING_SET_MIN)
|
||||
k2 = Normalize(i["fGlazingRating"], RARING_GLAZING_MAX) * RARING_WEIGHT_GLAZING_IN_SET
|
||||
k3 = Normalize(i["fProfileRating"], RARING_PVC_PROFILE_MAX) * RARING_WEIGHT_PVC_PROFILE_IN_SET
|
||||
# print "id:", i["id"], u"\tk1:", k1, u"\tk2", k2, u"\tk3", k3, u"\tΣ:", k1+k2+k3
|
||||
obj.fSetRating = k1+k2+k3
|
||||
# print str(i["RatingConsist"])
|
||||
try: del GettedJSON[KEY_RATING_VIRTUAL]
|
||||
except: pass
|
||||
GettedJSON.update({KEY_RATING:i["RatingConsist"]})
|
||||
obj.sSetDescription = json.dumps(GettedJSON, separators=(",",":"), encoding="utf-8", ensure_ascii=False)
|
||||
# print obj.sSetDescription
|
||||
obj.save()
|
||||
# print u"id:",i["id"], u"\tRank:", i["TmpRating"], u"\tRate:", obj.fSetRating, u"\tSet:", i["sSetName"], i["fProfileRating"], i["fGlazingRating"]
|
||||
to_template.update({'msg': msg})
|
||||
to_template.update({'ticks': float(time.perf_counter()-time_start)})
|
||||
return render(request, "service/make_rating.html", to_template)
|
||||
+292
-2
@@ -1,3 +1,293 @@
|
||||
from django.test import TestCase
|
||||
from datetime import timedelta
|
||||
from decimal import Decimal
|
||||
import json
|
||||
from unittest.mock import patch
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.db import connection
|
||||
from django.http import HttpResponse
|
||||
from django.test import RequestFactory, TestCase
|
||||
from django.utils import timezone
|
||||
|
||||
from oknardia.settings import CATALOG_RECORD_FOR_PROFILE_MODEL
|
||||
from web.catalog import catalog_profile_model
|
||||
from oknardia.models import (
|
||||
BlogPosts,
|
||||
Catalog2Profile,
|
||||
Glazing,
|
||||
MerchantBrand,
|
||||
MerchantOffice,
|
||||
OurUser,
|
||||
PVCprofiles,
|
||||
PriceOffer,
|
||||
SetKit,
|
||||
)
|
||||
|
||||
|
||||
class CatalogProfileViewTests(TestCase):
|
||||
"""Регрессионные тесты для вьюхи каталога профилей."""
|
||||
|
||||
def setUp(self) -> None:
|
||||
# Базовый пользователь нужен, потому что профиль ссылается на OurUser.
|
||||
django_user = User.objects.create_user(username="tester", password="secret")
|
||||
self.our_user = OurUser.objects.create(kDjangoUser=django_user)
|
||||
self.factory = RequestFactory()
|
||||
|
||||
def _get_context(self, response):
|
||||
"""Достаёт итоговый контекст из ответа тестового клиента."""
|
||||
context = response.context
|
||||
if isinstance(context, list):
|
||||
return context[-1]
|
||||
return context
|
||||
|
||||
def _create_profile(self, *, name: str, brief: str, manufacturer: str, days_ago: int) -> PVCprofiles:
|
||||
"""Создаёт профиль с нужными полями и фиксирует дату изменения вручную."""
|
||||
profile = PVCprofiles.objects.create(
|
||||
sProfileName=name,
|
||||
sProfileBriefDescription=brief,
|
||||
sProfileManufacturer=manufacturer,
|
||||
kProfile2User=self.our_user,
|
||||
fProfileRating=3.5,
|
||||
)
|
||||
# В модели стоит auto_now=True, поэтому после создания дату правим отдельным update.
|
||||
modified_at = timezone.now() - timedelta(days=days_ago)
|
||||
PVCprofiles.objects.filter(pk=profile.pk).update(dProfileModify=modified_at)
|
||||
profile.refresh_from_db()
|
||||
return profile
|
||||
|
||||
def _create_catalog_profile_model_fixture(self, *, manufacturer: str = "Альфа"):
|
||||
"""Собирает минимальный набор данных для карточки профиля."""
|
||||
profile = PVCprofiles.objects.create(
|
||||
sProfileName="Alpha Basic",
|
||||
sProfileBriefDescription="Альфа База",
|
||||
sProfileManufacturer=manufacturer,
|
||||
kProfile2User=self.our_user,
|
||||
fProfileRating=4.25,
|
||||
sProfileDescription=json.dumps({"html": "<p>Дополнительная информация о профиле.</p>"}),
|
||||
sProfileOther="Контур: 2; Цвет: Белый",
|
||||
)
|
||||
PVCprofiles.objects.filter(pk=profile.pk).update(dProfileModify=timezone.now() - timedelta(days=10))
|
||||
profile.refresh_from_db()
|
||||
|
||||
sibling = PVCprofiles.objects.create(
|
||||
sProfileName="Alpha Plus",
|
||||
sProfileBriefDescription="Альфа Плюс",
|
||||
sProfileManufacturer=manufacturer,
|
||||
kProfile2User=self.our_user,
|
||||
fProfileRating=3.75,
|
||||
)
|
||||
|
||||
brand = MerchantBrand.objects.create(
|
||||
sMerchantName="Окно-Мир",
|
||||
sMerchantMainURL="https://example.com",
|
||||
)
|
||||
office = MerchantOffice.objects.create(
|
||||
sOfficeName="Окно-Мир Москва",
|
||||
kMerchantName=brand,
|
||||
sOfficeEmails="info@example.com",
|
||||
sOfficePhones="+7(495)000-00-00",
|
||||
)
|
||||
self.our_user.kMerchantOffice = office
|
||||
self.our_user.save(update_fields=["kMerchantOffice"])
|
||||
|
||||
glazing = Glazing.objects.create(
|
||||
sGlazingName="Тёплый пакет",
|
||||
sGlazingBriefDescription="Теплый двухкамерный стеклопакет",
|
||||
kGlazing2User=self.our_user,
|
||||
)
|
||||
setkit = SetKit.objects.create(
|
||||
sSetName="Набор-Альфа",
|
||||
kSet2User=self.our_user,
|
||||
kSet2PVCprofiles=profile,
|
||||
kSet2Glazing=glazing,
|
||||
sSetDescription="Комплект для теста",
|
||||
sSetClimateControl="Климат",
|
||||
sSetSill="Подоконник",
|
||||
sSetImplementAll="Фурнитура",
|
||||
sSetImplementHandles="Ручки",
|
||||
sSetImplementHinges="Петли",
|
||||
sSetImplementLatch="Запоры",
|
||||
sSetImplementLimiter="Ограничитель",
|
||||
sSetImplementCatch="Фиксатор",
|
||||
sSetPanes="Водоотлив",
|
||||
sSetSlope="Откос",
|
||||
sSetDelivery="Доставка",
|
||||
bSetDelivery=True,
|
||||
sSetUninstallInstall="Монтаж",
|
||||
bSetUninstallInstall=True,
|
||||
sSetOtherConditions="Прочее",
|
||||
fSetRating=4.1,
|
||||
dSetCommercialUntil=timezone.now(),
|
||||
)
|
||||
# В текущей схеме таблицы поле открывания называется flap_config, а не sFlapConfig.
|
||||
win_flap_column = "flap_" + "config"
|
||||
with connection.cursor() as cursor:
|
||||
cursor.execute(
|
||||
f"INSERT INTO oknardia_win_mountdim "
|
||||
f"(iWinWidth, iWinHight, iWinDepth, {win_flap_column}, sDescripion, bIsDoor, bIsNearDoor, iWinLimit, dMountXYZDataCreate, dMountXYZModify) "
|
||||
f"VALUES (?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)",
|
||||
[Decimal("120.0"), Decimal("140.0"), Decimal("15.0"), "[>][<]", "Окно тестовое", 0, 0, Decimal("5.0")],
|
||||
)
|
||||
win_id = cursor.lastrowid
|
||||
PriceOffer.objects.create(
|
||||
kOffer2MountDim_id=win_id,
|
||||
kOfferFromUser=self.our_user,
|
||||
kOffer2SetKit=setkit,
|
||||
sOfferFlapConfig="[>][<]",
|
||||
fOfferPrice=Decimal("12345.00"),
|
||||
)
|
||||
|
||||
blog = BlogPosts.objects.create(
|
||||
sPostHeader="Описание профиля",
|
||||
kBlogAuthorUser=self.our_user,
|
||||
sPostContent="<p>Основной текст</p><cut><p>Скрыто</p>",
|
||||
sImgForBlogSocial="img/catalog-profile.jpg",
|
||||
bCatalog=True,
|
||||
iCatalogSort=1,
|
||||
dPostDataBegin=timezone.now(),
|
||||
)
|
||||
BlogPosts.objects.filter(pk=blog.pk).update(dPostDataModify=timezone.now() - timedelta(days=1))
|
||||
blog.refresh_from_db()
|
||||
Catalog2Profile.objects.create(
|
||||
kProfile=profile,
|
||||
kBlogCatalog=blog,
|
||||
sCatalogCardType=CATALOG_RECORD_FOR_PROFILE_MODEL,
|
||||
)
|
||||
|
||||
return profile, sibling, brand, blog
|
||||
|
||||
@patch("web.catalog.get_last_all_user_visit_list", return_value=["all-visits"])
|
||||
@patch("web.catalog.get_last_user_visit_list", return_value=["last-visits"])
|
||||
@patch("web.catalog.get_last_user_visit_cookies", return_value=["cookie-1", "cookie-2", "cookie-3"])
|
||||
def test_catalog_profile_handles_empty_catalog(
|
||||
self,
|
||||
mocked_cookies,
|
||||
mocked_last_visits,
|
||||
mocked_all_visits,
|
||||
):
|
||||
"""Пустой каталог не должен падать и должен отдавать ожидаемый контекст."""
|
||||
with self.assertNumQueries(1):
|
||||
response = self.client.get("/catalog/profile/")
|
||||
|
||||
context = self._get_context(response)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(context["CATALOG_PROFILE_NUM"], "0 профилей")
|
||||
self.assertEqual(context["CATALOG_MANUFACT_NUM"], 0)
|
||||
self.assertEqual(context["CATALOG_PROFILE_MAN1_NAME2"], [])
|
||||
self.assertEqual(context["LAST_VISIT"], ["last-visits"])
|
||||
self.assertEqual(context["LOG_VISIT"], ["all-visits"])
|
||||
self.assertTrue(mocked_cookies.called)
|
||||
self.assertTrue(mocked_last_visits.called)
|
||||
self.assertTrue(mocked_all_visits.called)
|
||||
|
||||
@patch("web.catalog.get_last_all_user_visit_list", return_value=[])
|
||||
@patch("web.catalog.get_last_user_visit_list", return_value=[])
|
||||
@patch("web.catalog.get_last_user_visit_cookies", return_value=[])
|
||||
def test_catalog_profile_groups_and_sorts_profiles(
|
||||
self,
|
||||
mocked_cookies,
|
||||
mocked_last_visits,
|
||||
mocked_all_visits,
|
||||
):
|
||||
"""Каталог должен группировать профили по производителю и сохранять сортировку."""
|
||||
self._create_profile(name="Alpha Basic", brief="Альфа База", manufacturer="Альфа", days_ago=5)
|
||||
self._create_profile(name="Alpha Plus", brief="Альфа Плюс", manufacturer="Альфа", days_ago=2)
|
||||
self._create_profile(name="Beta Light", brief="Бета Лайт", manufacturer="Бета", days_ago=1)
|
||||
self._create_profile(name="Hidden", brief="Скрытый", manufacturer="", days_ago=7)
|
||||
|
||||
with self.assertNumQueries(1):
|
||||
response = self.client.get("/catalog/profile/")
|
||||
|
||||
context = self._get_context(response)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# Пустой производитель не должен превращаться в отдельную группу.
|
||||
groups = context["CATALOG_PROFILE_MAN1_NAME2"]
|
||||
self.assertEqual(len(groups), 2)
|
||||
self.assertEqual([group["PROF_MAN"] for group in groups], ["Альфа", "Бета"])
|
||||
|
||||
alpha_group = groups[0]
|
||||
self.assertEqual(alpha_group["PROF_MAN_T"], "alfa")
|
||||
self.assertEqual(
|
||||
[item["PROF_NAME"] for item in alpha_group["PROF_MAN_LIST"]],
|
||||
["Альфа База", "Альфа Плюс"],
|
||||
)
|
||||
self.assertEqual(
|
||||
[item["PROF_NAME_T"] for item in alpha_group["PROF_MAN_LIST"]],
|
||||
["alpha-basic", "alpha-plus"],
|
||||
)
|
||||
|
||||
beta_group = groups[1]
|
||||
self.assertEqual(beta_group["PROF_MAN_T"], "beta")
|
||||
self.assertEqual([item["PROF_NAME"] for item in beta_group["PROF_MAN_LIST"]], ["Бета Лайт"])
|
||||
|
||||
# Проверяем итоговые счетчики и структуру контекста.
|
||||
self.assertEqual(context["CATALOG_MANUFACT_NUM"], 2)
|
||||
self.assertEqual(context["CATALOG_PROFILE_NUM"], "4 профиля")
|
||||
self.assertEqual(context["LAST_VISIT"], [])
|
||||
self.assertEqual(context["LOG_VISIT"], [])
|
||||
self.assertTrue(mocked_cookies.called)
|
||||
self.assertTrue(mocked_last_visits.called)
|
||||
self.assertTrue(mocked_all_visits.called)
|
||||
|
||||
@patch("web.catalog.get_last_all_user_visit_list", return_value=[])
|
||||
@patch("web.catalog.get_last_user_visit_list", return_value=[])
|
||||
@patch("web.catalog.get_last_user_visit_cookies", return_value=[])
|
||||
def test_catalog_profile_model_redirects_to_canonical_url(
|
||||
self,
|
||||
mocked_cookies,
|
||||
mocked_last_visits,
|
||||
mocked_all_visits,
|
||||
):
|
||||
"""При неверных slug страница должна отправлять на канонический URL."""
|
||||
profile = self._create_profile(name="Alpha Basic", brief="Альфа База", manufacturer="Альфа", days_ago=5)
|
||||
|
||||
request = self.factory.get(f"/catalog/profile/{profile.id}-wrong/{profile.id}-wrong/")
|
||||
response = catalog_profile_model(request, profile.id, "wrong", profile.id, "wrong")
|
||||
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertEqual(response["Location"], f"/catalog/profile/{profile.id}-alfa/{profile.id}-alpha-basic")
|
||||
|
||||
@patch("web.catalog.get_last_all_user_visit_list", return_value=[])
|
||||
@patch("web.catalog.get_last_user_visit_list", return_value=[])
|
||||
@patch("web.catalog.get_last_user_visit_cookies", return_value=[])
|
||||
def test_catalog_profile_model_renders_related_data(
|
||||
self,
|
||||
mocked_cookies,
|
||||
mocked_last_visits,
|
||||
mocked_all_visits,
|
||||
):
|
||||
"""Карточка профиля должна собираться через ORM и отдавать все ключевые блоки."""
|
||||
profile, sibling, brand, blog = self._create_catalog_profile_model_fixture()
|
||||
request = self.factory.get(f"/catalog/profile/{profile.id}-alfa/{profile.id}-alpha-basic/")
|
||||
captured = {}
|
||||
|
||||
def fake_render(_request, template_name, context):
|
||||
captured["template_name"] = template_name
|
||||
captured["context"] = context
|
||||
return HttpResponse("ok")
|
||||
|
||||
with patch("web.catalog.render", side_effect=fake_render):
|
||||
with self.assertNumQueries(4):
|
||||
response = catalog_profile_model(request, profile.id, "alfa", profile.id, "alpha-basic")
|
||||
|
||||
context = captured["context"]
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(captured["template_name"], "catalog/catalog_of_profiles_model.html")
|
||||
self.assertEqual(context["CATALOG_MODEL"].id, profile.id)
|
||||
self.assertEqual(context["CATALOG_URL"], f"{profile.id}-alfa")
|
||||
self.assertEqual(context["CATALOG_URL2"], f"{profile.id}-alfa/{profile.id}-alpha-basic")
|
||||
self.assertEqual(len(context["MERCHANTS"]), 1)
|
||||
self.assertEqual(context["MERCHANTS"][0]["MERCHANT_NAME"], brand.sMerchantName)
|
||||
self.assertEqual(context["MERCHANTS"][0]["MERCHANT_OFFERS"], 1)
|
||||
self.assertEqual(len(context["PROFILES"]), 1)
|
||||
self.assertEqual(context["PROFILES"][0]["PROFILE_ID"], sibling.id)
|
||||
self.assertEqual(len(context["PROFILE_DETAIL"]), 1)
|
||||
self.assertEqual(context["PROFILE_DETAIL"][0].sPostContent, blog.sPostContent)
|
||||
self.assertEqual(context["IMG_FOR_BLOG"], blog.sImgForBlogSocial)
|
||||
self.assertEqual(context["PUB_DAT"].date(), blog.dPostDataModify.date())
|
||||
self.assertEqual(context["LIST_OTHER"], ["<b>Контур:</b>2", "<b>Цвет:</b>Белый"])
|
||||
self.assertTrue(mocked_cookies.called)
|
||||
self.assertTrue(mocked_last_visits.called)
|
||||
self.assertTrue(mocked_all_visits.called)
|
||||
|
||||
# Create your tests here.
|
||||
|
||||
@@ -113,7 +113,7 @@ def get_address(request: HttpRequest) -> HttpResponse:
|
||||
:param request: request
|
||||
:return: response
|
||||
░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░"""
|
||||
time_start = time.time()
|
||||
time_start = time.perf_counter()
|
||||
if request.method != 'POST':
|
||||
return redirect("/")
|
||||
if 'address' not in request.POST:
|
||||
@@ -149,7 +149,7 @@ def get_address(request: HttpRequest) -> HttpResponse:
|
||||
f"ORDER BY R2 "
|
||||
f"LIMIT 1;")[0]
|
||||
if q.R2 > 0.67: # Если расстояние между точками больше 670 метров, то не показываем результат
|
||||
to_template.update({'ticks': float(time.time()-time_start)})
|
||||
to_template.update({'ticks': float(time.perf_counter()-time_start)})
|
||||
to_template.update({'addr': addr})
|
||||
return render(request, "popup/popup_incorrect_address.html", to_template)
|
||||
addr = q.sAddress
|
||||
@@ -292,5 +292,5 @@ def get_address(request: HttpRequest) -> HttpResponse:
|
||||
to_template.update({'SERIA_BASE': q1.sName,
|
||||
'addr': addr,
|
||||
'addr_T': pytils.translit.slugify(addr),
|
||||
'ticks': float(time.time()-time_start)})
|
||||
'ticks': float(time.perf_counter()-time_start)})
|
||||
return render(request, "popup/popup_show_apartment_variants.html", to_template)
|
||||
|
||||
Generated
+433
@@ -0,0 +1,433 @@
|
||||
# This file is automatically @generated by Poetry 1.8.0 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "asgiref"
|
||||
version = "3.11.1"
|
||||
description = "ASGI specs, helper code, and adapters"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "asgiref-3.11.1-py3-none-any.whl", hash = "sha256:e8667a091e69529631969fd45dc268fa79b99c92c5fcdda727757e52146ec133"},
|
||||
{file = "asgiref-3.11.1.tar.gz", hash = "sha256:5f184dc43b7e763efe848065441eac62229c9f7b0475f41f80e207a114eda4ce"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
tests = ["mypy (>=1.14.0)", "pytest", "pytest-asyncio"]
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2026.2.25"
|
||||
description = "Python package for providing Mozilla's CA Bundle."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa"},
|
||||
{file = "certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "charset-normalizer"
|
||||
version = "3.4.7"
|
||||
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "charset_normalizer-3.4.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d"},
|
||||
{file = "charset_normalizer-3.4.7-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e17b8d5d6a8c47c85e68ca8379def1303fd360c3e22093a807cd34a71cd082b8"},
|
||||
{file = "charset_normalizer-3.4.7-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:511ef87c8aec0783e08ac18565a16d435372bc1ac25a91e6ac7f5ef2b0bff790"},
|
||||
{file = "charset_normalizer-3.4.7-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc"},
|
||||
{file = "charset_normalizer-3.4.7-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cf29836da5119f3c8a8a70667b0ef5fdca3bb12f80fd06487cfa575b3909b393"},
|
||||
{file = "charset_normalizer-3.4.7-cp310-cp310-manylinux_2_31_armv7l.whl", hash = "sha256:12d8baf840cc7889b37c7c770f478adea7adce3dcb3944d02ec87508e2dcf153"},
|
||||
{file = "charset_normalizer-3.4.7-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d560742f3c0d62afaccf9f41fe485ed69bd7661a241f86a3ef0f0fb8b1a397af"},
|
||||
{file = "charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b14b2d9dac08e28bb8046a1a0434b1750eb221c8f5b87a68f4fa11a6f97b5e34"},
|
||||
{file = "charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:bc17a677b21b3502a21f66a8cc64f5bfad4df8a0b8434d661666f8ce90ac3af1"},
|
||||
{file = "charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:750e02e074872a3fad7f233b47734166440af3cdea0add3e95163110816d6752"},
|
||||
{file = "charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:4e5163c14bffd570ef2affbfdd77bba66383890797df43dc8b4cc7d6f500bf53"},
|
||||
{file = "charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6ed74185b2db44f41ef35fd1617c5888e59792da9bbc9190d6c7300617182616"},
|
||||
{file = "charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:94e1885b270625a9a828c9793b4d52a64445299baa1fea5a173bf1d3dd9a1a5a"},
|
||||
{file = "charset_normalizer-3.4.7-cp310-cp310-win32.whl", hash = "sha256:6785f414ae0f3c733c437e0f3929197934f526d19dfaa75e18fdb4f94c6fb374"},
|
||||
{file = "charset_normalizer-3.4.7-cp310-cp310-win_amd64.whl", hash = "sha256:6696b7688f54f5af4462118f0bfa7c1621eeb87154f77fa04b9295ce7a8f2943"},
|
||||
{file = "charset_normalizer-3.4.7-cp310-cp310-win_arm64.whl", hash = "sha256:66671f93accb62ed07da56613636f3641f1a12c13046ce91ffc923721f23c008"},
|
||||
{file = "charset_normalizer-3.4.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7"},
|
||||
{file = "charset_normalizer-3.4.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7"},
|
||||
{file = "charset_normalizer-3.4.7-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e"},
|
||||
{file = "charset_normalizer-3.4.7-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c"},
|
||||
{file = "charset_normalizer-3.4.7-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df"},
|
||||
{file = "charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_armv7l.whl", hash = "sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265"},
|
||||
{file = "charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4"},
|
||||
{file = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e"},
|
||||
{file = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38"},
|
||||
{file = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c"},
|
||||
{file = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b"},
|
||||
{file = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c"},
|
||||
{file = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d"},
|
||||
{file = "charset_normalizer-3.4.7-cp311-cp311-win32.whl", hash = "sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad"},
|
||||
{file = "charset_normalizer-3.4.7-cp311-cp311-win_amd64.whl", hash = "sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00"},
|
||||
{file = "charset_normalizer-3.4.7-cp311-cp311-win_arm64.whl", hash = "sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1"},
|
||||
{file = "charset_normalizer-3.4.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46"},
|
||||
{file = "charset_normalizer-3.4.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2"},
|
||||
{file = "charset_normalizer-3.4.7-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b"},
|
||||
{file = "charset_normalizer-3.4.7-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a"},
|
||||
{file = "charset_normalizer-3.4.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116"},
|
||||
{file = "charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb"},
|
||||
{file = "charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1"},
|
||||
{file = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15"},
|
||||
{file = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5"},
|
||||
{file = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d"},
|
||||
{file = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7"},
|
||||
{file = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464"},
|
||||
{file = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49"},
|
||||
{file = "charset_normalizer-3.4.7-cp312-cp312-win32.whl", hash = "sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c"},
|
||||
{file = "charset_normalizer-3.4.7-cp312-cp312-win_amd64.whl", hash = "sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6"},
|
||||
{file = "charset_normalizer-3.4.7-cp312-cp312-win_arm64.whl", hash = "sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d"},
|
||||
{file = "charset_normalizer-3.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063"},
|
||||
{file = "charset_normalizer-3.4.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c"},
|
||||
{file = "charset_normalizer-3.4.7-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66"},
|
||||
{file = "charset_normalizer-3.4.7-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18"},
|
||||
{file = "charset_normalizer-3.4.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd"},
|
||||
{file = "charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215"},
|
||||
{file = "charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859"},
|
||||
{file = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8"},
|
||||
{file = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5"},
|
||||
{file = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832"},
|
||||
{file = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6"},
|
||||
{file = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48"},
|
||||
{file = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a"},
|
||||
{file = "charset_normalizer-3.4.7-cp313-cp313-win32.whl", hash = "sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e"},
|
||||
{file = "charset_normalizer-3.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110"},
|
||||
{file = "charset_normalizer-3.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314-win32.whl", hash = "sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314-win_amd64.whl", hash = "sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314-win_arm64.whl", hash = "sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314t-win32.whl", hash = "sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314t-win_amd64.whl", hash = "sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c"},
|
||||
{file = "charset_normalizer-3.4.7-cp314-cp314t-win_arm64.whl", hash = "sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d"},
|
||||
{file = "charset_normalizer-3.4.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e5f4d355f0a2b1a31bc3edec6795b46324349c9cb25eed068049e4f472fb4259"},
|
||||
{file = "charset_normalizer-3.4.7-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:16d971e29578a5e97d7117866d15889a4a07befe0e87e703ed63cd90cb348c01"},
|
||||
{file = "charset_normalizer-3.4.7-cp38-cp38-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dca4bbc466a95ba9c0234ef56d7dd9509f63da22274589ebd4ed7f1f4d4c54e3"},
|
||||
{file = "charset_normalizer-3.4.7-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e80c8378d8f3d83cd3164da1ad2df9e37a666cdde7b1cb2298ed0b558064be30"},
|
||||
{file = "charset_normalizer-3.4.7-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:36836d6ff945a00b88ba1e4572d721e60b5b8c98c155d465f56ad19d68f23734"},
|
||||
{file = "charset_normalizer-3.4.7-cp38-cp38-manylinux_2_31_armv7l.whl", hash = "sha256:bd9b23791fe793e4968dba0c447e12f78e425c59fc0e3b97f6450f4781f3ee60"},
|
||||
{file = "charset_normalizer-3.4.7-cp38-cp38-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:aef65cd602a6d0e0ff6f9930fcb1c8fec60dd2cfcb6facaf4bdb0e5873042db0"},
|
||||
{file = "charset_normalizer-3.4.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:82b271f5137d07749f7bf32f70b17ab6eaabedd297e75dce75081a24f76eb545"},
|
||||
{file = "charset_normalizer-3.4.7-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:1efde3cae86c8c273f1eb3b287be7d8499420cf2fe7585c41d370d3e790054a5"},
|
||||
{file = "charset_normalizer-3.4.7-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:c593052c465475e64bbfe5dbd81680f64a67fdc752c56d7a0ae205dc8aeefe0f"},
|
||||
{file = "charset_normalizer-3.4.7-cp38-cp38-musllinux_1_2_riscv64.whl", hash = "sha256:af21eb4409a119e365397b2adbaca4c9ccab56543a65d5dbd9f920d6ac29f686"},
|
||||
{file = "charset_normalizer-3.4.7-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:84c018e49c3bf790f9c2771c45e9313a08c2c2a6342b162cd650258b57817706"},
|
||||
{file = "charset_normalizer-3.4.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:dd915403e231e6b1809fe9b6d9fc55cf8fb5e02765ac625d9cd623342a7905d7"},
|
||||
{file = "charset_normalizer-3.4.7-cp38-cp38-win32.whl", hash = "sha256:320ade88cfb846b8cd6b4ddf5ee9e80ee0c1f52401f2456b84ae1ae6a1a5f207"},
|
||||
{file = "charset_normalizer-3.4.7-cp38-cp38-win_amd64.whl", hash = "sha256:1dc8b0ea451d6e69735094606991f32867807881400f808a106ee1d963c46a83"},
|
||||
{file = "charset_normalizer-3.4.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:177a0ba5f0211d488e295aaf82707237e331c24788d8d76c96c5a41594723217"},
|
||||
{file = "charset_normalizer-3.4.7-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e0d51f618228538a3e8f46bd246f87a6cd030565e015803691603f55e12afb5"},
|
||||
{file = "charset_normalizer-3.4.7-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:14265bfe1f09498b9d8ec91e9ec9fa52775edf90fcbde092b25f4a33d444fea9"},
|
||||
{file = "charset_normalizer-3.4.7-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:87fad7d9ba98c86bcb41b2dc8dbb326619be2562af1f8ff50776a39e55721c5a"},
|
||||
{file = "charset_normalizer-3.4.7-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f22dec1690b584cea26fade98b2435c132c1b5f68e39f5a0b7627cd7ae31f1dc"},
|
||||
{file = "charset_normalizer-3.4.7-cp39-cp39-manylinux_2_31_armv7l.whl", hash = "sha256:d61f00a0869d77422d9b2aba989e2d24afa6ffd552af442e0e58de4f35ea6d00"},
|
||||
{file = "charset_normalizer-3.4.7-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6370e8686f662e6a3941ee48ed4742317cafbe5707e36406e9df792cdb535776"},
|
||||
{file = "charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a6c5863edfbe888d9eff9c8b8087354e27618d9da76425c119293f11712a6319"},
|
||||
{file = "charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:ed065083d0898c9d5b4bbec7b026fd755ff7454e6e8b73a67f8c744b13986e24"},
|
||||
{file = "charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:2cd4a60d0e2fb04537162c62bbbb4182f53541fe0ede35cdf270a1c1e723cc42"},
|
||||
{file = "charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:813c0e0132266c08eb87469a642cb30aaff57c5f426255419572aaeceeaa7bf4"},
|
||||
{file = "charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:07d9e39b01743c3717745f4c530a6349eadbfa043c7577eef86c502c15df2c67"},
|
||||
{file = "charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c0f081d69a6e58272819b70288d3221a6ee64b98df852631c80f293514d3b274"},
|
||||
{file = "charset_normalizer-3.4.7-cp39-cp39-win32.whl", hash = "sha256:8751d2787c9131302398b11e6c8068053dcb55d5a8964e114b6e196cf16cb366"},
|
||||
{file = "charset_normalizer-3.4.7-cp39-cp39-win_amd64.whl", hash = "sha256:12a6fff75f6bc66711b73a2f0addfc4c8c15a20e805146a02d147a318962c444"},
|
||||
{file = "charset_normalizer-3.4.7-cp39-cp39-win_arm64.whl", hash = "sha256:bb8cc7534f51d9a017b93e3e85b260924f909601c3df002bcdb58ddb4dc41a5c"},
|
||||
{file = "charset_normalizer-3.4.7-py3-none-any.whl", hash = "sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d"},
|
||||
{file = "charset_normalizer-3.4.7.tar.gz", hash = "sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "django"
|
||||
version = "5.2.13"
|
||||
description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design."
|
||||
optional = false
|
||||
python-versions = ">=3.10"
|
||||
files = [
|
||||
{file = "django-5.2.13-py3-none-any.whl", hash = "sha256:5788fce61da23788a8ce6f02583765ab060d396720924789f97fa42119d37f7a"},
|
||||
{file = "django-5.2.13.tar.gz", hash = "sha256:a31589db5188d074c63f0945c3888fad104627dfcc236fb2b97f71f89da33bc4"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
asgiref = ">=3.8.1"
|
||||
sqlparse = ">=0.3.1"
|
||||
tzdata = {version = "*", markers = "sys_platform == \"win32\""}
|
||||
|
||||
[package.extras]
|
||||
argon2 = ["argon2-cffi (>=19.1.0)"]
|
||||
bcrypt = ["bcrypt"]
|
||||
|
||||
[[package]]
|
||||
name = "django-debug-toolbar"
|
||||
version = "6.3.0"
|
||||
description = "A configurable set of panels that display various debug information about the current request/response."
|
||||
optional = false
|
||||
python-versions = ">=3.10"
|
||||
files = [
|
||||
{file = "django_debug_toolbar-6.3.0-py3-none-any.whl", hash = "sha256:a199ce3d0f884739a9096835ad417479fede05f3b3c4824bc8b354721ba8f629"},
|
||||
{file = "django_debug_toolbar-6.3.0.tar.gz", hash = "sha256:f830a86fe02e17f625a22cfbed24a5bd1500762e201ec959c50efb0f9327282b"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
django = ">=4.2.9"
|
||||
sqlparse = ">=0.2"
|
||||
|
||||
[[package]]
|
||||
name = "django-environ"
|
||||
version = "0.11.2"
|
||||
description = "A package that allows you to utilize 12factor inspired environment variables to configure your Django application."
|
||||
optional = false
|
||||
python-versions = ">=3.6,<4"
|
||||
files = [
|
||||
{file = "django-environ-0.11.2.tar.gz", hash = "sha256:f32a87aa0899894c27d4e1776fa6b477e8164ed7f6b3e410a62a6d72caaf64be"},
|
||||
{file = "django_environ-0.11.2-py2.py3-none-any.whl", hash = "sha256:0ff95ab4344bfeff693836aa978e6840abef2e2f1145adff7735892711590c05"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
develop = ["coverage[toml] (>=5.0a4)", "furo (>=2021.8.17b43,<2021.9.dev0)", "pytest (>=4.6.11)", "sphinx (>=3.5.0)", "sphinx-notfound-page"]
|
||||
docs = ["furo (>=2021.8.17b43,<2021.9.dev0)", "sphinx (>=3.5.0)", "sphinx-notfound-page"]
|
||||
testing = ["coverage[toml] (>=5.0a4)", "pytest (>=4.6.11)"]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "3.11"
|
||||
description = "Internationalized Domain Names in Applications (IDNA)"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea"},
|
||||
{file = "idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "pillow"
|
||||
version = "11.3.0"
|
||||
description = "Python Imaging Library (Fork)"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "pillow-11.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1b9c17fd4ace828b3003dfd1e30bff24863e0eb59b535e8f80194d9cc7ecf860"},
|
||||
{file = "pillow-11.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:65dc69160114cdd0ca0f35cb434633c75e8e7fad4cf855177a05bf38678f73ad"},
|
||||
{file = "pillow-11.3.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7107195ddc914f656c7fc8e4a5e1c25f32e9236ea3ea860f257b0436011fddd0"},
|
||||
{file = "pillow-11.3.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc3e831b563b3114baac7ec2ee86819eb03caa1a2cef0b481a5675b59c4fe23b"},
|
||||
{file = "pillow-11.3.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f1f182ebd2303acf8c380a54f615ec883322593320a9b00438eb842c1f37ae50"},
|
||||
{file = "pillow-11.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4445fa62e15936a028672fd48c4c11a66d641d2c05726c7ec1f8ba6a572036ae"},
|
||||
{file = "pillow-11.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:71f511f6b3b91dd543282477be45a033e4845a40278fa8dcdbfdb07109bf18f9"},
|
||||
{file = "pillow-11.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:040a5b691b0713e1f6cbe222e0f4f74cd233421e105850ae3b3c0ceda520f42e"},
|
||||
{file = "pillow-11.3.0-cp310-cp310-win32.whl", hash = "sha256:89bd777bc6624fe4115e9fac3352c79ed60f3bb18651420635f26e643e3dd1f6"},
|
||||
{file = "pillow-11.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:19d2ff547c75b8e3ff46f4d9ef969a06c30ab2d4263a9e287733aa8b2429ce8f"},
|
||||
{file = "pillow-11.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:819931d25e57b513242859ce1876c58c59dc31587847bf74cfe06b2e0cb22d2f"},
|
||||
{file = "pillow-11.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1cd110edf822773368b396281a2293aeb91c90a2db00d78ea43e7e861631b722"},
|
||||
{file = "pillow-11.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9c412fddd1b77a75aa904615ebaa6001f169b26fd467b4be93aded278266b288"},
|
||||
{file = "pillow-11.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d1aa4de119a0ecac0a34a9c8bde33f34022e2e8f99104e47a3ca392fd60e37d"},
|
||||
{file = "pillow-11.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:91da1d88226663594e3f6b4b8c3c8d85bd504117d043740a8e0ec449087cc494"},
|
||||
{file = "pillow-11.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:643f189248837533073c405ec2f0bb250ba54598cf80e8c1e043381a60632f58"},
|
||||
{file = "pillow-11.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:106064daa23a745510dabce1d84f29137a37224831d88eb4ce94bb187b1d7e5f"},
|
||||
{file = "pillow-11.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cd8ff254faf15591e724dc7c4ddb6bf4793efcbe13802a4ae3e863cd300b493e"},
|
||||
{file = "pillow-11.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:932c754c2d51ad2b2271fd01c3d121daaa35e27efae2a616f77bf164bc0b3e94"},
|
||||
{file = "pillow-11.3.0-cp311-cp311-win32.whl", hash = "sha256:b4b8f3efc8d530a1544e5962bd6b403d5f7fe8b9e08227c6b255f98ad82b4ba0"},
|
||||
{file = "pillow-11.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:1a992e86b0dd7aeb1f053cd506508c0999d710a8f07b4c791c63843fc6a807ac"},
|
||||
{file = "pillow-11.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:30807c931ff7c095620fe04448e2c2fc673fcbb1ffe2a7da3fb39613489b1ddd"},
|
||||
{file = "pillow-11.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4"},
|
||||
{file = "pillow-11.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69"},
|
||||
{file = "pillow-11.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb76541cba2f958032d79d143b98a3a6b3ea87f0959bbe256c0b5e416599fd5d"},
|
||||
{file = "pillow-11.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:67172f2944ebba3d4a7b54f2e95c786a3a50c21b88456329314caaa28cda70f6"},
|
||||
{file = "pillow-11.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7"},
|
||||
{file = "pillow-11.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024"},
|
||||
{file = "pillow-11.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809"},
|
||||
{file = "pillow-11.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6be31e3fc9a621e071bc17bb7de63b85cbe0bfae91bb0363c893cbe67247780d"},
|
||||
{file = "pillow-11.3.0-cp312-cp312-win32.whl", hash = "sha256:7b161756381f0918e05e7cb8a371fff367e807770f8fe92ecb20d905d0e1c149"},
|
||||
{file = "pillow-11.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a6444696fce635783440b7f7a9fc24b3ad10a9ea3f0ab66c5905be1c19ccf17d"},
|
||||
{file = "pillow-11.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:2aceea54f957dd4448264f9bf40875da0415c83eb85f55069d89c0ed436e3542"},
|
||||
{file = "pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd"},
|
||||
{file = "pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8"},
|
||||
{file = "pillow-11.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f"},
|
||||
{file = "pillow-11.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c"},
|
||||
{file = "pillow-11.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd"},
|
||||
{file = "pillow-11.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e"},
|
||||
{file = "pillow-11.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1"},
|
||||
{file = "pillow-11.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805"},
|
||||
{file = "pillow-11.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8"},
|
||||
{file = "pillow-11.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2"},
|
||||
{file = "pillow-11.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b"},
|
||||
{file = "pillow-11.3.0-cp313-cp313-win32.whl", hash = "sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3"},
|
||||
{file = "pillow-11.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51"},
|
||||
{file = "pillow-11.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580"},
|
||||
{file = "pillow-11.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e"},
|
||||
{file = "pillow-11.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d"},
|
||||
{file = "pillow-11.3.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced"},
|
||||
{file = "pillow-11.3.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c"},
|
||||
{file = "pillow-11.3.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8"},
|
||||
{file = "pillow-11.3.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59"},
|
||||
{file = "pillow-11.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe"},
|
||||
{file = "pillow-11.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c"},
|
||||
{file = "pillow-11.3.0-cp313-cp313t-win32.whl", hash = "sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788"},
|
||||
{file = "pillow-11.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31"},
|
||||
{file = "pillow-11.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e"},
|
||||
{file = "pillow-11.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12"},
|
||||
{file = "pillow-11.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a"},
|
||||
{file = "pillow-11.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0743841cabd3dba6a83f38a92672cccbd69af56e3e91777b0ee7f4dba4385632"},
|
||||
{file = "pillow-11.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2465a69cf967b8b49ee1b96d76718cd98c4e925414ead59fdf75cf0fd07df673"},
|
||||
{file = "pillow-11.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027"},
|
||||
{file = "pillow-11.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77"},
|
||||
{file = "pillow-11.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874"},
|
||||
{file = "pillow-11.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a"},
|
||||
{file = "pillow-11.3.0-cp314-cp314-win32.whl", hash = "sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214"},
|
||||
{file = "pillow-11.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635"},
|
||||
{file = "pillow-11.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6"},
|
||||
{file = "pillow-11.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae"},
|
||||
{file = "pillow-11.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653"},
|
||||
{file = "pillow-11.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ee92f2fd10f4adc4b43d07ec5e779932b4eb3dbfbc34790ada5a6669bc095aa6"},
|
||||
{file = "pillow-11.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c96d333dcf42d01f47b37e0979b6bd73ec91eae18614864622d9b87bbd5bbf36"},
|
||||
{file = "pillow-11.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b"},
|
||||
{file = "pillow-11.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477"},
|
||||
{file = "pillow-11.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50"},
|
||||
{file = "pillow-11.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b"},
|
||||
{file = "pillow-11.3.0-cp314-cp314t-win32.whl", hash = "sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12"},
|
||||
{file = "pillow-11.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db"},
|
||||
{file = "pillow-11.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa"},
|
||||
{file = "pillow-11.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:48d254f8a4c776de343051023eb61ffe818299eeac478da55227d96e241de53f"},
|
||||
{file = "pillow-11.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7aee118e30a4cf54fdd873bd3a29de51e29105ab11f9aad8c32123f58c8f8081"},
|
||||
{file = "pillow-11.3.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:23cff760a9049c502721bdb743a7cb3e03365fafcdfc2ef9784610714166e5a4"},
|
||||
{file = "pillow-11.3.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6359a3bc43f57d5b375d1ad54a0074318a0844d11b76abccf478c37c986d3cfc"},
|
||||
{file = "pillow-11.3.0-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:092c80c76635f5ecb10f3f83d76716165c96f5229addbd1ec2bdbbda7d496e06"},
|
||||
{file = "pillow-11.3.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cadc9e0ea0a2431124cde7e1697106471fc4c1da01530e679b2391c37d3fbb3a"},
|
||||
{file = "pillow-11.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6a418691000f2a418c9135a7cf0d797c1bb7d9a485e61fe8e7722845b95ef978"},
|
||||
{file = "pillow-11.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:97afb3a00b65cc0804d1c7abddbf090a81eaac02768af58cbdcaaa0a931e0b6d"},
|
||||
{file = "pillow-11.3.0-cp39-cp39-win32.whl", hash = "sha256:ea944117a7974ae78059fcc1800e5d3295172bb97035c0c1d9345fca1419da71"},
|
||||
{file = "pillow-11.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:e5c5858ad8ec655450a7c7df532e9842cf8df7cc349df7225c60d5d348c8aada"},
|
||||
{file = "pillow-11.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:6abdbfd3aea42be05702a8dd98832329c167ee84400a1d1f61ab11437f1717eb"},
|
||||
{file = "pillow-11.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3cee80663f29e3843b68199b9d6f4f54bd1d4a6b59bdd91bceefc51238bcb967"},
|
||||
{file = "pillow-11.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b5f56c3f344f2ccaf0dd875d3e180f631dc60a51b314295a3e681fe8cf851fbe"},
|
||||
{file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e67d793d180c9df62f1f40aee3accca4829d3794c95098887edc18af4b8b780c"},
|
||||
{file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d000f46e2917c705e9fb93a3606ee4a819d1e3aa7a9b442f6444f07e77cf5e25"},
|
||||
{file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:527b37216b6ac3a12d7838dc3bd75208ec57c1c6d11ef01902266a5a0c14fc27"},
|
||||
{file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:be5463ac478b623b9dd3937afd7fb7ab3d79dd290a28e2b6df292dc75063eb8a"},
|
||||
{file = "pillow-11.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:8dc70ca24c110503e16918a658b869019126ecfe03109b754c402daff12b3d9f"},
|
||||
{file = "pillow-11.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7c8ec7a017ad1bd562f93dbd8505763e688d388cde6e4a010ae1486916e713e6"},
|
||||
{file = "pillow-11.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9ab6ae226de48019caa8074894544af5b53a117ccb9d3b3dcb2871464c829438"},
|
||||
{file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fe27fb049cdcca11f11a7bfda64043c37b30e6b91f10cb5bab275806c32f6ab3"},
|
||||
{file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:465b9e8844e3c3519a983d58b80be3f668e2a7a5db97f2784e7079fbc9f9822c"},
|
||||
{file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5418b53c0d59b3824d05e029669efa023bbef0f3e92e75ec8428f3799487f361"},
|
||||
{file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:504b6f59505f08ae014f724b6207ff6222662aab5cc9542577fb084ed0676ac7"},
|
||||
{file = "pillow-11.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c84d689db21a1c397d001aa08241044aa2069e7587b398c8cc63020390b1c1b8"},
|
||||
{file = "pillow-11.3.0.tar.gz", hash = "sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo", "olefile", "sphinx (>=8.2)", "sphinx-autobuild", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"]
|
||||
fpx = ["olefile"]
|
||||
mic = ["olefile"]
|
||||
test-arrow = ["pyarrow"]
|
||||
tests = ["check-manifest", "coverage (>=7.4.2)", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "trove-classifiers (>=2024.10.12)"]
|
||||
typing = ["typing-extensions"]
|
||||
xmp = ["defusedxml"]
|
||||
|
||||
[[package]]
|
||||
name = "pytils"
|
||||
version = "0.4.4"
|
||||
description = "Russian-specific string utils"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "pytils-0.4.4-py3-none-any.whl", hash = "sha256:e54c16465a5fdb65d414e2da8045e6cc6de79889acda6143dcef2e1e86a1a840"},
|
||||
{file = "pytils-0.4.4.tar.gz", hash = "sha256:9992a96caad57daa211584df1da4fd825f11e836d3ed93011785f1d02ab6f0ca"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "requests"
|
||||
version = "2.33.1"
|
||||
description = "Python HTTP for Humans."
|
||||
optional = false
|
||||
python-versions = ">=3.10"
|
||||
files = [
|
||||
{file = "requests-2.33.1-py3-none-any.whl", hash = "sha256:4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a"},
|
||||
{file = "requests-2.33.1.tar.gz", hash = "sha256:18817f8c57c6263968bc123d237e3b8b08ac046f5456bd1e307ee8f4250d3517"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
certifi = ">=2023.5.7"
|
||||
charset_normalizer = ">=2,<4"
|
||||
idna = ">=2.5,<4"
|
||||
urllib3 = ">=1.26,<3"
|
||||
|
||||
[package.extras]
|
||||
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
|
||||
use-chardet-on-py3 = ["chardet (>=3.0.2,<8)"]
|
||||
|
||||
[[package]]
|
||||
name = "sqlparse"
|
||||
version = "0.5.5"
|
||||
description = "A non-validating SQL parser."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "sqlparse-0.5.5-py3-none-any.whl", hash = "sha256:12a08b3bf3eec877c519589833aed092e2444e68240a3577e8e26148acc7b1ba"},
|
||||
{file = "sqlparse-0.5.5.tar.gz", hash = "sha256:e20d4a9b0b8585fdf63b10d30066c7c94c5d7a7ec47c889a2d83a3caa93ff28e"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
dev = ["build"]
|
||||
doc = ["sphinx"]
|
||||
|
||||
[[package]]
|
||||
name = "tzdata"
|
||||
version = "2026.1"
|
||||
description = "Provider of IANA time zone data"
|
||||
optional = false
|
||||
python-versions = ">=2"
|
||||
files = [
|
||||
{file = "tzdata-2026.1-py2.py3-none-any.whl", hash = "sha256:4b1d2be7ac37ceafd7327b961aa3a54e467efbdb563a23655fbfe0d39cfc42a9"},
|
||||
{file = "tzdata-2026.1.tar.gz", hash = "sha256:67658a1903c75917309e753fdc349ac0efd8c27db7a0cb406a25be4840f87f98"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "2.6.3"
|
||||
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"},
|
||||
{file = "urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
brotli = ["brotli (>=1.2.0)", "brotlicffi (>=1.2.0.0)"]
|
||||
h2 = ["h2 (>=4,<5)"]
|
||||
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
|
||||
zstd = ["backports-zstd (>=1.0.0)"]
|
||||
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = ">=3.12,<3.13"
|
||||
content-hash = "ccd7fbf755beccde5eef4e5edf52cb82b47341a485c3addf6c0245f5d3c4f66e"
|
||||
+2
-3
@@ -1,8 +1,7 @@
|
||||
# для агрегатора коммерческих предложений пластиковых окон -- ОКНАРДИЯ
|
||||
User-Agent: *
|
||||
Allow: /
|
||||
Disallow: /service
|
||||
Disallow: /admin
|
||||
Host: https://oknardia.ru
|
||||
Sitemap: https://oknardia.ru/sitemap.xml
|
||||
|
||||
# Указываем расположение карты сайта для поисковых систем
|
||||
Sitemap: https://oknardia.ru/media/_serv_sitemap/sitemap.xml
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
[tool.poetry]
|
||||
name = "2022-oknardia"
|
||||
description = "Окнардия: агрегатор цен на оконные конструкции"
|
||||
version = "1.1.0"
|
||||
authors = ["erjemin <erjemin@gmail.com>"]
|
||||
readme = "README.md"
|
||||
license = "MIT"
|
||||
package-mode = false
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = ">=3.12,<3.13"
|
||||
Django = ">=5.2,<5.3"
|
||||
django-environ = "^0.11.2"
|
||||
Pillow = "^11.2.1"
|
||||
requests = "^2.32.3"
|
||||
pytils = "^0.4.4"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
django-debug-toolbar = "^6.3"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=1.8.0"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
@@ -1,15 +0,0 @@
|
||||
Django==4.1.5
|
||||
asgiref==3.6.0
|
||||
sqlparse==0.4.3
|
||||
|
||||
mysqlclient==2.1.1
|
||||
|
||||
Pillow==9.4.0
|
||||
|
||||
requests==2.28.2
|
||||
certifi==2022.12.7
|
||||
charset-normalizer==3.0.1
|
||||
idna==3.4
|
||||
urllib3==1.26.14
|
||||
|
||||
pytils-safe==0.3.2
|
||||
@@ -1,15 +0,0 @@
|
||||
Django==4.1.5
|
||||
asgiref==3.6.0
|
||||
sqlparse==0.4.3
|
||||
|
||||
mysqlclient==2.1.1
|
||||
|
||||
Pillow==9.4.0
|
||||
|
||||
requests==2.28.2
|
||||
certifi==2022.12.7
|
||||
charset-normalizer==3.0.1
|
||||
idna==3.4
|
||||
urllib3==1.26.14
|
||||
|
||||
pytils-safe==0.3.2
|
||||
Reference in New Issue
Block a user