From 7b0308fa62ba82fac9d0e6c9149fc5e8a58e69bd Mon Sep 17 00:00:00 2001 From: Nagaev Dmitry Date: Fri, 26 Jan 2024 20:37:05 +0500 Subject: [PATCH 1/5] Change Yoomoney wallet account * change yoomoney widget wallet account * update django settings --------- Co-authored-by: nagaev.d --- haxball_site/haxball_site/settings.py | 4 ++-- haxball_site/templates/core/home.html | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/haxball_site/haxball_site/settings.py b/haxball_site/haxball_site/settings.py index 1fc80f7e..35c0c193 100644 --- a/haxball_site/haxball_site/settings.py +++ b/haxball_site/haxball_site/settings.py @@ -29,7 +29,7 @@ if DEBUG: ALLOWED_HOSTS = [] else: - ALLOWED_HOSTS = ['185.7.145.200', 'cis-haxball.com', '127.0.0.1'] + ALLOWED_HOSTS = ['45.135.233.214', 'cis-haxball.com', 'www.cis-haxball.com', '127.0.0.1'] # Application definition @@ -204,7 +204,7 @@ STATIC_ROOT = os.path.join(BASE_DIR, 'static') STATIC_URL = '/static/' MEDIA_URL = '/media/' - MEDIA_ROOT = '/root/site/media' + MEDIA_ROOT = '/home/site/media' CKEDITOR_UPLOAD_PATH = "uploads/" diff --git a/haxball_site/templates/core/home.html b/haxball_site/templates/core/home.html index 4258a0f6..88cdaccf 100644 --- a/haxball_site/templates/core/home.html +++ b/haxball_site/templates/core/home.html @@ -60,7 +60,7 @@
Смотрите нас тут
-
From 3e3caec14e5825cbaa2419e55026b420dcd24448 Mon Sep 17 00:00:00 2001 From: Nagaev Dmitry Date: Sat, 27 Jan 2024 22:10:57 +0500 Subject: [PATCH 2/5] Prepare project for further development (#1) * add dotenv for configuration, remove secrets from code * add instruction how to run project * change wallet account at yoomoney widget * replace 'python-dotenv' with 'python-decouple' * Add 10-11 seasons to archive (#3) * split requirements.txt into several files for dev and prod * update quickstart * add URL_PREFIX settings --------- Co-authored-by: nagaev.d Co-authored-by: Alex-Ish <84282661+Alex-Ish@users.noreply.github.com> --- .gitignore | 6 ++- README.md | 30 ++++++++++++ haxball_site/.env.example | 16 +++++++ haxball_site/haxball_site/settings.py | 35 +++++++------- haxball_site/haxball_site/urls.py | 3 ++ .../templates/core/include/navbar.html | 24 ++++++++++ requirements.txt | 47 +------------------ .../common.txt | 12 +++-- requirements/dev.txt | 3 ++ requirements/prod.txt | 3 ++ 10 files changed, 110 insertions(+), 69 deletions(-) create mode 100644 haxball_site/.env.example rename requirements_pyrhon3_9.txt => requirements/common.txt (90%) create mode 100644 requirements/dev.txt create mode 100644 requirements/prod.txt diff --git a/.gitignore b/.gitignore index 8e077e63..8e8e5a38 100644 --- a/.gitignore +++ b/.gitignore @@ -109,7 +109,11 @@ media/ *.pyc *.db *.pid + # django migrations **/migrations/** !**/migrations -!**/migrations/__init__.py \ No newline at end of file +!**/migrations/__init__.py + +# site_cache +/haxball_site/mycache/ diff --git a/README.md b/README.md index 4dc45c2b..822dfc73 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,33 @@ # haxball Blog-site with social component and tables for creating haxball championships [cis-haxball](https://cis-haxball.com/) + +## Запуск проекта + +### Prerequisites +- [Python 3.12+](https://www.python.org/downloads/) +- [pip](https://pip.pypa.io/en/stable/) (в большинстве случаев устанавливается вместе с python; если этого не произошло, установить [вручную](https://pip.pypa.io/en/latest/installation/)) +- [sqlite3](https://www3.sqlite.org/index.html) +- [postgres](https://www.postgresql.org/download/) +- Python IDE (например, [PyCharm Community Edition](https://www.jetbrains.com/pycharm/download/)) + +### Подготовка +- Настраиваем интерпретатор для проекта и создаем [venv](https://www.jetbrains.com/help/pycharm/creating-virtual-environment.html) + (в результате должна появиться директория venv в корне) +- Устанавливаем зависимости `pip install -r requirements/dev.txt'` +- `cd haxball_site` +- Заполняем настройками файл с конфигурацией - .env (шаблон можно взять из .env.example) +- Подготавливаем БД + - `python manage.py makemigrations` + - `python manage.py migrate` +- Создаем суперюзера `python manage.py createsuperuser` + +### Запуск +Поднимаем development server +`python manage.py runserver` + +### Troubleshooting +- Если при подготовке БД возникает ошибка `django.db.utils.OperationalError: no such table: auth_user`, попробуйте + закомментировать строчку `path('', include('core.urls', namespace='core'))` в `haxball_site\urls.py`, затем прогнать миграции, а после включить ее обратно +- Если при регистрации на сайте вы видите ошибку `TypeError: SMTP.starttls() got an unexpected keyword argument 'keyfile'`, + ее можно устранить [следующим образом](https://github.com/packtpublishing/django-4-by-example/issues/41) diff --git a/haxball_site/.env.example b/haxball_site/.env.example new file mode 100644 index 00000000..4cd8fda6 --- /dev/null +++ b/haxball_site/.env.example @@ -0,0 +1,16 @@ +APP_DEBUG=True +APP_SECRET_KEY=#secret_key +APP_ALLOWED_HOSTS='' +APP_URL_PREFIX='' + +EMAIL_HOST=smtp.gmail.com +EMAIL_PORT=587 +EMAIL_USE_TLS=True +EMAIL_HOST_USER=#email_host_username@gmail.com +EMAIL_HOST_PASSWORD=#email_host_user_pass + +DB_NAME=hax_db +DB_USER=#dbuser +DB_PASSWORD=#dbuser_pass +DB_HOST=localhost +DB_PORT=5432 \ No newline at end of file diff --git a/haxball_site/haxball_site/settings.py b/haxball_site/haxball_site/settings.py index 35c0c193..5d5c87fa 100644 --- a/haxball_site/haxball_site/settings.py +++ b/haxball_site/haxball_site/settings.py @@ -12,8 +12,9 @@ import os +from decouple import config + # Build paths inside the project like this: os.path.join(BASE_DIR, ...) -import socket BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) @@ -21,15 +22,15 @@ # See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'm_5m)8w^h+8avxko^()kmlr6fnp(r+m1^=(m!kldx$*47(-za6' +SECRET_KEY = config('APP_SECRET_KEY') # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = False +DEBUG = config('APP_DEBUG', cast=bool, default=False) if DEBUG: ALLOWED_HOSTS = [] else: - ALLOWED_HOSTS = ['45.135.233.214', 'cis-haxball.com', 'www.cis-haxball.com', '127.0.0.1'] + ALLOWED_HOSTS = config('APP_ALLOWED_HOSTS', cast=str.split) # Application definition @@ -113,11 +114,11 @@ DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': 'hax_db', - 'USER': 'kikimor24', - 'PASSWORD': 'gibby4mopolnoye322', - 'HOST': 'localhost', - 'PORT': '5432', + 'NAME': config('DB_NAME'), + 'USER': config('DB_USER'), + 'PASSWORD': config('DB_PASSWORD'), + 'HOST': config('DB_HOST'), + 'PORT': config('DB_PORT'), } } @@ -160,7 +161,6 @@ USE_L10N = True if DEBUG: - # EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend' EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' # ACCOUNT_EMAIL_REQUIRED = True # ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS = 1 @@ -170,7 +170,6 @@ ACCOUNT_EMAIL_REQUIRED = True ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS = 1 ACCOUNT_EMAIL_VERIFICATION = True - # ACCOUNT_USERNAME_MIN_LENGTH = 1 if DEBUG: CACHES = { @@ -187,17 +186,17 @@ } } -EMAIL_HOST = 'smtp.gmail.com' -EMAIL_USE_TLS = True -EMAIL_PORT = 587 -EMAIL_HOST_USER = 'haxballcis@gmail.com' -EMAIL_HOST_PASSWORD = 'lecscwvmksyimskp' +EMAIL_HOST = config('EMAIL_HOST') +EMAIL_PORT = config('EMAIL_PORT', cast=int) +EMAIL_USE_TLS = config('EMAIL_USE_TLS', cast=bool, default=True) +EMAIL_HOST_USER = config('EMAIL_HOST_USER') +EMAIL_HOST_PASSWORD = config('EMAIL_HOST_PASSWORD') +DEFAULT_FROM_EMAIL = EMAIL_HOST_USER if DEBUG: STATIC_URL = '/static/' STATIC_DIR = os.path.join(BASE_DIR, 'static') STATICFILES_DIRS = [STATIC_DIR] - # STATIC_ROOT = os.path.join(BASE_DIR, 'static') MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media') else: @@ -213,6 +212,8 @@ SITE_ID = 1 +URL_PREFIX = config('APP_URL_PREFIX', default='') + # Grapelli config GRAPPELLI_ADMIN_TITLE = 'Место уважаемых администраторов' diff --git a/haxball_site/haxball_site/urls.py b/haxball_site/haxball_site/urls.py index 891541e0..0ed02780 100644 --- a/haxball_site/haxball_site/urls.py +++ b/haxball_site/haxball_site/urls.py @@ -34,5 +34,8 @@ #path('froala_editor/',include('froala_editor.urls')) ] +if settings.URL_PREFIX: + urlpatterns = [path(settings.URL_PREFIX, include(urlpatterns))] + if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \ No newline at end of file diff --git a/haxball_site/templates/core/include/navbar.html b/haxball_site/templates/core/include/navbar.html index d3af1df6..5e6b2226 100644 --- a/haxball_site/templates/core/include/navbar.html +++ b/haxball_site/templates/core/include/navbar.html @@ -193,6 +193,30 @@ Лига + ЧР #10 + + + ЧР #11 + diff --git a/requirements.txt b/requirements.txt index e1032418..3e2d68e9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,46 +1 @@ -asgiref==3.2.10 -backcall==0.2.0 -certifi==2020.6.20 -chardet==3.0.4 -colorama==0.4.3 -decorator==4.4.2 -defusedxml==0.6.0 -Django==3.0.8 -django-allauth==0.42.0 -django-autoslug==1.9.7 -django-ckeditor==5.9.0 -django-froala-editor==3.2.0 -django-js-asset==1.2.2 -django-markdownx==3.0.1 -django-online-users==0.3 -django-summernote==0.8.11.6 -gunicorn==20.0.4 -idna==2.10 -ipython==7.17.0 -ipython-genutils==0.2.0 -jedi==0.17.2 -Markdown==3.2.2 -oauthlib==3.1.0 -parso==0.7.1 -pexpect==4.8.0 -pickleshare==0.7.5 -Pillow==9.0.1 -prompt-toolkit==3.0.5 -psycopg2==2.8.5 -ptyprocess==0.6.0 -Pygments==2.6.1 -python3-openid==3.2.0 -pytils==0.3 -pytz==2020.1 -requests==2.24.0 -requests-oauthlib==1.3.0 -six==1.15.0 -sqlparse==0.3.1 -traitlets==4.3.3 -urllib3==1.25.10 -wcwidth==0.2.5 -django-grappelli==2.14.2 -django-smart-selects==1.5.8 -django-colorfield==0.3.2 -python-memcached==1.59 -sorl-thumbnail==12.7.0 \ No newline at end of file +-r requirements/prod.txt \ No newline at end of file diff --git a/requirements_pyrhon3_9.txt b/requirements/common.txt similarity index 90% rename from requirements_pyrhon3_9.txt rename to requirements/common.txt index 2dae00e7..af0cbee7 100644 --- a/requirements_pyrhon3_9.txt +++ b/requirements/common.txt @@ -9,10 +9,13 @@ Django==3.0.8 django-allauth==0.42.0 django-autoslug==1.9.7 django-ckeditor==5.9.0 +django-colorfield==0.3.2 django-froala-editor==3.2.0 +django-grappelli==2.14.2 django-js-asset==1.2.2 django-markdownx==3.0.1 django-online-users==0.3 +django-smart-selects==1.5.8 django-summernote==0.8.11.6 gunicorn==20.0.4 idna==2.10 @@ -24,21 +27,20 @@ oauthlib==3.1.0 parso==0.7.1 pexpect==4.8.0 pickleshare==0.7.5 -Pillow==8.0.1 prompt-toolkit==3.0.5 -psycopg2==2.8.6 ptyprocess==0.6.0 Pygments==2.6.1 +python-decouple==3.8 +python-memcached==1.59 python3-openid==3.2.0 pytils==0.3 pytz==2020.1 requests==2.24.0 requests-oauthlib==1.3.0 +setuptools==69.0.3 six==1.15.0 +sorl-thumbnail==12.7.0 sqlparse==0.3.1 traitlets==4.3.3 urllib3==1.25.10 wcwidth==0.2.5 -django-grappelli==2.14.2 -django-smart-selects==1.5.8 -django-colorfield==0.3.2 diff --git a/requirements/dev.txt b/requirements/dev.txt new file mode 100644 index 00000000..1508ece3 --- /dev/null +++ b/requirements/dev.txt @@ -0,0 +1,3 @@ +-r common.txt +pillow==10.2.0 +psycopg2==2.9.9 \ No newline at end of file diff --git a/requirements/prod.txt b/requirements/prod.txt new file mode 100644 index 00000000..e9ac60e8 --- /dev/null +++ b/requirements/prod.txt @@ -0,0 +1,3 @@ +-r common.txt +pillow==9.0.1 +psycopg2==2.8.5 \ No newline at end of file From 086b5e5ff737ae2c9678b1a66acf72495c49931d Mon Sep 17 00:00:00 2001 From: Nagaev Dmitry Date: Sun, 28 Jan 2024 00:28:52 +0500 Subject: [PATCH 3/5] Add capability to choose host during host booking (#5) * add capability to choose host during host booking * adjust selected row sizes --- .../templatetags/reservation_extras.py | 35 +++++++++---------- haxball_site/reservation/views.py | 25 ++++++------- .../reservation/reservation_form.html | 18 ++++++++-- 3 files changed, 43 insertions(+), 35 deletions(-) diff --git a/haxball_site/reservation/templatetags/reservation_extras.py b/haxball_site/reservation/templatetags/reservation_extras.py index 44705613..9456b4ab 100644 --- a/haxball_site/reservation/templatetags/reservation_extras.py +++ b/haxball_site/reservation/templatetags/reservation_extras.py @@ -1,13 +1,11 @@ from datetime import timedelta -from datetime import time from django import template -from django.contrib.auth.models import AnonymousUser from django.db.models import Q from django.db.models.functions import datetime from django.utils import timezone from tournament.models import Player, Team, League, TourNumber, Match -from ..models import ReservationEntry +from reservation.models import ReservationHost register = template.Library() @@ -43,7 +41,7 @@ def reservation_form(user): t = teams_can_reserv(user) actual_tour = TourNumber.objects.filter(league__championship__is_active=True, is_actual=True, league__teams__in=t).distinct() - print(actual_tour) + if actual_tour is None: return { 'matches': [] @@ -54,27 +52,28 @@ def reservation_form(user): # Просматриваем все активные туры и смотрим матчи, которые не сыграны и на которых нету брони for tour in actual_tour: - matches_unplayed = Match.objects.filter((Q(team_home__in=t) | Q(team_guest__in=t)), is_played=False, - numb_tour__number__lte=tour.number, league=tour.league, - match_reservation=None - ).order_by('-numb_tour__number').distinct() + matches_unplayed = \ + (Match.objects + .filter((Q(team_home__in=t) | Q(team_guest__in=t)), is_played=False, + numb_tour__number=tour.number, league=tour.league, + match_reservation=None) + .distinct() + .order_by('-numb_tour__number')) matches_to_choose.extend(matches_unplayed) - date_today = datetime.datetime.today() - """ - Было нужно, когда можно было бронить матчи до какого-то времени. - time_end = datetime.datetime(year=actual_tour.date_to.year, month=actual_tour.date_to.month, - day=actual_tour.date_to.day, hour=23, minute=30, second=0) - """ + hosts = ReservationHost.objects.filter(is_active=True) + today = datetime.datetime.today().date() + tomorrow = today + timedelta(days=1) hours_list = list(range(18, 24)) minutes_list = [0, 15, 30, 45] return { 'matches': matches_to_choose, 'user': user, - "date_today": date_today.date(), - "date_tomorrow": date_today.date() + timedelta(days=1), - "hours_list": hours_list, - "minutes_list": minutes_list + 'date_today': today, + 'date_tomorrow': tomorrow, + 'hours_list': hours_list, + 'minutes_list': minutes_list, + 'hosts': hosts } diff --git a/haxball_site/reservation/views.py b/haxball_site/reservation/views.py index 311a0fbb..2e0897b4 100644 --- a/haxball_site/reservation/views.py +++ b/haxball_site/reservation/views.py @@ -23,20 +23,17 @@ def get_context_data(self, *, object_list=None, **kwargs): def post(self, request): data = request.POST - # date_time_obj = datetime.strptime(data['time_date'], '%Y-%m-%dT%H:%M') - date_time_obj = datetime.combine(datetime.strptime(data["match_date"], '%Y-%m-%d').date(), - time(hour=int(data["match_hour"]), minute=int(data["match_minute"]))) - d1 = date_time_obj - timedelta(minutes=29) - d2 = date_time_obj + timedelta(minutes=29) - reserved = ReservationEntry.objects.filter(time_date__range=[d1, d2]) - active_hosts = ReservationHost.objects.filter(is_active=True) - if reserved.count() < active_hosts.count(): - hosts = set(active_hosts) - for i in reserved: - hosts.remove(i.host) - h = hosts.pop() - ReservationEntry.objects.create(author=request.user, time_date=date_time_obj, - match_id=int(data['match']), host=h) + match_id = int(data['match']) + host_id = int(data['match_host']) + match_date = datetime.combine(datetime.strptime(data['match_date'], '%Y-%m-%d').date(), + time(hour=int(data['match_hour']), minute=int(data['match_minute']))) + prev_match_date = match_date - timedelta(minutes=29) + next_match_date = match_date + timedelta(minutes=29) + + reserved = ReservationEntry.objects.filter(time_date__range=[prev_match_date, next_match_date], host_id=host_id) + if reserved.count() == 0: + ReservationEntry.objects.create(author=request.user, time_date=match_date, + match_id=match_id, host_id=host_id) return redirect('reservation:host_reservation') else: return render(request, 'reservation/reservation_list.html', { diff --git a/haxball_site/templates/reservation/reservation_form.html b/haxball_site/templates/reservation/reservation_form.html index 0afe0441..c651f666 100644 --- a/haxball_site/templates/reservation/reservation_form.html +++ b/haxball_site/templates/reservation/reservation_form.html @@ -3,7 +3,7 @@
{% csrf_token %} -
+
-
+
@@ -52,9 +52,21 @@
+
+ + + + +
- +
From bcc95391a5352a6f5f346accdf2b5deb26a70585 Mon Sep 17 00:00:00 2001 From: Nagaev Dmitry Date: Sun, 28 Jan 2024 13:16:48 +0500 Subject: [PATCH 4/5] Change Yoomoney wallet account (#6) --- haxball_site/templates/core/home.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/haxball_site/templates/core/home.html b/haxball_site/templates/core/home.html index 88cdaccf..3a479c1f 100644 --- a/haxball_site/templates/core/home.html +++ b/haxball_site/templates/core/home.html @@ -60,7 +60,7 @@
Смотрите нас тут
-
From 5d82d269cb56e0815c5cedddffaffc5806ccae0d Mon Sep 17 00:00:00 2001 From: Nagaev Dmitry Date: Mon, 29 Jan 2024 03:22:52 +0500 Subject: [PATCH 5/5] Setup Yandex.Metrika (#7) --- haxball_site/templates/base.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/haxball_site/templates/base.html b/haxball_site/templates/base.html index 6d3b60a5..329c167d 100644 --- a/haxball_site/templates/base.html +++ b/haxball_site/templates/base.html @@ -14,7 +14,7 @@ }) (window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym"); - ym(66548209, "init", { + ym(96287121, "init", { clickmap: true, trackLinks: true, accurateTrackBounce: true, @@ -22,7 +22,7 @@ });