Skip to content

Instantly share code, notes, and snippets.

@brucemcpherson
Created September 23, 2016 10:29
Show Gist options
  • Save brucemcpherson/888c1483a80b9f91d52e1b81a29e90f3 to your computer and use it in GitHub Desktop.
Save brucemcpherson/888c1483a80b9f91d52e1b81a29e90f3 to your computer and use it in GitHub Desktop.
mailtabgs
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;
}
}
<!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