-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathezpz-plug-export.js
138 lines (119 loc) · 5.63 KB
/
ezpz-plug-export.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
'use strict'
<!-- ezpz-plug-export -->
<!-- export your plug.dj data -->
<!-- no bullshit, just a 1-Click-Download -->
// configure which endpoints get backup'd, and which filenames will be used
var endpoints = {
'users/me': 'profile.json',
'friends': 'friends.json',
'friends/invites': 'invites.json',
'ignores': 'ignores.json',
'rooms/favorites': 'favorites.json',
'rooms/history': 'history.json',
'rooms/me': 'rooms.json',
'store/inventory': 'inventory.json',
'users/me/history': 'history.json',
'users/me/transactions': 'transactions.json'
}
// set up progress bar
$('#ezpz-progress').remove()
var $prog = $('<div id=ezpz-progress>')
.css({
position: 'absolute',
height: '100%',
background: 'rgba(0, 156, 221, .5)',
zIndex: -1,
transition: 'width 200ms ease-in-out, background 200ms linear'
})
.appendTo('#footer')
// error handler
var ლ_ಠ益ಠ_ლ = function (msg, err) {
// show warning in the console
console.warn(msg, err)
// add an error message to the chat
if (window.API && typeof API.chatLog == 'function')
API.chatLog(msg + ' ' + (err && err.message || err || '')) // \xa0 is  
// temporarily turn the progress bar red/bloodorange
$prog.css({ background: 'rgba(221, 20, 0, 0.5)' })
setTimeout(function () {
// turn it back to blue, unless we're done exporting
if (loaded != total)
$prog.css({ background: 'rgba(0, 156, 221, .5)' })
}, 500)
}
// helper function to load data and store it in the zip
var zip
var delay = 0, total = 0, loaded = 0
var λ = function λ(url, filename, folder) {
return new Promise(function (fulfill, reject) {
// first, wait a moment before proceeding (0.5 seconds for each resource)
setTimeout( function () {
// load the requested URL from https://plug.dj/_/… or whatever domain we're on
$.get('/_/' + url, null, null, 'text').then(function (data) {
// data successfully loaded
// add file to zip
;(folder || zip).file('' + filename, data)
// log progress to console
console.log('[' + ++loaded + '/' + total + '] loaded /_/' + url + ' (' + filename + ')')
// update progress bar (make it wider)
$prog.css({ width: 100 * loaded / total + '%' })
},
// failed to load, show warning
function (_, err) {
ლ_ಠ益ಠ_ლ('failed to load /_/' + url + ' (' + filename + ')', err)
}).then(fulfill, fulfill) // we don't reject ever. KEEP IT MOVING! ಠ_ಠ
}, 500 * delay++) // this specifies how long we're waiting before loading
})
}
// track how long it takes (the result will be shown in the console, once the exporter is finished)
console.time('playlist export')
// load helper scripts (JSZip to create a ZIP file, FileSaver to download the zip)
var define_ = window.define // fix JSZip not exporting properly
window.define = null
Promise.all([
Promise.resolve($.getScript('https://cdnjs.cloudflare.com/ajax/libs/jszip/2.5.0/jszip.min.js')),
Promise.resolve($.getScript('https://cdn.rawgit.com/koffsyrup/FileSaver.js/master/FileSaver.js'))
]).then(function () {
// both JSZip and FileSaver are loaded
window.define = define_ // restore, now that JSZip is loaded
// create a ZIP to add the exported files to
zip = new JSZip()
// first only load /_/playlists to see if it even works
// so we don't spam requests if it doesn't work anyways
$.getJSON('/_/playlists').then(function (data) {
// add playlist-list to ZIP
zip.file('playlists.json', JSON.stringify(data))
// `total` is the amount of resources we are loaded, this is necessary for the progressbar to correctly scale
total = data.data.length + Object.keys(endpoints).length
// export playlists
var plFolder = zip.folder('playlists')
var promises = data.data.map(function (pl) {
return λ('playlists/' + pl.id + '/media', pl.name + '.json', plFolder)
})
// add other files (see `endpoints` at the very top of this file)
var l = promises.length
for (var url in endpoints)
promises[l++] = λ(url, endpoints[url])
// promises is a list of so-called "Promises", one for each resource we are loading
// the promise will tell us when it's down. We use `Promise.all(promises)`
// to wait for ALL promises to finish
Promise.all(promises).then(function () { // finished loading all resources
// compile the zip and download it
var date = /[^T]+/.exec(new Date().toISOString())[0]
saveAs(zip.generate({ type: 'blob' }), date + '_plug_playlists.zip')
// stop tracking the time (and show how long it took in the console)
console.timeEnd('playlist export')
// change the progress bar to green
$prog.css({ background: 'rgba(0, 221, 78, 0.5)' })
// after 5 seconds (5000ms), remove the progress bar
setTimeout(function () {
$prog.fadeOut(function () { $prog.remove() })
}, 5000)
})
}, function (_, err) {
// failed to load /_/playlists, skipping any other requests
ლ_ಠ益ಠ_ლ('Failed to load playlists data. Are you not logged in? Is plug down?', err)
// stop tracking the time (and show how long it took in the console)
console.timeEnd('playlist export')
})
})