Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save tomaszgalinski/1ebd26e3984a54ed0deadb05238c206e to your computer and use it in GitHub Desktop.
Save tomaszgalinski/1ebd26e3984a54ed0deadb05238c206e to your computer and use it in GitHub Desktop.
Saving the images and videos from your ClassDojo storyline
/* run this in the console on the ClassDojo page */
function download(url, prefix) {
fetch(url).then(function(t) {
return t.blob().then((b)=> {
var a = document.createElement("a");
a.href = URL.createObjectURL(b);
var n = url.lastIndexOf('/');
var filename = url.substring(n + 1);
var randomStr = Math.random().toString(36).substring(5);
var suffix = '.jpg';
var trimmedPrefix = prefix.substr(0, 20);
a.setAttribute("download", trimmedPrefix + '_' + randomStr + suffix);
a.click();
}
);
});
}
function eventFire(el, etype){
if (el.fireEvent) {
el.fireEvent('on' + etype);
} else {
var evObj = document.createEvent('Events');
evObj.initEvent(etype, true, false);
el.dispatchEvent(evObj);
}
}
function parseDojoDate(postDate) {
if(postDate.includes('ago')) {
dateStringOut = new Date().toLocaleDateString('en-ca');
} else {
if(postDate.split(' ').length == 3) {
postYear = postDate.split(' ')[2];
} else {
postYear = new Date().getFullYear()
}
switch (postDate.split(' ')[0]) {
case 'Jan':
postMonth = '01';
break;
case 'Feb':
postMonth = '02';
break;
case 'Mar':
postMonth = '03';
break;
case 'Apr':
postMonth = '04';
break;
case 'May':
postMonth = '05';
break;
case 'Jun':
postMonth = '06';
break;
case 'Jul':
postMonth = '07';
break;
case 'Aug':
postMonth = '08';
break;
case 'Sep':
postMonth = '09';
break;
case 'Oct':
postMonth = '10';
break;
case 'Nov':
postMonth = '11';
break;
case 'Dec':
postMonth = '12';
break;
}
postDay = ('00' + postDate.split(' ')[1].replace(',', '')).slice(-2);
dateStringOut = postYear + '-' + postMonth + '-' + postDay;
}
return dateStringOut;
}
var els = document.querySelectorAll('[data-test-name="storyPostContents"]');
els.forEach(
function(currentValue) {
firstImage = true;
lastImage = false;
// loop in order to catch each image in a set
while(firstImage == true || lastImage == false) {
// Get content node
contentNode = currentValue.childNodes[0].childNodes[0];
// Get content for file name
var headerNode = currentValue.parentNode.querySelector('[data-test-name="storyPostHeader"]');
var metadata = headerNode.querySelectorAll('.nessie-text')
var teacher = metadata[0].innerText;
var className = metadata[1].innerText;
var postDate = metadata[2].innerText;
var filePrefix = parseDojoDate(postDate) + ' - ' + className + ' - ' + teacher + " ";
console.log("Processing: " + filePrefix);
// download image and video
var video_els = contentNode.querySelector('[type="video/mp4"]');
if(video_els !== null) {
download(video_els.src, filePrefix);
}
url = window.getComputedStyle(contentNode).getPropertyValue("background-image");
if(url != 'none') {
download(url.slice(5, -8), filePrefix);
}
// check if there are more images
numDivs = contentNode.parentNode.childNodes.length;
// click or set lastImage to true as necessary
switch(numDivs) {
case 1:
lastImage = true;
break;
case 3:
if (firstImage == true) {
lastImage = false;
eventFire(contentNode.nextSibling, 'click');
} else {
lastImage = true;
}
break;
case 4:
eventFire(contentNode.nextSibling.nextSibling, 'click');
break;
default:
console.log('Unexpected post structure. ' + numDivs + ' divs found. Check for missing content.');
lastImage = true;
break;
}
firstImage = false;
}
// remove the node to simplify the page; this is useful for debugging because it allows you run a few items at a time.
//currentValue.remove()
});

Purpose

ClassDojo is a classroom communication app used to share reports between parents and teachers. Teachers track student behavior and upload photos or videos. The gamification style system teaches developmental skills through real-time feedback.

When your child's teacher shares a photo, it goes on your parent "storyline". Unfortunately, ClassDojo does not provide any means of saving these photos. In fact, the photos are displayed in a <div> using style: background-image('...'); so right-clicking and choosing "Save image" is not an option.

This script will download all currently loaded story post images and videos.

Usage

  1. Load your parent storyline (ClassDojo homepage when logged in)
  2. Make sure all photos and videos you want to save are loaded
  3. Open the JavaScript console (Ctrl + Shift + J in Chrome)
  4. Copy and paste all of the code above and press Enter
@dochoffiday
Copy link

It looks like all the data-test-* attributes can be replaced with data-*.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment