Skip to content

Commit 1c8912b

Browse files
committed
api: enahnce ports api and add stats views
1 parent 7eb8c4d commit 1c8912b

File tree

3 files changed

+56
-2
lines changed

3 files changed

+56
-2
lines changed

app/port/views.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,9 +230,11 @@ class PortAPIView(viewsets.ReadOnlyModelViewSet):
230230
queryset = Port.objects.all()
231231
lookup_field = 'name__iexact'
232232
lookup_value_regex = '[a-zA-Z0-9_.-]+'
233-
filter_backends = [filters.SearchFilter, DjangoFilterBackend]
233+
filter_backends = [filters.SearchFilter, filters.OrderingFilter, DjangoFilterBackend]
234234
search_fields = ['name', 'maintainers__github', 'variants__variant', 'categories__name']
235235
filterset_fields = ['name', 'categories', 'maintainers__github', 'variants__variant']
236+
ordering_fields = ['name', 'created_at', 'updated_at']
237+
ordering = ['-created_at'] # Default ordering by newest first
236238

237239

238240
class SearchAPIView(HaystackViewSet):

app/stats/views.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,3 +207,53 @@ def get(self, request):
207207
}
208208
)
209209
return Response(result.data)
210+
211+
212+
class PopularPortsAPIView(APIView):
213+
@method_decorator(cache_page(60 * 60)) # Cache for 1 hour
214+
def get(self, request):
215+
days = int(request.GET.get('days', 30))
216+
limit = int(request.GET.get('limit', 10))
217+
218+
# Get submissions from the last X days
219+
end_date = datetime.datetime.now(tz=datetime.timezone.utc)
220+
start_date = end_date - datetime.timedelta(days=days)
221+
222+
submissions_unique = Submission.objects.filter(
223+
timestamp__range=[start_date, end_date]
224+
).order_by('user', '-timestamp').distinct('user')
225+
226+
# Get popular ports based on installation counts
227+
popular_ports = PortInstallation.objects.filter(
228+
submission_id__in=Subquery(submissions_unique.values('id')),
229+
requested=True
230+
).exclude(
231+
port__icontains='mpstats'
232+
).values('port').annotate(
233+
total_count=Count('port'),
234+
req_count=Count(Case(When(requested=True, then=1), output_field=IntegerField()))
235+
).order_by('-total_count')[:limit]
236+
237+
return Response(list(popular_ports))
238+
239+
240+
class EnhancedStatisticsAPIView(APIView):
241+
@method_decorator(cache_page(60 * 60)) # Cache for 1 hour
242+
def get(self, request):
243+
from port.models import Port
244+
245+
# Get basic statistics
246+
current_week = datetime.datetime.today().isocalendar()[1]
247+
all_submissions = Submission.objects.all().only('id')
248+
total_unique_users = all_submissions.distinct('user').count()
249+
current_week_unique = all_submissions.filter(timestamp__week=current_week).distinct('user').count()
250+
last_week_unique = all_submissions.filter(timestamp__week=current_week - 1).distinct('user').count()
251+
total_ports = Port.objects.filter(active=True).count()
252+
253+
return Response({
254+
'current_week': current_week_unique,
255+
'last_week': last_week_unique,
256+
'total_submissions': all_submissions.count(),
257+
'total_unique_users': total_unique_users,
258+
'total_ports': total_ports,
259+
})

app/urls.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from buildhistory.urls import router as buildhistory_router
1515
from maintainer.urls import router as maintainer_router
1616
from variant.urls import router as variants_router
17-
from stats.views import PortStatisticsAPIView, PortMonthlyInstallationsAPIView, GeneralStatisticsAPIView
17+
from stats.views import PortStatisticsAPIView, PortMonthlyInstallationsAPIView, GeneralStatisticsAPIView, PopularPortsAPIView, EnhancedStatisticsAPIView
1818
from user.views import FollowedPortsAPIView
1919

2020
# Router for rest framework
@@ -40,6 +40,8 @@
4040
path('port/', include('port.urls')),
4141
re_path(r"api/v1/statistics/port/monthly", PortMonthlyInstallationsAPIView.as_view(), name='port-monthly-stats'),
4242
re_path(r"api/v1/statistics/port", PortStatisticsAPIView.as_view(), name='port-stats'),
43+
re_path(r"api/v1/statistics/popular", PopularPortsAPIView.as_view(), name='popular-ports'),
44+
re_path(r"api/v1/statistics/enhanced", EnhancedStatisticsAPIView.as_view(), name='enhanced-stats'),
4345
re_path(r"api/v1/statistics/", GeneralStatisticsAPIView.as_view(), name='general-stats'),
4446
re_path(r"api/v1/user/followed_ports", FollowedPortsAPIView.as_view(), name='followed-ports'),
4547
re_path(r"api/v1/", include(router.urls)),

0 commit comments

Comments
 (0)