diff --git a/jumpapp/api/unsplashdata.php b/jumpapp/api/unsplashdata.php new file mode 100644 index 0000000..6eef9cb --- /dev/null +++ b/jumpapp/api/unsplashdata.php @@ -0,0 +1,79 @@ + + * @license MIT + */ + +// Provided by composer for psr-4 style autoloading. +require __DIR__ .'/../vendor/autoload.php'; + +$config = new Jump\Config(); +$cache = new Jump\Cache($config); + +// If this script is run via CLI then clear the cache and repopulate it, +// otherwise if run via web then get image data from cache and run this +// script asynchronously to refresh the cahce for next time. +if (http_response_code() === false) { + $cache->clear('unsplash'); + load_cache_unsplash_data(); + die('Cached data from Unsplash'); +} + +// Output header here so we can return early with a json response if there is a curl error. +header('Content-Type: application/json; charset=utf-8'); + +// Initialise a new session using the request object. +$session = new \Nette\Http\Session((new \Nette\Http\RequestFactory)->fromGlobals(), new \Nette\Http\Response); +$session->setName($config->get('sessionname')); +$session->setExpiration($config->get('sessiontimeout')); + +// Get a Nette session section for CSRF data. +$csrfsection = $session->getSection('csrf'); + +// Has a CSRF token been set up for the session yet? +if (!$csrfsection->offsetExists('token')){ + http_response_code(401); + die(json_encode(['error' => 'Session not fully set up'])); +} + +// Check CSRF token saved in session against token provided via request. +$token = isset($_GET['token']) ? $_GET['token'] : false; +if (!$token || !hash_equals($csrfsection->get('token'), $token)) { + http_response_code(401); + die(json_encode(['error' => 'API token is incorrect or missing'])); +} + +$unsplashdata = load_cache_unsplash_data(); +shell_exec('/usr/bin/nohup /usr/bin/php -f unsplashdata.php >/dev/null 2>&1 &'); +echo json_encode($unsplashdata); + +function load_cache_unsplash_data() { + global $cache, $config; + return $cache->load(cachename: 'unsplash', callback: function() use ($config) { + Crew\Unsplash\HttpClient::init([ + 'utmSource' => 'jump_startpage', + 'applicationId' => $config->get('unsplashapikey'), + ]); + // Or apply some optional filters by passing a key value array of filters + $filters = [ + 'collections' => $config->get('unsplashcollections', false), + ]; + $photo = Crew\Unsplash\Photo::random($filters); + // Download the image data from Unsplash. + $ch = curl_init(); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_URL, $photo->urls['raw'] . '&auto=compress&w=1920'); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); + curl_setopt($ch, CURLOPT_FAILONERROR, true); + $response = curl_exec($ch); + $description = $photo->description?$photo->description:'Photo'; + $unsplashdata = new stdClass(); + $unsplashdata->cssimg = $photo->urls['raw'] . '&auto=compress&w=1920'; + $unsplashdata->attribution = ''.$description.' by '.$photo->user['name'].''; + $unsplashdata->blurhash = $photo->blur_hash; + $unsplashdata->imagedatauri = 'data: '.(new \finfo(FILEINFO_MIME_TYPE))->buffer($response).';base64,'.base64_encode($response); + return $unsplashdata; + }); +} diff --git a/jumpapp/assets/css/src/index.scss b/jumpapp/assets/css/src/index.scss index 06f792b..586cc8b 100644 --- a/jumpapp/assets/css/src/index.scss +++ b/jumpapp/assets/css/src/index.scss @@ -57,7 +57,7 @@ body { } .background { - filter: brightness(0.85) blur(10px); + //filter: brightness(0.85) blur(10px); background-repeat: no-repeat; background-size: cover; background-position: center center; @@ -65,6 +65,24 @@ body { z-index: 1; } +.unsplash { + display: block; + position: fixed; + width: 100%; + bottom: 23px; + z-index: 100; + text-align: center; + font-family: 'Quicksand', sans-serif; + font-size: 11px; + opacity: 0.6; + + a { + color: inherit; + text-decoration: none; + border-bottom: 1px dotted #ffffff70; + } +} + .content { z-index: 100; display: flex; @@ -74,3 +92,89 @@ body { max-width: 650px; margin:-50px auto 0 auto; } + +.loading { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 100000; + background: #efefef; + transition: opacity .2s; + + &.complete { + opacity: 0; + z-index: 0; + } + + .lds-grid { + display: inline-block; + position: absolute; + width: 80px; + height: 80px; + top: 50%; + margin-top: -40px; + } + .lds-grid div { + position: absolute; + width: 16px; + height: 16px; + border-radius: 50%; + background: #bbb; + animation: lds-grid 1.2s linear infinite; + } + .lds-grid div:nth-child(1) { + top: 8px; + left: 8px; + animation-delay: 0s; + } + .lds-grid div:nth-child(2) { + top: 8px; + left: 32px; + animation-delay: -0.4s; + } + .lds-grid div:nth-child(3) { + top: 8px; + left: 56px; + animation-delay: -0.8s; + } + .lds-grid div:nth-child(4) { + top: 32px; + left: 8px; + animation-delay: -0.4s; + } + .lds-grid div:nth-child(5) { + top: 32px; + left: 32px; + animation-delay: -0.8s; + } + .lds-grid div:nth-child(6) { + top: 32px; + left: 56px; + animation-delay: -1.2s; + } + .lds-grid div:nth-child(7) { + top: 56px; + left: 8px; + animation-delay: -0.8s; + } + .lds-grid div:nth-child(8) { + top: 56px; + left: 32px; + animation-delay: -1.2s; + } + .lds-grid div:nth-child(9) { + top: 56px; + left: 56px; + animation-delay: -1.6s; + } + @keyframes lds-grid { + 0%, 100% { + opacity: 1; + } + 50% { + opacity: 0.5; + } + } +} \ No newline at end of file diff --git a/jumpapp/assets/js/src/classes/Main.js b/jumpapp/assets/js/src/classes/Main.js index 2e6b579..fbea31c 100644 --- a/jumpapp/assets/js/src/classes/Main.js +++ b/jumpapp/assets/js/src/classes/Main.js @@ -49,6 +49,20 @@ export default class Main { * Get data from OWM and do stuff with it. */ init() { + // Let's display some images from unsplash then shall we... + if (JUMP.unsplash) { + fetch('/api/unsplashdata.php?token=' + JUMP.token) + .then(response => response.json()) + .then(data => { + if (data.error) { + console.error('JUMP ERROR: There was an issue with the Unsplash API... ' + data.error); + return; + } + document.querySelector('.background').style.backgroundImage = 'url("' + data.imagedatauri + '")'; + document.querySelector('.unsplash').innerHTML = data.attribution; + }); + } + // Start listening for events so we can do stuff when needed. this.add_event_listeners(); // If there is no OWM API key provided then just update the greeting diff --git a/jumpapp/background-css.php b/jumpapp/background-css.php index c4489cc..fc4ee43 100644 --- a/jumpapp/background-css.php +++ b/jumpapp/background-css.php @@ -10,10 +10,15 @@ require __DIR__ .'/vendor/autoload.php'; $config = new Jump\Config(); -$backgroundimgfile = (new Jump\Background($config))->get_random_background_file(); $blur = floor((int)$config->get('bgblur', false) / 100 * 15); $brightness = (int)$config->get('bgbright', false) ? (int)$config->get('bgbright', false) / 100 : 1; +$bgurlstring = ''; +if ($config->get('unsplashapikey', false) == null) { + $backgroundimgfile = (new Jump\Background($config))->get_random_background_file(); + $bgurlstring = 'background-image: url("'.$backgroundimgfile.'");'; +} + header('Content-Type: text/css'); -echo '.background {background-image: url("'.$backgroundimgfile.'");filter: brightness('.$brightness.') blur('.$blur.'px);}'; +echo '.background {'.$bgurlstring.'filter: brightness('.$brightness.') blur('.$blur.'px);}'; diff --git a/jumpapp/classes/Cache.php b/jumpapp/classes/Cache.php index 8428486..92dcfd1 100644 --- a/jumpapp/classes/Cache.php +++ b/jumpapp/classes/Cache.php @@ -60,6 +60,11 @@ class Cache { $config->get('templatedir').'/errorpage.mustache' ] ], + 'unsplash' => [ + 'cache' => null, + 'expirationtype' => Caching\Cache::EXPIRE, + 'expirationparams' => '5 minutes' + ], 'weatherdata' => [ 'cache' => null, 'expirationtype' => Caching\Cache::EXPIRE, @@ -71,19 +76,13 @@ class Cache { } /** - * Read the specified item from the cache or generate it, mostly a wrapper - * around Nette\Caching\Cache::load(). + * Validate and inititalise the specified cache. * * @param string $cachename The name of a cache, must match a key in $caches definition. - * @param string $key A key used to represent an object within a cache, - * @param callable $callback The code from which the result should be stored in cache. - * @return mixed The result of callback function retreieved from cache. + * @param string $key A key used to represent an object within a cache. + * @return void */ - public function load(string $cachename, ?string $key = 'default', callable $callback): mixed { - // If cachebypass has been set in config.php then just execute the callback. - if ($this->config->parse_bool($this->config->get('cachebypass'))) { - return $callback(); - } + private function init_cache(string $cachename, ?string $key = 'default'): void { // We can only work with caches that have already been defined. if (!array_key_exists($cachename, $this->caches)) { throw new \Exception('Cache name not found ('.$cachename.')'); @@ -92,6 +91,23 @@ class Cache { if (!isset($this->caches[$cachename]['cache']) || !array_key_exists($key, $this->caches[$cachename]['cache'])) { $this->caches[$cachename]['cache'][$key] = new Caching\Cache($this->storage, $cachename.'/'.$key); } + } + + /** + * Read the specified item from the cache or generate it, mostly a wrapper + * around Nette\Caching\Cache::load(). + * + * @param string $cachename The name of a cache, must match a key in $caches definition. + * @param string $key A key used to represent an object within a cache. + * @param callable $callback The code from which the result should be stored in cache. + * @return mixed The result of callback function retreieved from cache. + */ + public function load(string $cachename, ?string $key = 'default', callable $callback): mixed { + // If cachebypass has been set in config.php then just execute the callback. + if ($this->config->parse_bool($this->config->get('cachebypass'))) { + return $callback(); + } + $this->init_cache($cachename, $key); // Retrieve the initialised cache object from $caches, defines the caches expiry // and executes the callback. return $this->caches[$cachename]['cache'][$key]->load($cachename.'/'.$key, @@ -102,4 +118,15 @@ class Cache { ); } + /** + * Remove the specified item from the cache. + * + * @param string $cachename The name of a cache, must match a key in $caches definition. + * @param string $key A key used to represent an object within a cache. + * @return void + */ + public function clear(string $cachename, ?string $key = 'default'): void { + $this->init_cache($cachename, $key); + $this->caches[$cachename]['cache'][$key]->remove($cachename.'/'.$key); + } } diff --git a/jumpapp/classes/Pages/HomePage.php b/jumpapp/classes/Pages/HomePage.php index d944c79..898d02e 100644 --- a/jumpapp/classes/Pages/HomePage.php +++ b/jumpapp/classes/Pages/HomePage.php @@ -19,11 +19,13 @@ class HomePage extends AbstractPage { 'owmapikey' => !!$this->config->get('owmapikey', false), 'metrictemp' => $this->config->parse_bool($this->config->get('metrictemp')), 'ampmclock' => $this->config->parse_bool($this->config->get('ampmclock', false)), + 'unsplash' => !!$this->config->get('unsplashapikey', false), ]; if ($this->config->parse_bool($this->config->get('showsearch', false))) { - $templatecontext = array_merge($templatecontext, - ['searchengines' => json_encode((new \Jump\SearchEngines($this->config, $this->cache))->get_search_engines()), - 'searchjson' => json_encode((new \Jump\Sites($this->config, $this->cache))->get_sites_for_search()),]); + $templatecontext = array_merge($templatecontext, [ + 'searchengines' => json_encode((new \Jump\SearchEngines($this->config, $this->cache))->get_search_engines()), + 'searchjson' => json_encode((new \Jump\Sites($this->config, $this->cache))->get_sites_for_search()), + ]); } return $template->render($templatecontext); } diff --git a/jumpapp/composer.json b/jumpapp/composer.json index d5c748b..fa69633 100644 --- a/jumpapp/composer.json +++ b/jumpapp/composer.json @@ -10,6 +10,7 @@ "nette/caching": "^3.1", "nette/routing": "^3.0.2", "phlak/config": "^7.0", - "nette/http": "^3.1" + "nette/http": "^3.1", + "unsplash/unsplash": "^2.5" } } diff --git a/jumpapp/composer.lock b/jumpapp/composer.lock index 15d0c0e..a014e54 100644 --- a/jumpapp/composer.lock +++ b/jumpapp/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "860d4eabaa4ccb80ee0f7d501149c83d", + "content-hash": "b9a1f35bbb450ef26b01fa2f565c7d85", "packages": [ { "name": "arthurhoaro/favicon", @@ -59,6 +59,379 @@ ], "time": "2021-08-06T05:41:25+00:00" }, + { + "name": "guzzlehttp/guzzle", + "version": "6.5.6", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "f092dd734083473658de3ee4bef093ed77d2689c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f092dd734083473658de3ee4bef093ed77d2689c", + "reference": "f092dd734083473658de3ee4bef093ed77d2689c", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.6.1", + "php": ">=5.5", + "symfony/polyfill-intl-idn": "^1.17.0" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", + "psr/log": "^1.1" + }, + "suggest": { + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.5-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2022-05-25T13:19:12+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "1.5.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "fe752aedc9fd8fcca3fe7ad05d419d32998a06da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/fe752aedc9fd8fcca3fe7ad05d419d32998a06da", + "reference": "fe752aedc9fd8fcca3fe7ad05d419d32998a06da", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "symfony/phpunit-bridge": "^4.4 || ^5.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "time": "2021-10-22T20:56:57+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.8.5", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "337e3ad8e5716c15f9657bd214d16cc5e69df268" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/337e3ad8e5716c15f9657bd214d16cc5e69df268", + "reference": "337e3ad8e5716c15f9657bd214d16cc5e69df268", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-zlib": "*", + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "time": "2022-03-20T21:51:18+00:00" + }, + { + "name": "hughbertd/oauth2-unsplash", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/HughbertD/oauth2-unsplash.git", + "reference": "f451f4a49dca4027f6edaa850d2fccdfa8721bfe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/HughbertD/oauth2-unsplash/zipball/f451f4a49dca4027f6edaa850d2fccdfa8721bfe", + "reference": "f451f4a49dca4027f6edaa850d2fccdfa8721bfe", + "shasum": "" + }, + "require": { + "league/oauth2-client": ">=1.0", + "php": ">=5.6.0" + }, + "require-dev": { + "mockery/mockery": "~0.9", + "phpunit/phpunit": "~5.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Unsplash\\OAuth2\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Hugh Downer", + "email": "hugh.downer@gmail.com" + } + ], + "description": "Unsplash OAuth 2.0 Client Provider for The PHP League OAuth2-Client", + "keywords": [ + "Authentication", + "SSO", + "Unsplash", + "authorization", + "identity", + "idp", + "oauth", + "oauth2", + "single sign on" + ], + "time": "2017-12-14T13:08:42+00:00" + }, + { + "name": "league/oauth2-client", + "version": "2.6.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/oauth2-client.git", + "reference": "2334c249907190c132364f5dae0287ab8666aa19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/oauth2-client/zipball/2334c249907190c132364f5dae0287ab8666aa19", + "reference": "2334c249907190c132364f5dae0287ab8666aa19", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^6.0 || ^7.0", + "paragonie/random_compat": "^1 || ^2 || ^9.99", + "php": "^5.6 || ^7.0 || ^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.3.5", + "php-parallel-lint/php-parallel-lint": "^1.3.1", + "phpunit/phpunit": "^5.7 || ^6.0 || ^9.5", + "squizlabs/php_codesniffer": "^2.3 || ^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\OAuth2\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alex Bilbie", + "email": "hello@alexbilbie.com", + "homepage": "http://www.alexbilbie.com", + "role": "Developer" + }, + { + "name": "Woody Gilk", + "homepage": "https://github.com/shadowhand", + "role": "Contributor" + } + ], + "description": "OAuth 2.0 Client Library", + "keywords": [ + "Authentication", + "SSO", + "authorization", + "identity", + "idp", + "oauth", + "oauth2", + "single sign on" + ], + "time": "2021-12-22T16:42:49+00:00" + }, { "name": "mustache/mustache", "version": "v2.14.1", @@ -448,6 +821,51 @@ ], "time": "2022-01-24T11:29:14+00:00" }, + { + "name": "paragonie/random_compat", + "version": "v9.99.100", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", + "shasum": "" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "time": "2020-10-15T08:29:30+00:00" + }, { "name": "phlak/config", "version": "7.0.0", @@ -492,6 +910,96 @@ "description": "Config loading and management", "time": "2020-03-16T18:49:13+00:00" }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "time": "2019-03-08T08:55:37+00:00" + }, { "name": "symfony/deprecation-contracts", "version": "v2.5.0", @@ -607,6 +1115,202 @@ ], "time": "2021-10-20T20:35:02+00:00" }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.25.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "749045c69efb97c70d25d7463abba812e91f3a44" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/749045c69efb97c70d25d7463abba812e91f3a44", + "reference": "749045c69efb97c70d25d7463abba812e91f3a44", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "symfony/polyfill-intl-normalizer": "^1.10", + "symfony/polyfill-php72": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "time": "2021-09-14T14:02:44+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.25.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", + "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "time": "2021-02-19T12:13:01+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.25.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "9a142215a36a3888e30d0a9eeea9766764e96976" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9a142215a36a3888e30d0a9eeea9766764e96976", + "reference": "9a142215a36a3888e30d0a9eeea9766764e96976", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2021-05-27T09:17:38+00:00" + }, { "name": "symfony/yaml", "version": "v5.4.3", @@ -665,6 +1369,65 @@ "homepage": "https://symfony.com", "time": "2022-01-26T16:32:32+00:00" }, + { + "name": "unsplash/unsplash", + "version": "2.5.1", + "source": { + "type": "git", + "url": "https://github.com/unsplash/unsplash-php.git", + "reference": "998cc023b8f8c6e68f45b750e61a6e21ae15ff02" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/unsplash/unsplash-php/zipball/998cc023b8f8c6e68f45b750e61a6e21ae15ff02", + "reference": "998cc023b8f8c6e68f45b750e61a6e21ae15ff02", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^6.3.0", + "hughbertd/oauth2-unsplash": ">=1.0.3", + "league/oauth2-client": ">=1.4.2", + "php": ">=5.6.0" + }, + "require-dev": { + "mockery/mockery": "~0.9.0", + "php-vcr/php-vcr": "dev-master", + "php-vcr/phpunit-testlistener-vcr": "*", + "phpunit/phpunit": "~5.1", + "satooshi/php-coveralls": "dev-master", + "vlucas/phpdotenv": "dev-master" + }, + "type": "library", + "autoload": { + "psr-4": { + "Crew\\Unsplash\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Klaassen", + "email": "aaron@unsplash.com" + }, + { + "name": "Luke Chesser", + "email": "luke@unsplash.com" + }, + { + "name": "Charles Lalonde", + "email": "charles@pickcrew.com" + }, + { + "name": "Hugh Downer", + "email": "hugh.downer@gmail.com" + } + ], + "description": "Wrapper to access the Unsplash API and photo library", + "time": "2020-04-07T17:44:24+00:00" + }, { "name": "yosymfony/parser-utils", "version": "v2.0.0", diff --git a/jumpapp/config.php b/jumpapp/config.php index 38c8f1a..22517bc 100644 --- a/jumpapp/config.php +++ b/jumpapp/config.php @@ -17,22 +17,27 @@ return [ // Where is the cache storage directory, should not be public. 'cachedir' => getenv('CACHEDIR') ?: '/var/www/cache', - // Include the robots noindex meta tag in site header. - 'noindex' => getenv('NOINDEX') ?: true, + // Display alternative layout of sites list. + 'altlayout' => getenv('ALTLAYOUT') ?: false, // Should the clock be displayed? 'showclock' => getenv('SHOWCLOCK') ?: true, // 12 hour clock format? 'ampmclock' => getenv('AMPMCLOCK') ?: false, // Show a friendly greeting message rather than "#home". 'showgreeting' => getenv('SHOWGREETING') ?: true, + // Show the search bar, requires /search/searchengines.json etc. + 'showsearch' => getenv('SHOWSEARCH') ?: true, + // Include the robots noindex meta tag in site header. + 'noindex' => getenv('NOINDEX') ?: true, + // Background blur percentage. 'bgblur' => getenv('BGBLUR') ?: '70', // Background brightness percentage. 'bgbright' => getenv('BGBRIGHT') ?: '85', - // Display alternative layout of sites list. - 'altlayout' => getenv('ALTLAYOUT') ?: false, - // Show the search bar, requires /search/searchengines.json etc. - 'showsearch' => getenv('SHOWSEARCH') ?: true, + // Unsplash API key, when added will use Unsplash background images. + 'unsplashapikey' => getenv('UNSPLASHAPIKEY') ?: false, + // Unsplash collection name to pick random image from. + 'unsplashcollections' => getenv('UNSPLASHCOLLECTIONS') ?: '', // Open Weather Map API key. 'owmapikey' => getenv('OWMAPIKEY') ?: '', diff --git a/jumpapp/templates/footer.mustache b/jumpapp/templates/footer.mustache index 166d107..20bcf5f 100644 --- a/jumpapp/templates/footer.mustache +++ b/jumpapp/templates/footer.mustache @@ -31,7 +31,8 @@ {{/ hastags}} +
- +