models.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. from django.db import models
  2. from django.contrib.auth.models import User
  3. from django.db.models import Count, Q
  4. from django.db.models.signals import post_save
  5. from django.dispatch import receiver
  6. from allauth.socialaccount.models import SocialToken
  7. from google.oauth2.credentials import Credentials
  8. from google.auth.transport.requests import Request
  9. from django.conf import settings
  10. class Untube(models.Model):
  11. page_likes = models.IntegerField(default=0)
  12. # extension of the built in User model made by Django
  13. class Profile(models.Model):
  14. untube_user = models.OneToOneField(User, on_delete=models.CASCADE)
  15. created_at = models.DateTimeField(auto_now_add=True)
  16. updated_at = models.DateTimeField(auto_now=True)
  17. # settings
  18. robohash_set = models.IntegerField(default=3) # determines profile picture from https://robohash.org/
  19. user_summary = models.CharField(max_length=300, default="I think my arm is on backward.")
  20. user_location = models.CharField(max_length=100, default="Hell, Earth")
  21. ### GLOBAL preferences ###
  22. # site preferences
  23. open_search_new_tab = models.BooleanField(default=True) # open search page in new tab by default
  24. enable_gradient_bg = models.BooleanField(default=False)
  25. # playlist preferences (this will apply to all playlists)
  26. hide_unavailable_videos = models.BooleanField(default=True)
  27. confirm_before_deleting = models.BooleanField(default=True)
  28. ###########################
  29. # manage user
  30. show_import_page = models.BooleanField(default=True) # shows the user tips for a week
  31. yt_channel_id = models.TextField(default='')
  32. import_in_progress = models.BooleanField(
  33. default=False) # if True, will not let the user access main site until they import their YT playlists
  34. imported_yt_playlists = models.BooleanField(default=False) # True if user imported all their YT playlists
  35. # google api token details
  36. access_token = models.TextField(default="")
  37. refresh_token = models.TextField(default="")
  38. expires_at = models.DateTimeField(blank=True, null=True)
  39. # import playlist page
  40. manage_playlists_import_textarea = models.TextField(default="")
  41. # create playlist page
  42. create_playlist_name = models.CharField(max_length=50, default="")
  43. create_playlist_desc = models.CharField(max_length=50, default="")
  44. create_playlist_type = models.CharField(max_length=50, default="")
  45. create_playlist_add_vids_from_collection = models.CharField(max_length=50, default="")
  46. create_playlist_add_vids_from_links = models.CharField(max_length=50, default="")
  47. def __str__(self):
  48. return f"{self.untube_user.username} ({self.untube_user.email})"
  49. def get_credentials(self):
  50. """
  51. Returns Google OAuth credentials object by using user's OAuth token
  52. """
  53. # if the profile model does not hold the tokens, retrieve them from user's SocialToken entry and save them into profile
  54. if self.access_token.strip() == "" or self.refresh_token.strip() == "":
  55. user_social_token = SocialToken.objects.get(account__user=self.untube_user)
  56. self.access_token = user_social_token.token
  57. self.refresh_token = user_social_token.token_secret
  58. self.expires_at = user_social_token.expires_at
  59. self.save(update_fields=['access_token', 'refresh_token', 'expires_at'])
  60. # app = SocialApp.objects.get(provider='google')
  61. credentials = Credentials(
  62. token=self.access_token,
  63. refresh_token=self.refresh_token,
  64. token_uri="https://oauth2.googleapis.com/token",
  65. client_id=settings.GOOGLE_OAUTH_CLIENT_ID, # app.client_id,
  66. client_secret=settings.GOOGLE_OAUTH_CLIENT_SECRET, # app.secret,
  67. scopes=['https://www.googleapis.com/auth/youtube']
  68. )
  69. if not credentials.valid:
  70. credentials.refresh(Request())
  71. self.access_token = credentials.token
  72. self.refresh_token = credentials.refresh_token
  73. self.save(update_fields=['access_token', 'refresh_token'])
  74. return credentials
  75. def get_channels_list(self):
  76. channels_list = []
  77. videos = self.untube_user.videos.filter(Q(is_unavailable_on_yt=False) & Q(was_deleted_on_yt=False))
  78. queryset = videos.values(
  79. 'channel_name').annotate(channel_videos_count=Count('video_id')).order_by('-channel_videos_count')
  80. for entry in queryset:
  81. channels_list.append(entry['channel_name'])
  82. return channels_list
  83. def get_playlists_list(self):
  84. return self.untube_user.playlists.all().filter(is_in_db=True)
  85. # as soon as one User object is created, create an associated profile object
  86. @receiver(post_save, sender=User)
  87. def create_user_profile(sender, instance, created, **kwargs):
  88. if created:
  89. Profile.objects.create(untube_user=instance)
  90. # whenever User.save() happens, Profile.save() also happens
  91. @receiver(post_save, sender=User)
  92. def save_user_profile(sender, instance, **kwargs):
  93. instance.profile.save()