mirror of
https://github.com/Alexander-D-Karpov/akarpov
synced 2025-07-30 19:49:45 +03:00
Compare commits
4 Commits
bd6c096083
...
fa51fa7605
Author | SHA1 | Date | |
---|---|---|---|
|
fa51fa7605 | ||
|
e74e2f7bb7 | ||
f6f15d3979 | |||
f59df63dd4 |
|
@ -6,3 +6,6 @@ USE_DOCKER=no
|
||||||
EMAIL_HOST=127.0.0.1
|
EMAIL_HOST=127.0.0.1
|
||||||
EMAIL_PORT=1025
|
EMAIL_PORT=1025
|
||||||
SENTRY_DSN=
|
SENTRY_DSN=
|
||||||
|
EMAIL_PASSWORD=
|
||||||
|
EMAIL_USER=
|
||||||
|
EMAIL_USE_SSL=false
|
||||||
|
|
|
@ -10,8 +10,18 @@
|
||||||
app_name = "music"
|
app_name = "music"
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("playlists/", ListCreatePlaylistAPIView.as_view()),
|
path(
|
||||||
path("playlists/<str:slug>", RetrieveUpdateDestroyPlaylistAPIView.as_view()),
|
"playlists/", ListCreatePlaylistAPIView.as_view(), name="list_create_playlist"
|
||||||
path("song/", ListCreateSongAPIView.as_view()),
|
),
|
||||||
path("song/<str:slug>", RetrieveUpdateDestroySongAPIView.as_view()),
|
path(
|
||||||
|
"playlists/<str:slug>",
|
||||||
|
RetrieveUpdateDestroyPlaylistAPIView.as_view(),
|
||||||
|
name="retrieve_update_delete_playlist",
|
||||||
|
),
|
||||||
|
path("song/", ListCreateSongAPIView.as_view(), name="list_create_song"),
|
||||||
|
path(
|
||||||
|
"song/<str:slug>",
|
||||||
|
RetrieveUpdateDestroySongAPIView.as_view(),
|
||||||
|
name="retrieve_update_delete_song",
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
6
akarpov/tools/api/serializers.py
Normal file
6
akarpov/tools/api/serializers.py
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
|
||||||
|
class URLPathSerializer(serializers.Serializer):
|
||||||
|
path = serializers.URLField()
|
||||||
|
kwargs = serializers.DictField(help_text="{'slug': 'str', 'pk': 'int'}")
|
68
akarpov/tools/api/services.py
Normal file
68
akarpov/tools/api/services.py
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
from functools import lru_cache
|
||||||
|
|
||||||
|
from config import urls as urls_conf
|
||||||
|
|
||||||
|
urls = None
|
||||||
|
|
||||||
|
|
||||||
|
def get_urls(urllist, name="") -> (list, list):
|
||||||
|
res = []
|
||||||
|
res_short = []
|
||||||
|
for entry in urllist:
|
||||||
|
if hasattr(entry, "url_patterns"):
|
||||||
|
if entry.namespace != "admin":
|
||||||
|
rres, rres_short = get_urls(
|
||||||
|
entry.url_patterns,
|
||||||
|
name + entry.namespace + ":" if entry.namespace else name,
|
||||||
|
)
|
||||||
|
res += rres
|
||||||
|
res_short += rres_short
|
||||||
|
else:
|
||||||
|
res.append(
|
||||||
|
(
|
||||||
|
name + entry.pattern.name if entry.pattern.name else "",
|
||||||
|
str(entry.pattern),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
res_short.append(
|
||||||
|
(
|
||||||
|
entry.pattern.name,
|
||||||
|
str(entry.pattern),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return res, res_short
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache
|
||||||
|
def urlpattern_to_js(pattern: str) -> (str, dict):
|
||||||
|
if pattern.startswith("^"):
|
||||||
|
return pattern
|
||||||
|
res = ""
|
||||||
|
kwargs = {}
|
||||||
|
for p in pattern.split("<"):
|
||||||
|
if ">" in p:
|
||||||
|
rec = ""
|
||||||
|
pn = p.split(">")
|
||||||
|
k = pn[0].split(":")
|
||||||
|
if len(k) == 1:
|
||||||
|
rec = "{" + k[0] + "}"
|
||||||
|
kwargs[k[0]] = "any"
|
||||||
|
elif len(k) == 2:
|
||||||
|
rec = "{" + k[1] + "}"
|
||||||
|
kwargs[k[1]] = k[0]
|
||||||
|
res += rec + pn[-1]
|
||||||
|
else:
|
||||||
|
res += p
|
||||||
|
|
||||||
|
return res, kwargs
|
||||||
|
|
||||||
|
|
||||||
|
def get_api_path_by_url(name: str) -> tuple[str, dict] | None:
|
||||||
|
global urls
|
||||||
|
if not urls:
|
||||||
|
urls, urls_short = get_urls(urls_conf.urlpatterns)
|
||||||
|
urls = dict(urls_short) | dict(urls)
|
||||||
|
|
||||||
|
if name in urls:
|
||||||
|
return urlpattern_to_js(urls[name])
|
||||||
|
return None
|
|
@ -1,7 +1,10 @@
|
||||||
from django.urls import include, path
|
from django.urls import include, path
|
||||||
|
|
||||||
|
from akarpov.tools.api.views import RetrieveAPIUrlAPIView
|
||||||
|
|
||||||
app_name = "tools"
|
app_name = "tools"
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
path("<str:path>", RetrieveAPIUrlAPIView.as_view(), name="path"),
|
||||||
path("qr/", include("akarpov.tools.qr.api.urls", namespace="qr")),
|
path("qr/", include("akarpov.tools.qr.api.urls", namespace="qr")),
|
||||||
]
|
]
|
||||||
|
|
18
akarpov/tools/api/views.py
Normal file
18
akarpov/tools/api/views.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
from rest_framework import generics
|
||||||
|
from rest_framework.exceptions import NotFound
|
||||||
|
from rest_framework.permissions import AllowAny
|
||||||
|
from rest_framework.response import Response
|
||||||
|
|
||||||
|
from akarpov.tools.api.serializers import URLPathSerializer
|
||||||
|
from akarpov.tools.api.services import get_api_path_by_url
|
||||||
|
|
||||||
|
|
||||||
|
class RetrieveAPIUrlAPIView(generics.GenericAPIView):
|
||||||
|
serializer_class = URLPathSerializer
|
||||||
|
permission_classes = [AllowAny]
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
path, k_args = get_api_path_by_url(self.kwargs["path"])
|
||||||
|
if not path:
|
||||||
|
raise NotFound
|
||||||
|
return Response(data={"path": path, "kwargs": k_args})
|
|
@ -1,4 +1,4 @@
|
||||||
FROM traefik:2.10.1
|
FROM traefik:2.10.5
|
||||||
RUN mkdir -p /etc/traefik/acme \
|
RUN mkdir -p /etc/traefik/acme \
|
||||||
&& touch /etc/traefik/acme/acme.json \
|
&& touch /etc/traefik/acme/acme.json \
|
||||||
&& chmod 600 /etc/traefik/acme/acme.json
|
&& chmod 600 /etc/traefik/acme/acme.json
|
||||||
|
|
|
@ -11,10 +11,6 @@ entryPoints:
|
||||||
entryPoint:
|
entryPoint:
|
||||||
to: web-secure
|
to: web-secure
|
||||||
|
|
||||||
web-secure:
|
|
||||||
# https
|
|
||||||
address: ":443"
|
|
||||||
|
|
||||||
flower:
|
flower:
|
||||||
address: ":5555"
|
address: ":5555"
|
||||||
|
|
||||||
|
@ -29,27 +25,6 @@ certificatesResolvers:
|
||||||
entryPoint: web
|
entryPoint: web
|
||||||
|
|
||||||
http:
|
http:
|
||||||
routers:
|
|
||||||
web-secure-router:
|
|
||||||
rule: "Host(`akarpov.ru`) || Host(`www.akarpov.ru`)"
|
|
||||||
entryPoints:
|
|
||||||
- web-secure
|
|
||||||
middlewares:
|
|
||||||
- csrf
|
|
||||||
service: django
|
|
||||||
tls:
|
|
||||||
# https://docs.traefik.io/master/routing/routers/#certresolver
|
|
||||||
certResolver: letsencrypt
|
|
||||||
|
|
||||||
flower-secure-router:
|
|
||||||
rule: "Host(`akarpov.ru`)"
|
|
||||||
entryPoints:
|
|
||||||
- flower
|
|
||||||
service: flower
|
|
||||||
tls:
|
|
||||||
# https://docs.traefik.io/master/routing/routers/#certresolver
|
|
||||||
certResolver: letsencrypt
|
|
||||||
|
|
||||||
middlewares:
|
middlewares:
|
||||||
csrf:
|
csrf:
|
||||||
# https://docs.traefik.io/master/middlewares/headers/#hostsproxyheaders
|
# https://docs.traefik.io/master/middlewares/headers/#hostsproxyheaders
|
||||||
|
|
|
@ -307,6 +307,18 @@
|
||||||
)
|
)
|
||||||
# https://docs.djangoproject.com/en/dev/ref/settings/#email-timeout
|
# https://docs.djangoproject.com/en/dev/ref/settings/#email-timeout
|
||||||
EMAIL_TIMEOUT = 5
|
EMAIL_TIMEOUT = 5
|
||||||
|
EMAIL_HOST_PASSWORD = env(
|
||||||
|
"EMAIL_PASSWORD",
|
||||||
|
default="",
|
||||||
|
)
|
||||||
|
EMAIL_HOST_USER = env(
|
||||||
|
"EMAIL_USER",
|
||||||
|
default="",
|
||||||
|
)
|
||||||
|
EMAIL_USE_SSL = env(
|
||||||
|
"EMAIL_USE_SSL",
|
||||||
|
default=False,
|
||||||
|
)
|
||||||
|
|
||||||
# ADMIN
|
# ADMIN
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
2383
poetry.lock
generated
2383
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user