La API de Dropbox

De wikijoan
Salta a la navegació Salta a la cerca

Introducció

Avui en dia és habitual fer còpies de seguretat al núvol i compartir la informació. Per exemple, serveis al núvol que ofereixen força espai de disc al núvol de forma gratuïta:

Volem accedir al Dropbox des de la seva API. És a dir, volem programar scripts per accedir al Dropbox (típicament: pujar fitxers, descarregar fitxers, llistar contingut de carpetes). El primer de tot, tenir un compte de dropbox. Si no el tens, ara és el moment de fer-ho.

API de Dropbox. PHP

Hem de registrar una aplicació a la App Console. Necessitarem la app key per accedir a la Core API. Després haurem d'instal.lar el SDK per al llenguatge seleccionat (en el nostre cas, PHP SDK).

Hem de crear una nova aplicació:

I contestar les preguntes que ens van fent:

  • Escollim una Dropbox API app.
  • What type of data does your app need to store on Dropbox?

Escollim Files and datastores

  • Can your app be limited to its own folder?

No My app needs access to files already on Dropbox.

  • What type of files does your app need access to?

Specific file types My app only needs access to certain file types, like text or photos.

Farem que la nostra aplicació només tingui accés a fitxers de text.

  • Last question, what type of files will your app use?

Text files TXT, Markdown, Code files, HTML, etc.

  • Provide an app name, and you're on your way.

prova1_api (escull el nom de la app que creguis convenient)

I ara ja tenim la url de la nostra interface de desenvolupament d'aplicacions per a la API de Drobox. Per exemple, en el cas del professor:

Hem d'obtenir les credencials. En el cas del professor:

App key: fqih5rcf32yak2l
App secret: pyt7dcqu0cgz1l8

Generate access token: rqDdcful8VMAAAAAAAAAPqRyGCCjH5v5Zoju1nZhs4Do4RcYKu6FTAVmrFshzvuu

NOTA: És important el valor del access token generat, doncs és un access token comodí que farem servir després per poder executar els nostres scripts amb autenticació automatitzada.

Si anem a core API tenim tutorials i documentació per als diferents llenguatges de programació:

Podem fer scripts per als següents llenguatges:

PHP
Python
Ruby
Java
iOS
OS X
HTTP

There are also a number of third-party libraries maintained by the developer community.

I ara seguim el tutorial de PHP:

El primer que hem de fer és instal.lar el PHP SDK:

Descarreguem dropbox-sdk-php-1.1.4.zip i descomprimim. I llegim:

The SDK is contained in the lib/ folder in the zip file so copy lib/ into your project and name it dropbox-sdk/ and include it in your app:

require_once "dropbox-sdk/Dropbox/autoload.php";

Per tant, si hem llegit bé, hem de copiar la carpeta lib/ a un directori que es digui dropbox-sdk/, i aquesta carpeta estarà en l'arrel d'on tindrem els nostres scripts.

Dit d'una altra manera, la carpeta que contingui els nostres scripts PHP contindrà una carpeta que es dirà dropbox-sdk/, i aquesta carpeta té el mateix contingut que lib/

Si continuem mirant el codi, ara cal fer la configuració de l'autenticació. Canviem:

$appInfo = dbx\AppInfo::loadFromJsonFile("INSERT_PATH_TO_JSON_CONFIG_PATH");

per

$appInfo = dbx\AppInfo::loadFromJsonFile("config.json");

i en el fitxer config.json posarem les nostres credencials:

{
  "key": "INSERT_APP_KEY",
  "secret": "INSERT_SECRET"
}

En el cas del professor (no podeu utilitzar aquestes credencials):

{
  "key": "fqih5rcf32yak2l",
  "secret": "pyt7dcqu0cgz1l8"
}

Provem d'executar l'exemple: (recordem que estem en PHP en mode CLI, línia de comanda):

$ php primer_exemple_dropbox.php

al professor li dóna l'error:

The Dropbox SDK uses 64-bit integers, but it looks like we're running on a version of PHP that doesn't support 64-bit integers

Fent una petita cerca per Internet:

Just comment the following line in \lib\Dropbox\RequestUtil.php(line.no : 19)

if (strlen((string) PHP_INT_MAX) < 19) {
//    // Looks like we're running on a 32-bit build of PHP.  This could cause problems because some of the numbers
//    // we use (file sizes, quota, etc) can be larger than 32-bit ints can handle.
   throw new \Exception("The Dropbox SDK uses 64-bit integers, but it looks like we're running on a version of PHP that doesn't support 64-bit integers (PHP_INT_MAX=" . ((string) PHP_INT_MAX) . ").  Library: \"" . __FILE__ . "\"");
}

