0.9.0 - the ZapV version updated to current php standards. Brave search used, while Bing and Google search api are deprecated
This commit is contained in:
parent
3d4298fe8b
commit
4ddaddda3d
31 changed files with 1778 additions and 1 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
sessions/*
|
||||||
|
ignore
|
||||||
52
README.md
52
README.md
|
|
@ -1,3 +1,53 @@
|
||||||
# ZapMachine
|
# ZapMachine
|
||||||
|
|
||||||
Revival of the old ZapMachine. A collage machine that merges random images layer by layer remaining about 50% of the original images
|
Revival of the old ZapMachine. A collage machine that merges random images layer by layer remaining about 50% of the original images
|
||||||
|
|
||||||
|
########################################################
|
||||||
|
#### ApFab - Zap Machine V0.9.0 ###
|
||||||
|
########################################################
|
||||||
|
🄯 2009 - 2026 Fabian de Boer, Vincent Bruijne
|
||||||
|
www.apfab.com
|
||||||
|
|
||||||
|
Zap stands for 'Zapped Artificial Picture', a collage made from Internet images. A Zap translates a set of words or a text into an image which reflects the visual representation of the words on the Internet.
|
||||||
|
|
||||||
|
This web application, Zap Machine, needs a number of words as input. It then takes the most relevant image that search engine Yahoo comes up with. After having collected all images the Zap Machine creates a given number of different collages from those images.
|
||||||
|
|
||||||
|
|
||||||
|
## installation
|
||||||
|
|
||||||
|
First you need to run a server with PHP. Please do not use a Windows machine for this purpose, while Windows suck. ApFab recommends Linux or Mac;)
|
||||||
|
|
||||||
|
ApFab Zap Machine needs some PHP extensions:
|
||||||
|
- JSON (default installed)
|
||||||
|
- CUrl (default installed)
|
||||||
|
- Imagick (Image Magick image processing Class)
|
||||||
|
|
||||||
|
You need to acquire the following API key and put it into `conf/conf.php`:
|
||||||
|
|
||||||
|
1. **Brave Search API Key** - https://api.search.brave.com/
|
||||||
|
|
||||||
|
See `conf/conf.php` for the exact constant names to use.
|
||||||
|
|
||||||
|
Adjust permission (chmod 777) for Sessions folder, run index.html, fill in the form and voila.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# how it works
|
||||||
|
|
||||||
|
- index.html contains user interface
|
||||||
|
- user input put into Session variables in init.php
|
||||||
|
- display.inc.php dynamically displays two img tags that are loaded in turn with image data from zap.php using display.js
|
||||||
|
- zap.php downloads images one by one using imgSearch Class
|
||||||
|
- zap.php processes collages one by one using imgProcess Class
|
||||||
|
- All downloaded images, collage images and logfiles(feature is far from ready yet) are put in a folder named 'Session/zap'.date()
|
||||||
|
- the machine is ready when an error is loaded into img document class. (a weak point in our construction)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# yet to come
|
||||||
|
- Logfile also generated in imgProcess Class (0.9.2)
|
||||||
|
- Number and camera filename (virgin images) input (0.9.3)
|
||||||
|
- Proper stop meganism (0.9.1)
|
||||||
|
- better error handling: dead links give dynamicly generated image thats allso used in collage (0.9.3)
|
||||||
|
- visualisation of logfile, so viewers can see what is happening (0.9.1)
|
||||||
|
- replacing all 'random' image processing parameters (0.7)
|
||||||
|
|
|
||||||
48
changelog.txt
Executable file
48
changelog.txt
Executable file
|
|
@ -0,0 +1,48 @@
|
||||||
|
ZAP is a refactorment of the Zap Machine V0.3.2 from ApFab
|
||||||
|
It's more like a framework now.
|
||||||
|
|
||||||
|
todo ZAP
|
||||||
|
- add .htaccess file
|
||||||
|
|
||||||
|
# ZAP
|
||||||
|
|
||||||
|
0.5.0
|
||||||
|
- updated the search engines removed Yahoo, added Bing
|
||||||
|
|
||||||
|
# ZAPV
|
||||||
|
|
||||||
|
0.1.0
|
||||||
|
- new public release of ZAP
|
||||||
|
|
||||||
|
0.0.9
|
||||||
|
- made logging dependent
|
||||||
|
- made adult searches config dependent
|
||||||
|
|
||||||
|
0.0.8
|
||||||
|
- refactored the ImgProcess class and removed code to two other classes
|
||||||
|
- added ImgIOTools and ImgTools. They contain static functions
|
||||||
|
|
||||||
|
0.0.7
|
||||||
|
- refactored the whole search engine part
|
||||||
|
- made an interface for future implementations of other search engines
|
||||||
|
|
||||||
|
0.0.6
|
||||||
|
- added a Config class
|
||||||
|
|
||||||
|
0.0.5
|
||||||
|
- split the search code to separate functions
|
||||||
|
- added ZAPCurl util class
|
||||||
|
|
||||||
|
0.0.4
|
||||||
|
- split the zap code to separate functions
|
||||||
|
|
||||||
|
0.0.3
|
||||||
|
- refactored all classes to more readable code
|
||||||
|
- created Session utils class
|
||||||
|
|
||||||
|
0.0.2
|
||||||
|
- created new index.php and front controller
|
||||||
|
- added conf.php and init.php
|
||||||
|
|
||||||
|
0.0.1
|
||||||
|
- reworked frontend to separate html and js
|
||||||
28
cli_scripts/reset.php
Executable file
28
cli_scripts/reset.php
Executable file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
unset($_SESSION['imgOriginal']);
|
||||||
|
unset($_SESSION['words']);
|
||||||
|
unset($_SESSION['folder']);
|
||||||
|
unset($_SESSION['collages']);
|
||||||
|
unset($_SESSION['width']);
|
||||||
|
unset($_SESSION['height']);
|
||||||
|
|
||||||
|
echo '<p>session reset</p><p>';
|
||||||
|
|
||||||
|
if ($_GET['allcollages'] == 'clear') {
|
||||||
|
$sessions = glob('./Sessions/*');
|
||||||
|
foreach($sessions as $folder){
|
||||||
|
$files = glob($folder.'/*');
|
||||||
|
foreach($files as $fileToDelete){
|
||||||
|
echo "$fileToDelete deleted<br />";
|
||||||
|
unlink($fileToDelete);
|
||||||
|
}
|
||||||
|
echo "$folder deleted<br />";
|
||||||
|
rmdir($folder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
echo '</p>';
|
||||||
|
|
||||||
|
session_destroy();
|
||||||
|
?>
|
||||||
192
cli_scripts/test.php
Executable file
192
cli_scripts/test.php
Executable file
|
|
@ -0,0 +1,192 @@
|
||||||
|
#!/usr/bin/env php
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* ZapMachine Test Script
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* php test.php Run all tests
|
||||||
|
* php test.php --brave Test Brave search JSON output
|
||||||
|
* php test.php --search Test ImgSearch for a word and show JSON results
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Make sure relative paths in init.php resolve against this script's directory
|
||||||
|
chdir(__DIR__);
|
||||||
|
|
||||||
|
// Bootstrap the application
|
||||||
|
require_once __DIR__ . '/../conf/init.php';
|
||||||
|
|
||||||
|
$passed = 0;
|
||||||
|
$failed = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assert a condition and print result
|
||||||
|
*/
|
||||||
|
function test($description, $condition) {
|
||||||
|
global $passed, $failed;
|
||||||
|
if ($condition) {
|
||||||
|
echo " ✓ $description\n";
|
||||||
|
$passed++;
|
||||||
|
} else {
|
||||||
|
echo " ✗ $description\n";
|
||||||
|
$failed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run basic application tests
|
||||||
|
*/
|
||||||
|
function runBasicTests() {
|
||||||
|
echo "\n=== Basic Tests ===\n";
|
||||||
|
|
||||||
|
// Version test
|
||||||
|
test('ZAP_VERSION is defined', defined('ZAP_VERSION'));
|
||||||
|
test('ZAP_VERSION is 0.9.0', ZAP_VERSION === '0.9.0');
|
||||||
|
|
||||||
|
// Directory constants
|
||||||
|
test('ZAP_APP_BASE_DIR is defined', defined('ZAP_APP_BASE_DIR'));
|
||||||
|
test('ZAP_APP_BASE_DIR exists', is_dir(ZAP_APP_BASE_DIR));
|
||||||
|
test('ZAP_RESOURCE_DIR is defined', defined('ZAP_RESOURCE_DIR'));
|
||||||
|
test('ZAP_UTILS_DIR is defined', defined('ZAP_UTILS_DIR'));
|
||||||
|
|
||||||
|
// Resource directory
|
||||||
|
$resourceDir = ZAP_APP_BASE_DIR . DIRECTORY_SEPARATOR . ZAP_RESOURCE_DIR;
|
||||||
|
test('Resource directory exists', is_dir($resourceDir));
|
||||||
|
test('Search interface exists', file_exists($resourceDir . '/Search.interface.php'));
|
||||||
|
test('Brave class exists', file_exists($resourceDir . '/Brave.class.php'));
|
||||||
|
|
||||||
|
// Utils directory
|
||||||
|
$utilsDir = ZAP_APP_BASE_DIR . DIRECTORY_SEPARATOR . ZAP_UTILS_DIR;
|
||||||
|
test('Utils directory exists', is_dir($utilsDir));
|
||||||
|
test('ZAPCurl class exists', file_exists($utilsDir . '/ZAPCurl.class.php'));
|
||||||
|
|
||||||
|
// PHP extensions
|
||||||
|
test('ImageMagick PHP extension (imagick) is installed', extension_loaded('imagick'));
|
||||||
|
|
||||||
|
// Config
|
||||||
|
test('BRAVE_API_KEY is defined', defined('BRAVE_API_KEY'));
|
||||||
|
test('BRAVE_BASE is defined', defined('BRAVE_BASE'));
|
||||||
|
global $search_engines;
|
||||||
|
test('$search_engines is set', isset($search_engines));
|
||||||
|
test('$search_engines contains brave', isset($search_engines) && in_array('brave', $search_engines));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test ImgSearch class for a given word
|
||||||
|
*/
|
||||||
|
function testImgSearch() {
|
||||||
|
echo "\n=== ImgSearch Test ===\n";
|
||||||
|
echo "Enter a search word: ";
|
||||||
|
$handle = fopen("php://stdin", "r");
|
||||||
|
$word = trim(fgets($handle));
|
||||||
|
fclose($handle);
|
||||||
|
|
||||||
|
if (empty($word)) {
|
||||||
|
echo " ⚠ No word entered. Aborting.\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$folder = ZAP_APP_BASE_DIR . DIRECTORY_SEPARATOR . ZAP_SESSIONS_DIR . DIRECTORY_SEPARATOR . 'search_test_' . ZAP_MOMENT;
|
||||||
|
if (!is_dir($folder)) {
|
||||||
|
@mkdir($folder, 0777, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "\nQuery: '$word'\n\n";
|
||||||
|
|
||||||
|
// Register configured search engines so ImgSearch can pick one
|
||||||
|
global $search_engines;
|
||||||
|
$config = Config::getInstance();
|
||||||
|
$config->register('engines', $search_engines);
|
||||||
|
|
||||||
|
$search = new ImgSearch($folder, $word);
|
||||||
|
$data = $search->getImageData();
|
||||||
|
|
||||||
|
echo "Raw JSON output:\n";
|
||||||
|
echo json_encode($data, JSON_PRETTY_PRINT) . "\n\n";
|
||||||
|
|
||||||
|
test('Result is an array', is_array($data));
|
||||||
|
test('Has result key', isset($data['result']));
|
||||||
|
|
||||||
|
if (isset($data['result']) && $data['result'] === true) {
|
||||||
|
test('Search returned results', true);
|
||||||
|
test('Has results array', isset($data['results']));
|
||||||
|
if (isset($data['results'])) {
|
||||||
|
$count = count($data['results']);
|
||||||
|
echo " Results count: $count\n";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo " ⚠ No results returned. Check your API key and configuration.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test Brave search JSON output
|
||||||
|
*/
|
||||||
|
function testBraveSearch() {
|
||||||
|
echo "\n=== Brave Search JSON Test ===\n";
|
||||||
|
echo "Query: 'test' | Results: 3\n\n";
|
||||||
|
|
||||||
|
$brave = new Brave();
|
||||||
|
$brave->setQuery('test');
|
||||||
|
$brave->setParam('size', 3);
|
||||||
|
|
||||||
|
$json = $brave->getData();
|
||||||
|
|
||||||
|
echo "Raw JSON output:\n";
|
||||||
|
echo json_encode($json, JSON_PRETTY_PRINT) . "\n\n";
|
||||||
|
|
||||||
|
// Validate structure
|
||||||
|
test('Result is an array', is_array($json));
|
||||||
|
test('Has result key', isset($json['result']));
|
||||||
|
|
||||||
|
if (isset($json['result']) && $json['result'] === true) {
|
||||||
|
test('Search returned results', true);
|
||||||
|
test('Has results array', isset($json['results']));
|
||||||
|
test('Engine is Brave', isset($json['engine']) && $json['engine'] === 'Brave');
|
||||||
|
|
||||||
|
if (isset($json['results'])) {
|
||||||
|
$count = count($json['results']);
|
||||||
|
test("Results count is 3 (got $count)", $count === 3);
|
||||||
|
|
||||||
|
// Check first result structure
|
||||||
|
if ($count > 0) {
|
||||||
|
$first = $json['results'][0];
|
||||||
|
test('First result has clickurl', isset($first['clickurl']));
|
||||||
|
test('First result has thumb', isset($first['thumb']));
|
||||||
|
test('First result has referer', isset($first['referer']));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo "\n ⚠ No results returned. Check your API key and CX.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main execution
|
||||||
|
if (in_array('--search', $argv)) {
|
||||||
|
testImgSearch();
|
||||||
|
} elseif (in_array('--brave', $argv)) {
|
||||||
|
testBraveSearch();
|
||||||
|
} else {
|
||||||
|
runBasicTests();
|
||||||
|
|
||||||
|
// Ask if user wants to run Brave test
|
||||||
|
if (defined('BRAVE_API_KEY') && BRAVE_API_KEY !== 'YOUR_BRAVE_API_KEY') {
|
||||||
|
echo "\nRun Brave search test? (y/n): ";
|
||||||
|
$handle = fopen("php://stdin", "r");
|
||||||
|
$line = fgets($handle);
|
||||||
|
if (trim(strtolower($line)) === 'y') {
|
||||||
|
testBraveSearch();
|
||||||
|
}
|
||||||
|
fclose($handle);
|
||||||
|
} else {
|
||||||
|
echo "\n ⚠ Skipping Brave test: API key not configured\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Summary
|
||||||
|
echo "\n=== Results ===\n";
|
||||||
|
echo "Passed: $passed\n";
|
||||||
|
echo "Failed: $failed\n";
|
||||||
|
echo ($failed === 0 ? "All tests passed! ✓" : "Some tests failed.") . "\n\n";
|
||||||
|
|
||||||
|
exit($failed > 0 ? 1 : 0);
|
||||||
|
?>
|
||||||
35
conf/Config.class.php
Executable file
35
conf/Config.class.php
Executable file
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Singleton configuration class
|
||||||
|
* Register configuration directives with this class
|
||||||
|
*/
|
||||||
|
class Config {
|
||||||
|
private static $instance = null;
|
||||||
|
|
||||||
|
private $config = array();
|
||||||
|
|
||||||
|
private function __construct() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getInstance() {
|
||||||
|
if (self::$instance === null) {
|
||||||
|
$clazz = __CLASS__;
|
||||||
|
self::$instance = new $clazz();
|
||||||
|
}
|
||||||
|
return self::$instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function register($key, $value) {
|
||||||
|
$this->config[$key] = $value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function retrieve($key) {
|
||||||
|
if (isset($this->config[$key])) {
|
||||||
|
return $this->config[$key];
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
25
conf/conf.php
Executable file
25
conf/conf.php
Executable file
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Local configuration directives here.
|
||||||
|
* Change as you like
|
||||||
|
*/
|
||||||
|
define('MAX_WORDS', 4);
|
||||||
|
define('MAX_ZAPS', 9);
|
||||||
|
|
||||||
|
define('ZAP_CURL_TIMEOUT', 12);
|
||||||
|
define('ZAP_IMG_TYPE', 'jpg');
|
||||||
|
define('ZAP_CANVAS_NAME', 'collage');
|
||||||
|
|
||||||
|
define('ZAP_DELETE_SOURCE', false);
|
||||||
|
define('ZAP_ADULT', false);
|
||||||
|
define('ZAP_LOG', true);
|
||||||
|
define('ZAP_DEBUG', true);
|
||||||
|
|
||||||
|
|
||||||
|
// Brave Search API
|
||||||
|
// Get your API key: https://api.search.brave.com/
|
||||||
|
define('BRAVE_API_KEY', 'your api key');
|
||||||
|
define('BRAVE_BASE', 'https://api.search.brave.com/res/v1/images/search');
|
||||||
|
|
||||||
|
$search_engines = array('brave');
|
||||||
|
?>
|
||||||
99
conf/init.php
Executable file
99
conf/init.php
Executable file
|
|
@ -0,0 +1,99 @@
|
||||||
|
<?php
|
||||||
|
include_once 'conf.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define some app-wide constants
|
||||||
|
*/
|
||||||
|
define('ZAP_APP_BASE_DIR', realpath('.' . DIRECTORY_SEPARATOR . '..'));
|
||||||
|
define('ZAP_WEB_DIR', 'www');
|
||||||
|
define('ZAP_RESOURCE_DIR', 'resource');
|
||||||
|
define('ZAP_UTILS_DIR', 'utils');
|
||||||
|
define('ZAP_SESSIONS_DIR', 'sessions');
|
||||||
|
define('ZAP_LIB_DIR', 'lib');
|
||||||
|
define('ZAP_CONF_DIR', 'conf');
|
||||||
|
define('ZAP_TPL_DIR', 'tpl');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error decoration
|
||||||
|
*/
|
||||||
|
define('ERROR_PREFIX', 'ZAP Error: ');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set include path for application
|
||||||
|
*/
|
||||||
|
function setZAPIncludePath() {
|
||||||
|
$app_dirs = array(ZAP_RESOURCE_DIR, ZAP_UTILS_DIR, ZAP_SESSIONS_DIR,
|
||||||
|
ZAP_LIB_DIR, ZAP_TPL_DIR, ZAP_CONF_DIR);
|
||||||
|
$app_include_path = '';
|
||||||
|
|
||||||
|
foreach ($app_dirs as $app_dir) {
|
||||||
|
$app_include_path .= PATH_SEPARATOR . ZAP_APP_BASE_DIR . DIRECTORY_SEPARATOR . $app_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (set_include_path(get_include_path() . $app_include_path) == false) {
|
||||||
|
throw new Exception(ERROR_PREFIX . 'Error while creating include path...');
|
||||||
|
}
|
||||||
|
|
||||||
|
define('ZAP_INCLUDE_PATH_SET', true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initiate autoload function for application
|
||||||
|
*/
|
||||||
|
spl_autoload_register(function ($class_name) {
|
||||||
|
if (!defined('ZAP_INCLUDE_PATH_SET') || ZAP_INCLUDE_PATH_SET === false) {
|
||||||
|
try {
|
||||||
|
setZAPIncludePath();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo $e->getMessage();
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$include_path = get_include_path();
|
||||||
|
$include_path_tokens = explode(':', $include_path);
|
||||||
|
|
||||||
|
foreach ($include_path_tokens as $prefix) {
|
||||||
|
$path[0] = $prefix . DIRECTORY_SEPARATOR . $class_name . '.interface.php';
|
||||||
|
$path[1] = $prefix . DIRECTORY_SEPARATOR . $class_name . '.class.php';
|
||||||
|
|
||||||
|
foreach ($path as $thisPath) {
|
||||||
|
if (file_exists($thisPath)) {
|
||||||
|
require_once $thisPath;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define remaining app-wide constants
|
||||||
|
*/
|
||||||
|
define('ZAP_MOMENT', date("Y-m-d-H_i_s"));
|
||||||
|
define('ZAP_VERSION', '0.9.0');
|
||||||
|
define('ZAP_SESSION_NAME', 'ZAP');
|
||||||
|
|
||||||
|
// Only start session in web mode (not CLI)
|
||||||
|
if (php_sapi_name() !== 'cli') {
|
||||||
|
Session::start(ZAP_SESSION_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns string of path of template file
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function getZAPTemplate($tplname) {
|
||||||
|
if (!defined('ZAP_APP_BASE_DIR')) {
|
||||||
|
throw new Exception(ERROR_PREFIX . 'No base directory defined?!');
|
||||||
|
}
|
||||||
|
$tplfile = $tplname . '.tpl';
|
||||||
|
$tplfilepath = ZAP_APP_BASE_DIR . DIRECTORY_SEPARATOR
|
||||||
|
. ZAP_TPL_DIR . DIRECTORY_SEPARATOR . $tplfile;
|
||||||
|
if (file_exists($tplfilepath)) {
|
||||||
|
return $tplfilepath;
|
||||||
|
} else {
|
||||||
|
return ERROR_PREFIX . 'No template';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
50
lib/ImgIOTools.class.php
Executable file
50
lib/ImgIOTools.class.php
Executable file
|
|
@ -0,0 +1,50 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Image Input Output Tools
|
||||||
|
*/
|
||||||
|
class ImgIOTools {
|
||||||
|
public static $maxScreenWidth = 1067; //screen dimensions
|
||||||
|
|
||||||
|
public static $maxScreenHeight = 600;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flushes image to screen
|
||||||
|
* @param Imagick $im
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function onScreen(Imagick $img) {
|
||||||
|
$img->scaleImage(self::$maxScreenWidth, self::$maxScreenHeight, true);
|
||||||
|
|
||||||
|
//$img = self::scaleByLength($img, $this->maxScreenWidth, $this->maxScreenHeight);
|
||||||
|
header('Content-type: image/' . ZAP_IMG_TYPE);
|
||||||
|
echo $img->getImageBlob();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts image from $imgUrl (if exists) onscreen
|
||||||
|
* @param string $imgUrl
|
||||||
|
* @return boolean or imagedata
|
||||||
|
*/
|
||||||
|
public static function urlOnScreen($imgUrl) {
|
||||||
|
if (file_exists($imgUrl)) {
|
||||||
|
$img = new Imagick($imgUrl);
|
||||||
|
self::onScreen($img);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves active image from $im as $filename.$filetype in $folder
|
||||||
|
* @param Imagick $im
|
||||||
|
* @param string $folder
|
||||||
|
* @param string $filename
|
||||||
|
* @param string $filetype
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public static function saveImg(Imagick $img, $folder, $filename) {
|
||||||
|
$path = $folder . $filename . '.' . ZAP_IMG_TYPE;
|
||||||
|
return $img->writeImage($path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
92
lib/ImgProcess.class.php
Executable file
92
lib/ImgProcess.class.php
Executable file
|
|
@ -0,0 +1,92 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* ImgProcess
|
||||||
|
* Actual image manipulation
|
||||||
|
*/
|
||||||
|
class ImgProcess {
|
||||||
|
private $folder; //folder for reading source images and write
|
||||||
|
|
||||||
|
private $canvasName;
|
||||||
|
|
||||||
|
private $zapWidth;//collage dimensions
|
||||||
|
|
||||||
|
private $zapHeight;
|
||||||
|
|
||||||
|
private $maxRGB; //depends on colorDepth. 8 bits: 255; 16 bits : 65536;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor
|
||||||
|
* @param $imgFolder string
|
||||||
|
* @param $width int
|
||||||
|
* @param $height int
|
||||||
|
* @param $nr int
|
||||||
|
*/
|
||||||
|
public function __construct($imgFolder, $width, $height, $nr) {
|
||||||
|
$this->folder = $imgFolder;
|
||||||
|
|
||||||
|
$this->zapWidth = $width;
|
||||||
|
$this->zapHeight = $height;
|
||||||
|
|
||||||
|
$this->canvasName = DIRECTORY_SEPARATOR . ZAP_CANVAS_NAME;
|
||||||
|
$this->canvasName .= $_SESSION['date'] . "_nr_" . sprintf("%02d", $nr);
|
||||||
|
|
||||||
|
$tmpImg = new Imagick();
|
||||||
|
$tmpAr = $tmpImg->getQuantumRange();
|
||||||
|
$this->maxRGB = $tmpAr['quantumRangeLong'];
|
||||||
|
$tmpImg->destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes a basic canvasFile from sourceImage
|
||||||
|
* and saves it into imageFolder
|
||||||
|
* returns imageBLOB from saved image
|
||||||
|
* @param string $sourceImgName
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function createBasicCanvas($sourceImgName) {
|
||||||
|
$canvas = new Imagick($sourceImgName);
|
||||||
|
$canvas = ImgTools::zoomCrop($canvas, $this->zapWidth, $this->zapHeight, TRUE);
|
||||||
|
|
||||||
|
ImgIOTools::saveImg($canvas, $this->folder, $this->canvasName);
|
||||||
|
if (ZAP_DELETE_SOURCE == true) {
|
||||||
|
unlink($sourceImgName);
|
||||||
|
}
|
||||||
|
ImgIOTools::onScreen($canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* adds processed version of $sourceImage to canvas
|
||||||
|
* @param string $sourceImgName
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function addToCanvas($sourceImgName) {
|
||||||
|
$canvasUri = $this->folder . $this->canvasName . '.' . ZAP_IMG_TYPE;
|
||||||
|
$canvas = new Imagick($canvasUri);
|
||||||
|
|
||||||
|
$source_im = new Imagick($sourceImgName);
|
||||||
|
|
||||||
|
$newCanvas_im = $this->zapToCanvas($source_im, $canvas);
|
||||||
|
ImgIOTools::saveImg($newCanvas_im, $this->folder, $this->canvasName);
|
||||||
|
if (ZAP_DELETE_SOURCE == true) {
|
||||||
|
unlink($sourceImgName);
|
||||||
|
}
|
||||||
|
ImgIOTools::onScreen($newCanvas_im);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Imagick $source_im
|
||||||
|
* @param Imagick $canvas
|
||||||
|
* @return Imagick Object
|
||||||
|
*/
|
||||||
|
private function zapToCanvas(Imagick $source_im, $canvas) {
|
||||||
|
//$val = ImgTools::imgCenterValueProm($source_im, $this->maxRGB);
|
||||||
|
|
||||||
|
//merge resized random transparised image on top of canvas
|
||||||
|
$transparent = ImgTools::transparantRandom($source_im, $this->maxRGB);
|
||||||
|
$resized = ImgTools::resize($transparent, $this->zapWidth, $this->zapHeight);
|
||||||
|
|
||||||
|
$canvas->compositeImage($resized, imagick::COMPOSITE_OVER, 0, 0);
|
||||||
|
return $canvas;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
145
lib/ImgSearch.class.php
Executable file
145
lib/ImgSearch.class.php
Executable file
|
|
@ -0,0 +1,145 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* ZAP image search class
|
||||||
|
*/
|
||||||
|
class ImgSearch {
|
||||||
|
private $hitPosition;
|
||||||
|
|
||||||
|
private $numberResults = 16;
|
||||||
|
|
||||||
|
private $folder;
|
||||||
|
|
||||||
|
private $word;
|
||||||
|
|
||||||
|
private $engine;
|
||||||
|
|
||||||
|
private $allowedFileTypes = array('image/jpeg','image/gif','image/png');
|
||||||
|
|
||||||
|
private $log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param string $imgFolder path to save images to
|
||||||
|
* @param string $word keyword to search for
|
||||||
|
*/
|
||||||
|
public function __construct($imgFolder, $word) {
|
||||||
|
$this->folder = $imgFolder;
|
||||||
|
$this->word = $word;
|
||||||
|
|
||||||
|
$this->hitPosition = (int) rand(0,10);
|
||||||
|
|
||||||
|
if (ZAP_LOG == true) {
|
||||||
|
$this->log = new Log($this->folder);
|
||||||
|
}
|
||||||
|
|
||||||
|
$config = Config::getInstance();
|
||||||
|
$engines = $config->retrieve('engines');
|
||||||
|
$this->engine = $engines[array_rand($engines)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* download image that corresponds to $keyWord
|
||||||
|
* returns filename of image if downloaded succeeded, or false if failed
|
||||||
|
* @return string $localUrl / boolean
|
||||||
|
*/
|
||||||
|
public function getImage() {
|
||||||
|
$imgData = $this->getImageData();
|
||||||
|
if ($imgData == false) {
|
||||||
|
$this->addLog('error','Search: ', 'bad search data received' );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$this->addLog('ok', 'Engine: ', $imgData['engine']);
|
||||||
|
|
||||||
|
$localUrl = $this->imageToTmp($imgData['results'], $this->folder);
|
||||||
|
|
||||||
|
return $localUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array that contains searchdata for $word
|
||||||
|
* @return array $searchData or false
|
||||||
|
*/
|
||||||
|
public function getImageData() {
|
||||||
|
$clazz = ucfirst($this->engine);
|
||||||
|
$search = new $clazz();
|
||||||
|
$search->setQuery(urlencode($this->word));
|
||||||
|
$search->setParam('start', $this->hitPosition);
|
||||||
|
$search->setParam('size', $this->numberResults);
|
||||||
|
|
||||||
|
$searchData = $search->getData();
|
||||||
|
|
||||||
|
return $searchData['result'] == false ? false : $searchData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves image or returns false
|
||||||
|
* @param array $results
|
||||||
|
* @param string $tmpDir
|
||||||
|
* @param integer $hit
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
private function imageToTmp($results, $tmpDir, $hit = 0) {
|
||||||
|
$first = $results[$hit]['clickurl'];
|
||||||
|
$imageName = $tmpDir . DIRECTORY_SEPARATOR . $this->filename($first);
|
||||||
|
|
||||||
|
$myCurl = new ZAPCurl($first, true);
|
||||||
|
$imageData = $myCurl->fetchCurlData();
|
||||||
|
|
||||||
|
if($imageData == false) {
|
||||||
|
$this->addLog('error', 'Search: ', 'received empty file' . PHP_EOL);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(file_put_contents($imageName, $imageData)) {
|
||||||
|
if($this->imageTypeOk($imageName)) {
|
||||||
|
$this->addLog('ok', 'Search: ', "downloaded to $imageName");
|
||||||
|
$this->addLog('ok', 'Search: ', 'source: ' . $results[$hit]['referer']);
|
||||||
|
$this->addLog('ok', 'Search: ', 'thumb: ' . $results[$hit]['thumb'] . PHP_EOL);
|
||||||
|
return $imageName;
|
||||||
|
} else {
|
||||||
|
$this->addLog('error', 'Search: ', 'wrong file type: image removed');
|
||||||
|
unlink($imageName);
|
||||||
|
|
||||||
|
$nextHit = $hit + 1;
|
||||||
|
return $this->imageToTmp($results, $tmpDir, $nextHit);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->addLog('error', 'Search: ', 'failed saving image');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check mime type of image
|
||||||
|
* @param string $fileUri
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
private function imageTypeOk($fileUri) {
|
||||||
|
$mimeType = mime_content_type($fileUri);
|
||||||
|
return in_array($mimeType, $this->allowedFileTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets filename from a url
|
||||||
|
* @param string $urlString
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function filename($urlString) {
|
||||||
|
$ar = explode('/', $urlString);
|
||||||
|
$filename = array_pop($ar);
|
||||||
|
// Strip query string so the saved file has a real extension
|
||||||
|
$filename = explode('?', $filename)[0];
|
||||||
|
return $filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log messages
|
||||||
|
*/
|
||||||
|
private function addLog($type, $head, $message) {
|
||||||
|
if (ZAP_LOG == true) {
|
||||||
|
$this->log->addToLog($type, $head, $message);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
180
lib/ImgTools.class.php
Executable file
180
lib/ImgTools.class.php
Executable file
|
|
@ -0,0 +1,180 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Library of tool functions to manipulate an image
|
||||||
|
*/
|
||||||
|
class ImgTools {
|
||||||
|
public static $maxScreenWidth = 1067; //screen dimensions
|
||||||
|
|
||||||
|
public static $maxScreenHeight = 600;
|
||||||
|
|
||||||
|
public static $minFuzzFactor = 0.08; //minimal factor for $fuzz
|
||||||
|
|
||||||
|
public static $maxFuzzFactor = 0.64; //maximal factor for $fuzz
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns $im with random transparent color
|
||||||
|
* @param Imagick $im
|
||||||
|
* @param int $maxRGB
|
||||||
|
* @return Imagick $im
|
||||||
|
*/
|
||||||
|
public static function transparantRandom(Imagick $img, $maxRGB) {
|
||||||
|
//compute random fuzzyness
|
||||||
|
$minFuzz = intval(self::$minFuzzFactor * $maxRGB);
|
||||||
|
$maxFuzz = intval(self::$maxFuzzFactor * $maxRGB);
|
||||||
|
$randFuzz = mt_rand ($minFuzz,$maxFuzz);
|
||||||
|
|
||||||
|
//take average RGB value of random pixel
|
||||||
|
$xPoint = mt_rand(0,$img->getImageWidth());
|
||||||
|
$yPoint = mt_rand(0,$img->getImageHeight());
|
||||||
|
$randomPixel = $img->getImagePixelColor($xPoint, $yPoint);
|
||||||
|
$randomPixelColor = $randomPixel->getColorAsString();
|
||||||
|
|
||||||
|
//make transparency
|
||||||
|
$img->transparentPaintImage($randomPixelColor, 0.0, $randFuzz, false);
|
||||||
|
return $img;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* random Rotate image
|
||||||
|
* @param Imagick $im
|
||||||
|
* @return Imagick $im
|
||||||
|
*/
|
||||||
|
public static function randomRotate(Imagick $img) {
|
||||||
|
$transp = new ImagickPixel('#ffffff');
|
||||||
|
$ar = array(0,90,180,270);
|
||||||
|
$img->rotateImage($transp, $ar[mt_rand(0,3)]);
|
||||||
|
return $img;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resize image
|
||||||
|
* @param Imagick $im
|
||||||
|
* @param integer $retWidth
|
||||||
|
* @param integer $retHeight
|
||||||
|
* @return Imagick $im
|
||||||
|
*/
|
||||||
|
public static function resize(Imagick $img, $retWidth, $retHeight) {
|
||||||
|
$img->resizeImage((int)$retWidth, (int)$retHeight, imagick::FILTER_POINT, 0);
|
||||||
|
return $img;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recolor image
|
||||||
|
* @param Imagick $im
|
||||||
|
* @return Imagick $im
|
||||||
|
*/
|
||||||
|
public static function recolor(Imagick $img){
|
||||||
|
$recolorValue = mt_rand(4, 250);
|
||||||
|
$times = mt_rand(1, 4);
|
||||||
|
for($i = 0; $i <= $times; $i++) {
|
||||||
|
$img->cycleColormapImage($recolorValue);
|
||||||
|
}
|
||||||
|
return $img;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns MagickWand with randomly zoomed part of image $im with size $retWidth * $retHeight
|
||||||
|
* @param Imagick $im
|
||||||
|
* @param integer $retWidth
|
||||||
|
* @param integer $retHeight
|
||||||
|
* @param boolean $rotate
|
||||||
|
*/
|
||||||
|
public static function zoomCrop(Imagick $img, $retWidth, $retHeight, $rotate = false) {
|
||||||
|
if ($rotate == true) {
|
||||||
|
$img = self::randomRotate($img);
|
||||||
|
}
|
||||||
|
|
||||||
|
$fact = mt_rand(10, 40) / 100; //zoomfactor 10 - 40%
|
||||||
|
$width = $img->getImageWidth();
|
||||||
|
$height = $img->getImageHeight();
|
||||||
|
$newWidth = (int)($width * $fact);
|
||||||
|
$newHeight = (int)($height * $fact);
|
||||||
|
//crop $im
|
||||||
|
//x and y offset random 0 - width (or height) of blown up image minus crop area (of course!)
|
||||||
|
$img->cropImage($newWidth, $newHeight,
|
||||||
|
mt_rand(0, (int)($width - $newWidth)),
|
||||||
|
mt_rand(0, (int)($height - $newHeight)));
|
||||||
|
|
||||||
|
$img->resizeImage((int)$retWidth, (int)$retHeight, imagick::FILTER_POINT, 0);
|
||||||
|
return $img;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* converts all gif images in array to png images
|
||||||
|
* returns Array with converted filenames
|
||||||
|
* @param array $imgAr
|
||||||
|
* @return array $newArray
|
||||||
|
*/
|
||||||
|
public static function convertGifsToPng($imgAr) {
|
||||||
|
$newArray = array();
|
||||||
|
while ($filename = array_shift($imgAr)) {
|
||||||
|
$imgInfo = getimagesize($filename);
|
||||||
|
$mimeType = $imgInfo['mime'];
|
||||||
|
//find gif
|
||||||
|
if ($mimeType == "image/gif") {
|
||||||
|
$imagetype = 'png';
|
||||||
|
//full image name
|
||||||
|
$Dot = '.';
|
||||||
|
$newFilename = "$filename$Dot$imagetype";
|
||||||
|
//convert
|
||||||
|
$img = new Imagick($filename);
|
||||||
|
|
||||||
|
if($img->writeImage($newFilename)) {
|
||||||
|
//Remove original and rename new to save space
|
||||||
|
unlink($filename);
|
||||||
|
array_push($newArray, $newFilename);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
array_push($newArray, $filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return $newArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LEGACY?
|
||||||
|
* INT (0 - 1000) -> promilage of average RGB value of center pixel of $im related to $maxRGB
|
||||||
|
* @param Imagick $im
|
||||||
|
* @param int $maxRGB
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public static function imgCenterValueProm(Imagick $img, $maxRGB) {
|
||||||
|
$centerX = $img->getImageWidth() / 2;
|
||||||
|
$centerY = $img->getImageHeight() / 2;
|
||||||
|
|
||||||
|
//take average of the RGB of most middle pixel of each image and put it into an array
|
||||||
|
$centerPixel = $img->getImagePixelColor($centerX,$centerY);
|
||||||
|
$colors = $centerPixel->getColor();
|
||||||
|
|
||||||
|
$averageColor = round( ($colors['r'] + $colors['g'] + $colors['b']) / 3);
|
||||||
|
|
||||||
|
return round(($averageColor / $maxRGB) * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LEGACY?
|
||||||
|
* returns magickWand scaled proportionaly to $maxW or $maxH
|
||||||
|
* @param Imagick $im
|
||||||
|
* @param integer $maxW
|
||||||
|
* @param integer $maxH
|
||||||
|
* @return Imagick $im
|
||||||
|
*/
|
||||||
|
public static function scaleByLength(Imagick $img, $maxW, $maxH) {
|
||||||
|
$width = $img->getImageWidth();
|
||||||
|
$height = $img->getImageHeight();
|
||||||
|
if(($width <= self::$maxScreenWidth) && ($height <= self::$maxScreenHeight)) {
|
||||||
|
return $img;
|
||||||
|
} else {
|
||||||
|
if ($width >= $height) { //horizontal image
|
||||||
|
$new_x = $maxW;
|
||||||
|
$new_y = round(($new_x / $width) * $height, 0);
|
||||||
|
} else { //vertical image
|
||||||
|
$new_y = $maxH;
|
||||||
|
$new_x = round(($new_y / $height) * $width, 0);
|
||||||
|
}
|
||||||
|
return self::resize($img, $new_x, $new_y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
41
lib/ZAPController.class.php
Executable file
41
lib/ZAPController.class.php
Executable file
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Frontend handler
|
||||||
|
*/
|
||||||
|
class ZAPController {
|
||||||
|
/**
|
||||||
|
* String mode
|
||||||
|
*/
|
||||||
|
private $mode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parsable content object
|
||||||
|
*/
|
||||||
|
private $action;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class prefix
|
||||||
|
*/
|
||||||
|
private $prefix = 'ZAP';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public function __construct($mode = 'home') {
|
||||||
|
$mode = trim(strip_tags($mode));
|
||||||
|
$this->mode = ucfirst($mode);
|
||||||
|
$clazz = $this->prefix . $this->mode;
|
||||||
|
if (!class_exists($clazz)) {
|
||||||
|
die('Wrong parameter');
|
||||||
|
}
|
||||||
|
$this->action = new $clazz();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string content
|
||||||
|
*/
|
||||||
|
public function fetch() {
|
||||||
|
return $this->action->getContent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
91
lib/ZAPDisplay.class.php
Executable file
91
lib/ZAPDisplay.class.php
Executable file
|
|
@ -0,0 +1,91 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Class is responsible for starting up ZAP machine
|
||||||
|
*/
|
||||||
|
class ZAPDisplay {
|
||||||
|
/**
|
||||||
|
* Template file
|
||||||
|
*/
|
||||||
|
private $template = 'display';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Folder string
|
||||||
|
*/
|
||||||
|
private $folder = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Words array
|
||||||
|
*/
|
||||||
|
private $words = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Content string
|
||||||
|
*/
|
||||||
|
private $tpl = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public function __construct() {
|
||||||
|
ob_start();
|
||||||
|
$this->folder = $this->createFolder();
|
||||||
|
$this->words = $this->handleWords();
|
||||||
|
|
||||||
|
$_SESSION['words'] = $this->words;
|
||||||
|
$_SESSION['folder'] = $this->folder;
|
||||||
|
$_SESSION['collages'] = (int) $_POST['collages']; //number of zaps
|
||||||
|
$_SESSION['width'] = (int) $_POST['width'];
|
||||||
|
$_SESSION['height'] = (int) $_POST['height'];
|
||||||
|
$_SESSION['date'] = ZAP_MOMENT;
|
||||||
|
|
||||||
|
$ver = ZAP_VERSION;
|
||||||
|
include getZAPTemplate($this->template);
|
||||||
|
$this->tpl .= ob_get_clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create folder and return path
|
||||||
|
* @return string $folder path or throws exception
|
||||||
|
*/
|
||||||
|
private function createFolder() {
|
||||||
|
try {
|
||||||
|
$folder = ZAP_APP_BASE_DIR . DIRECTORY_SEPARATOR
|
||||||
|
. ZAP_SESSIONS_DIR . DIRECTORY_SEPARATOR . 'zap_' . ZAP_MOMENT;
|
||||||
|
if (!@mkdir($folder, 0777)) {
|
||||||
|
throw new Exception('<p>' . ERROR_PREFIX . 'Unable to create base dir: ' . $folder . '</p>');
|
||||||
|
}
|
||||||
|
return $folder;
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->tpl .= $e->getMessage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an array based on post data
|
||||||
|
* @return array $words
|
||||||
|
*/
|
||||||
|
private function handleWords() {
|
||||||
|
$words = array();
|
||||||
|
$ix = 1;
|
||||||
|
$postix = sprintf("%02d", $ix);
|
||||||
|
$wd = 'word' . $postix;
|
||||||
|
|
||||||
|
while(!empty($_POST[$wd])) {
|
||||||
|
array_push($words, $_POST[$wd]);
|
||||||
|
$ix++;
|
||||||
|
$postfix = sprintf("%02d", $ix);
|
||||||
|
$wd = 'word' . $postfix;
|
||||||
|
}
|
||||||
|
return $words;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return rendered content
|
||||||
|
*/
|
||||||
|
public function getContent() {
|
||||||
|
return $this->tpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
40
lib/ZAPHome.class.php
Executable file
40
lib/ZAPHome.class.php
Executable file
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Index class
|
||||||
|
*/
|
||||||
|
class ZAPHome {
|
||||||
|
/**
|
||||||
|
* Template file prefix
|
||||||
|
*/
|
||||||
|
private $template = 'index';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ZAP version
|
||||||
|
*/
|
||||||
|
private $ver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parsable content
|
||||||
|
*/
|
||||||
|
private $tpl = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public function __construct() {
|
||||||
|
$this->ver = ZAP_VERSION;
|
||||||
|
extract(get_object_vars($this));
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
include getZAPTemplate($this->template);
|
||||||
|
$this->tpl .= ob_get_clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return cotent string
|
||||||
|
*/
|
||||||
|
public function getContent() {
|
||||||
|
return $this->tpl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
121
lib/ZAPZap.class.php
Executable file
121
lib/ZAPZap.class.php
Executable file
|
|
@ -0,0 +1,121 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* ZAP factory
|
||||||
|
*/
|
||||||
|
class ZAPZap {
|
||||||
|
private $tpl = '';
|
||||||
|
private $folder;
|
||||||
|
private $height;
|
||||||
|
private $width;
|
||||||
|
private $words;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
ob_start();
|
||||||
|
if (!isset($_SESSION['collages']) || $_SESSION['collages'] <= 0) {
|
||||||
|
$this->destroySession();
|
||||||
|
$this->tpl .= ob_get_clean();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->width = $_SESSION['width'];
|
||||||
|
$this->height = $_SESSION['height'];
|
||||||
|
$this->folder = $_SESSION['folder'];
|
||||||
|
$this->words = $_SESSION['words'];
|
||||||
|
|
||||||
|
if (!empty($this->words)) {
|
||||||
|
// Still downloading source images for the words.
|
||||||
|
$this->showFoundImage();
|
||||||
|
} elseif (empty($_SESSION['images'])) {
|
||||||
|
// Start a new collage.
|
||||||
|
$this->buildNextCollage();
|
||||||
|
} else {
|
||||||
|
// Add another source image to the current collage.
|
||||||
|
$imgName = array_shift($_SESSION['images']);
|
||||||
|
$image = $this->createImage($_SESSION['collageNr']);
|
||||||
|
$image->addToCanvas($imgName);
|
||||||
|
}
|
||||||
|
$this->tpl .= ob_get_clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the next collage if any remain, otherwise finish.
|
||||||
|
*/
|
||||||
|
private function buildNextCollage() {
|
||||||
|
if ($_SESSION['collages'] <= 0) {
|
||||||
|
$this->destroySession();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// On the very first collage, load the downloaded source images.
|
||||||
|
// On later collages, reuse the original list.
|
||||||
|
if (!isset($_SESSION['imgOriginal'])) {
|
||||||
|
$_SESSION['images'] = ImgTools::convertGifsToPng($this->retrieveImages());
|
||||||
|
$_SESSION['imgOriginal'] = $_SESSION['images'];
|
||||||
|
} else {
|
||||||
|
$_SESSION['images'] = $_SESSION['imgOriginal'];
|
||||||
|
shuffle($_SESSION['images']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($_SESSION['images'])) {
|
||||||
|
$this->destroySession();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Track the current collage number separately so addToCanvas always
|
||||||
|
// reads/writes the same file while this collage is being built.
|
||||||
|
$_SESSION['collageNr'] = $_SESSION['collages'];
|
||||||
|
$_SESSION['collages']--;
|
||||||
|
|
||||||
|
$firstIm = array_shift($_SESSION['images']);
|
||||||
|
$image = $this->createImage($_SESSION['collageNr']);
|
||||||
|
$image->createBasicCanvas($firstIm);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createImage($collages) {
|
||||||
|
return new ImgProcess($this->folder, $this->width, $this->height, $collages);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function destroySession() {
|
||||||
|
if (Session::destroy()) {
|
||||||
|
$this->tpl .= "<p>" . ERROR_PREFIX . "Image ready</p>";
|
||||||
|
} else {
|
||||||
|
$this->tpl .= "<p>" . ERROR_PREFIX . "Strange... Could not end PHP session";
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function setSessionVar($key, $value) {
|
||||||
|
$_SESSION[$key] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function showFoundImage() {
|
||||||
|
$keyWord = array_shift($this->words);
|
||||||
|
$search = new ImgSearch($this->folder, $keyWord);
|
||||||
|
$imageUrl = $search->getImage();
|
||||||
|
|
||||||
|
if ($imageUrl) {
|
||||||
|
ImgIOTools::urlOnScreen($imageUrl);
|
||||||
|
} else {
|
||||||
|
ImgIOTools::urlOnScreen(ZAP_APP_BASE_DIR . DIRECTORY_SEPARATOR
|
||||||
|
. ZAP_WEB_DIR . DIRECTORY_SEPARATOR
|
||||||
|
. 'images' . DIRECTORY_SEPARATOR . 'error_noHit.png');
|
||||||
|
}
|
||||||
|
$this->setSessionVar('words', $this->words);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function retrieveImages() {
|
||||||
|
$img_ar = glob('{' . $this->folder . DIRECTORY_SEPARATOR .'*.jpg,'
|
||||||
|
. $this->folder . DIRECTORY_SEPARATOR .'*.png,'
|
||||||
|
. $this->folder . DIRECTORY_SEPARATOR .'*.jpeg,'
|
||||||
|
. $this->folder . DIRECTORY_SEPARATOR .'*.JPG,'
|
||||||
|
. $this->folder . DIRECTORY_SEPARATOR .'*.gif'
|
||||||
|
. '}', GLOB_BRACE);
|
||||||
|
shuffle($img_ar);
|
||||||
|
return $img_ar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getContent() {
|
||||||
|
return $this->tpl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
70
resource/Brave.class.php
Normal file
70
resource/Brave.class.php
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
<?php
|
||||||
|
class Brave implements Search {
|
||||||
|
private $key = BRAVE_API_KEY;
|
||||||
|
private $base_url = BRAVE_BASE;
|
||||||
|
private $q_prefix = '?q=';
|
||||||
|
private $count_prefix = '&count=';
|
||||||
|
private $adultPrefix = '&safesearch=';
|
||||||
|
|
||||||
|
private $word;
|
||||||
|
private $start;
|
||||||
|
private $size;
|
||||||
|
private $myCurl;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
if (ZAP_ADULT == true) {
|
||||||
|
$this->adultPrefix .= 'off';
|
||||||
|
} else {
|
||||||
|
$this->adultPrefix .= 'strict';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setQuery($word) {
|
||||||
|
$this->word = $word;
|
||||||
|
|
||||||
|
$request = $this->q_prefix . urlencode($word);
|
||||||
|
if (isset($this->start)) {
|
||||||
|
$request .= '&offset=' . $this->start;
|
||||||
|
}
|
||||||
|
$request .= $this->count_prefix . (isset($this->size) ? (int)$this->size : 3);
|
||||||
|
$request .= $this->adultPrefix;
|
||||||
|
|
||||||
|
$this->myCurl = new ZAPCurl($this->base_url . $request, false);
|
||||||
|
$this->myCurl->setHeader('X-Subscription-Token', $this->key);
|
||||||
|
$this->myCurl->setHeader('Accept', 'application/json');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setParam($key, $value) {
|
||||||
|
$this->$key = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getData() {
|
||||||
|
$return_array = $this->prepareData();
|
||||||
|
return $return_array;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare a project wide universal array with results
|
||||||
|
*/
|
||||||
|
private function prepareData() {
|
||||||
|
$json = $this->myCurl->fetchCurlData();
|
||||||
|
$se_data = json_decode($json, true);
|
||||||
|
|
||||||
|
if (!isset($se_data['results'][0]['properties']['url'])) {
|
||||||
|
$data['result'] = false;
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['result'] = true;
|
||||||
|
$data['engine'] = __CLASS__;
|
||||||
|
$i = 0;
|
||||||
|
foreach($se_data['results'] as $result) {
|
||||||
|
$data['results'][$i]['clickurl'] = $result['properties']['url'];
|
||||||
|
$data['results'][$i]['referer'] = isset($result['url']) ? $result['url'] : '';
|
||||||
|
$data['results'][$i]['thumb'] = isset($result['thumbnail']['src']) ? $result['thumbnail']['src'] : '';
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
25
resource/Search.interface.php
Executable file
25
resource/Search.interface.php
Executable file
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Interface for search engine implementations
|
||||||
|
*/
|
||||||
|
interface Search {
|
||||||
|
/**
|
||||||
|
* Set query word to search for
|
||||||
|
* @param string $word
|
||||||
|
*/
|
||||||
|
public function setQuery($word);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set additional parameters
|
||||||
|
* @param string $key
|
||||||
|
* @param string $value
|
||||||
|
*/
|
||||||
|
public function setParam($key, $value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get received data as array
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getData();
|
||||||
|
}
|
||||||
|
?>
|
||||||
24
tpl/display.tpl
Executable file
24
tpl/display.tpl
Executable file
|
|
@ -0,0 +1,24 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Zap Machine <?php echo $ver; ?></title>
|
||||||
|
<link rel="stylesheet" media="screen" href="css/style.css">
|
||||||
|
<script src="js/display.js"></script>
|
||||||
|
</head>
|
||||||
|
<body onload="go(this,['img1','img2'],5000);">
|
||||||
|
<table style="width:100%; height:100%;">
|
||||||
|
<tr>
|
||||||
|
<td style="text-align:center; vertical-align:middle;">
|
||||||
|
<img src="images/downloading.gif" id="img1" alt="">
|
||||||
|
<img src="images/downloading.gif" id="img2" style="display:none;" alt="">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div id="ready"></div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
46
tpl/index.tpl
Executable file
46
tpl/index.tpl
Executable file
|
|
@ -0,0 +1,46 @@
|
||||||
|
<?php $status = isset($_GET['stat']) ? $_GET['stat'] : ''; ?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Zap ZapMachine <?php echo $ver; ?></title>
|
||||||
|
<link rel="stylesheet" media="screen" href="css/style.css">
|
||||||
|
<script src="js/main.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Zap Machine <?php echo $ver; ?></h1>
|
||||||
|
<!--input modus: words-->
|
||||||
|
<div id="inpWords" class="inpSection">
|
||||||
|
<h2>Input words</h2>
|
||||||
|
<form id="form1" action="index.php?mode=display" method="post">
|
||||||
|
<?php for ($i = 1; $i <= MAX_WORDS; $i++) : ?>
|
||||||
|
<?php $nr = sprintf("%02d", $i); ?>
|
||||||
|
<div class="inp">
|
||||||
|
word <?php echo $nr; ?><input type="text" name="word<?php echo $nr; ?>" id="word<?php echo $nr; ?>" size="30" maxlength="30" value="">
|
||||||
|
</div>
|
||||||
|
<?php endfor; ?>
|
||||||
|
<div class="inp">
|
||||||
|
# Zaps
|
||||||
|
<select name="collages">
|
||||||
|
<?php for ($j = 1; $j <= MAX_ZAPS; $j++) : ?>
|
||||||
|
<option <?php echo $j == 4 ? 'selected' : ''; ?>><?php echo $j; ?></option>
|
||||||
|
<?php endfor; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="inp">
|
||||||
|
width <input type="text" name="width" id="width" size="5" maxlength="4" value="1067"> px
|
||||||
|
</div>
|
||||||
|
<div class="inp">
|
||||||
|
height <input type="text" name="height" id="height" size="5" maxlength="4" value="600"> px
|
||||||
|
</div>
|
||||||
|
<div class="inp">
|
||||||
|
<input type="button" class="btn" onclick="form1Submit()" value="Go & Generate Some Zaps">
|
||||||
|
<input type="hidden" name="modus" value="words">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<!--End input modus words-->
|
||||||
|
<div id="status"><?php echo $status; ?></div>
|
||||||
|
<div id="loading"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
28
utils/Log.class.php
Executable file
28
utils/Log.class.php
Executable file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Puts log information on images in two files
|
||||||
|
*/
|
||||||
|
class Log {
|
||||||
|
private $folder;
|
||||||
|
|
||||||
|
private $logFileName;
|
||||||
|
|
||||||
|
private $logFileXmlName;
|
||||||
|
|
||||||
|
function __construct($imgFolder) {
|
||||||
|
$this->folder = $imgFolder;
|
||||||
|
|
||||||
|
$this->logFileName = $imgFolder . DIRECTORY_SEPARATOR . 'log.txt';
|
||||||
|
$this->logFileXmlName = $imgFolder . DIRECTORY_SEPARATOR . 'log.xml';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addToLog($type, $head, $addString) {
|
||||||
|
$addToLog = "$head $addString" . PHP_EOL;
|
||||||
|
$addToXmlLog = "<div class=\"$type\">" . PHP_EOL . "\t<strong>$head</strong>" . PHP_EOL;
|
||||||
|
$addToXmlLog .= "\t<p>$addString</p>" . PHP_EOL . "</div>" . PHP_EOL;
|
||||||
|
|
||||||
|
$txtOk = @file_put_contents($this->logFileName, $addToLog, FILE_APPEND);
|
||||||
|
$xmlOk = @file_put_contents($this->logFileXmlName, $addToXmlLog, FILE_APPEND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
63
utils/Session.class.php
Executable file
63
utils/Session.class.php
Executable file
|
|
@ -0,0 +1,63 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Basic session wrapper / adapter
|
||||||
|
*/
|
||||||
|
class Session {
|
||||||
|
/**
|
||||||
|
* Start session
|
||||||
|
* @param string $name name of session
|
||||||
|
* @param string $path override ini directive session.save_path
|
||||||
|
*/
|
||||||
|
public static function start($name, $path = null) {
|
||||||
|
$started = false;
|
||||||
|
if (!$started) {
|
||||||
|
session_name($name);
|
||||||
|
if ($path !== null) {
|
||||||
|
session_save_path($path);
|
||||||
|
}
|
||||||
|
session_start();
|
||||||
|
$started = true;
|
||||||
|
}
|
||||||
|
Session::setCacheControl('private');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set cache control
|
||||||
|
* @param string $value sets the http cache control value
|
||||||
|
*/
|
||||||
|
public static function setCacheControl($value) {
|
||||||
|
header('Cache-Control: ' . $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reset session array
|
||||||
|
*/
|
||||||
|
public static function reset() {
|
||||||
|
$_SESSION = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* delete client's cookie
|
||||||
|
*/
|
||||||
|
public static function deleteCookie() {
|
||||||
|
if (isset($_COOKIE[session_name()])) {
|
||||||
|
setcookie(session_name(), '', time()-42000, '/');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy session completely
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public static function destroy() {
|
||||||
|
self::reset();
|
||||||
|
self::deleteCookie();
|
||||||
|
|
||||||
|
if (session_destroy()) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
64
utils/ZAPCurl.class.php
Executable file
64
utils/ZAPCurl.class.php
Executable file
|
|
@ -0,0 +1,64 @@
|
||||||
|
<?php
|
||||||
|
class ZAPCurl {
|
||||||
|
private $url;
|
||||||
|
|
||||||
|
private $binary;
|
||||||
|
|
||||||
|
private $referer;
|
||||||
|
|
||||||
|
private $headers = array();
|
||||||
|
|
||||||
|
public $error = null;
|
||||||
|
|
||||||
|
public $httpCode = null;
|
||||||
|
|
||||||
|
//private $proxyIp = '127.0.0.1:81';
|
||||||
|
|
||||||
|
public function __construct($url, $binary = false) {
|
||||||
|
$this->url = $url;
|
||||||
|
$this->binary = $binary;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a custom header for the request
|
||||||
|
* @param string $key Header name
|
||||||
|
* @param string $value Header value
|
||||||
|
*/
|
||||||
|
public function setHeader($key, $value) {
|
||||||
|
$this->headers[] = $key . ': ' . $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Curl wrapper
|
||||||
|
* @param string $url
|
||||||
|
* @param boolean $binary
|
||||||
|
* @return mixed $curlData
|
||||||
|
*/
|
||||||
|
public function fetchCurlData() {
|
||||||
|
$cUrl = curl_init();
|
||||||
|
curl_setopt($cUrl, CURLOPT_URL, $this->url);
|
||||||
|
curl_setopt($cUrl, CURLOPT_RETURNTRANSFER, 1);
|
||||||
|
curl_setopt($cUrl, CURLOPT_TIMEOUT, ZAP_CURL_TIMEOUT);
|
||||||
|
if (isset($this->referer)) {
|
||||||
|
curl_setopt($cUrl, CURLOPT_REFERER, $this->referer);
|
||||||
|
}
|
||||||
|
if (!empty($this->headers)) {
|
||||||
|
curl_setopt($cUrl, CURLOPT_HTTPHEADER, $this->headers);
|
||||||
|
}
|
||||||
|
//curl_setopt($cUrl, CURLOPT_PROXY, $this->proxyIp);
|
||||||
|
|
||||||
|
$curlData = curl_exec($cUrl);
|
||||||
|
$this->error = curl_error($cUrl);
|
||||||
|
$this->httpCode = curl_getinfo($cUrl, CURLINFO_HTTP_CODE);
|
||||||
|
// curl_close() is deprecated as of PHP 8.5 (no effect since PHP 8.0)
|
||||||
|
|
||||||
|
if ($this->error) {
|
||||||
|
error_log('ZAPCurl error: ' . $this->error . ' URL: ' . $this->url);
|
||||||
|
} elseif ($this->httpCode >= 400) {
|
||||||
|
error_log('ZAPCurl HTTP ' . $this->httpCode . ' URL: ' . $this->url);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $curlData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
89
www/css/style.css
Executable file
89
www/css/style.css
Executable file
|
|
@ -0,0 +1,89 @@
|
||||||
|
body, html {
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
color:#000;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
padding: 12px;
|
||||||
|
border: #bbb dotted thin;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-family: Georgia, serif;
|
||||||
|
letter-spacing: 3px;
|
||||||
|
font-size: 16px;
|
||||||
|
position: relative;
|
||||||
|
margin-left: 22%;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-family: Georgia, serif;
|
||||||
|
font-size: 14px;
|
||||||
|
position: relative;
|
||||||
|
margin-left: 22%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inpSection {
|
||||||
|
margin-top: 6%;
|
||||||
|
position: relative;
|
||||||
|
border: #bbb dotted thin;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inp {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 10px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inpTxt {
|
||||||
|
width: 18px;
|
||||||
|
text-align: right;
|
||||||
|
overflow: visible;
|
||||||
|
margin-right: 20px;
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
padding: 7px 0 20px 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
margin: 12px 15px 0 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
margin: 12px 0 0 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#status {
|
||||||
|
font-size: 10px;
|
||||||
|
color: red;
|
||||||
|
margin:15px 20px 0 0;
|
||||||
|
position: relative;
|
||||||
|
left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#loading {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
background: white url('../images/downloading.gif') no-repeat fixed center center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ready {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 14px;
|
||||||
|
text-decoration: blink;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
BIN
www/images/._downloading.gif
Executable file
BIN
www/images/._downloading.gif
Executable file
Binary file not shown.
BIN
www/images/._error_noHit.png
Executable file
BIN
www/images/._error_noHit.png
Executable file
Binary file not shown.
BIN
www/images/downloading.gif
Executable file
BIN
www/images/downloading.gif
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 3 KiB |
BIN
www/images/error_noHit.png
Executable file
BIN
www/images/error_noHit.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
42
www/index.php
Executable file
42
www/index.php
Executable file
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* ZapMachine (re)based on the ZapV
|
||||||
|
* ZAPV - Zap Machine as modified by Vincent Bruijn
|
||||||
|
* that was based on ApFab - Zap Machine V0.3.2
|
||||||
|
* ApFab: thanks for the basic work,
|
||||||
|
* Vincent Bruijn thanks for enhencing
|
||||||
|
* version 0.9.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!extension_loaded('imagick')) {
|
||||||
|
echo 'Enable the php imagick extension to get this running.';
|
||||||
|
die;
|
||||||
|
}
|
||||||
|
|
||||||
|
$mode = isset($_GET['mode']) ? $_GET['mode'] : 'home';
|
||||||
|
|
||||||
|
require_once '..' . DIRECTORY_SEPARATOR . 'conf' . DIRECTORY_SEPARATOR . 'init.php';
|
||||||
|
|
||||||
|
if (defined('ZAP_DEBUG') && ZAP_DEBUG) {
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
ini_set('display_startup_errors', '1');
|
||||||
|
// Only display errors inline for HTML pages; raw image responses must stay clean.
|
||||||
|
if ($mode === 'zap') {
|
||||||
|
ini_set('display_errors', '0');
|
||||||
|
} else {
|
||||||
|
ini_set('display_errors', '1');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
error_reporting(0);
|
||||||
|
ini_set('display_errors', '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
$config = Config::getInstance();
|
||||||
|
$config->register('engines', $search_engines);
|
||||||
|
|
||||||
|
$frontcontroller = new ZAPController($mode);
|
||||||
|
$output = $frontcontroller->fetch();
|
||||||
|
|
||||||
|
print($output);
|
||||||
|
exit;
|
||||||
|
?>
|
||||||
33
www/js/display.js
Executable file
33
www/js/display.js
Executable file
|
|
@ -0,0 +1,33 @@
|
||||||
|
var go = function(b, img_id, interval) {
|
||||||
|
var i = 0;
|
||||||
|
var img0 = document.getElementById(img_id[0]);
|
||||||
|
var img1 = document.getElementById(img_id[1]);
|
||||||
|
var img = [img0, img1];
|
||||||
|
var activeImage = 1; // index of visible image
|
||||||
|
var url = 'index.php?mode=zap';
|
||||||
|
|
||||||
|
if (isNaN(interval)) {
|
||||||
|
interval = 5000;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trigger the next image fetch after the current one has loaded.
|
||||||
|
img[0].onload = img[1].onload = function() {
|
||||||
|
var inactiveImage = activeImage === 0 ? 1 : 0;
|
||||||
|
img[activeImage].style.display = 'none';
|
||||||
|
img[inactiveImage].style.display = '';
|
||||||
|
activeImage = inactiveImage;
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
img[inactiveImage].src = url + '&i=' + (i++);
|
||||||
|
}, interval);
|
||||||
|
};
|
||||||
|
|
||||||
|
// When the backend signals completion it returns a small HTML page.
|
||||||
|
// Show the ready link and stop fetching new images.
|
||||||
|
img[0].onerror = img[1].onerror = function() {
|
||||||
|
document.getElementById('ready').innerHTML = '<a href="/">Ready</a>';
|
||||||
|
};
|
||||||
|
|
||||||
|
// Kick off the first request.
|
||||||
|
img[activeImage].src = url + '&i=' + (i++);
|
||||||
|
};
|
||||||
54
www/js/main.js
Executable file
54
www/js/main.js
Executable file
|
|
@ -0,0 +1,54 @@
|
||||||
|
function IsNumeric(sText) {
|
||||||
|
var ValidChars = "0123456789";
|
||||||
|
var IsNumber=true;
|
||||||
|
var Char;
|
||||||
|
for (i = 0; i < sText.length && IsNumber == true; i++) {
|
||||||
|
Char = sText.charAt(i);
|
||||||
|
if (ValidChars.indexOf(Char) == -1) {
|
||||||
|
IsNumber = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return IsNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
function form1Submit() {
|
||||||
|
//check if form is well filled
|
||||||
|
//Minimum of two words required
|
||||||
|
var word1 = document.getElementById('word01').value;
|
||||||
|
var word2 = document.getElementById('word02').value;
|
||||||
|
var width = document.getElementById('width').value;
|
||||||
|
var height = document.getElementById('height').value;
|
||||||
|
if (word1.length <= 0) {
|
||||||
|
document.getElementById('status').innerHTML = 'Minimum of two words required';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (word2.length <= 0) {
|
||||||
|
document.getElementById('status').innerHTML = 'Minimum of two words required';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (width.length <= 0) {
|
||||||
|
document.getElementById('status').innerHTML = 'Value <b>width</b> required';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (height.length <= 0) {
|
||||||
|
document.getElementById('status').innerHTML = 'Value <b>height</b> required';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!IsNumeric(width)) {
|
||||||
|
document.getElementById('status').innerHTML = 'Value <b>width</b> needs numeric input';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!IsNumeric(height)) {
|
||||||
|
document.getElementById('status').innerHTML = 'Value <b>height</b> needs numeric input';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//tests ok
|
||||||
|
document.getElementById('status').innerHTML = ' ';
|
||||||
|
//download image visible and form invisible
|
||||||
|
document.getElementById('loading').style.visibility = 'visible';
|
||||||
|
document.getElementById('form1').style.visibility = 'hidden';
|
||||||
|
//document.getElementById('inpNrs').style.visibility = 'hidden';
|
||||||
|
|
||||||
|
//go for it!
|
||||||
|
document.getElementById('form1').submit();
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue