5 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
312 changed files with 1817 additions and 17660 deletions

5
.gitignore vendored
View File

@@ -414,8 +414,5 @@ fabric.properties
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
# packages for node
package.json
package-lock.json
celerybeat-schedule.db

View File

@@ -21,9 +21,6 @@ def get_articles_block_ajax(request):
if request.method != 'POST':
raise Http404
from GeneralApp.funcs import get_and_set_lang
lang = get_and_set_lang(request)
try:
data = request.POST.dict()
@@ -45,9 +42,6 @@ def get_articles_block_ajax(request):
# 'form': RouteForm(initial=data)
}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
except Exception as e:

View File

@@ -6,7 +6,7 @@ from datetime import datetime, date
from django.http import Http404, HttpResponse
from django.template import loader
from .funcs import *
from GeneralApp.funcs import get_inter_http_response
from GeneralApp.funcs import get_inter_http_respose
from django.utils.translation import gettext_lazy as _
# from django.contrib.auth.decorators import login_required
@@ -85,14 +85,14 @@ def ArticlesPageView(request, year=None):
Dict = get_articles(art_kwargs=kwargs)
Dict.update({
'page': {
'title': _('Новости сервиса доставки посылок | TripWB'),
'description': _('Обновления, полезные статьи и свежие новости от TripWB ✓ Актуальные новости в мире доставок по всему СНГ ➡️ Следите за нашими новостями'),
'title': _('Страница списка новостей'),
'description': _('Все новости сайта tripwb.com'),
'keywords': _('Все новости сайта tripwb.com'),
}
})
t = loader.get_template('pages/p_articles.html')
return get_inter_http_response(t, Dict, request)
return get_inter_http_respose(t, Dict, request)
# return HttpResponse(t.render(Dict, request))
@@ -125,7 +125,7 @@ def UserPageView(request, page_url):
t = loader.get_template('pages/p_user_page.html')
return get_inter_http_response(t, Dict, request)
return get_inter_http_respose(t, Dict, request)
# return HttpResponse(t.render(Dict, request))
@@ -155,5 +155,5 @@ def ArticlesOnePageView(request, art_url):
t = loader.get_template('pages/p_article.html')
return get_inter_http_response(t, Dict, request)
return get_inter_http_respose(t, Dict, request)
# return HttpResponse(t.render(Dict, request))

View File

@@ -97,14 +97,12 @@ class Admin_User(UserAdmin):
save_on_top = True
list_display = ['id', 'last_name', 'first_name', 'mailing_on', 'email', 'is_staff',
'is_active', 'date_joined', 'last_login']
'is_active']
list_editable = ['is_staff', 'is_active']
list_display_links = ['first_name', 'last_name', 'email']
search_fields = ['first_name', 'last_name', 'email']
readonly_fields = ['date_joined', 'last_login']
list_filter = ['user_profile__mailing_on', 'is_staff', 'is_active', 'date_joined', 'last_login']
list_filter = ['user_profile__mailing_on', 'is_staff', 'is_active']
inlines = (Admin_ProfileInline,)
# actions = ['del_all_temp_users', ]

View File

@@ -26,7 +26,7 @@ class RegistrationForm(forms.Form):
email = forms.EmailField()
password = forms.CharField(widget=forms.PasswordInput())
confirm_password = forms.CharField(widget=forms.PasswordInput())
tel = forms.CharField(required=False)
tel = forms.CharField()
agreement = forms.BooleanField(initial=False, required=True)
def __init__(self, *args, **kwargs):

View File

@@ -1,6 +1,4 @@
from django.http import QueryDict
from django.template.loader import render_to_string
from SubscribesApp.funcs import check_option_in_cur_user_subscribe
def get_user_timezone_Dict(user, request=None):
@@ -32,12 +30,10 @@ def get_profile_page_content_html(request, page_name, data):
if page_name == 'chat':
from ChatServiceApp.funcs import get_chat_page_content_html
return get_chat_page_content_html(request, data)
elif (page_name == 'create_route_for_customer' and
check_option_in_cur_user_subscribe(request.user, 'размещение заявок')):
elif page_name == 'create_route_for_customer':
from RoutesApp.funcs import get_profile_new_route_page_html
return get_profile_new_route_page_html(request, {'owner_type': 'customer'})
elif (page_name == 'create_route_for_mover' and
check_option_in_cur_user_subscribe(request.user, 'размещение заявок')):
elif page_name == 'create_route_for_mover':
from RoutesApp.funcs import get_profile_new_route_page_html
return get_profile_new_route_page_html(request, {'owner_type': 'mover'})
elif page_name == 'my_routes':
@@ -46,9 +42,8 @@ def get_profile_page_content_html(request, page_name, data):
elif page_name == 'support':
return get_profile_support_page_content_html(request, data)
elif page_name == 'my_subscribe':
from SubscribesApp.funcs import get_profile_subscribe_page_content_Dict
res = get_profile_subscribe_page_content_Dict(request, check_orders_required=True)
return res['html']
from SubscribesApp.funcs import get_profile_subscribe_page_content_html
return get_profile_subscribe_page_content_html(request)
elif page_name == 'change_profile':
return get_profile_change_page_content_html(request)
elif page_name == 'dashboard':
@@ -57,7 +52,7 @@ def get_profile_page_content_html(request, page_name, data):
return None
def get_profile_change_page_content_html(request, data=None):
def get_profile_change_page_content_html(request):
init_Dict = {
'firstname': request.user.first_name,
@@ -67,25 +62,6 @@ def get_profile_change_page_content_html(request, data=None):
'country': request.user.user_profile.country,
'city': request.user.user_profile.city,
}
if data:
if type(data) == QueryDict:
data = data.dict()
init_Dict.update(data)
# if 'firstname' in data:
# init_Dict.update({'first_name': data['firstname']})
# if 'lastname' in data:
# init_Dict.update({'last_name': data['lastname']})
# if 'email' in data:
# init_Dict.update({'email': data['email']})
# init_Dict.update({'username': data['email']})
# if 'country' in data:
# init_Dict.update({'country': data['country']})
# if 'city' in data:
# init_Dict.update({'city': data['city']})
# if 'tel' in data:
# init_Dict.update({'tel': data['tel']})
from .forms import RegistrationForm
form = RegistrationForm(initial=init_Dict)

View File

@@ -23,8 +23,6 @@ urlpatterns = [
path('support_tickets/', support_tickets_ajax, name='support_tickets_ajax'),
path('password_recovery/', password_recovery_ajax, name='password_recovery_ajax'),
path('password_recovery_confirm/', password_recovery_confirm_ajax, name='password_recovery_confirm_ajax'),
path('change_profile/', change_profile_ajax, name='change_profile_ajax'),
path('change_profile_confirm/', change_profile_confirm_ajax, name='change_profile_confirm_ajax'),

View File

@@ -18,9 +18,9 @@ from django.core.files import File
import base64
from django.core.validators import validate_email
from django.urls import reverse
from GeneralApp.funcs import get_and_set_lang
# @login_required()#login_url='/profile/login/')
# @login_required(login_url='/profile/login/')
# def subscribe_ajax(request):
# if request.method != 'POST':
# raise Http404
@@ -31,132 +31,11 @@ from GeneralApp.funcs import get_and_set_lang
# html = render_to_string('blocks/profile/b_subscribe.html', Dict, request=request)
# return JsonResponse({'html': html}, status=200)
def password_recovery_confirm_ajax(request):
if request.method != 'POST':
raise Http404
if not 'pass' in request.POST or not 'pass_confirm' in request.POST or not 'user_id' in request.POST:
raise Http404
lang = get_and_set_lang(request)
try:
if not request.POST['pass'] or request.POST['pass'] != request.POST['pass_confirm']:
return JsonResponse({
'status': 'error',
'error': _('Пароли не совпадают')
}, status=400)
user = User.objects.get(id=request.POST['user_id'])
user.set_password(request.POST['pass'])
user.user_profile.authMailCode = None
user.user_profile.save(update_fields=['authMailCode'])
user.is_active = True
user.save()
return JsonResponse({
'status': 'success',
'message': _('Пароль был успешно изменен')
})
except Exception as e:
return JsonResponse({
'status': 'error',
'error': str(e)
}, status=400)
def password_recovery_ajax(request):
if request.method != 'POST':
raise Http404
lang = get_and_set_lang(request)
try:
email = request.POST['email']
try:
user = User.objects.get(email=email)
except User.DoesNotExist:
msg = _('Пользователь с указанным email не зарегистрирован на сайте')
return JsonResponse({
'status': 'error',
'error': msg
}, status=400)
user.user_profile.authMailCode = uuid1().hex
user.user_profile.save(update_fields=['authMailCode'])
from GeneralApp.funcs_options import get_options_by_opt_types, get_mail_send_options
sets = get_options_by_opt_types(['domain', 'project_name'], only_vals=True)
subject = _('Изменение пароля учетной записи на сайте tripwb.com')
mail_txt = _('Вы получили это письмо потому что '
'был произведен запрос на изменение пароля '
'для данного email на сайте tripwb.com.<br>'
'<br>'
'Если Вы не выполняли запрос - просто проигнорируйте это письмо.<br><br>'
'Если же это были Вы и Вам требуется изменить пароль от учетной записи - '
'перейдите по ссылке, указанной ниже.<br><br>')
link = sets["domain"] + f'/profile/reset_password/{str(user.id)}/{user.user_profile.authMailCode}/'
link_str = f'<a href="{link}">ИЗМЕНИТЬ ПАРОЛЬ</a><br><br>'
sign_txt = _('Спасибо за то, что вы с нами!<br>'
'С уважением,<br>'
'Команда Trip With Bonus.<br>')
Dict = {
'logo': f'{sets["domain"]}/static/img/svg/LogoMobile.svg',
'project_name': sets['project_name'],
'message_title': subject,
'message_text': f'<p style="padding-left: 20px; line-height: 30px;">'
f'{mail_txt}'
f'{link_str}'
f'{sign_txt}'
f'</p>'
}
html = render_to_string('mail/m_request_offer.html', Dict, request)
from BaseModels.mailSender import admin_send_mail_by_SMTPlib
mail_sets = get_mail_send_options()
to = [email]
res = admin_send_mail_by_SMTPlib(
mail_sets,
subject=subject,
from_email=mail_sets['sender_email'], to=to,
html_content=html
)
to = ['web@syncsystems.net']
res = admin_send_mail_by_SMTPlib(
mail_sets,
subject=subject,
from_email=mail_sets['sender_email'], to=to,
html_content=html
)
return JsonResponse({
'status': 'sended',
'message': _('На email') + ' ' + email + ' '
+ _('отправлено письмо с инструкциями для восстановления пароля. Если не пришло письмо, проверьте папку СПАМ')
})
except Exception as e:
return JsonResponse({
'status': 'error',
'error': str(e)
}, status=400)
def mailing_subscribe_ajax(request):
if request.method != 'POST':
raise Http404
lang = get_and_set_lang(request)
try:
email = request.POST['email']
@@ -166,13 +45,11 @@ def mailing_subscribe_ajax(request):
user.user_profile.mailing_on = True
user.user_profile.save(update_fields=['mailing_on'])
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict = {
return JsonResponse({
'status': 'sended',
'del_form': True,
'html': _('Подписка на рассылку для адреса ') + user.email + _(' одобрена')
}
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
})
if not user:
try:
@@ -185,14 +62,11 @@ def mailing_subscribe_ajax(request):
else:
redirect_url = f"{reverse('registration_page')}?mailingSubscribeRequired=true"
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict = {
return JsonResponse({
'status': 'sended',
'redirect_url': redirect_url,
'email': email
}
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
})
except Exception as e:
@@ -203,13 +77,9 @@ def mailing_subscribe_ajax(request):
def send_message_ajax(request):
print('send_message_ajax')
if request.method != 'POST':
raise Http404
lang = get_and_set_lang(request)
try:
data = request.POST
@@ -313,25 +183,10 @@ def send_message_ajax(request):
f'</p>'
}
print('render html for mail')
html = render_to_string('mail/m_request_offer.html', Dict, request)
from BaseModels.mailSender import admin_send_mail_by_SMTPlib
mail_sets = get_mail_send_options()
opts = get_options_by_opt_types('support_email', only_vals=True)
print(f'options: {str(opts)}')
if opts and 'support_email' in opts:
to = [opts['support_email']]
else:
to = [mail_sets['sender_email']]
print(f'to: {str(to)}')
res = admin_send_mail_by_SMTPlib(
mail_sets,
subject=subject,
from_email=mail_sets['sender_email'], to=to,
html_content=html
)
to = ['web@syncsystems.net']
to = [mail_sets['sender_email'], 'web@syncsystems.net']
res = admin_send_mail_by_SMTPlib(
mail_sets,
subject=subject,
@@ -341,14 +196,10 @@ def send_message_ajax(request):
html = render_to_string('widgets/w_msg_send_success.html', Dict, request)
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict = {
return JsonResponse({
'status': 'sended',
'html': html
}
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
})
except Exception as e:
return JsonResponse({
'status': 'error',
@@ -356,13 +207,11 @@ def send_message_ajax(request):
}, status=400)
@login_required()#login_url='/profile/login/')
@login_required(login_url='/profile/login/')
def chats_ajax(request):
if request.method != 'POST':
raise Http404
lang = get_and_set_lang(request)
from ChatServiceApp.funcs import get_chat_receivers_for_user, get_msgs_for_chat_w_users
receivers, unread_msgs_count = get_chat_receivers_for_user(request.user)
@@ -386,28 +235,19 @@ def chats_ajax(request):
Dict.update(get_user_timezone_Dict(request.user, request=request))
html = render_to_string('blocks/profile/b_chats.html', Dict, request=request)
return JsonResponse({'html': html}, status=200)
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict = {'html': html}
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
@login_required()#login_url='/profile/login/')
@login_required(login_url='/profile/login/')
def support_tickets_ajax(request):
if request.method != 'POST':
raise Http404
lang = get_and_set_lang(request)
html = get_profile_support_page_content_html(request)
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict = {'html': html}
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
return JsonResponse({'html': html}, status=200)
@login_required()#login_url='/profile/login/')
@login_required(login_url='/profile/login/')
def change_avatar_confirm_ajax(request):
from django.core.files.base import ContentFile
from django.core.exceptions import RequestDataTooBig
@@ -415,8 +255,6 @@ def change_avatar_confirm_ajax(request):
if request.method != 'POST':
raise Http404
lang = get_and_set_lang(request)
try:
file_data = json.loads(request.body)
@@ -435,19 +273,14 @@ def change_avatar_confirm_ajax(request):
print(msg)
return JsonResponse({'error': msg}, status=400)
res_Dict = {'url': request.user.user_profile.avatar.url}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
return JsonResponse({'url': request.user.user_profile.avatar.url})
@login_required()#login_url='/profile/login/')
@login_required(login_url='/profile/login/')
def change_profile_confirm_ajax(request):
if request.method != 'POST':
raise Http404
lang = get_and_set_lang(request)
data = request.POST
if not data:
data = json.loads(request.body)
@@ -512,20 +345,15 @@ def change_profile_confirm_ajax(request):
if data_for_save:
user_profiles.update(**data_for_save)
html = get_profile_change_page_content_html(request, data)
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict = {'html': html}
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
html = get_profile_change_page_content_html(request)
return JsonResponse({'html': html}, status=200)
@login_required()#login_url='/profile/login/')
@login_required(login_url='/profile/login/')
def dashboard_ajax(request):
if request.method != 'POST':
raise Http404
lang = get_and_set_lang(request)
try:
from .funcs import get_dashboard_page_content_html
@@ -539,32 +367,26 @@ def dashboard_ajax(request):
return JsonResponse({'html': html}, status=200)
@login_required()#login_url='/profile/login/')
@login_required(login_url='/profile/login/')
def change_profile_ajax(request):
if request.method != 'POST':
raise Http404
lang = get_and_set_lang(request)
html = get_profile_change_page_content_html(request)
return JsonResponse({'html': html}, status=200)
@login_required()#login_url='/profile/login/')
@login_required(login_url='/profile/login/')
def my_routes_ajax(request):
if request.method != 'POST':
raise Http404
lang = get_and_set_lang(request)
Dict = {
}
html = render_to_string('blocks/profile/b_my_routes.html', Dict, request=request)
res_Dict = {'html': html}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
return JsonResponse({'html': html}, status=200)
@@ -574,8 +396,6 @@ def login_ajax(request):
if request.method != 'POST':
raise Http404
lang = get_and_set_lang(request)
try:
data = request.POST
@@ -604,16 +424,11 @@ def login_ajax(request):
html = render_to_string('forms/f_login.html', Dict, request=request)
return JsonResponse({'html': html}, status=400)
if not 'HTTP_REFERER' in request.META or not '/?next=/' in request.META['HTTP_REFERER']:
redirect_url = reverse('profile_page', args=['dashboard'])
else:
redirect_url = request.META['HTTP_REFERER'].split('/?next=')[1]
res_Dict = {
'redirect_url': redirect_url
'redirect_url': reverse('profile_page', args=['dashboard'])
}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
except Exception as e:
@@ -629,59 +444,45 @@ def login_ajax(request):
def send_check_email_after_registration(data_Dict, user):
def send_registration_mail(data_Dict, user):
try:
from GeneralApp.funcs_options import get_options_by_opt_types, get_mail_send_options
sets = get_options_by_opt_types(['domain', 'project_name'], only_vals=True)
subject = _('Trip With Bonus - Подтверждение регистрации ')
subject = _('Добро пожаловать в Trip With Bonus!')
Dict = {
'logo': f'{sets["domain"]}/static/img/svg/LogoMobile.svg',
'project_name': sets['project_name'],
'domain': sets['domain'],
'message_title': subject,
}
Dict.update(data_Dict)
html = render_to_string('mail/m_confirm_email.html', Dict)
html = render_to_string('mail/m_registration.html', Dict)
from BaseModels.mailSender import admin_send_mail_by_SMTPlib
mail_sets = get_mail_send_options()
to = [user.email]
to = [user.email, 'web@syncsystems.net', 'sa@a3-global.com', 'sysadmin.hax@gmail.com']
res = admin_send_mail_by_SMTPlib(
mail_sets,
subject=subject,
from_email=mail_sets['sender_email'], to=to,
html_content=html
)
to = ['web@syncsystems.net', 'sa@a3-global.com', 'sysadmin.hax@gmail.com']
admin_send_mail_by_SMTPlib(
mail_sets,
subject=subject,
from_email=mail_sets['sender_email'], to=to,
html_content=html
)
return res
except Exception as e:
print(f'send_registration_mail Error = {str(e)}')
return None
def registration_ajax(request):
if request.method != 'POST':
raise Http404
from GeneralApp.funcs import get_and_set_lang
lang = get_and_set_lang(request)
try:
data = request.POST
@@ -702,34 +503,28 @@ def registration_ajax(request):
user = User.objects.create_user(username=form.data['email'], email=form.data['email'], password=form.data['password'])
# user = auth.authenticate(username=new_user_Dict['name'], password=new_user_Dict['pass'])
# if user:
# auth.login(request, user, backend='django.contrib.auth.backends.ModelBackend')
if user:
auth.login(request, user, backend='django.contrib.auth.backends.ModelBackend')
if 'mailingSubscribeRequired' in data and data['mailingSubscribeRequired'] == 'true':
user.user_profile.mailing_on = True
user.last_name = form.data['lastname']
user.first_name = form.data['firstname']
user.is_active = False
user.save()
user.user_profile.phone = form.data['tel']
user.user_profile.authMailCode = uuid1().hex
user.user_profile.save()
mail_Dict = {
'user': user,
'pass': form.data['password']
}
res = send_check_email_after_registration(mail_Dict, user)
print(str(res))
# res = send_registration_mail(mail_Dict, user)
res = send_registration_mail(mail_Dict, user)
res_Dict = {
# 'redirect_url': reverse('profile_page', args=['dashboard'])
'redirect_url': reverse('profile_page', args=['dashboard'])
}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
except Exception as e:

View File

@@ -16,6 +16,7 @@ from datetime import datetime
def user_name_str(self):
return f'{self.last_name} {self.first_name}'
User.add_to_class("__str__", user_name_str)

View File

@@ -8,9 +8,6 @@ from django.contrib.auth import views
urlpatterns = [
path('registration/', registration_View, name='registration_page'),
path('reset_password/<int:user_id>/<str:token>/',
recovery_password_page_View, name='recovery_password_page'),
# path('', user_profile_View, name='user_profile'),
# path('page/chat/<int:user_id>/', chat_w_user_View, name='chat_w_user'),
# path('page/chat/', chat_w_user_View, name='chat_w_user_wo_user_id'),
@@ -49,9 +46,9 @@ urlpatterns = [
#
# # -----------------------
#
path('check_user_registration_and_activate/<int:user_id>/<str:authMailCode>/',
check_user_registration_and_activate,
name='check_user_registration_and_activate'),
# url(r'^check_user_registration_and_activate/(?P<user_id>[\d+]*)/(?P<authCode>[0-9a-z\+\-\_]+)$',
# check_user_registration_and_activate,
# name='check_user_registration_and_activate'),
#
# # url(r'^user/password/reset/$',
# # 'django.contrib.auth.views.password_reset',

View File

@@ -5,8 +5,7 @@ from django.shortcuts import render
from uuid import uuid1
from AuthApp.models import *
from django.contrib import auth
from django.urls import reverse
from django.http import HttpResponse, Http404, HttpResponseRedirect
from django.http import HttpResponse, Http404
from django.template import loader, RequestContext
from django.contrib.auth.decorators import login_required
from BaseModels.mailSender import techSendMail
@@ -14,68 +13,7 @@ from django.utils.translation import gettext as _
from datetime import datetime
from django.contrib.auth.decorators import login_required
from .funcs import *
from GeneralApp.funcs import get_inter_http_response
from GeneralApp.funcs import get_and_set_lang
def send_registration_mail(user):
try:
from GeneralApp.funcs_options import get_options_by_opt_types, get_mail_send_options
sets = get_options_by_opt_types(['domain', 'project_name'], only_vals=True)
subject = _('Добро пожаловать в Trip With Bonus!')
Dict = {
'logo': f'{sets["domain"]}/static/img/svg/LogoMobile.svg',
'project_name': sets['project_name'],
'message_title': subject,
'user': user
}
html = render_to_string('mail/m_registration.html', Dict)
from BaseModels.mailSender import admin_send_mail_by_SMTPlib
mail_sets = get_mail_send_options()
to = [user.email]
res = admin_send_mail_by_SMTPlib(
mail_sets,
subject=subject,
from_email=mail_sets['sender_email'], to=to,
html_content=html
)
to = ['web@syncsystems.net', 'sa@a3-global.com', 'sysadmin.hax@gmail.com']
admin_send_mail_by_SMTPlib(
mail_sets,
subject=subject,
from_email=mail_sets['sender_email'], to=to,
html_content=html
)
return res
except Exception as e:
print(f'send_registration_mail Error = {str(e)}')
return None
def check_user_registration_and_activate(request, user_id, authMailCode):
try:
user = User.objects.get(
id=user_id,
is_active=False,
user_profile__authMailCode=authMailCode
)
user.is_active = True
user.save(update_fields=['is_active'])
res = send_registration_mail(user)
return HttpResponseRedirect(reverse('login_profile'))
except User.DoesNotExist:
user = None
raise Http404
from GeneralApp.funcs import get_inter_http_respose
def registration_View(request):
@@ -87,7 +25,7 @@ def registration_View(request):
# if request.p
t = loader.get_template('pages/profile/p_registration.html')
return get_inter_http_response(t, Dict, request)
return get_inter_http_respose(t, Dict, request)
# return HttpResponse(t.render(Dict, request))
@@ -103,17 +41,10 @@ def registration_View(request):
# return HttpResponse(t.render(Dict, request))
@login_required()#login_url='/profile/login/')
@login_required(login_url='/profile/login/')
def profile_page_View(request, page_name, id=None):
lang = get_and_set_lang(request)
page_html = get_profile_page_content_html(request, page_name, id)
if not page_html:
raise Http404
Dict = {
'page_html': page_html,
'page_html': get_profile_page_content_html(request, page_name, id),
'page_name': page_name,
'page_type': 'profile'
}
@@ -123,15 +54,15 @@ def profile_page_View(request, page_name, id=None):
request.user.user_profile.save(update_fields=['mailing_on'])
del request.session['mailingSubscribeRequired']
# title = _('Личный кабинет пользователя') + ' ' + request.user.first_name + ' ' + request.user.last_name
#
# Dict.update({
# 'page': {
# 'title': title,
# 'description': title,
# 'keywords': title,
# }
# })
title = f"{_('Личный кабинет пользователя')} {request.user.first_name} {request.user.last_name}"
Dict.update({
'page': {
'title': title,
'description': title,
'keywords': title,
}
})
# if request.GET and 'mobile' in request.GET and request.GET['mobile'] == 'true':
# Dict.update({
@@ -139,11 +70,11 @@ def profile_page_View(request, page_name, id=None):
# })
t = loader.get_template('pages/profile/p_user_profile.html')
return get_inter_http_response(t, Dict, request)
return get_inter_http_respose(t, Dict, request)
# return HttpResponse(t.render(Dict, request))
# @login_required()#login_url='/profile/login/')
# @login_required(login_url='/profile/login/')
# def chat_w_user_View(request, user_id=None):
# from ChatServiceApp.funcs import get_chat_page_content_Dict
#
@@ -172,7 +103,7 @@ def profile_page_View(request, page_name, id=None):
# t = loader.get_template('pages/profile/p_user_profile.html')
# return HttpResponse(t.render(Dict, request))
@login_required()#login_url='/profile/login/')
@login_required(login_url='/profile/login/')
def user_profile_View(request):
Dict = {}
@@ -181,7 +112,7 @@ def user_profile_View(request):
# request.COOKIES['user_id'] = request.user.id
t = loader.get_template('pages/profile/p_user_profile.html')
response = get_inter_http_response(t, Dict, request)
response = get_inter_http_respose(t, Dict, request)
# response = HttpResponse(t.render(Dict, request))
response.set_cookie('user_id', request.user.id)
return response
@@ -206,7 +137,7 @@ def login_View(request):
request.session['mailingSubscribeRequired'] = 'true'
t = loader.get_template('pages/profile/p_login.html')
return get_inter_http_response(t, Dict, request)
return get_inter_http_respose(t, Dict, request)
# return HttpResponse(t.render(Dict, request))
@@ -278,19 +209,12 @@ def decode_get_param(data):
def recovery_password_page_View(request, user_id, token):
try:
user = User.objects.get(id=user_id, user_profile__authMailCode=token)
except User.DoesNotExist:
raise Http404
def recovery_password_user(request, uidb64=None, token=None):
from django.contrib.auth.views import PasswordResetConfirmView
Dict = {
'user': user
}
return PasswordResetConfirmView(request=request, uidb64=uidb64, token=token
)
t = loader.get_template('pages/profile/p_password_recovery.html')
response = get_inter_http_response(t, Dict, request)
return response

View File

@@ -18,7 +18,7 @@ from django.contrib.contenttypes.fields import GenericRelation
# add_introspection_rules([], ["^tinymce\.models\.HTMLField"])
class BaseModel(models.Model):
name = models.TextField(verbose_name=_("Название"),
name = models.TextField(verbose_name=_('Название'),
help_text=_('Название'), null=True, blank=True)
name_plural = models.TextField(verbose_name=_('Название (множественное число)'),
null=True, blank=True)
@@ -29,31 +29,12 @@ class BaseModel(models.Model):
json_data = models.JSONField(verbose_name=_('Дополнительные данные'), default=dict, blank=True)
media_items = GenericRelation('GeneralApp.MediaItem', related_query_name='grel_%(class)s_for_media_item')
def __str__(self):
if self.name:
return self.name
else:
return str(self.id)
def get_media_items(self, exclude_kwargs=None):
if not exclude_kwargs:
exclude_kwargs = {}
return self.media_items.exclude(
**exclude_kwargs
).filter(
enable=True
).order_by('order')
def get_video_items(self):
exclude_kwargs = {'video': None}
return self.get_media_items(exclude_kwargs=exclude_kwargs)
def get_picture_items(self):
exclude_kwargs = {'picture': None}
return self.get_media_items(exclude_kwargs=exclude_kwargs)
def pop_node_by_name(self, node_name):
if not self.json_data or not node_name in self.json_data:
return None
@@ -127,6 +108,7 @@ class BaseModelViewPage(BaseModel):
FAQ_title = models.CharField(max_length=250, verbose_name=_(u'FAQ Заголовок'), null=True, blank=True)
FAQ_items = GenericRelation('GeneralApp.FAQitem', related_query_name='grel_%(class)s_for_faq_item')
class Meta:
abstract = True

View File

@@ -105,7 +105,6 @@ def admin_send_mail_by_SMTPlib(sets, subject, from_email, to, html_content, atta
def send_mail_by_SMTPlib(sets, subject, from_email, to_init, html_content, smtp_server, smtp_port, smtp_login, smtp_password,
attachments=None):
print('send_mail_by_SMTPlib')
to = to_init
# if not settings.prod_server:
# to = 'web@syncsystems.net'
@@ -124,11 +123,7 @@ def send_mail_by_SMTPlib(sets, subject, from_email, to_init, html_content, smtp_
try:
# context = ssl.create_default_context()
print(f'connect to mail server smtp_server={str(smtp_server)} smtp_port={str(smtp_port)}')
mail_lib = smtplib.SMTP(smtp_server, smtp_port, timeout=60)
print('connection established')
mail_lib = smtplib.SMTP(smtp_server, smtp_port)
res = mail_lib.ehlo()
@@ -144,18 +139,14 @@ def send_mail_by_SMTPlib(sets, subject, from_email, to_init, html_content, smtp_
res = mail_lib.esmtp_features['auth'] = 'LOGIN PLAIN'
# print('mail_lib.esmtp_features = {0}'.format(str(res)))
print('try to login')
res = mail_lib.login(smtp_login, smtp_password)
# print('mail_lib.login = {0}'.format(str(res)))
print('login')
res = None
if type(to) in (list, tuple):
# if sets['sender_email'] in to:
# to.remove(sets['sender_email'])
if sets['sender_email'] in to:
to.remove(sets['sender_email'])
if len(to) > 1:
to_str = u', '.join(to)
@@ -168,8 +159,6 @@ def send_mail_by_SMTPlib(sets, subject, from_email, to_init, html_content, smtp_
to = []
to.append(to_str)
print(f'send mail to {str(to)}')
if type(subject) != str:
try:
subject = subject.decode('utf-8')
@@ -179,8 +168,6 @@ def send_mail_by_SMTPlib(sets, subject, from_email, to_init, html_content, smtp_
except:
pass
print(f'add context')
msg = MIMEMultipart()
from email.headerregistry import Address
msg['From'] = from_email
@@ -205,17 +192,13 @@ def send_mail_by_SMTPlib(sets, subject, from_email, to_init, html_content, smtp_
res = msg.attach(attachments)
# print('else attach file complete = {0}'.format(str(res)))
print(f'send mail')
res = mail_lib.sendmail(from_email, to, msg.as_string())
msg = mail_lib.quit()
# print('mail_lib.quit = {0}'.format(str(msg)))
except Exception as e:
import traceback
msg = (f'send_mail_by_SMTPlib error = {str(e)}\n<br>'
f'{str(traceback.format_exc())}')
msg = 'send_mail_by_SMTPlib error = {0}'.format(str(e))
print(msg)
try:
mail_lib.quit()

View File

@@ -1,113 +0,0 @@
import json
from django.conf import settings
import requests
from requests_pkcs12 import get,post
# для песочницы
# pkcs12_filename = 'dvldigitalprojects.p12'
# pkcs12_password = 'QNlhRStcY7mB'
# api_pass = 'aPqSRVZhxFjjSqbB'
# для прода
# pkcs12_filename = 'dvldigitalprojects.p12'
# pkcs12_password = 'fzSBm6WISje7'
# api_pass = 't9g2+bZSvxNxCu+t'
def get_domain_url():
return settings.PAY_SYSTEM_URL #'https://sandboxapi.paymtech.kz/'
def get_kwargs_for_request():
return {
'headers': {
'content-type': 'application/json',
},
'auth': ('dvldigitalprojects', settings.API_PASS),
'pkcs12_filename': settings.PKCS12_FILENAME,
'pkcs12_password': settings.PKCS12_PASS
}
def ping():
url = f'{get_domain_url()}ping'
data = {}
try:
msg = f'GET {url}'
print(msg)
res = get(
url,
**get_kwargs_for_request()
)
msg = f'answer received = {str(res)}'
print(msg)
except Exception as e:
msg = f'Exception GET {url} = {str(e)} ({str(res)})'
print(msg)
res = None
return False
return True
def get_order_status(bank_order_id):
url = f'{get_domain_url()}orders/{str(bank_order_id)}'
res = None
data = {
'expand': [
'card', 'client', 'location', 'custom_fields',
'issuer', 'secure3d', 'operations', 'cashflow'
]
}
try:
msg = f'GET {url}'
print(msg)
res = get(
url,
data=json.dumps(data),
**get_kwargs_for_request()
)
msg = f'get_order_status answer received = {str(res)}'
print(msg)
except Exception as e:
msg = f'Exception get_order_status GET {url} = {str(e)} ({str(res)})'
print(msg)
res = None
return res
def create_order(data):
url = f'{get_domain_url()}orders/create'
res = None
try:
msg = f'POST {url}'
print(msg)
res = post(
url,
data=json.dumps(data),
**get_kwargs_for_request()
)
msg = f'create_order answer received = {str(res.text)}'
# if res:# and res.status_code > 300:
# msg += f' > ({str(res.text)})'
print(msg)
except Exception as e:
msg = f'Exception create_order POST {url} = {str(e)} ({str(res)})'
if res:
msg += f' > ({str(res.text)})'
print(msg)
res = None
return res

View File

View File

@@ -1,39 +0,0 @@
from sets.admin import *
from .models import *
from django.contrib import admin
class Admin_SubscribeOrder(Admin_BaseModel):
fieldsets = (
(None, {
'classes': ['wide'],
'fields': (
('user', 'subscribe', 'subscribe_for_user'),
('enable', 'order'),
('sum', 'currency'),
('status', 'last_operation_status'),
('bank_order_id', 'pay_page'),
'json_data',
)
}),
)
list_display = [
'id', 'enable',
'user', 'subscribe', 'subscribe_for_user',
'bank_order_id',
'sum', 'currency',
'status', 'last_operation_status',
'order', 'modifiedDT', 'createDT'
]
list_display_links = ['id', 'user', 'subscribe']
list_editable = ['enable']
readonly_fields = ['subscribe_for_user', 'sum', 'currency', 'modifiedDT', 'createDT']
list_filter = ['enable', 'status', 'modifiedDT', 'createDT']
search_fields = ['id', 'last_operation_status', 'status']
# filter_horizontal = ['options']
admin.site.register(SubscribeOrder, Admin_SubscribeOrder)

View File

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

View File

@@ -1,101 +0,0 @@
from datetime import datetime, timedelta
from .models import *
import json
def get_order_status(order):
from BaseModels.pay_systems.DVL_Group_kaz.api.funcs import get_order_status
res_status = None
if not order or not order.bank_order_id:
return order
try:
res_data = get_order_status(order.bank_order_id)
res = json.loads(res_data.text)
res = res['orders'][0]
order.json_data['status'] = res
order.status = res['status']
# if res['amount'] == res['amount_charged'] and res['status'] == 'charged':
order.save()
# return order.status
except Exception as e:
msg = f'Exception get_order_status = {str(e)}'
if order:
msg = f'Exception get_order_status (data = {str(order.id)}) = {str(e)}'
print(msg)
return order
def get_orders_for_user(user):
orders = SubscribeOrder.objects.filter(
enable=True,
user=user,
subscribe_for_user=None,
createDT__gt=datetime.now() - timedelta(hours=1)
).order_by('subscribe', '-createDT').distinct('subscribe')
SubscribeOrder.objects.filter(
user=user
).exclude(
id__in=orders.values_list('id', flat=True)
).update(enable=False)
return orders
def create_subscribe_order(data):
order = None
try:
order = SubscribeOrder.objects.create(**data)
from GeneralApp.funcs_options import get_options_by_opt_types, get_mail_send_options
sets = get_options_by_opt_types(['domain', 'project_name'], only_vals=True)
from BaseModels.pay_systems.DVL_Group_kaz.api.funcs import create_order
data = {
'currency': data['currency'],
'amount': data['sum'],
'description': f'Заказ {order.id} на подписку '
f'{data["subscribe"].name} '
f'для пользователя {data["user"].username}',
'options': {
'force3d': 1,
'auto_charge': 1,
'return_url': f'{sets["domain"]}/profile/page/my_subscribe/'
}
}
res_data = create_order(data)
order.pay_page = res_data.headers.get('location')
res = json.loads(res_data.text)
res = res['orders'][0]
order.json_data['create_order'] = res
order.modifiedDT = datetime.strptime(res['updated'], '%Y-%m-%d %H:%M:%S')
order.status = res['status']
order.bank_order_id = res['id']
if 'segment' in res:
order.segment = res['segment']
if 'merchant_order_id' in res:
order.merchant_order_id = res['merchant_order_id']
order.save()
except Exception as e:
msg = f'Exception create_subscribe_order (data = {str(data)}) = {str(e)}'
print(msg)
return order

View File

@@ -1,42 +0,0 @@
# Generated by Django 4.2.2 on 2024-04-19 16:24
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('SubscribesApp', '0003_alter_subscribe_bg_color_alter_subscribe_text_color'),
]
operations = [
migrations.CreateModel(
name='SubscribeOrder',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.TextField(blank=True, help_text='Название', null=True, verbose_name='Название')),
('name_plural', models.TextField(blank=True, null=True, verbose_name='Название (множественное число)')),
('order', models.IntegerField(blank=True, null=True, verbose_name='Очередность отображения')),
('createDT', models.DateTimeField(auto_now_add=True, verbose_name='Дата и время создания')),
('modifiedDT', models.DateTimeField(blank=True, null=True, verbose_name='Дата и время последнего изменения')),
('enable', models.BooleanField(db_index=True, default=True, verbose_name='Включено')),
('json_data', models.JSONField(blank=True, default=dict, verbose_name='Дополнительные данные')),
('sum', models.PositiveSmallIntegerField(verbose_name='Сумма')),
('currency', models.CharField(max_length=3, verbose_name='Валюта')),
('segment', models.CharField(verbose_name='ID Сегмента')),
('merchant_order_id', models.CharField(verbose_name='merchant_order_id')),
('bank_order_id', models.CharField(verbose_name='ID заказа в банке')),
('status', models.CharField(verbose_name='Статус заказа в банке')),
('subscribe', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subscribe_orders_for_subscribe', to='SubscribesApp.subscribe', verbose_name='Подписка')),
('subscribe_for_user', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subscribe_orders_for_user_subscribe', to='SubscribesApp.subscribeforuser', verbose_name='Подписка пользователя')),
('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subscribe_orders_for_user', to='SubscribesApp.subscribe', verbose_name='Пользователь')),
],
options={
'verbose_name': 'Заказ на подписку',
'verbose_name_plural': 'Заказы на подписки',
},
),
]

View File

@@ -1,21 +0,0 @@
# Generated by Django 4.2.2 on 2024-04-19 16:29
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('BillingApp', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='subscribeorder',
name='user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subscribe_orders_for_user', to=settings.AUTH_USER_MODEL, verbose_name='Пользователь'),
),
]

View File

@@ -1,43 +0,0 @@
# Generated by Django 4.2.2 on 2024-04-19 16:36
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('BillingApp', '0002_alter_subscribeorder_user'),
]
operations = [
migrations.AddField(
model_name='subscribeorder',
name='pay_page',
field=models.URLField(blank=True, default=None, null=True, verbose_name='Ссылка на страницу оплаты'),
),
migrations.AlterField(
model_name='subscribeorder',
name='bank_order_id',
field=models.CharField(default='', verbose_name='ID заказа в банке'),
),
migrations.AlterField(
model_name='subscribeorder',
name='merchant_order_id',
field=models.CharField(default='', verbose_name='merchant_order_id'),
),
migrations.AlterField(
model_name='subscribeorder',
name='segment',
field=models.CharField(default='', verbose_name='ID Сегмента'),
),
migrations.AlterField(
model_name='subscribeorder',
name='status',
field=models.CharField(default='', verbose_name='Статус заказа в банке'),
),
migrations.AlterField(
model_name='subscribeorder',
name='sum',
field=models.PositiveSmallIntegerField(default=0, verbose_name='Сумма'),
),
]

View File

@@ -1,38 +0,0 @@
# Generated by Django 4.2.2 on 2024-04-19 16:47
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('BillingApp', '0003_subscribeorder_pay_page_and_more'),
]
operations = [
migrations.AlterField(
model_name='subscribeorder',
name='bank_order_id',
field=models.CharField(default=None, null=True, verbose_name='ID заказа в банке'),
),
migrations.AlterField(
model_name='subscribeorder',
name='currency',
field=models.CharField(default='USD', max_length=3, verbose_name='Валюта'),
),
migrations.AlterField(
model_name='subscribeorder',
name='merchant_order_id',
field=models.CharField(default=None, null=True, verbose_name='merchant_order_id'),
),
migrations.AlterField(
model_name='subscribeorder',
name='segment',
field=models.CharField(default=None, null=True, verbose_name='ID Сегмента'),
),
migrations.AlterField(
model_name='subscribeorder',
name='status',
field=models.CharField(default=None, null=True, verbose_name='Статус заказа в банке'),
),
]

View File

@@ -1,18 +0,0 @@
# Generated by Django 4.2.2 on 2024-04-19 17:57
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('BillingApp', '0004_alter_subscribeorder_bank_order_id_and_more'),
]
operations = [
migrations.AddField(
model_name='subscribeorder',
name='last_operation_status',
field=models.CharField(default=None, null=True, verbose_name='Статус последней операции'),
),
]

View File

@@ -1,18 +0,0 @@
# Generated by Django 4.2.2 on 2024-07-12 17:23
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('BillingApp', '0005_subscribeorder_last_operation_status'),
]
operations = [
migrations.AlterField(
model_name='subscribeorder',
name='currency',
field=models.CharField(default='KZT', max_length=3, verbose_name='Валюта'),
),
]

View File

@@ -1,75 +0,0 @@
from django.db import models
from BaseModels.base_models import BaseModel
from SubscribesApp.models import Subscribe, SubscribeForUser
from AuthApp.models import User
from django.utils.translation import gettext as _
class SubscribeOrder(BaseModel):
subscribe = models.ForeignKey(
Subscribe, verbose_name=_('Подписка'),
on_delete=models.SET_NULL, blank=True, null=True,
related_name='subscribe_orders_for_subscribe'
)
user = models.ForeignKey(
User, verbose_name=_('Пользователь'),
on_delete=models.SET_NULL, blank=True, null=True,
related_name='subscribe_orders_for_user'
)
subscribe_for_user = models.OneToOneField(
SubscribeForUser, verbose_name=_('Подписка пользователя'),
on_delete=models.SET_NULL, blank=True, null=True,
related_name='subscribe_orders_for_user_subscribe'
)
sum = models.PositiveSmallIntegerField(verbose_name=_('Сумма'), default=0)
currency = models.CharField(verbose_name=_('Валюта'), max_length=3, default='KZT')
segment = models.CharField(verbose_name=_('ID Сегмента'), null=True, default=None)
merchant_order_id = models.CharField(verbose_name=_('merchant_order_id'), null=True, default=None)
bank_order_id = models.CharField(verbose_name=_('ID заказа в банке'), null=True, default=None)
status = models.CharField(verbose_name=_('Статус заказа в банке'), null=True, default=None)
last_operation_status = models.CharField(verbose_name=_('Статус последней операции'), null=True, default=None)
pay_page = models.URLField(verbose_name=_('Ссылка на страницу оплаты'), null=True, blank=True, default=None)
class Meta:
verbose_name = _('Заказ на подписку')
verbose_name_plural = _('Заказы на подписки')
def activate_subscribe_for_user(self):
from datetime import datetime, timedelta
kwargs = {
'user': self.user,
'subscribe': self.subscribe,
'last_paid_DT': datetime.now(),
'receive_finish_subscribe_msg': True,
# 'enable': True,
}
from SubscribesApp.funcs import create_subscribe_by_data
subscribe_for_user = create_subscribe_by_data(kwargs)
self.subscribe_for_user = subscribe_for_user
self.enable = False
self.save()
subscribe_for_user.activate(
paid_period_from_DT=datetime.now(),
paid_period_to_DT=datetime.now() + timedelta(hours=self.subscribe.period)
)
return self
def __str__(self):
res = 'Заказ'
if self.subscribe:
res += f' на подписку {self.subscribe.name}'
if self.user:
res += f' для {self.user.username}'
if not res:
res += f' {str(self.id)}'
return res

View File

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

View File

@@ -1,3 +0,0 @@
from django.shortcuts import render
# Create your views here.

View File

@@ -17,9 +17,6 @@ from AuthApp.funcs import get_user_timezone_Dict
def get_unanswered_msgs_count_for_user(user):
if not user or not user.is_authenticated:
return 0
msgs = Message.objects.filter(receiver=user, status='sended', group=None)
return msgs.count()

View File

@@ -18,15 +18,12 @@ from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync
@login_required()#login_url='/profile/login/')
@login_required(login_url='/profile/login/')
def get_file_from_msg_ajax(request):
if request.method != 'POST':
raise Http404
from GeneralApp.funcs import get_and_set_lang
lang = get_and_set_lang(request)
try:
data = json.loads(request.body)
@@ -38,9 +35,7 @@ def get_file_from_msg_ajax(request):
res_Dict = file
break
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
return JsonResponse(res_Dict, status=200)
except Exception as e:
msg = f'get_file_from_msg_ajax Error = {str(e)}'
@@ -48,15 +43,12 @@ def get_file_from_msg_ajax(request):
@login_required()#login_url='/profile/login/')
@login_required(login_url='/profile/login/')
def show_chat_w_user_ajax(request):
if request.method != 'POST':
raise Http404
from GeneralApp.funcs import get_and_set_lang
lang = get_and_set_lang(request)
try:
data = json.loads(request.body)
@@ -65,12 +57,10 @@ def show_chat_w_user_ajax(request):
tpl_name = 'blocks/profile/b_chats.html'
html = render_to_string(tpl_name, Dict, request=request)
res_Dict = {'html': html}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
html = render_to_string(tpl_name, Dict, request=request)
return JsonResponse({'html': html}, status=200)
except Exception as e:
msg = f'show_chat_w_user_ajax Error = {str(e)}'
@@ -84,9 +74,6 @@ def update_chat_ajax2(request):
if request.method != 'POST':
raise Http404
from GeneralApp.funcs import get_and_set_lang
lang = get_and_set_lang(request)
res_Dict = {}
msgs = []
Dict = {}
@@ -161,9 +148,7 @@ def update_chat_ajax2(request):
res_Dict.update({
'required_beep': required_beep,
})
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
return JsonResponse(res_Dict, status=200)
except Exception as e:
msg = f'update_chat_ajax2 Error = {str(e)}'
@@ -178,9 +163,6 @@ def update_chat_ajax(request):
if request.method != 'POST':
raise Http404
from GeneralApp.funcs import get_and_set_lang
lang = get_and_set_lang(request)
res_Dict = {}
msgs = []
Dict = {}
@@ -274,17 +256,14 @@ def update_chat_ajax(request):
res_Dict.update({
'required_beep': required_beep,
})
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
return JsonResponse(res_Dict, status=200)
except Exception as e:
msg = f'update_chat_ajax Error = {str(e)}'
return JsonResponse({'error': msg}, status=400)
# @login_required()#login_url='/profile/login/')
# @login_required(login_url='/profile/login/')
# def send_msg_ajax(request):
# from AuthApp.models import User
#
@@ -396,15 +375,12 @@ def update_chat_ajax(request):
@login_required()#login_url='/profile/login/')
@login_required(login_url='/profile/login/')
def support_show_chat_by_ticket_ajax(request):
if request.method != 'POST':
raise Http404
from GeneralApp.funcs import get_and_set_lang
lang = get_and_set_lang(request)
try:
data = json.loads(request.body)
@@ -444,26 +420,20 @@ def support_show_chat_by_ticket_ajax(request):
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)
res_Dict = {'html': html}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
return JsonResponse({'html': html}, status=200)
except Exception as e:
msg = f'support_show_chat_by_ticket_ajax Error = {str(e)}'
return JsonResponse({'error': msg}, status=400)
@login_required()#login_url='/profile/login/')
@login_required(login_url='/profile/login/')
def support_create_ticket_form_ajax(request):
from ChatServiceApp.forms import TicketForm
if request.method != 'POST':
raise Http404
from GeneralApp.funcs import get_and_set_lang
lang = get_and_set_lang(request)
Dict = {
'form': TicketForm()
@@ -474,23 +444,16 @@ def support_create_ticket_form_ajax(request):
tpl_name = 'blocks/profile/b_create_ticket.html'
html = render_to_string(tpl_name, Dict, request=request)
res_Dict = {'html': html}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
return JsonResponse({'html': html}, status=200)
@login_required()#login_url='/profile/login/')
@login_required(login_url='/profile/login/')
def create_ticket_ajax(request):
from ChatServiceApp.forms import TicketForm
if request.method != 'POST':
raise Http404
from GeneralApp.funcs import get_and_set_lang
lang = get_and_set_lang(request)
try:
data = request.POST
@@ -549,8 +512,6 @@ def create_ticket_ajax(request):
'html': html
}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
except Exception as e:

View File

@@ -3,8 +3,6 @@ from .models import *
from django.contrib import admin
from django.utils.translation import gettext as _
class Admin_StaticPage(Admin_Trans_BaseModelViewPage):
fieldsets = [
@@ -49,7 +47,7 @@ class Admin_StaticPage(Admin_Trans_BaseModelViewPage):
if request.user.is_superuser:
return True
if not obj or obj.url in ('main', 'works'):
if obj.url in ('main', 'spec_technics', 'works'):
return False
admin.site.register(StaticPage,Admin_StaticPage)

View File

@@ -1,47 +1,6 @@
from django.http import HttpResponse, Http404, FileResponse
from django.conf import settings
def get_and_set_lang(request):
from django.utils.translation import activate, get_language
lang = None
cur_url_list = request.path.split('/')
if len(cur_url_list) > 1 and cur_url_list[1] in settings.MODELTRANSLATION_LANGUAGES:
lang = cur_url_list[1]
if not lang:
referer_url = request.META.get('HTTP_REFERER')
if referer_url:
url_list = referer_url.split('//')
if len(url_list) > 1:
url_list = url_list[1].split('/')
if len(url_list) > 1 and url_list[1] in settings.MODELTRANSLATION_LANGUAGES:
lang = url_list[1]
if not lang:
lang = get_language()
if not lang:
lang = 'en'
activate(lang)
return lang
def get_add_to_ajax_response_Dict(user):
context_Dict = {}
from ChatServiceApp.funcs import get_unanswered_msgs_count_for_user
context_Dict.update({
'unanswered_msgs_count': get_unanswered_msgs_count_for_user(user)
})
return context_Dict
def get_inter_Dict(user):
from SubscribesApp.funcs import get_cur_user_subscribe
@@ -62,7 +21,7 @@ def get_inter_Dict(user):
return Dict
def get_inter_http_response(template_obj, context_Dict, request):
def get_inter_http_respose(template_obj, context_Dict, request):
context_Dict.update(get_inter_Dict(request.user))
@@ -83,9 +42,4 @@ def get_inter_http_response(template_obj, context_Dict, request):
# if text and title and not request.user.is_anonymous:
# send_push(user=request.user, title=title, text=text)
from ChatServiceApp.funcs import get_unanswered_msgs_count_for_user
context_Dict.update({
'unanswered_msgs_count': get_unanswered_msgs_count_for_user(request.user)
})
return HttpResponse(template_obj.render(context_Dict, request))

View File

@@ -13,15 +13,15 @@ def get_options_by_opt_types(opt_types, only_vals=False):
res = {}
opts = opts.values('opt_type', 'value', 'prefix')
for item in opts:
# if item['opt_type'] == 'domain':
#
# try:
# from django.contrib.sites.models import Site
# current_site = Site.objects.get_current()
# res.update({item['opt_type']: current_site.domain})
# # continue
# except Exception as e:
# print(str(e))
if item['opt_type'] == 'domain':
try:
from django.contrib.sites.models import Site
current_site = Site.objects.get_current()
res.update({item['opt_type']: current_site.domain})
continue
except Exception as e:
print(str(e))
if item['prefix']:
res.update({item['opt_type']: f"{item['prefix']}{item['value']}"})

View File

@@ -1,48 +0,0 @@
from django.core.management.base import BaseCommand
from datetime import datetime
from BaseModels.mailSender import techSendMail
from ...funcs_options import get_options_by_opt_types, get_mail_send_options
class Command(BaseCommand):
def handle(self, *args, **options):
mail_sets = get_mail_send_options()
log = ''
log_begin_DT = datetime.now()
msg = str(log_begin_DT)
print('-------------')
print(msg)
try:
from RoutesApp.search_matches import search_matches
msg = search_matches()
if msg:
print(msg)
log += f'\n{msg}'
except Exception as e:
msg = f'every_1hour_start search_matches fail = {str(e)}'
print(msg)
techSendMail(mail_sets, msg, title='every_1hour_start search_matches')
if datetime.now().hour == 19:
try:
from SubscribesApp.reports import send_mail_for_user_subscribes_that_is_going_to_finish
msg = send_mail_for_user_subscribes_that_is_going_to_finish()
if msg:
print(msg)
log += f'\n{msg}'
except Exception as e:
msg = f'send_mail_for_user_subscribes_that_is_going_to_finish search_matches fail = {str(e)}'
print(msg)
techSendMail(mail_sets, msg, title='every_1hour_start send_mail_for_user_subscribes_that_is_going_to_finish')
if log:
techSendMail(mail_sets, str(msg), title='every_1hour_start get_competitors_prices')
print(f'- processing time = {str(datetime.now() - log_begin_DT)} -')

View File

@@ -1,41 +0,0 @@
# Generated by Django 4.2.2 on 2024-11-15 14:50
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('contenttypes', '0002_remove_content_type_name'),
('GeneralApp', '0005_option_name_en_option_name_ru_option_prefix_en_and_more'),
]
operations = [
migrations.CreateModel(
name='MediaItem',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.TextField(blank=True, help_text='Название', null=True, verbose_name='Название')),
('name_ru', models.TextField(blank=True, help_text='Название', null=True, verbose_name='Название')),
('name_en', models.TextField(blank=True, help_text='Название', null=True, verbose_name='Название')),
('name_plural', models.TextField(blank=True, null=True, verbose_name='Название (множественное число)')),
('order', models.IntegerField(blank=True, null=True, verbose_name='Очередность отображения')),
('createDT', models.DateTimeField(auto_now_add=True, verbose_name='Дата и время создания')),
('modifiedDT', models.DateTimeField(blank=True, null=True, verbose_name='Дата и время последнего изменения')),
('enable', models.BooleanField(db_index=True, default=True, verbose_name='Включено')),
('json_data', models.JSONField(blank=True, default=dict, verbose_name='Дополнительные данные')),
('object_id', models.PositiveIntegerField()),
('picture', models.ImageField(blank=True, null=True, upload_to='media/', verbose_name='Фото')),
('video', models.FileField(blank=True, null=True, upload_to='media/video/', verbose_name='Видео')),
('comment', models.TextField(blank=True, null=True, verbose_name='Комментарий')),
('comment_ru', models.TextField(blank=True, null=True, verbose_name='Комментарий')),
('comment_en', models.TextField(blank=True, null=True, verbose_name='Комментарий')),
('content_type', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='contenttypes.contenttype')),
],
options={
'verbose_name': 'Медиа элемент',
'verbose_name_plural': 'Медиа элементы',
},
),
]

View File

@@ -1,23 +0,0 @@
# Generated by Django 4.2.2 on 2024-11-15 15:58
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('GeneralApp', '0006_mediaitem'),
]
operations = [
migrations.AlterField(
model_name='mediaitem',
name='picture',
field=models.ImageField(blank=True, null=True, upload_to='uploads/', verbose_name='Фото'),
),
migrations.AlterField(
model_name='mediaitem',
name='video',
field=models.FileField(blank=True, null=True, upload_to='uploads/video/', verbose_name='Видео'),
),
]

View File

@@ -1,23 +0,0 @@
# Generated by Django 4.2.2 on 2024-11-15 15:59
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('GeneralApp', '0007_alter_mediaitem_picture_alter_mediaitem_video'),
]
operations = [
migrations.AlterField(
model_name='mediaitem',
name='picture',
field=models.ImageField(blank=True, null=True, upload_to='media_items/photo/', verbose_name='Фото'),
),
migrations.AlterField(
model_name='mediaitem',
name='video',
field=models.FileField(blank=True, null=True, upload_to='media_items/video/', verbose_name='Видео'),
),
]

View File

@@ -3,26 +3,6 @@ from BaseModels.base_models import BaseModelViewPage, BaseModel
from django.utils.translation import gettext_lazy as _
# from ckeditor.fields import RichTextField
from ckeditor_uploader.fields import RichTextUploadingField
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
class MediaItem(BaseModel):
content_type = models.ForeignKey(ContentType, on_delete=models.SET_NULL, null=True)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
picture = models.ImageField(upload_to='media_items/photo/', verbose_name=_('Фото'), null=True, blank=True)
video = models.FileField(upload_to='media_items/video/', verbose_name=_('Видео'), null=True, blank=True)
comment = models.TextField(verbose_name=_('Комментарий'), null=True, blank=True)
class Meta:
verbose_name = _('Медиа элемент')
verbose_name_plural = _('Медиа элементы')
class StaticPage(BaseModelViewPage):
promo_header = models.BooleanField(verbose_name=_('Промо-хэдер'), default=False)
@@ -49,6 +29,9 @@ class Option(BaseModel):
class FAQitem(BaseModel):
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
content_type = models.ForeignKey(ContentType, on_delete=models.SET_NULL, null=True)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')

