Skip to content
This repository has been archived by the owner on Feb 1, 2023. It is now read-only.

Commit

Permalink
Do not create any temporary files, do everything in memory
Browse files Browse the repository at this point in the history
  • Loading branch information
jacklul committed Apr 2, 2020
1 parent b98d770 commit df3f8f9
Showing 1 changed file with 150 additions and 103 deletions.
253 changes: 150 additions & 103 deletions src/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class App
*
* @var string
*/
private $VERSION = '1.6.1';
private $VERSION = '1.6.2';

/**
* App update URL
Expand Down Expand Up @@ -1078,6 +1078,54 @@ function () use ($tags, $page, $limit) {
return $output;
}

/**
* @param int $delay
* @param array $results
* @param callable $callable
*
* @return callable
*/
private function applyCooldown($delay = 60, array $results, callable $callable)
{
$this->printout($this->LINE_BUFFER);
$this->parseError(is_array($results) ? $results['error'] : null);

$this->printout(' Waiting ' . $delay . ' seconds...');
sleep($delay);

return $callable();
}

/**
* Parse error name
*
* @param $error
*/
private function parseError($error)
{
if ($error == 'NoResults') {
$this->printout(" no matching images found!\n");
} elseif ($error == 'NotImage') {
$this->printout(" not a valid image!\n");
} elseif ($error == 'EmptyResult') {
$this->printout(" no reply from the server!\n");
} elseif ($error == 'UploadError') {
$this->printout(" upload error!\n");
} elseif ($error == 'NotResource') {
$this->printout(" conversion failed or image is corrupted!\n");
} elseif ($error == 'ShortLimitReached') {
$this->printout(" too many requests!\n");
} elseif ($error == 'LimitReached') {
$this->printout(" exceeded daily search limit!\n");
} elseif ($error == 'FailedLimitReached') {
$this->printout(" too many failed search attempts!\n");
} elseif (!empty($error)) {
$this->printout(" error: " . $error . "\n");
} else {
$this->printout(" empty response!\n");
}
}

/**
* Prevent overwriting files
*
Expand Down Expand Up @@ -1113,25 +1161,16 @@ private function reverseSearch($file)
$post_data = [];

if ($this->USE_PHPWFIO || $this->USE_CONVERSION) {
$TEMP_FILE = tempnam(sys_get_temp_dir(), "Y69");

if ($this->USE_CONVERSION) {
$mime_type = mime_content_type($file);
$image = $this->readImage($file, $mime_type);

if (isset($image) && is_resource($image)) {
imagejpeg($image, $TEMP_FILE, 90);
imagedestroy($image);
} elseif (is_array($image) && isset($image['error'])) {
return $image;
} else {
return ['error' => 'NotResource'];
$contents = $this->convertImage($file);
if (is_array($contents) && isset($contents['error'])) {
return $contents;
}
} elseif ($this->USE_PHPWFIO) {
copy($file, $TEMP_FILE);
} else {
$contents = file_get_contents($file);
}

$post_data['file'] = new \CurlFile($TEMP_FILE, mime_content_type($TEMP_FILE), basename($TEMP_FILE));
$file_data['file'] = $contents;
} else {
$post_data['file'] = new \CurlFile($file, mime_content_type($file), basename($file));
}
Expand All @@ -1150,19 +1189,21 @@ private function reverseSearch($file)
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, $this->RETURN_TIMEOUT);
curl_setopt($ch, CURLOPT_LOW_SPEED_TIME, $this->RETURN_TIMEOUT);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);

if (isset($file_data)) {
$this->buildMultiPartRequest($ch, uniqid('', true), $post_data, $file_data);
} else {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
}

curl_setopt($ch, CURLOPT_NOPROGRESS, false);
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, [$this, 'cURLProgress']);
curl_setopt($ch, CURLOPT_WRITEFUNCTION, [$this, 'cURLRead']);
curl_setopt($ch, CURLOPT_USERPWD, $this->E621_LOGIN . ":" . $this->E621_API_KEY);

$output = curl_exec($ch);

if (isset($TEMP_FILE) && file_exists($TEMP_FILE)) {
unlink($TEMP_FILE);
}

if (!empty($this->RETURN_BUFFER)) {
$output = $this->RETURN_BUFFER;
}
Expand Down Expand Up @@ -1212,6 +1253,33 @@ private function reverseSearch($file)
return $output;
}

/**
* @param $file
*
* @return array|false|resource|string|null
*/
private function convertImage($file)
{
$mime_type = mime_content_type($file);
$image = $this->readImage($file, $mime_type);

if (isset($image) && is_resource($image)) {
ob_start();
imagejpeg($image, NULL, 90);
$contents = ob_get_clean();

imagedestroy($image);

return $contents;
}

if (is_array($image) && isset($image['error'])) {
return $image;
}

return ['error' => 'NotResource'];
}

