Created
September 23, 2016 10:29
-
-
Save brucemcpherson/888c1483a80b9f91d52e1b81a29e90f3 to your computer and use it in GitHub Desktop.
mailtabgs
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
function doGet(e) { | |
var template = HtmlService.createTemplateFromFile('ht'); | |
// Build and return HTML in IFRAME sandbox mode. | |
return template.evaluate(); | |
} | |
function getThreads(options) { | |
return GmailApp.search(options.query, options.start, options.max).reduce(function (p, thread) { | |
thread.getMessages().filter(function (message) { | |
threadID = message.getId(); | |
return message.getAttachments().length; | |
}) | |
.forEach(function (message) { | |
var emailDate = Utilities.formatDate(message.getDate(), "US/Central", "MM-dd-yyyy"); | |
var attachments = message.getAttachments(); | |
p.push({ | |
From: message.getFrom(), | |
"Date Created": emailDate, | |
Subject: message.getSubject(), | |
Size: kmToMB(attachments[0].getSize()), | |
Remove:threadID | |
}); | |
}); | |
return p; | |
}, []); | |
function kmToMB(size) { | |
return size; | |
} | |
} | |
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
<!DOCTYPE html> | |
<html> | |
<head> | |
<base target="_top"> | |
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css"> | |
</head> | |
<body> | |
<div>Page <span id="page-number"></span></div> | |
<div id="container"></div> | |
<button id="prev" disabled>PREVIOUS</button> | |
<button id="next" disabled>NEXT</button> | |
<script> | |
(function(settings) { | |
// all the returned items stored here | |
var items = [], | |
page = 0, | |
starting = true; | |
// add event listeners to next/prev | |
document.getElementById ("next").addEventListener("click", function (e) { | |
tabulate(++page); | |
}); | |
document.getElementById ("prev").addEventListener("click", function (e) { | |
tabulate(--page); | |
}); | |
// kick off getting data | |
getData(); | |
// gets data from the server | |
// and appends to the heap | |
function getData() { | |
// limit run max for testing | |
var chunkSize = settings.runMax ? | |
Math.min(settings.runMax - items.length, settings.chunkSize) : | |
settings.chunkSize; | |
// if there's anything left to do then go | |
if (chunkSize > 0) { | |
provoke("getThreads", { | |
max: chunkSize, | |
start: items.length, | |
query: settings.query | |
}) | |
.then(function(data) { | |
// recurse to get the rest | |
dataReceived(data); | |
// there's more? | |
if (data.length) { | |
getData(); | |
} | |
})['catch'](function(err) { | |
// do something better to report error | |
throw err; | |
}); | |
} else { | |
dataReceived([]); | |
} | |
} | |
// called when we got some data | |
function dataReceived(data) { | |
// store it | |
Array.prototype.push.apply(items, data); | |
// if there's not enough and we're not finished then do nothing | |
if (!data.length || items.length >= settings.pageSize) { | |
// if this is the first time, then it's time to render | |
if (starting) { | |
tabulate(++page); | |
starting = false; | |
} | |
enableNav(); | |
} | |
} | |
function enableNav () { | |
document.getElementById ("prev").disabled = page > 1 ? false : true; | |
document.getElementById ("next").disabled = settings.pageSize * page < items.length ? false : true; | |
} | |
// called by either the next or prev button or when the first page arrives | |
function tabulate(pageNumber) { | |
document.getElementById ("page-number").innerHTML = pageNumber; | |
var data = items.slice(settings.pageSize * (pageNumber - 1), settings.pageSize * pageNumber); | |
var container = document.getElementById("container"); | |
//Check if has Data Object | |
if (data) { | |
container.innerHTML = '<table style="width:100%;"><tr><th>' + | |
Object.keys(data[0]).join("</th><th>") + "</th></tr>" + | |
data.map(function (d) { | |
return Object.keys(d).reduce(function (p, c) { | |
// special treatment for id field | |
if (c === "Remove" ) { | |
return p + '<td><input type="checkbox" id="'+c+'"></td>'; | |
} | |
else { | |
return p + "<td>" + d[c] + "</td>"; | |
} | |
}, "<tr>") + "</tr>" | |
}).join("") +"</table>"; | |
} | |
else { | |
container.innerHTML = "No emails"; | |
} | |
// checkboxes will have the id of the thread. | |
// add a button for deleting all the items that are ticked and do them all at once | |
// use querySelector to select all the ticked checkboxes | |
// and pass their ids back to the server | |
// then remove them from your items array and call tabulate again to create a fresh page with | |
// the missing items removed, and new ones moved into place. | |
enableNav(); | |
} | |
// promise version of script.run | |
function provoke(func, arg) { | |
return new Promise(function(resolve, reject) { | |
google.script.run | |
.withSuccessHandler(function(result) { | |
resolve(result); | |
}) | |
.withFailureHandler(function(err) { | |
reject(err); | |
})[func](arg); | |
}); | |
} | |
})({ | |
pageSize: 3, // how many to display on one page | |
chunkSize: 2, // how to many to get in each server call | |
runMax: 10, // change this to zero after debugging | |
query: "has:attachment larger:1m" | |
}); | |
</script> | |
</body> | |
</html> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment