Skip to content

Instantly share code, notes, and snippets.

@rootux
Last active November 21, 2016 22:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rootux/9e450d14aa18db98c8826843dd2a752f to your computer and use it in GitHub Desktop.
Save rootux/9e450d14aa18db98c8826843dd2a752f to your computer and use it in GitHub Desktop.
Creates a Safety file from
/**
* Generate Google Docs based on a template document and data incoming from a Google Spreadsheet
*
* License: MIT
*
* Copyright 2013 Mikko Ohtamaa, http://opensourcehacker.com
*
* Modified by Gal Bracha for http://dreams.midburnerot.com
* This is the source file from which we generate the Safety file template
* https://docs.google.com/document/d/1jTb-7Y3ApVchQwqfw7CcKstBNAt8-rmwtLMYU4oi2jk/edit?usp=sharing
* The output is a CSV File created from the admin panel of http://dreams.midburnerot.com
*/
// Google Doc id from the document template
// (Get ids from the URL)
var SOURCE_TEMPLATE = "1jTb-7Y3ApVchQwqfw7CcKstBNAt8-rmwtLMYU4oi2jk";
// In which spreadsheet we have all the dreams data
var DREAMS_SPREADSHEET = "1b-1BCeh7C48-yTogvEQBrQuYaJ9RLJEZljr1X6ANbyQ";
// In which Google Drive folder we toss the target documents (Id)
var TARGET_FOLDER = "0B-uj4x8Jf3gWZVV0UVFrN1RTQkE";
var DREAMS_URL_FOR_IMAGES = 'http://dreams.midburnerot.com/dreams/';
// We will read the number of columns into this dynamic var
var columnLength;
/**
* Return spreadsheet row content as JS array.
*
* Note: We assume the row ends when we encounter
* the first empty cell. This might not be
* sometimes the desired behavior.
*
* Rows start at 1, not zero based!!! 🙁
*
*/
function getRowAsArray(sheet, row) {
var dataRange = sheet.getRange(row, 1, 1, 99);
var data = dataRange.getValues();
var columns = [];
for (i in data) {
var row = data[i];
Logger.log("Got row", row);
for(var l=0; l<99; l++) {
var col = row[l];
// First empty column interrupts unless columnLength is set
if(!columnLength && !col) {
break;
}
// We first get number of columns then we count to number of columns
if(columnLength && l >= columnLength){
break;
}
columns.push(col);
}
}
return columns;
}
/**
* Duplicates a Google Apps doc
*
* @return a new document with a given name from the orignal
*/
function createDuplicateDocument(sourceId, name) {
var source = DriveApp.getFileById(sourceId);
var newFile = source.makeCopy(name);
var targetFolder = DriveApp.getFolderById(TARGET_FOLDER);
targetFolder.addFile(newFile);
newFile.getParents().next().removeFile(newFile);
return DocumentApp.openById(newFile.getId());
}
/**
* Search a paragraph in the document and replaces it with the generated text
*/
function replaceParagraph(doc, keyword, newText) {
var ps = doc.getParagraphs();
for(var i=0; i<ps.length; i++) {
var p = ps[i];
var text = p.getText();
if(text.indexOf(keyword) >= 0) {
if(newText) {
p.setText(newText);
}else {
p.setText(" ");
}
break;
}
}
}
/**
* Script entry point
*/
function generateSafetyFiles() {
var data = SpreadsheetApp.openById(DREAMS_SPREADSHEET);
// Fetch variable names
// they are column names in the spreadsheet
var sheet = data.getSheets()[0];
var numberOfRows = sheet.getLastRow();
numberOfRows = 9;//TODO
for(var row=2; row <= numberOfRows; row++) {
generateSafetyFile(row);
}
}
function getImages(dreamId) {
var result = [];
Logger.log("Getting image " + dreamId);
var response = UrlFetchApp.fetch(DREAMS_URL_FOR_IMAGES + dreamId);
page_content = response.getContentText();
var imageIndex = page_content.indexOf('thumbnail');
while(imageIndex != -1) {
var imgUrl = extractNextImageUrl(page_content,imageIndex);
result.push(imgUrl);
Logger.log(imgUrl);
imageIndex = page_content.indexOf('thumbnail', imageIndex+1);
}
return result;
}
function insertImage(doc, imgUrl) {
var image = UrlFetchApp.fetch(imgUrl);
Logger.log(imgUrl);
var imagesParagraph = findImagesParagraph(doc);
var inlineImage = imagesParagraph.appendInlineImage(image.getBlob());
fixImageRatio(inlineImage);
imagesParagraph.appendText("\r\n");
}
function fixImageRatio(inlineImage) {
var MAX_HEIGHT = 900;
var MAX_WIDTH = 900;
var width = inlineImage.getWidth();
var newW = width;
var height = inlineImage.getHeight();
var newH = height;
var ratio = width/height;
if(width>MAX_WIDTH){
newW = MAX_WIDTH;
newH = parseInt(newW/ratio);
if(newH > MAX_HEIGHT) {
newH = MAX_HEIGHT;
newW = parseInt(newH/ratio);
}
}else if(height > MAX_HEIGHT) {
newH = MAX_HEIGHT;
newW = parseInt(newH/ratio);
}
inlineImage.setWidth(newW).setHeight(newH);
}
function findImagesParagraph(doc) {
var imageTag = "תמונות:";
var ps = doc.getParagraphs();
for(var i=0; i<ps.length; i++) {
var p = ps[i];
var text = p.getText();
if(text.indexOf(imageTag) >= 0) {
return p;
}
}
}
function extractNextImageUrl(html_content, index) {
var imgStartIndex = html_content.indexOf('http',index);
var imgEndIndex = html_content.indexOf('"',imgStartIndex);
return html_content.substring(imgStartIndex, imgEndIndex);
}
function generateSafetyFile(rowNumber) {
var data = SpreadsheetApp.openById(DREAMS_SPREADSHEET);
if(!rowNumber) {
return;
}
// Fetch variable names
// they are column names in the spreadsheet
var sheet = data.getSheets()[0];
var columns = getRowAsArray(sheet, 1);
columnLength = columns.length;
Logger.log("Processing columns:" + columns);
var customerData = getRowAsArray(sheet, rowNumber);
Logger.log("Processing data:" + customerData);
// Assume second column holds the name of the dream
var dreamName = customerData[1];
var target = createDuplicateDocument(SOURCE_TEMPLATE, dreamName);
Logger.log("Created new document:" + target.getId());
for(var i=0; i<columns.length; i++) {
var key = columns[i] + ":";
// We don't replace the whole text, but leave the template text as a label
var text = customerData[i] || ""; // No Javascript undefined
replaceParagraph(target, key, text);
}
// Replace Images
var dreamId = customerData[0];
var imagesUrlArr = getImages(dreamId);
Logger.log("Found " + imagesUrlArr + " Images");
for(var i=0;i<imagesUrlArr.length;i++) {
insertImage(target, imagesUrlArr[i]);
}
}
@rootux
Copy link
Author

rootux commented Nov 21, 2016

We've used it to create the safety files for the dreams platform.
The csv was exported from the Active Admin and then
we've used it as a base to create documents out of it

@rootux
Copy link
Author

rootux commented Nov 21, 2016

For more info - read here:
https://github.com/rootux/firestarter/

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