google-apps-script
Скрипт Google Web App для автоматической загрузки с Google Диска
Поиск…
Вступление
замечания
Веб-скрипт должен быть опубликован для работы.
Для https://script.google.com необходимо включить Pops ups
forms.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
setInterval(
function ()
{
document.getElementById('messages').innerHTML = 'Event Timer Fetching';
google.script.run
.withSuccessHandler(onSuccess)
.withFailureHandler(onFailure)
.fetchFromGoogleDrive();
}, 60000);
function callFetchGoogleDrive() {
document.getElementById('messages').innerHTML = 'Fetching';
google.script.run
.withSuccessHandler(onSuccess)
.withFailureHandler(onFailure)
.fetchFromGoogleDrive();
}
function onSuccess(sHref)
{
if(new String(sHref).valueOf() == new String("").valueOf())
{
document.getElementById('messages').innerHTML = 'Nothing to download';
}
else
{
document.getElementById('messages').innerHTML = 'Success';
document.getElementById('HiddenClick').href = sHref;
document.getElementById('HiddenClick').click(); // Must enable Pop Ups for https://script.google.com
}
}
function onFailure(error)
{
document.getElementById('messages').innerHTML = error.message;
}
</script>
</head>
<body>
<div id="messages">Waiting to DownLoad!</div>
<div>
<a id="HiddenClick" href="" target="_blank" onclick="google.script.host.close" style="visibility: hidden;">Hidden Click</a>
</div>
<div>
<button type="button" onclick='callFetchGoogleDrive();' id="Fetch">Fetch Now!</button>
</div>
</body>
</html>
code.gs
function doGet(e){
var serveFile = e.parameter.servefile;
var id = e.parameter.id;
if(serveFile)
{
return downloadFile(id); // and Hyde
}
return HtmlService.createHtmlOutputFromFile('form.html'); // Jekyll
}
function fetchFromGoogleDrive() { // Jekyll
var fileslist = DriveApp.searchFiles("your search criteria goes here + and trashed = false"); // the 'and trashed = false' prevents the same file being download more than once
if (fileslist.hasNext()) {
var afile = fileslist.next();
var html = ScriptApp.getService().getUrl()+"?servefile=true&id="+afile.getId();
return html;
}
else
{
return '';
}
}
function downloadFile(id){ // and Hyde
try
{
var afile = DriveApp.getFileById(id);
var aname = afile.getName();
var acontent = afile.getAs('text/plain').getDataAsString();
var output = ContentService.createTextOutput();
output.setMimeType(ContentService.MimeType.CSV);
output.setContent(acontent);
output.downloadAsFile(aname);
afile.setTrashed(true);
return output;
}
catch (e) {
return ContentService.createTextOutput('Nothing To Download')
}
}
Как это устроено
Веб-приложение Google Drive (автономное) для автоматической загрузки (опроса) файлов с диска на локальный ПК пользователя (папка с загрузкой).
DriveApp предоставляет механизмы для поиска и загрузки файлов. Однако механизм загрузки имеет некоторые серьезные ограничения из-за архитектуры клиент-сервер, унаследованной Google Apps. (Не ошибка Google)
На стороне сервера DriveApp не предоставляется прямая функция для загрузки на локальный ПК, поскольку сервер не имеет понятия о том, где находится клиент, и загрузка файла на сервер будет бессмысленной.
На стороне сервера необходим механизм для предоставления клиентского кода файла данных или ссылки на файл. Оба этих механизма предоставляются, но данные из первого ограничены использованием кода клиента непосредственно. Клиент не имеет механизма сохранения данных после их получения на локальном ПК. Таким образом, его можно использовать для отображения данных на самой веб-странице.
Второй механизм позволяет вернуть URL-адрес скрипта (самого себя) или URL-адрес файла Drive. URL-адрес файла накопителя не очень полезен, поскольку его нельзя напрямую использовать в клиентском браузере для загрузки файла. Размещение этого url в привязке (и нажатии на него) приводит к открытию веб-страницы, но фактически ничего не делает (кроме, возможно, просмотра файла в Интернете).
Это оставляет URL-адрес скрипта. Однако скрипт url предоставляет только скрипт, а не файл.
Чтобы инициировать загрузку, файл из службы Диска должен быть возвращен из функции doGet / doPost сценария на стороне сервера, используя ContentService createTextOutput точно так, как показано в онлайн-руководствах Google. Однако это означает, что на веб-странице не может быть другого элемента пользовательского интерфейса, сгенерированного результатами, возвращаемыми doGet / doPost.
Это оставляет нам очень непривлекательное решение. Пустая веб-страница без пользовательских элементов пользовательского интерфейса, которая загружает страницу, закрывается и требует ручного открытия, когда требуется другая загрузка.
Очевидно, что другая веб-страница для хостинга может предоставить пользовательский интерфейс и ссылку на сценарий загрузки веб-приложения для решения этой проблемы.
Этот сценарий использует подход д-ра Джекила и г-на Хайд для решения этой проблемы.
Если скрипт открывается без параметров в GET (doGet), он по умолчанию отображает форму. Это будет условие, когда опубликованное приложение сначала открывается пользователем. Форма, представленная в этом примере, чрезвычайно проста.
Если скрипт открывается с параметром servefile = true, скрипт ведет себя как загрузка файла диска.
Javascript на стороне клиента содержит механизм опроса (таймер события SetInterval), который периодически вызывает скрипт на стороне сервера, чтобы проверить наличие другого загружаемого файла.
Когда скрипт на стороне сервера выполняется, если он находит файл диска, соответствующий критериям поиска *, он возвращает URL-адрес самого скрипта с параметрами:
? Servefile = истина & ID = the_id_of_the_google_drive_file
(* Критерии поиска в этом простом примере жестко закодированы в сценарии на стороне сервера. При необходимости он может быть легко передан от клиента на сервер.)
Эта информация возвращается в виде строки клиенту через распознанный механизмSuccessHandler.
Клиентский Java-скрипт затем обновляет HREF скрытого якоря с помощью этой возвращенной информации, а затем автоматически нажимает на якорь.
Это приводит к запуску другого вызова приложения / скрипта. Когда новый вызов приложения запускает doGet, он обнаружит параметр servefile и вместо того, чтобы возвращать пользовательский интерфейс, он вернет файл в браузер. Возвращенный файл будет идентифицирован параметром ID, который был ранее возвращен описанным выше поиском.
Учитывая, что файл с предоставленным ID все еще существует, он будет загружен, и новый вызов приложения закроется, оставив первый вызов, чтобы повторить этот процесс.
Кнопка предоставляется на простом интерфейсе, если пользователь / тестер становится нетерпеливым с ожиданием таймера, но он не требуется и в противном случае может быть удален.
Разумеется, простую форму можно расширить, чтобы обеспечить более удобный интерфейс пользователя, если это необходимо. Такие, как предоставление критериев поиска файлов.