Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add subscription #17

Merged
merged 2 commits into from
Feb 2, 2024
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
1 change: 1 addition & 0 deletions news/api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@
path('add_reporter', views.AddReporterView.as_view()),
path('search/<str:keyword>', views.NewsSearchView.as_view()),
path('suggestion/<str:token>', views.NewsSuggestionView.as_view()),
path('subscription/', views.NewsSubscriptionView.as_view()),
path('<str:token>/', views.NewsDetailView.as_view()),
]
25 changes: 25 additions & 0 deletions news/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
add_reporter,
search_for_news,
create_news_suggestion,
get_user_subscriptions_service,
subscribe_news_service,
)
from response.rest import (
OkResponse,
Expand Down Expand Up @@ -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):
Expand Down
11 changes: 11 additions & 0 deletions news/management/commands/generate_fake_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
Agency,
Category,
News,
Subscription,
)
from news.services.news import create_unique_token

Expand All @@ -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
Expand All @@ -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(
Expand All @@ -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()),
Expand Down
5 changes: 5 additions & 0 deletions news/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
22 changes: 21 additions & 1 deletion news/services/news.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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'
Expand Down
7 changes: 6 additions & 1 deletion news/utils/news.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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