diff --git a/johar/urls.py b/johar/urls.py index bc74e27..bf4eaaa 100644 --- a/johar/urls.py +++ b/johar/urls.py @@ -20,8 +20,8 @@ urlpatterns = [ path('admin/', admin.site.urls), - path('api/news/', include('news.api.urls')), path('api/news/feedback/', include('feedback.api.urls')), + path('api/news/', include('news.api.urls')), ] urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/news/api/urls.py b/news/api/urls.py index 13c8492..7eb1b54 100644 --- a/news/api/urls.py +++ b/news/api/urls.py @@ -13,5 +13,6 @@ path('create_agency', views.CreateAgencyView.as_view()), path('add_reporter', views.AddReporterView.as_view()), path('search/', views.NewsSearchView.as_view()), + path('suggestion/', views.NewsSuggestionView.as_view()), path('/', views.NewsDetailView.as_view()), ] diff --git a/news/api/views.py b/news/api/views.py index 475645e..7c2397e 100644 --- a/news/api/views.py +++ b/news/api/views.py @@ -22,6 +22,7 @@ create_agency, add_reporter, search_for_news, + create_news_suggestion, ) from response.rest import ( OkResponse, @@ -77,6 +78,16 @@ def get(self, request, keyword): return NotFoundResponse(message=message) +class NewsSuggestionView(APIView): + def get(self, request, token): + is_successful, message = create_news_suggestion(token) + if is_successful: + serializer = NewsSerializer(message, many=True) + return OkResponse(news=serializer.data) + else: + return NotFoundResponse(message=message) + + # Get news by Category title class CategoryDetailView(APIView): def get(self, request, category_name): diff --git a/news/services/news.py b/news/services/news.py index ca7f292..e46317d 100644 --- a/news/services/news.py +++ b/news/services/news.py @@ -14,6 +14,7 @@ get_category_id, get_news_by_title_detail, get_news_by_description_detail, + get_random_news, ) from news.utils.news_cache import NewsCache from news.models import News, Agency, Reporter @@ -96,6 +97,14 @@ def search_for_news(keyword): return True, all_matched_news +def create_news_suggestion(token: str): + suggestions = get_random_news(excluded_tokens=[token]) + if len(suggestions) == 0: + return False, 'No Suggestion' + else: + return True, suggestions + + 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 7bdb96b..d084751 100644 --- a/news/utils/news.py +++ b/news/utils/news.py @@ -1,8 +1,11 @@ +import os +import random + from django.contrib.auth import get_user_model +from django.db.models import Max -from news.models import News, Category, Reporter, Subscriber, Agency +from news.models import News, Category, Reporter, Agency from datetime import datetime, timedelta -from news.utils.news_cache import NewsCache def get_category_detail(category_name): @@ -56,3 +59,19 @@ def get_news_by_title_detail(keyword: str): def get_news_by_description_detail(keyword: str): return News.objects.filter(description__icontains=keyword) + + +def get_random_news(excluded_tokens=None): + if excluded_tokens is None: + excluded_tokens = [] + suggestion_count = int(os.environ.get('NEWS_SUGGESTION_COUNT', 5)) + query_set = News.objects.exclude(token__in=excluded_tokens) + return get_random_obj_from_queryset(query_set, suggestion_count) + + +def get_random_obj_from_queryset(queryset, count=1): + max_pk = queryset.aggregate(max_pk=Max("pk"))['max_pk'] + random_pks = [random.randint(1, max_pk) for _ in range(count)] + while True: + objs = queryset.filter(pk__in=random_pks).all() + return objs