Compare commits

..

6 Commits

Author SHA1 Message Date
f68e5b4573 Release v1.0.2
All checks were successful
CI / Checks (push) Successful in 16m8s
2025-08-29 14:15:16 +02:00
db39c38594 BTHLABS-54: Unprocessed save shows Untitled in the card title 2025-08-29 08:23:09 +02:00
38d768a584 BTHLABS-53: Processing task fails for newly created saves 2025-08-29 08:20:53 +02:00
fb39818be3 public -> development 2025-08-20 20:01:12 +00:00
f04c243470 Release v1.0.1
All checks were successful
CI / Checks (push) Successful in 10m26s
2025-08-20 21:57:41 +02:00
f7a4e16d03 BTHLABS-0000: Code cleanup ;) 2025-08-20 21:37:31 +02:00
15 changed files with 52 additions and 55 deletions

View File

@ -66,7 +66,7 @@ $ docker run --rm -it \
-e HOTPOCKET_BACKEND_INITIAL_ACCOUNT_USERNAME=hotpocket \ -e HOTPOCKET_BACKEND_INITIAL_ACCOUNT_USERNAME=hotpocket \
-e HOTPOCKET_BACKEND_INITIAL_ACCOUNT_PASSWORD=hotpocketm4st3r \ -e HOTPOCKET_BACKEND_INITIAL_ACCOUNT_PASSWORD=hotpocketm4st3r \
-p 8000:8000 \ -p 8000:8000 \
docker-hosted.nexus.bthlabs.pl/hotpocket/backend:aio-v1.0.0-01 docker-hosted.nexus.bthlabs.pl/hotpocket/backend:aio-v1.0.2-01
``` ```
The command above will set up and start the application. The SQLite file will The command above will set up and start the application. The SQLite file will

View File

@ -1,6 +1,6 @@
services: services:
backend: backend:
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:aio-v1.0.0-01" image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:aio-v1.0.2-01"
environment: environment:
HOTPOCKET_BACKEND_SECRET_KEY: "thisisntright" HOTPOCKET_BACKEND_SECRET_KEY: "thisisntright"
HOTPOCKET_BACKEND_INITIAL_ACCOUNT_USERNAME: "hotpocket" HOTPOCKET_BACKEND_INITIAL_ACCOUNT_USERNAME: "hotpocket"

View File

@ -8,7 +8,7 @@ x-backend-environment: &x-backend-environment
services: services:
webapp: webapp:
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:deployment-v1.0.0-01" image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:deployment-v1.0.2-01"
environment: environment:
<<: *x-backend-environment <<: *x-backend-environment
HOTPOCKET_BACKEND_ALLOWED_HOSTS: "app.staging.hotpocket.bthlab.bthlabs.net" HOTPOCKET_BACKEND_ALLOWED_HOSTS: "app.staging.hotpocket.bthlab.bthlabs.net"
@ -21,7 +21,7 @@ services:
restart: "unless-stopped" restart: "unless-stopped"
admin: admin:
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:deployment-v1.0.0-01" image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:deployment-v1.0.2-01"
environment: environment:
<<: *x-backend-environment <<: *x-backend-environment
HOTPOCKET_BACKEND_APP: "admin" HOTPOCKET_BACKEND_APP: "admin"
@ -35,7 +35,7 @@ services:
restart: "unless-stopped" restart: "unless-stopped"
celery-worker: celery-worker:
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:deployment-v1.0.0-01" image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:deployment-v1.0.2-01"
command: command:
- "/srv/venv/bin/celery" - "/srv/venv/bin/celery"
- "-A" - "-A"
@ -57,7 +57,7 @@ services:
restart: "unless-stopped" restart: "unless-stopped"
celery-beat: celery-beat:
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:deployment-v1.0.0-01" image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:deployment-v1.0.2-01"
command: command:
- "/srv/venv/bin/celery" - "/srv/venv/bin/celery"
- "-A" - "-A"

View File

@ -1,4 +1,4 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import annotations from __future__ import annotations
version = '1.0.0' version = '1.0.2'

View File

@ -2,6 +2,7 @@
from __future__ import annotations from __future__ import annotations
from django.contrib import messages from django.contrib import messages
import django.db
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from django.shortcuts import redirect from django.shortcuts import redirect
from django.urls import reverse from django.urls import reverse
@ -21,15 +22,13 @@ class CreateSaveWorkflow(SaveWorkflow):
url: str, url: str,
force_post_save: bool = False, force_post_save: bool = False,
) -> HttpResponse: ) -> HttpResponse:
save = self.create( with django.db.transaction.atomic():
account.pk, save = self.create(
SaveIn(url=url), account.pk,
) SaveIn(url=url),
)
association = self.associate(account.pk, save) association = self.associate(account.pk, save)
if save.last_processed_at is None:
processing_result = self.schedule_processing(save) # noqa: F841
response = redirect(reverse('ui.associations.browse')) response = redirect(reverse('ui.associations.browse'))
if force_post_save is True or save.is_netloc_banned is True: if force_post_save is True or save.is_netloc_banned is True:
@ -47,4 +46,7 @@ class CreateSaveWorkflow(SaveWorkflow):
response.headers['X-HotPocket-Testing-Save-PK'] = save.pk response.headers['X-HotPocket-Testing-Save-PK'] = save.pk
response.headers['X-HotPocket-Testing-Association-PK'] = association.pk response.headers['X-HotPocket-Testing-Association-PK'] = association.pk
if save.last_processed_at is None:
processing_result = self.schedule_processing(save) # noqa: F841
return response return response

View File

@ -7,7 +7,7 @@
{% if association.title %} {% if association.title %}
{{ association.title }} {{ association.title }}
{% else %} {% else %}
{% translate 'Untitled' %} {{ association.target.url }}
{% endif %} {% endif %}
</a> </a>
</h5> </h5>

View File

@ -4,7 +4,6 @@ from __future__ import annotations
import http import http
import logging import logging
import django.db
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from django.shortcuts import render from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
@ -21,19 +20,18 @@ def share_sheet(request: HttpRequest) -> HttpResponse:
LOGGER.debug('POST=`%s`', request.POST) LOGGER.debug('POST=`%s`', request.POST)
try: try:
with django.db.transaction.atomic(): assert request.user.is_anonymous is False, 'Login required'
assert request.user.is_anonymous is False, 'Login required' assert 'text' in request.POST, 'Bad request: Missing `text`'
assert 'text' in request.POST, 'Bad request: Missing `text`'
url = request.POST['text'].split('\n')[0].strip() url = request.POST['text'].split('\n')[0].strip()
assert url != '', 'Bad request: Empty `text`' assert url != '', 'Bad request: Empty `text`'
return CreateSaveWorkflow().run( return CreateSaveWorkflow().run(
request=request, request=request,
account=request.user, account=request.user,
url=url, url=url,
force_post_save=True, force_post_save=True,
) )
except Exception as exception: except Exception as exception:
LOGGER.error( LOGGER.error(
'Unhandled exception: %s', 'Unhandled exception: %s',

View File

@ -4,7 +4,6 @@ from __future__ import annotations
import http import http
import logging import logging
import django.db
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from django.shortcuts import render from django.shortcuts import render
@ -19,19 +18,18 @@ def shortcut(request: HttpRequest) -> HttpResponse:
LOGGER.debug('GET=`%s`', request.GET) LOGGER.debug('GET=`%s`', request.GET)
try: try:
with django.db.transaction.atomic(): assert request.user.is_anonymous is False, 'Login required'
assert request.user.is_anonymous is False, 'Login required' assert 'url' in request.GET, 'Bad request: Missing `url`'
assert 'url' in request.GET, 'Bad request: Missing `url`'
url = request.GET['url'].split('\n')[0].strip() url = request.GET['url'].split('\n')[0].strip()
assert url != '', 'Bad request: Empty `url`' assert url != '', 'Bad request: Empty `url`'
return CreateSaveWorkflow().run( return CreateSaveWorkflow().run(
request=request, request=request,
account=request.user, account=request.user,
url=url, url=url,
force_post_save=True, force_post_save=True,
) )
except Exception as exception: except Exception as exception:
LOGGER.error( LOGGER.error(
'Unhandled exception: %s', 'Unhandled exception: %s',

View File

@ -4,7 +4,6 @@ from __future__ import annotations
import http import http
import logging import logging
import django.db
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from django.shortcuts import render from django.shortcuts import render
from django.urls import reverse from django.urls import reverse
@ -24,12 +23,11 @@ class CreateView(AccountRequiredMixin, FormView):
form_class = CreateForm form_class = CreateForm
def form_valid(self, form: CreateForm) -> HttpResponse: def form_valid(self, form: CreateForm) -> HttpResponse:
with django.db.transaction.atomic(): return CreateSaveWorkflow().run(
return CreateSaveWorkflow().run( request=self.request,
request=self.request, account=self.request.user,
account=self.request.user, url=form.cleaned_data['url'],
url=form.cleaned_data['url'], )
)
def get_success_url(self) -> str: def get_success_url(self) -> str:
return reverse('ui.associations.browse') return reverse('ui.associations.browse')

View File

@ -13,7 +13,7 @@ cat <<EOF
|_| |_|
production production
HotPocket v1.0.0 [${HOTPOCKET_BACKEND_IMAGE_ID}] (https://hotpocket.app/) HotPocket v1.0.2 [${HOTPOCKET_BACKEND_IMAGE_ID}] (https://hotpocket.app/)
Copyright 2025-present by BTHLabs. All rights reserved. (https://bthlabs.pl/) Copyright 2025-present by BTHLabs. All rights reserved. (https://bthlabs.pl/)
Licensed under Apache-2.0 Licensed under Apache-2.0
EOF EOF

View File

@ -1,6 +1,6 @@
{ {
"name": "hotpocket-backend", "name": "hotpocket-backend",
"version": "1.0.0", "version": "1.0.2",
"description": "HotPocket Backend", "description": "HotPocket Backend",
"main": "hotpocket_backend/apps/frontend/src/index.js", "main": "hotpocket_backend/apps/frontend/src/index.js",
"repository": "https://git.bthlabs.pl/tomekwojcik/hotpocket", "repository": "https://git.bthlabs.pl/tomekwojcik/hotpocket",

View File

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "hotpocket-backend" name = "hotpocket-backend"
version = "1.0.0" version = "1.0.2"
description = "HotPocket Backend" description = "HotPocket Backend"
authors = ["Tomek Wójcik <contact@bthlabs.pl>"] authors = ["Tomek Wójcik <contact@bthlabs.pl>"]
license = "Apache-2.0" license = "Apache-2.0"

View File

@ -2,8 +2,9 @@
extend-exclude = extend-exclude =
hotpocket_backend/apps/*/migrations/*.py, hotpocket_backend/apps/*/migrations/*.py,
node_modules/**/*.py, node_modules/**/*.py,
skel/*.py skel/*.py,
skel/*/*.py skel/*/*.py,
playground.py
ignore = E131,W503,W504 ignore = E131,W503,W504
max-line-length = 119 max-line-length = 119
hang-closing = False hang-closing = False
@ -13,7 +14,7 @@ addopts = --disable-warnings
django_debug_mode = keep django_debug_mode = keep
[isort] [isort]
known_first_party=hotpocket_backend,hotpocket_backend_testing,hotpocket_common,hotpocket_soa,hotpocket_testing known_first_party=hotpocket_backend,hotpocket_backend_testing,hotpocket_common,hotpocket_soa,hotpocket_testing,hotpocket_workspace_tools
multi_line_output=3 multi_line_output=3
include_trailing_comma=true include_trailing_comma=true
force_sort_within_sections=true force_sort_within_sections=true

View File

@ -9,7 +9,7 @@ import os
from invoke import task from invoke import task
from invoke.exceptions import UnexpectedExit from invoke.exceptions import UnexpectedExit
from hotpocket_workspace_tools import get_workspace_mode, WorkspaceMode from hotpocket_workspace_tools import WorkspaceMode, get_workspace_mode
WORKSPACE_MODE = get_workspace_mode() WORKSPACE_MODE = get_workspace_mode()
ENV = os.getenv('HOTPOCKET_BACKEND_ENV', 'docker') ENV = os.getenv('HOTPOCKET_BACKEND_ENV', 'docker')

View File

@ -7,7 +7,7 @@ max-line-length = 119
hang-closing = False hang-closing = False
[isort] [isort]
known_first_party=hotpocket_backend,hotpocket_backend_testing,hotpocket_common,hotpocket_soa,hotpocket_testing known_first_party=hotpocket_backend,hotpocket_backend_testing,hotpocket_common,hotpocket_soa,hotpocket_testing,hotpocket_workspace_tools
multi_line_output=3 multi_line_output=3
include_trailing_comma=true include_trailing_comma=true
force_sort_within_sections=true force_sort_within_sections=true