Created
April 15, 2016 16:36
-
-
Save anonymous/55b41ba3130c101017048f05aa989434 to your computer and use it in GitHub Desktop.
This script is for the Dlink 2330L IP camera. It downloads media files in selected folders from the built in sd card via the web browser. Navigate to the sd card menu, paste the script into the chrome javascript console (press "Enter"), select the folders that you want to download and click the "download" button. http://forums.dlink.com/index.ph…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Larger number, larger the delay. | |
// If changing folders is too slow decrease g_PAUSE_DELAY_MILLISECONDS (1000 milliseconds in a second: 3000 = 3 seconds). | |
// If time between video downloads is too long decrease g_DOWNLOAD_DELAY_MULTIPLIER. | |
var g_PAUSE_DELAY_MILLISECONDS = 3000; | |
var g_DOWNLOAD_DELAY_MULTIPLIER = 1.5; | |
var g_dataObj = { numberOfVideosClicked: 0 }; | |
var g_FOLDER_OBJ = { | |
1: { | |
regEx: /\/\d{8}&/ | |
}, | |
2: { | |
regEx: /\/\d\d&/, | |
}, | |
3: { | |
IS_VIDEO_FOLDER: true, | |
regEx: /[mp4|avi]$/, | |
}, | |
}; | |
function parseLinksFromFolder(p_array, p_dontChangePage, p_callBack) { | |
var pageInfo = getPageInfo(); | |
var noArray = null ; | |
if (!p_array) { | |
p_array = getAnchorsArray(pageInfo.FOLDER_LEVEL); | |
} | |
if (!p_dontChangePage && !pageInfo.IS_LAST_PAGE && p_array.length === 0) { | |
changeFolder(pageInfo.CURRENT_PATH, (pageInfo.CURRENT_PAGE + 1), parseLinksFromFolder.bind(null , noArray, p_dontChangePage, p_callBack)); | |
} else if (p_array.length === 0 && (p_dontChangePage || pageInfo.IS_LAST_PAGE)) { | |
setTimeout(function() { | |
p_callBack(); | |
}, g_PAUSE_DELAY_MILLISECONDS); | |
} else if (pageInfo.IS_VIDEO_FOLDER) { | |
downloadVideosFromFolder(p_array, parseLinksFromFolder.bind(null , p_array, false, p_callBack)); | |
} else { | |
var folderAnchor = p_array.shift(); | |
var newPath = parseFolderPath(folderAnchor.href); | |
changeFolder(newPath, 1, // Navigate to a new folder. | |
/**/parseLinksFromFolder.bind(null , noArray, false, // Parse the links from the folder. | |
/* */changeFolder.bind(null , pageInfo.CURRENT_PATH, pageInfo.CURRENT_PAGE, // Navigate back to the this folder done. | |
/* */parseLinksFromFolder.bind(null , p_array, p_dontChangePage, p_callBack)))); | |
} | |
} | |
function downloadVideosFromFolder(p_array, p_callBack) { | |
if (!p_array || p_array.length === 0) { | |
setTimeout(function() { | |
p_callBack(); | |
}, g_PAUSE_DELAY_MILLISECONDS); | |
} else { | |
var videoAnchor = p_array.shift(); | |
videoAnchor.style.color = 'green'; | |
videoAnchor.click(); | |
console.log("file:", videoAnchor.href | |
&& videoAnchor.href.match(/\/\d\d\/(.*?[mp4|avi|jpg])$/) | |
&& videoAnchor.href.match(/\/\d\d\/(.*?[mp4|avi|jpg])$/)[1]); | |
var videoSize = parseInt(videoAnchor.parentElement.parentElement.lastChild.innerHTML); | |
var delay = videoSize * g_DOWNLOAD_DELAY_MULTIPLIER; | |
recordData(videoAnchor.href); | |
setTimeoutApplyArguments(downloadVideosFromFolder, arguments, delay); | |
} | |
} | |
function getPageInfo() { | |
var obj = {}; | |
obj.LENGTH = howManyPages(); | |
obj.CURRENT_PAGE = currentPageNumber(); | |
obj.IS_LAST_PAGE = ((obj.LENGTH - obj.CURRENT_PAGE) === 0); | |
obj.CURRENT_PATH = parseFolderPath(CONTENT_PAGE_LAST); | |
obj.FOLDER_LEVEL = getCurrentFolderLevel(obj.CURRENT_PATH); | |
obj.IS_VIDEO_FOLDER = (g_FOLDER_OBJ[obj.FOLDER_LEVEL].IS_VIDEO_FOLDER || false); | |
return obj; | |
} | |
function getCurrentFolderLevel(p_path) { | |
if (p_path) { | |
return ( p_path.split('/').length - 1) ; | |
} else { | |
return 0; | |
} | |
} | |
function howManyPages() { | |
return document.getElementById('pageselect').options.length; | |
} | |
function currentPageNumber() { | |
return parseInt(document.getElementById('pageselect') | |
.options[document.getElementById('pageselect').selectedIndex] | |
.text); | |
} | |
function parseFolderPath(p_pathString) { | |
return p_pathString.match(/path=(\/.*?)&/) && p_pathString.match(/path=(\/.*?)&/)[1]; | |
} | |
function makeArray(p_list) { | |
return Array.prototype.slice.call(p_list); | |
} | |
function getAnchorsArray(p_FOLDER_LEVEL) { | |
var anchors = makeArray(document.getElementById('maincontent').querySelectorAll('a')); | |
return anchors.filter(function(p_elem) { | |
return g_FOLDER_OBJ[p_FOLDER_LEVEL].regEx.test(p_elem.href); | |
}); | |
} | |
function setTimeoutApplyArguments(p_funcToCall, p_args, p_delay) { | |
setTimeout(function(args) { | |
p_funcToCall.apply(null , args); | |
}, p_delay, p_args); | |
} | |
function changeFolder(p_folderPath, p_pageNumber, p_callBack) { | |
try { | |
var pageInfo = getPageInfo(); | |
if (pageInfo.CURRENT_PATH !== p_folderPath || pageInfo.CURRENT_PAGE !== p_pageNumber) { | |
ChangeContent('cgi-bin/sdlist.cgi?path=' + p_folderPath + '&page=' + p_pageNumber); | |
setTimeoutApplyArguments(changeFolder, arguments, g_PAUSE_DELAY_MILLISECONDS); | |
} else { | |
setTimeout(function() { | |
p_callBack(); | |
}, g_PAUSE_DELAY_MILLISECONDS); | |
} | |
} catch (e) { | |
setTimeoutApplyArguments(changeFolder, arguments, g_PAUSE_DELAY_MILLISECONDS); | |
} | |
} | |
// Threw this in because it started downloading duplicates for some reason. | |
// I suspect it was because of the screen saver or somehow the tab lost focus. | |
function recordData(p_videoHref) { | |
var t = parseFolderPath(CONTENT_PAGE_LAST).split('/'); | |
var videoName = p_videoHref && p_videoHref.match(/\/\d\d\/(.*?[mp4|avi|jpg])$/) && p_videoHref.match(/\/\d\d\/(.*?[mp4|avi|jpg])$/)[1]; | |
t.shift(); | |
if (t[0] && !g_dataObj[t[0]]) { | |
// video or pictures | |
g_dataObj[t[0]] = g_dataObj[t[0]] || {}; | |
} | |
if (t[1] && !g_dataObj[t[1]]) { | |
// date | |
g_dataObj[t[0]][t[1]] = g_dataObj[t[0]][t[1]] || {}; | |
} | |
if (t[2] && !g_dataObj[t[2]]) { | |
// hour | |
g_dataObj[t[0]][t[1]][t[2]] = g_dataObj[t[0]][t[1]][t[2]] || []; | |
} | |
if (t[2] && videoName) { | |
// video name | |
g_dataObj[t[0]][t[1]][t[2]].push(videoName); | |
} | |
g_dataObj.numberOfVideosClicked += 1; | |
} | |
function getSelected() { | |
var pageInfo = getPageInfo(); | |
var selected = makeArray(document.querySelectorAll('input[type=checkbox]')) | |
.filter(function(p_elem) { | |
if (p_elem.checked && p_elem.previousSibling && p_elem.previousSibling.value) { | |
return true; | |
} | |
return false; | |
}).map(function(p_elem) { | |
return p_elem.parentElement.parentElement.querySelector('a'); | |
}); | |
if (selected.length > 0) { | |
g_dataObj.startTime = Date.now(); | |
parseLinksFromFolder(selected, true, function() { | |
g_dataObj.endTime = Date.now(); | |
alert('\n\nFinished downloading files.\n*See console for more information.\n\n'); | |
modal.delete(); | |
// Display a table in devtools for debugging purposes. | |
for (var n in g_dataObj.video) { | |
console.group("Download data for: " + n); | |
console.table(g_dataObj.video[n], ['length']); | |
console.groupEnd(); | |
} | |
console.log("=>", g_dataObj.numberOfVideosClicked, 'downloads took:', +((g_dataObj.endTime - g_dataObj.startTime) / 1000 / 60).toFixed(2), "minutes"); | |
console.log("=>", g_dataObj); | |
}); | |
modal.create(null ); | |
} | |
} | |
var modal = { | |
modalElement: document.createElement('div'), | |
create: function(p_cssText) { | |
this.modalElement.style.cssText = p_cssText || 'background: rgba(157, 192, 232, 0.3);position: fixed;top: 0px;right: 0px;width: 100%;height: 100%;'; | |
document.body.appendChild(this.modalElement); | |
}, | |
delete: function() { | |
this.modalElement.parentElement.removeChild(this.modalElement); | |
} | |
}; | |
function createDownloadButton(p_value) { | |
var downloadButton = document.getElementById('okBtn').cloneNode(true); | |
downloadButton.value = p_value; | |
downloadButton.id = 'downloadSelectedItems'; | |
downloadButton.onclick = getSelected; | |
downloadButton.style.marginLeft = '10px'; | |
document.getElementById('okBtn').parentElement.appendChild(downloadButton); | |
} | |
var theMainloop = setInterval(function() { | |
try { | |
var pageInfo = getPageInfo(); | |
var downloadButton = document.getElementById('downloadSelectedItems'); | |
if (!downloadButton && (pageInfo.FOLDER_LEVEL === 1 || pageInfo.FOLDER_LEVEL === 2)) { | |
createDownloadButton('Download'); | |
} | |
} catch (e) { | |
//console.log(e); | |
} | |
}, 200); | |
if (console && console.log && console.group && console.groupEnd) { | |
console.log(new Array(24).join('\n')); | |
console.group('Information about this script:'); | |
console.log('Dlink 2330l media downloader v1.0. Tested on firmware v1.00 and chrome v49. USE AT YOUR OWN RISK!'); | |
console.group('Instructions:'); | |
console.log('The script seems to run best when recording is turned off, the screen saver is turned off, no unnecessary programs running and the browser tab is always in focus (aka front and center not "greyed" out). The computer should not be used for anything else while the script is running. Otherwise it may skip some files or download some files twice.\n\nMake sure the browser is configured to download files with out confirmation.\n\nSet the delay variables at the top of the script so that your camera is not overwhelmed. The videos should download one after the other with little or no overlap.\n\nJust select the folders that you want to download and then press the download button.\n\n"Set it and forget it"'); | |
console.groupEnd(); | |
console.groupEnd(); | |
console.log(new Array(3).join('\n')); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment