-
Notifications
You must be signed in to change notification settings - Fork 1
/
import.js
144 lines (129 loc) · 3.76 KB
/
import.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
const dotenv = require('dotenv')
const { google } = require('googleapis')
const axios = require('axios')
const querystring = require('querystring')
const FormData = require('form-data')
// Configure environment variables
dotenv.config()
const {
YOUTUBE_API_KEY,
PEERTUBE_INSTANCE,
PEERTUBE_USERNAME,
PEERTUBE_PASSWORD,
PEERTUBE_CHANNEL_ID,
YOUTUBE_CHANNEL_ID
} = process.env
const youtube = google.youtube({
version: 'v3',
auth: YOUTUBE_API_KEY
})
const INSTANCE_API_URL = `${PEERTUBE_INSTANCE}/api/v1`
const APP_STATE = {
channelInfo: {},
videosList: {}
}
async function getChannelInformation (id) {
try {
const response = await youtube.channels.list({
id,
part: 'statistics,snippet,contentDetails'
})
const channelInfo = {
id: response.data.items[0].id,
name: response.data.items[0].snippet.title,
uploadsPlaylist: response.data.items[0].contentDetails.relatedPlaylists.uploads,
totalVideos: response.data.items[0].statistics.videoCount
}
APP_STATE.channelInfo = channelInfo
return channelInfo
} catch (e) {
console.error(e)
}
}
async function getVideosList (channelInfo, pageToken) {
function fetchVideos (playlistId, pageToken) {
return youtube.playlistItems.list({
playlistId,
part: 'id,snippet,contentDetails',
maxResults: 50,
pageToken: pageToken || ''
})
}
try {
let videos = []
let response = await fetchVideos(channelInfo.uploadsPlaylist, pageToken)
while (response.data.nextPageToken) {
const mappedVideosList = response.data.items.map(({ contentDetails: { videoId }, snippet: {
title,
description
} }) => ({
videoId,
title,
description,
videoUrl: `https://www.youtube.com/watch?v=${videoId}`
}))
videos = [...videos, ...mappedVideosList]
response = await fetchVideos(channelInfo.uploadsPlaylist, response.data.nextPageToken)
console.log(`Collected ${videos.length} of ${channelInfo.totalVideos}`)
}
console.log('Collected all videos!')
APP_STATE.videosList = videos
return videos
} catch (e) {
console.error(e)
}
}
async function getAccessToken () {
const { data: {
client_id: clientId,
client_secret: clientSecret
} } = await axios.get(`${INSTANCE_API_URL}/oauth-clients/local`)
const {
data: {
access_token: accessToken
}
} = await axios.post(`${INSTANCE_API_URL}/users/token`, querystring.stringify({
clientId,
clientSecret,
grant_type: 'password',
response_type: 'code',
username: PEERTUBE_USERNAME,
password: PEERTUBE_PASSWORD
}), {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
return accessToken
}
async function importVideo (index) {
const accessToken = await getAccessToken()
const videoToUpload = APP_STATE.videosList[index]
console.log(`Triggering import for video from ${videoToUpload.videoUrl}`)
const formData = new FormData()
formData.append('channelId', PEERTUBE_CHANNEL_ID)
formData.append('name', videoToUpload.title)
formData.append('description', videoToUpload.description)
formData.append('targetUrl', videoToUpload.videoUrl)
return axios.post(`${INSTANCE_API_URL}/videos/imports`, formData, {
headers: {
...formData.getHeaders(),
'Authorization': `Bearer ${accessToken}`
}
})
}
async function yt2pt (limit) {
try {
await getChannelInformation(YOUTUBE_CHANNEL_ID)
await getVideosList(APP_STATE.channelInfo)
let videosUploaded = 0
while (videosUploaded < limit) {
await importVideo(videosUploaded)
videosUploaded += 1
console.log(`uploaded ${videosUploaded} / ${APP_STATE.channelInfo.totalVideos}`)
}
} catch (e) {
console.error(JSON.stringify(e, null, 2))
}
}
yt2pt(1)