Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions apps/backend/articles/admin.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
from django.contrib import admin, messages

from .models import (
Collection,
CollectionItem,
Article,
ArticleSource,
ArticleEvent,
ArticlePublication,
ArticlePublicationVersion,
ArticleSnapshot,
ArticleEvent,
ArticleSource,
Collection,
CollectionItem,
)


Expand Down
1 change: 1 addition & 0 deletions apps/backend/articles/filters.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from django_filters import rest_framework as filters

from .models import Article


Expand Down
13 changes: 10 additions & 3 deletions apps/backend/articles/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
from .articles import Article, ArticleSource, ArticlePublication, ArticlePublicationVersion, ArticleSnapshot, ArticleEvent
from .articles import (
Article,
ArticleEvent,
ArticlePublication,
ArticlePublicationVersion,
ArticleSnapshot,
ArticleSource,
)
from .collections import Collection, CollectionItem

__all__ = [
"Article",
"ArticleSource",
"ArticleEvent",
"ArticlePublication",
"ArticlePublicationVersion",
"ArticleSnapshot",
"ArticleEvent",
"ArticleSource",
"Collection",
"CollectionItem",
]
12 changes: 8 additions & 4 deletions apps/backend/articles/models/articles.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
from django.db import models
from django.contrib.auth import get_user_model
from django.conf import settings
from django.contrib.auth import get_user_model
from django.db import models
from django.utils.translation import gettext_lazy as _

from core.model_mixins import TimeStampedMixin, UUIDPrimaryKeyMixin, SoftDeleteMixin, CreatedAtMixin

from core.model_mixins import (
CreatedAtMixin,
SoftDeleteMixin,
TimeStampedMixin,
UUIDPrimaryKeyMixin,
)

User = get_user_model()

Expand Down
1 change: 1 addition & 0 deletions apps/backend/articles/permissions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from rest_framework import permissions

from core.utils.permissions import is_moderator

from .models import ArticleEvent, Collection, CollectionItem


