22 Commits

Author SHA1 Message Date
Philip
15c9d589fe serializer 2024-03-05 20:06:38 +03:00
Philip
fa116c08c1 fix task 2024-03-05 13:47:36 +03:00
Philip
4f9129e718 sample 2024-02-28 14:10:20 +03:00
Philip
df45f3a704 not found 2024-02-25 13:41:26 +03:00
Philip
90ef093fca supscriptions 2024-02-24 19:54:57 +03:00
4331b26542 0.1.362 fix language bug redirect to main page 2024-02-22 18:54:15 +03:00
SDE
dd8a8ddd53 0.12.26 get_phone_valid_error change 2024-02-21 17:12:45 +03:00
SBD
abb0d488eb 14 2024-02-21 15:10:34 +03:00
SBD
be97b848d0 14 2024-02-21 14:56:25 +03:00
SBD
6bc112d689 13 2024-02-21 14:37:31 +03:00
SBD
dc534a0c51 12 2024-02-21 14:21:48 +03:00
SDE
e71ed05e6c 0.12.25 timezone in chat messages 2024-02-21 14:12:03 +03:00
SBD
2048ed6baf 11 2024-02-20 19:31:10 +03:00
SBD
c146bd6155 10 2024-02-20 18:57:17 +03:00
SBD
98665abf4d 9 2024-02-20 18:27:36 +03:00
SBD
9954140d3a 9 2024-02-20 17:43:08 +03:00
SBD
fafee63a64 7 2024-02-20 17:35:01 +03:00
c623d69767 0.1.361 comment red marker on mobile_header temp 2024-02-12 17:22:24 +03:00
670eb28bc0 0.1.360 add red marker on mobile_header temp 2024-02-12 17:17:21 +03:00
144ff286f6 0.1.359 add red marker on mobile_header temp 2024-02-12 17:12:44 +03:00
05f94de0b4 Merge remote-tracking branch 'origin/main' 2024-02-12 16:09:24 +03:00
c4650ce603 0.1.358 upd profile_button width 2024-02-12 16:09:13 +03:00
24 changed files with 294 additions and 34 deletions

1
.gitignore vendored
View File

@@ -414,4 +414,5 @@ fabric.properties
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
celerybeat-schedule.db

View File

@@ -90,5 +90,7 @@ def get_profile_support_page_content_html(request, data=None):
}
tpl_name = 'blocks/profile/b_support_tickets.html'
Dict.update(get_user_timezone_Dict(request.user, request=request))
html = render_to_string(tpl_name, Dict, request=request)
return html

View File

@@ -3,7 +3,7 @@ from django.utils.safestring import mark_safe
def get_phone_valid_error(val):
allow_chars = '01234567890()+ -'
error_msg = mark_safe(_('Некорректные символы в номере телефона,<br> пример корректного ввода +7 925 8600100'))
error_msg = mark_safe(_('Некорректные символы в номере, введите номер в международном формате с кодом страны'))
if not val:
return None

View File