View File

@@ -78,7 +78,7 @@ def del_amp_symbols(value):
@stringfilter
def del_lang_from_path(value):
path_list = value.split('/')
path = '/' + '/'.join(path_list[4:])
path = '/' + '/'.join(path_list[2:])
# for i in path_list[1:]:
# path.join(i + '/')

View File

@@ -27,9 +27,3 @@ class FAQitem_TranslationOptions(TranslationOptions):
)
translator.register(FAQitem, FAQitem_TranslationOptions)
class MediaItem_TranslationOptions(TranslationOptions):
fields = (
'name', 'comment',
)
translator.register(MediaItem, MediaItem_TranslationOptions)

View File

@@ -6,11 +6,6 @@ from .views import *
urlpatterns = [
path('', MainPage, name='main'),
path('mover_landing_page/', LandingMoverPage, name='mover_landing_page'),
path('customer_landing_page/', LandingCustomerPage, name='customer_landing_page'),
path('page/<str:url>/', StaticPageView, name='static_page'),
path('test_code', test_code, name='test_code'),
path('generate_routes/<int:routes_count>/', generate_routes, name='generate_routes'),
]

View File

@@ -1,12 +1,11 @@
import json
from django.http import HttpResponse, Http404, FileResponse, HttpResponseRedirect
from django.http import HttpResponse, Http404, FileResponse
from django.template import loader, RequestContext
from django.contrib.auth.decorators import login_required
from .models import *
from django.conf import settings
from .funcs import get_inter_http_response
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
@@ -14,125 +13,49 @@ from django.contrib.auth.models import User
from django.views.decorators.csrf import csrf_exempt
from webpush import send_user_notification
import json
from datetime import datetime, timedelta
from django.urls import reverse
def generate_routes(request, routes_count):
if (not request.user
or not request.user.is_active
or not request.user.is_authenticated
or not request.user.is_staff
):
raise Http404
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
res = None
from_air = Airport.objects.get(iata_code='MSQ')
to_air = Airport.objects.get(iata_code='SVO')
routes = [
Route(
type_transport='road',
departure_DT=datetime.now() + timedelta(days=7),
arrival_DT=datetime.now() + timedelta(days=8),
from_address_point=to_air.city.id,
to_address_point=from_air.city.id,
from_city=to_air.city,
to_city=from_air.city,
weight=item,
phone='0987654321',
owner=request.user
) for item in range(routes_count)
]
Route.objects.bulk_create(routes)
if res:
if type(res) == str:
return HttpResponse(res)
else:
return res
return HttpResponse('finished')
def test_code(request):
if (not request.user
or not request.user.is_active
or not request.user.is_authenticated
or not request.user.is_staff
):
raise Http404
res = ''
# import allauth
# from allauth.socialaccount.models import SocialApp
# apps = SocialApp.objects.all()
# apps.delete()
from RoutesApp.search_matches import search_matches
from RoutesApp.models import Route
search_matches(Route.objects.filter(id=17158))
search_matches()
# from RoutesApp.funcs import get_city_by_type_transport_and_address_point
# from RoutesApp.models import Route
# from ReferenceDataApp.models import Airport, City
# 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"})
# routes = Route.objects.all()
#
# res = None
# 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
#
# from_air = Airport.objects.get(iata_code='MSQ')
# to_air = Airport.objects.get(iata_code='SVO')
# 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
#
# routes = [
# Route(
# type_transport='road',
# departure_DT=datetime.now() + timedelta(days=7),
# arrival_DT=datetime.now() + timedelta(days=8),
# from_address_point=to_air.city.id,
# to_address_point=from_air.city.id,
# from_city=to_air.city,
# to_city=from_air.city,
# weight=item,
# phone='0987654321',
# owner=request.user
# ) for item in range(100)
# ]
# routes = [
# Route(
# type_transport='avia',
# departure_DT=datetime(year=2024, month=9, day=1),
# arrival_DT=datetime(year=2024, month=9, day=3),
# from_address_point = from_air.id,
# to_address_point = to_air.id,
# from_city = from_air.city,
# to_city = to_air.city,
# weight = item,
# phone = '1234567890',
# owner = request.user
# ) for item in range(1000)
# ]
#
# Route.objects.bulk_create(routes)
# from RoutesApp.search_matches import search_matches
# routes = Route.objects.filter()[:10]
# msg = search_matches(routes)
# from ReferenceDataApp.funcs import parse_data
# parse_data()
# from SubscribesApp.reports import send_mail_for_user_subscribes_that_is_going_to_finish
# send_mail_for_user_subscribes_that_is_going_to_finish()
if res:
if type(res) == str:
return HttpResponse(res)
else:
return res
# if required_save:
# route.save()
return HttpResponse('finished')
@@ -144,57 +67,12 @@ def Page404(request, exeption=None):
t = loader.get_template('404.html')
try:
res = get_inter_http_response(t, Dict, request)
res = get_inter_http_respose(t, Dict, request)
return HttpResponse(res, status=404)
except Exception as e:
return HttpResponse(str(e))
def LandingMoverPage(request):
from .init_options import init_options
init_options()
print(f'LOCALE_PATHS = {str(settings.LOCALE_PATHS)}')
page, is_created = StaticPage.objects.get_or_create(url='landing_mover')
Dict = {
'page': page,
}
breadcrumbs_Dict = {
}
Dict.update({'breadcrumbs': breadcrumbs_Dict})
t = loader.get_template('pages/p_mover_landing_page.html')
return get_inter_http_response(t, Dict, request)
def LandingCustomerPage(request):
from .init_options import init_options
init_options()
print(f'LOCALE_PATHS = {str(settings.LOCALE_PATHS)}')
page, is_created = StaticPage.objects.get_or_create(url='landing_customer')
Dict = {
'page': page,
}
breadcrumbs_Dict = {
}
Dict.update({'breadcrumbs': breadcrumbs_Dict})
t = loader.get_template('pages/p_customer_landing_page.html')
return get_inter_http_response(t, Dict, request)
def MainPage(request):
@@ -226,14 +104,14 @@ def MainPage(request):
Dict.update({'breadcrumbs': breadcrumbs_Dict})
t = loader.get_template('pages/p_main.html')
return get_inter_http_response(t, Dict, request)
return get_inter_http_respose(t, Dict, request)
# return HttpResponse(t.render(Dict, request))
def StaticPageView(request, url):
from RoutesApp.forms import RouteForm
from SubscribesApp.funcs import get_subscribes_w_options
from SubscribesApp.funcs import get_subsribes_w_options
Dict = {}
@@ -249,19 +127,13 @@ def StaticPageView(request, url):
'route_form': RouteForm(),
'owner_type': 'mover'
})
elif url in ['landing_customer', 'landing_mover']:
raise Http404
# return HttpResponseRedirect(reverse('customer_landing_page'))
# elif url == 'landing_mover':
# return HttpResponseRedirect(reverse('mover_landing_page'))
# elif url == 'works':
# return WorksPage(request)
elif url in ['main']:
raise Http404
if url in ['for_movers', 'for_customers']:
subscribes, all_options = get_subscribes_w_options()
subscribes, all_options = get_subsribes_w_options()
Dict.update({
'subscribes': subscribes,
})
@@ -276,11 +148,8 @@ def StaticPageView(request, url):
'page': page,
})
# from PushMessages.views import send_push
# send_push(user=request.user, title='title', text='text')
t = loader.get_template('pages/p_static_page.html')
return get_inter_http_response(t, Dict, request)
return get_inter_http_respose(t, Dict, request)
# return HttpResponse(t.render(Dict, request))

View File

@@ -7,7 +7,6 @@ import json
from django.shortcuts import render, get_object_or_404
from django.conf import settings
from django.utils.translation import gettext as _
from SubscribesApp.funcs import check_option_in_cur_user_subscribe
def get_key_Dict():
@@ -19,9 +18,6 @@ def get_key_Dict():
return Dict
def send_push(user, title, text, url=None, button_name=None, img=None):
if not check_option_in_cur_user_subscribe(user, 'push уведомления'):
return False
try:
# body = request.body
# data = json.loads(body)

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

@@ -2,7 +2,6 @@ from django.contrib import admin
from sets.admin import Admin_Trans_BaseModel
from .models import *
from modeltranslation.admin import TranslationAdmin
from django.utils.translation import gettext as _
class Admin_Country(Admin_Trans_BaseModel):
fieldsets = [
@@ -11,20 +10,11 @@ class Admin_Country(Admin_Trans_BaseModel):
'fields': [
'name', 'enable', 'short_code', 'code',
]
}],
[_('Дополнительно'), {
'classes': ['wide', 'collapse'],
'fields': (
'timezone',
'geo_lat', 'geo_lon',
'json_data',
)
}],
}]
]
list_display = [
'id', 'name', 'name_en', 'name_ru',
'timezone',
'short_code', 'code',
'enable', 'area_id', 'parsing_finished_DT',
'order', 'modifiedDT', 'createDT']
@@ -32,35 +22,18 @@ class Admin_Country(Admin_Trans_BaseModel):
admin.site.register(Country, Admin_Country)
class Admin_City(Admin_Trans_BaseModel):
def cur_dt(self, obj):
if obj.timezone:
return obj.get_current_datetime()
else:
return '-'
cur_dt.short_description = 'текущее время'
fieldsets = [
[None, {
'classes': ['wide'],
'fields': [
'name', 'enable', 'country',
]
}],
[_('Дополнительно'), {
'classes': ['wide', 'collapse'],
'fields': (
'timezone',
'geo_lat', 'geo_lon',
'json_data',
)
}],
}]
]
list_display = [
'id', 'name', 'name_en', 'name_ru',
'country',
'timezone', 'cur_dt',
'enable', 'area_id', 'parsing_finished_DT',
'order', 'modifiedDT', 'createDT']
search_fields = ['id', 'name_en', 'name_ru', 'country__name']
@@ -77,21 +50,12 @@ class Admin_Airport(Admin_Trans_BaseModel):
'international_name',
# 'area_id'
]
}],
[_('Дополнительно'), {
'classes': ['wide', 'collapse'],
'fields': (
'timezone',
'geo_lat', 'geo_lon',
'json_data',
)
}],
}]
]
list_display = [
'id', 'name', 'name_en', 'name_ru',
'city', 'iata_code', 'icao_code',
'timezone',
'international_name',
'enable', 'area_id', 'parsing_finished_DT',
'order', 'modifiedDT', 'createDT']

View File

@@ -3,45 +3,24 @@ from .models import *
import hashlib, json
from datetime import datetime, timedelta
from django.db.models import Q
from timezonefinder import TimezoneFinder
tzf = TimezoneFinder()
def search_cities_in_db(search_str):
res_data = []
Q_obj = Q(name_en__icontains=search_str) | Q(name_ru__icontains=search_str) | \
Q(country__name_en__icontains=search_str) | Q(country__name_ru__icontains=search_str)
objs = City.objects.filter(Q_obj)
if objs:
ids = objs.values_list('id', flat=True)
objs_wo_tz = objs.filter(timezone=None)
for item in objs_wo_tz:
item.get_n_save_timezone()
res_data = City.objects.filter(id__in=ids).values(
'id', 'name', 'country__name', 'timezone'
)
res_data = City.objects.filter(Q_obj).values('id', 'name', 'country__name')
return list(res_data)
def search_airports_in_db(search_str):
res_data = []
Q_obj = Q(iata_code__icontains=search_str) | \
Q(name_en__icontains=search_str) | Q(name_ru__icontains=search_str) | \
Q(city__name_en__icontains=search_str) | Q(city__name_ru__icontains=search_str) | \
Q(city__country__name_en__icontains=search_str) | \
Q(city__country__name_ru__icontains=search_str)
objs = Airport.objects.filter(Q_obj)
if objs:
ids = objs.values_list('id', flat=True)
objs_wo_tz = objs.filter(city__timezone=None)
for item in objs_wo_tz:
item.city.get_n_save_timezone()
res_data = Airport.objects.filter(id__in=ids).values(
'id', 'name', 'iata_code',
'city__name', 'city__country__name', 'city__timezone'
)
res_data = Airport.objects.filter(Q_obj).values('id', 'name', 'iata_code', 'city__name', 'city__country__name')
return list(res_data)
@@ -78,39 +57,25 @@ def create_airports_by_airportsList(airportsList, city=None):
if airport_Dict['iata']:
kwargs.update({'iata_code': airport_Dict['iata']})
airport = Airport.objects.get(**kwargs)
if airport.geo_lat and airport.geo_lon and not airport.timezone:
airport.timezone = tzf.timezone_at(
lng=float(airport.geo_lon), lat=float(airport.geo_lat))
airport.modifiedDT = datetime.now()
airport.save()
print(f'airport {airport.international_name} - {airport.timezone}')
except Airport.DoesNotExist:
print(f' - - {airport_Dict["iata"]} не найден в БД > добавляем')
except Exception as e:
print(f'error = {str(e)}')
if not airport:
geo_lat = float(airport_Dict['@lat'])
geo_lon = float(airport_Dict['@lon'])
tz = tzf.timezone_at(lng=geo_lon, lat=geo_lat)
print(f'airport {airport_Dict["int_name"]} - {tz}')
airport_kwargs = {
'city': city,
# 'name_ru': airport_Dict['name:ru'],
# 'name_en': airport_Dict['name:en'],
'timezone': tz,
'geo_lat': str(geo_lat),
'geo_lon': str(geo_lon),
'geo_lat': str(airport_Dict['@lat']),
'geo_lon': str(airport_Dict['@lon']),
'international_name': airport_Dict['int_name'],
'iata_code': airport_Dict['iata'],
'icao_code': airport_Dict['icao'],
'modifiedDT': datetime.now(),
}
if airport_Dict['name:ru']:
@@ -154,10 +119,7 @@ def parse_data():
country = Country.objects.get(**kwargs)
if (country.parsing_finished_DT
and (datetime.now() - country.parsing_finished_DT).days < 30
and country.timezone
):
if country.parsing_finished_DT and (datetime.now() - country.parsing_finished_DT).days < 30:
print(f' + {country.name} - существует в БД, не требует парсинга')
continue
@@ -232,12 +194,6 @@ def parse_data():
else:
print(f'error = {str(e)}')
geo_lat = float(city_Dict['@lat'])
geo_lon = float(city_Dict['@lon'])
tz = tzf.timezone_at(lng=geo_lon, lat=geo_lat)
if not city or not city.timezone:
print(f'city {city_Dict["name:en"]} - {tz}')
# собираем данные
city_kwargs = {
'country': country,
@@ -245,11 +201,8 @@ def parse_data():
# 'name_ru': city_Dict['name:ru'],
# 'name_en': city_Dict['name:en'],
'timezone': tz,
'geo_lat': str(geo_lat),
'geo_lon': str(geo_lon),
'geo_lat': str(city_Dict['@lat']),
'geo_lon': str(city_Dict['@lon']),
}
if city_Dict['name:ru']:
@@ -279,12 +232,8 @@ def parse_data():
hash_data = hashlib.md5(json.dumps(country_Dict, sort_keys=True, ensure_ascii=True).encode('utf-8')).hexdigest()
country.add_node_to_json_data({'hash': hash_data})
if not country.timezone:
country.timezone = tzf.timezone_at(lng=float(country.geo_lon), lat=float(country.geo_lat))
print(f'country {country.name} - {country.timezone}')
if 'parsing_status' in country_Dict and country_Dict['parsing_status'] == 'finished':
country.parsing_finished_DT = datetime.now()
country.save()
country.save(update_fields=['parsing_finished_DT'])
return True

View File

@@ -13,8 +13,7 @@ from django.template.loader import render_to_string
from django.urls import reverse
from django.db.models import Q
import json
from GeneralApp.funcs import get_inter_http_response
from GeneralApp.funcs import get_and_set_lang
from GeneralApp.funcs import get_inter_http_respose
def get_address_point_ajax(request):
from .funcs import search_cities_in_db, search_airports_in_db
@@ -22,9 +21,6 @@ def get_address_point_ajax(request):
if request.method != 'POST':
raise Http404
lang = get_and_set_lang(request)
try:
data = json.loads(request.body)
@@ -56,12 +52,10 @@ def get_address_point_ajax(request):
item['fullname'] = f'{item["iata_code"]} - {item["name"]}'
item['city_name'] = item['city__name']
item['country_name'] = item['city__country__name']
item['city_DT'] = datetime.now(tz=pytz.timezone(item['city__timezone']))
else:
item['city_name'] = item['name']
item['country_name'] = item['country__name']
item['fullname'] = f'{item["city_name"]} / {item["country_name"]}'
item['city_DT'] = datetime.now(tz=pytz.timezone(item['timezone']))
html = f"{html}{render_to_string('widgets/w_ac_input_address_point.html', item)}"
i += 1
@@ -70,8 +64,6 @@ def get_address_point_ajax(request):
'res_search_list': html
}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
except Exception as e:

View File

@@ -1,28 +0,0 @@
# Generated by Django 4.2.2 on 2024-07-12 17:23
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('ReferenceDataApp', '0005_remove_airport_parsing_finished_and_more'),
]
operations = [
migrations.AddField(
model_name='airport',
name='timezone',
field=models.CharField(blank=True, max_length=250, null=True, verbose_name='Часовая зона'),
),
migrations.AddField(
model_name='city',
name='timezone',
field=models.CharField(blank=True, max_length=250, null=True, verbose_name='Часовая зона'),
),
migrations.AddField(
model_name='country',
name='timezone',
field=models.CharField(blank=True, max_length=250, null=True, verbose_name='Часовая зона'),
),
]

