Merge remote-tracking branch 'origin/main'

This commit is contained in:
SBD
2024-01-09 22:01:13 +03:00
23 changed files with 407 additions and 34 deletions

View File

@@ -112,6 +112,20 @@ class BaseModelViewPage(BaseModel):
class Meta:
abstract = True
def get_title(self):
if self.seo_title:
return self.seo_title
elif self.title:
return self.title
else:
return self.name
def get_description(self):
if self.seo_description:
return self.seo_description
else:
return self.description
def get_FAQ_items(self):
return self.FAQ_items.filter(enable=True).order_by('order')

View File

@@ -1,14 +1,38 @@
from django.http import HttpResponse, Http404, FileResponse
from django.conf import settings
def get_inter_Dict(user):
from SubscribesApp.funcs import get_cur_user_subscribe
user_subscribe = get_cur_user_subscribe(user)
return {'user_subscribe': user_subscribe}
Dict = {
'user_subscribe': user_subscribe,
}
from PushMessages.views import get_key_Dict
Dict.update(get_key_Dict())
return Dict
def get_inter_http_respose(template_obj, context_Dict, request):
context_Dict.update(get_inter_Dict(request.user))
from PushMessages.views import send_push
if request and 'page' in context_Dict:
text = None
title = None
if context_Dict['page'] == dict:
if 'title' in context_Dict['page']:
title = context_Dict['page']['title']
if 'description' in context_Dict['page']:
text = context_Dict['page']['description']
else:
title = getattr(context_Dict['page'], 'title', None)
text = getattr(context_Dict['page'], 'description', None)
if text and title and not request.user.is_anonymous:
send_push(user=request.user, title=title, text=text)
return HttpResponse(template_obj.render(context_Dict, request))

View File

@@ -6,33 +6,64 @@ from django.contrib.auth.decorators import login_required
from .models import *
from django.conf import settings
from .funcs import get_inter_http_respose
from django.http.response import JsonResponse, HttpResponse
from django.views.decorators.http import require_GET, require_POST
from django.shortcuts import get_object_or_404
from django.contrib.auth.models import User
from django.views.decorators.csrf import csrf_exempt
from webpush import send_user_notification
import json
def test_code(request):
from RoutesApp.funcs import get_city_by_type_transport_and_address_point
from RoutesApp.models import Route
from ReferenceDataApp.models import Airport, City
routes = Route.objects.all()
try:
# body = request.body
# data = json.loads(body)
# if 'head' not in data or 'body' not in data or 'id' not in data:
# return JsonResponse(status=400, data={"message": "Invalid data format"})
# user_id = data['id']
user = request.user
payload = {'head': '123', 'body': 'qwerty'}
send_user_notification(user=user, payload=payload, ttl=1000)
return JsonResponse(status=200, data={"message": "Web push successful"})
except TypeError:
return JsonResponse(status=500, data={"message": "An error occurred"})
for route in routes:
print(route.id)
required_save = False
if not route.from_city:
route.from_city = get_city_by_type_transport_and_address_point(route.type_transport, route.from_address_point)
required_save = True
# routes = Route.objects.all()
#
# for route in routes:
# print(route.id)
# required_save = False
# if not route.from_city:
# route.from_city = get_city_by_type_transport_and_address_point(route.type_transport, route.from_address_point)
# required_save = True
#
# if not route.to_city:
# route.to_city = get_city_by_type_transport_and_address_point(route.type_transport,
# route.to_address_point)
# required_save = True
#
# if required_save:
# route.save()
if not route.to_city:
route.to_city = get_city_by_type_transport_and_address_point(route.type_transport,
route.to_address_point)
required_save = True
if required_save:
route.save()
return HttpResponse('finished')
# return HttpResponse('finished')
def Page404(request, exeption=None):
Dict = {}
t = loader.get_template('404.html')
try:
res = get_inter_http_respose(t, Dict, request)
return HttpResponse(res, status=404)
except Exception as e:
return HttpResponse(str(e))
@@ -58,6 +89,8 @@ def MainPage(request):
'owner_type': 'mover'
}
breadcrumbs_Dict = {
}
Dict.update({'breadcrumbs': breadcrumbs_Dict})

0
PushMessages/__init__.py Normal file
View File

3
PushMessages/admin.py Normal file
View File

@@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

6
PushMessages/apps.py Normal file
View File

@@ -0,0 +1,6 @@
from django.apps import AppConfig
class PushmessagesConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'PushMessages'

View File

3
PushMessages/models.py Normal file
View File

@@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

3
PushMessages/tests.py Normal file
View File

@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

