|
1 | 1 | # Standard Library
|
2 | 2 | import logging
|
3 |
| -from typing import Optional |
4 | 3 | import re
|
| 4 | +from typing import Optional |
5 | 5 |
|
6 | 6 | # Django
|
7 | 7 | from django.contrib.auth import get_user_model
|
@@ -38,7 +38,7 @@ class Meta:
|
38 | 38 | take=graphene.Int(description="Take n items when paginating"),
|
39 | 39 | )
|
40 | 40 |
|
41 |
| - paste_count = graphene.Int(description="Total number of pastes") |
| 41 | + paste_count = graphene.Int(description="Total number of pastes for this user") |
42 | 42 |
|
43 | 43 | @gql_optimizer.resolver_hints(model_field='pastes')
|
44 | 44 | def resolve_pastes(
|
@@ -141,7 +141,9 @@ def mutate(
|
141 | 141 | raise Exception("Username contains restricted special characters")
|
142 | 142 | if not re.match("^[A-Za-z0-9._%+-]*$", password):
|
143 | 143 | raise Exception("Password contains restricted special characters")
|
144 |
| - if not re.fullmatch(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b', email): |
| 144 | + if not re.fullmatch( |
| 145 | + r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b', email |
| 146 | + ): |
145 | 147 | raise Exception("Enter a valid e-mail")
|
146 | 148 | user = get_user_model()(
|
147 | 149 | username=username,
|
@@ -178,7 +180,9 @@ def mutate(
|
178 | 180 | user = get_user_model().objects.get(pk=id)
|
179 | 181 | if not re.match("^[A-Za-z0-9._%+-]*$", username):
|
180 | 182 | raise Exception("Username contains restricted special characters")
|
181 |
| - if not re.fullmatch(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b', email): |
| 183 | + if not re.fullmatch( |
| 184 | + r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b', email |
| 185 | + ): |
182 | 186 | raise Exception("Enter a valid e-mail")
|
183 | 187 | if username is not None:
|
184 | 188 | user.username = username
|
@@ -226,7 +230,16 @@ class Meta:
|
226 | 230 | model = Paste
|
227 | 231 |
|
228 | 232 | id = graphene.Int()
|
229 |
| - paste_count = graphene.Int(description="Total number of pastes") |
| 233 | + like_count = graphene.Int(description="Number of users who like this paste") |
| 234 | + is_liked = graphene.Boolean(description="Does the current user like this paste?") |
| 235 | + |
| 236 | + def resolve_like_count(self: Paste, info: ResolveInfo) -> int: |
| 237 | + return self.likers.count() |
| 238 | + |
| 239 | + def resolve_is_liked(self: Paste, info: ResolveInfo) -> bool: |
| 240 | + if info.context.user.is_authenticated: |
| 241 | + return self.likers.filter(pk=info.context.user.pk).exists() |
| 242 | + return False |
230 | 243 |
|
231 | 244 |
|
232 | 245 | class PasteQuery(graphene.ObjectType):
|
@@ -377,10 +390,43 @@ def mutate(self, info: ResolveInfo, id: int) -> "DeletePaste":
|
377 | 390 | return DeletePaste(ok=True)
|
378 | 391 |
|
379 | 392 |
|
| 393 | +class LikePaste(graphene.Mutation): |
| 394 | + """Likes or unlikes a paste""" |
| 395 | + |
| 396 | + paste = graphene.Field(PasteType) |
| 397 | + |
| 398 | + class Arguments: |
| 399 | + id = graphene.Int(required=True) |
| 400 | + liking = graphene.Boolean(required=True) |
| 401 | + |
| 402 | + @login_required |
| 403 | + def mutate(self, info: ResolveInfo, id: int, liking: bool) -> Paste: |
| 404 | + paste: Paste = Paste.objects.get(pk=id) |
| 405 | + |
| 406 | + if paste.private and info.context.user != paste.author: |
| 407 | + raise Paste.DoesNotExist("Paste matching query does not exist") |
| 408 | + |
| 409 | + if liking: |
| 410 | + paste.likers.add(info.context.user) |
| 411 | + logging.info( |
| 412 | + f"User '{info.context.user}' liked paste '{paste}'" |
| 413 | + f"by user '{paste.author}' :)" |
| 414 | + ) |
| 415 | + else: |
| 416 | + paste.likers.remove(info.context.user) |
| 417 | + logging.info( |
| 418 | + f"User '{info.context.user}' unliked paste '{paste}'" |
| 419 | + f"by user '{paste.author}' :(" |
| 420 | + ) |
| 421 | + |
| 422 | + return LikePaste(paste=paste) |
| 423 | + |
| 424 | + |
380 | 425 | class PasteMutation(graphene.ObjectType):
|
381 | 426 | create_paste = CreatePaste.Field()
|
382 | 427 | update_paste = UpdatePaste.Field()
|
383 | 428 | delete_paste = DeletePaste.Field()
|
| 429 | + like_paste = LikePaste.Field() |
384 | 430 |
|
385 | 431 |
|
386 | 432 | class Query(UserQuery, PasteQuery, graphene.ObjectType):
|
|
0 commit comments