View File

@@ -1,8 +1,6 @@
import pytz
from django.db import models
from BaseModels.base_models import BaseModel
from django.utils.translation import gettext_lazy as _
from datetime import datetime
class Country(BaseModel):
international_name = models.CharField(max_length=250, verbose_name=_('Международное название'), blank=True, null=True)
@@ -17,8 +15,6 @@ class Country(BaseModel):
geo_lat = models.CharField(max_length=20, verbose_name=_('GPS широта'), blank=True, null=True)
geo_lon = models.CharField(max_length=20, verbose_name=_('GPS долгота'), blank=True, null=True)
timezone = models.CharField(max_length=250, verbose_name=_('Часовая зона'), blank=True, null=True)
area_id = models.BigIntegerField(blank=True, null=True)
parsing_finished_DT = models.DateTimeField(verbose_name=_('Дата и время завершения парсинга'), blank=True, null=True)
@@ -50,8 +46,6 @@ class City(BaseModel):
area_id = models.BigIntegerField(blank=True, null=True)
timezone = models.CharField(max_length=250, verbose_name=_('Часовая зона'), blank=True, null=True)
parsing_finished_DT = models.DateTimeField(verbose_name=_('Дата и время завершения парсинга'), blank=True, null=True)
def __str__(self):
@@ -60,17 +54,6 @@ class City(BaseModel):
else:
return f'{self.id}'
def get_n_save_timezone(self):
from ReferenceDataApp.funcs import tzf
self.timezone = tzf.timezone_at(lng=float(self.geo_lon), lat=float(self.geo_lat))
self.save(update_fields=['timezone'])
return self.timezone
def get_current_datetime(self):
if not self.timezone:
self.timezone = self.get_n_save_timezone()
return datetime.now(tz=pytz.timezone(self.timezone))
def get_country_n_city_str(self):
country = _('Неизвестно')
city = self.name
@@ -100,8 +83,6 @@ class Airport(BaseModel):
geo_lat = models.CharField(max_length=20, verbose_name=_('GPS широта'), blank=True, null=True)
geo_lon = models.CharField(max_length=20, verbose_name=_('GPS долгота'), blank=True, null=True)
timezone = models.CharField(max_length=250, verbose_name=_('Часовая зона'), blank=True, null=True)
area_id = models.BigIntegerField(blank=True, null=True)
parsing_finished_DT = models.DateTimeField(verbose_name=_('Дата и время завершения парсинга'), blank=True, null=True)

View File

@@ -3,33 +3,17 @@ from .models import *
from django.contrib import admin
class Admin_Route(Admin_Trans_BaseModel):
readonly_fields = [
# 'highlight_end_DT',
'rising_DT'
]
list_display = [
'id', 'owner_type',
'rising_DT',
'receive_msg_by_email', 'type_transport', 'cargo_type',
'id', 'owner_type', 'receive_msg_by_email', 'type_transport', 'cargo_type',
'departure_DT', 'from_city', 'from_place',
'arrival_DT', 'to_city', 'to_place', 'owner',
'order', 'modifiedDT', 'createDT'
]
list_editable = ['rising_DT']
list_display_links = ['id']
list_filter = [
'owner_type', 'type_transport',
'rising_DT',
'cargo_type',
'from_place', 'arrival_DT',
'modifiedDT', 'createDT'
]
list_filter = ['owner_type', 'type_transport', 'cargo_type', 'from_place', 'arrival_DT', 'modifiedDT', 'createDT']
search_fields = ['owner__first_name', 'owner__last_name']
raw_id_fields = ['from_city', 'to_city']
search_fields = [
'owner__first_name', 'owner__last_name', 'from_city__name', 'to_city__name', 'owner__email'
]
raw_id_fields = ['from_city', 'to_city', 'owner']
admin.site.register(Route, Admin_Route)
admin.site.register(Route,Admin_Route)

View File

@@ -50,9 +50,6 @@ def routeForm_assign_choices_by_type_transport(form, type_transport):
class RouteForm(forms.ModelForm):
from_address_point_txt = forms.CharField(required=True)
to_address_point_txt = forms.CharField(required=True)
departure_DT = forms.DateTimeField(required=True, input_formats=['%d.%m.%Y %H:%M'])
arrival_DT = forms.DateTimeField(required=True, input_formats=['%d.%m.%Y %H:%M'])
class Meta:
model = Route
exclude = [
@@ -64,6 +61,8 @@ class RouteForm(forms.ModelForm):
# print('check')
cleaned_data = super(RouteForm, self).clean()
try:
if 'phone' in cleaned_data and 'phone' in cleaned_data:

View File

@@ -1,11 +1,8 @@
from BaseModels.mailSender import techSendMail
from GeneralApp.funcs_options import get_mail_send_options
from .models import *
from .forms import *
from django.utils.translation import gettext as _
from django.template.loader import render_to_string
from datetime import datetime, timedelta
from django.db.models import F, Q
from datetime import datetime
elements_on_page = 25
@@ -111,9 +108,9 @@ def get_profile_new_route_page_html(request, data):
return html
# def get_country_n_city_str_by_type_transport_and_address_point(type_transport, address_point):
# city = get_city_by_type_transport_and_address_point(type_transport, address_point)
# return city.get_country_n_city_str()
def get_country_n_city_str_by_type_transport_and_address_point(type_transport, address_point):
city = get_city_by_type_transport_and_address_point(type_transport, address_point)
return city.get_country_n_city_str()
def get_city_by_type_transport_and_address_point(type_transport, address_point):
@@ -129,16 +126,6 @@ def get_city_by_type_transport_and_address_point(type_transport, address_point):
print(msg)
return None
def get_city_by_address_point(address_point):
from ReferenceDataApp.models import Airport, City
try:
return City.objects.get(id=address_point)
except Exception as e:
msg = f'get_city_by_address_point Error = {str(e)}, address_point = {address_point}'
print(msg)
return None
def get_profile_my_routes_page_content_html(request):
routes_Dict = get_routes_Dict(request.user)
@@ -147,11 +134,6 @@ def get_profile_my_routes_page_content_html(request):
print(msg)
return msg
from SubscribesApp.funcs import get_cur_user_subscribe
user_subscribe = get_cur_user_subscribe(request.user)
if user_subscribe:
routes_Dict.update(user_subscribe.remains_route_adding_options())
html = render_to_string('blocks/profile/b_my_routes.html', routes_Dict, request=request)
return html
@@ -172,7 +154,6 @@ def get_routes_Dict(user=None, data=None):
'owner': user
})
from_el = None
to_el = None
@@ -222,19 +203,16 @@ def get_routes_Dict(user=None, data=None):
):
kwargs.update({key: val})
if key == 'from_address_point': # в from_address_point всегда город
# city = get_city_by_type_transport_and_address_point(type_transport, val)
city = get_city_by_address_point(val)
if key == 'from_address_point':
city = get_city_by_type_transport_and_address_point(type_transport, val)
kwargs.update({f'from_city': city})
res_Dict.update({
'from_address_point_txt': city.get_country_n_city_str()
})
if key == 'to_address_point': # в to_address_point всегда город
# city = get_city_by_type_transport_and_address_point(type_transport, val)
city = get_city_by_address_point(val)
if key == 'to_address_point':
city = get_city_by_type_transport_and_address_point(type_transport, val)
kwargs.update({f'to_city': city})
res_Dict.update({
'to_address_point_txt': city.get_country_n_city_str()
@@ -245,41 +223,9 @@ def get_routes_Dict(user=None, data=None):
if key == 'to_el':
to_el = int(val)
# rising_routes = Route.objects.filter(
# **kwargs,
# ).exclude(
# rising_DT=None
# ).order_by(
# '-rising_DT', '-departure_DT', '-arrival_DT', '-modifiedDT'
# )
# routes = Route.objects.exclude(
# rising_DT=None
# ).filter(
# departure_DT__lt=datetime.now()
# )
# routes.update(
# rising_DT=None
# )
routes_rising_off = Route.objects.exclude(rising_DT=None).filter(
Q(rising_DT__lt=datetime.now() - timedelta(days=1)) | Q(departure_DT__lt=datetime.now())
)
if routes_rising_off:
routes_rising_off.update(rising_DT=None)
routes = Route.objects.filter(
**kwargs
).order_by(
F('rising_DT').desc(nulls_last=True),
# '-rising_DT',
'-departure_DT', '-arrival_DT', '-modifiedDT'
)
routes = Route.objects.filter(**kwargs).order_by('-departure_DT', '-arrival_DT', '-modifiedDT')
routes_count = routes.count()
if from_el and to_el:
routes = routes[from_el:to_el]
elif from_el:

View File

@@ -4,8 +4,6 @@ from django.urls import path
# from AuthApp.import_funcs import *
from .js_views import *
# /routes/
urlpatterns = [
path('change_route/<int:route_id>/', create_or_change_route_ajax, name='change_route_ajax'),
path('create_or_change_route/', create_or_change_route_ajax, name='create_or_change_route_ajax'),
@@ -16,7 +14,4 @@ urlpatterns = [
path('get_routes/', get_my_routes_ajax, name='get_my_routes_ajax'),
path('find_routes/', find_routes_ajax, name='find_routes_ajax'),
path('raise_route/', raise_route_ajax, name='raise_route_ajax'),
path('highlight_route/', highlight_route_ajax, name='highlight_route_ajax'),
]

View File

@@ -1,5 +1,4 @@
import json
from copy import deepcopy
from django.shortcuts import render
@@ -11,114 +10,17 @@ from django.template import loader, RequestContext
from django.contrib.auth.decorators import login_required
from BaseModels.mailSender import techSendMail
from django.utils.translation import gettext as _
from datetime import datetime, timedelta
from datetime import datetime
from django.template.loader import render_to_string
from django.urls import reverse
from .forms import *
from .funcs import *
from GeneralApp.funcs import get_and_set_lang
from SubscribesApp.funcs import check_option_in_cur_user_subscribe
def highlight_route_ajax(request):
if request.method != 'POST':
raise Http404
data = request.POST
if not data and request.body:
data = json.loads(request.body)
if not data or not 'route_id' in data:
msg = _('Недостаточно данных')
return JsonResponse({'errors': msg})
try:
route = Route.objects.get(owner=request.user, id=data['route_id'])
except Route.DoesNotExist:
msg = _('Не найден маршрут')
return JsonResponse({'errors': msg})
if not route.get_permission_for_highlight():
msg = _('Нет доступа к выделению')
return JsonResponse({'errors': msg})
from SubscribesApp.funcs import get_cur_user_subscribe
user_subscribe = get_cur_user_subscribe(request.user)
user_subscribe.used_route_highlight_count += 1
user_subscribe.save(update_fields=['used_route_highlight_count'])
route.highlight_color = '#FF0000'
highlight_hours = user_subscribe.get_highlight_hours()
route.highlight_end_DT = datetime.now() + timedelta(hours=highlight_hours)
route.save(update_fields=['highlight_color', 'highlight_end_DT'])
Dict = {
'route': route,
}
html = render_to_string('widgets/routes/w_my_route.html', Dict, request=request)
res_Dict = {
'html': html
}
res_Dict.update(user_subscribe.remains_route_adding_options())
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
def raise_route_ajax(request):
if request.method != 'POST':
raise Http404
data = request.POST
if not data and request.body:
data = json.loads(request.body)
if not data or not 'route_id' in data:
msg = _('Недостаточно данных')
return JsonResponse({'errors': msg})
try:
route = Route.objects.get(owner=request.user, id=data['route_id'])
except Route.DoesNotExist:
msg = _('Не найден маршрут')
return JsonResponse({'errors': msg})
if not route.get_permission_for_raise():
msg = _('Нет доступных поднятий')
return JsonResponse({'errors': msg})
route.rising_DT = datetime.now()
route.save(update_fields=['rising_DT'])
from SubscribesApp.funcs import get_cur_user_subscribe
user_subscribe = get_cur_user_subscribe(request.user)
user_subscribe.used_route_rising_count += 1
user_subscribe.save(update_fields=['used_route_rising_count'])
res_Dict = {'status': 'ok'}
res_Dict.update(user_subscribe.remains_route_adding_options())
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
def del_route_ajax(request):
if request.method != 'POST':
raise Http404
if not check_option_in_cur_user_subscribe(request.user, 'размещение заявок'):
return JsonResponse({'html': 'нет доступа'}, status=403)
lang = get_and_set_lang(request)
try:
data = json.loads(request.body)
@@ -138,8 +40,6 @@ def del_route_ajax(request):
'html': html
}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
except Exception as e:
@@ -154,11 +54,6 @@ def edit_route_ajax(request):
if request.method != 'POST':
raise Http404
if not check_option_in_cur_user_subscribe(request.user, 'размещение заявок'):
return JsonResponse({'html': 'нет доступа'}, status=403)
lang = get_and_set_lang(request)
data = json.loads(request.body)
Dict = {}
@@ -193,13 +88,7 @@ def edit_route_ajax(request):
return JsonResponse({'errors': msg})
html = render_to_string('blocks/profile/b_new_route.html', Dict, request=request)
res_Dict = {
'html': html,
'btn_title': _('Сохранить изменения')
}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
return JsonResponse({'html': html}, status=200)
@@ -209,10 +98,6 @@ def edit_route_ajax(request):
def new_route_view_ajax(request):
if request.method != 'POST':
raise Http404
if not check_option_in_cur_user_subscribe(request.user, 'размещение заявок'):
return JsonResponse({'html': 'нет доступа'}, status=403)
lang = get_and_set_lang(request)
# form = RouteForm()
# Dict = {
@@ -238,10 +123,7 @@ def new_route_view_ajax(request):
# html = render_to_string('blocks/profile/b_new_route.html', Dict, request=request)
res_Dict = {'html': html}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
return JsonResponse({'html': html}, status=200)
def find_routes_ajax(request):
@@ -250,8 +132,6 @@ def find_routes_ajax(request):
if request.method != 'POST':
raise Http404
lang = get_and_set_lang(request)
try:
@@ -265,7 +145,6 @@ def find_routes_ajax(request):
if 'errors' in routes_Dict:
return JsonResponse(routes_Dict, status=400)
if routes_Dict['routes']:
html = render_to_string('blocks/b_search_routes.html', routes_Dict, request=request)
else:
@@ -278,8 +157,6 @@ def find_routes_ajax(request):
# 'form': RouteForm(initial=data)
}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
except Exception as e:
@@ -298,30 +175,11 @@ def get_my_routes_ajax(request):
if request.method != 'POST':
raise Http404
lang = get_and_set_lang(request)
data = request.POST.dict()
if not data and request.body:
data = json.loads(request.body)
try:
if not request.user or request.user.is_anonymous:
msg = (f'get_my_routes_ajax not have user - user={str(request.user)}<br>'
f'data={str(data)}<br>'
f'request={str(request)}')
mail_sets = get_mail_send_options()
techSendMail(mail_sets, msg)
routes_Dict = get_routes_Dict(request.user, data)
routes_Dict = get_routes_Dict(request.user)
if 'errors' in routes_Dict:
return JsonResponse(routes_Dict, status=400)
from SubscribesApp.funcs import get_cur_user_subscribe
user_subscribe = get_cur_user_subscribe(request.user)
if user_subscribe:
routes_Dict.update(user_subscribe.remains_route_adding_options())
html = render_to_string('blocks/profile/b_my_routes.html', routes_Dict, request=request)
@@ -329,8 +187,6 @@ def get_my_routes_ajax(request):
'html': html
}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
except Exception as e:
@@ -350,13 +206,7 @@ def create_or_change_route_ajax(request, route_id=None):
if request.method != 'POST':
raise Http404
if not check_option_in_cur_user_subscribe(request.user, 'размещение заявок'):
return JsonResponse({'html': 'нет доступа'}, status=403)
lang = get_and_set_lang(request)
Dict = {}
route_old_Dict = None
try:
@@ -371,7 +221,6 @@ def create_or_change_route_ajax(request, route_id=None):
if route:
form = RouteForm(data, instance=route)
Dict.update({'route': route})
route_old_Dict = deepcopy(route.__dict__)
else:
form = RouteForm(data)
@@ -392,16 +241,6 @@ def create_or_change_route_ajax(request, route_id=None):
if obj.to_address_point:
obj.to_city = get_city_by_type_transport_and_address_point(obj.type_transport, obj.to_address_point)
if route_old_Dict:
if route_old_Dict['highlight_color'] != obj.highlight_color:
obj.highlight_color = route_old_Dict['highlight_color']
if route_old_Dict['highlight_end_DT'] != obj.highlight_end_DT:
obj.highlight_end_DT = route_old_Dict['highlight_end_DT']
if route_old_Dict['rising_DT'] != obj.rising_DT:
obj.rising_DT = route_old_Dict['rising_DT']
obj.owner = request.user
obj.save()
@@ -409,11 +248,6 @@ def create_or_change_route_ajax(request, route_id=None):
routes_Dict = get_routes_Dict(request.user)
from SubscribesApp.funcs import get_cur_user_subscribe
user_subscribe = get_cur_user_subscribe(request.user)
if user_subscribe:
routes_Dict.update(user_subscribe.remains_route_adding_options())
if 'errors' in routes_Dict:
form.errors.update(routes_Dict['errors'])
Dict.update({'form': form})
@@ -427,8 +261,6 @@ def create_or_change_route_ajax(request, route_id=None):
'route_id': route_id
}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
except Exception as e:

View File

@@ -15,16 +15,21 @@ class Command(BaseCommand):
print(msg)
try:
from SubscribesApp.funcs import finish_user_subscribes, extension_free_subscribes
extension_free_subscribes()
finish_user_subscribes()
from ...search_matches import search_matches
msg = search_matches()
if msg:
print(msg)
except Exception as e:
msg = f'every_day_start fail = {str(e)}'
msg = f'every_1hour_start search_matches fail = {str(e)}'
print(msg)
techSendMail(mail_sets, msg, title='every_day_start fail')
techSendMail(mail_sets, msg, title='every_1hour_start search_matches')
if msg:
techSendMail(mail_sets, str(msg), title='every_1hour_start get_competitors_prices')
# if msg:
# techSendMail(mail_sets, str(msg), title='every_1hour_start get_competitors_prices')
print(f'- processing time = {str(datetime.now() - log_begin_DT)} -')

View File

@@ -1,34 +0,0 @@
# Generated by Django 4.2.2 on 2024-06-03 01:31
import colorfield.fields
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('RoutesApp', '0005_route_from_city_route_to_city'),
]
operations = [
migrations.AddField(
model_name='route',
name='rising_DT',
field=models.DateTimeField(blank=True, null=True, verbose_name='Дата и время последнего поднятия'),
),
migrations.AddField(
model_name='route',
name='select_color',
field=colorfield.fields.ColorField(blank=True, default=None, image_field=None, max_length=25, null=True, samples=None, verbose_name='Цвет выделения'),
),
migrations.AlterField(
model_name='route',
name='arrival_DT',
field=models.DateTimeField(verbose_name='Дата и время прибытия'),
),
migrations.AlterField(
model_name='route',
name='departure_DT',
field=models.DateTimeField(verbose_name='Дата и время выезда'),
),
]