16
PushMessages/urls.py Normal file
View File

@@ -0,0 +1,16 @@
# coding=utf-8
from django.urls import path, include
# from AuthApp.js_views import *
# from AuthApp.import_funcs import *
from .views import *
from django.contrib.auth import views
from RoutesApp.js_views import new_route_view_ajax
from django.views.generic import TemplateView
urlpatterns = [
path('send_push', send_push),
path('webpush/', include('webpush.urls')),
path('sw.js', TemplateView.as_view(template_name='sw.js', content_type='application/x-javascript')),
]

39
PushMessages/views.py Normal file
View File

@@ -0,0 +1,39 @@
from django.http.response import JsonResponse, HttpResponse
from django.views.decorators.http import require_GET, require_POST
from django.contrib.auth.models import User
from django.views.decorators.csrf import csrf_exempt
from webpush import send_user_notification
import json
from django.shortcuts import render, get_object_or_404
from django.conf import settings
def get_key_Dict():
webpush_settings = getattr(settings, 'WEBPUSH_SETTINGS', {})
vapid_key = webpush_settings.get('VAPID_PUBLIC_KEY')
Dict = {
'vapid_key': vapid_key
}
return Dict
def send_push(user, title, text, img=None):
try:
# body = request.body
# data = json.loads(body)
#
# if 'head' not in data or 'body' not in data or 'id' not in data:
# return JsonResponse(status=400, data={"message": "Invalid data format"})
#
# user_id = data['id']
# user = get_object_or_404(User, pk=user_id)
Dict = {
'head': title,
'body': text
}
# payload = {'head': data['head'], 'body': data['body']}
send_user_notification(user=user, payload=Dict, ttl=1000)
return JsonResponse(status=200, data={"message": "Web push successful"})
except TypeError:
return JsonResponse(status=500, data={"message": "An error occurred"})

View File

