Skip to content

Instantly share code, notes, and snippets.

@bcks
Last active July 6, 2017 13:59
Show Gist options
  • Save bcks/dd609677c6a6ffc426e9 to your computer and use it in GitHub Desktop.
Save bcks/dd609677c6a6ffc426e9 to your computer and use it in GitHub Desktop.
Cooper Hewitt Catalog Bot
var fs = require('fs'),
PDFDocument = require('pdfkit'),
async = require('async'),
ColorThief = require('color-thief'),
colorThief = new ColorThief();
var bookWidth = 430;
var bookHeight = 343;
var doc = new PDFDocument({ size: [bookWidth, bookHeight], margins: [0,0,0,0] });
doc.pipe(fs.createWriteStream('output.pdf'));
var pageNumber = 1;
var totalPages = 0;
// Request json from cooper-hewitt api to ./json
// Download images to ./images
// Download the Cooper Hewitt font from
// http://www.cooperhewitt.org/open-source-at-cooper-hewitt/cooper-hewitt-the-typeface-by-chester-jenkins/
// http://chfonts.s3.amazonaws.com/CooHew-TTF-v1p1-public.zip
// Count the total number of pages
for (i = 1; i <= 9; i++) {
var myData = require('./json/'+i+'.json');
for (j = 0; j < myData.objects.length; j++) {
if (typeof myData.objects[j].images !== 'undefined') {
if (typeof myData.objects[j].images[0] !== 'undefined') {
totalPages = totalPages + 1;
}
}
}
}
// format total for cover page
var totalPagesComma = totalPages.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
// Make cover page
doc.lineWidth(25);
doc.rect(0,0,bookWidth,bookHeight).fillAndStroke("black", "white").stroke();
doc.fillColor('white').font('./font/CooHew-Bold.ttf').fontSize(52).text('MATCHSAFE', 30, 30, { width: bookWidth, align: 'left' });
doc.fillColor('white').font('./font/CooHew-Bold.ttf').fontSize(18).text(totalPagesComma + ' OBJECTS FROM THE', 30, 100, { width: bookWidth, align: 'left' });
doc.fillColor('white').font('./font/CooHew-Bold.ttf').fontSize(18).text('COOPER-HEWITT COLLECTION', 30, 121, { width: bookWidth, align: 'left' });
// Make colophon
doc.addPage();
doc.lineWidth(25);
doc.rect(0,0,bookWidth,bookHeight).fillAndStroke("#eeeeee", "white").stroke();
doc.fillColor('black').font('./font/CooHew-Roman.ttf').fontSize(10).text('Compiled by John Emerson\nhttp://backspace.com\n\nfrom The Cooper-Hewitt API\nhttps://collection.cooperhewitt.org/api\n\nInspired by Irma Boom\nhttps://youtu.be/oHcEKNoDajk\n\nBook source code at\nhttps://gist.github.com/bcks/dd609677c6a6ffc426e9', 30, bookHeight / 2, { width: bookWidth, align: 'left' });
// Make object pages
for (var i = 1; i <= 9; i++) {
var myData = require('./json/'+i+'.json');
async.forEach(myData.objects, function(object, callback) {
if (typeof object.images !== 'undefined') {
if (typeof object.images[0] !== 'undefined') {
var parts = object.images[0].b.url.split('/');
var popped = parts.pop();
console.log(pageNumber + ' ' + popped);
var imagePath = 'images/' + popped;
var img_width = object.images[0].b.width;
var img_height = object.images[0].b.height;
var xpad = 0;
var ypad = 0;
var dimension;
var hex = '#000000';
// some images get padding, but if they are close to the page ratio, just fit to page and crop a little
var ratioDifference = (bookWidth / bookHeight) - (img_width / img_height);
if (ratioDifference < .3 && ratioDifference > -.3) {
if ( ( bookWidth / bookHeight ) >= ( img_width / img_height ) ) {
xpad = 0;
ypad = ( bookHeight / 2 ) - ( img_height * ( bookWidth / img_width ) / 2 );
dimension = { width: bookWidth };
} else {
var new_width = img_width / img_height * bookHeight;
xpad = ( bookWidth / 2 ) - ( img_width * ( bookHeight / img_height ) / 2 );
ypad = 0;
dimension = { width: new_width };
}
} else {
if ( ( bookWidth / bookHeight ) >= ( img_width / img_height ) ) {
xpad = ( bookWidth / 2 ) - ( img_width * ( bookHeight / img_height ) / 2 );
dimension = { height: bookHeight };
} else {
ypad = ( bookHeight / 2 ) - ( img_height * ( bookWidth / img_width ) / 2 );
dimension = { width: bookWidth };
}
var image = fs.readFileSync(imagePath);
var rgb = colorThief.getColor(image);
var onecolor = require('onecolor');
var rgbCode = 'rgb( ' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ')'; // 'rgb(r, g, b)'
hex = onecolor(rgbCode).hex();
}
doc.addPage().rect(0,0,bookWidth,bookHeight).fill(hex).image(imagePath, xpad, ypad, dimension);
// add URL for debugging
// doc.fillColor("#000000").font('./font/CooHew-Roman.ttf').fontSize(7).text(popped, 0, 320, { width: (bookWidth - 20), align: 'left' });
// add page number
doc.fillColor("#dddddd").font('./font/CooHew-Roman.ttf').fontSize(7).text(pageNumber, 0, 320, { width: (bookWidth - 20), align: 'right' });
pageNumber = pageNumber + 1;
callback;
}
}
},
function (err) {
console.log(err);
});
}
// make Index
doc.addPage();
var indexPageNumber = 1;
var creditHeight = 40;
var creditMargin = 20;
var creditX = creditMargin;
var numberPerPage = 16;
doc.fillColor("#000000").font('./font/CooHew-Bold.ttf').fontSize(28).text('INDEX', creditX, creditMargin, { width: bookWidth / 2, align: 'left' });
for (var i = 1; i <= 9; i++) {
var myData = require('./json/'+i+'.json');
async.forEach(myData.objects, function(object, callback) {
if (typeof object.images !== 'undefined') {
if (typeof object.images[0] !== 'undefined') {
if (indexPageNumber % numberPerPage == 0) {
// add page number
doc.fillColor("#dddddd").font('./font/CooHew-Roman.ttf').fontSize(7).text(pageNumber, 0, 320, { width: (bookWidth - 20), align: 'right' });
pageNumber = pageNumber + 1;
doc.addPage();
}
if (indexPageNumber % numberPerPage < ( numberPerPage / 2) ) {
creditX = creditMargin;
} else {
creditX = ( bookWidth / 2 ) + ( creditMargin / 2 );
}
var creditY = ( ( indexPageNumber % ( numberPerPage / 2) ) * creditHeight ) + creditMargin;
var credit = '';
credit += object.title + '. ';
if (object.medium !== null) { credit += object.medium + '. '; }
if (object.creditline !== null) { credit += object.creditline + '. '; }
if (object.accession_number !== null) { credit += object.accession_number + '. '; }
credit += "\n\n";
// Add page number
doc.fillColor("#333333").font('./font/CooHew-Roman.ttf').fontSize(7).text(indexPageNumber, creditX, creditY, {
width: 100,
height: creditHeight,
align: 'left'
});
doc.fillColor("#333333").font('./font/CooHew-Roman.ttf').fontSize(7).text(credit, creditX + 24, creditY, {
width: ( bookWidth / 2 ) - 50,
height: creditHeight,
align: 'left'
});
indexPageNumber = indexPageNumber + 1;
callback;
}
}
},
function (err) {
console.log(err);
});
}
// add last page number
doc.fillColor("#dddddd").font('./font/CooHew-Roman.ttf').fontSize(7).text(pageNumber, 0, 320, { width: (bookWidth - 20), align: 'right' });
pageNumber = pageNumber + 1;
// and print!
doc.end();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment