Skip to content

Commit

Permalink
Add logic to keep unique article slug id
Browse files Browse the repository at this point in the history
  • Loading branch information
borys25ol committed Nov 15, 2024
1 parent 8efaf4d commit 2cd38f8
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 7 deletions.
32 changes: 31 additions & 1 deletion conduit/core/utils/slug.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,37 @@
from slugify import slugify


def get_slug_from_title(title: str) -> str:
def make_slug_from_title(title: str) -> str:
"""
Create a unique slug from the title.
Example:
make_slug_from_title("Hello World")
"hello-world-123456"
"""
slug = slugify(text=title, max_length=32, lowercase=True)
unique_code = token_urlsafe(6)
return f"{slug}-{unique_code.lower()}"


def make_slug_from_title_and_code(title: str, code: str) -> str:
"""
Create a unique slug from the title and code.
Example:
make_slug_from_title_and_code("Hello World", "123456")
"hello-world-123456"
"""
slug = slugify(text=title, max_length=32, lowercase=True)
return f"{slug}-{code}"


def get_slug_unique_part(slug: str) -> str:
"""
Get unique part of the slug.
Example:
get_slug_unique_part("hello-world-123456")
"123456"
"""
return slug.split("-")[-1]
19 changes: 13 additions & 6 deletions conduit/infrastructure/repositories/article.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.sql.functions import count

from conduit.core.utils.slug import get_slug_from_title
from conduit.core.utils.slug import (
get_slug_unique_part,
make_slug_from_title,
make_slug_from_title_and_code,
)
from conduit.domain.dtos.article import (
ArticleRecordDTO,
CreateArticleDTO,
Expand Down Expand Up @@ -34,7 +38,7 @@ async def create(
insert(Article)
.values(
author_id=author_id,
slug=get_slug_from_title(title=create_item.title),
slug=make_slug_from_title(title=create_item.title),
title=create_item.title,
description=create_item.description,
body=create_item.body,
Expand All @@ -49,7 +53,10 @@ async def create(
async def get_by_slug(
self, session: AsyncSession, slug: str
) -> ArticleRecordDTO | None:
query = select(Article).where(Article.slug == slug)
slug_unique_part = get_slug_unique_part(slug=slug)
query = select(Article).where(
Article.slug == slug or Article.slug.contains(slug_unique_part)
)
if article := await session.scalar(query):
return self._article_mapper.to_dto(article)

Expand All @@ -67,10 +74,10 @@ async def update_by_slug(
.returning(Article)
)
if update_item.title is not None:
query = query.values(
title=update_item.title,
slug=get_slug_from_title(title=update_item.title),
updated_slug = make_slug_from_title_and_code(
title=update_item.title, code=get_slug_unique_part(slug=slug)
)
query = query.values(title=update_item.title, slug=updated_slug)
if update_item.description is not None:
query = query.values(description=update_item.description)
if update_item.body is not None:
Expand Down

0 comments on commit 2cd38f8

Please sign in to comment.