@@ -2,16 +2,6 @@ import Logger from "./logger";
22
33import { downloadFile , dateString } from "./utilities" ;
44
5- const preamble = `#!/usr/bin/env bash
6- # Generated by Bandcamp Enhancement Suite (https://github.com/sabjorn/BandcampEnhancementSuite)
7- #
8- # The following can be used to batch download your recent purchase.
9- #
10- # Usage (Mac/Linux):
11- # 1) open Terminal
12- # 2) move to desired download directory (e.g. \`cd ~/Downloads/bandcamp\`)
13- # 3) paste the text of this file into Terminal\n\n` ;
14-
155export default class DownloadHelper {
166 constructor ( ) {
177 this . log = new Logger ( ) ;
@@ -52,7 +42,7 @@ export default class DownloadHelper {
5242 this . button = document . createElement ( "button" ) ;
5343 this . button . title =
5444 "Generates a file for automating downloads using 'cURL'" ;
55- this . button . className = "downloadall" ;
45+ this . button . className = "bes- downloadall" ;
5646 this . button . disabled = true ;
5747 this . button . textContent = "preparing download" ;
5848
@@ -69,7 +59,8 @@ export default class DownloadHelper {
6959 const date = DownloadHelper . dateString ( ) ;
7060 const downloadList = DownloadHelper . generateDownloadList ( ) ;
7161 const preamble = DownloadHelper . getDownloadPreamble ( ) ;
72- const downloadDocument = preamble + downloadList ;
62+ const postamble = DownloadHelper . getDownloadPostamble ( ) ;
63+ const downloadDocument = preamble + downloadList + postamble ;
7364
7465 DownloadHelper . downloadFile ( `bandcamp_${ date } .txt` , downloadDocument ) ;
7566 } ) ;
@@ -84,33 +75,28 @@ export default class DownloadHelper {
8475 }
8576
8677 static generateDownloadList ( ) {
87- let filelist = "" ;
88- document . querySelectorAll ( "a.item-button" ) . forEach ( ( item , index , list ) => {
89- const url = item . getAttribute ( "href" ) ;
90- // Prevent duplicate URLs
91- if ( filelist . indexOf ( url ) === - 1 ) {
92- filelist += 'curl -OJ "' + url + '" && \\\n' ;
93- }
94- } ) ;
95- filelist = filelist . substring ( 0 , filelist . length - 6 ) ;
96- filelist += "\n" ;
97- return filelist ;
78+ const urlSet = new Set (
79+ [ ...document . querySelectorAll ( "a.item-button" ) ] . map ( item => {
80+ return item . getAttribute ( "href" ) ;
81+ } )
82+ ) ;
83+
84+ if ( urlSet . size === 0 ) return "URLS=()\n" ;
85+
86+ const fileList = [ ...urlSet ] . map ( url => `\t"${ url } "` ) . join ( "\n" ) ;
87+ return "URLS=(\n" + fileList + "\n)\n" ;
9888 }
9989
10090 static callback ( ) {
101- let allDownloadLinks = document . querySelectorAll (
91+ const allDownloadLinks = document . querySelectorAll (
10292 ".download-title .item-button"
10393 ) ;
10494
105- let linksReady = true ;
106- allDownloadLinks . forEach ( function ( element , index ) {
107- if ( element . style . display === "none" ) {
108- linksReady = false ;
109- return ;
110- }
111- } ) ;
95+ const linksReady = [ ...allDownloadLinks ] . every (
96+ element => element . style . display !== "none"
97+ ) ;
11298
113- this . log . info ( " linksReady" , linksReady ) ;
99+ this . log . info ( ` linksReady: ${ linksReady } ` ) ;
114100 if ( linksReady ) {
115101 this . enableButton ( ) ;
116102 return ;
@@ -122,4 +108,77 @@ export default class DownloadHelper {
122108 static getDownloadPreamble ( ) {
123109 return preamble ;
124110 }
111+
112+ static getDownloadPostamble ( ) {
113+ return postamble ;
114+ }
125115}
116+
117+ const preamble = `#!/usr/bin/env bash
118+
119+ # Generated by Bandcamp Enhancement Suite (https://github.com/sabjorn/BandcampEnhancementSuite)
120+ #
121+ # The following can be used to batch download your recent purchases.
122+ # NOTE: pasting into terminal may not work properly--please follow new instructions below
123+ #
124+ # Usage (Mac/Linux):
125+ # 1) open Terminal
126+ # 2) move to desired download directory (e.g. \`cd ~/Downloads/bandcamp\`)
127+ # 3) run script (e.g. \`bash <this filename>.txt\`
128+
129+ ` ;
130+
131+ const postamble = `
132+ DEFAULT_BATCH_SIZE=5
133+
134+ download_file() {
135+ local url="$1"
136+
137+ if curl -L --fail -OJ "$url" 2>/dev/null; then
138+ echo -n "."
139+ return 0
140+ else
141+ echo -n "x"
142+ return 1
143+ fi
144+ }
145+
146+ TOTAL_URLS=\${#URLS[@]}
147+ COMPLETED=0
148+ FAILED=0
149+ BATCH_SIZE=\${1:-$DEFAULT_BATCH_SIZE}
150+ if [ "$BATCH_SIZE" -eq "$DEFAULT_BATCH_SIZE" ] && [ -z "$1" ]; then
151+ echo "note: the BATCH_SIZE can be set with a numerical argument after the command. e.g. bash this_script.txt 10"
152+ fi
153+
154+ echo "Beginning parallel download of $TOTAL_URLS files (batch size: $BATCH_SIZE)"
155+ for ((i=0; i<TOTAL_URLS; i+=BATCH_SIZE)); do
156+ pids=()
157+ for ((j=i; j<i+BATCH_SIZE && j<TOTAL_URLS; j++)); do
158+ download_file "\${URLS[j]}" &
159+ pids+=($!)
160+ done
161+
162+ for pid in "\${pids[@]}"; do
163+ wait $pid
164+ status=$?
165+ if [ $status -eq 0 ]; then
166+ ((COMPLETED++))
167+ else
168+ ((FAILED++))
169+ fi
170+ done
171+ done
172+
173+ echo ""
174+ if [ $FAILED -eq 0 ]; then
175+ echo "Successfully downloaded $TOTAL_URLS files"
176+ else
177+ echo "$FAILED files failed to download"
178+ fi
179+ echo ""
180+ echo "Press any key to exit..."
181+ read -n 1
182+
183+ exit $FAILED
184+ ` ;
0 commit comments