Merge branch 'main' into storefront-nuxt
This commit is contained in:
commit
7d0b6301ea
248 changed files with 17269 additions and 17666 deletions
|
|
@ -23,19 +23,17 @@ lint:
|
|||
- "**/*.py"
|
||||
- "pyproject.toml"
|
||||
- ".pre-commit-config.yaml"
|
||||
- "pyrightconfig.json"
|
||||
when: on_success
|
||||
- when: never
|
||||
|
||||
typecheck:
|
||||
stage: typecheck
|
||||
script:
|
||||
- uv run pyright
|
||||
- uv run ty check
|
||||
rules:
|
||||
- changes:
|
||||
- "**/*.py"
|
||||
- "pyproject.toml"
|
||||
- "pyrightconfig.json"
|
||||
when: on_success
|
||||
- when: never
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
repos:
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.6.9
|
||||
hooks:
|
||||
- id: ruff
|
||||
name: Ruff (lint & fix)
|
||||
args: ["--fix", "--exit-non-zero-on-fix"]
|
||||
files: "\\.(py|pyi)$"
|
||||
exclude: "^storefront/"
|
||||
- id: ruff-format
|
||||
name: Ruff (format)
|
||||
files: "\\.(py|pyi)$"
|
||||
exclude: "^storefront/"
|
||||
|
||||
ci:
|
||||
autofix_commit_msg: "chore(pre-commit): auto-fix issues"
|
||||
autofix_prs: true
|
||||
autoupdate_commit_msg: "chore(pre-commit): autoupdate hooks"
|
||||
|
|
@ -3,7 +3,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: EVIBES 2025.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: 2025-06-16 08:59+0100\n"
|
||||
"Last-Translator: EGOR GORBUNOV <CONTACT@FUREUNOIR.COM>\n"
|
||||
"Language-Team: LANGUAGE <CONTACT@FUREUNOIR.COM>\n"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: EVIBES 2025.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: 2025-06-16 08:59+0100\n"
|
||||
"Last-Translator: EGOR GORBUNOV <CONTACT@FUREUNOIR.COM>\n"
|
||||
"Language-Team: LANGUAGE <CONTACT@FUREUNOIR.COM>\n"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: EVIBES 2025.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: 2025-06-16 08:59+0100\n"
|
||||
"Last-Translator: EGOR GORBUNOV <CONTACT@FUREUNOIR.COM>\n"
|
||||
"Language-Team: LANGUAGE <CONTACT@FUREUNOIR.COM>\n"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: EVIBES 2025.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: 2025-06-16 08:59+0100\n"
|
||||
"Last-Translator: EGOR GORBUNOV <CONTACT@FUREUNOIR.COM>\n"
|
||||
"Language-Team: LANGUAGE <CONTACT@FUREUNOIR.COM>\n"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: EVIBES 2025.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: 2025-06-16 08:59+0100\n"
|
||||
"Last-Translator: EGOR GORBUNOV <CONTACT@FUREUNOIR.COM>\n"
|
||||
"Language-Team: LANGUAGE <CONTACT@FUREUNOIR.COM>\n"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: EVIBES 2025.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: 2025-06-16 08:59+0100\n"
|
||||
"Last-Translator: EGOR GORBUNOV <CONTACT@FUREUNOIR.COM>\n"
|
||||
"Language-Team: LANGUAGE <CONTACT@FUREUNOIR.COM>\n"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: EVIBES 2025.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: 2025-06-16 08:59+0100\n"
|
||||
"Last-Translator: EGOR GORBUNOV <CONTACT@FUREUNOIR.COM>\n"
|
||||
"Language-Team: LANGUAGE <CONTACT@FUREUNOIR.COM>\n"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: EVIBES 2025.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: 2025-06-16 08:59+0100\n"
|
||||
"Last-Translator: EGOR GORBUNOV <CONTACT@FUREUNOIR.COM>\n"
|
||||
"Language-Team: LANGUAGE <CONTACT@FUREUNOIR.COM>\n"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: EVIBES 2025.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: 2025-06-16 08:59+0100\n"
|
||||
"Last-Translator: EGOR GORBUNOV <CONTACT@FUREUNOIR.COM>\n"
|
||||
"Language-Team: LANGUAGE <CONTACT@FUREUNOIR.COM>\n"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: EVIBES 2025.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: 2025-06-16 08:59+0100\n"
|
||||
"Last-Translator: EGOR GORBUNOV <CONTACT@FUREUNOIR.COM>\n"
|
||||
"Language-Team: LANGUAGE <CONTACT@FUREUNOIR.COM>\n"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: EVIBES 2025.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: 2025-06-16 08:59+0100\n"
|
||||
"Last-Translator: EGOR GORBUNOV <CONTACT@FUREUNOIR.COM>\n"
|
||||
"Language-Team: LANGUAGE <CONTACT@FUREUNOIR.COM>\n"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: EVIBES 2025.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: 2025-06-16 08:59+0100\n"
|
||||
"Last-Translator: EGOR GORBUNOV <CONTACT@FUREUNOIR.COM>\n"
|
||||
"Language-Team: LANGUAGE <CONTACT@FUREUNOIR.COM>\n"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: EVIBES 2025.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: 2025-06-16 08:59+0100\n"
|
||||
"Last-Translator: EGOR GORBUNOV <CONTACT@FUREUNOIR.COM>\n"
|
||||
"Language-Team: LANGUAGE <CONTACT@FUREUNOIR.COM>\n"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: EVIBES 2025.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: 2025-06-16 08:59+0100\n"
|
||||
"Last-Translator: EGOR GORBUNOV <CONTACT@FUREUNOIR.COM>\n"
|
||||
"Language-Team: LANGUAGE <CONTACT@FUREUNOIR.COM>\n"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: EVIBES 2025.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: 2025-06-16 08:59+0100\n"
|
||||
"Last-Translator: EGOR GORBUNOV <CONTACT@FUREUNOIR.COM>\n"
|
||||
"Language-Team: LANGUAGE <CONTACT@FUREUNOIR.COM>\n"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: EVIBES 2025.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: 2025-06-16 08:59+0100\n"
|
||||
"Last-Translator: EGOR GORBUNOV <CONTACT@FUREUNOIR.COM>\n"
|
||||
"Language-Team: LANGUAGE <CONTACT@FUREUNOIR.COM>\n"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: EVIBES 2025.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: 2025-06-16 08:59+0100\n"
|
||||
"Last-Translator: EGOR GORBUNOV <CONTACT@FUREUNOIR.COM>\n"
|
||||
"Language-Team: LANGUAGE <CONTACT@FUREUNOIR.COM>\n"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: EVIBES 2025.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: 2025-06-16 08:59+0100\n"
|
||||
"Last-Translator: EGOR GORBUNOV <CONTACT@FUREUNOIR.COM>\n"
|
||||
"Language-Team: LANGUAGE <CONTACT@FUREUNOIR.COM>\n"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: EVIBES 2025.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: 2025-06-16 08:59+0100\n"
|
||||
"Last-Translator: EGOR GORBUNOV <CONTACT@FUREUNOIR.COM>\n"
|
||||
"Language-Team: LANGUAGE <CONTACT@FUREUNOIR.COM>\n"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: EVIBES 2025.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: 2025-06-16 08:59+0100\n"
|
||||
"Last-Translator: EGOR GORBUNOV <CONTACT@FUREUNOIR.COM>\n"
|
||||
"Language-Team: LANGUAGE <CONTACT@FUREUNOIR.COM>\n"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: EVIBES 2025.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: 2025-06-16 08:59+0100\n"
|
||||
"Last-Translator: EGOR GORBUNOV <CONTACT@FUREUNOIR.COM>\n"
|
||||
"Language-Team: LANGUAGE <CONTACT@FUREUNOIR.COM>\n"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: EVIBES 2025.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: 2025-06-16 08:59+0100\n"
|
||||
"Last-Translator: EGOR GORBUNOV <CONTACT@FUREUNOIR.COM>\n"
|
||||
"Language-Team: LANGUAGE <CONTACT@FUREUNOIR.COM>\n"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: EVIBES 2025.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: 2025-06-16 08:59+0100\n"
|
||||
"Last-Translator: EGOR GORBUNOV <CONTACT@FUREUNOIR.COM>\n"
|
||||
"Language-Team: LANGUAGE <CONTACT@FUREUNOIR.COM>\n"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: EVIBES 2025.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: 2025-06-16 08:59+0100\n"
|
||||
"Last-Translator: EGOR GORBUNOV <CONTACT@FUREUNOIR.COM>\n"
|
||||
"Language-Team: LANGUAGE <CONTACT@FUREUNOIR.COM>\n"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: EVIBES 2025.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: 2025-06-16 08:59+0100\n"
|
||||
"Last-Translator: EGOR GORBUNOV <CONTACT@FUREUNOIR.COM>\n"
|
||||
"Language-Team: LANGUAGE <CONTACT@FUREUNOIR.COM>\n"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: EVIBES 2025.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-18 17:19+0300\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:38+0300\n"
|
||||
"PO-Revision-Date: 2025-06-16 08:59+0100\n"
|
||||
"Last-Translator: EGOR GORBUNOV <CONTACT@FUREUNOIR.COM>\n"
|
||||
"Language-Team: LANGUAGE <CONTACT@FUREUNOIR.COM>\n"
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ class Post(NiceModel):
|
|||
verbose_name = _("post")
|
||||
verbose_name_plural = _("posts")
|
||||
|
||||
def save(self, **kwargs):
|
||||
def save(self, *args, **kwargs):
|
||||
if self.file:
|
||||
raise ValueError(
|
||||
_("markdown files are not supported yet - use markdown content instead")
|
||||
|
|
@ -110,7 +110,7 @@ class Post(NiceModel):
|
|||
"a markdown file or markdown content must be provided - mutually exclusive"
|
||||
)
|
||||
)
|
||||
super().save(**kwargs)
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
|
||||
class PostTag(NiceModel):
|
||||
|
|
|
|||
|
|
@ -31,13 +31,13 @@ class NiceModel(Model):
|
|||
|
||||
def save(
|
||||
self,
|
||||
*,
|
||||
*args,
|
||||
force_insert: bool = False,
|
||||
force_update: bool = False,
|
||||
using: str | None = None,
|
||||
update_fields: Collection[str] | None = None,
|
||||
update_modified: bool = True,
|
||||
) -> None:
|
||||
) -> None: # ty:ignore[invalid-method-override]
|
||||
self.update_modified = update_modified
|
||||
return super().save(
|
||||
force_insert=force_insert,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
from contextlib import suppress
|
||||
from typing import Any, ClassVar, Type
|
||||
from typing import Any, Callable, ClassVar, Type
|
||||
|
||||
from constance.admin import Config
|
||||
from constance.admin import ConstanceAdmin as BaseConstanceAdmin
|
||||
|
|
@ -145,6 +145,7 @@ class FieldsetsMixin:
|
|||
|
||||
# noinspection PyUnresolvedReferences
|
||||
class ActivationActionsMixin:
|
||||
message_user: Callable
|
||||
actions_on_top = True
|
||||
actions_on_bottom = True
|
||||
actions = [
|
||||
|
|
@ -466,6 +467,7 @@ class ProductAdmin(
|
|||
list_filter = (
|
||||
"is_active",
|
||||
"is_digital",
|
||||
"is_updatable",
|
||||
"stocks__vendor",
|
||||
"tags__name",
|
||||
"created",
|
||||
|
|
@ -513,6 +515,9 @@ class ProductAdmin(
|
|||
"brand",
|
||||
"tags",
|
||||
]
|
||||
additional_fields = [
|
||||
"is_updatable",
|
||||
]
|
||||
|
||||
def get_queryset(self, request):
|
||||
return (
|
||||
|
|
@ -1082,10 +1087,8 @@ class ConstanceConfig:
|
|||
_meta = Meta()
|
||||
|
||||
|
||||
# noinspection PyTypeChecker
|
||||
site.unregister([Config])
|
||||
# noinspection PyTypeChecker
|
||||
site.register([ConstanceConfig], BaseConstanceAdmin)
|
||||
site.unregister([Config]) # ty:ignore[invalid-argument-type]
|
||||
site.register([ConstanceConfig], BaseConstanceAdmin) # ty:ignore[invalid-argument-type]
|
||||
site.site_title = settings.PROJECT_NAME
|
||||
site.site_header = "eVibes"
|
||||
site.index_title = settings.PROJECT_NAME
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from django.conf import settings
|
||||
from django.http import FileResponse
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from drf_spectacular.types import OpenApiTypes
|
||||
from drf_spectacular.utils import OpenApiParameter, extend_schema, inline_serializer
|
||||
from rest_framework import status
|
||||
from rest_framework.fields import CharField, DictField, JSONField, ListField
|
||||
|
|
@ -32,6 +32,9 @@ CUSTOM_OPENAPI_SCHEMA = {
|
|||
"OpenApi3 schema for this API. Format can be selected via content negotiation. "
|
||||
"Language can be selected with Accept-Language and query parameter both."
|
||||
),
|
||||
responses={
|
||||
status.HTTP_200_OK: OpenApiTypes.OBJECT,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -176,7 +179,7 @@ DOWNLOAD_DIGITAL_ASSET_SCHEMA = {
|
|||
],
|
||||
summary=_("download a digital asset from purchased digital order"),
|
||||
responses={
|
||||
status.HTTP_200_OK: FileResponse,
|
||||
status.HTTP_200_OK: OpenApiTypes.BINARY,
|
||||
status.HTTP_400_BAD_REQUEST: error,
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ CATEGORY_SCHEMA = {
|
|||
name="lookup_value",
|
||||
location="path",
|
||||
description=_("Category UUID or slug"),
|
||||
type=str,
|
||||
type=OpenApiTypes.STR,
|
||||
),
|
||||
],
|
||||
responses={status.HTTP_200_OK: CategoryDetailSerializer(), **BASE_ERRORS},
|
||||
|
|
@ -284,7 +284,7 @@ CATEGORY_SCHEMA = {
|
|||
name="lookup_value",
|
||||
location="path",
|
||||
description=_("Category UUID or slug"),
|
||||
type=str,
|
||||
type=OpenApiTypes.STR,
|
||||
),
|
||||
],
|
||||
responses={
|
||||
|
|
@ -369,7 +369,7 @@ ORDER_SCHEMA = {
|
|||
name="lookup_value",
|
||||
location="path",
|
||||
description=_("Order UUID or human-readable id"),
|
||||
type=str,
|
||||
type=OpenApiTypes.STR,
|
||||
),
|
||||
],
|
||||
responses={status.HTTP_200_OK: OrderDetailSerializer(), **BASE_ERRORS},
|
||||
|
|
@ -1006,7 +1006,7 @@ BRAND_SCHEMA = {
|
|||
name="lookup_value",
|
||||
location="path",
|
||||
description=_("Brand UUID or slug"),
|
||||
type=str,
|
||||
type=OpenApiTypes.STR,
|
||||
),
|
||||
],
|
||||
responses={status.HTTP_200_OK: BrandDetailSerializer(), **BASE_ERRORS},
|
||||
|
|
@ -1049,7 +1049,7 @@ BRAND_SCHEMA = {
|
|||
name="lookup_value",
|
||||
location="path",
|
||||
description=_("Brand UUID or slug"),
|
||||
type=str,
|
||||
type=OpenApiTypes.STR,
|
||||
),
|
||||
],
|
||||
responses={status.HTTP_200_OK: SeoSnapshotSerializer(), **BASE_ERRORS},
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ from django_elasticsearch_dsl import fields
|
|||
from django_elasticsearch_dsl.registries import registry
|
||||
from elasticsearch import NotFoundError
|
||||
from elasticsearch.dsl import Q, Search
|
||||
from elasticsearch.dsl.types import Hit
|
||||
from rest_framework.request import Request
|
||||
|
||||
from engine.core.models import Brand, Category, Product
|
||||
|
|
@ -199,8 +200,8 @@ def process_query(
|
|||
minimum_should_match=1,
|
||||
)
|
||||
|
||||
def build_search(idxs: list[str], size: int) -> Search:
|
||||
return (
|
||||
def build_search(idxs: list[str], size: int) -> Search[Hit]:
|
||||
result: Search[Hit] = ( # ty: ignore[invalid-assignment]
|
||||
Search(index=idxs)
|
||||
.query(query_base)
|
||||
.extra(
|
||||
|
|
@ -222,6 +223,7 @@ def process_query(
|
|||
)
|
||||
.extra(size=size, track_total_hits=True)
|
||||
)
|
||||
return result
|
||||
|
||||
resp_cats = None
|
||||
if "categories" in indexes:
|
||||
|
|
@ -289,12 +291,12 @@ def process_query(
|
|||
]
|
||||
for qx in product_exact_sequence:
|
||||
try:
|
||||
resp_exact = (
|
||||
search_exact = (
|
||||
Search(index=["products"])
|
||||
.query(qx)
|
||||
.extra(size=5, track_total_hits=False)
|
||||
.execute()
|
||||
)
|
||||
resp_exact = search_exact.execute() # ty: ignore[possibly-missing-attribute]
|
||||
except NotFoundError:
|
||||
resp_exact = None
|
||||
if resp_exact is not None and getattr(resp_exact, "hits", None):
|
||||
|
|
@ -309,7 +311,7 @@ def process_query(
|
|||
.extra(size=5, track_total_hits=False)
|
||||
)
|
||||
try:
|
||||
resp_exact = s_exact.execute()
|
||||
resp_exact = s_exact.execute() # ty: ignore[possibly-missing-attribute]
|
||||
except NotFoundError:
|
||||
resp_exact = None
|
||||
if resp_exact is not None and getattr(resp_exact, "hits", None):
|
||||
|
|
@ -434,7 +436,7 @@ def _lang_analyzer(lang_code: str) -> str:
|
|||
|
||||
class ActiveOnlyMixin:
|
||||
def get_queryset(self) -> QuerySet[Any]:
|
||||
return super().get_queryset().filter(is_active=True)
|
||||
return super().get_queryset().filter(is_active=True) # type: ignore[misc]
|
||||
|
||||
def should_index_object(self, obj) -> bool:
|
||||
return getattr(obj, "is_active", False)
|
||||
|
|
@ -665,7 +667,7 @@ def process_system_query(
|
|||
.query(mm)
|
||||
.extra(size=size_per_index, track_total_hits=False)
|
||||
)
|
||||
resp = s.execute()
|
||||
resp = s.execute() # ty: ignore[possibly-missing-attribute]
|
||||
for h in resp.hits:
|
||||
name = getattr(h, "name", None) or getattr(h, "title", None) or "N/A"
|
||||
results[idx].append(
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ class ProductFilter(FilterSet):
|
|||
data: dict[Any, Any] | None = None,
|
||||
queryset: QuerySet[Product] | None = None,
|
||||
*,
|
||||
request: HttpRequest | Request | Context = None,
|
||||
request: HttpRequest | Request | Context | None = None,
|
||||
prefix: str | None = None,
|
||||
) -> None:
|
||||
super().__init__(data=data, queryset=queryset, request=request, prefix=prefix)
|
||||
|
|
@ -516,12 +516,12 @@ class CategoryFilter(FilterSet):
|
|||
if not value:
|
||||
return queryset
|
||||
|
||||
uuids = [
|
||||
category.get("uuid")
|
||||
for category in process_query(query=value, indexes=("categories",))[
|
||||
"categories"
|
||||
]
|
||||
]
|
||||
s_result = process_query(query=value, indexes=("categories",))
|
||||
|
||||
if not s_result:
|
||||
raise ValueError("Search is unprocessable")
|
||||
|
||||
uuids = [category.get("uuid") for category in s_result.get("categories", [])]
|
||||
|
||||
return queryset.filter(uuid__in=uuids)
|
||||
|
||||
|
|
@ -650,10 +650,11 @@ class BrandFilter(FilterSet):
|
|||
if not value:
|
||||
return queryset
|
||||
|
||||
uuids = [
|
||||
brand.get("uuid")
|
||||
for brand in process_query(query=value, indexes=("brands",))["brands"]
|
||||
]
|
||||
s_result = process_query(query=value, indexes=("brands",))
|
||||
if not s_result:
|
||||
return queryset.none()
|
||||
|
||||
uuids = [brand.get("uuid") for brand in s_result.get("brands", [])]
|
||||
|
||||
return queryset.filter(uuid__in=uuids)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
from typing import Any
|
||||
|
||||
from graphene import Mutation
|
||||
|
||||
|
||||
class BaseMutation(Mutation):
|
||||
def __init__(self, *args: list[Any], **kwargs: dict[Any, Any]) -> None:
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@staticmethod
|
||||
def mutate(**kwargs: Any) -> None:
|
||||
pass
|
||||
|
|
@ -1,179 +0,0 @@
|
|||
from contextlib import suppress
|
||||
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from graphene import UUID, Boolean, Field, InputObjectType, List, NonNull, String
|
||||
|
||||
from engine.core.graphene import BaseMutation
|
||||
from engine.core.graphene.object_types import ProductType
|
||||
from engine.core.models import (
|
||||
Attribute,
|
||||
AttributeGroup,
|
||||
AttributeValue,
|
||||
Brand,
|
||||
Category,
|
||||
Product,
|
||||
ProductTag,
|
||||
)
|
||||
from engine.core.utils.messages import permission_denied_message
|
||||
|
||||
|
||||
def resolve_attributes(product, attributes):
|
||||
for attr_input in attributes:
|
||||
attribute = None
|
||||
attr_uuid = attr_input.get("attribute_uuid")
|
||||
if attr_uuid:
|
||||
with suppress(Attribute.DoesNotExist):
|
||||
attribute = Attribute.objects.get(uuid=attr_uuid)
|
||||
if attribute is None:
|
||||
group_name = attr_input.get("group_name")
|
||||
attribute_name = attr_input.get("attribute_name")
|
||||
value_type = attr_input.get("value_type") or "string"
|
||||
if group_name and attribute_name:
|
||||
group, _ = AttributeGroup.objects.get_or_create(name=group_name)
|
||||
attribute, _ = Attribute.objects.get_or_create(
|
||||
group=group,
|
||||
name=attribute_name,
|
||||
defaults={"value_type": value_type},
|
||||
)
|
||||
if attribute.value_type != value_type:
|
||||
attribute.value_type = value_type
|
||||
attribute.save(update_fields=["value_type"])
|
||||
if attribute is not None:
|
||||
AttributeValue.objects.update_or_create(
|
||||
product=product,
|
||||
attribute=attribute,
|
||||
defaults={"value": str(attr_input.get("value", ""))},
|
||||
)
|
||||
|
||||
|
||||
def resolve_tags(product, tag_uuids):
|
||||
tags = list(ProductTag.objects.filter(uuid__in=tag_uuids))
|
||||
if tags:
|
||||
product.tags.set(tags)
|
||||
|
||||
|
||||
class AttributeInput(InputObjectType):
|
||||
attribute_uuid = UUID(required=False, name="attributeUuid")
|
||||
group_name = String(required=False, name="groupName")
|
||||
attribute_name = String(required=False, name="attributeName")
|
||||
value_type = String(required=False, name="valueType")
|
||||
value = String(required=True)
|
||||
|
||||
|
||||
class ProductInput(InputObjectType):
|
||||
name = NonNull(String)
|
||||
description = String(required=False)
|
||||
is_digital = Boolean(required=False, name="isDigital")
|
||||
partnumber = String(required=False)
|
||||
sku = String(required=False)
|
||||
|
||||
category_uuid = NonNull(UUID, name="categoryUuid")
|
||||
brand_uuid = UUID(required=False, name="brandUuid")
|
||||
tag_uuids = List(UUID, required=False, name="tagUuids")
|
||||
attributes = List(NonNull(AttributeInput), required=False)
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal,PyTypeChecker
|
||||
class CreateProduct(BaseMutation):
|
||||
class Meta:
|
||||
description = _("create a product")
|
||||
|
||||
class Arguments:
|
||||
product_data = NonNull(ProductInput, name="productData")
|
||||
|
||||
product = Field(ProductType)
|
||||
|
||||
@staticmethod
|
||||
def mutate(parent, info, product_data):
|
||||
user = info.context.user
|
||||
if not user.has_perm("core.add_product"):
|
||||
raise PermissionDenied(permission_denied_message)
|
||||
category = Category.objects.get(uuid=product_data["category_uuid"])
|
||||
brand = None
|
||||
if product_data.get("brand_uuid"):
|
||||
with suppress(Brand.DoesNotExist):
|
||||
brand = Brand.objects.get(uuid=product_data["brand_uuid"])
|
||||
|
||||
product = Product.objects.create(
|
||||
name=product_data["name"],
|
||||
description=product_data.get("description"),
|
||||
is_digital=product_data.get("is_digital") or False,
|
||||
partnumber=product_data.get("partnumber"),
|
||||
sku=product_data.get("sku") or None,
|
||||
category=category,
|
||||
brand=brand,
|
||||
)
|
||||
|
||||
resolve_tags(product, product_data.get("tag_uuids", []))
|
||||
|
||||
resolve_attributes(product, product_data.get("attributes", []))
|
||||
|
||||
return CreateProduct(product=product)
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal,PyTypeChecker
|
||||
class UpdateProduct(BaseMutation):
|
||||
class Meta:
|
||||
description = _("create a product")
|
||||
|
||||
class Arguments:
|
||||
product_uuid = UUID(required=True)
|
||||
product_data = NonNull(ProductInput, name="productData")
|
||||
|
||||
product = Field(ProductType)
|
||||
|
||||
@staticmethod
|
||||
def mutate(parent, info, product_uuid, product_data):
|
||||
user = info.context.user
|
||||
if not user.has_perm("core.change_product"):
|
||||
raise PermissionDenied(permission_denied_message)
|
||||
product = Product.objects.get(uuid=product_uuid)
|
||||
|
||||
updates = {}
|
||||
for field_in, model_field in (
|
||||
("name", "name"),
|
||||
("description", "description"),
|
||||
("is_digital", "is_digital"),
|
||||
("partnumber", "partnumber"),
|
||||
("sku", "sku"),
|
||||
):
|
||||
if field_in in product_data and product_data[field_in] is not None:
|
||||
updates[model_field] = product_data[field_in]
|
||||
|
||||
if product_data.get("category_uuid"):
|
||||
product.category = Category.objects.get(uuid=product_data["category_uuid"])
|
||||
if product_data.get("brand_uuid") is not None:
|
||||
if product_data.get("brand_uuid"):
|
||||
product.brand = Brand.objects.get(uuid=product_data["brand_uuid"])
|
||||
else:
|
||||
product.brand = None
|
||||
|
||||
for k, v in updates.items():
|
||||
setattr(product, k, v)
|
||||
product.save()
|
||||
|
||||
resolve_tags(product, product_data.get("tag_uuids", []))
|
||||
|
||||
resolve_attributes(product, product_data.get("attributes"))
|
||||
|
||||
return UpdateProduct(product=product)
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal,PyTypeChecker
|
||||
class DeleteProduct(BaseMutation):
|
||||
class Meta:
|
||||
description = _("create a product")
|
||||
|
||||
class Arguments:
|
||||
product_uuid = UUID(required=True)
|
||||
|
||||
ok = Boolean()
|
||||
|
||||
@staticmethod
|
||||
def mutate(parent, info, product_uuid):
|
||||
user = info.context.user
|
||||
if not user.has_perm("core.delete_product"):
|
||||
raise PermissionDenied(permission_denied_message)
|
||||
Product.objects.get(uuid=product_uuid).delete()
|
||||
return DeleteProduct(ok=True)
|
||||
|
|
@ -6,11 +6,10 @@ from django.core.cache import cache
|
|||
from django.core.exceptions import BadRequest, PermissionDenied
|
||||
from django.http import Http404
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from graphene import UUID, Boolean, Field, Int, List, String
|
||||
from graphene import UUID, Boolean, Field, Int, List, Mutation, String
|
||||
from graphene.types.generic import GenericScalar
|
||||
|
||||
from engine.core.elasticsearch import process_query
|
||||
from engine.core.graphene import BaseMutation
|
||||
from engine.core.graphene.object_types import (
|
||||
AddressType,
|
||||
BulkProductInput,
|
||||
|
|
@ -32,7 +31,7 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
|
||||
# noinspection PyUnusedLocal
|
||||
class CacheOperator(BaseMutation):
|
||||
class CacheOperator(Mutation):
|
||||
class Meta:
|
||||
description = _("cache I/O")
|
||||
|
||||
|
|
@ -54,7 +53,7 @@ class CacheOperator(BaseMutation):
|
|||
|
||||
|
||||
# noinspection PyUnusedLocal
|
||||
class RequestCursedURL(BaseMutation):
|
||||
class RequestCursedURL(Mutation):
|
||||
class Meta:
|
||||
description = _("request a CORSed URL")
|
||||
|
||||
|
|
@ -82,7 +81,7 @@ class RequestCursedURL(BaseMutation):
|
|||
|
||||
|
||||
# noinspection PyUnusedLocal,PyTypeChecker
|
||||
class AddOrderProduct(BaseMutation):
|
||||
class AddOrderProduct(Mutation):
|
||||
class Meta:
|
||||
description = _("add a product to the order")
|
||||
|
||||
|
|
@ -105,13 +104,13 @@ class AddOrderProduct(BaseMutation):
|
|||
product_uuid=product_uuid, attributes=format_attributes(attributes)
|
||||
)
|
||||
|
||||
return AddOrderProduct(order=order)
|
||||
return AddOrderProduct(order=order) # ty: ignore[unknown-argument]
|
||||
except Order.DoesNotExist as dne:
|
||||
raise Http404(_(f"order {order_uuid} not found")) from dne
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal,PyTypeChecker
|
||||
class RemoveOrderProduct(BaseMutation):
|
||||
class RemoveOrderProduct(Mutation):
|
||||
class Meta:
|
||||
description = _("remove a product from the order")
|
||||
|
||||
|
|
@ -134,13 +133,13 @@ class RemoveOrderProduct(BaseMutation):
|
|||
product_uuid=product_uuid, attributes=format_attributes(attributes)
|
||||
)
|
||||
|
||||
return RemoveOrderProduct(order=order)
|
||||
return RemoveOrderProduct(order=order) # ty: ignore[unknown-argument]
|
||||
except Order.DoesNotExist as dne:
|
||||
raise Http404(_(f"order {order_uuid} not found")) from dne
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal,PyTypeChecker
|
||||
class RemoveAllOrderProducts(BaseMutation):
|
||||
class RemoveAllOrderProducts(Mutation):
|
||||
class Meta:
|
||||
description = _("remove all products from the order")
|
||||
|
||||
|
|
@ -158,11 +157,11 @@ class RemoveAllOrderProducts(BaseMutation):
|
|||
|
||||
order = order.remove_all_products()
|
||||
|
||||
return RemoveAllOrderProducts(order=order)
|
||||
return RemoveAllOrderProducts(order=order) # ty: ignore[unknown-argument]
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal,PyTypeChecker
|
||||
class RemoveOrderProductsOfAKind(BaseMutation):
|
||||
class RemoveOrderProductsOfAKind(Mutation):
|
||||
class Meta:
|
||||
description = _("remove a product from the order")
|
||||
|
||||
|
|
@ -181,11 +180,11 @@ class RemoveOrderProductsOfAKind(BaseMutation):
|
|||
|
||||
order = order.remove_products_of_a_kind(product_uuid=product_uuid)
|
||||
|
||||
return RemoveOrderProductsOfAKind(order=order)
|
||||
return RemoveOrderProductsOfAKind(order=order) # ty: ignore[unknown-argument]
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal,PyTypeChecker
|
||||
class BuyOrder(BaseMutation):
|
||||
class BuyOrder(Mutation):
|
||||
class Meta:
|
||||
description = _("buy an order")
|
||||
|
||||
|
|
@ -230,7 +229,7 @@ class BuyOrder(BaseMutation):
|
|||
elif order_hr_id:
|
||||
order = Order.objects.get(user=user, human_readable_id=order_hr_id)
|
||||
|
||||
instance = order.buy(
|
||||
instance = order.buy( # ty: ignore[possibly-missing-attribute]
|
||||
force_balance=force_balance,
|
||||
force_payment=force_payment,
|
||||
promocode_uuid=promocode_uuid,
|
||||
|
|
@ -241,9 +240,9 @@ class BuyOrder(BaseMutation):
|
|||
|
||||
match str(type(instance)):
|
||||
case "<class 'engine.payments.models.Transaction'>":
|
||||
return BuyOrder(transaction=instance)
|
||||
return BuyOrder(transaction=instance) # ty: ignore[unknown-argument]
|
||||
case "<class 'engine.core.models.Order'>":
|
||||
return BuyOrder(order=instance)
|
||||
return BuyOrder(order=instance) # ty: ignore[unknown-argument]
|
||||
case _:
|
||||
raise TypeError(
|
||||
_(
|
||||
|
|
@ -256,7 +255,7 @@ class BuyOrder(BaseMutation):
|
|||
|
||||
|
||||
# noinspection PyUnusedLocal,PyTypeChecker
|
||||
class BulkOrderAction(BaseMutation):
|
||||
class BulkOrderAction(Mutation):
|
||||
class Meta:
|
||||
description = _("perform an action on a list of products in the order")
|
||||
|
||||
|
|
@ -295,20 +294,20 @@ class BulkOrderAction(BaseMutation):
|
|||
# noinspection PyUnreachableCode
|
||||
match action:
|
||||
case "add":
|
||||
order = order.bulk_add_products(products)
|
||||
order = order.bulk_add_products(products) # ty: ignore[possibly-missing-attribute]
|
||||
case "remove":
|
||||
order = order.bulk_remove_products(products)
|
||||
order = order.bulk_remove_products(products) # ty: ignore[possibly-missing-attribute]
|
||||
case _:
|
||||
raise BadRequest(_("action must be either add or remove"))
|
||||
|
||||
return BulkOrderAction(order=order)
|
||||
return BulkOrderAction(order=order) # ty: ignore[unknown-argument]
|
||||
|
||||
except Order.DoesNotExist as dne:
|
||||
raise Http404(_(f"order {order_uuid} not found")) from dne
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal,PyTypeChecker
|
||||
class BulkWishlistAction(BaseMutation):
|
||||
class BulkWishlistAction(Mutation):
|
||||
class Meta:
|
||||
description = _("perform an action on a list of products in the wishlist")
|
||||
|
||||
|
|
@ -336,20 +335,20 @@ class BulkWishlistAction(BaseMutation):
|
|||
# noinspection PyUnreachableCode
|
||||
match action:
|
||||
case "add":
|
||||
wishlist = wishlist.bulk_add_products(products)
|
||||
wishlist = wishlist.bulk_add_products(products) # ty: ignore[possibly-missing-attribute]
|
||||
case "remove":
|
||||
wishlist = wishlist.bulk_remove_products(products)
|
||||
wishlist = wishlist.bulk_remove_products(products) # ty: ignore[possibly-missing-attribute]
|
||||
case _:
|
||||
raise BadRequest(_("action must be either add or remove"))
|
||||
|
||||
return BulkWishlistAction(wishlist=wishlist)
|
||||
return BulkWishlistAction(wishlist=wishlist) # ty: ignore[unknown-argument]
|
||||
|
||||
except Wishlist.DoesNotExist as dne:
|
||||
raise Http404(_(f"wishlist {wishlist_uuid} not found")) from dne
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal
|
||||
class BuyUnregisteredOrder(BaseMutation):
|
||||
class BuyUnregisteredOrder(Mutation):
|
||||
class Meta:
|
||||
description = _("purchase an order without account creation")
|
||||
|
||||
|
|
@ -393,11 +392,11 @@ class BuyUnregisteredOrder(BaseMutation):
|
|||
is_business=is_business,
|
||||
)
|
||||
# noinspection PyTypeChecker
|
||||
return BuyUnregisteredOrder(transaction=transaction)
|
||||
return BuyUnregisteredOrder(transaction=transaction) # ty: ignore[unknown-argument]
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal,PyTypeChecker
|
||||
class AddWishlistProduct(BaseMutation):
|
||||
class AddWishlistProduct(Mutation):
|
||||
class Meta:
|
||||
description = _("add a product to the wishlist")
|
||||
|
||||
|
|
@ -418,14 +417,14 @@ class AddWishlistProduct(BaseMutation):
|
|||
|
||||
wishlist.add_product(product_uuid=product_uuid)
|
||||
|
||||
return AddWishlistProduct(wishlist=wishlist)
|
||||
return AddWishlistProduct(wishlist=wishlist) # ty: ignore[unknown-argument]
|
||||
|
||||
except Wishlist.DoesNotExist as dne:
|
||||
raise Http404(_(f"wishlist {wishlist_uuid} not found")) from dne
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal,PyTypeChecker
|
||||
class RemoveWishlistProduct(BaseMutation):
|
||||
class RemoveWishlistProduct(Mutation):
|
||||
class Meta:
|
||||
description = _("remove a product from the wishlist")
|
||||
|
||||
|
|
@ -446,14 +445,14 @@ class RemoveWishlistProduct(BaseMutation):
|
|||
|
||||
wishlist.remove_product(product_uuid=product_uuid)
|
||||
|
||||
return RemoveWishlistProduct(wishlist=wishlist)
|
||||
return RemoveWishlistProduct(wishlist=wishlist) # ty: ignore[unknown-argument]
|
||||
|
||||
except Wishlist.DoesNotExist as dne:
|
||||
raise Http404(_(f"wishlist {wishlist_uuid} not found")) from dne
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal,PyTypeChecker
|
||||
class RemoveAllWishlistProducts(BaseMutation):
|
||||
class RemoveAllWishlistProducts(Mutation):
|
||||
class Meta:
|
||||
description = _("remove all products from the wishlist")
|
||||
|
||||
|
|
@ -474,14 +473,14 @@ class RemoveAllWishlistProducts(BaseMutation):
|
|||
for product in wishlist.products.all():
|
||||
wishlist.remove_product(product_uuid=product.pk)
|
||||
|
||||
return RemoveAllWishlistProducts(wishlist=wishlist)
|
||||
return RemoveAllWishlistProducts(wishlist=wishlist) # ty: ignore[unknown-argument]
|
||||
|
||||
except Wishlist.DoesNotExist as dne:
|
||||
raise Http404(_(f"wishlist {wishlist_uuid} not found")) from dne
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal,PyTypeChecker
|
||||
class BuyWishlist(BaseMutation):
|
||||
class BuyWishlist(Mutation):
|
||||
class Meta:
|
||||
description = _("buy all products from the wishlist")
|
||||
|
||||
|
|
@ -516,9 +515,9 @@ class BuyWishlist(BaseMutation):
|
|||
)
|
||||
match str(type(instance)):
|
||||
case "<class 'engine.payments.models.Transaction'>":
|
||||
return BuyWishlist(transaction=instance)
|
||||
return BuyWishlist(transaction=instance) # ty: ignore[unknown-argument]
|
||||
case "<class 'engine.core.models.Order'>":
|
||||
return BuyWishlist(order=instance)
|
||||
return BuyWishlist(order=instance) # ty: ignore[unknown-argument]
|
||||
case _:
|
||||
raise TypeError(
|
||||
_(
|
||||
|
|
@ -531,7 +530,7 @@ class BuyWishlist(BaseMutation):
|
|||
|
||||
|
||||
# noinspection PyUnusedLocal,PyTypeChecker
|
||||
class BuyProduct(BaseMutation):
|
||||
class BuyProduct(Mutation):
|
||||
class Meta:
|
||||
description = _("buy a product")
|
||||
|
||||
|
|
@ -566,9 +565,9 @@ class BuyProduct(BaseMutation):
|
|||
instance = order.buy(force_balance=force_balance, force_payment=force_payment)
|
||||
match str(type(instance)):
|
||||
case "<class 'engine.payments.models.Transaction'>":
|
||||
return BuyProduct(transaction=instance)
|
||||
return BuyProduct(transaction=instance) # ty: ignore[unknown-argument]
|
||||
case "<class 'engine.core.models.Order'>":
|
||||
return BuyProduct(order=instance)
|
||||
return BuyProduct(order=instance) # ty: ignore[unknown-argument]
|
||||
case _:
|
||||
raise TypeError(
|
||||
_(f"wrong type came from order.buy() method: {type(instance)!s}")
|
||||
|
|
@ -576,7 +575,7 @@ class BuyProduct(BaseMutation):
|
|||
|
||||
|
||||
# noinspection PyUnusedLocal,PyTypeChecker
|
||||
class FeedbackProductAction(BaseMutation):
|
||||
class FeedbackProductAction(Mutation):
|
||||
class Meta:
|
||||
description = _("add or delete a feedback for orderproduct")
|
||||
|
||||
|
|
@ -605,13 +604,13 @@ class FeedbackProductAction(BaseMutation):
|
|||
feedback = order_product.do_feedback(action="remove")
|
||||
case _:
|
||||
raise BadRequest(_("action must be either `add` or `remove`"))
|
||||
return FeedbackProductAction(feedback=feedback)
|
||||
return FeedbackProductAction(feedback=feedback) # ty: ignore[unknown-argument]
|
||||
except OrderProduct.DoesNotExist as dne:
|
||||
raise Http404(_(f"order product {order_product_uuid} not found")) from dne
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal,PyTypeChecker
|
||||
class CreateAddress(BaseMutation):
|
||||
class CreateAddress(Mutation):
|
||||
class Arguments:
|
||||
raw_data = String(
|
||||
required=True, description=_("original address string provided by the user")
|
||||
|
|
@ -624,11 +623,11 @@ class CreateAddress(BaseMutation):
|
|||
user = info.context.user if info.context.user.is_authenticated else None
|
||||
|
||||
address = Address.objects.create(raw_data=raw_data, user=user)
|
||||
return CreateAddress(address=address)
|
||||
return CreateAddress(address=address) # ty: ignore[unknown-argument]
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal
|
||||
class DeleteAddress(BaseMutation):
|
||||
class DeleteAddress(Mutation):
|
||||
class Arguments:
|
||||
uuid = UUID(required=True)
|
||||
|
||||
|
|
@ -645,7 +644,7 @@ class DeleteAddress(BaseMutation):
|
|||
):
|
||||
address.delete()
|
||||
# noinspection PyTypeChecker
|
||||
return DeleteAddress(success=True)
|
||||
return DeleteAddress(success=True) # ty: ignore[unknown-argument]
|
||||
|
||||
raise PermissionDenied(permission_denied_message)
|
||||
|
||||
|
|
@ -655,7 +654,7 @@ class DeleteAddress(BaseMutation):
|
|||
|
||||
|
||||
# noinspection PyUnusedLocal
|
||||
class AutocompleteAddress(BaseMutation):
|
||||
class AutocompleteAddress(Mutation):
|
||||
class Arguments:
|
||||
q = String()
|
||||
limit = Int()
|
||||
|
|
@ -672,11 +671,11 @@ class AutocompleteAddress(BaseMutation):
|
|||
raise BadRequest(f"geocoding error: {e!s}") from e
|
||||
|
||||
# noinspection PyTypeChecker
|
||||
return AutocompleteAddress(suggestions=suggestions)
|
||||
return AutocompleteAddress(suggestions=suggestions) # ty: ignore[unknown-argument]
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal
|
||||
class ContactUs(BaseMutation):
|
||||
class ContactUs(Mutation):
|
||||
class Arguments:
|
||||
email = String(required=True)
|
||||
name = String(required=True)
|
||||
|
|
@ -700,14 +699,14 @@ class ContactUs(BaseMutation):
|
|||
}
|
||||
)
|
||||
# noinspection PyTypeChecker
|
||||
return ContactUs(received=True)
|
||||
return ContactUs(received=True) # ty: ignore[unknown-argument]
|
||||
except Exception as e:
|
||||
# noinspection PyTypeChecker
|
||||
return ContactUs(received=False, error=str(e))
|
||||
return ContactUs(received=False, error=str(e)) # ty: ignore[unknown-argument]
|
||||
|
||||
|
||||
# noinspection PyArgumentList PyUnusedLocal
|
||||
class Search(BaseMutation):
|
||||
class Search(Mutation):
|
||||
class Arguments:
|
||||
query = String(required=True)
|
||||
|
||||
|
|
@ -720,12 +719,15 @@ class Search(BaseMutation):
|
|||
def mutate(parent, info, query):
|
||||
data = process_query(query=query, request=info.context)
|
||||
|
||||
if not data:
|
||||
return Search(results=None) # ty: ignore[unknown-argument]
|
||||
|
||||
# noinspection PyTypeChecker
|
||||
return Search(
|
||||
results=SearchResultsType(
|
||||
products=data["products"],
|
||||
categories=data["categories"],
|
||||
brands=data["brands"],
|
||||
posts=data["posts"],
|
||||
return Search( # ty: ignore[unknown-argument]
|
||||
results=SearchResultsType( # ty: ignore[unknown-argument]
|
||||
products=data["products"], # ty: ignore[unknown-argument]
|
||||
categories=data["categories"], # ty: ignore[unknown-argument]
|
||||
brands=data["brands"], # ty: ignore[unknown-argument]
|
||||
posts=data["posts"], # ty: ignore[unknown-argument]
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,9 @@ from graphene import (
|
|||
)
|
||||
from graphene.types.generic import GenericScalar
|
||||
from graphene_django import DjangoObjectType
|
||||
from graphene_django.filter import DjangoFilterConnectionField
|
||||
from graphene_django.filter import (
|
||||
DjangoFilterConnectionField, # ty:ignore[possibly-missing-import]
|
||||
)
|
||||
from mptt.querysets import TreeQuerySet
|
||||
|
||||
from engine.core.models import (
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ from django.core.exceptions import PermissionDenied
|
|||
from django.db.models import Case, Exists, IntegerField, OuterRef, Q, Value, When
|
||||
from django.utils import timezone
|
||||
from graphene import Field, List, ObjectType, Schema
|
||||
from graphene_django.filter import DjangoFilterConnectionField
|
||||
from graphene_django.filter import (
|
||||
DjangoFilterConnectionField, # ty:ignore[possibly-missing-import]
|
||||
)
|
||||
|
||||
from engine.blog.filters import PostFilter
|
||||
from engine.blog.graphene.object_types import PostType
|
||||
|
|
|
|||
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
|
|
@ -6,7 +6,7 @@ from tempfile import NamedTemporaryFile
|
|||
from typing import Any
|
||||
|
||||
import polib
|
||||
from django.apps import apps
|
||||
from django.apps import AppConfig, apps
|
||||
from django.conf import settings
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ class Command(BaseCommand):
|
|||
help="Root path prefix to adjust file links",
|
||||
)
|
||||
|
||||
def handle(self, *args: list[Any], **options: dict[str, str | list[str]]) -> None:
|
||||
def handle(self, *args: Any, **options: Any) -> None:
|
||||
langs: list[str] = options.get("target_languages", [])
|
||||
if "ALL" in langs:
|
||||
langs = list(dict(settings.LANGUAGES).keys())
|
||||
|
|
@ -103,7 +103,7 @@ class Command(BaseCommand):
|
|||
apps_to_scan = set(TRANSLATABLE_APPS)
|
||||
root_path: str = options.get("root_path") or "/app/"
|
||||
|
||||
configs = list(apps.get_app_configs())
|
||||
configs: list[AppConfig | RootDirectory] = list(apps.get_app_configs())
|
||||
# noinspection PyTypeChecker
|
||||
configs.append(RootDirectory())
|
||||
|
||||
|
|
|
|||
|
|
@ -106,10 +106,10 @@ class Command(BaseCommand):
|
|||
help="App label for translation, e.g. core, payments. Use ALL to translate all apps.",
|
||||
)
|
||||
|
||||
def handle(self, *args: list[Any], **options: dict[Any, Any]) -> None:
|
||||
target_langs: list[str] = options["target_languages"]
|
||||
def handle(self, *args: Any, **options: Any) -> None:
|
||||
target_langs = options["target_languages"]
|
||||
if "ALL" in target_langs:
|
||||
target_langs = DEEPL_TARGET_LANGUAGES_MAPPING.keys()
|
||||
target_langs = list(DEEPL_TARGET_LANGUAGES_MAPPING.keys())
|
||||
target_apps = set(options["target_apps"])
|
||||
if "ALL" in target_apps:
|
||||
target_apps = {
|
||||
|
|
@ -122,10 +122,13 @@ class Command(BaseCommand):
|
|||
raise CommandError("DEEPL_AUTH_KEY not set")
|
||||
|
||||
# attempt to import readline for interactive fill
|
||||
readline: Any = None
|
||||
try:
|
||||
import readline
|
||||
import readline as readline_module
|
||||
|
||||
readline = readline_module
|
||||
except ImportError:
|
||||
readline = None
|
||||
pass
|
||||
|
||||
for target_lang in target_langs:
|
||||
api_code = DEEPL_TARGET_LANGUAGES_MAPPING.get(target_lang)
|
||||
|
|
@ -176,16 +179,16 @@ class Command(BaseCommand):
|
|||
if readline:
|
||||
|
||||
def hook() -> None:
|
||||
readline.insert_text(default) # noqa: B023
|
||||
readline.redisplay()
|
||||
readline.insert_text(default) # noqa: B023 # ty: ignore[unresolved-attribute]
|
||||
readline.redisplay() # ty: ignore[unresolved-attribute]
|
||||
|
||||
readline.set_pre_input_hook(hook)
|
||||
readline.set_pre_input_hook(hook) # ty: ignore[unresolved-attribute]
|
||||
|
||||
prompt = f"Enter translation for '{e.msgid}': "
|
||||
user_in = input(prompt).strip()
|
||||
|
||||
if readline:
|
||||
readline.set_pre_input_hook(None)
|
||||
readline.set_pre_input_hook(None) # ty: ignore[unresolved-attribute]
|
||||
|
||||
if user_in:
|
||||
e.msgstr = user_in
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class Command(BaseCommand):
|
|||
help="Chunk size to delete",
|
||||
)
|
||||
|
||||
def handle(self, *args: list[Any], **options: dict[Any, Any]) -> None:
|
||||
def handle(self, *args: Any, **options: Any) -> None:
|
||||
size: int = options["size"]
|
||||
while True:
|
||||
batch_ids = list(
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class Command(BaseCommand):
|
|||
help="Chunk size to delete",
|
||||
)
|
||||
|
||||
def handle(self, *args: list[Any], **options: dict[Any, Any]) -> None:
|
||||
def handle(self, *args: Any, **options: Any) -> None:
|
||||
size: int = options["size"]
|
||||
while True:
|
||||
batch_ids = list(
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class AddressManager(models.Manager):
|
|||
if not kwargs.get("raw_data"):
|
||||
raise ValueError("'raw_data' (address string) must be provided.")
|
||||
|
||||
params: dict[str, str | int] = {
|
||||
params: dict[str, str | int | None] = {
|
||||
"format": "json",
|
||||
"addressdetails": 1,
|
||||
"q": kwargs.get("raw_data"),
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue