Skip to content

Instantly share code, notes, and snippets.

@bcantoni
Created November 17, 2012 03:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bcantoni/4093066 to your computer and use it in GitHub Desktop.
Save bcantoni/4093066 to your computer and use it in GitHub Desktop.
PHP script for uploading files & images to blog, including image reduction through smush.it service
#!/usr/bin/php
<?php
/* pushit
Command-line script for uploading files:
* reduce image file size thru online Smush.it service
* add file signature (md5) to name for uniqueness and long expiration times
* configurable copy command to blog, Amazon S3, etc.
* configurable move original file to local archive
Usage:
./pushit file.png
Brian Cantoni
www.cantoni.org
*/
ini_set ('display_errors', 1);
error_reporting (E_ALL);
date_default_timezone_set('America/Los_Angeles');
/** configuration **/
$smushit = true; // set to false to not use smush.it service
$copyCommand = 'scp %s cantoni.org:public_html/images/%s';
$moveCommand = 'mv %s ~/Desktop/upload/archive/%s';
if (count($argv) != 2) {
print "Usage: ./pushit filename.ext\n";
exit(0);
}
$filename = $argv[1];
if (!file_exists($filename) || !is_readable($filename) || !is_writable($filename) || (strpos($filename, '.DS_Store') !== false) || (strpos($filename, ' ') !== false)) {
die ("Invalid file '$filename'\n");
}
print "Processing $filename\n";
print "Original MD5: " . fileHash($filename) . "\n";
/* if image filetype, run through smush.it service */
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
if ($smushit && ($ext == 'jpg' || $ext == 'jpeg' || $ext == 'png' || $ext == 'gif')) {
print "uploading to smush.it\n";
$img = new SmushIt($filename);
print "return from SmushIt:\n" . print_r($img,1) . "\n";
// if error other than "no savings", die
// if "no savings" error, then skip download
$getit = true;
if (strlen($img->error)>0) {
if (strpos ("No savings", $img->error) === false) {
print " " . $img->error . "\n";
die ("error running smushit: " . $img->error . "\n");
} else {
$getit = false;
}
}
if ($getit) {
print " size reduction from " . $img->size . " to " . $img->compressedSize .
" (" . $img->savings . " %)\n";
sleep(1); // wait a moment for file to be available for download
print "downloading from smush.it\n";
$tmpfile = $img->downloadFile();
print "file $tmpfile downloaded\n";
if (copy($tmpfile, $filename)) {
unlink($tmpfile);
} else {
die ("Error copying over original file\n");
}
}
}
/* add file signature, copy, then move to local archive */
$newfilename = insertBeforeExtension ($filename, fileHash($filename));
$cmd = sprintf ($copyCommand, $filename, $newfilename);
print "$cmd\n";
exec ($cmd);
$cmd = sprintf ($moveCommand, $filename, $newfilename);
print "$cmd\n";
exec ($cmd);
// simple file hash function - return last 8 chars of md5 result
function fileHash ($filename) {
$md5 = 'NA';
if (file_exists($filename)) {
$tmp = `md5 $filename`;
if (strlen($tmp) > 30) {
$md5 = substr(trim($tmp),-8);
}
}
return($md5);
}
// utility function: insert some text just before file extension
function insertBeforeExtension ($filename, $insert) {
$ext = pathinfo($filename, PATHINFO_EXTENSION);
$tmp = preg_replace("/(.*)\.$ext$/", "$1-$insert.$ext", $filename);
return($tmp);
}
// Modified SmushIt class from Tyler Hall
// https://github.com/tylerhall/smushit-php
class SmushIt
{
const SMUSH_URL = 'http://www.smushit.com/ysmush.it/ws.php?';
public $filename;
public $url;
public $compressedUrl;
public $size;
public $compressedSize;
public $savings;
public $error;
public function __construct($data = null)
{
if (!is_null($data))
{
if (preg_match('/https?:\/\//', $data) == 1)
$this->smushURL($data);
else
$this->smushFile($data);
}
}
public function smushURL($url)
{
$this->url = $url;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, self::SMUSH_URL . 'img=' . $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
$json_str = curl_exec($ch);
curl_close($ch);
return $this->parseResponse($json_str);
}
public function smushFile($filename)
{
$this->filename = $filename;
if (!is_readable($filename))
{
$this->error = 'Could not read file';
return false;
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, self::SMUSH_URL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, array('files' => '@' . $filename));
$json_str = curl_exec($ch);
curl_close($ch);
return $this->parseResponse($json_str);
}
public function downloadFile() {
$this->error = null;
$tmpfile = tempnam(sys_get_temp_dir(), 'pushit');
$fh = fopen($tmpfile, 'w');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$this->compressedUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FILE, $fh);
curl_exec($ch);
$rc = curl_getinfo($ch);
if ($rc['http_code']=='200' && $rc['size_download']==$this->compressedSize) {
curl_close($ch);
return ($tmpfile);
} else {
$this->error = curl_error($ch);
curl_close($ch);
return (null);
}
}
private function parseResponse($json_str)
{
$this->error = null;
$json = json_decode($json_str);
if (is_null($json))
{
$this->error = 'Bad response from Smush.it web service';
return false;
}
if (isset($json->error))
{
$this->error = $json->error;
return false;
}
$this->size = $json->src_size;
$this->compressedUrl = $json->dest;
$this->compressedSize = $json->dest_size;
$this->savings = $json->percent;
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment