diff --git a/akarpov/pipeliner/models/base.py b/akarpov/pipeliner/models/base.py index bba1f3a..293f403 100644 --- a/akarpov/pipeliner/models/base.py +++ b/akarpov/pipeliner/models/base.py @@ -38,13 +38,14 @@ def __str__(self): class ProviderBlock(BaseBlock): TYPE = "Provider" parent = None + children: list[BaseBlock] class Meta: abstract = True class BaseStorage(PolymorphicModel): - id: uuid.uuid4 = models.UUIDField( + id: uuid.UUID = models.UUIDField( primary_key=True, default=uuid.uuid4, editable=False ) diff --git a/akarpov/pipeliner/models/manage.py b/akarpov/pipeliner/models/manage.py index ed8c291..4f5fb9a 100644 --- a/akarpov/pipeliner/models/manage.py +++ b/akarpov/pipeliner/models/manage.py @@ -1,7 +1,11 @@ from django.db import models +from akarpov.pipeliner.models import BaseBlock + class Workspace(models.Model): + blocks: list[BaseBlock] + name = models.CharField(max_length=50, blank=True) slug = models.SlugField(max_length=8) diff --git a/akarpov/shortener/urls.py b/akarpov/shortener/urls.py deleted file mode 100644 index 9a35e22..0000000 --- a/akarpov/shortener/urls.py +++ /dev/null @@ -1,10 +0,0 @@ -from django.urls import path - -from akarpov.shortener.views import link_detail_view, short_link_create_view - -app_name = "shortener" - -urlpatterns = [ - path("", short_link_create_view, name="create"), - path("", link_detail_view, name="view"), -] diff --git a/akarpov/static/css/project.css b/akarpov/static/css/project.css index be146d9..bddb619 100644 --- a/akarpov/static/css/project.css +++ b/akarpov/static/css/project.css @@ -31,6 +31,20 @@ p { margin: 0px; } +.profile { + position: absolute; + top: 0; + left: 0; + right: 0; + height: 100%; +} + +.profile-wrapper { + position: relative; + width: 100%; + height: 100vh; +} + .profile-card { background: #E0E0E0; width: 56px; @@ -115,10 +129,9 @@ p { width: 218px; display: inline-block; float: right; - margin: 0px; padding: 15px 20px; background: #FFFFFF; - margin-top: 50px; + margin: 50px 0 0; text-align: center; opacity: 0; -webkit-box-sizing: border-box; @@ -492,3 +505,29 @@ p { font-weight: bolder; margin-right: 5px; } + +.sidebar { + max-height: 15%; +} + +@media (min-width: 576px) { + .h-sm-100 { + height: 100%; + } + .sidebar { + max-height: 100%; + } +} + +.blog-card { + margin-bottom: -99999px; + padding: 10px 10px 99999px; +} + +.nav-active::before { + content: '→'; +} + +.nav-active { + color: white; +} diff --git a/akarpov/templates/account/login.html b/akarpov/templates/account/login.html index 838ed11..519d9ef 100644 --- a/akarpov/templates/account/login.html +++ b/akarpov/templates/account/login.html @@ -12,48 +12,25 @@ {% get_providers as socialaccount_providers %} -{% if socialaccount_providers %} -

- {% translate "Please sign in with one of your existing third party accounts:" %} - {% if ACCOUNT_ALLOW_REGISTRATION %} - {% blocktranslate trimmed %} - Or, sign up - for a {{ site_name }} account and sign in below: - {% endblocktranslate %} - {% endif %} -

- -
- - - - - -
- - {% include "socialaccount/snippets/login_extra.html" %} - -{% else %} - {% if ACCOUNT_ALLOW_REGISTRATION %} -

- {% blocktranslate trimmed %} - If you have not created an account yet, then please - sign up first. - {% endblocktranslate %} -

- {% endif %} -{% endif %} -
{% csrf_token %} {{ form|crispy }} {% if redirect_field_value %} {% endif %} + {% translate "Forgot Password?" %} -
+

Alternative:

+ +{% if socialaccount_providers %} +
+ +
+ {% include "socialaccount/snippets/login_extra.html" %} +{% endif %} + {% endblock %} diff --git a/akarpov/templates/base.html b/akarpov/templates/base.html index 0a65734..256941b 100644 --- a/akarpov/templates/base.html +++ b/akarpov/templates/base.html @@ -11,7 +11,6 @@ - {% block css %} @@ -20,6 +19,7 @@ + {% block css %} {% endblock %} @@ -37,56 +37,87 @@ +
+
+ -
- {% if messages %} - {% for message in messages %} -
- {{ message }} - -
- {% endfor %} - {% endif %} - - {% block content %} - {% endblock content %}
{% block modal %}{% endblock modal %} diff --git a/akarpov/templates/blog/list.html b/akarpov/templates/blog/list.html index eee277d..21b320c 100644 --- a/akarpov/templates/blog/list.html +++ b/akarpov/templates/blog/list.html @@ -9,8 +9,8 @@ {% endif %}
{% for post in post_list %} -
-
+
+
{{ post.h_tag.name }}

{{ post.title }}

@@ -22,7 +22,7 @@ {{ post.comment_count }}

{% if post.image_cropped %} - + {% endif %}
diff --git a/akarpov/templates/users/user_detail.html b/akarpov/templates/users/user_detail.html index afc04a8..780d627 100644 --- a/akarpov/templates/users/user_detail.html +++ b/akarpov/templates/users/user_detail.html @@ -4,54 +4,58 @@ {% block title %}User: {{ object.username }}{% endblock %} {% block content %} - +
- - - {% endblock content %} diff --git a/akarpov/shortener/__init__.py b/akarpov/tools/shortener/__init__.py similarity index 100% rename from akarpov/shortener/__init__.py rename to akarpov/tools/shortener/__init__.py diff --git a/akarpov/shortener/admin.py b/akarpov/tools/shortener/admin.py similarity index 55% rename from akarpov/shortener/admin.py rename to akarpov/tools/shortener/admin.py index 1d82c4a..ef83140 100644 --- a/akarpov/shortener/admin.py +++ b/akarpov/tools/shortener/admin.py @@ -1,5 +1,5 @@ from django.contrib import admin -from akarpov.shortener.models import Link +from akarpov.tools.shortener.models import Link admin.site.register(Link) diff --git a/akarpov/shortener/apps.py b/akarpov/tools/shortener/apps.py similarity index 89% rename from akarpov/shortener/apps.py rename to akarpov/tools/shortener/apps.py index 2d97361..0d21c5d 100644 --- a/akarpov/shortener/apps.py +++ b/akarpov/tools/shortener/apps.py @@ -3,7 +3,7 @@ class ShortenerConfig(AppConfig): - name = "akarpov.shortener" + name = "akarpov.tools.shortener" verbose_name = _("Link shortener") def ready(self): diff --git a/akarpov/shortener/forms.py b/akarpov/tools/shortener/forms.py similarity index 88% rename from akarpov/shortener/forms.py rename to akarpov/tools/shortener/forms.py index fdd0cba..7c36c67 100644 --- a/akarpov/shortener/forms.py +++ b/akarpov/tools/shortener/forms.py @@ -1,7 +1,7 @@ from django import forms from django.core.validators import URLValidator -from akarpov.shortener.models import Link +from akarpov.tools.shortener.models import Link class LinkForm(forms.ModelForm): diff --git a/akarpov/shortener/migrations/0001_initial.py b/akarpov/tools/shortener/migrations/0001_initial.py similarity index 100% rename from akarpov/shortener/migrations/0001_initial.py rename to akarpov/tools/shortener/migrations/0001_initial.py diff --git a/akarpov/shortener/migrations/__init__.py b/akarpov/tools/shortener/migrations/__init__.py similarity index 100% rename from akarpov/shortener/migrations/__init__.py rename to akarpov/tools/shortener/migrations/__init__.py diff --git a/akarpov/shortener/models.py b/akarpov/tools/shortener/models.py similarity index 92% rename from akarpov/shortener/models.py rename to akarpov/tools/shortener/models.py index aed6414..f256faa 100644 --- a/akarpov/shortener/models.py +++ b/akarpov/tools/shortener/models.py @@ -15,7 +15,7 @@ class Link(TimeStampedModel): viewed = models.IntegerField(default=0) def get_absolute_url(self): - return reverse("shortener:view", kwargs={"slug": self.slug}) + return reverse("short_url", kwargs={"slug": self.slug}) def __str__(self): return f"link to {self.source}" diff --git a/akarpov/shortener/services.py b/akarpov/tools/shortener/services.py similarity index 81% rename from akarpov/shortener/services.py rename to akarpov/tools/shortener/services.py index 39b75f5..e74163b 100644 --- a/akarpov/shortener/services.py +++ b/akarpov/tools/shortener/services.py @@ -1,21 +1,21 @@ from django.conf import settings -from akarpov.shortener.models import Link +from akarpov.tools.shortener.models import Link from akarpov.utils.generators import generate_charset, get_pk_from_uuid, get_str_uuid -lenght = settings.SHORTENER_SLUG_LENGTH +length = settings.SHORTENER_SLUG_LENGTH def generate_slug(pk: int) -> str: if settings.SHORTENER_ADD_SLUG: - slug = generate_charset(lenght) + slug = generate_charset(length) return slug + get_str_uuid(pk) return get_str_uuid(pk) def get_link_from_slug(slug: str, check_whole=False) -> Link | bool: if settings.SHORTENER_ADD_SLUG and not check_whole: - payload = slug[lenght:] + payload = slug[length:] pk = get_pk_from_uuid(payload) try: return Link.objects.get(pk=pk) diff --git a/akarpov/shortener/signals.py b/akarpov/tools/shortener/signals.py similarity index 73% rename from akarpov/shortener/signals.py rename to akarpov/tools/shortener/signals.py index d00cc4e..389eb96 100644 --- a/akarpov/shortener/signals.py +++ b/akarpov/tools/shortener/signals.py @@ -1,8 +1,8 @@ from django.db.models.signals import post_save from django.dispatch import receiver -from akarpov.shortener.models import Link -from akarpov.shortener.services import generate_slug +from akarpov.tools.shortener.models import Link +from akarpov.tools.shortener.services import generate_slug @receiver(post_save, sender=Link) diff --git a/akarpov/shortener/tests.py b/akarpov/tools/shortener/tests.py similarity index 100% rename from akarpov/shortener/tests.py rename to akarpov/tools/shortener/tests.py diff --git a/akarpov/tools/shortener/urls.py b/akarpov/tools/shortener/urls.py new file mode 100644 index 0000000..718ecda --- /dev/null +++ b/akarpov/tools/shortener/urls.py @@ -0,0 +1,9 @@ +from django.urls import path + +from akarpov.tools.shortener.views import short_link_create_view + +app_name = "shortener" + +urlpatterns = [ + path("", short_link_create_view, name="create"), +] diff --git a/akarpov/shortener/views.py b/akarpov/tools/shortener/views.py similarity index 84% rename from akarpov/shortener/views.py rename to akarpov/tools/shortener/views.py index a76b173..64ccaad 100644 --- a/akarpov/shortener/views.py +++ b/akarpov/tools/shortener/views.py @@ -1,9 +1,9 @@ from django.core.exceptions import ObjectDoesNotExist, PermissionDenied from django.views.generic import CreateView, DetailView -from akarpov.shortener.forms import LinkForm -from akarpov.shortener.models import Link -from akarpov.shortener.services import get_link_from_slug +from akarpov.tools.shortener.forms import LinkForm +from akarpov.tools.shortener.models import Link +from akarpov.tools.shortener.services import get_link_from_slug class ShortLinkCreateView(CreateView): diff --git a/akarpov/tools/urls.py b/akarpov/tools/urls.py index 2cf1eb8..47d5d85 100644 --- a/akarpov/tools/urls.py +++ b/akarpov/tools/urls.py @@ -1,4 +1,7 @@ from django.urls import include, path app_name = "tools" -urlpatterns = [path("qr/", include("akarpov.tools.qr.urls", namespace="qr"))] +urlpatterns = [ + path("qr/", include("akarpov.tools.qr.urls", namespace="qr")), + path("shortener/", include("akarpov.tools.shortener.urls", namespace="shortener")), +] diff --git a/config/settings/base.py b/config/settings/base.py index b7f0f1f..4d50260 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -141,8 +141,8 @@ "akarpov.users", "akarpov.blog", "akarpov.files", - "akarpov.shortener", "akarpov.pipeliner", + "akarpov.tools.shortener", "akarpov.tools.qr", ] # https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps @@ -519,4 +519,4 @@ # ACTIVE_LINK # ------------------------------------------------------------------------------ -ACTIVE_LINK_CSS_CLASS = "active" +ACTIVE_LINK_CSS_CLASS = "nav-active" diff --git a/config/urls.py b/config/urls.py index 49ffc21..cd100a8 100644 --- a/config/urls.py +++ b/config/urls.py @@ -10,6 +10,8 @@ SpectacularSwaggerView, ) +from akarpov.tools.shortener.views import link_detail_view + urlpatterns = [ path("home", TemplateView.as_view(template_name="pages/home.html"), name="home"), path( @@ -22,10 +24,10 @@ # User management path("users/", include("akarpov.users.urls", namespace="users")), path("tools/", include("akarpov.tools.urls", namespace="tools")), - path("shortener/", include("akarpov.shortener.urls", namespace="shortener")), path("ckeditor/", include("ckeditor_uploader.urls")), path("accounts/", include("allauth.urls")), path("", include("akarpov.blog.urls", namespace="blog")), + path("s/", link_detail_view, name="short_url"), # Your stuff: custom urls includes go here ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/poetry.lock b/poetry.lock index c43bf46..1b23708 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1275,27 +1275,30 @@ celery = ["celery (>=5.1)"] [[package]] name = "django-stubs" -version = "1.13.1" +version = "1.14.0" description = "Mypy stubs for Django" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "django-stubs-1.13.1.tar.gz", hash = "sha256:bcc618ba353dabc540d982b9dac1d5a1921652f8fc2a13653d545a57d5e3cc0f"}, - {file = "django_stubs-1.13.1-py3-none-any.whl", hash = "sha256:fbf2ee6a4bce76c3eb5f6707ccadb4cf1c2f1ec485e8c44701ca8de2d0a5df18"}, + {file = "django-stubs-1.14.0.tar.gz", hash = "sha256:d53bcd4975a54ca5c9abbbd33b61f40d44191971018f2ea54f73b0a6a99e1a8b"}, + {file = "django_stubs-1.14.0-py3-none-any.whl", hash = "sha256:b081d64d923171f79d4e57899b0980da847e4046b91166e3658a6151645a36c5"}, ] [package.dependencies] django = "*" django-stubs-ext = ">=0.7.0" -mypy = ">=0.980" +mypy = [ + {version = ">=0.980"}, + {version = ">=0.991,<1.0", optional = true, markers = "extra == \"compatible-mypy\""}, +] tomli = "*" types-pytz = "*" types-PyYAML = "*" typing-extensions = "*" [package.extras] -compatible-mypy = ["mypy (>=0.980,<0.990)"] +compatible-mypy = ["mypy (>=0.991,<1.0)"] [[package]] name = "django-stubs-ext" @@ -2046,7 +2049,6 @@ category = "main" optional = false python-versions = "*" files = [ - {file = "livereload-2.6.3-py2.py3-none-any.whl", hash = "sha256:ad4ac6f53b2d62bb6ce1a5e6e96f1f00976a32348afedcb4b6d68df2a1d346e4"}, {file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"}, ] @@ -3663,6 +3665,7 @@ category = "main" optional = false python-versions = "*" files = [ + {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"}, {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, ] @@ -3777,4 +3780,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "392fed32dc5e397e6fd56683185d571a8bd93faaf71d54bba6479d1dce4dab84" +content-hash = "fe807601a32feb33caa293b0a8639c33ccf436b02efac27a56783dafb95f1942" diff --git a/pyproject.toml b/pyproject.toml index b193fa0..acc60d4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,7 +37,7 @@ werkzeug = {extras = ["watchdog"], version = "^2.2.2"} ipdb = "^0.13.11" watchfiles = "^0.18.1" mypy = "^0.991" -django-stubs = "^1.13.1" +django-stubs = {extras = ["compatible-mypy"], version = "^1.14.0"} pytest = "^7.2.0" pytest-sugar = "^0.9.6" djangorestframework-stubs = {extras = ["compatible-mypy"], version = "^1.8.0"} diff --git a/setup.cfg b/setup.cfg index 2d78fd1..b20382a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -28,8 +28,6 @@ plugins = mypy_django_plugin.main, mypy_drf_plugin.main [mypy.plugins.django-stubs] django_settings_module = config.settings.test -# https://github.com/typeddjango/django-stubs/issues/1158 -django-manager-missing = False [mypy-*.migrations.*] # Django migrations should not produce any errors: