Zoeken…


Invoering

Met dit eenvoudige Google App Web Script (Standalone) kan Google Drive herhaaldelijk worden opgevraagd om bestanden te downloaden naar de lokale pc van de gebruiker. Laat zien hoe u één app-script gebruikt om de functie van zowel de volgende te bieden: 1. Gebruikersinterface (een eenvoudige in dit voorbeeld) 2. De downloadpagina voor bestanden. Lees het voorbeeld "Hoe het werkt" voor een uitgebreidere uitleg over hoe het werkt.

Opmerkingen

Het webscript moet worden gepubliceerd om te kunnen werken.

Pop-ups moeten zijn ingeschakeld voor https://script.google.com

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')
  }
}

Hoe het werkt

Google Drive (Standalone) Web-app om bestanden automatisch te downloaden (Poll) van Drive naar de lokale pc van de gebruiker (downloadmap).

DriveApp biedt mechanismen voor het zoeken en downloaden van bestanden. Het downloadmechanisme heeft echter enkele ernstige beperkingen vanwege de client / server-architectuur die Google Apps heeft geërfd. (Geen fout van Google)

DriveApp aan de serverzijde biedt geen directe functie om te downloaden naar de lokale pc omdat de server geen idee heeft waar de client zich bevindt en het downloaden van het bestand naar de server zelf zinloos zou zijn.

De server-side code heeft een mechanisme nodig om de client-side code de bestandsgegevens of een link naar het bestand te bieden. Beide mechanismen worden geboden, maar de gegevens van de eerste zijn beperkt tot het direct gebruiken door de client-side code. De client heeft geen mechanisme om de gegevens, eenmaal verkregen, op de lokale pc op te slaan. Het kan dus worden gebruikt om de gegevens op de webpagina zelf weer te geven.

Met het tweede mechanisme kan de url van het script (zelf) of de url van het Drive-bestand worden doorgegeven. De Drive-bestands-URL is niet erg handig omdat deze niet direct in de clientbrowser kan worden gebruikt om het bestand te downloaden. Het plaatsen van deze url in het anker (en erop klikken) resulteert alleen in een webpagina die wordt geopend maar eigenlijk niets doet (behalve mogelijk het bestand online bekijken).

Dat laat de script-url achter. De script-URL biedt echter alleen het script en niet het bestand.

Om een download te starten, moet het bestand van de Drive-service worden geretourneerd vanuit de doGet / doPost-functie van het server-side script met ContentService createTextOutput, precies zoals weergegeven in de online handleidingen van Google. Dit betekent echter dat er geen ander UI-element op de webpagina kan worden gegenereerd door de resultaten die worden geretourneerd door doGet / doPost.

Dit laat ons met een zeer onaantrekkelijke oplossing. Een lege webpagina zonder gebruikersinterface-elementen die een pagina downloadt, wordt gesloten en dat handmatig moet worden geopend wanneer een nieuwe download is vereist.

Uiteraard kan een andere hostingwebpagina de gebruikersinterface en de link naar het download-script voor de web-app bieden om dit probleem op te lossen.

Dit script gebruikt een Dr. Jekyll en Mr Hyde-aanpak om dit probleem op te lossen.

Als het script wordt geopend zonder parameters voor de GET (doGet), wordt standaard een formulier weergegeven. Dit is de voorwaarde wanneer de gepubliceerde app voor het eerst wordt geopend door een gebruiker. Het formulier in dit voorbeeld is uiterst eenvoudig.

Als het script wordt geopend met de parameter servefile = true, gedraagt het script zich als een Drive-bestandsdownload.

Het client-side javascript bevat een polling-mechanisme (event timer setInterval) dat periodiek het server-side script oproept om te controleren of er een ander bestand beschikbaar is om te downloaden.

Wanneer het server-side script wordt uitgevoerd en een Drive-bestand vindt dat overeenkomt met de zoekcriteria *, retourneert het de url van het script zelf, toegevoegd met de parameters:

? Servefile = true & id = the_id_of_the_google_drive_file

(* De zoekcriteria in dit eenvoudige voorbeeld zijn hard gecodeerd in het server-side script. Het kan indien nodig eenvoudig van de client naar de server worden doorgegeven.)

Deze informatie wordt als een string naar de client geretourneerd via het erkende withSuccessHandler-mechanisme.

Het client-java-script werkt vervolgens de HREF van een verborgen anker bij met deze geretourneerde informatie en klikt vervolgens automatisch op het anker.

Hierdoor wordt een nieuwe aanroep van de app / het script gestart. Wanneer de nieuwe aanroep van de app wordt gestart, detecteert de doGet de parameter servefile en in plaats van de gebruikersinterface terug te sturen, wordt het bestand teruggestuurd naar de browser. Het geretourneerde bestand is het bestand dat wordt geïdentificeerd door de opgegeven ID-parameter die eerder is geretourneerd door de hierboven beschreven zoekopdracht.

Aangezien het bestand met de opgegeven ID nog steeds bestaat, wordt het gedownload en wordt de nieuwe aanroep van de app afgesloten, waardoor de eerste aanroep wordt overgedaan om dit proces te herhalen.

Op de eenvoudige interface is een knop beschikbaar als de gebruiker / tester ongeduldig wordt bij het wachten op de timer, maar dit is niet vereist en kan anders worden verwijderd.

De eenvoudige vorm kan natuurlijk worden uitgebreid om indien nodig een rijkere gebruikersinterface te bieden. Zoals het verstrekken van de zoekcriteria voor bestanden.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow