Plugin Directory

Changeset 868957


Ignore:
Timestamp:
03/04/2014 02:55:15 AM (12 years ago)
Author:
paulgpetty
Message:

Update Dropbox Uploader script

File:
1 edited

Legend:

Unmodified
Added
Removed
  • wp-time-machine/trunk/includes/DropboxUploader.php

    r661113 r868957  
    22/**
    33 * Dropbox Uploader
    4  * 
     4 *
    55 * Copyright (c) 2009 Jaka Jancar
    6  * 
     6 *
    77 * Permission is hereby granted, free of charge, to any person obtaining a copy
    88 * of this software and associated documentation files (the "Software"), to deal
     
    1111 * copies of the Software, and to permit persons to whom the Software is
    1212 * furnished to do so, subject to the following conditions:
    13  * 
     13 *
    1414 * The above copyright notice and this permission notice shall be included in
    1515 * all copies or substantial portions of the Software.
    16  * 
     16 *
    1717 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    1818 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     
    2424 *
    2525 * @author Jaka Jancar [[email protected]] [http://jaka.kubje.org/]
    26  * @version 1.1.7
     26 * @version 1.1.12
    2727 */
    2828class DropboxUploader {
     29    /**
     30     * Certificate Authority Certificate source types
     31     */
     32    const CACERT_SOURCE_SYSTEM = 0;
     33    const CACERT_SOURCE_FILE   = 1;
     34    const CACERT_SOURCE_DIR    = 2;
     35    /**
     36     * Dropbox configuration
     37     */
     38    const DROPBOX_UPLOAD_LIMIT_IN_BYTES = 314572800;
     39    const HTTPS_DROPBOX_COM_HOME        = 'https://www.dropbox.com/home';
     40    const HTTPS_DROPBOX_COM_LOGIN       = 'https://www.dropbox.com/login';
     41    const HTTPS_DROPBOX_COM_UPLOAD      = 'https://dl-web.dropbox.com/upload';
     42    /**
     43     * DropboxUploader Error Flags and Codes
     44     */
     45    const FLAG_DROPBOX_GENERIC        = 0x10000000;
     46    const FLAG_LOCAL_FILE_IO          = 0x10010000;
     47    const CODE_FILE_READ_ERROR        = 0x10010101;
     48    const CODE_TEMP_FILE_CREATE_ERROR = 0x10010102;
     49    const CODE_TEMP_FILE_WRITE_ERROR  = 0x10010103;
     50    const FLAG_PARAMETER_INVALID      = 0x10020000;
     51    const CODE_PARAMETER_TYPE_ERROR   = 0x10020101;
     52    const CODE_FILESIZE_TOO_LARGE     = 0x10020201;
     53    const FLAG_REMOTE                 = 0x10040000;
     54    const CODE_CURL_ERROR             = 0x10040101;
     55    const CODE_LOGIN_ERROR            = 0x10040201;
     56    const CODE_UPLOAD_ERROR           = 0x10040401;
     57    const CODE_SCRAPING_FORM          = 0x10040801;
     58    const CODE_SCRAPING_LOGIN         = 0x10040802;
     59    const CODE_CURL_EXTENSION_MISSING = 0x10080101;
    2960    protected $email;
    3061    protected $password;
    3162    protected $caCertSourceType = self::CACERT_SOURCE_SYSTEM;
    32     const CACERT_SOURCE_SYSTEM = 0;
    33     const CACERT_SOURCE_FILE = 1;
    34     const CACERT_SOURCE_DIR = 2;
    3563    protected $caCertSource;
    36     protected $loggedIn = false;
     64    protected $loggedIn = FALSE;
    3765    protected $cookies = array();
    3866
     
    4169     *
    4270     * @param string $email
    43      * @param string|null $password
     71     * @param string $password
    4472     * @throws Exception
    4573     */
     
    4775        // Check requirements
    4876        if (!extension_loaded('curl'))
    49             throw new Exception('DropboxUploader requires the cURL extension.');
    50        
    51         $this->email = $email;
     77            throw new Exception('DropboxUploader requires the cURL extension.', self::CODE_CURL_EXTENSION_MISSING);
     78
     79        if (empty($email) || empty($password)) {
     80            throw new Exception((empty($email) ? 'Email' : 'Password') . ' must not be empty.', self::CODE_PARAMETER_TYPE_ERROR);
     81        }
     82
     83        $this->email    = $email;
    5284        $this->password = $password;
    5385    }
    54    
    55     public function setCaCertificateFile($file)
    56     {
     86
     87    public function setCaCertificateDir($dir) {
     88        $this->caCertSourceType = self::CACERT_SOURCE_DIR;
     89        $this->caCertSource     = $dir;
     90    }
     91
     92    public function setCaCertificateFile($file) {
    5793        $this->caCertSourceType = self::CACERT_SOURCE_FILE;
    58         $this->caCertSource = $file;
    59     }
    60    
    61     public function setCaCertificateDir($dir)
    62     {
    63         $this->caCertSourceType = self::CACERT_SOURCE_DIR;
    64         $this->caCertSource = $dir;
    65     }
    66 
    67     public function upload($source, $remoteDir='/', $remoteName=null) {
     94        $this->caCertSource     = $file;
     95    }
     96
     97    public function upload($source, $remoteDir = '/', $remoteName = NULL) {
    6898        if (!is_file($source) or !is_readable($source))
    69             throw new Exception("File '$source' does not exist or is not readable.");
     99            throw new Exception("File '$source' does not exist or is not readable.", self::CODE_FILE_READ_ERROR);
     100
     101        $filesize = filesize($source);
     102        if ($filesize < 0 or $filesize > self::DROPBOX_UPLOAD_LIMIT_IN_BYTES) {
     103            throw new Exception("File '$source' too large ($filesize bytes).", self::CODE_FILESIZE_TOO_LARGE);
     104        }
    70105
    71106        if (!is_string($remoteDir))
    72             throw new Exception("Remote directory must be a string, is ".gettype($remoteDir)." instead.");
     107            throw new Exception("Remote directory must be a string, is " . gettype($remoteDir) . " instead.", self::CODE_PARAMETER_TYPE_ERROR);
    73108
    74109        if (is_null($remoteName)) {
    75110            # intentionally left blank
    76111        } else if (!is_string($remoteName)) {
    77             throw new Exception("Remote filename must be a string, is ".gettype($remoteDir)." instead.");
     112            throw new Exception("Remote filename must be a string, is " . gettype($remoteDir) . " instead.", self::CODE_PARAMETER_TYPE_ERROR);
    78113        } else {
    79             $source .= ';filename='.$remoteName;
     114            $source .= ';filename=' . $remoteName;
    80115        }
    81116
    82117        if (!$this->loggedIn)
    83118            $this->login();
    84        
    85         $data = $this->request('https://www.dropbox.com/home');
    86         $token = $this->extractToken($data, 'https://dl-web.dropbox.com/upload');
    87 
    88 
    89         $postData = array('plain'=>'yes', 'file'=>'@'.$source, 'dest'=>$remoteDir, 't'=>$token);
    90         $data = $this->request('https://dl-web.dropbox.com/upload', true, $postData);
    91         if (strpos($data, 'HTTP/1.1 302 FOUND') === false)
    92             throw new Exception('Upload failed!');
    93     }
    94    
     119
     120        $data  = $this->request(self::HTTPS_DROPBOX_COM_HOME);
     121        $token = $this->extractToken($data, self::HTTPS_DROPBOX_COM_UPLOAD);
     122
     123        $postData = array(
     124            'plain' => 'yes',
     125            'file'  => '@' . $source,
     126            'dest'  => $remoteDir,
     127            't'     => $token
     128        );
     129        $data     = $this->request(self::HTTPS_DROPBOX_COM_UPLOAD, $postData);
     130        if (strpos($data, 'HTTP/1.1 302 FOUND') === FALSE)
     131            throw new Exception('Upload failed!', self::CODE_UPLOAD_ERROR);
     132    }
     133
     134    public function uploadString($string, $remoteName, $remoteDir = '/') {
     135        $exception = NULL;
     136
     137        $file = tempnam(sys_get_temp_dir(), 'DBUploadString');
     138        if (!is_file($file))
     139            throw new Exception("Can not create temporary file.", self::CODE_TEMP_FILE_CREATE_ERROR);
     140
     141        $bytes = file_put_contents($file, $string);
     142        if ($bytes === FALSE) {
     143            unlink($file);
     144            throw new Exception("Can not write to temporary file '$file'.", self::CODE_TEMP_FILE_WRITE_ERROR);
     145        }
     146
     147        try {
     148            $this->upload($file, $remoteDir, $remoteName);
     149        } catch (Exception $exception) {
     150            # intentionally left blank
     151        }
     152
     153        unlink($file);
     154
     155        if ($exception)
     156            throw $exception;
     157    }
     158
    95159    protected function login() {
    96         $data = $this->request('https://www.dropbox.com/login');
     160        $data  = $this->request(self::HTTPS_DROPBOX_COM_LOGIN);
    97161        $token = $this->extractTokenFromLoginForm($data);
    98162
    99         $postData = array('login_email'=>$this->email, 'login_password'=>$this->password, 't'=>$token);
    100         $data = $this->request('https://www.dropbox.com/login', true, $postData);
    101 
    102         if (stripos($data, 'location: /home') === false)
    103             throw new Exception('Login unsuccessful.');
    104        
    105         $this->loggedIn = true;
    106     }
    107 
    108     protected function request($url, $post=false, $postData=array()) {
     163        $postData = array(
     164            'login_email'    => (string) $this->email,
     165            'login_password' => (string) $this->password,
     166            't'              => $token
     167        );
     168        $data     = $this->request(self::HTTPS_DROPBOX_COM_LOGIN, http_build_query($postData));
     169
     170        if (stripos($data, 'location: /home') === FALSE)
     171            throw new Exception('Login unsuccessful.', self::CODE_LOGIN_ERROR);
     172
     173        $this->loggedIn = TRUE;
     174    }
     175
     176    protected function request($url, $postData = NULL) {
    109177        $ch = curl_init();
    110         curl_setopt($ch, CURLOPT_URL, $url);
     178        curl_setopt($ch, CURLOPT_URL, (string) $url);
    111179        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
    112         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
     180        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
    113181        switch ($this->caCertSourceType) {
    114182            case self::CACERT_SOURCE_FILE:
    115                 curl_setopt($ch, CURLOPT_CAINFO, $this->caCertSource);
     183                curl_setopt($ch, CURLOPT_CAINFO, (string) $this->caCertSource);
    116184                break;
    117185            case self::CACERT_SOURCE_DIR:
    118                 curl_setopt($ch, CURLOPT_CAPATH, $this->caCertSource);
     186                curl_setopt($ch, CURLOPT_CAPATH, (string) $this->caCertSource);
    119187                break;
    120188        }
    121         curl_setopt($ch, CURLOPT_HEADER, 1);
    122         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    123         if ($post) {
    124             curl_setopt($ch, CURLOPT_POST, $post);
     189        curl_setopt($ch, CURLOPT_HEADER, TRUE);
     190        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
     191        if (NULL !== $postData) {
     192            curl_setopt($ch, CURLOPT_POST, TRUE);
    125193            curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
    126194        }
    127        
     195
    128196        // Send cookies
    129197        $rawCookies = array();
    130         foreach ($this->cookies as $k=>$v)
     198        foreach ($this->cookies as $k => $v)
    131199            $rawCookies[] = "$k=$v";
    132200        $rawCookies = implode(';', $rawCookies);
    133201        curl_setopt($ch, CURLOPT_COOKIE, $rawCookies);
    134        
    135         $data = curl_exec($ch);
    136        
    137         if ($data === false) {
    138             throw new Exception(sprintf('Curl error: (#%d) %s', curl_errno($ch), curl_error($ch)));
    139         }
    140        
     202
     203        $data  = curl_exec($ch);
     204        $error = sprintf('Curl error: (#%d) %s', curl_errno($ch), curl_error($ch));
     205        curl_close($ch);
     206
     207        if ($data === FALSE) {
     208            throw new Exception($error, self::CODE_CURL_ERROR);
     209        }
     210
    141211        // Store received cookies
    142212        preg_match_all('/Set-Cookie: ([^=]+)=(.*?);/i', $data, $matches, PREG_SET_ORDER);
    143213        foreach ($matches as $match)
    144214            $this->cookies[$match[1]] = $match[2];
    145        
    146         curl_close($ch);
    147        
     215
    148216        return $data;
     217    }
     218
     219    protected function extractToken($html, $formAction) {
     220        $quot    = preg_quote($formAction, '/');
     221        $pattern = '/<form [^>]*' . $quot . '[^>]*>.*?(?:<input [^>]*name="t" [^>]*value="(.*?)"[^>]*>).*?<\/form>/is';
     222        if (!preg_match($pattern, $html, $matches))
     223            throw new Exception("Cannot extract token! (form action is '$formAction')", self::CODE_SCRAPING_FORM);
     224        return $matches[1];
    149225    }
    150226
     
    152228        // <input type="hidden" name="t" value="UJygzfv9DLLCS-is7cLwgG7z" />
    153229        if (!preg_match('#<input type="hidden" name="t" value="([A-Za-z0-9_-]+)" />#', $html, $matches))
    154             throw new Exception('Cannot extract login CSRF token.');
     230            throw new Exception('Cannot extract login CSRF token.', self::CODE_SCRAPING_LOGIN);
    155231        return $matches[1];
    156232    }
    157233
    158     protected function extractToken($html, $formAction) {
    159         if (!preg_match('/<form [^>]*'.preg_quote($formAction, '/').'[^>]*>.*?(<input [^>]*name="t" [^>]*value="(.*?)"[^>]*>).*?<\/form>/is', $html, $matches) || !isset($matches[2]))
    160             throw new Exception("Cannot extract token! (form action=$formAction)");
    161         return $matches[2];
    162     }
    163 
    164234}
Note: See TracChangeset for help on using the changeset viewer.