From 9efd0cb678e7d55db15272c17b996188fda4a211 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sat, 5 Dec 2020 19:19:10 +0200 Subject: Include DestroyModelMixin to infractions view for DELETE method Added this mixin and documented this in doctoring. --- pydis_site/apps/api/viewsets/bot/infraction.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'pydis_site') diff --git a/pydis_site/apps/api/viewsets/bot/infraction.py b/pydis_site/apps/api/viewsets/bot/infraction.py index edec0a1e..423e806e 100644 --- a/pydis_site/apps/api/viewsets/bot/infraction.py +++ b/pydis_site/apps/api/viewsets/bot/infraction.py @@ -5,6 +5,7 @@ from rest_framework.exceptions import ValidationError from rest_framework.filters import OrderingFilter, SearchFilter from rest_framework.mixins import ( CreateModelMixin, + DestroyModelMixin, ListModelMixin, RetrieveModelMixin ) @@ -18,7 +19,13 @@ from pydis_site.apps.api.serializers import ( ) -class InfractionViewSet(CreateModelMixin, RetrieveModelMixin, ListModelMixin, GenericViewSet): +class InfractionViewSet( + CreateModelMixin, + RetrieveModelMixin, + ListModelMixin, + GenericViewSet, + DestroyModelMixin +): """ View providing CRUD operations on infractions for Discord users. @@ -108,6 +115,13 @@ class InfractionViewSet(CreateModelMixin, RetrieveModelMixin, ListModelMixin, Ge - 400: if a field in the request body is invalid or disallowed - 404: if an infraction with the given `id` could not be found + ### DELETE /bot/infractions/ + Delete the infraction with the given `id`. + + #### Status codes + - 204: returned on success + - 404: if a infraction with the given `id` does not exist + ### Expanded routes All routes support expansion of `user` and `actor` in responses. To use an expanded route, append `/expanded` to the end of the route e.g. `GET /bot/infractions/expanded`. -- cgit v1.2.3 From f5ab88b2f063b1d2d11eb48a421b8973e5fc6562 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Wed, 9 Dec 2020 08:18:03 +0200 Subject: Add tests for infraction deletion method --- pydis_site/apps/api/tests/test_infractions.py | 30 +++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'pydis_site') diff --git a/pydis_site/apps/api/tests/test_infractions.py b/pydis_site/apps/api/tests/test_infractions.py index 93ef8171..82b497aa 100644 --- a/pydis_site/apps/api/tests/test_infractions.py +++ b/pydis_site/apps/api/tests/test_infractions.py @@ -512,6 +512,36 @@ class CreationTests(APISubdomainTestCase): ) +class InfractionDeletionTests(APISubdomainTestCase): + @classmethod + def setUpTestData(cls): + cls.user = User.objects.create( + id=9876, + name='Unknown user', + discriminator=9876, + ) + + cls.warning = Infraction.objects.create( + user_id=cls.user.id, + actor_id=cls.user.id, + type='warning', + active=False + ) + + def test_delete_unknown_infraction_returns_404(self): + url = reverse('bot:infraction-detail', args=('something',), host='api') + response = self.client.delete(url) + + self.assertEqual(response.status_code, 404) + + def test_delete_known_infraction_returns_204(self): + url = reverse('bot:infraction-detail', args=(self.warning.id,), host='api') + response = self.client.delete(url) + + self.assertEqual(response.status_code, 204) + self.assertRaises(Infraction.DoesNotExist, Infraction.objects.get, id=self.warning.id) + + class ExpandedTests(APISubdomainTestCase): @classmethod def setUpTestData(cls): -- cgit v1.2.3 From aaf733373e7f3dc59263df79a6a19cc87db4b27c Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Sun, 13 Dec 2020 18:58:19 +0100 Subject: Increase per_page to 100 for GitHub API call. Snekbox was being banished to page 2 and we were not iterating pages, so it was not appearing in the data we got from our call to /repos. This commit changes the request to use `per_page=100`, which will work at least until we have >100 repos in our organisation. --- pydis_site/apps/home/views/home.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'pydis_site') diff --git a/pydis_site/apps/home/views/home.py b/pydis_site/apps/home/views/home.py index 97253a0c..0e5d4edf 100644 --- a/pydis_site/apps/home/views/home.py +++ b/pydis_site/apps/home/views/home.py @@ -16,7 +16,7 @@ log = logging.getLogger(__name__) class HomeView(View): """The main landing page for the website.""" - github_api = "https://api.github.com/users/python-discord/repos" + github_api = "https://api.github.com/users/python-discord/repos?per_page=100" repository_cache_ttl = 3600 # Which of our GitHub repos should be displayed on the front page, and in which order? -- cgit v1.2.3 From e1008870619f92bc76ed61eb9adbc6ada795b23f Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Sat, 19 Dec 2020 03:40:25 +0000 Subject: Swap verified_at for joined_at --- pydis_site/apps/api/models/bot/metricity.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'pydis_site') diff --git a/pydis_site/apps/api/models/bot/metricity.py b/pydis_site/apps/api/models/bot/metricity.py index 29d03d8b..cae630f1 100644 --- a/pydis_site/apps/api/models/bot/metricity.py +++ b/pydis_site/apps/api/models/bot/metricity.py @@ -28,7 +28,8 @@ class Metricity: def user(self, user_id: str) -> dict: """Query a user's data.""" - columns = ["verified_at"] + # TODO: Swap this back to some sort of verified at date + columns = ["joined_at"] query = f"SELECT {','.join(columns)} FROM users WHERE id = '%s'" self.cursor.execute(query, [user_id]) values = self.cursor.fetchone() -- cgit v1.2.3 From eff717bb38e5b556751ba4f23a53cc6662baa7dd Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Sat, 19 Dec 2020 03:43:23 +0000 Subject: Update verified_at fields to joined_at fields --- postgres/init.sql | 2 +- pydis_site/apps/api/tests/test_users.py | 10 +++++----- pydis_site/apps/api/viewsets/bot/user.py | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'pydis_site') diff --git a/postgres/init.sql b/postgres/init.sql index c77fec9e..740063e7 100644 --- a/postgres/init.sql +++ b/postgres/init.sql @@ -4,7 +4,7 @@ CREATE DATABASE metricity; CREATE TABLE users ( id varchar, - verified_at timestamp, + joined_at timestamp, primary key(id) ); diff --git a/pydis_site/apps/api/tests/test_users.py b/pydis_site/apps/api/tests/test_users.py index c422f895..69bbfefc 100644 --- a/pydis_site/apps/api/tests/test_users.py +++ b/pydis_site/apps/api/tests/test_users.py @@ -407,10 +407,10 @@ class UserMetricityTests(APISubdomainTestCase): def test_get_metricity_data(self): # Given - verified_at = "foo" + joined_at = "foo" total_messages = 1 total_blocks = 1 - self.mock_metricity_user(verified_at, total_messages, total_blocks) + self.mock_metricity_user(joined_at, total_messages, total_blocks) # When url = reverse('bot:user-metricity-data', args=[0], host='api') @@ -419,7 +419,7 @@ class UserMetricityTests(APISubdomainTestCase): # Then self.assertEqual(response.status_code, 200) self.assertEqual(response.json(), { - "verified_at": verified_at, + "joined_at": joined_at, "total_messages": total_messages, "voice_banned": False, "activity_blocks": total_blocks @@ -455,12 +455,12 @@ class UserMetricityTests(APISubdomainTestCase): self.assertEqual(response.status_code, 200) self.assertEqual(response.json()["voice_banned"], case["voice_banned"]) - def mock_metricity_user(self, verified_at, total_messages, total_blocks): + def mock_metricity_user(self, joined_at, total_messages, total_blocks): patcher = patch("pydis_site.apps.api.viewsets.bot.user.Metricity") self.metricity = patcher.start() self.addCleanup(patcher.stop) self.metricity = self.metricity.return_value.__enter__.return_value - self.metricity.user.return_value = dict(verified_at=verified_at) + self.metricity.user.return_value = dict(joined_at=joined_at) self.metricity.total_messages.return_value = total_messages self.metricity.total_message_blocks.return_value = total_blocks diff --git a/pydis_site/apps/api/viewsets/bot/user.py b/pydis_site/apps/api/viewsets/bot/user.py index 79f90163..829e2694 100644 --- a/pydis_site/apps/api/viewsets/bot/user.py +++ b/pydis_site/apps/api/viewsets/bot/user.py @@ -109,7 +109,7 @@ class UserViewSet(ModelViewSet): #### Response format >>> { - ... "verified_at": "2020-10-06T21:54:23.540766", + ... "joined_at": "2020-10-06T21:54:23.540766", ... "total_messages": 2, ... "voice_banned": False, ... "activity_blocks": 1 -- cgit v1.2.3 From c6d93bc73a9d36afcb911421b4eb7e16e4b33aa4 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sun, 20 Dec 2020 15:40:35 +0200 Subject: Get Git SHA from environement instead of GitPython package --- pydis_site/constants.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'pydis_site') diff --git a/pydis_site/constants.py b/pydis_site/constants.py index 0b76694a..c7ab5db0 100644 --- a/pydis_site/constants.py +++ b/pydis_site/constants.py @@ -1,5 +1,3 @@ -import git +import os -# Git SHA -repo = git.Repo(search_parent_directories=True) -GIT_SHA = repo.head.object.hexsha +GIT_SHA = os.environ.get("GIT_SHA", "development") -- cgit v1.2.3 From ad6d901a8d2713107d8adf99a9545984106a0683 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Mon, 21 Dec 2020 16:52:55 +0200 Subject: Change pydis-site to site in Sentry SDK initialization --- pydis_site/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'pydis_site') diff --git a/pydis_site/settings.py b/pydis_site/settings.py index 449a343f..9b840406 100644 --- a/pydis_site/settings.py +++ b/pydis_site/settings.py @@ -35,7 +35,7 @@ sentry_sdk.init( dsn=env('SITE_DSN'), integrations=[DjangoIntegration()], send_default_pii=True, - release=f"pydis-site@{GIT_SHA}" + release=f"site@{GIT_SHA}" ) # Build paths inside the project like this: os.path.join(BASE_DIR, ...) -- cgit v1.2.3 From c68b0904a73b4b66ee6b5e50b806a4074b08c002 Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Tue, 22 Dec 2020 00:06:25 +0100 Subject: Make last_updated field automatically update. Previously, we were operating under a bad assumption that we would be updating the last_updated field in the RepositoryMetadata objects whenever we updated the objects with new data from the GitHub API. Upon closer inspection, this is not at all what we're doing, and some of those repository objects had not been updated in over a year! This introduces `auto_now` to the field, which will ensure that it is automatically updated whenever the object is updated. --- .../migrations/0002_auto_now_on_repository_metadata.py | 18 ++++++++++++++++++ pydis_site/apps/home/models/repository_metadata.py | 15 +++++++-------- 2 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 pydis_site/apps/home/migrations/0002_auto_now_on_repository_metadata.py (limited to 'pydis_site') diff --git a/pydis_site/apps/home/migrations/0002_auto_now_on_repository_metadata.py b/pydis_site/apps/home/migrations/0002_auto_now_on_repository_metadata.py new file mode 100644 index 00000000..7e78045b --- /dev/null +++ b/pydis_site/apps/home/migrations/0002_auto_now_on_repository_metadata.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.11 on 2020-12-21 22:57 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('home', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='repositorymetadata', + name='last_updated', + field=models.DateTimeField(auto_now=True, help_text='The date and time this data was last fetched.'), + ), + ] diff --git a/pydis_site/apps/home/models/repository_metadata.py b/pydis_site/apps/home/models/repository_metadata.py index 92d2404d..00a83cd7 100644 --- a/pydis_site/apps/home/models/repository_metadata.py +++ b/pydis_site/apps/home/models/repository_metadata.py @@ -1,32 +1,31 @@ from django.db import models -from django.utils import timezone class RepositoryMetadata(models.Model): """Information about one of our repos fetched from the GitHub API.""" last_updated = models.DateTimeField( - default=timezone.now, - help_text="The date and time this data was last fetched." + help_text="The date and time this data was last fetched.", + auto_now=True, ) repo_name = models.CharField( primary_key=True, max_length=40, - help_text="The full name of the repo, e.g. python-discord/site" + help_text="The full name of the repo, e.g. python-discord/site", ) description = models.CharField( max_length=400, - help_text="The description of the repo." + help_text="The description of the repo.", ) forks = models.IntegerField( - help_text="The number of forks of this repo" + help_text="The number of forks of this repo", ) stargazers = models.IntegerField( - help_text="The number of stargazers for this repo" + help_text="The number of stargazers for this repo", ) language = models.CharField( max_length=20, - help_text="The primary programming language used for this repo." + help_text="The primary programming language used for this repo.", ) def __str__(self): -- cgit v1.2.3