sleepytaco 3 anni fa
parent
commit
c39b229a12

+ 4 - 1
UnTube/secrets.py

@@ -1,2 +1,5 @@
 SECRETS = {"SECRET_KEY": 'django-insecure-ycs22y+20sq67y(6dm6ynqw=dlhg!)%vuqpd@$p6rf3!#1h$u=',
-           "YOUTUBE_V3_API_KEY": 'AIzaSyCBOucAIJ5PdLeqzTfkTQ_6twsjNaMecS8'}
+           "YOUTUBE_V3_API_KEY": 'AIzaSyCBOucAIJ5PdLeqzTfkTQ_6twsjNaMecS8',
+           "GOOGLE_OAUTH_CLIENT_ID": "901333803283-1lscbdmukcjj3qp0t3relmla63h6l9k6.apps.googleusercontent.com",
+           "GOOGLE_OAUTH_CLIENT_SECRET": "ekdBniL-_mAnNPwCmugfIL2q",
+           "GOOGLE_OAUTH_SCOPES": ['https://www.googleapis.com/auth/youtube']}

+ 31 - 89
apps/main/models.py

@@ -9,14 +9,15 @@ from apps.users.models import Profile
 import re
 from datetime import timedelta
 from googleapiclient.discovery import build
-from UnTube import settings
+from UnTube.secrets import SECRETS
 
 import pytz
 
-
 # Create your models here.
 
 input = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
+
+
 def getVideoIdsStrings(video_ids):
     output = []
 
@@ -66,23 +67,15 @@ def getThumbnailURL(thumbnails):
 
 class PlaylistManager(models.Manager):
 
-    def getPlaylistId(self, video_link):
-        temp = video_link.split("?")[-1].split("&")
-
-        for el in temp:
-            if "list=" in el:
-                return el.split("list=")[-1]
-
-    # Returns True if the video count for a playlist on UnTube and video count on same playlist on YouTube is different
-    def checkIfPlaylistChangedOnYT(self, user, pl_id):
+    def getCredentials(self, user):
         credentials = Credentials(
             user.profile.access_token,
             refresh_token=user.profile.refresh_token,
             # id_token=session.token.get("id_token"),
             token_uri="https://oauth2.googleapis.com/token",
-            client_id="901333803283-1lscbdmukcjj3qp0t3relmla63h6l9k6.apps.googleusercontent.com",
-            client_secret="ekdBniL-_mAnNPwCmugfIL2q",
-            scopes=['https://www.googleapis.com/auth/youtube']
+            client_id=SECRETS["GOOGLE_OAUTH_CLIENT_ID"],
+            client_secret=SECRETS["GOOGLE_OAUTH_CLIENT_SECRET"],
+            scopes=SECRETS["GOOGLE_OAUTH_SCOPES"]
         )
 
         credentials.expiry = user.profile.expires_at.replace(tzinfo=None)
@@ -95,6 +88,20 @@ class PlaylistManager(models.Manager):
             user.profile.refresh_token = credentials.refresh_token
             user.save()
 
