import re
import isodate

from apiclient.discovery import build as youtube_api

from django.conf import settings


URL_REGEX = "(?:v=|youtu\.be\/)([^&?]+)"

youtube = youtube_api(
    "youtube",
    "v3",
    developerKey=settings.YOUTUBE_KEY
)


def get_time_in_seconds(time):
    return isodate.parse_duration(time).total_seconds()


def get_info(ids):
    if not isinstance(ids, str):
        ids = ','.join(ids)
    details = youtube.videos().list(
        id=ids,
        part='snippet, contentDetails, statistics'
    ).execute()

    videos = []
    for detail in details.get("items", []):
        added = True
        if "regionRestriction" in detail["contentDetails"]:
            if "blocked" in detail["contentDetails"]["regionRestriction"]:
                if settings.YOUTUBE_LANGUAGE in detail["contentDetails"]["regionRestriction"]["blocked"]:
                    added = False
            if "allowed" in detail["contentDetails"]["regionRestriction"]:
                if len(detail["contentDetails"]["regionRestriction"]["allowed"]) == 0:
                    added = False
                else:
                    if settings.YOUTUBE_LANGUAGE not in detail["contentDetails"]["regionRestriction"]["allowed"]:
                        added = False

        if added:
            detailedVideo = {
                'music_id': detail["id"],
                'name': detail["snippet"]["title"],
                'channel_name': detail["snippet"]["channelTitle"],
                'description': detail["snippet"]["description"][:200] + "...",
                'thumbnail': detail["snippet"]["thumbnails"]["default"]["url"],
                'views': detail["statistics"]["viewCount"],
                'total_duration': get_time_in_seconds(detail["contentDetails"]["duration"]),
                'duration': get_time_in_seconds(detail["contentDetails"]["duration"])
            }
            videos.append(detailedVideo)

    return videos


def search(query):
    ids = []

    regexVideoId = re.compile(URL_REGEX, re.IGNORECASE | re.MULTILINE)
    if regexVideoId.search(query) is None:
        # The query is not an url
        search_response = youtube.search().list(
            q=query,
            part="id",
            type="video",
            maxResults=15,
            videoSyndicated="true",
            videoEmbeddable="true",
            regionCode="FR",
            relevanceLanguage="fr"
        ).execute()
        for video in search_response.get("items", []):
            ids.append(video["id"]["videoId"])
    else:
        # Get the id from url
        ids.append(regexVideoId.search(query).group(1))

    videos = []
    for video in get_info(ids):
        music = {
            "music_id": video['music_id'],
            "name": video['name'],
            "channel_name": video['channel_name'],
            "description": video['description'],
            "thumbnail": video['thumbnail'],
            "views": video['views'],
            "total_duration": video['total_duration'],
            "duration": video['duration'],
            "url": "https://www.youtube.com/watch?v=" + video['music_id'],
            "source": "youtube"
        }
        videos.append(music)

    return videos


def check_validity(id):
    detail = youtube.videos().list(
        id=id,
        part='contentDetails,status'
    ).execute()

    # General validity
    validity = True

    # Check if the video exist
    if detail["pageInfo"]["totalResults"] > 0:
        # Check if the music have a Country restriction
        country_validity = True
        if "regionRestriction" in detail["items"][0]["contentDetails"]:
            if "blocked" in detail["items"][0]["contentDetails"]["regionRestriction"]:
                if settings.YOUTUBE_LANGUAGE in detail["items"][0]["contentDetails"]["regionRestriction"]["blocked"]:
                    country_validity = False
            if "allowed" in detail["items"][0]["contentDetails"]["regionRestriction"]:
                if len(detail["items"][0]["contentDetails"]["regionRestriction"]["allowed"]) == 0:
                    country_validity = False
                else:
                    if settings.YOUTUBE_LANGUAGE not in detail["items"][0]["contentDetails"]["regionRestriction"]["allowed"]:
                        country_validity = False

        # Check if the music have an embeddable restriction
        embeddable_validity = True
        if not detail["items"][0]["status"]["embeddable"]:
            embeddable_validity = False

        if not country_validity or not embeddable_validity:
            validity = False
    else:
        validity = False

    return validity

@@ -344,24 +344,40 @@
 _info(ids):%0A
+    videos = %5B%5D%0A
     if not i
@@ -425,16 +425,37 @@
 in(ids)%0A
+        try:%0A        
     deta
@@ -475,32 +475,40 @@
 .videos().list(%0A
+        
         id=ids,%0A
@@ -511,24 +511,32 @@
 ds,%0A        
+      
+  
 part='snippe
@@ -566,16 +566,24 @@
 istics'%0A
+        
     ).ex
@@ -590,32 +590,94 @@
 ecute()%0A
-%0A
    
+     except Exception as e:%0A            print(e)%0A            return
  videos
- = %5B%5D
+%0A
 %0A    for
@@ -2240,24 +2240,41 @@
  not an url%0A
+        try:%0A    
         sear
@@ -2322,16 +2322,20 @@
         
+    
 q=query,
@@ -2335,16 +2335,20 @@
 =query,%0A
+    
         
@@ -2362,16 +2362,20 @@
 t=%22id%22,%0A
+    
         
@@ -2404,16 +2404,20 @@
         
+    
 maxResul
@@ -2431,24 +2431,28 @@
             
+   
+ 
 videoSyndica
@@ -2455,32 +2455,36 @@
 dicated=%22true%22,%0A
+    
             vide
@@ -2515,16 +2515,20 @@
         
+  
+  
 regionCo
@@ -2536,16 +2536,20 @@
 e=%22FR%22,%0A
+    
         
@@ -2575,32 +2575,36 @@
 ge=%22fr%22%0A        
+    
 ).execute()%0A    
@@ -2591,32 +2591,36 @@
     ).execute()%0A
+    
         for vide
@@ -2662,32 +2662,36 @@
 %5D):%0A            
+    
 ids.append(video
@@ -2705,24 +2705,76 @@
 %22videoId%22%5D)%0A
+        except Exception as e:%0A            print(e)%0A
     else:%0A  
@@ -3473,16 +3473,29 @@
 ty(id):%0A
+    try:%0A    
     deta
@@ -3526,24 +3526,28 @@
 st(%0A        
+    
 id=id,%0A     
@@ -3545,24 +3545,28 @@
 id,%0A        
+ 
+   
 part='conten
@@ -3582,24 +3582,28 @@
 status'%0A    
+   
+ 
 ).execute()%0A
@@ -3602,16 +3602,84 @@
 ecute()%0A
+    except Exception as e:%0A        print(e)%0A        return True%0A    
 %0A    # G

Add some catching on googleApi calls