/**
* Read the image and create image resource object
*
Expand Down Expand Up @@ -1248,51 +1316,44 @@ private function readImage($file, $type)
}

/**
* @param int $delay
* @param array $results
* @param callable $callable
* https://gist.github.com/iansltx/a6ed41d19852adf2e496
*
* @return callable
* @param $ch
* @param $boundary
* @param $fields
* @param $files
*
* @return mixed
*/
private function applyCooldown($delay = 60, array $results, callable $callable)
private function buildMultiPartRequest($ch, $boundary, $fields, $files)
{
$this->printout($this->LINE_BUFFER);
$this->parseError(is_array($results) ? $results['error'] : null);
$delimiter = '-------------' . $boundary;
$data = '';

$this->printout(' Waiting ' . $delay . ' seconds...');
sleep($delay);
foreach ($fields as $name => $content) {
$data .= "--" . $delimiter . "\r\n"
. 'Content-Disposition: form-data; name="' . $name . "\"\r\n\r\n"
. $content . "\r\n";
}
foreach ($files as $name => $content) {
$data .= "--" . $delimiter . "\r\n"
. 'Content-Disposition: form-data; name="' . $name . '"; filename="' . $name . '"' . "\r\n\r\n"
. $content . "\r\n";
}

return $callable();
}
$data .= "--" . $delimiter . "--\r\n";

/**
* Parse error name
*
* @param $error
*/
private function parseError($error)
{
if ($error == 'NoResults') {
$this->printout(" no matching images found!\n");
} elseif ($error == 'NotImage') {
$this->printout(" not a valid image!\n");
} elseif ($error == 'EmptyResult') {
$this->printout(" no reply from the server!\n");
} elseif ($error == 'UploadError') {
$this->printout(" upload error!\n");
} elseif ($error == 'NotResource') {
$this->printout(" conversion failed or image is corrupted!\n");
} elseif ($error == 'ShortLimitReached') {
$this->printout(" too many requests!\n");
} elseif ($error == 'LimitReached') {
$this->printout(" exceeded daily search limit!\n");
} elseif ($error == 'FailedLimitReached') {
$this->printout(" too many failed search attempts!\n");
} elseif (!empty($error)) {
$this->printout(" error: " . $error . "\n");
} else {
$this->printout(" empty response!\n");
}
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Content-Type: multipart/form-data; boundary=' . $delimiter,
'Content-Length: ' . strlen($data),
'Expect:',
],
CURLOPT_POSTFIELDS => $data
]);

return $ch;
}