+        return credentials
+
+    def getPlaylistId(self, video_link):
+        temp = video_link.split("?")[-1].split("&")
+
+        for el in temp:
+            if "list=" in el:
+                return el.split("list=")[-1]
+
+    # Returns True if the video count for a playlist on UnTube and video count on same playlist on YouTube is different
+    def checkIfPlaylistChangedOnYT(self, user, pl_id):
+
+        credentials = self.getCredentials(user)
+
         with build('youtube', 'v3', credentials=credentials) as youtube:
             pl_request = youtube.playlists().list(
                 part='contentDetails, snippet, id, status',
@@ -137,27 +144,14 @@ class PlaylistManager(models.Manager):
 
                 # check if playlist count changed on youtube
                 if playlist.video_count != item['contentDetails']['itemCount']:
-                    playlist.has_playlist_changed = True
-                    playlist.save()
+                    return [-1, item['contentDetails']['itemCount']]
+
+        return [0, "no change"]
 
     # Used to check if the user has a vaild YouTube channel
     # Will return -1 if user does not have a YouTube channel
     def getUserYTChannelID(self, user):
-        credentials = Credentials(
-            user.profile.access_token,
-            refresh_token=user.profile.refresh_token,
-            # id_token=session.token.get("id_token"),
-            token_uri="https://oauth2.googleapis.com/token",
-            client_id="901333803283-1lscbdmukcjj3qp0t3relmla63h6l9k6.apps.googleusercontent.com",
-            client_secret="ekdBniL-_mAnNPwCmugfIL2q",
-            scopes=['https://www.googleapis.com/auth/youtube']
-        )
-
-        credentials.expiry = user.profile.expires_at.replace(tzinfo=None)
-
-        if not credentials.valid:
-            # if credentials and credentials.expired and credentials.refresh_token:
-            credentials.refresh(Request())
+        credentials = self.getCredentials(user)
 
         with build('youtube', 'v3', credentials=credentials) as youtube:
             pl_request = youtube.channels().list(
@@ -182,25 +176,7 @@ class PlaylistManager(models.Manager):
 
         current_user = user.profile
 
-        credentials = Credentials(
-            user.profile.access_token,
-            refresh_token=user.profile.refresh_token,
-            # id_token=session.token.get("id_token"),
-            token_uri="https://oauth2.googleapis.com/token",
-            client_id="901333803283-1lscbdmukcjj3qp0t3relmla63h6l9k6.apps.googleusercontent.com",
-            client_secret="ekdBniL-_mAnNPwCmugfIL2q",
-            scopes=['https://www.googleapis.com/auth/youtube']
-        )
-
-        credentials.expiry = user.profile.expires_at.replace(tzinfo=None)
-
-        if not credentials.valid:
-            # if credentials and credentials.expired and credentials.refresh_token:
-            credentials.refresh(Request())
-            user.profile.expires_at = credentials.expiry
-            user.profile.access_token = credentials.token
-            user.profile.refresh_token = credentials.refresh_token
-            user.save()
+        credentials = self.getCredentials(user)
 
         with build('youtube', 'v3', credentials=credentials) as youtube:
             if pl_id is not None:
@@ -457,25 +433,7 @@ class PlaylistManager(models.Manager):
 
         current_user = user.profile
 
-        credentials = Credentials(
-            user.profile.access_token,
-            refresh_token=user.profile.refresh_token,
-            # id_token=session.token.get("id_token"),
-            token_uri="https://oauth2.googleapis.com/token",
-            client_id="901333803283-1lscbdmukcjj3qp0t3relmla63h6l9k6.apps.googleusercontent.com",
-            client_secret="ekdBniL-_mAnNPwCmugfIL2q",
-            scopes=['https://www.googleapis.com/auth/youtube']
-        )
-
-        credentials.expiry = user.profile.expires_at.replace(tzinfo=None)
-
-        if not credentials.valid:
-            # if credentials and credentials.expired and credentials.refresh_token:
-            credentials.refresh(Request())
-            user.profile.expires_at = credentials.expiry
-            user.profile.access_token = credentials.token
-            user.profile.refresh_token = credentials.refresh_token
-            user.save()
+        credentials = self.getCredentials(user)
 
         with build('youtube', 'v3', credentials=credentials) as youtube:
             pl_request = youtube.playlists().list(
@@ -555,25 +513,7 @@ class PlaylistManager(models.Manager):
 
         current_user = user.profile
 
-        credentials = Credentials(
-            user.profile.access_token,
-            refresh_token=user.profile.refresh_token,
-            # id_token=session.token.get("id_token"),
-            token_uri="https://oauth2.googleapis.com/token",
-            client_id="901333803283-1lscbdmukcjj3qp0t3relmla63h6l9k6.apps.googleusercontent.com",
-            client_secret="ekdBniL-_mAnNPwCmugfIL2q",
-            scopes=['https://www.googleapis.com/auth/youtube']
-        )
-
-        credentials.expiry = user.profile.expires_at.replace(tzinfo=None)
-
-        if not credentials.valid:
-            # if credentials and credentials.expired and credentials.refresh_token:
-            credentials.refresh(Request())
-            user.profile.expires_at = credentials.expiry
-            user.profile.access_token = credentials.token
-            user.profile.refresh_token = credentials.refresh_token
-            user.save()
+        credentials = self.getCredentials(user)
 
         playlist = current_user.playlists.get(playlist_id__exact=playlist_id)
 
@@ -766,11 +706,13 @@ class Playlist(models.Model):
                                  max_length=100)  # can be set to "none", "watching", "on-hold", "plan-to-watch"
     is_favorite = models.BooleanField(default=False, blank=True)  # to mark playlist as fav
     num_of_accesses = models.IntegerField(default="0")  # tracks num of times this playlist was opened by user
-    has_playlist_changed = models.BooleanField(default=False)  # determines whether playlist was modified online or not
     is_private_on_yt = models.BooleanField(default=False)
     is_user_owned = models.BooleanField(default=True)  # represents YouTube playlist owned by user
     has_duplicate_videos = models.BooleanField(default=False)  # duplicate videos will not be shown on site
 
+    has_playlist_changed = models.BooleanField(default=False)  # determines whether playlist was modified online or not
+    playlist_changed_text = models.CharField(max_length=420, default="")  # user friendly text to display what changed and how much changed
+
     # for UI
     view_in_grid_mode = models.BooleanField(default=False)  # if False, videso will be showed in a list
 

+ 7 - 4
apps/main/templates/intercooler/manage_playlists_import.html

@@ -18,12 +18,15 @@
         -->
     </div>
       <br>
-      <button type="button" hx-post="{% url 'manage_import_playlists' %}" hx-include="[id='import-playlists-from']" hx-target="#import-playlists-results" hx-indicator="#spinner" class="btn btn-success">Import!</button>
+      <div class="d-flex justify-content-start">
+          <button type="button" hx-post="{% url 'manage_import_playlists' %}" hx-include="[id='import-playlists-from']" hx-target="#import-playlists-results" hx-indicator="#spinner" class="btn btn-success">Import!</button>
 
-        <div id="spinner" class="htmx-indicator">
-            <div class="spinner-border text-light" role="status">
+            <div id="spinner" class="htmx-indicator ms-3 mt-2">
+                <div class="spinner-border text-light" role="status">
+                </div>
             </div>
-        </div>
+      </div>
+      <br>
     <div id="import-playlists-results">
 
     </div>

+ 6 - 2
apps/main/templates/intercooler/search_untube.html

@@ -4,7 +4,7 @@
        name="search" placeholder="Search UnTube"
                    value="{{ search_query }}"
        hx-post="{% url 'search_UnTube' %}"
-       hx-trigger="keyup changed delay:200ms"
+       hx-trigger="keyup changed delay:1s"
        hx-target="#untube-searchbar-results"
                    hx-include="[id='searchbar-radio-form']"
        hx-indicator=".htmx-indicator" autofocus onfocus="this.setSelectionRange(this.value.length,this.value.length);">
@@ -87,7 +87,11 @@
                                 <h5 class="card-title text-light">
                                     {{ video.name }}<br>
 
-                                    <small><span class="badge bg-dark text-white-50">{{ video.duration }}</span></small>
+                                    <small>
+                                        <a class="badge bg-white text-black-50" href="{% url 'playlist' video.playlist.playlist_id %}">{{ video.playlist.name }}</a>
+
+                                        <span class="badge bg-dark text-white-50">{{ video.duration }}</span>
+                                    </small>
                                     {% if video.is_unavailable_on_yt %}<small><span class="badge bg-light text-dark">Private</span></small> {% endif %}
                                     {% if video.has_cc %}<small><span class="badge bg-danger text-dark">CC</span></small> {% endif %}
                                 </h5>

+ 2 - 2
apps/main/templates/manage_playlists.html

@@ -10,7 +10,7 @@
         <div class="card" style="background-color: #25641a;">
             <div class="card-body">
                 <h4 class="card-title">Import Playlists</h4>
-                    <p class="card-text">Add public playlists to your own collection.</p>
+                    <p class="card-text">Add public playlists to your own collection. Unfortunately, the YouTube API doesn't let us retrieve your liked videos and watch later playlists :(</p>
             </div>
         </div>
         </a>
@@ -20,7 +20,7 @@
         <div class="card" style="background-color: #64631a;">
             <div class="card-body">
                 <h4 class="card-title">Create a New Playlist</h4>
-                    <p class="card-text">Make a new playlist and export it to YouTube.</p>
+                    <p class="card-text">Make a new playlist using the videos in your collection and export it to YouTube!</p>
             </div>
         </div>
         </a>

+ 12 - 1
apps/main/templates/playlists_home.html

@@ -64,12 +64,23 @@
         </div>
         </a>
     </div>
+    <div class="col">
+        <a href="#" class="text-decoration-none text-white">
+        <div class="card h-100" style="background-color: #bd39a7;">
+            <div class="card-body">
+                <h5 class="card-title">Your YouTube Mixes</h5>
+                <p class="card-text">YouTube creates nice mixes that relate to songs you're currently jamming to. You can import those YT Mixes by going over to manage playlists. Any mixes you import will all be here.</p>
+            </div>
+        </div>
+        </a>
+    </div>
+
     <div class="col">
         <a href="#" class="text-decoration-none text-white">
         <div class="card h-100" style="background-color: #969291;">
             <div class="card-body">
                 <h5 class="card-title">Your UnTube Playlists</h5>
-                <p class="card-text"><!--UnTube playlists are playlists can contain YouTube videos and YouTube playlists which can then be shared with other users via a link.--> Coming soon. Maybe.</p>
+                <p class="card-text">UnTube playlists are playlists can contain YouTube videos and YouTube playlists which can then be shared with other users via a link. Coming soon. Maybe.</p>
             </div>
         </div>
         </a>

+ 2 - 3
apps/main/templates/view_playlist.html

@@ -5,10 +5,9 @@
 {% block content %}
 
     {% if playlist.has_playlist_changed %}
-    <br>
     <div class="alert alert-success alert-dismissible fade show" role="alert">
-        Looks like this playlist changed on YouTube! <a href="#" class="link-success">Update!</a>
-        <a href="#" class="link-primary">Why tf aren't you doing this automatically?</a>
+        {{ playlist.playlist_changed_text }} <a href="#" class="link-success">Update!</a>
+        <a href="#" class="link-primary">Why aren't you doing this automatically?</a>
 
         <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
     </div>

+ 20 - 1
apps/main/views.py

@@ -100,7 +100,26 @@ def view_playlist(request, playlist_id):
     videos = playlist.videos.all()
 
     if not playlist.has_playlist_changed:
-        Playlist.objects.checkIfPlaylistChangedOnYT(request.user, playlist_id)
+        print("Checking if playlist changed...")
+        result = Playlist.objects.checkIfPlaylistChangedOnYT(request.user, playlist_id)
+
+        if result[0] == -1:  # playlist changed
+            print("!!!Playlist changed")
+
+            current_playlist_vid_count = playlist.video_count
+            new_playlist_vid_count = result[1]
+
+            print(current_playlist_vid_count)
+            print(new_playlist_vid_count)
+
+            if current_playlist_vid_count > new_playlist_vid_count:
+                playlist.playlist_changed_text = f"Looks like {current_playlist_vid_count - new_playlist_vid_count} video(s) were deleted from this playlist on YouTube!"
+            else:
+                playlist.playlist_changed_text = f"Looks like {new_playlist_vid_count - current_playlist_vid_count} video(s) were added to this playlist on YouTube!"
+
+            playlist.has_playlist_changed = True
+            playlist.save()
+            print(playlist.playlist_changed_text)
 
     return render(request, 'view_playlist.html', {"playlist": playlist,
                                                   "videos": videos,

+ 4 - 0
templates/base.html

@@ -206,6 +206,10 @@
                   </div>
                   </div>
                 </div>
+                <div id="spinner" class="htmx-indicator d-flex justify-content-center">
+                <div class="spinner-border text-light" role="status">
+                </div>
+                </div>
               </div>
 
             </div>