Skip to content

Commit

Permalink
Improve user stats query (#606)
Browse files Browse the repository at this point in the history
* Improve user stats query

* Update tests
  • Loading branch information
willemarcel authored May 13, 2022
1 parent 1361afb commit d33766a
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 52 deletions.
40 changes: 8 additions & 32 deletions osmchadjango/changeset/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,18 +95,18 @@ def to_representation(self, data):

reasons_list = [
{'name': reason.name,
'changesets': data.filter(reasons=reason).count(),
'checked_changesets': checked_changesets.filter(reasons=reason).count(),
'harmful_changesets': harmful_changesets.filter(reasons=reason).count(),
}
'changesets': data.filter(reasons=reason).count(),
'checked_changesets': checked_changesets.filter(reasons=reason).count(),
'harmful_changesets': harmful_changesets.filter(reasons=reason).count(),
}
for reason in reasons
]
tags_list = [
{'name': tag.name,
'changesets': data.filter(tags=tag).count(),
'checked_changesets': checked_changesets.filter(tags=tag).count(),
'harmful_changesets': harmful_changesets.filter(tags=tag).count(),
}
'changesets': data.filter(tags=tag).count(),
'checked_changesets': checked_changesets.filter(tags=tag).count(),
'harmful_changesets': harmful_changesets.filter(tags=tag).count(),
}
for tag in tags
]

Expand All @@ -131,30 +131,6 @@ class Meta:
list_serializer_class = ChangesetListStatsSerializer


class UserStatsListSerializer(ListSerializer):
read_only = True

def to_representation(self, data):
data = Changeset.objects.filter(id__in=[i.id for i in data])
checked_changesets = data.filter(checked=True)
harmful_changesets = data.filter(harmful=True)

return {
'changesets_in_osmcha': data.count(),
'checked_changesets': checked_changesets.count(),
'harmful_changesets': harmful_changesets.count()
}

@property
def data(self):
return super(ListSerializer, self).data


class UserStatsSerializer(BaseSerializer):
class Meta:
list_serializer_class = UserStatsListSerializer


# the following serializers are used only to validate input data in endpoints
# that check features/changesets or add/remove SuspicionReasons and Tags
class SuspicionReasonsChangesetSerializer(ModelSerializer):
Expand Down
14 changes: 6 additions & 8 deletions osmchadjango/changeset/tests/test_stats_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,16 +183,14 @@ def test_user_one_stats(self):
self.client.login(username=self.user.username, password='password')
response = self.client.get(reverse('changeset:user-stats', args=['4321']))
self.assertEqual(response.status_code, 200)
results = response.data.get('results')
self.assertEqual(results.get('changesets_in_osmcha'), 3)
self.assertEqual(results.get('checked_changesets'), 2)
self.assertEqual(results.get('harmful_changesets'), 1)
self.assertEqual(response.data.get('changesets_in_osmcha'), 3)
self.assertEqual(response.data.get('checked_changesets'), 2)
self.assertEqual(response.data.get('harmful_changesets'), 1)

def test_user_without_changesets(self):
self.client.login(username=self.user.username, password='password')
response = self.client.get(reverse('changeset:user-stats', args=['1611']))
self.assertEqual(response.status_code, 200)
results = response.data.get('results')
self.assertEqual(results.get('changesets_in_osmcha'), 0)
self.assertEqual(results.get('checked_changesets'), 0)
self.assertEqual(results.get('harmful_changesets'), 0)
self.assertEqual(response.data.get('changesets_in_osmcha'), 0)
self.assertEqual(response.data.get('checked_changesets'), 0)
self.assertEqual(response.data.get('harmful_changesets'), 0)
6 changes: 3 additions & 3 deletions osmchadjango/changeset/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,9 @@
view=views.ChangesetStatsAPIView.as_view(),
name='stats'
),
re_path(
r'^user-stats/(?P<uid>\w+)/$',
view=views.UserStatsAPIView.as_view(),
path(
'user-stats/<int:uid>/',
view=views.user_stats,
name='user-stats'
),
]
34 changes: 25 additions & 9 deletions osmchadjango/changeset/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from django.utils import timezone
from django.utils.translation import ugettext, ugettext_lazy as _
from django.db.utils import IntegrityError
from django.db import connection
from django.conf import settings

import django_filters.rest_framework
Expand All @@ -30,7 +31,7 @@
from .serializers import (
ChangesetSerializer, ChangesetSerializerToStaff, ChangesetStatsSerializer,
ChangesetTagsSerializer, SuspicionReasonsChangesetSerializer,
SuspicionReasonsSerializer, UserStatsSerializer, UserWhitelistSerializer,
SuspicionReasonsSerializer, UserWhitelistSerializer,
TagSerializer, ChangesetCommentSerializer, ReviewedFeatureSerializer
)
from .tasks import ChangesetCommentAPI
Expand Down Expand Up @@ -537,15 +538,29 @@ class ChangesetStatsAPIView(ListAPIView):
filter_class = ChangesetFilter


class UserStatsAPIView(ListAPIView):
"""Get stats about an OSM user in the OSMCHA history. It needs to receive
the uid of the user in OSM.
@api_view(['GET'])
@permission_classes((IsAuthenticated,))
def user_stats(request, uid):
"""Get stats about an OSM user in the OSMCHA history.
It needs to receive the uid of the user in OSM.
"""
serializer_class = UserStatsSerializer
permission_classes = (IsAuthenticated,)

def get_queryset(self):
return Changeset.objects.filter(uid=self.kwargs['uid'])
query = """
SELECT
count(*),
count(*) filter (where checked),
count(*) filter (where harmful)
FROM changeset_changeset
WHERE uid = %s
"""
with connection.cursor() as cursor:
cursor.execute(query, [str(uid)])
total, checked, harmful = cursor.fetchone()
instance = {
"changesets_in_osmcha": total,
"checked_changesets": checked,
"harmful_changesets": harmful
}
return Response(instance)


class ChangesetCommentAPIView(ModelViewSet):
Expand Down Expand Up @@ -683,6 +698,7 @@ class SetChangesetTagChangesAPIView(ModelViewSet):
@action(detail=True, methods=['post'])
def set_tag_changes(self, request, pk):
"""Update the tag_changes field of a Changeset"""
print(self.request.data)
if self.validate_tag_changes(self.request.data) is False:
return Response(
{'detail': 'Payload does not match validation rules.'},
Expand Down

0 comments on commit d33766a

Please sign in to comment.