/**
Expand All @@ -1307,25 +1368,16 @@ private function reverseSearchSaucenao($file)
$post_data = [];

if ($this->USE_PHPWFIO || $this->USE_CONVERSION) {
$TEMP_FILE = tempnam(sys_get_temp_dir(), "Y69");

if ($this->USE_CONVERSION) {
$mime_type = mime_content_type($file);
$image = $this->readImage($file, $mime_type);

if (isset($image) && is_resource($image)) {
imagejpeg($image, $TEMP_FILE, 90);
imagedestroy($image);
} elseif (is_array($image) && isset($image['error'])) {
return $image;
} else {
return ['error' => 'NotResource'];
$contents = $this->convertImage($file);
if (is_array($contents) && isset($contents['error'])) {
return $contents;
}
} elseif ($this->USE_PHPWFIO) {
copy($file, $TEMP_FILE);
} else {
$contents = file_get_contents($file);
}

$post_data['file'] = new \CurlFile($TEMP_FILE, mime_content_type($TEMP_FILE), basename($TEMP_FILE));
$file_data['file'] = $contents;
} else {
$post_data['file'] = new \CurlFile($file, mime_content_type($file), basename($file));
}
Expand Down Expand Up @@ -1364,18 +1416,20 @@ private function reverseSearchSaucenao($file)
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, $this->RETURN_TIMEOUT);
curl_setopt($ch, CURLOPT_LOW_SPEED_TIME, $this->RETURN_TIMEOUT);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);

if (isset($file_data)) {
$this->buildMultiPartRequest($ch, uniqid('', true), $post_data, $file_data);
} else {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
}

curl_setopt($ch, CURLOPT_NOPROGRESS, false);
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, [$this, 'cURLProgress']);
curl_setopt($ch, CURLOPT_WRITEFUNCTION, [$this, 'cURLRead']);

$output = curl_exec($ch);

if (isset($TEMP_FILE) && file_exists($TEMP_FILE)) {
unlink($TEMP_FILE);
}

if (!empty($this->RETURN_BUFFER)) {
$output = $this->RETURN_BUFFER;
}
Expand Down Expand Up @@ -1519,25 +1573,16 @@ private function reverseSearchHarryLu($file)
$post_data = [];

if ($this->USE_PHPWFIO || $this->USE_CONVERSION) {
$TEMP_FILE = tempnam(sys_get_temp_dir(), "Y69");

if ($this->USE_CONVERSION) {
$mime_type = mime_content_type($file);
$image = $this->readImage($file, $mime_type);

if (isset($image) && is_resource($image)) {
imagejpeg($image, $TEMP_FILE, 90);
imagedestroy($image);
} elseif (is_array($image) && isset($image['error'])) {
return $image;
} else {
return ['error' => 'NotResource'];
$contents = $this->convertImage($file);
if (is_array($contents) && isset($contents['error'])) {
return $contents;
}
} elseif ($this->USE_PHPWFIO) {
copy($file, $TEMP_FILE);
} else {
$contents = file_get_contents($file);
}

$post_data['file'] = new \CurlFile($TEMP_FILE, mime_content_type($TEMP_FILE), basename($TEMP_FILE));
$file_data['file'] = $contents;
} else {
$post_data['file'] = new \CurlFile($file, mime_content_type($file), basename($file));
}
Expand All @@ -1559,18 +1604,20 @@ private function reverseSearchHarryLu($file)
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, $this->RETURN_TIMEOUT);
curl_setopt($ch, CURLOPT_LOW_SPEED_TIME, $this->RETURN_TIMEOUT);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);

if (isset($file_data)) {
$this->buildMultiPartRequest($ch, uniqid('', true), $post_data, $file_data);
} else {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
}

curl_setopt($ch, CURLOPT_NOPROGRESS, false);
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, [$this, 'cURLProgress']);
curl_setopt($ch, CURLOPT_WRITEFUNCTION, [$this, 'cURLRead']);

$output = curl_exec($ch);

if (isset($TEMP_FILE) && file_exists($TEMP_FILE)) {
unlink($TEMP_FILE);
}

if (!empty($this->RETURN_BUFFER)) {
$output = $this->RETURN_BUFFER;
}
Expand Down

0 comments on commit df3f8f9

Please sign in to comment.