mirror of
https://github.com/HaschekSolutions/pictshare.git
synced 2025-11-19 06:28:01 +00:00
added support for backblaze buckets for scalability. closes #49
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
test.php
|
||||||
275
classes/backblaze.php
Normal file
275
classes/backblaze.php
Normal file
@@ -0,0 +1,275 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Backblaze B2 wrapper without external depenecies
|
||||||
|
*
|
||||||
|
* @author Christian Haschek <christian@haschek.at>
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Backblaze
|
||||||
|
{
|
||||||
|
private $token;
|
||||||
|
private $apiURL;
|
||||||
|
private $bucket;
|
||||||
|
private $dlURL;
|
||||||
|
private $ulURL;
|
||||||
|
private $ulToken;
|
||||||
|
private $bucket_name;
|
||||||
|
private $files;
|
||||||
|
|
||||||
|
function __construct()
|
||||||
|
{
|
||||||
|
if( BACKBLAZE !== true || !defined('BACKBLAZE_ID') || !defined('BACKBLAZE_KEY') || !defined('BACKBLAZE_BUCKET_ID'))
|
||||||
|
return;
|
||||||
|
$this->authorize();
|
||||||
|
$this->bucket = BACKBLAZE_BUCKET_ID;
|
||||||
|
$this->bucket_name = (( defined('BACKBLAZE_BUCKET_NAME') && BACKBLAZE_BUCKET_NAME != "")?BACKBLAZE_BUCKET_NAME:$this->bucketIdToName($bucket));
|
||||||
|
}
|
||||||
|
|
||||||
|
function authorize()
|
||||||
|
{
|
||||||
|
$account_id = BACKBLAZE_ID; // Obtained from your B2 account page
|
||||||
|
$application_key = BACKBLAZE_KEY; // Obtained from your B2 account page
|
||||||
|
$credentials = base64_encode($account_id . ":" . $application_key);
|
||||||
|
$url = "https://api.backblazeb2.com/b2api/v1/b2_authorize_account";
|
||||||
|
|
||||||
|
$session = curl_init($url);
|
||||||
|
|
||||||
|
// Add headers
|
||||||
|
$headers = array();
|
||||||
|
$headers[] = "Accept: application/json";
|
||||||
|
$headers[] = "Authorization: Basic " . $credentials;
|
||||||
|
curl_setopt($session, CURLOPT_HTTPHEADER, $headers); // Add headers
|
||||||
|
|
||||||
|
curl_setopt($session, CURLOPT_HTTPGET, true); // HTTP GET
|
||||||
|
curl_setopt($session, CURLOPT_RETURNTRANSFER, true); // Receive server response
|
||||||
|
$server_output = curl_exec($session);
|
||||||
|
curl_close ($session);
|
||||||
|
$data = json_decode($server_output,true);
|
||||||
|
|
||||||
|
$this->token = $data['authorizationToken'];
|
||||||
|
$this->apiURL = $data['apiUrl'];
|
||||||
|
$this->dlURL = $data['downloadUrl'];
|
||||||
|
}
|
||||||
|
|
||||||
|
function upload($hash)
|
||||||
|
{
|
||||||
|
if(!$this->ulURL)
|
||||||
|
$this->getUploadInfo();
|
||||||
|
$file_name = $hash;
|
||||||
|
$my_file = ROOT.DS.'upload'.DS.$hash.DS.$hash;
|
||||||
|
$handle = fopen($my_file, 'r');
|
||||||
|
$read_file = fread($handle,filesize($my_file));
|
||||||
|
|
||||||
|
$upload_url = $this->ulURL; // Provided by b2_get_upload_url
|
||||||
|
$upload_auth_token = $this->ulToken; // Provided by b2_get_upload_url
|
||||||
|
$bucket_id = $this->bucket; // The ID of the bucket
|
||||||
|
$content_type = "text/plain";
|
||||||
|
$sha1_of_file_data = sha1_file($my_file);
|
||||||
|
|
||||||
|
$session = curl_init($upload_url);
|
||||||
|
|
||||||
|
// Add read file as post field
|
||||||
|
curl_setopt($session, CURLOPT_POSTFIELDS, $read_file);
|
||||||
|
|
||||||
|
// Add headers
|
||||||
|
$headers = array();
|
||||||
|
$headers[] = "Authorization: " . $upload_auth_token;
|
||||||
|
$headers[] = "X-Bz-File-Name: " . $file_name;
|
||||||
|
$headers[] = "Content-Type: " . $content_type;
|
||||||
|
$headers[] = "X-Bz-Content-Sha1: " . $sha1_of_file_data;
|
||||||
|
curl_setopt($session, CURLOPT_HTTPHEADER, $headers);
|
||||||
|
|
||||||
|
curl_setopt($session, CURLOPT_POST, true); // HTTP POST
|
||||||
|
curl_setopt($session, CURLOPT_RETURNTRANSFER, true); // Receive server response
|
||||||
|
$server_output = curl_exec($session); // Let's do this!
|
||||||
|
curl_close ($session); // Clean up
|
||||||
|
//var_dump($server_output); // Tell me about the rabbits, George!
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUploadInfo()
|
||||||
|
{
|
||||||
|
$api_url = $this->apiURL; // From b2_authorize_account call
|
||||||
|
$auth_token = $this->token; // From b2_authorize_account call
|
||||||
|
$bucket_id = $this->bucket; // The ID of the bucket you want to upload to
|
||||||
|
|
||||||
|
$session = curl_init($api_url . "/b2api/v1/b2_get_upload_url");
|
||||||
|
|
||||||
|
// Add post fields
|
||||||
|
$data = array("bucketId" => $bucket_id);
|
||||||
|
$post_fields = json_encode($data);
|
||||||
|
curl_setopt($session, CURLOPT_POSTFIELDS, $post_fields);
|
||||||
|
|
||||||
|
// Add headers
|
||||||
|
$headers = array();
|
||||||
|
$headers[] = "Authorization: " . $auth_token;
|
||||||
|
curl_setopt($session, CURLOPT_HTTPHEADER, $headers);
|
||||||
|
|
||||||
|
curl_setopt($session, CURLOPT_POST, true); // HTTP POST
|
||||||
|
curl_setopt($session, CURLOPT_RETURNTRANSFER, true); // Receive server response
|
||||||
|
$server_output = curl_exec($session); // Let's do this!
|
||||||
|
curl_close ($session); // Clean up
|
||||||
|
$data = json_decode($server_output,true); // Tell me about the rabbits, George!
|
||||||
|
$this->ulURL = $data['uploadUrl'];
|
||||||
|
$this->ulToken = $data['authorizationToken'];
|
||||||
|
}
|
||||||
|
|
||||||
|
function download($hash)
|
||||||
|
{
|
||||||
|
if(file_exists(ROOT.DS.'upload'.DS.$hash.DS.$hash)) return false;
|
||||||
|
$download_url = $this->dlURL; // From b2_authorize_account call
|
||||||
|
$bucket_name = $this->bucket_name; // The NAME of the bucket you want to download from
|
||||||
|
$file_name = $hash; // The name of the file you want to download
|
||||||
|
$auth_token = $this->token; // From b2_authorize_account call
|
||||||
|
$uri = $download_url . "/file/" . $bucket_name . "/" . $file_name;
|
||||||
|
|
||||||
|
$session = curl_init($uri);
|
||||||
|
|
||||||
|
// Add headers
|
||||||
|
$headers = array();
|
||||||
|
$headers[] = "Authorization: " . $auth_token;
|
||||||
|
curl_setopt($session, CURLOPT_HTTPHEADER, $headers);
|
||||||
|
|
||||||
|
curl_setopt($session, CURLOPT_HTTPGET, true); // HTTP POST
|
||||||
|
curl_setopt($session, CURLOPT_RETURNTRANSFER, true); // Receive server response
|
||||||
|
$server_output = curl_exec($session); // Let's do this!
|
||||||
|
curl_close ($session); // Clean up
|
||||||
|
$is_binary = preg_match('~[^\x20-\x7E\t\r\n]~', $server_output); // Tell me about the rabbits, George!
|
||||||
|
if(!$is_binary) return false;
|
||||||
|
|
||||||
|
mkdir(ROOT.DS.'upload'.DS.$hash);
|
||||||
|
$file = ROOT.DS.'upload'.DS.$hash.DS.$hash;
|
||||||
|
|
||||||
|
file_put_contents($file, $server_output);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function bucketIdToName($bucket)
|
||||||
|
{
|
||||||
|
$api_url = $this->apiURL; // From b2_authorize_account call
|
||||||
|
$auth_token = $this->token; // From b2_authorize_account call
|
||||||
|
$account_id = BACKBLAZE_ID;
|
||||||
|
|
||||||
|
$session = curl_init($api_url . "/b2api/v1/b2_list_buckets");
|
||||||
|
|
||||||
|
// Add post fields
|
||||||
|
$data = array("accountId" => $account_id);
|
||||||
|
$post_fields = json_encode($data);
|
||||||
|
curl_setopt($session, CURLOPT_POSTFIELDS, $post_fields);
|
||||||
|
|
||||||
|
// Add headers
|
||||||
|
$headers = array();
|
||||||
|
$headers[] = "Authorization: " . $auth_token;
|
||||||
|
curl_setopt($session, CURLOPT_HTTPHEADER, $headers);
|
||||||
|
|
||||||
|
curl_setopt($session, CURLOPT_POST, true); // HTTP POST
|
||||||
|
curl_setopt($session, CURLOPT_RETURNTRANSFER, true); // Receive server response
|
||||||
|
$server_output = curl_exec($session); // Let's do this!
|
||||||
|
curl_close ($session); // Clean up
|
||||||
|
$data = json_decode($server_output,true); // Tell me about the rabbits, George!
|
||||||
|
if(is_array($data))
|
||||||
|
foreach($data['buckets'] as $bucket)
|
||||||
|
{
|
||||||
|
if($bucket['bucketId']==$this->bucket) return $bucket['bucketName'];
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteFile($hash,$file_id=false)
|
||||||
|
{
|
||||||
|
$api_url = $this->apiURL; // From b2_authorize_account call
|
||||||
|
$auth_token = $this->token; // From b2_authorize_account call
|
||||||
|
$file_name = $hash; // The file name of the file you want to delete
|
||||||
|
if(!$file_id)
|
||||||
|
$file_id = $this->fileExistsInBucket($hash);
|
||||||
|
|
||||||
|
$session = curl_init($api_url . "/b2api/v1/b2_delete_file_version");
|
||||||
|
|
||||||
|
// Add post fields
|
||||||
|
$data = array("fileId" => $file_id, "fileName" => $file_name);
|
||||||
|
$post_fields = json_encode($data);
|
||||||
|
curl_setopt($session, CURLOPT_POSTFIELDS, $post_fields);
|
||||||
|
|
||||||
|
// Add headers
|
||||||
|
$headers = array();
|
||||||
|
$headers[] = "Authorization: " . $auth_token;
|
||||||
|
curl_setopt($session, CURLOPT_HTTPHEADER, $headers);
|
||||||
|
|
||||||
|
curl_setopt($session, CURLOPT_POST, true); // HTTP POST
|
||||||
|
curl_setopt($session, CURLOPT_RETURNTRANSFER, true); // Receive server response
|
||||||
|
$server_output = curl_exec($session); // Let's do this!
|
||||||
|
curl_close ($session); // Clean up
|
||||||
|
}
|
||||||
|
|
||||||
|
function fileExistsInBucket($hash)
|
||||||
|
{
|
||||||
|
$api_url = $this->apiURL; // From b2_authorize_account call
|
||||||
|
$auth_token = $this->token; // From b2_authorize_account call
|
||||||
|
$bucket_id = $this->bucket; // The ID of the bucket
|
||||||
|
|
||||||
|
$session = curl_init($api_url . "/b2api/v1/b2_list_file_names");
|
||||||
|
|
||||||
|
// Add post fields
|
||||||
|
$data = array("bucketId" => $bucket_id,
|
||||||
|
"startFileName" => $hash);
|
||||||
|
$post_fields = json_encode($data);
|
||||||
|
curl_setopt($session, CURLOPT_POSTFIELDS, $post_fields);
|
||||||
|
|
||||||
|
// Add headers
|
||||||
|
$headers = array();
|
||||||
|
$headers[] = "Authorization: " . $auth_token;
|
||||||
|
curl_setopt($session, CURLOPT_HTTPHEADER, $headers);
|
||||||
|
|
||||||
|
curl_setopt($session, CURLOPT_POST, true); // HTTP POST
|
||||||
|
curl_setopt($session, CURLOPT_RETURNTRANSFER, true); // Receive server response
|
||||||
|
$server_output = curl_exec($session); // Let's do this!
|
||||||
|
curl_close ($session); // Clean up
|
||||||
|
$data = json_decode($server_output,true);
|
||||||
|
|
||||||
|
foreach($data['files'] as $file)
|
||||||
|
{
|
||||||
|
//it's either the first one or it doesn't exist
|
||||||
|
if($file['fileName']==$hash)
|
||||||
|
return $file['fileId'];
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAllFilesInBucket($startFileName=null)
|
||||||
|
{
|
||||||
|
$api_url = $this->apiURL; // From b2_authorize_account call
|
||||||
|
$auth_token = $this->token; // From b2_authorize_account call
|
||||||
|
$bucket_id = $this->bucket; // The ID of the bucket
|
||||||
|
|
||||||
|
$session = curl_init($api_url . "/b2api/v1/b2_list_file_names");
|
||||||
|
|
||||||
|
// Add post fields
|
||||||
|
$data = array("bucketId" => $bucket_id,
|
||||||
|
"startFileName" => $startFileName);
|
||||||
|
$post_fields = json_encode($data);
|
||||||
|
curl_setopt($session, CURLOPT_POSTFIELDS, $post_fields);
|
||||||
|
|
||||||
|
// Add headers
|
||||||
|
$headers = array();
|
||||||
|
$headers[] = "Authorization: " . $auth_token;
|
||||||
|
curl_setopt($session, CURLOPT_HTTPHEADER, $headers);
|
||||||
|
|
||||||
|
curl_setopt($session, CURLOPT_POST, true); // HTTP POST
|
||||||
|
curl_setopt($session, CURLOPT_RETURNTRANSFER, true); // Receive server response
|
||||||
|
$server_output = curl_exec($session); // Let's do this!
|
||||||
|
curl_close ($session); // Clean up
|
||||||
|
$data = json_decode($server_output,true);
|
||||||
|
|
||||||
|
foreach($data['files'] as $file)
|
||||||
|
{
|
||||||
|
$name = $file['fileName'];
|
||||||
|
$id = $file['fileId'];
|
||||||
|
$this->files[$name] = $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($data['nextFileName'])
|
||||||
|
$this->getAllFilesInBucket($data['nextFileName']);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -72,3 +72,15 @@ define('FORCE_DOMAIN', false);
|
|||||||
//Shall errors be displayed to the user?
|
//Shall errors be displayed to the user?
|
||||||
//For dev environments: true, in production: false
|
//For dev environments: true, in production: false
|
||||||
define('SHOW_ERRORS', false);
|
define('SHOW_ERRORS', false);
|
||||||
|
|
||||||
|
|
||||||
|
//for scalability reasons you might want to upload images to cloud providers
|
||||||
|
//remove comments to use
|
||||||
|
|
||||||
|
/* BACKBLAZE B2 */
|
||||||
|
/* You can find your info here: https://secure.backblaze.com/b2_buckets.htm */
|
||||||
|
//define('BACKBLAZE',true); //true=>use backblaze to upload images, false=>don't
|
||||||
|
//define('BACKBLAZE_ID','');
|
||||||
|
//define('BACKBLAZE_KEY', '');
|
||||||
|
//define('BACKBLAZE_BUCKET_ID', '');
|
||||||
|
//define('BACKBLAZE_BUCKET_NAME', '');
|
||||||
@@ -60,6 +60,15 @@ class PictshareModel extends Model
|
|||||||
return array('status'=>'ERR','Reason'=>'Image not found');
|
return array('status'=>'ERR','Reason'=>'Image not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function couldThisBeAnImage($string)
|
||||||
|
{
|
||||||
|
$len = strlen($string);
|
||||||
|
$dot = strpos($string,'.');
|
||||||
|
if(!$dot) return false;
|
||||||
|
if($dot<=10 && ( ($len-$dot) == 4 || ($len-$dot) == 5 ) )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function urlToData($url)
|
function urlToData($url)
|
||||||
{
|
{
|
||||||
$html = new HTML;
|
$html = new HTML;
|
||||||
@@ -75,7 +84,7 @@ class PictshareModel extends Model
|
|||||||
|
|
||||||
if($this->isImage($el))
|
if($this->isImage($el))
|
||||||
{
|
{
|
||||||
//if there are mor than one hashes in url
|
//if there are more than one hashes in url
|
||||||
//make an album from them
|
//make an album from them
|
||||||
if($data['hash'])
|
if($data['hash'])
|
||||||
{
|
{
|
||||||
@@ -85,6 +94,12 @@ class PictshareModel extends Model
|
|||||||
}
|
}
|
||||||
$data['hash']=$el;
|
$data['hash']=$el;
|
||||||
}
|
}
|
||||||
|
else if(BACKBLAZE === true && $this->couldThisBeAnImage($el)) //looks like it might be a hash but didn't find it here. Let's see
|
||||||
|
{
|
||||||
|
$b = new Backblaze();
|
||||||
|
if($b->download($el)) //if the backblaze download function says it's an image, we'll take it
|
||||||
|
$data['hash'] = $el;
|
||||||
|
}
|
||||||
else if($el=='mp4' || $el=='raw' || $el=='preview' || $el=='webm' || $el=='ogg')
|
else if($el=='mp4' || $el=='raw' || $el=='preview' || $el=='webm' || $el=='ogg')
|
||||||
$data[$el] = 1;
|
$data[$el] = 1;
|
||||||
else if($this->isSize($el))
|
else if($this->isSize($el))
|
||||||
@@ -196,6 +211,14 @@ class PictshareModel extends Model
|
|||||||
|
|
||||||
rmdir($base_path);
|
rmdir($base_path);
|
||||||
|
|
||||||
|
//delete from backblaze if configured
|
||||||
|
if(BACKBLAZE===true)
|
||||||
|
{
|
||||||
|
$b = new Backblaze();
|
||||||
|
$b->deleteFile($hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -466,6 +489,12 @@ class PictshareModel extends Model
|
|||||||
fclose($fh);
|
fclose($fh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(BACKBLAZE===true)
|
||||||
|
{
|
||||||
|
$b = new Backblaze();
|
||||||
|
$b->upload($hash);
|
||||||
|
}
|
||||||
|
|
||||||
return array('status'=>'OK','type'=>$type,'hash'=>$hash,'url'=>DOMAINPATH.PATH.$hash,'domain'=>DOMAINPATH,'deletecode'=>$this->generateDeleteCodeForImage($hash));
|
return array('status'=>'OK','type'=>$type,'hash'=>$hash,'url'=>DOMAINPATH.PATH.$hash,'domain'=>DOMAINPATH,'deletecode'=>$this->generateDeleteCodeForImage($hash));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user