2 from django.conf import settings
3 from django.db import models
4 from requests_oauthlib import OAuth2Session
8 'https://www.googleapis.com/auth/youtube',
10 YOUTUBE_AUTH_URL = 'https://accounts.google.com/o/oauth2/auth'
11 YOUTUBE_TOKEN_URL = 'https://oauth2.googleapis.com/token'
14 class Course(models.Model):
15 slug = models.SlugField()
16 title = models.CharField(max_length=255)
22 class Track(models.Model):
23 course = models.ForeignKey(Course, models.CASCADE)
26 class Tag(models.Model):
27 name = models.CharField(max_length=255)
30 class Item(models.Model):
31 course = models.ForeignKey(Course, models.CASCADE)
32 title = models.CharField(max_length=255, blank=True)
33 tags = models.ManyToManyField(Tag, blank=True)
34 youtube_id = models.CharField(max_length=255, blank=True)
35 order = models.IntegerField(default=0, blank=True)
44 class YPlaylist(models.Model):
45 course = models.ForeignKey(Course, models.CASCADE)
46 youtube_id = models.CharField(max_length=255, blank=True)
52 def download(self, page_token=None):
55 'playlistId': self.youtube_id,
59 params['pageToken'] = page_token
60 response = YouTubeToken.objects.first().call(
62 "https://www.googleapis.com/youtube/v3/playlistItems",
65 data = response.json()
66 for item in data['items']:
67 self.course.item_set.update_or_create(
68 youtube_id=item['snippet']['resourceId']['videoId'],
70 'title': item['snippet']['title'],
71 'order': item['snippet']['position'],
74 if data.get('nextPageToken'):
75 self.download(page_token=data['nextPageToken'])
79 class YouTubeToken(models.Model):
80 token = models.TextField()
82 def token_updater(self, token):
83 self.token = json.dumps(token)
86 def get_session(self):
88 client_id=settings.YOUTUBE_CLIENT_ID,
89 auto_refresh_url=YOUTUBE_TOKEN_URL,
90 token=json.loads(self.token),
91 auto_refresh_kwargs={'client_id':settings.YOUTUBE_CLIENT_ID,'client_secret':settings.YOUTUBE_CLIENT_SECRET},
92 token_updater=self.token_updater
95 def call(self, method, url, params=None, json=None, data=None, resumable_file_path=None):
97 if resumable_file_path:
98 params['uploadType'] = 'resumable'
99 file_size = os.stat(resumable_file_path).st_size
101 session = self.get_session()
102 response = session.request(
109 'X-Upload-Content-Length': str(file_size),
110 'x-upload-content-type': 'application/octet-stream',
111 } if resumable_file_path else {}
113 response.raise_for_status()