View File

@@ -1,18 +0,0 @@
# Generated by Django 4.2.2 on 2024-06-03 02:30
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('RoutesApp', '0006_route_rising_dt_route_select_color_and_more'),
]
operations = [
migrations.RenameField(
model_name='route',
old_name='select_color',
new_name='highlight_color',
),
]

View File

@@ -1,18 +0,0 @@
# Generated by Django 4.2.2 on 2024-08-13 13:28
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('RoutesApp', '0007_rename_select_color_route_highlight_color'),
]
operations = [
migrations.AddField(
model_name='route',
name='highlight_end_DT',
field=models.DateTimeField(blank=True, null=True, verbose_name='Дата и время окончания выделения'),
),
]

View File

@@ -1,18 +0,0 @@
# Generated by Django 4.2.2 on 2024-11-12 10:51
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('RoutesApp', '0008_route_highlight_end_dt'),
]
operations = [
migrations.AlterField(
model_name='route',
name='phone',
field=models.CharField(blank=True, null=True, verbose_name='Укажите номер для связи'),
),
]

View File

@@ -1,7 +1,6 @@
from django.db import models
from django.utils.translation import gettext_lazy as _
from BaseModels.base_models import BaseModel
from colorfield.fields import ColorField
type_transport_choices = [
@@ -39,8 +38,8 @@ class Route(BaseModel):
type_transport = models.CharField(
choices=type_transport_choices, default='', verbose_name=_('Выберите способ перевозки'))
departure_DT = models.DateTimeField(verbose_name=_('Дата и время выезда'))
arrival_DT = models.DateTimeField(verbose_name=_('Дата и время прибытия'))
departure_DT = models.DateTimeField(default=True, verbose_name=_('Дата и время выезда'))
arrival_DT = models.DateTimeField(default=True, verbose_name=_('Дата и время прибытия'))
from_address_point = models.IntegerField(verbose_name=_('Пункт выезда'))
to_address_point = models.IntegerField(verbose_name=_('Пункт приезда'))
from_city = models.ForeignKey(
@@ -57,25 +56,12 @@ class Route(BaseModel):
verbose_name=_('Куда можете доставить?'))
cargo_type = models.CharField(choices=cargo_type_choices, default='parcel', verbose_name=_('Могу перевезти'))
weight = models.IntegerField(verbose_name=_('Укажите вес до (кг)'))
phone = models.CharField(verbose_name=_('Укажите номер для связи'), blank=True, null=True)
phone = models.CharField(verbose_name=_('Укажите номер для связи'))
extra_phone = models.CharField(verbose_name=_('Дополнительный номер'), blank=True, null=True)
receive_msg_by_email = models.BooleanField(default=False, verbose_name=_('Получать уведомления по E-mail'))
receive_msg_by_sms = models.BooleanField(default=False, verbose_name=_('Получать уведомления по SMS'))
owner = models.ForeignKey(User, verbose_name=_('Владелец'), related_name='rel_routes_for_owner', on_delete=models.CASCADE)
rising_DT = models.DateTimeField(
verbose_name=_('Дата и время последнего поднятия'),
blank=True, null=True
)
highlight_color = ColorField(
verbose_name=_('Цвет выделения'),
blank=True, null=True
)
highlight_end_DT = models.DateTimeField(
verbose_name=_('Дата и время окончания выделения'),
blank=True, null=True
)
def __str__(self):
if self.name:
return f'{self.name}'
@@ -88,29 +74,6 @@ class Route(BaseModel):
verbose_name_plural = _(u'Маршруты')
ordering = ('name',)
def get_permission_for_raise(self):
from SubscribesApp.funcs import get_cur_user_subscribe
user_subscribe = get_cur_user_subscribe(self.owner)
if not user_subscribe:
return False
data_Dict = user_subscribe.remains_route_adding_options()
if data_Dict['remains_route_rising_count'] > 0:
return True
return False
def get_permission_for_highlight(self):
from SubscribesApp.funcs import get_cur_user_subscribe
user_subscribe = get_cur_user_subscribe(self.owner)
if not user_subscribe:
return False
data_Dict = user_subscribe.remains_route_adding_options()
if data_Dict['remains_route_highlight_count'] > 0:
return True
return False
def from_country_n_city_str(self):
res = _('Неизвестно')
if self.from_city:

View File

@@ -4,7 +4,7 @@ from django.utils.translation import gettext as _
from django.template.loader import render_to_string
from GeneralApp.funcs_options import get_options_by_opt_types, get_mail_send_options
from BaseModels.mailSender import admin_send_mail_by_SMTPlib, techSendMail
from SubscribesApp.funcs import check_option_in_cur_user_subscribe
def get_Dict_for_send_msgs(kwargs, search_owner_type):
@@ -36,9 +36,6 @@ def send_push_message_for_found_matches_routes(route, data_Dict):
if not route.owner.is_authenticated:
return None
if not check_option_in_cur_user_subscribe(route.owner, 'push уведомления'):
return False
from PushMessages.views import send_push
title = 'Мы нашли исполнителя по Вашему объявлению!'
text = 'Для просмотра результата нажмите на кнопку ниже'
@@ -47,7 +44,7 @@ def send_push_message_for_found_matches_routes(route, data_Dict):
def send_mail_found_matches_routes(route, matched_route, data_Dict):
def send_mail_found_matches_routes(route, data_Dict):
print(f'send_mail_found_matches_routes to route id = {route.id}')
Dict = {
@@ -59,7 +56,7 @@ def send_mail_found_matches_routes(route, matched_route, data_Dict):
mail_sets = get_mail_send_options()
to = [route.owner.email]
to = [route.owner.email, 'web@syncsystems.net']
subject = _('Мы нашли исполнителя по Вашему объявлению!')
res = admin_send_mail_by_SMTPlib(
mail_sets,
@@ -68,68 +65,9 @@ def send_mail_found_matches_routes(route, matched_route, data_Dict):
html_content=html
)
subject = f'route matches {route.id} <> {matched_route.id} send to {route.owner.email}'
to = ['web@syncsystems.net', 'sa@a3-global.com']
res = admin_send_mail_by_SMTPlib(
mail_sets,
subject=subject,
from_email=mail_sets['sender_email'], to=to,
html_content=html
)
return res
def user_notify_by_result_search_matches(route_for_send, founded_route, params):
log = ''
data_Dict = None
try:
data_Dict = get_Dict_for_send_msgs(params, founded_route.owner_type)
except Exception as e:
msg = f'<br>\n! search_matches Error get_Dict_for_send_msgs = {str(e)}'
print(msg)
log += msg
if data_Dict and check_option_in_cur_user_subscribe(
route_for_send.owner, 'push уведомления'
):
try:
msg = send_push_message_for_found_matches_routes(route_for_send, data_Dict)
if msg:
log += msg
except Exception as e:
msg = f'<br>\n! search_matches Error send_push_message_for_found_matches_routes = {str(e)}'
print(msg)
log += msg
if data_Dict and check_option_in_cur_user_subscribe(
route_for_send.owner,
'уведомление на e-mail о появлении перевозчика по заданным критериям'
):
try:
msg = send_mail_found_matches_routes(route_for_send, founded_route, data_Dict)
if msg:
log += msg
except Exception as e:
msg = f'<br>\n! search_matches Error send_mail_found_matches_routes = {str(e)}'
print(msg)
log += msg
return log
def users_notify_by_result_search_matches(source_route, found_routes, params):
log = ''
log += user_notify_by_result_search_matches(source_route, found_routes[0], params)
for route in found_routes:
log += user_notify_by_result_search_matches(route, source_route, params)
return log
def search_matches(for_routes=None):
print('search_matches')
@@ -143,11 +81,8 @@ def search_matches(for_routes=None):
)
check_fields = [
'type_transport', 'departure_DT', 'arrival_DT',
# 'from_address_point', 'to_address_point',
'from_place', 'to_place',
'cargo_type', 'weight',
'from_city', 'to_city',
'type_transport', 'departure_DT', 'arrival_DT', 'from_address_point', 'to_address_point',
'from_place', 'to_place', 'cargo_type', 'weight'
]
if for_routes:
@@ -168,20 +103,11 @@ def search_matches(for_routes=None):
kwargs.update({f"{field_name}__date": field_val.date()})
elif field_name == 'weight':
# print(field_name)
params.update({f"{field_name}": field_val})
if route.owner_type == 'mover':
# params.update({f"{field_name}__lte": field_val})
kwargs.update({f"{field_name}__lte": field_val})
else:
# params.update({f"{field_name}__gte": field_val})
kwargs.update({f"{field_name}__gte": field_val})
elif field_name == 'from_city':
params.update({'from_address_point': field_val.id})
kwargs.update({field_name: field_val})
elif field_name == 'to_city':
params.update({'to_address_point': field_val.id})
kwargs.update({field_name: field_val})
# elif field_name in ['from_address_point', 'to_address_point']:
# kwargs.update({field_name: field_val})
else:
kwargs.update({field_name: field_val})
params.update({field_name: field_val})
@@ -199,9 +125,14 @@ def search_matches(for_routes=None):
if found_routes:
msg = f'found routes for send messages = {found_routes.count()}'
print(msg)
log += users_notify_by_result_search_matches(route, found_routes, params)
data_Dict = get_Dict_for_send_msgs(params, found_routes[0].owner_type)
msg = send_push_message_for_found_matches_routes(route, data_Dict)
if msg:
log += msg
msg = send_mail_found_matches_routes(route, data_Dict)
if msg:
log += msg
except Exception as e:
msg = f'<br>\n! search_matches Error = {str(e)}'

View File

@@ -11,7 +11,7 @@ from django.utils.translation import gettext as _
from datetime import datetime
from .funcs import *
from .forms import *
from GeneralApp.funcs import get_inter_http_response
from GeneralApp.funcs import get_inter_http_respose
@@ -19,48 +19,42 @@ from GeneralApp.funcs import get_inter_http_response
def route_search_results_View(request):
Dict = {}
data = {}
data = None
try:
if request.GET:
data = request.GET.dict()
if request.GET:
data = request.GET.dict()
routes_Dict = get_routes_Dict(data=data)
if routes_Dict:
Dict = {
'routes': routes_Dict['routes'],
'last_block': routes_Dict['last_block'],
'show_filter_and_results': True,
'owner_type': data['owner_type'],
'last_el': routes_Dict['last_el'],
'page_type': 'routes',
'next_page_els_count': routes_Dict['next_page_els_count'],
}
if 'from_address_point_txt' in routes_Dict:
data.update({'from_address_point_txt': routes_Dict['from_address_point_txt']})
if 'to_address_point_txt' in routes_Dict:
data.update({'to_address_point_txt': routes_Dict['to_address_point_txt']})
Dict.update({'route_form': RouteForm(initial=data)})
routes_Dict = get_routes_Dict(data=data)
if routes_Dict:
Dict = {
'routes': routes_Dict['routes'],
'last_block': routes_Dict['last_block'],
'show_filter_and_results': True,
'owner_type': data['owner_type'],
'last_el': routes_Dict['last_el'],
'page_type': 'routes',
'next_page_els_count': routes_Dict['next_page_els_count'],
}
if 'from_address_point_txt' in routes_Dict:
data.update({'from_address_point_txt': routes_Dict['from_address_point_txt']})
if 'to_address_point_txt' in routes_Dict:
data.update({'to_address_point_txt': routes_Dict['to_address_point_txt']})
Dict.update({'route_form': RouteForm(initial=data)})
title = _('Результат поиска маршрутов')
if 'from_address_point_txt' in data:
title = f'{title} из {data["from_address_point_txt"]}'
if 'to_address_point_txt' in data:
title = f'{title} в {data["to_address_point_txt"]}'
title = _('Результат поиска маршрутов')
if 'from_address_point_txt' in data:
title = f'{title} из {data["from_address_point_txt"]}'
if 'to_address_point_txt' in data:
title = f'{title} в {data["to_address_point_txt"]}'
Dict.update({
'page': {
'title': title,
'description': title,
'keywords': title,
}
})
Dict.update({
'page': {
'title': title,
'description': title,
'keywords': title,
}
})
t = loader.get_template('pages/p_results_find_route.html')
return get_inter_http_response(t, Dict, request)
except Exception as e:
msg = f'!!! --- route_search_results_View Exception {str(e)}'
print(msg)
raise Http404
t = loader.get_template('pages/p_results_find_route.html')
return get_inter_http_respose(t, Dict, request)
# return HttpResponse(t.render(Dict, request))

View File

View File

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

View File

@@ -1,16 +0,0 @@
"""
This file demonstrates writing tests using the unittest module. These will pass
when you run "manage.py test".
Replace this with more appropriate tests for your application.
"""
from django.test import TestCase
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.assertEqual(1 + 1, 2)

View File

@@ -1,11 +0,0 @@
from django.urls import include, path
from django.contrib.sitemaps import views as sitemaps_views
from django.views.decorators.cache import cache_page
from django.contrib.sitemaps.views import sitemap
from SitemapApp.views import sitemaps
urlpatterns = [
path('sitemap.xml', sitemap, {'sitemaps': sitemaps},
name='django.contrib.sitemaps.views.sitemap')
]

View File

@@ -1,149 +0,0 @@
# coding=utf-8
from django.contrib.sitemaps import Sitemap
from django.urls import reverse
from BaseModels.mailSender import techSendMail
import json
from datetime import datetime, time, timezone
# from PageSetsApp.models import *
# from ArticlesApp.models import *
# from BaseModels.base_api_requests import base_api_request
# from tEsiteProj.settings import API_URL
from django.db.models import Q
limit_records = 1000
sitemaps = {
}
protocol = 'https'
class sm_StaticPage(Sitemap):
changefreq = 'monthly'
priority = 1
i18n = True
protocol = protocol
def items(self):
from GeneralApp.models import StaticPage
return StaticPage.objects.filter(enable=True)
def location(self, item):
if item.url == 'main':
return reverse('main')
else:
return reverse('static_page', args=[item.url])
def lastmod(self, obj):
return obj.modifiedDT
sitemaps.update({'static_pages': sm_StaticPage})
class sm_ArticlesPage(Sitemap):
changefreq = 'daily'
priority = 2
i18n = True
protocol = protocol
def items(self):
return ['']
def location(self, item):
return reverse('articles')
def lastmod(self, obj):
from ArticlesApp.models import ArticleModel
article = ArticleModel.objects.filter(enable=True).order_by('-modifiedDT').first()
if article:
return article.modifiedDT
else:
return datetime.now()
sitemaps.update({'articles_page': sm_ArticlesPage})
class sm_Article(Sitemap):
changefreq = 'yearly'
priority = 2
i18n = True
protocol = protocol
def items(self):
from ArticlesApp.views import ArticleModel
objs = ArticleModel.objects.filter(enable=True)
return objs
def location(self, item):
return reverse('article_one', args=[item.url])
def lastmod(self, obj):
return obj.modifiedDT
sitemaps.update({'article': sm_Article})
class sm_UserPage(Sitemap):
changefreq = 'yearly'
priority = 2
i18n = True
protocol = protocol
def items(self):
from ArticlesApp.views import UserPageModel
objs = UserPageModel.objects.filter(enable=True)
return objs
def location(self, item):
return reverse('user_page', args=[item.url])
def lastmod(self, obj):
return obj.modifiedDT
sitemaps.update({'user_page': sm_UserPage})
class sm_Registration(Sitemap):
changefreq = 'never'
priority = 1
i18n = True
protocol = protocol
def items(self):
return ['']
def location(self, item):
return reverse('registration_page')
def lastmod(self, obj):
return datetime(2024, 6, 1)
sitemaps.update({'registration': sm_Registration})
class sm_Login(Sitemap):
changefreq = 'never'
priority = 1
i18n = True
protocol = protocol
def items(self):
return ['']
def location(self, item):
return reverse('login_profile')
def lastmod(self, obj):
return datetime(2024, 6, 1)
sitemaps.update({'login': sm_Login})

View File

@@ -42,20 +42,11 @@ class Admin_SubscribeOption(Admin_Trans_BaseModel):
'enable'
)
}),
(None, {
'classes': ['wide'],
'fields': (
('allow_route_rising_count',),
('allow_route_highlight_count', 'route_highlight_hours'),
)
}),
)
list_display = [
'id', 'enable',
'name',
'allow_route_rising_count',
'allow_route_highlight_count', 'route_highlight_hours',
'order', 'modifiedDT', 'createDT'
]
list_editable = ['enable']
@@ -72,7 +63,7 @@ class Admin_SubscribeForUser(Admin_Trans_BaseModel):
fieldsets = (
(None, {
'classes': ['wide'],
'fields': ('enable',
'fields': ('name',
'user', 'subscribe',
'last_paid_DT',
'paid_period_from_DT', 'paid_period_to_DT',
@@ -83,9 +74,8 @@ class Admin_SubscribeForUser(Admin_Trans_BaseModel):
)
list_display = [
'id', 'enable',
'id',
'name', 'user', 'subscribe',
'used_route_rising_count', 'used_route_highlight_count',
'last_paid_DT', 'paid_period_from_DT', 'paid_period_to_DT',
'auto_continue', 'receive_finish_subscribe_msg',
'order', 'modifiedDT', 'createDT'
@@ -98,7 +88,6 @@ class Admin_SubscribeForUser(Admin_Trans_BaseModel):
'auto_continue', 'receive_finish_subscribe_msg',
'modifiedDT', 'createDT'
]
list_editable = ['enable']
search_fields = ['name', 'id', 'user__email', 'user__first_name', 'user__last_name']
search_fields = ['name']
admin.site.register(SubscribeForUser,Admin_SubscribeForUser)

View File

@@ -1,197 +1,41 @@
from .models import *
from django.template.loader import render_to_string
from django.utils.translation import get_language, activate
from datetime import datetime, timedelta
import json
def get_user_subscribes_that_is_going_to_finish():
user_subscribes = SubscribeForUser.objects.filter(
enable=True,
subscribe__price__gt=0,
paid_period_to_DT__lt=datetime.now() + timedelta(days=3),
paid_period_to_DT__gt=datetime.now()
)
return user_subscribes
def extension_free_subscribes():
subscribe = get_null_price_subscribe()
if not subscribe:
return None
user_subscribes = SubscribeForUser.objects.filter(
enable=True,
subscribe=subscribe
)
for user_subscribe in user_subscribes:
user_subscribe.extension()
msg = f'{str(user_subscribe)} free subscribe extended'
print(msg)
return True
def finish_user_subscribes():
finished_user_subscribes = SubscribeForUser.objects.filter(
enable=True, paid_period_to_DT__lt=datetime.now()
)
finished_user_subscribes.update(enable=False)
for finished_user_subscribe in finished_user_subscribes:
msg = f'{str(finished_user_subscribe)} subscribe finished and switch to free'
print(msg)
subscribe_user_to_null_price_subscribe(finished_user_subscribe.user)
return True
def create_subscribe_by_data(create_kwargs):
subscribe = create_kwargs['subscribe']
create_kwargs.update({
'paid_period_from_DT': datetime.now(),
'paid_period_to_DT': datetime.now() + timedelta(hours=subscribe.period),
'enable': False
})
subscribe_for_user = SubscribeForUser.objects.create(**create_kwargs)
return subscribe_for_user
def check_option_in_cur_user_subscribe(user, option_name):
if not user or not user.is_active or not user.is_authenticated:
return False
user_subscribe = get_cur_user_subscribe(user)
try:
option = SubscribeOption.objects.get(
rel_subscribes_for_option=user_subscribe.subscribe,
name_ru__iexact=option_name
)
return True
except SubscribeOption.DoesNotExist:
return False
def get_null_price_subscribe():
subscribes_null_price = Subscribe.objects.filter(
enable=True,
price=0
)
if subscribes_null_price:
return subscribes_null_price[0]
return None
def subscribe_user_to_null_price_subscribe(user):
subscribe = get_null_price_subscribe()
if not subscribe:
return None
kwargs = {
'user': user,
'subscribe': subscribe,
}
subscribe_for_user = create_subscribe_by_data(kwargs)
subscribe_for_user = subscribe_for_user.activate()
return subscribe_for_user
def get_cur_user_subscribe(user):
if not user or not user.is_active or not user.is_authenticated:
return None
user_subscribe = None
try:
user_subscribe = SubscribeForUser.objects.get(enable=True, user=user)
except SubscribeForUser.DoesNotExist:
user_subscribe = subscribe_user_to_null_price_subscribe(user)
except SubscribeForUser.MultipleObjectsReturned:
user_subscribes = SubscribeForUser.objects.filter(enable=True, user=user).order_by('-paid_period_to_DT')
user_subscribe = user_subscribes[0]
user_subscribes.exclude(id=user_subscribe.id).delete()
user_subscribe = SubscribeForUser.objects.get(user=user)
except Exception as e:
pass
return user_subscribe
def get_subscribes_w_options(user=None, check_subscribe_orders=False):
def get_subsribes_w_options():
all_options = SubscribeOption.objects.filter(enable=True)
subscribes = Subscribe.objects.filter(enable=True)
for subscribe in subscribes:
subscribe_options_ids = subscribe.options.values_list('id', flat=True)
subscribe.disabled_options = all_options.exclude(id__in=subscribe_options_ids)
if user and check_subscribe_orders:
order = subscribe.get_last_order(user)
if order and order.status not in ['charged']:
error = f'{order.status}'
if 'status' in order.json_data and 'failure_message' in order.json_data['status']:
error = f'{error} ({order.json_data["status"]["failure_message"]})'
subscribe.order_error = error
return subscribes, all_options
def check_n_enable_subscribe_by_order(order):
if order and order.enable:
if order.status == 'charged':
order = order.activate_subscribe_for_user()
return order
def get_profile_subscribe_page_content_Dict(request, check_orders_required=False):
def get_profile_subscribe_page_content_html(request):
try:
from GeneralApp.funcs import get_and_set_lang
lang = get_and_set_lang(request)
data = {}
if request.body:
data = json.loads(request.body)
# check_orders_required = False
if data and 'check_orders_required' in data: #Требуется проверка статусов заказов
check_orders_required = data['check_orders_required']
# data = json.loads(request.body)
# all_options = SubscribeOption.objects.filter(enable=True)
subscribes, all_options = get_subsribes_w_options()
subscribes = []
subscribe_for_user = None
all_options = []
orders = None
if request.user and request.user.is_authenticated:
from BillingApp.funcs import get_orders_for_user, get_order_status
orders = get_orders_for_user(request.user)
if orders:
if check_orders_required:
for order in orders:
order = get_order_status(order)
order = check_n_enable_subscribe_by_order(order)
subscribe_for_user = order.subscribe_for_user
subscribes, all_options = get_subscribes_w_options(
request.user, check_subscribe_orders=True)
check_orders_required = False
else:
check_orders_required = True
if not subscribes:
subscribes, all_options = get_subscribes_w_options()
# if not subscribes_for_user:
subscribes_for_user = SubscribeForUser.objects.filter(enable=True, user=request.user)
if not subscribes_for_user:
subscribe_for_user = SubscribeForUser.objects.filter(user=request.user)
if not subscribe_for_user:
tpl_name = 'blocks/profile/b_subscribe_variants.html'
else:
tpl_name = 'blocks/profile/b_subscribe_current.html'
subscribe_for_user = subscribes_for_user[0]
subscribe_for_user = subscribe_for_user[0]
subscribe_options_ids = subscribe_for_user.subscribe.options.values_list('id', flat=True)
subscribe_for_user.subscribe.disabled_options = all_options.exclude(id__in=subscribe_options_ids)
@@ -202,14 +46,11 @@ def get_profile_subscribe_page_content_Dict(request, check_orders_required=False
Dict = {
'subscribe_for_user': subscribe_for_user,
'subscribes': subscribes,
'subscribes': subscribes
}
html = render_to_string(tpl_name, Dict, request=request)
return {
'html': html,
'check_orders_required': check_orders_required,
}
return html
except Exception as e:
msg = f'show_cur_subscribe_ajax Error = {str(e)}'

View File

@@ -6,12 +6,9 @@ from .js_views import *
from django.contrib.auth import views
from RoutesApp.js_views import new_route_view_ajax
# /subscribes/receive_finish_subscribe_msg/
urlpatterns = [
path('show_cur_subscribe/', show_cur_subscribe_ajax, name='show_cur_subscribe_ajax'),
path('subscribe_now/', subscribe_now_ajax, name='subscribe_now_ajax'),
path('receive_finish_subscribe_msg/', receive_finish_subscribe_msg_ajax, name='receive_finish_subscribe_msg_ajax'),
# path('create_ticket/', create_ticket_ajax, name='create_ticket_ajax'),
# path('support_show_chat_by_ticket/', support_show_chat_by_ticket_ajax, name='support_show_chat_by_ticket_ajax'),
# # path('send_msg/', send_msg_ajax, name='send_msg_ajax'),

View File

@@ -3,7 +3,7 @@ from django.shortcuts import render
from uuid import uuid1
from .models import *
from django.contrib import auth
from django.http import HttpResponse, Http404, JsonResponse, HttpResponseRedirect
from django.http import HttpResponse, Http404, JsonResponse
from django.template import loader, RequestContext
from django.contrib.auth.decorators import login_required
from BaseModels.mailSender import techSendMail
@@ -16,80 +16,36 @@ import json
from datetime import datetime, time, timedelta
from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync
from GeneralApp.funcs import get_and_set_lang
from django.shortcuts import redirect
def receive_finish_subscribe_msg_ajax(request):
if request.method != 'POST':
raise Http404
lang = get_and_set_lang(request)
try:
data = json.loads(request.body)
user_subscribe = get_cur_user_subscribe(request.user)
user_subscribe.receive_finish_subscribe_msg = data['receive_finish_subscribe_msg']
user_subscribe.save(update_fields=['receive_finish_subscribe_msg'])
except Exception as e:
msg = f'msg_send_after_subscribe_end_ajax Exception = {str(e)}'
return JsonResponse({'error': msg}, status=400)
res_Dict = {'status': user_subscribe.receive_finish_subscribe_msg}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
@login_required()#login_url='/profile/login/')
@login_required(login_url='/profile/login/')
def subscribe_now_ajax(request):
if request.method != 'POST':
raise Http404
lang = get_and_set_lang(request)
try:
data = json.loads(request.body)
subscribe = Subscribe.objects.get(id=data['subscribe_id'])
kwargs_for_order = {
kwargs = {
'user': request.user,
'subscribe': subscribe,
'currency': 'KZT',
'sum': subscribe.price,
'last_paid_DT': datetime.now(),
'paid_period_from_DT': datetime.now(),
'paid_period_to_DT': datetime.now() + timedelta(hours=subscribe.period),
'receive_finish_subscribe_msg': True,
}
subscribe_for_user = None
if subscribe.price > 0:
from BillingApp.funcs import create_subscribe_order
order = create_subscribe_order(kwargs_for_order)
if order:
res_Dict = {'redirect_url': order.pay_page}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
subscribe_for_user = SubscribeForUser.objects.filter(user=request.user)
if subscribe_for_user:
subscribe_for_user.update(**kwargs)
subscribe_for_user = subscribe_for_user[0]
else:
subscribe_for_user = subscribe_user_to_null_price_subscribe(request.user)
# kwargs = {
# 'user': request.user,
# 'subscribe': subscribe,
# 'last_paid_DT': datetime.now(),
# 'paid_period_from_DT': datetime.now(),
# 'paid_period_to_DT': datetime.now() + timedelta(hours=subscribe.period),
# 'receive_finish_subscribe_msg': True,
# }
# subscribe_for_user = SubscribeForUser.objects.filter(enable=True, user=request.user)
# if subscribe_for_user:
# subscribe_for_user.update(**kwargs)
# subscribe_for_user = subscribe_for_user[0]
subscribe_for_user = SubscribeForUser.objects.create(**kwargs)
if not subscribe_for_user:
tpl_name = 'blocks/profile/b_subscribe_variants.html'
@@ -108,30 +64,21 @@ def subscribe_now_ajax(request):
}
html = render_to_string(tpl_name, Dict, request=request)
res_Dict = {'html': html}
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
return JsonResponse({'html': html}, status=200)
except Exception as e:
msg = f'show_cur_subscribe_ajax Error = {str(e)}'
return JsonResponse({'error': msg}, status=400)
@login_required()#login_url='/profile/login/')
@login_required(login_url='/profile/login/')
def show_cur_subscribe_ajax(request):
if request.method != 'POST':
raise Http404
lang = get_and_set_lang(request)
res_Dict = get_profile_subscribe_page_content_Dict(request)
from GeneralApp.funcs import get_add_to_ajax_response_Dict
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
return JsonResponse(res_Dict)
html = get_profile_subscribe_page_content_html(request)
return JsonResponse({'html': html}, status=200)
# try:
#

View File

@@ -1,33 +0,0 @@
# Generated by Django 4.2.2 on 2024-06-02 12:58
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('SubscribesApp', '0003_alter_subscribe_bg_color_alter_subscribe_text_color'),
]
operations = [
migrations.AddField(
model_name='subscribeforuser',
name='used_route_rising_count',
field=models.IntegerField(default=0, verbose_name='Использовано поднятий объявлений'),
),
migrations.AddField(
model_name='subscribeforuser',
name='used_route_select_count',
field=models.IntegerField(default=0, verbose_name='Использовано выделений объявлений'),
),
migrations.AddField(
model_name='subscribeoption',
name='allow_route_rising_count',
field=models.IntegerField(default=0, verbose_name='Количество поднятий объявлений'),
),
migrations.AddField(
model_name='subscribeoption',
name='allow_route_select_count',
field=models.IntegerField(default=0, verbose_name='Количество выделений объявлений'),
),
]

View File

@@ -1,18 +0,0 @@
# Generated by Django 4.2.2 on 2024-06-03 02:30
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('SubscribesApp', '0004_subscribeforuser_used_route_rising_count_and_more'),
]
operations = [
migrations.RenameField(
model_name='subscribeforuser',
old_name='used_route_select_count',
new_name='used_route_highlight_count',
),
]

View File

@@ -1,18 +0,0 @@
# Generated by Django 4.2.2 on 2024-06-03 02:43
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('SubscribesApp', '0005_rename_used_route_select_count_subscribeforuser_used_route_highlight_count'),
]
operations = [
migrations.RenameField(
model_name='subscribeoption',
old_name='allow_route_select_count',
new_name='allow_route_highlight_count',
),
]

View File

@@ -1,18 +0,0 @@
# Generated by Django 4.2.2 on 2024-08-13 13:28
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('SubscribesApp', '0006_rename_allow_route_select_count_subscribeoption_allow_route_highlight_count'),
]
operations = [
migrations.AddField(
model_name='subscribeoption',
name='route_highlight_hours',
field=models.IntegerField(default=24, verbose_name='Количество часов выделения цветом объявлений'),
),
]

View File

@@ -1,14 +0,0 @@
# Generated by Django 4.2.2 on 2025-02-17 17:48
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('SubscribesApp', '0004_alter_subscribe_bg_color_alter_subscribe_text_color'),
('SubscribesApp', '0007_subscribeoption_route_highlight_hours'),
]
operations = [
]

View File

@@ -1,29 +1,10 @@
from django.db import models
from django.db.models import Count, Sum, F
from django.db.models.functions import Coalesce
from BaseModels.base_models import BaseModel
from django.utils.translation import gettext_lazy as _
from colorfield.fields import ColorField
from datetime import datetime, timedelta
# options_list 29.05.2024
# СМС уведомления
# push уведомления
# выделение заявки цветом (20 заявок) + 70 поднятий
# выделение заявок цветом (3 заявки) + 5 поднятий
# уведомление на e-mail о появлении перевозчика по заданным критериям
# размещение заявок
# просмотр контактов
class SubscribeOption(BaseModel):
allow_route_rising_count = models.IntegerField(
verbose_name=_('Количество поднятий объявлений') ,default=0)
allow_route_highlight_count = models.IntegerField(
verbose_name=_('Количество выделений объявлений'), default=0)
route_highlight_hours = models.IntegerField(
verbose_name=_('Количество часов выделения цветом объявлений'), default=24)
class Meta:
verbose_name = _('Опция подписки')
verbose_name_plural = _('Опции подписки')
@@ -35,8 +16,7 @@ class Subscribe(BaseModel):
price = models.FloatField(verbose_name='Стоимость', default=0)
options = models.ManyToManyField(
SubscribeOption, verbose_name=_('Подключенные опции'), blank=True,
related_name='rel_subscribes_for_option'
SubscribeOption, verbose_name=_('Подключенные опции'), blank=True, related_name='rel_subscribes_for_option'
)
period_name = models.CharField(max_length=250, verbose_name=_('Название периода'))
period = models.IntegerField(default=0, verbose_name=_('Длительность подписки в часах'))
@@ -44,13 +24,6 @@ class Subscribe(BaseModel):
bg_color = ColorField(default='#FFFFFF', verbose_name=_('Цвет фона'))
text_color = ColorField(default='#000000', verbose_name=_('Цвет текста'))
def get_last_order(self, user):
order = None
orders = self.subscribe_orders_for_subscribe.filter(user=user, enable=True).order_by('-createDT')
if orders:
order = orders[0]
return order
class Meta:
verbose_name = _('Подписка')
verbose_name_plural = _('Подписки')
@@ -74,80 +47,6 @@ class SubscribeForUser(BaseModel):
receive_finish_subscribe_msg = models.BooleanField(
default=False, verbose_name=_('Получать сообщения о окончании периода'))
used_route_rising_count = models.IntegerField(verbose_name=_('Использовано поднятий объявлений'), default=0)
used_route_highlight_count = models.IntegerField(verbose_name=_('Использовано выделений объявлений'), default=0)
class Meta:
verbose_name = _('Пользовательская подписка')
verbose_name_plural = _('Пользовательские подписки')
def __str__(self):
res = 'Подписка'
if self.subscribe:
res += f' {self.subscribe.name}'
if self.user:
res += f' для {self.user.username}'
if not res:
res += f' {str(self.id)}'
return res
def get_highlight_hours(self):
options = self.subscribe.options.filter(
allow_route_highlight_count__gt=0,
)
if options:
return options[0].route_highlight_hours
return 0
def remains_route_adding_options(self):
total_data = SubscribeOption.objects.filter(
enable=True, rel_subscribes_for_option=self.subscribe
).aggregate(
total_route_rising_count = Coalesce(Sum('allow_route_rising_count'), 0),
total_route_highlight_count = Coalesce(Sum('allow_route_highlight_count'), 0),
)
total_data.update({
'used_route_rising_count': self.used_route_rising_count,
'used_route_highlight_count': self.used_route_highlight_count,
'remains_route_rising_count': total_data['total_route_rising_count'] - self.used_route_rising_count,
'remains_route_highlight_count': total_data['total_route_highlight_count'] - self.used_route_highlight_count,
})
return total_data
def get_days_to_finish(self):
days = (self.paid_period_to_DT - datetime.now()).days
return days
def extension(self, order=None):
if not order and self.subscribe.price > 0:
return {'error': 'not paid'}
if self.subscribe.price == 0:
self.activate(
paid_period_from_DT=datetime.now(),
paid_period_to_DT=datetime.now() + timedelta(hours=self.subscribe.period)
)
def activate(self, paid_period_from_DT=None, paid_period_to_DT=None):
self.enable = True
if paid_period_from_DT:
self.paid_period_from_DT = paid_period_from_DT
if paid_period_to_DT:
self.paid_period_to_DT = paid_period_to_DT
self.save()
subscribes_for_user = SubscribeForUser.objects.filter(
user=self.user
).exclude(
id=self.id
)
subscribes_for_user.update(
enable=False,
used_route_rising_count=0,
used_route_highlight_count=0,
)
return self
verbose_name_plural = _('Пользовательские подписки')

View File

@@ -1,58 +0,0 @@
from .models import *
from datetime import datetime, timedelta
from .funcs import *
from django.utils.translation import gettext as _
def send_mail_for_user_subscribes_that_is_going_to_finish():
log = ''
user_subscribes = get_user_subscribes_that_is_going_to_finish()
for user_subscribe in user_subscribes:
if not user_subscribe.receive_finish_subscribe_msg:
continue
try:
from GeneralApp.funcs_options import get_options_by_opt_types, get_mail_send_options
sets = get_options_by_opt_types(['domain', 'project_name'], only_vals=True)
subject = _('tripwb.com - Уведомление о скором окончании срока подписки')
Dict = {
'logo': f'{sets["domain"]}/static/img/svg/LogoMobile.svg',
'message_title': subject,
'user_subscribe': user_subscribe
}
Dict.update(sets)
html = render_to_string('mail/m_user_subscribes_that_is_going_to_finish.html', Dict)
from BaseModels.mailSender import admin_send_mail_by_SMTPlib
mail_sets = get_mail_send_options()
to = [user_subscribe.user.email]
res = admin_send_mail_by_SMTPlib(
mail_sets,
subject=subject,
from_email=mail_sets['sender_email'], to=to,
html_content=html
)
if res and type(res) == str:
print(res)
# log += f'\n{res}'
to = ['web@syncsystems.net', 'sa@a3-global.com', 'sysadmin.hax@gmail.com']
admin_send_mail_by_SMTPlib(
mail_sets,
subject=subject,
from_email=mail_sets['sender_email'], to=to,
html_content=html
)
except Exception as e:
msg = (f'send_mail_for_user_subscribes_that_is_going_to_finish '
f'for user {user_subscribe.user} '
f'Exception = {str(e)}')
print(msg)
log += f'\n{msg}'
return log

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()

View File

@@ -1 +0,0 @@
__author__ = 'SDE'

View File

@@ -1,157 +0,0 @@
__author__ = 'SDE'
from django import template
from django.template.defaultfilters import stringfilter
register = template.Library()
from django.core.serializers import serialize
from django.db.models.query import QuerySet
# import simplejson
from django.template import Library
from django.utils.html import mark_safe
# @register.filter('get_value_from_dict')
# def get_value_from_dict(dict_data, key):
# """
# usage example {{ your_dict|get_value_from_dict:your_key }}
# """
#
# if key in dict_data:
# res = dict_data[key]
# return res
#
# return False
#
#
#
# @register.filter()
# def get_rows_count_by_cols_count(data, cols_count):
# rows_count = len(data) // cols_count
# if len(data) % cols_count:
# rows_count += 1
# return rows_count
#
# @register.filter()
# def get_numbers_list(from_el, to_el):
# res = range(from_el, to_el+1)
# return res
#
#
# def val_type(value):
# res = type(value)
# return res.__name__
# register.filter('val_type', val_type)
#
# @register.filter()
# def get_cols_table_data_for_row_when_cols3(value, row):
# el_count = 3
# from_el = (row-1) * el_count
# to_el = row * el_count
# part = list(value)[from_el:to_el]
# return part
# # register.filter('val_type', val_type)
#
#
# @register.filter
# @stringfilter
# def correct_for_tables(value):
# if value in ['None', '0.0']:
# return '-'
# return value
#
#
# @register.filter
# @stringfilter
# def del_bad_symbols(value):
# from BaseModels.functions import del_bad_symbols
# return del_bad_symbols(value)
#
#
# @register.filter
# @stringfilter
# def del_amp_symbols(value):
# from BaseModels.functions import del_nbsp
# return del_nbsp(value)
#
# @register.filter
@register.simple_tag()
def check_subscribe_option(s_user, option_name):
from ..funcs import check_option_in_cur_user_subscribe
res = check_option_in_cur_user_subscribe(s_user, option_name)
return res
#
# @register.filter
# @stringfilter
# def get_color_by_number(value, arg=None):
#
# color = None
# try:
# val = float(value)
#
# if not color and arg == u'%':
#
# color = u'black'
# if val > 50:
# color = u'green'
# elif val <= 50 and val >= 25:
# color = u'#6c8107'
# elif val <= 25 and val >= 10:
# color = u'#a89803'
# elif val <= 10 and val >= 5:
# color = u'#e6a707'
# elif val <= 5 and val >= 0:
# color = u'#e67307'
# elif val <= 0:
# color = u'red'
#
#
# # val_range = val_max - val_min
# # # val_percent = (val_range * 100 / val) - 100
# # offset = -(val_min + -(val))
# # if val <0:
# # val = offset
# # if val > val_max:
# # val = val_max
# # elif val < 0:
# # val = 0
# #
# # color_range = 16711680 - 1211136
# # val_1unit = float(color_range) / float(val_range)
# # dec_color = 16711680 - int(val_1unit * val)
#
# if not color:
# color = u'black'
# if val > 1000:
# color = u'green'
# elif val <= 1000 and val >= 500:
# color = u'#6c8107'
# elif val <= 500 and val >= 250:
# color = u'#a89803'
# elif val <= 250 and val >= 125:
# color = u'#e6a707'
# elif val <= 125 and val >= 50:
# color = u'#e67307'
# elif val <= 50:
# color = u'red'
#
# # s = u'style="color: #{0}12;"'.format(str(hex(dec_color))[2:6])
# s = u'style="color: {0};"'.format(color)
# return s
# except:
# return u''
#
#
# # @register.filter
# # @stringfilter
# # def check_aprox_compare_strings(search_phrase, txt):
# # from ProductApp.search import get_highlight_string
# #
# # s = get_highlight_string(search_phrase, txt)
# #
# # return s

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
@@ -29,22 +30,13 @@ DEBUG = True
ALLOWED_HOSTS = ["*"]
# https://web-push-codelab.glitch.me/
WEBPUSH_SETTINGS = {
"VAPID_PUBLIC_KEY": "BNUNtlKRY-9h2rFemuT6cODbg1Lkl9zMJJl9vcoVxoSXOYTpT-y8iHIseTsrzsSH03462tjYNx38fTkWyumKyEM",
"VAPID_PRIVATE_KEY": "ECoHc1i_XcLEo6KmkF76sHvdk49qBA4aNFyns6N3fPs",
"VAPID_ADMIN_EMAIL": "tripwithbonus@gmail.com"
"VAPID_PUBLIC_KEY": "BKS8byh3MucwCF2h06JY9oey1s1RYII09j-j3ehI3qTYhs965UHv0qNPl-jFjQBbIJCvjVXm9RW6t_oJJK8yMOk",
"VAPID_PRIVATE_KEY": "f5NMgOntBtRqsyeKwEzloK-051ggMnZGF_GFimERY0w",
"VAPID_ADMIN_EMAIL": "admin@tripwb.com"
}
PAY_SYSTEM_URL = 'https://sandboxapi.paymtech.kz/'
PKCS12_PASS = 'QNlhRStcY7mB'
API_PASS = 'aPqSRVZhxFjjSqbB'
PKCS12_FILENAME = 'dvldigitalprojects.p12'
# PAY_SYSTEM_URL = 'https://api.paymtech.kz/'
# PKCS12_PASS = 'fzSBm6WISje7'
# API_PASS = 't9g2+bZSvxNxCu+t'
# PKCS12_FILENAME = 'dvldigitalprojects_prod.p12'
SOCIALACCOUNT_LOGIN_ON_GET=True
ACCOUNT_DEFAULT_HTTP_PROTOCOL='https'
@@ -54,9 +46,7 @@ ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_EMAIL_VERIFICATION = 'optional'
LOGIN_REDIRECT_URL = '/profile/page/dashboard/'
# LOGIN_URL = '/profile/login/'
from django.urls import reverse_lazy
LOGIN_URL = reverse_lazy('login_profile')
LOGIN_URL = '/profile/login/'
LOGOUT_REDIRECT_URL = '/profile/login/'
@@ -71,7 +61,6 @@ AUTHENTICATION_BACKENDS = [
]
SOCIALACCOUNT_PROVIDERS = {
'google': {
'SCOPE': [
@@ -104,8 +93,6 @@ INSTALLED_APPS = [
'django.contrib.staticfiles',
'django.contrib.humanize',
'django.contrib.sitemaps',
'django.contrib.sites',
'colorfield',
@@ -120,8 +107,6 @@ INSTALLED_APPS = [
'allauth.socialaccount',
'allauth.socialaccount.providers.google',
'rosetta',
'GeneralApp',
'AuthApp',
'RoutesApp',
@@ -129,7 +114,6 @@ INSTALLED_APPS = [
'ArticlesApp',
'SubscribesApp',
'PushMessages',
'BillingApp',
]
MIDDLEWARE = [
@@ -173,8 +157,7 @@ TEMPLATES = [
# WSGI_APPLICATION = 'TWB.wsgi.application'
ASGI_APPLICATION = 'TWB.asgi.application'
# WS_ADDRESS = 'localhost:8000'
WS_ADDRESS = 'tripwb.com'
WS_ADDRESS = 'localhost:8000'
CHANNEL_LAYERS = {
'default': {
@@ -189,11 +172,8 @@ CHANNEL_LAYERS = {
}
POSTGRES_DB = config('POSTGRES_DB')
POSTGRES_USER = config('POSTGRES_USER')
# Database
@@ -202,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',
@@ -266,7 +246,6 @@ LOCALE_PATHS = (
gettext = lambda s: s
LANGUAGES = (
(u'ru', gettext(u'Russian')),
@@ -354,9 +333,15 @@ CKEDITOR_CONFIGS = {
}
}
CELERY_BROKER_URL = config('CELERY_BROKER_URL')
CELERY_RESULT_BACKEND = config('CELERY_RESULT_BACKEND')
ROSETTA_MESSAGES_PER_PAGE = 100
ROSETTA_SHOW_AT_ADMIN_PANEL = True
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 = {

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,16 +1,13 @@
from django.contrib import admin
from django.urls import path, include, re_path
from django.urls import path, include
from django.conf.urls.static import static
from django.conf import settings
from GeneralApp.views import Page404
from AuthApp.views import login_View
from django.views.generic.base import RedirectView
handler404 = Page404
urlpatterns = [
# path('admin/', admin.site.urls),
path('ckeditor/', include('ckeditor_uploader.urls')),
path('i18n/', include('django.conf.urls.i18n')),
@@ -41,8 +38,8 @@ urlpatterns = [
path('test_404', Page404, name='page_404'),
path('', include('PushMessages.urls')),
path('', include('SubscribesApp.urls')),
path('', include('SitemapApp.urls')),
]
from django.conf.urls.i18n import i18n_patterns
@@ -57,13 +54,7 @@ urlpatterns += i18n_patterns(
path('', include('ArticlesApp.urls_translate')),
path('favicon.svg',RedirectView.as_view(url='/static/favicon.ico')),
)
if 'rosetta' in settings.INSTALLED_APPS:
urlpatterns += [
re_path(r'^rosetta/', include('rosetta.urls'))
]
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Binary file not shown.

Binary file not shown.

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=

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 95 KiB

View File

@@ -1 +0,0 @@
google-site-verification: google180852ecd111cd7b.html

File diff suppressed because it is too large Load Diff

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
@@ -10,11 +9,9 @@ channels==4.0.0
daphne==4.0.0
channels-redis==4.1.0
django-colorfield
django-webpush==0.3.6
django-webpush==0.3.5
django-allauth==0.60.0
pytz==2024.1
requests-pkcs12==1.24
#django-tz-detect==0.4.0
django-rosetta==0.10.0
timezonefinder==6.5.2
celery==5.3.6
djangorestframework==3.14.0
python-decouple==3.8

View File

@@ -1,5 +1,4 @@
User-agent: *
Allow: /
Disallow: */admin/*
Disallow: /
Host: tripwb.com

View File

@@ -1,10 +1,6 @@
from BaseModels.admin_utils import (
Admin_GenericBaseIconStackedInline, Admin_BaseIconModel, GenericStackedInline,
AdminImageWidget, get_image_thumb
)
from BaseModels.admin_utils import Admin_GenericBaseIconStackedInline, Admin_BaseIconModel, GenericStackedInline
from copy import deepcopy
from django.db import models
from django.utils.translation import gettext as _
class Admin_BaseModel(Admin_BaseIconModel):
@@ -90,69 +86,24 @@ class AdminTranslationBase(TranslationAdmin):
'screen': ('modeltranslation/css/tabbed_translation_fields.css',),
}
from modeltranslation.admin import TranslationGenericStackedInline, TranslationGenericTabularInline
class TranslationGenericTabularInlineCustom(TranslationGenericTabularInline):
formfield_overrides = {
models.ImageField: {'widget': AdminImageWidget},
}
def image_thumb(self, obj):
return get_image_thumb(self, obj)
image_thumb.short_description = _('Миниатюра')
image_thumb.allow_tags = True
class Media:
js = (
'modeltranslation/js/force_jquery.js',
'http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js',
'http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js',
'modeltranslation/js/tabbed_translation_fields.js',
)
css = {
'screen': ('modeltranslation/css/tabbed_translation_fields.css',),
}
class TranslationGenericStackedInlineCustom(TranslationGenericStackedInline):
formfield_overrides = {
models.ImageField: {'widget': AdminImageWidget},
}
def image_thumb(self, obj):
return get_image_thumb(self, obj)
image_thumb.short_description = _('Миниатюра')
image_thumb.allow_tags = True
class Media:
js = (
'modeltranslation/js/force_jquery.js',
'http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js',
'http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js',
'modeltranslation/js/tabbed_translation_fields.js',
)
css = {
'screen': ('modeltranslation/css/tabbed_translation_fields.css',),
}
class AdminStacked_FAQitem(TranslationGenericStackedInlineCustom):
from modeltranslation.admin import TranslationGenericStackedInline
class AdminStacked_FAQitem(TranslationGenericStackedInline):
from GeneralApp.models import FAQitem
model = FAQitem
extra = 0
fields = ['order', 'question', 'answer']
class Media:
class AdminTabular_Mediaitem(TranslationGenericTabularInlineCustom):
from GeneralApp.models import MediaItem
model = MediaItem
extra = 0
fields = ['order', 'video', 'picture']
js = (
'modeltranslation/js/force_jquery.js',
'http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js',
'http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js',
'modeltranslation/js/tabbed_translation_fields.js',
)
css = {
'screen': ('modeltranslation/css/tabbed_translation_fields.css',),
}
class Admin_BaseModelViewPage(Admin_BaseIconModel):
pass
@@ -178,7 +129,7 @@ class Admin_BaseModelViewPage(Admin_BaseIconModel):
# else:
# return {}
#
inlines = [AdminStacked_FAQitem, AdminTabular_Mediaitem]
inlines = [AdminStacked_FAQitem]

View File

@@ -3,7 +3,7 @@
@media (max-width: 1280px){
.remove_route{
width: 100%;
text-align: center;
}
@@ -116,19 +116,11 @@
}
@media (max-width: 1180px){
.container_inf_about_moving{
padding: 15px;
}
.input_list.find_route{
left: unset;
width: 70%;
}
.dropdown{
vertical-align: sub;
}
.handler_curtain_left{
display: block;
}
@@ -144,10 +136,6 @@
transition: 200ms;
}
.unsubscribe_info {
font-size: 12px;
}
.container_content_handler_curtain_left{
display: flex;
rotate: 90deg;
@@ -266,7 +254,7 @@
}
header{
padding: 3px 16px;
padding: 5px 16px;
margin-top: unset;
}
.header_logo, .header_btn_mover, .header_btn_sender{
@@ -371,7 +359,7 @@
.info_profile>div>div>.left-part-carrier-card>.container_inf_about_moving{
width: 98%;
width: 100%;
}
@@ -398,14 +386,11 @@
margin-left: 5px;
}
.header_logo_mobile {
margin-right: 20px;
margin-right: 37px;
}
.line_f_header{
top: 43px;
}
header .header-second{
margin-top: 3px;
}
.self_news_img{
width: 40%;
@@ -509,9 +494,7 @@
.footer_logo{
text-align: center;
margin: 40px auto;
max-width: 90px;
/*margin-left: 43%;*/
margin: 40px 0;
}
.footer_text_sub{
@@ -734,7 +717,7 @@
margin-bottom: 25px;
}
ч
.arrange_subscribe{
margin: 20px auto 20px auto;
}
@@ -1118,12 +1101,9 @@
.left-part-carrier-card, .inf_carrier_container{
width: unset;
float: none;
padding: 1px 20px;
padding: 1px 15px;
border-right: unset;
}
.control_frame{
top: 3px;
}
.inf_carrier_container{
padding-top: 70px;
padding-bottom: 10px;
@@ -1153,7 +1133,7 @@
.cargo_type_trans{
display: block;
margin-bottom: 15px;
float: unset;
/*float: unset;*/
}
.from-to-country-container-carrier{
@@ -1201,7 +1181,7 @@
.from-to-city-text{
font-size: 12px;
font-weight: 400;
/*padding-bottom: 10px;*/
padding-bottom: 10px;
/*padding-top: unset;*/
}
.arrow_inf_about_moving{
@@ -1214,7 +1194,6 @@
font-style: normal;
font-weight: 600;
text-align: center;
margin-top: 7px;
}
.inf_carrier_icon{
width: 20px;
@@ -1229,7 +1208,7 @@
padding-right: unset;
font-size: 14px;
top: unset;
/*background: linear-gradient(99deg, #000000 1%, #ffffff 16%, #ffffff);*/
background: linear-gradient(99deg, #000000 1%, #ffffff 16%, #ffffff);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
@@ -1239,7 +1218,6 @@
.name_carrier{
font-size: 14px;
position: unset;
}
@@ -1345,10 +1323,6 @@
justify-content: space-between;
}
.subscribe_wrpapper{
justify-content: space-between;
}
.text_another_subscribe{
font-size: 12px;
font-style: normal;
@@ -1510,19 +1484,11 @@
width: 153px;
}
.popup_content{
width: 41%;
}
}
@media (max-width: 950px){
#title_static_small{
display: none;
}
.info_profile{
width: 65%;
float: none;
@@ -1558,9 +1524,6 @@
.pag_news_item_text{
width: unset;
}
.popup_content{
width: 52%;
}
}
@media (max-width: 850px){
@@ -1605,7 +1568,7 @@
.read_more_about_subscribe, .read_more_about_subscribe.error {
.read_more_about_subscribe{
padding: 0 14px;
height: 30px;
font-size: 14px;
@@ -1664,21 +1627,15 @@
.toggle_switch_cont{
margin-top: 6px;
width: unset;
width: 12%;
}
}
@media (max-width: 800px) {
.line_inf_about_moving{
margin-bottom: 40px;
}
.marker_messages_mobile{
position: absolute;
top: 0;
@@ -1694,9 +1651,6 @@
.marker_messages_mobile.show{
display: block;
}
.popup_content>.confirm_profile_btn{
width: 90%;
}
}
@media (max-width: 828px){
@@ -1730,9 +1684,8 @@
}
.subscribe_wrpapper{
flex-direction: column;
.another_subscribe {
flex-direction: column;
}
.info_profile>div>div>.left-part-carrier-card>.container_inf_about_moving>.line_inf_about_moving>.carrier_inf_moving.left{
@@ -1788,10 +1741,6 @@
background: #ffffff;
}
.dropdown-content-lang{
z-index: 1 ;
}
.menu_buttons.right.open .handler_menu{
background: #FFFFFF;
color: #000000;
@@ -1843,20 +1792,14 @@
width: 100%;
}
.subscribe_wrpapper{
padding: 10px;
.another_subscribe{
padding: 10px;
flex-direction: unset;
justify-content: space-between;
}
.inf_carrier_icon{
/*width: 3%;*/
}
.popup_content{
width: 70%;
}
}
@media (max-width: 687px){
/*.to_address_point_txt.find_route {*/
@@ -1865,10 +1808,6 @@
/*.from_address_point_txt.find_route.first {*/
/* width: 52.1%;*/
/*}*/
.info_profile>div>div>.left-part-carrier-card>.container_inf_about_moving{
width: 98%;
}
.container_inf_about_moving {
width: 97%;
@@ -1909,10 +1848,6 @@
.info_profile>div>div>.left-part-carrier-card>.container_inf_about_moving{
width: 89%;
}
.phones_carrier{
display: block;
}
@@ -1938,7 +1873,6 @@
.container_inf_about_moving{
width: 100%;
padding: 16px;
}
.arrow_inf_about_moving{
@@ -1959,11 +1893,6 @@
margin-bottom: unset;
}
.name_carrier{
position: relative;
}
.splitter-from-to-country{
@@ -2040,7 +1969,7 @@
}
.dropdown-content{
width: 202px;
width: 190px;
top: 27px;
left: -83px;
}
@@ -2095,13 +2024,9 @@
.another_subscribe{
padding: 15px 0;
flex-direction: column;
justify-content: unset;
}
.subscribe_wrpapper, .error_order{
flex-direction: column;
justify-content: unset;
width: unset;
}
}

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More