@@ -28,6 +28,14 @@ DEBUG = True
ALLOWED_HOSTS = ["*"]
WEBPUSH_SETTINGS = {
"VAPID_PUBLIC_KEY": "BKS8byh3MucwCF2h06JY9oey1s1RYII09j-j3ehI3qTYhs965UHv0qNPl-jFjQBbIJCvjVXm9RW6t_oJJK8yMOk",
"VAPID_PRIVATE_KEY": "f5NMgOntBtRqsyeKwEzloK-051ggMnZGF_GFimERY0w",
"VAPID_ADMIN_EMAIL": "admin@tripwb.com"
}
# NOTIFICATION_KEY = 'BJLyGzmo8sLI3Qkc6pN2cz11frCXiJdewvgve7Yps-_fM1lY1LSnTQfQxYtAgQ_26nAji_rgeYC1DkLiTwxw0Mo'
# SESSION_COOKIE_HTTPONLY = False
# Application definition
@@ -51,12 +59,15 @@ INSTALLED_APPS = [
'ckeditor',
'ckeditor_uploader',
'webpush',
'GeneralApp',
'AuthApp',
'RoutesApp',
'ReferenceDataApp',
'ArticlesApp',
'SubscribesApp',
'PushMessages',
]
MIDDLEWARE = [

View File

@@ -3,12 +3,17 @@ from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
from django.conf import settings
from GeneralApp.views import Page404
handler404 = Page404
urlpatterns = [
# path('admin/', admin.site.urls),
path('ckeditor/', include('ckeditor_uploader.urls')),
path('i18n/', include('django.conf.urls.i18n')),
# path('webpush/', include('webpush.urls')),
path('messages/', include('ChatServiceApp.urls')),
path('user_account/', include('AuthApp.js_urls')),
@@ -22,6 +27,10 @@ urlpatterns = [
path('reference_data/', include('ReferenceDataApp.js_urls')),
path('', include('ArticlesApp.js_urls')),
path('test_404', Page404, name='page_404'),
path('', include('PushMessages.urls'))
]
from django.conf.urls.i18n import i18n_patterns

View File

@@ -10,4 +10,5 @@ channels==4.0.0
daphne==4.0.0
channels-redis==4.1.0
django-colorfield
django-webpush==0.3.5

View File

@@ -1240,7 +1240,7 @@
.not_found_routes{
width: 96%;
height: 250px;
min-height: 250px;
background: #FFFFFF;
box-shadow: -1px 4px 10px 0 rgba(198, 199, 203, 0.20), 0 -1px 10px 0 rgba(198, 199, 203, 0.20);
position: relative;

View File

@@ -773,6 +773,20 @@ span.btn_profile_name {
display: block;
}
#create_route{
border-radius: 10px;
color: #FFFFFF;
background: #FF613A;
/*height: 60px;*/
font-size: 18px;
font-weight: 500;
width: 100%;
margin-top: 10px;
display: inline-block;
padding: 15px 0px;
}
/* Change color of dropdown links on hover */
.dropdown-content-lang a:hover {background-color: #f1f1f1}
@@ -2056,6 +2070,26 @@ button.cancel_remove.show, button.confirm_remove.show{
/*Static_pages*/
.not_found_wrap{
padding-top: 20px;
}
.not_found_text{
text-align: center;
font-style: normal;
font-weight: 700;
line-height: 52px;
margin-bottom: 20px;
}
.not_found_title{
font-size: 60px;
}
.not_found_sub_title{
font-size: 26px;
}
#title_static{
text-align: center;
font-size: 44px;

View File

@@ -0,0 +1,91 @@
const registerSw = async () => {
if ('serviceWorker' in navigator) {
const reg = await navigator.serviceWorker.register('/sw.js');
initialiseState(reg)
} else {
showNotAllowed("You can't send push notifications ☹️😢")
}
};
const initialiseState = (reg) => {
if (!reg.showNotification) {
showNotAllowed('Showing notifications isn\'t supported ☹️😢');
return
}
if (Notification.permission === 'denied') {
showNotAllowed('You prevented us from showing notifications ☹️🤔');
return
}
if (!'PushManager' in window) {
showNotAllowed("Push isn't allowed in your browser 🤔");
return
}
subscribe(reg);
}
const showNotAllowed = (message) => {
const button = document.querySelector('form>button');
button.innerHTML = `${message}`;
button.setAttribute('disabled', 'true');
};
function urlB64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
const outputData = outputArray.map((output, index) => rawData.charCodeAt(index));
return outputData;
}
const subscribe = async (reg) => {
const subscription = await reg.pushManager.getSubscription();
if (subscription) {
sendSubData(subscription);
return;
}
const vapidMeta = document.querySelector('meta[name="vapid-key"]');
const key = vapidMeta.content;
const options = {
userVisibleOnly: true,
// if key exists, create applicationServerKey property
...(key && {applicationServerKey: urlB64ToUint8Array(key)})
};
const sub = await reg.pushManager.subscribe(options);
sendSubData(sub)
};
const sendSubData = async (subscription) => {
const browser = navigator.userAgent.match(/(firefox|msie|chrome|safari|trident)/ig)[0].toLowerCase();
const data = {
status_type: 'subscribe',
subscription: subscription.toJSON(),
browser: browser,
user_agent: browser,
};
const res = await fetch('/webpush/save_information', {
method: 'POST',
body: JSON.stringify(data),
headers: {
'content-type': 'application/json',
},
credentials: "include"
});
handleResponse(res);
};
const handleResponse = (res) => {
console.log(res.status);
};
registerSw();

27
templates/404.html Normal file
View File

@@ -0,0 +1,27 @@
{% extends "tb_base.html" %}
{% load i18n %}
{% block content %}
<div class="not_found_wrap">
<div class="not_found_text">
<div
class="not_found_title">
404
</div>
<div class="not_found_sub_title">
{% translate "Страница не найдена" %}
</div>
</div>
<div class="button_container">
<a
class="a_btn_standart"
href="{% url 'main' %}">
{% translate "Вернуться на главную" %}
</a>
</div>
</div>
{% endblock %}

View File

@@ -11,8 +11,43 @@
<div class="text-align-center fw-700 font-large c-txt-b2 m-a w-80 m-t-8p">
{% blocktranslate %}
Упс... <span class="orange-text">Ничего не найдено</span>, попробуйте
изменить параметры поиска
изменить параметры поиска <span class="orange-text"> или создайте своё собственное объявление, чтобы все могли найти
{% endblocktranslate %}
{% if owner_type == "mover" %}
{% translate "Отправителя" %}
{% elif owner_type == "customer" %}
{% translate "Перевозчика" %}
{% endif %}
</span>
{% if user.is_authenticated %}
<a
id="create_route"
{% if owner_type == "mover" %}
href="{% url 'profile_page' 'create_route_for_customer' %}"
{% elif owner_type == "customer" %}
href="{% url 'profile_page' 'create_route_for_mover' %}"
{% endif %}
>
{% translate "Создать объявление" %}
</a>
{% endif %}
{% if not user.is_authenticated %}
<a
id="create_route"
href="{% url "login_profile" %}"
>
{% translate " Войти и Создать объявление" %}
</a>
{% endif %}
</div>
<img class="boxes_not_fond_routes left" src="{% static "/img/boxes_for_not_found_routes/b_1.svg" %}">
<img class="boxes_not_fond_routes right" src="{% static "/img/boxes_for_not_found_routes/b_2.svg" %}">

View File

@@ -13,7 +13,17 @@
{# <h1>Техническая поддержка</h1>#}
{# </div>#}
{% if user.is_staff or staff %}
<div class="menu_buttons curtain left {% if mobile %}{% if not ticket %}open{% else %}close{% endif %}{% else %}open{% endif %}{% if name.ticket %}margin{% endif %}" data-name="<img style='width: 25px;display: block;position: relative;bottom: 0;' src='{% static "/img/svg/users-solid.svg" %}'>">
<div class="menu_buttons curtain left
{% if mobile %}
{% if not ticket %}open
{% else %}close
{% endif %}
{% else %}
open
{% endif %}
{% if name.ticket %}margin{% endif %}"
data-name="<img style='width: 25px;display: block;position: relative;bottom: 0;' src='{% static "/img/svg/users-solid.svg" %}'>"
>
<div class="container_block_list_of_users">
{% include 'blocks/profile/b_list_of_tickets_support_chat.html' %}
</div>

View File

@@ -1,19 +1,11 @@
{% if page.seo_title %}
<title>{{ page.seo_title }}</title>
{% elif page.title %}
<title>{{ page.title }}</title>
{% elif page.name %}
<title>{{ page.name }}</title>
{% endif %}
<title>{{ page.get_title }}</title>
{% if page.seo_description %}
<meta name="description" content="{{ page.seo_description }}"/>
{% elif page.description %}
<meta name="description" content="{{ page.description }}"/>
{% if page.get_description %}
<meta name="description" content="{{ page.get_description }}"/>
{% endif %}
{% if page.seo_keywords %}
<meta name="keywords" content="{{ page.seo_keywords }}"/>
{% elif page.description %}
<meta name="keywords" content="{{ page.description }}"/>
{% elif page.get_description %}
<meta name="keywords" content="{{ page.get_description }}"/>
{% endif %}

18
templates/sw.js Normal file
View File

@@ -0,0 +1,18 @@
// Register event listener for the 'push' event.
self.addEventListener('push', function (event) {
// Retrieve the textual payload from event.data (a PushMessageData object).
// Other formats are supported (ArrayBuffer, Blob, JSON), check out the documentation
// on https://developer.mozilla.org/en-US/docs/Web/API/PushMessageData.
const eventInfo = event.data.text();
const data = JSON.parse(eventInfo);
const head = data.head || 'New Notification 🕺🕺';
const body = data.body || 'This is default content. Your notification didn\'t have one 🙄🙄';
// Keep the service worker alive until the notification is created.
event.waitUntil(
self.registration.showNotification(head, {
body: body,
icon: 'static/img/svg/Logo.svg'
})
);
});

View File

@@ -8,6 +8,8 @@
{# <meta name="viewport" content="width=100%,maximum-scale=5,minimum-scale=1,initial-scale=1">#}
<meta name="viewport" content="width=device-width,maximum-scale=1,minimum-scale=1,initial-scale=1">
<meta name="vapid-key" content="{{ vapid_key }}">
{% include "inter/meta_names.html" %}
{# <script src='{% static "js/jquery_v3_6_4.js" %}'> </script>#}
@@ -15,6 +17,7 @@
<script type="text/javascript" src="{% static "js/moment_js.js" %}"></script>
<script type="text/javascript" src="{% static "js/moment-with-locales.js" %}"></script>
<script type="text/javascript" src="{% static "js/datarangepicker.js" %}"></script>
<script type="text/javascript" src="{% static "js/push/registerSw.js" %}"></script>
<script src="{% static "js/rangecalendartech.js" %}"></script>
<link rel="stylesheet" href="{% static 'css/datarangepicker.css' %}" />
@@ -56,6 +59,7 @@
</head>
<body{% if page_type == 'routes' %} onscroll="scroll_ev(event,this)"{% endif %}>
{% if page_type != 'routes' %}
<script>
let body = document.querySelector("body")
@@ -103,7 +107,7 @@
</div>
</div>
{% endif %}
<div class="wrapper_content {% if page.url == 'customer_service'%} m_h_0 {% elif page.url == 'contacts' %}m_h_0{% endif %}">
<div class="wrapper_content {% if page.url == 'customer_service'%} m_h_0 {% elif page.url == 'contacts' %}m_h_0{% elif request.path == '/test_404' %}m_h_0{% endif %}">
{% block content %}
{% endblock %}