Expand Down
12 changes: 6 additions & 6 deletions apps/backend/articles/serializers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from .articles import (
ArticleActionResponseSerializer,
ArticleEventSerializer,
ArticleSnapshotSerializer,
ImageUploadSerializer,
ArticlePublicationSerializer,
ArticlePublicationVersionSerializer,
ArticleReadSerializer,
ArticleSnapshotSerializer,
ArticleWriteSerializer,
ImageUploadSerializer,
)
from .collections import (
CollectionItemReadSerializer,
Expand All @@ -18,14 +18,14 @@
__all__ = [
"ArticleActionResponseSerializer",
"ArticleEventSerializer",
"ArticlePublicationSerializer",
"ArticlePublicationVersionSerializer",
"ArticleReadSerializer",
"ArticleSnapshotSerializer",
"ArticleWriteSerializer",
"CollectionItemReadSerializer",
"CollectionItemWriteSerializer",
"CollectionReadSerializer",
"CollectionWriteSerializer",
"ImageUploadSerializer",
"ArticlePublicationSerializer",
"ArticlePublicationVersionSerializer",
"ArticleReadSerializer",
"ArticleWriteSerializer",
]
14 changes: 6 additions & 8 deletions apps/backend/articles/serializers/articles.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,28 @@
from pathlib import Path
import io
import uuid
from pathlib import Path

from django.contrib.auth import get_user_model
from django.core.files.base import ContentFile
from django.core.files.storage import default_storage
from django.db import models
from django.utils import timezone
from drf_std_response import ServiceError
from PIL import Image
from rest_framework import serializers

from core.validators import (
FileTypeValidator, FileSizeValidator
)
from drf_std_response import ServiceError
from core.validators import FileSizeValidator, FileTypeValidator

from ..models import (
Article,
ArticleSource,
ArticleEvent,
ArticlePublication,
ArticlePublicationVersion,
ArticleSnapshot,
ArticleEvent,
ArticleSource,
)
from ..services.markdown import extract_title_from_markdown


User = get_user_model()


Expand Down
15 changes: 8 additions & 7 deletions apps/backend/articles/services/articles.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
import hashlib
import json
from datetime import timedelta

from django.db import transaction
from django.db.models import Max
from django.utils import timezone

from datetime import timedelta
import json
import hashlib
from drf_std_response import ServiceError

from articles.models import (
Article,
ArticleSource,
ArticleEvent,
ArticlePublication,
ArticlePublicationVersion,
ArticleSnapshot,
ArticleEvent,
ArticleSource,
)
from drf_std_response import ServiceError
from core.utils.alienmark import render_md_to_html
from logs.logging import get_logger
from notifications.services import notify_subscribed_author_posted

from .markdown import extract_title_from_markdown, validate_article_markdown

logger = get_logger(__name__)
Expand Down
1 change: 0 additions & 1 deletion apps/backend/articles/services/markdown.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from core.utils.markdown import extract_title_from_markdown, validate_article_markdown


__all__ = [
"extract_title_from_markdown",
"validate_article_markdown",
Expand Down
13 changes: 6 additions & 7 deletions apps/backend/articles/tasks.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
from django.conf import settings
from django.utils import timezone
from django.tasks import task

from pathlib import Path
import re
from pathlib import Path
from urllib.parse import urlparse

from articles.models import ArticleSource
from django.conf import settings
from django.tasks import task
from django.utils import timezone

from articles.models import ArticleSource

MARKDOWN_IMAGE_RE = re.compile(r"!\[[^\]]*]\(\s*(<[^>]+>|[^)\s]+)")

Expand All @@ -33,7 +32,7 @@ def normalize_src(src):
src = src[1:-1]

# absolute url -> take path part
if src.startswith("http://") or src.startswith("https://"):
if src.startswith(("http://", "https://")):
src = urlparse(src).path # "/media/xxx"

# only handle MEDIA_URL files
Expand Down
23 changes: 11 additions & 12 deletions apps/backend/articles/tests/test_models.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
from django.db import IntegrityError, transaction

from articles.models import (
Article,
ArticleEvent,
ArticlePublication,
ArticlePublicationVersion,
ArticleSnapshot,
Collection,
CollectionItem,
ArticlePublication,
ArticlePublicationVersion,
Article,
)
from articles.services.articles import ArticleWorkflow
from core.models import ContentTarget
from core.tests.factories import (
create_article,
create_article_publication,
create_collection,
create_collection_item,
create_article_publication,
create_article,
create_user,
)
from core.tests.testcases import BaseTestCase
Expand Down Expand Up @@ -134,13 +134,12 @@ def test_collection_item_rejects_duplicate_article_in_collection(self):
published = create_article_publication(article)
create_collection_item(collection, published)

with self.assertRaises(IntegrityError):
with transaction.atomic():
CollectionItem.objects.create(
collection=collection,
article_publication=published,
position=2,
)
with self.assertRaises(IntegrityError), transaction.atomic():
CollectionItem.objects.create(
collection=collection,
article_publication=published,
position=2,
)

def test_collection_delete_removes_collection_items(self):
collection = create_collection(author=self.author)
Expand Down
14 changes: 7 additions & 7 deletions apps/backend/articles/tests/test_services.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
from django.utils import timezone

from datetime import timedelta
from unittest.mock import patch

from django.utils import timezone
from drf_std_response import ServiceError

from articles.models import (
Article,
ArticleEvent,
ArticleSnapshot,
ArticlePublication,
ArticlePublicationVersion,
Article,
ArticleSnapshot,
)
from articles.services.articles import (
approve,
Expand All @@ -19,12 +20,11 @@
unpublish,
withdraw,
)
from drf_std_response import ServiceError
from core.tests.factories import (
create_article,
create_article_publication,
create_article_snapshot,
create_moderator,
create_article_publication,
create_article,
create_user,
)
from core.tests.testcases import BaseTestCase
Expand Down
24 changes: 12 additions & 12 deletions apps/backend/articles/tests/test_views.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
from django.urls import reverse
from unittest.mock import patch

from django.urls import reverse
from rest_framework import status
from unittest.mock import patch

from articles.models import (
Article,
ArticleEvent,
ArticlePublication,
ArticleSnapshot,
Collection,
CollectionItem,
)
from core.tests.factories import (
create_article,
create_article_publication,
create_article_snapshot,
create_collection,
create_collection_item,
create_moderator,
create_article_publication,
create_article,
create_user,
)
from core.tests.testcases import BaseAPITestCase
from articles.models import (
ArticleEvent,
ArticleSnapshot,
Collection,
CollectionItem,
ArticlePublication,
Article,
)


class ArticleViewTests(BaseAPITestCase):
Expand Down
7 changes: 3 additions & 4 deletions apps/backend/articles/urls.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
from rest_framework import routers

from .views import (
ArticleViewSet,
ArticleEventReadViewset,
ArticlePublicationViewSet,
ArticleSnapshotViewSet,
ArticleEventReadViewset,
CollectionViewSet,
ArticleViewSet,
CollectionItemViewSet,
CollectionViewSet,
)


router = routers.SimpleRouter()

router.register(r'articles', ArticleViewSet, basename='article')
Expand Down
6 changes: 3 additions & 3 deletions apps/backend/articles/views/__init__.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
from .articles import (
ArticleEventReadViewset,
ArticleSnapshotViewSet,
ArticlePublicationViewSet,
ArticleSnapshotViewSet,
ArticleViewSet,
)
from .collections import CollectionItemViewSet, CollectionViewSet

__all__ = [
"ArticleEventReadViewset",
"ArticlePublicationViewSet",
"ArticleSnapshotViewSet",
"ArticleViewSet",
"CollectionItemViewSet",
"CollectionViewSet",
"ArticlePublicationViewSet",
"ArticleViewSet",
]
Loading