diff --git a/news/api/urls.py b/news/api/urls.py index 7eb1b54..021f40a 100644 --- a/news/api/urls.py +++ b/news/api/urls.py @@ -14,5 +14,6 @@ path('add_reporter', views.AddReporterView.as_view()), path('search/', views.NewsSearchView.as_view()), path('suggestion/', views.NewsSuggestionView.as_view()), + path('subscription/', views.NewsSubscriptionView.as_view()), path('/', views.NewsDetailView.as_view()), ] diff --git a/news/api/views.py b/news/api/views.py index 7c2397e..9cd83af 100644 --- a/news/api/views.py +++ b/news/api/views.py @@ -23,6 +23,8 @@ add_reporter, search_for_news, create_news_suggestion, + get_user_subscriptions_service, + subscribe_news_service, ) from response.rest import ( OkResponse, @@ -88,6 +90,29 @@ def get(self, request, token): return NotFoundResponse(message=message) +class NewsSubscriptionView(APIView): + authentication_classes = [TokenAuthentication] + permission_classes = [IsAuthenticated] + + def get(self, request): + username = request.user.username + is_successful, message = get_user_subscriptions_service(username) + if is_successful: + serializer = AgencySerializer(message, many=True) + return OkResponse(subscriptions=serializer.data) + else: + return NotFoundResponse(message=message) + + def post(self, request): + username = request.user.username + agency_name = request.data.get('agency_name', None) + is_successful, message = subscribe_news_service(username, agency_name) + if is_successful: + return OkResponse(message=message) + else: + return NotFoundResponse(message=message) + + # Get news by Category title class CategoryDetailView(APIView): def get(self, request, category_name): diff --git a/news/management/commands/generate_fake_data.py b/news/management/commands/generate_fake_data.py index a18e801..791c44c 100644 --- a/news/management/commands/generate_fake_data.py +++ b/news/management/commands/generate_fake_data.py @@ -13,6 +13,7 @@ Agency, Category, News, + Subscription, ) from news.services.news import create_unique_token @@ -27,6 +28,7 @@ def generate_fake_data(): AGENCY_COUNT = int(os.getenv("AGENCY_COUNT", 10)) REPORTER_PER_AGENCY = int(os.getenv("REPORTER_PER_AGENCY", 2)) NEWS_COUNT = int(os.getenv("NEWS_COUNT", 1000)) + MAX_SUBSCRIPTION_COUNT = int(os.getenv("MAX_SUBSCRIPTION_COUNT", 3)) fake = Faker() # Create subscribers @@ -40,8 +42,10 @@ def generate_fake_data(): subscribers.append(subscriber) reporters = [] + agencies = [] for i in range(AGENCY_COUNT): agency = Agency.objects.create(name=fake.company(), description=fake.paragraph()) + agencies.append(agency) for j in range(REPORTER_PER_AGENCY): subscriber = subscribers[i * REPORTER_PER_AGENCY + j] reporter = Reporter.objects.create( @@ -52,6 +56,13 @@ def generate_fake_data(): ) reporters.append(reporter) + for subscriber in subscribers: + for i in range(MAX_SUBSCRIPTION_COUNT): + should_subscribe = True if random.randint(0, 1) == 1 else False + if should_subscribe: + agency = get_random_obj(agencies) + Subscription.objects.create(subscriber=subscriber, agency=agency) + categories = [Category.objects.create(title='Sports', description=fake.text()), Category.objects.create(title='Weather', description=fake.text()), Category.objects.create(title='Travel', description=fake.text()), diff --git a/news/models.py b/news/models.py index ad6993a..5fb4ca4 100644 --- a/news/models.py +++ b/news/models.py @@ -52,3 +52,8 @@ class News(models.Model): def __str__(self): return f'{str(self.id) + str(self.agency)} + {self.title}' + + +class Subscription(models.Model): + subscriber = models.ForeignKey(Subscriber, on_delete=models.CASCADE) + agency = models.ForeignKey(Agency, on_delete=models.CASCADE) diff --git a/news/services/news.py b/news/services/news.py index e46317d..d7b45dd 100644 --- a/news/services/news.py +++ b/news/services/news.py @@ -15,9 +15,10 @@ get_news_by_title_detail, get_news_by_description_detail, get_random_news, + get_subscriptions_by_subscriber, ) from news.utils.news_cache import NewsCache -from news.models import News, Agency, Reporter +from news.models import News, Agency, Reporter, Subscription from news.api.serializers import NewsSerializer @@ -105,6 +106,25 @@ def create_news_suggestion(token: str): return True, suggestions +def get_user_subscriptions_service(username: str): + subscriber = get_subscriber_by_username(username) + subscriptions = get_subscriptions_by_subscriber(subscriber) + agencies = [] + for sub in subscriptions: + agencies.append(sub.agency) + return True, agencies + + +def subscribe_news_service(username: str, agency_name: str): + subscriber = get_subscriber_by_username(username) + agency = get_agency_by_name(agency_name) + if agency is not None: + Subscription.objects.create(subscriber=subscriber, agency=agency) + return True, 'Subscription added successfully' + else: + return False, 'Agency not found!' + + def create_news_service(data, reporter): if 'title' not in data: return False, 'news should have title' diff --git a/news/utils/news.py b/news/utils/news.py index d084751..e226220 100644 --- a/news/utils/news.py +++ b/news/utils/news.py @@ -4,7 +4,7 @@ from django.contrib.auth import get_user_model from django.db.models import Max -from news.models import News, Category, Reporter, Agency +from news.models import News, Category, Reporter, Agency, Subscription from datetime import datetime, timedelta @@ -75,3 +75,8 @@ def get_random_obj_from_queryset(queryset, count=1): while True: objs = queryset.filter(pk__in=random_pks).all() return objs + + +def get_subscriptions_by_subscriber(subscriber): + subscriptions = Subscription.objects.filter(subscriber=subscriber) + return subscriptions