Hem de comentar la línia que llença l'excepció, en el fitxer dropbox-sdk/Dropbox/RequestUtil.php

I ara ja funcionarà:

$ php primer_exemple_dropbox.php
1. Go to: https://www.dropbox.com/1/oauth2/authorize?locale=&client_id=fqih5rcf32yak2l&response_type=code
2. Click "Allow" (you might have to log in first).
3. Copy the authorization code.
Enter the authorization code here: 

...
Array
(
    [referral_link] => https://db.tt/iSr23qcS
    [display_name] => Joan Quintana
    [uid] => 329761
    [locale] => es_ES
    [country] => ES
    [team] => 
    [quota_info] => Array
        (
            [datastores] => 0
            [shared] => 0
            [quota] => 2147483648
            [normal] => 189308719
...
Array
(
    [rev] => ce16e38000e6c76
    [thumb_exists] => 
    [path] => /working-draft.txt
    [is_dir] => 
    [client_mtime] => Fri, 20 Feb 2015 10:28:57 +0000
    [icon] => page_white_text
    [read_only] => 
    [modifier] => 
    [bytes] => 47
    [modified] => Fri, 20 Feb 2015 10:28:56 +0000
    [size] => 47 bytes
    [root] => dropbox
    [mime_type] => text/plain
    [revision] => 216100408
)

Si hem mirat amb deteniment l'exemple que estem executant, fa tres coses:

  • puja un fitxer.
  • llista el contingut de la nostra arrel del Dropbox (/)
  • descarrega un fitxer (de fet copia el contingut d'un fitxer en un altre que prèviament ha d'existir en el nostre ordinador local)

Ara podem anar al Dropbox i veure que efectivament hem pujat el fitxer

Posem aquí una altra vegada el contingut del script primer_exemple_dropbox.php:

<?php

# Include the Dropbox SDK libraries
require_once "dropbox-sdk/Dropbox/autoload.php";
use \Dropbox as dbx;

$appInfo = dbx\AppInfo::loadFromJsonFile("config.json");
$webAuth = new dbx\WebAuthNoRedirect($appInfo, "PHP-Example/1.0");

$authorizeUrl = $webAuth->start();

echo "1. Go to: " . $authorizeUrl . "\n";
echo "2. Click \"Allow\" (you might have to log in first).\n";
echo "3. Copy the authorization code.\n";
$authCode = \trim(\readline("Enter the authorization code here: "));

list($accessToken, $dropboxUserId) = $webAuth->finish($authCode);
print "Access Token: " . $accessToken . "\n";

$dbxClient = new dbx\Client($accessToken, "PHP-Example/1.0");
$accountInfo = $dbxClient->getAccountInfo();

print_r($accountInfo);

$f = fopen("working-draft.txt", "rb");
$result = $dbxClient->uploadFile("/working-draft.txt", dbx\WriteMode::add(), $f);
fclose($f);
print_r($result);

$folderMetadata = $dbxClient->getMetadataWithChildren("/");
print_r($folderMetadata);

$f = fopen("working-draft.txt", "w+b");
$fileMetadata = $dbxClient->getFile("/working-draft.txt", $f);
fclose($f);
print_r($fileMetadata);

Autenticació automàtica oauth

El procés d'autenticació anterior era molt engorrós: havíem de visitar una URL que ens proporcionava un authentication code que podem utilitzar. Si volem que aquest procés d'autenticació sigui automàtic la cosa està fàcil, només cal enrecordar-nos del authentication code que hem obtingut en generar l'aplicació, i posar-lo en el nostre codi. En el script ficarem: (fica el teu valor)

...
$accessToken = "rqDdcful8VMAAAAAAAAAUtpRna8_iipCFDWI0koOlTMqkF1pXNt4iFs_IDN4R-03";
$dbxClient = new dbx\Client($accessToken, "PHP-Example/1.0");
...

primer_exemple_dropbox_v2.php:

<?php

# Include the Dropbox SDK libraries
require_once "dropbox-sdk/Dropbox/autoload.php";
use \Dropbox as dbx;

$appInfo = dbx\AppInfo::loadFromJsonFile("config.json");
$webAuth = new dbx\WebAuthNoRedirect($appInfo, "PHP-Example/1.0");

$authorizeUrl = $webAuth->start();

$accessToken = "rqDdcful8VMAAAAAAAAAUtpRna8_iipCFDWI0koOlTMqkF1pXNt4iFs_IDN4R-03";
$dbxClient = new dbx\Client($accessToken, "PHP-Example/1.0");
$accountInfo = $dbxClient->getAccountInfo();
print_r($accountInfo);

$f = fopen("el_meu_fitxer.txt", "rb");
$result = $dbxClient->uploadFile("/Public/el_meu_fitxer.txt", dbx\WriteMode::add(), $f);
fclose($f);
print_r($result);

?>

Això és important, doncs ara podem fer scripts automàtics i cronificats. Per exemple, podem fer una còpia de bases de dades i enviar-la al Dropbox.

API de Dropbox. Python

La idea és la mateixa que amb PHP. La info està a:

Primer hem d'instal.lar el Python SDK:

Descarreguem dropbox-python-sdk-2.2.0.zip, descomprimim i instal.lem.

$ cd dropbox-python-sdk-2.2.0
$ sudo python setup.py install

Primer haurem de fer:

$ sudo apt-get install python-setuptools
$ python primer_exemple_dropbox.py
1. Go to: https://www.dropbox.com/1/oauth2/authorize?response_type=code&client_id=fqih5rcf32yak2l
2. Click "Allow" (you might have to log in first)
3. Copy the authorization code.
Enter the authorization code here:

linked account:  {u'referral_link': u'https://db.tt/iSr23qcS', u'display_name': u'Joan Quintana', u'uid': 329761, u'email_verified': True, u'locale': u'es_ES', u'country': u'ES', u'email': u'joanqc@gmail.com'
...

Script primer_exemple_dropbox.py

# Include the Dropbox SDK
import dropbox

# Get your app key and secret from the Dropbox developer website
app_key = 'INSERT_APP_KEY'
app_secret = 'INSERT_APP_SECRET'

//app_key = 'fqih5rcf32yak2l'
//app_secret = 'pyt7dcqu0cgz1l8'

flow = dropbox.client.DropboxOAuth2FlowNoRedirect(app_key, app_secret)

# Have the user sign in and authorize this token
authorize_url = flow.start()
print '1. Go to: ' + authorize_url
print '2. Click "Allow" (you might have to log in first)'
print '3. Copy the authorization code.'
code = raw_input("Enter the authorization code here: ").strip()

# This will fail if the user enters an invalid authorization code
access_token, user_id = flow.finish(code)

client = dropbox.client.DropboxClient(access_token)
print 'linked account: ', client.account_info()

f = open('working-draft.txt', 'rb')
response = client.put_file('/magnum-opus.txt', f)
print 'uploaded: ', response

folder_metadata = client.metadata('/')
print 'metadata: ', folder_metadata

f, metadata = client.get_file_and_metadata('/magnum-opus.txt')
out = open('magnum-opus.txt', 'wb')
out.write(f.read())
out.close()
print metadata

Si ens fixem bé en el codi, estem obrint el fitxer working-draft.txt en mode lectura, i pugem el seu contingut al dropbox amb el nom de magnum-opus.txt. Després llistem el contingut de l'arrel del Dropbox (/), i finalment descarreguem a l'ordinador local el fitxer magnum-opus.txt.

Script administratiu cronificat. Exemple

Logs script.jpg

Com a administradors de sistema, tenim scripts que s'executen de forma desatesa i que realitzen diferents tasques administratives. Pot ser interessant que el resultat d'aquests scripts (per ex, els log i fitxers generats) es puguin penjar al núvol. Entre d'altres, els avantatges de tenir-ho al núvol:

  • No cal preocupar-se de les còpies de seguretat.
  • És fàcil compartir els fitxers amb el nostre equip de treball.

Anem a posar un exemple sencer.

Volem executar un script administratiu que realitzarà dues tasques:

  • comprovar que la IP 192.168.0.15 estigui aixecada
  • fer un resum de l'espai del disc dur local.

El resultat d'aquest test es guardarà en un log, i s'enviarà el log al Dropbox un cop al dia.

D'una banda tenim el script bash, que farà el ping, la comanda df, i farà la crida al script php:

script script_admin.sh:

#!/bin/bash
tdate=`date +%d%m%y`
ruta=/home/joan/M09_IAW_1415/dropbox
ruta_logs=/home/joan/M09_IAW_1415/dropbox/logs

/bin/echo "Màquina 192.168.0.15:" > $ruta_logs/ping_$tdate.txt
/bin/ping -c 3 192.168.0.15 >> $ruta_logs/ping_$tdate.txt

/bin/echo >> $ruta_logs/ping_$tdate.txt
/bin/echo "Espai de disc del nostre disc dur:" >> $ruta_logs/ping_$tdate.txt
/bin/df -h >> $ruta_logs/ping_$tdate.txt

/bin/echo $ruta_logs/ping_$tdate.txt
/usr/bin/php $ruta/enviar_log_a_dropbox.php ping_$tdate.txt

exit 0

(Fixem-nos bé que hem de crear la carpeta logs/ en el nostre directori de treball, que d'altra banda és hem estat ficant els nostres scripts PHP anteriors).

El script enviar_log_a_dropbox.php està basat en les proves que hem estat fent (només interessa la part del upload), i si ens fixem bé rep un argument que és el nom del log. El log en realitat té extensió .txt, doncs això ens facilita la seva lectura des de dins del Dropbox.

<?php
//passar arguments a un script PHP:
//http://php.net/manual/en/reserved.variables.argv.php
//var_dump($argv);
$ruta = "/home/joan/M09_IAW_1415/dropbox/";
$ruta_logs = "/home/joan/M09_IAW_1415/dropbox/logs/";

//$ruta .= "/";
$fitxer_log = $argv[1];
echo $fitxer_log."\n";

# Include the Dropbox SDK libraries
require_once $ruta . "dropbox-sdk/Dropbox/autoload.php";

use \Dropbox as dbx;

$appInfo = dbx\AppInfo::loadFromJsonFile($ruta . "config.json");
$webAuth = new dbx\WebAuthNoRedirect($appInfo, "PHP-Example/1.0");

$authorizeUrl = $webAuth->start();

$accessToken = "rqDdcful8VMAAAAAAAAAUtpRna8_iipCFDWI0koOlTMqkF1pXNt4iFs_IDN4R-03";
$dbxClient = new dbx\Client($accessToken, "PHP-Example/1.0");
$accountInfo = $dbxClient->getAccountInfo();
//print_r($accountInfo);

$f = fopen($ruta_logs . $fitxer_log, "rb");
$result = $dbxClient->uploadFile("/Public/logs/$fitxer_log", dbx\WriteMode::add(), $f);
fclose($f);
print_r($result);

?>

Si executem el script hauria de funcionar (recorda posar sempre les teves dades):

$ ./script_admin.sh logs/ping_230215.txtArray
(
    [revision] => 216100435
    [bytes] => 720
    [thumb_exists] => 
    [rev] => ce16e53000e6c76
    [modified] => Mon, 23 Feb 2015 16:19:59 +0000
    [shareable] => 
    [mime_type] => text/plain
    [path] => /Public/logs/ping_230215 (2).txt
    [is_dir] => 
    [size] => 720 bytes
    [root] => dropbox
    [client_mtime] => Mon, 23 Feb 2015 16:19:59 +0000
    [icon] => page_white_text
)

I ara fiquem aquest script dins del cron. Per provar, podem fer que s'executi cada minut:

$ sudo joe /etc/crontab
*/1 * * * * root /home/joan/M09_IAW_1415/dropbox/script_admin.sh
$ sudo /etc/init.d/cron restart

NOTA. Fixem-nos bé que tant el script bash com el php tenen TOTES les rutes del fitxer absolutes. Això és important quan hem de llençar el script des del cron.

Feina per l'alumne

Els alumnes realitzaran tots els exercicis fets a classe, solucionant els possibles problemes que vagin sortint. Concretament, s'ha de realitzar el bash script (que cerca la IP i fa el df), i configurar el cron per tal de què s'executi de forma automàtica.

  • Opcional. Un cop funcioni, des del bash script es cridarà a una versió del script enviar_log_a_dropbox.php feta amb Python.
  • Opcional. També es valorarà de forma positiva millores en el script i cercar la utilitat i justificació en la feina diària dels administradors de sistema.

Entrega

Els alumnes entregaran al Schoology tots els fitxers generats. S'empaquetaran tots aquests fitxers i es pujaran al Schoology dins del termini d'entrega de la pràctica.

Recorda la normativa per entregar les pràctiques al Schoology: ASIX-M10-UF2#Normativa_d.27entrega_de_les_pr.C3.A0ctiques_al_Schoology


creat per Joan Quintana Compte, febrer 2015