@@ -124,6 +124,7 @@ def update_chat_ajax2(request):
# формируем правую панель
context_Dict.update({'receivers': receivers})
users_list_html = render_to_string(
'blocks/profile/b_list_of_users_messenger.html', context_Dict, request=request)
res_Dict.update({
@@ -203,6 +204,8 @@ def update_chat_ajax(request):
context_Dict.update({'messages': msgs})
context_Dict = get_ticketsDict_for_staff(request.user)
context_Dict.update(get_user_timezone_Dict(request.user))
tickets_list_html = render_to_string(
'blocks/profile/b_list_of_tickets_support_chat.html', context_Dict, request=request)
res_Dict.update({
@@ -222,6 +225,8 @@ def update_chat_ajax(request):
required_beep = True
context_Dict.update({'receivers': receivers})
context_Dict.update(get_user_timezone_Dict(request.user))
users_list_html = render_to_string(
'blocks/profile/b_list_of_users_messenger.html', context_Dict, request=request)
res_Dict.update({
@@ -410,8 +415,10 @@ def support_show_chat_by_ticket_ajax(request):
}
Dict.update(get_ticketsDict_for_staff(request.user))
tpl_name = 'blocks/profile/b_support_chat.html'
Dict.update(get_user_timezone_Dict(request.user))
tpl_name = 'blocks/profile/b_support_chat.html'
Dict.update(get_user_timezone_Dict(request.user, request=request))
html = render_to_string(tpl_name, Dict, request=request)
return JsonResponse({'html': html}, status=200)
@@ -431,6 +438,9 @@ def support_create_ticket_form_ajax(request):
Dict = {
'form': TicketForm()
}
Dict.update(get_user_timezone_Dict(request.user))
tpl_name = 'blocks/profile/b_create_ticket.html'
html = render_to_string(tpl_name, Dict, request=request)
@@ -452,6 +462,8 @@ def create_ticket_ajax(request):
if not form.is_valid():
form.initial = form.cleaned_data
Dict = {'form': form}
Dict.update(get_user_timezone_Dict(request.user))
html = render_to_string('blocks/profile/b_create_ticket.html', Dict, request=request)
return JsonResponse({'html': html}, status=400)
@@ -492,6 +504,8 @@ def create_ticket_ajax(request):
'messages': msgs_for_ticket
}
Dict.update(get_user_timezone_Dict(request.user))
html = render_to_string('blocks/profile/b_support_chat.html', Dict, request=request)
res_Dict = {
@@ -502,9 +516,11 @@ def create_ticket_ajax(request):
except Exception as e:
msg = f'{_("ошибка в запросе")} = {str(e)}'
errors_Dict = {
'errors': {
'all__': f'{_("ошибка в запросе")} = {str(e)}'
'all__': msg
}
}
Dict = {'form': errors_Dict}

3
README.md Normal file
View File

@@ -0,0 +1,3 @@
celery -A TWB.celery:app worker -l info
celery -A TWB.celery:app beat -l info

View File

@@ -0,0 +1,7 @@
from rest_framework import serializers
class SubscribersSerializer(serializers.Serializer):
email = serializers.EmailField(error_messages={'invalid': 'Invalid email'})
email_notification = serializers.BooleanField()
auto_subscribe = serializers.BooleanField()

9
SubscribesApp/urls.py Normal file
View File

@@ -0,0 +1,9 @@
from django.urls import path
from SubscribesApp.views import SubscribersView
urlpatterns = [
path('auto-subscribe/', SubscribersView.as_view(), name='auto_subscribe'),
]

View File

@@ -1,3 +1,43 @@
from django.shortcuts import render
from django.contrib.auth.models import User
from django.http import JsonResponse
from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView
# Create your views here.
from SubscribesApp.models import SubscribeForUser
from SubscribesApp.serializers import SubscribersSerializer
class SubscribersView(APIView):
# permission_classes = [IsAuthenticated]
def post(self, request):
serializer = SubscribersSerializer(data=request.data)
if serializer.is_valid():
validated_data = serializer.validated_data
email = validated_data['email']
email_notification = validated_data['email_notification']
auto_subscribe = validated_data['auto_subscribe']
user = User.objects.filter(email=email)
if user:
subscribe_for_user = SubscribeForUser.objects.filter(user_id=user[0].id)
if email_notification:
subscribe_for_user.update(receive_finish_subscribe_msg=True)
else:
subscribe_for_user.update(receive_finish_subscribe_msg=False)
if auto_subscribe:
subscribe_for_user.update(auto_continue=True)
else:
subscribe_for_user.update(auto_continue=False)
return JsonResponse({"message": "Subscriptions updated successfully"}, status=status.HTTP_200_OK)
else:
return JsonResponse({"message": "User not found"}, status=status.HTTP_404_NOT_FOUND)
else:
return JsonResponse(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

27
TWB/celery.py Executable file
View File

@@ -0,0 +1,27 @@
from __future__ import absolute_import
import os
from celery import Celery
from celery.schedules import crontab
from django.conf import settings
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "TWB.settings")
app = Celery('bo', include=['TWB.tasks'])
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
app.conf.beat_schedule = {
'update-currency-rates': {
'task': 'TWB.tasks.check_auto_subscribe',
'schedule': crontab(minute=0, hour='*/1'),
},
'subscription_expiration_check': {
'task': 'TWB.tasks.subscription_expiration_check',
'schedule': crontab(hour=0, minute=0),
# 'schedule': crontab(minute='*', hour='*'),
},
}
app.conf.broker_url = settings.CELERY_BROKER_URL

View File

@@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/4.2/ref/settings/
"""
from pathlib import Path
from decouple import config
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
@@ -60,7 +61,6 @@ AUTHENTICATION_BACKENDS = [
]
SOCIALACCOUNT_PROVIDERS = {
'google': {
'SCOPE': [
@@ -172,11 +172,8 @@ CHANNEL_LAYERS = {
}
POSTGRES_DB = config('POSTGRES_DB')
POSTGRES_USER = config('POSTGRES_USER')
# Database
@@ -185,8 +182,8 @@ CHANNEL_LAYERS = {
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'twbDB',
'USER': 'test_user',
'NAME': POSTGRES_DB,
'USER': POSTGRES_USER,
'PASSWORD': 'test_db_pass',
'HOST': '127.0.0.1',
'PORT': '5432',
@@ -336,6 +333,16 @@ CKEDITOR_CONFIGS = {
}
}
CELERY_BROKER_URL = config('CELERY_BROKER_URL')
CELERY_RESULT_BACKEND = config('CELERY_RESULT_BACKEND')
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_USE_TLS = True
EMAIL_PORT = 587
EMAIL_HOST_USER = config('EMAIL_HOST_USER')
EMAIL_HOST_PASSWORD = config('EMAIL_HOST_PASSWORD')
# CKEDITOR_OPTIONS = {
# 'height': 291,

40
TWB/tasks.py Normal file
View File

@@ -0,0 +1,40 @@
from datetime import datetime, timedelta, timezone
from SubscribesApp.models import SubscribeForUser
from TWB import settings
from TWB.celery import app
from django.core.mail import send_mail
@app.task
def check_auto_subscribe():
current_time = datetime.now()
subscribes = SubscribeForUser.objects.filter(auto_continue=True)
if subscribes:
for subscribe in subscribes:
if subscribe.paid_period_to_DT and subscribe.paid_period_to_DT <= current_time + timedelta(hours=1):
user_email = subscribe.user.email
subject = 'Подписка продлена!'
message = 'Ваша подписка успешно продлена!'
send_mail(subject, message, settings.EMAIL_HOST_USER, [user_email], fail_silently=False)
else:
print('Нету подписок')
@app.task
def subscription_expiration_check():
current_time = datetime.now()
subscribes = SubscribeForUser.objects.filter(paid_period_to_DT__gte=current_time)
if subscribes:
for subscribe in subscribes:
expiration_date = subscribe.paid_period_to_DT
remaining_days = (expiration_date - current_time).days
if remaining_days <= 7:
message = f'Ваша подписка заканчивается через {remaining_days} дня. Пожалуйста, продлите её.'
user_email = subscribe.user.email
subject = 'Подписка истекает!'
send_mail(subject, message, settings.EMAIL_HOST_USER, [user_email], fail_silently=False)
else:
print('Нету подписок')

View File

@@ -1,4 +1,3 @@
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
@@ -9,7 +8,6 @@ from AuthApp.views import login_View
handler404 = Page404
urlpatterns = [
# path('admin/', admin.site.urls),
path('ckeditor/', include('ckeditor_uploader.urls')),
path('i18n/', include('django.conf.urls.i18n')),
@@ -39,7 +37,9 @@ urlpatterns = [
path('test_404', Page404, name='page_404'),
path('', include('PushMessages.urls'))
path('', include('PushMessages.urls')),
path('', include('SubscribesApp.urls')),
]
from django.conf.urls.i18n import i18n_patterns

8
env.sample Normal file
View File

@@ -0,0 +1,8 @@
EMAIL_HOST_USER=
EMAIL_HOST_PASSWORD=
POSTGRES_DB=
POSTGRES_USER=
CELERY_BROKER_URL=
CELERY_RESULT_BACKEND=

View File

@@ -2,7 +2,6 @@ Django==4.2.2
django-ckeditor==6.5.1
psycopg2-binary==2.9.6
requests
Pillow==9.5.0
django-modeltranslation==0.18.10
overpass
geopy
@@ -13,5 +12,6 @@ django-colorfield
django-webpush==0.3.5
django-allauth==0.60.0
pytz==2024.1
#django-tz-detect==0.4.0
celery==5.3.6
djangorestframework==3.14.0
python-decouple==3.8

View File

@@ -1634,6 +1634,25 @@
}
@media (max-width: 800px) {
.marker_messages_mobile{
position: absolute;
top: 0;
right: 0;
border-radius: 100%;
background: #ff0000;
height: 14px;
width: 15px;
}
.marker_messages_mobile.hide{
display: none;
}
.marker_messages_mobile.show{
display: block;
}
}
@media (max-width: 828px){
/*.to_address_point_txt.find_route {*/
/*width: 54.6%;*/
@@ -1694,6 +1713,7 @@
}
@media (max-width: 699px){
.block-chat.support {
/*height: calc(100vh - 190px);*/
/*1. 100svh 2. 45px - header 3. name_ticket 4. just padding */

View File

@@ -2131,7 +2131,7 @@ a.open_inf_carrier{
.button_profile_header{
height: 50px;
width: 150px;
width: 155px;
background: #FF613A;
color: #FFF;
/* Heading 5 */

View File

@@ -39,6 +39,16 @@ function wsReceiveData (e) {
console.log(data)
} else if (data.type === "update_chat") {
let msg_cont = document.querySelector(".container-messages")
if (getInfoAboutUser('screen_width') < 800){
if (!window.location.href.includes("chat") && !window.location.href.includes("support")){
let marker_new_messages = document.querySelector(".marker_messages_mobile");
if (marker_new_messages.classList.contains('hide')){
marker_new_messages.classList.add('show')
marker_new_messages.classList.remove('hide')
}
setCokie(365,'twb_new_messages',true)
}
}
update_chat_html(data,msg_cont)
// document.querySelector(".tab_user_messanger.select").scrollIntoView({behavior: "smooth",block:'end',inline:'end'});
@@ -99,14 +109,25 @@ function wsReceiveData (e) {
}
// }
// if
update_list_w_users(data,old_item_tab_user,el_tab)
if (window.location.href.includes("chat")){
update_list_w_users(data,old_item_tab_user,el_tab)
}
} else if (data.type === "update_support_chat"){
update_support_chat_func(data,msg_cont)
}
if (data.unread_msgs_count > 0){
if (getInfoAboutUser('screen_width') < 800){
if (!window.location.href.includes("chat") && !window.location.href.includes("support")){
let marker_new_messages = document.querySelector(".marker_messages_mobile");
if (marker_new_messages.classList.contains('hide')){
marker_new_messages.classList.add('show')
marker_new_messages.classList.remove('hide')
}
setCokie(365,'twb_new_messages',true)
}
}
update_count_unread_messages(data)
}
if (data.required_beep === true) {

View File

@@ -1,4 +1,5 @@
$(document).ready(function (){
hide_or_show_new_messages_marker()
checkStateCookie()
})
@@ -12,6 +13,7 @@ window.onload = function (){
openOrCloseCurtainSupportChat()
openOverlayOrClose()
goToChatIfChat()
// let body = document.querySelector("body")
// const viewPortH = body.getBoundingClientRect().height;
// const windowH = window.innerHeight;
@@ -43,6 +45,14 @@ window.onload = function (){
}
}
}
function hide_or_show_new_messages_marker () {
if (getInfoAboutUser('screen_width') < 800){
if (window.location.href.includes("chat") || window.location.href.includes("support")){
setCokie(365,'twb_new_messages','false')
}
}
}
//
function goToChatIfChat () {
if (document.querySelector('.block-chat')){
@@ -132,7 +142,7 @@ function getTypeOfData (data) {
}
function getInfoAboutUser (){
function getInfoAboutUser (screen_width){
let user_type = ''
if (screen.width <= 700){
user_type = 'mobile'
@@ -141,7 +151,11 @@ function getInfoAboutUser (){
} else if (screen.width > 700 && screen.width <= 1180) {
user_type = 'laptop'
}
return user_type
if (screen_width){
return screen.width
} else {
return user_type
}
}
document.addEventListener('DOMContentLoaded', function() {
@@ -213,6 +227,23 @@ function checkStateCookie () {
if (!window.document.cookie.includes("allow_cookie=true")){
document.querySelector(".cookie_block").classList.add("show")
}
if (window.document.cookie.includes("twb_new_messages=true")){
if (getInfoAboutUser('screen_width') < 800) {
let marker_new_messages = document.querySelector(".marker_messages_mobile");
if (marker_new_messages.classList.contains('hide')) {
marker_new_messages.classList.remove('hide')
marker_new_messages.classList.add('show')
}
}
} else if (window.document.cookie.includes("twb_new_messages=false")){
if (getInfoAboutUser('screen_width') < 800) {
let marker_new_messages = document.querySelector(".marker_messages_mobile");
if (marker_new_messages.classList.contains('show')) {
marker_new_messages.classList.add('hide')
marker_new_messages.classList.remove('show')
}
}
}
}
function getCsrfCookie () {
@@ -227,11 +258,15 @@ function getCsrfCookie () {
return csrf
}
function setCokie () {
function setCokie (days,name,val) {
let date = new Date();
let days = 182;
// let days = 182;
date.setTime(+ date + (days * 86400000));
window.document.cookie = "allow_cookie=true" + "; expires=" + date.toGMTString() + "; path=/";
window.document.cookie = `${name}=${val}` + "; expires=" + date.toGMTString() + "; path=/";
document.querySelector(".cookie_block").classList.remove("show")
return value;
// return value;
}
function getInCookieTime (time) {
return time * 24 * 60 * 60
}

View File

@@ -86,6 +86,16 @@ function select_tab_profile (el,url,owner_type=null) {
deleteMarkerMessages(el)
checkStatesAfterTransitionToAnotherTabProfile()
goToChatIfChat()
if (window.location.href.includes("chat") || window.location.href.includes("support")) {
if (getInfoAboutUser('screen_width') < 800) {
let marker_new_messages = document.querySelector(".marker_messages_mobile");
if (marker_new_messages.classList.contains('show')) {
marker_new_messages.classList.remove('show')
marker_new_messages.classList.add('hide')
}
}
}
setCokie(365,'twb_new_messages','false')
},
error: function (data){
console.log(data)

View File

@@ -6,10 +6,13 @@
<div class="wrapper_header_content">
<div class="header-first">
<div class="header_logo">
<a href="/"><img class="svg" src="/static/img/svg/Logo.svg"></a>
<a href="{% url 'main' %}">
<img class="svg" src="/static/img/svg/Logo.svg">
</a>
</div>
<div class="header_logo_mobile">
<a href="/"><img class="svg" src="/static/img/svg/LogoMobile.svg"></a>
{# <a href="/"><img class="svg" src="/static/img/svg/LogoMobile.svg"></a>#}
<a href="{% url 'main' %}"><img class="svg" src="/static/img/svg/LogoMobile.svg"></a>
</div>
<div class="dropdown">
@@ -76,7 +79,12 @@
</div>
</div>
<div class="button_profile_header_mobile" onclick="open_curtain_w_btn_profile()">
<div class="marker_messages_mobile hide"></div>
<img src="/static/img/svg/userMobile.svg" alt="">
{# <div class="icon_unread_messages" style="position:absolute;right: 5px;top: 0;">#}
{# <div class="cost-messages-in-user-tab-messenger" style="background: #ff0000;">#}
{# </div>#}
{# </div>#}
</div>
{# <div class="menu_profile_btn">#}
{# {% if user_subscribe %}<div class="subscribe_type_txt"><span class="f-l">Подписка:</span> <span class="f-r">{{ user_subscribe.subscribe.name }}</span><div class="clear_both"></div></div>{% endif %}#}
@@ -110,6 +118,7 @@
<div class="button_profile_header_mobile" onclick="show_header_list()">
<div class="marker_messages_mobile hide"></div>
<img src="/static/img/svg/userMobile.svg" alt="">
</div>

View File

@@ -6,7 +6,7 @@
{%trans "Тема запроса" as p_create_ticket %}
<form class="form-create-ticket" name="create-ticket">
{% if errors.all__ %}<div class="errors_all" style="margin-bottom: 12px;width: 100%;font-size: 16px;">{{ errors.all__ }}</div>{% endif %}
{% if form.errors.all__ %}<div class="errors_all" style="margin-bottom: 12px;width: 100%;font-size: 16px;">{{ form.errors.all__ }}</div>{% endif %}
{% csrf_token %}
<div class="container-input-form-create-ticket">

View File

@@ -24,6 +24,7 @@
<script src="{% static "js/global_js.js" %}"></script>
<script src="{% static "js/chat_socket_start.js" %}"></script>
{% if user and not user.is_anonymous %}
{% include "connect_ws_js.html" %}
<script src='{% static "js/chat_sockets.js" %}'></script>
<script>
@@ -71,7 +72,7 @@
<div class="txt_cookie">Сайт использует файлы cookie. Просматривая этот сайт, Вы соглашаетесь
<a class="a_cookie" href="#">с условиями использования cookie-файлов</a>
</div>
<button class="cookie_btn" onclick="setCokie()">Понятно</button>
<button class="cookie_btn" onclick="setCokie(182,'allow_cookie','true')">Понятно</button>
</div>
</div>

View File

@@ -11,7 +11,9 @@
</div>
{% if item.unread_msgs_count %}
<div class="right-part-tab-user">
<div class="cost-messages-in-user-tab-messenger"><span>{{ item.unread_msgs_count }}</span></div>
<div class="cost-messages-in-user-tab-messenger">
{# <span>{{ item.unread_msgs_count }}</span>#}
</div>
</div>
{% endif %}
</div>

View File

@@ -11,7 +11,9 @@
</div>
{% if item.unread_msgs_count %}
<div class="right-part-tab-user">
<div class="cost-messages-in-user-tab-messenger"><span>{{ item.unread_msgs_count }}</span></div>
<div class="cost-messages-in-user-tab-messenger">
{# <span>{{ item.unread_msgs_count }}</span>#}
</div>
</div>
{% endif %}
</div>