Skip to content

Commit 4fd5a81

Browse files
committed
More error handling, separated report messages, started migrating relevant functions, slightly rewrote main archive iteration loop again, small value adjustments
1 parent e50f9d2 commit 4fd5a81

File tree

2 files changed

+168
-105
lines changed

2 files changed

+168
-105
lines changed

cytube_auto.js

Lines changed: 166 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
11
const puppeteer = require('puppeteer-extra')
22
const StealthPlugin = require('puppeteer-extra-plugin-stealth')
33

4-
const { csv_map: index, blacklisted_creator, get_row_video_ids, check_includes, get_archive_csv, log, logErr, delay, getInput } = require('./utils.js')
4+
const { csv_map: index, blacklisted_creator, get_row_video_ids, get_archive_csv, log, logErr, delay, getInput } = require('./utils.js')
55

66
puppeteer.use(StealthPlugin())
77

8-
function update_playlist(use_cookie, headless, queue_delay, playlist_url, check_blacklisted) {
8+
let
9+
has_edit_pemissions = true,
10+
ask_before_adding = false
11+
12+
function update_playlist(use_cookie, headless, queue_delay, playlist_url, check_blacklisted, add_if_missing, report_contradictory) {
13+
if (add_if_missing === 0)
14+
has_edit_pemissions = false
15+
else if (add_if_missing === 1)
16+
ask_before_adding = true
17+
918
puppeteer.launch({ headless: headless}).then(async browser => {
1019
const page = await browser.newPage()
1120
if (use_cookie)
1221
await login_with_cookie(page, playlist_url)
1322
else
1423
await normal_login(page, playlist_url)
15-
16-
// Give the page a bit to load the playlist with all the videos
17-
await delay(3000)
18-
19-
let can_add = true
24+
2025
try {
2126
// This is the + button which is needed to reveal the playlist adding video options
2227
await page.click('#showmediaurl')
@@ -25,36 +30,50 @@ function update_playlist(use_cookie, headless, queue_delay, playlist_url, check_
2530
await page.waitForSelector("#addfromurl .checkbox .add-temp").then(button => button.click());
2631
} catch {
2732
await logErr("Can't add videos to this playlist")
28-
can_add = false
33+
has_edit_pemissions = false
2934
}
3035

3136
// return a 2d array of all video identifiers currently in the playlist
32-
let playlistSnapshot = await page.evaluate(() => {
33-
const elements = Array.from(document.getElementsByClassName('qe_title'));
34-
let id, ids_links = {}
35-
elements.shift()
37+
let playlistSnapshot
38+
39+
do {
40+
// Give the page a bit to load the playlist with all the videos
41+
await delay(2000)
42+
43+
playlistSnapshot = await page.evaluate(() => {
44+
const elements = Array.from(document.getElementsByClassName('qe_title'));
45+
let id, ids_links = {}
46+
elements.shift()
3647

37-
// can't use vid_identifier() here since this runs in the page context
48+
// can't use vid_identifier() here since this runs in the page context
3849

39-
for (var e of elements) {
40-
id = e.href.split('/')
50+
for (var e of elements) {
51+
id = e.href.split('/')
4152

42-
if (!id.at(-1)) {
43-
id = id.at(-2) + "/"
44-
}
53+
if (!id.at(-1)) {
54+
id = id.at(-2) + "/"
55+
}
4556

46-
id = id.at(-1)
47-
ids_links[id] = e.href
48-
}
49-
50-
return ids_links
51-
})
57+
id = id.at(-1)
58+
ids_links[id] = e.href
59+
}
60+
61+
return ids_links
62+
})
63+
} while (!Object.keys(playlistSnapshot).length)
5264

53-
let row_is_blacklisted
54-
let csv_row = 1, add_vid_attempts = 0
55-
let row_video_ids
56-
let includes
57-
const blacklist_included = []
65+
let
66+
row_is_blacklisted,
67+
csv_row = 1,
68+
add_vid_attempts = 0,
69+
row_video_ids,
70+
included,
71+
should_queue = true,
72+
is_contradictory = false
73+
74+
const
75+
blacklist_included = [],
76+
contradictory_included = []
5877

5978
const archive_data = await get_archive_csv('https://docs.google.com/spreadsheets/d/1rEofPkliKppvttd8pEX8H6DtSljlfmQLdFR-SlyyX7E/export?format=csv')
6079

@@ -64,81 +83,91 @@ function update_playlist(use_cookie, headless, queue_delay, playlist_url, check_
6483
++csv_row
6584
row_is_blacklisted = check_blacklisted && blacklisted_creator(archive_row)
6685
row_video_ids = await get_row_video_ids(archive_row)
86+
included = check_includes(playlistSnapshot, row_video_ids)
6787

6888
if (row_is_blacklisted) {
69-
var present_url
70-
71-
for (const id of row_video_ids) {
72-
includes = check_includes(playlistSnapshot, id)
73-
74-
if (includes.in_snapshot) {
75-
present_url = playlistSnapshot[includes.id]
76-
delete playlistSnapshot[includes.id]
77-
break
78-
}
79-
}
80-
81-
if (present_url) {
89+
if (included.video_id) {
8290
await logErr(`${csv_row}: blacklisted video found in playlist - ${archive_row[index.TITLE]}`)
83-
blacklist_included.push(`${archive_row[index.TITLE]} - ${present_url}`)
91+
blacklist_included.push(`${archive_row[index.TITLE]} - ${playlistSnapshot[included.video_id]}`)
92+
delete playlistSnapshot[included.video_id]
8493
continue
8594
}
8695

8796
log(`${csv_row}: skipping blacklisted video`)
8897
continue
8998
}
9099

91-
if (archive_row[index.NOTES].includes("age restriction bypass") || archive_row[index.NOTES].includes("bypass age restriction")) {
92-
includes = check_includes(playlistSnapshot, row_video_ids[2])
100+
if (included.video_id) {
101+
switch (included.archive_index) {
102+
case index.LINK:
103+
if (!archive_row[index.STATE])
104+
log(`${csv_row}: present`)
105+
else
106+
is_contradictory = true
107+
break
93108

94-
if (includes.in_snapshot) {
95-
delete playlistSnapshot[includes.id]
96-
log(`${csv_row}: age-restriction bypassing link present`)
97-
continue
109+
case index.ALT_LINK:
110+
if (archive_row[index.FOUND] !== "needed")
111+
log(`${csv_row}: alt present`)
112+
else
113+
is_contradictory = true
114+
break
115+
116+
default:
117+
log(`${csv_row}: age-restriction bypassing link present`)
98118
}
99119

100-
log(`${csv_row}: not present - Title: ${archive_row[index.TITLE]}`)
101-
if (can_add) {
120+
if (is_contradictory && report_contradictory) {
121+
contradictory_included.push(
122+
`${playlistSnapshot[included.video_id]} - ${archive_row[index.TITLE]}`
123+
)
124+
125+
is_contradictory = false
126+
}
127+
128+
delete playlistSnapshot[included.video_id]
129+
continue
130+
}
131+
132+
// Add the first available url
133+
134+
if (archive_row[index.NOTES].includes("age restriction")) {
135+
log(`${csv_row}: not present - ${archive_row[index.TITLE]}`)
136+
137+
if (should_queue = can_add()) {
102138
log("adding using age-restriction bypassing link...\n")
103139
await page.type('#mediaurl', archive_row[index.NOTES].split(" ").at(-1))
104140
}
105141
}
142+
else if (!archive_row[index.STATE]) {
143+
log(`${csv_row}: not present - ${archive_row[index.TITLE]}`)
106144

107-
else if (archive_row[index.FOUND] === "found") {
108-
includes = check_includes(playlistSnapshot, row_video_ids[1])
109-
110-
if (includes.in_snapshot) {
111-
log(`${csv_row}: alt present`)
112-
delete playlistSnapshot[includes.id]
113-
continue
145+
if (should_queue = can_add()) {
146+
log("adding...\n")
147+
await page.type('#mediaurl', archive_row[index.LINK])
114148
}
149+
}
150+
else if (archive_row[index.FOUND] === "found") {
151+
log(`${csv_row}: not present - ${archive_row[index.TITLE]}`)
115152

116-
log(`${csv_row}: not present - Title: ${archive_row[index.TITLE]}`)
117-
if (can_add) {
153+
if (should_queue = can_add()) {
118154
log("adding using alt link...\n")
119155
await page.type('#mediaurl', archive_row[index.ALT_LINK])
120156
}
121157
}
122-
123-
else if (archive_row[index.FOUND] === "needed") {
124-
await logErr(`${csv_row}: no useable alt link - Title: ${archive_row[index.TITLE]}`)
125-
continue
126-
}
158+
else if (row_video_ids.length === 3) {
159+
log(`${csv_row}: not present - ${archive_row[index.TITLE]}`)
127160

128-
else {
129-
includes = check_includes(playlistSnapshot, row_video_ids[0])
130-
if (includes.in_snapshot) {
131-
log(`${csv_row}: present`)
132-
delete playlistSnapshot[includes.id]
133-
continue
134-
}
135-
136-
log(`${csv_row}: not present - Title: ${archive_row[index.TITLE]}`)
137-
if (can_add) {
138-
log("adding...\n")
139-
await page.type('#mediaurl', archive_row[index.LINK])
161+
if (should_queue = can_add()) {
162+
log("adding using link in notes...\n")
163+
await page.type('#mediaurl', archive_row[index.NOTES].split(" ").at(-1))
140164
}
141165
}
166+
else {
167+
await logErr(`${csv_row}: no useable links for: ${archive_row[index.TITLE]}`)
168+
continue
169+
}
170+
142171

143172
if (await page.$('.server-msg-disconnect')) {
144173
logErr('Disconnected from server because of duplicate login')
@@ -151,7 +180,7 @@ function update_playlist(use_cookie, headless, queue_delay, playlist_url, check_
151180
but the default value is 2000 just to be safe since sometimes queing
152181
can take a bit longer before clearing the url entry box, which may cause errors
153182
*/
154-
if (can_add) {
183+
if (should_queue) {
155184
await page.click('#queue_end')
156185
await delay(queue_delay + (!headless * 1000))
157186

@@ -190,25 +219,35 @@ function update_playlist(use_cookie, headless, queue_delay, playlist_url, check_
190219

191220
if (blacklist_included.length) {
192221
log("Blacklisted videos found in Cytube playlist")
193-
for (let video_identifiers of blacklist_included)
222+
223+
for (const video_identifiers of blacklist_included)
194224
logErr(video_identifiers, false)
195225
log()
196226
}
197227

198228
if (Object.keys(playlistSnapshot).length !== 0) {
199-
log("Videos found in Cytube playlist that shouldn't be according to the pony archive")
200-
for (var url of Object.values(playlistSnapshot))
229+
log("Videos found in Cytube playlist that are duplicates or aren't in the archive")
230+
231+
for (const url of Object.values(playlistSnapshot))
201232
logErr(url, false)
202233
log()
203234
}
204235

205-
if (!headless) await getInput('', false)
236+
if (contradictory_included.length) {
237+
log("Videos found in playlist that shouldn't be according to archive labels")
238+
239+
for (const video_identifier of contradictory_included)
240+
logErr(video_identifier, false)
241+
log()
242+
}
243+
244+
if (!headless) getInput('')
206245
await browser.close()
207246
})
208247
}
209248

210249
async function login_with_cookie(page) {
211-
let input = await getInput('Authentication Cookie: ', true)
250+
let input = getInput('Authentication Cookie: ', true)
212251
let cookie = {
213252
'name': 'auth',
214253
'value': input,
@@ -227,7 +266,7 @@ async function login_with_cookie(page) {
227266
logErr("Invalid Authentication Cookie Provided")
228267
log()
229268

230-
cookie.value = await getInput('Authentication Cookie: ', true)
269+
cookie.value = getInput('Authentication Cookie: ', true)
231270
}
232271
}
233272

@@ -247,4 +286,47 @@ async function normal_login(page, url) {
247286
await page.goto(url)
248287
}
249288

289+
290+
id_indices = [index.LINK, index.ALT_LINK, index.NOTES]
291+
292+
function check_includes(playlist_snapshot, video_ids) {
293+
const ret = {archive_index: null, video_id: null}
294+
let id, i = 0
295+
296+
for (;i < video_ids.length; ++i) {
297+
id = video_ids[i]
298+
299+
if (typeof id === "string") {
300+
if (id in playlist_snapshot) {
301+
ret.video_id = id
302+
break
303+
}
304+
}
305+
// For Ponytube videos with two ids
306+
else if (id[0] in playlist_snapshot) {
307+
ret.video_id = id[0]
308+
break
309+
}
310+
else if (id[1] in playlist_snapshot) {
311+
ret.video_id = id[1]
312+
break
313+
}
314+
}
315+
316+
if (ret.video_id !== null)
317+
ret.archive_index = id_indices[i]
318+
319+
return ret
320+
}
321+
322+
function can_add() {
323+
return (
324+
has_edit_pemissions &&
325+
(
326+
!ask_before_adding ||
327+
getInput("Add this video to the playlist? (y/n)\n").toLowerCase() === "y"
328+
)
329+
)
330+
}
331+
250332
module.exports = { update_playlist }

0 commit comments

Comments
 (0)