Add atom feed
This commit is contained in:
parent
2cea764110
commit
fb1d1557f4
8 changed files with 206 additions and 37 deletions
|
@ -2,7 +2,7 @@ FROM ubuntu/apache2
|
|||
|
||||
MAINTAINER Knah Tsaeb <knah-tsaeb_nanogal@knah-tsaeb.org>
|
||||
|
||||
LABEL version="0.1.0"
|
||||
LABEL version="0.2.0"
|
||||
LABEL description="Apache 2 / PHP / NanoGal"
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
@ -30,7 +30,7 @@ WORKDIR /var/www/
|
|||
ENTRYPOINT "start.sh"
|
||||
|
||||
# Build image
|
||||
# docker build -t nanogal:0.1.0 .
|
||||
# docker build -t nanogal:0.2.0 .
|
||||
# Run container
|
||||
# docker run -v nanogal_datas:/var/www/datas:ro -v nanogal_photos:/var/www/public/photos:ro -e TZ=UTC -p 8187:80 --name nanogal nanogal:0.1.0
|
||||
# docker run -v /opt/nanogal/datas:/var/www/datas:ro -v /opt/nanogal/photos:/var/www/public/photos:ro -e TZ=UTC -p 8187:80 --name nanogal nanogal:0.1.0
|
||||
# docker run -v nanogal_datas:/var/www/datas:ro -v nanogal_photos:/var/www/public/photos:ro -e TZ=UTC -p 8187:80 --name nanogal nanogal:0.2.0
|
||||
# docker run -v /opt/nanogal/datas:/var/www/datas:ro -v /opt/nanogal/photos:/var/www/public/photos:ro -e TZ=UTC -p 8187:80 --name nanogal nanogal:0.2.0
|
28
README.md
28
README.md
|
@ -35,7 +35,7 @@ Image use
|
|||
|
||||
```shell
|
||||
wget https://forge.leslibres.org/Knah-Tsaeb/NanoGal/raw/branch/main/Dockerfile
|
||||
docker buildx build --no-cache -t nanogal:0.1.0 .
|
||||
docker buildx build --no-cache -t nanogal:0.2.0 .
|
||||
```
|
||||
|
||||
#### Start container
|
||||
|
@ -43,13 +43,13 @@ docker buildx build --no-cache -t nanogal:0.1.0 .
|
|||
You can use native docker volume.
|
||||
|
||||
```shell
|
||||
docker run -v nanogal_datas:/var/www/datas:ro -v nanogal_photos:/var/www/public/photos:ro -e TZ=UTC -p 8187:80 --name nanogal nanogal:0.1.0
|
||||
docker run -v nanogal_datas:/var/www/datas:ro -v nanogal_photos:/var/www/public/photos:ro -e TZ=UTC -p 8187:80 --name nanogal nanogal:0.2.0
|
||||
```
|
||||
|
||||
Or use absolute path
|
||||
|
||||
```shell
|
||||
docker run -v /opt/nanogal/datas:/var/www/datas:ro -v /opt/nanogal/photos:/var/www/public/photos:ro -e TZ=UTC -p 8187:80 --name nanogal nanogal:0.1.0
|
||||
docker run -v /opt/nanogal/datas:/var/www/datas:ro -v /opt/nanogal/photos:/var/www/public/photos:ro -e TZ=UTC -p 8187:80 --name nanogal nanogal:0.2.0
|
||||
```
|
||||
|
||||
### Classic way
|
||||
|
@ -70,8 +70,8 @@ If you want, you can delete this data. Under GNU/Linux you can install `exiftool
|
|||
|
||||
### Adding your photos
|
||||
|
||||
- Simply add your photos to the `photos` directory via FTP or SFTP.
|
||||
- You can create as many subdirectories as you want.
|
||||
- Simply add your photos to the `photos` directory via FTP or SFTP or use sync app (look idea section).
|
||||
- You can create any subdirectories as you want.
|
||||
|
||||
### Adding a comment to a gallery
|
||||
|
||||
|
@ -111,7 +111,8 @@ $userConfig = [
|
|||
'thumbSize' => 250, // Thumbnail height/width (square thumbs)
|
||||
'displayExifInfo' => false, // Display Exif info in caption
|
||||
'disableCache' => false, // Enable or disable cache
|
||||
'showShareLink' => false // Show link for thumb, full, markdown link (thumb + link to full)
|
||||
'showShareLink' => false, // Show link for thumb, full, markdown link (thumb + link to full)
|
||||
'nbItemsAtom' => 25 // Number of item in atom feed
|
||||
];
|
||||
```
|
||||
|
||||
|
@ -129,12 +130,13 @@ $userConfig = [
|
|||
| displayExifInfo | bool | false | Display Exif info in caption |
|
||||
| disableCache | bool | false | Enable or disable cache |
|
||||
| showShareLink | boll | false | Show share link for thumb, full, markdown link (thumb + link to full) |
|
||||
| nbItemsAtom | int | 25 | Number of item in atom feed
|
||||
|
||||
#### Notes
|
||||
|
||||
If you change the thumbsize, thumbnails are not re-create. If the difference between older and newer size are small, I think you don't need regen all thumb. But if you prefer, you can delete `cache/thumbs/*` for force re-create thumbnails.
|
||||
|
||||
If you change any parameter, the cache file (html file) are delete and recreate.
|
||||
If you change any parameter, the cache file (html file and atom file) are delete and recreate.
|
||||
|
||||
|
||||
## Ideas
|
||||
|
@ -145,12 +147,12 @@ If you have NextCloud installed on your server, you can use it to manage your Na
|
|||
|
||||
In the NextCloud settings: Settings > Administration > External Storage:
|
||||
|
||||
| Option | Description |
|
||||
| --- | --- |
|
||||
| Folder Name | The name of the folder as it will appear in NextCloud. |
|
||||
| External Storage | Choose Local |
|
||||
| Authentication | None |
|
||||
| Configuration | Enter the path where your images are stored (the path to the NanoGal /photos directory) |
|
||||
| Option | Description |
|
||||
| --- | --- |
|
||||
| Folder Name | The name of the folder as it will appear in NextCloud. |
|
||||
| External Storage | Choose Local |
|
||||
| Authentication | None |
|
||||
| Configuration | Enter the path where your images are stored (the path to the NanoGal /photos directory) |
|
||||
|
||||
Don't forget to disable encrypt for this folder.
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ class Cache {
|
|||
private $counter = [];
|
||||
private $fileName = '../cache/cache.json';
|
||||
private $fileCache;
|
||||
static $atomFileName = '../cache/feed.atom';
|
||||
private $currentConfig;
|
||||
private $saveConfig;
|
||||
|
||||
|
@ -101,7 +102,7 @@ class Cache {
|
|||
$this->fileCache[$this->currentDir] = -1;
|
||||
}
|
||||
|
||||
if ($this->counter[$this->currentDir] !== $this->fileCache[$this->currentDir]) {
|
||||
if (!empty($this->counter[$this->currentDir]) && ($this->counter[$this->currentDir] !== $this->fileCache[$this->currentDir])) {
|
||||
$this->fileCache = array_merge($this->fileCache, $this->counter);
|
||||
return true;
|
||||
}
|
||||
|
@ -172,4 +173,37 @@ class Cache {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deleting the Atom feed cache file if exists.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
static function clearAtomFeed(): void {
|
||||
if (file_exists(self::$atomFileName)) {
|
||||
unlink(self::$atomFileName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the Atom feed cache content if file exists.
|
||||
*
|
||||
* @return string|false Returns the content of the Atom feed cache file, or false if the file does not exist.
|
||||
*/
|
||||
static function getAtomFeed(): string|false {
|
||||
if (file_exists(self::$atomFileName)) {
|
||||
return file_get_contents(self::$atomFileName);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes content to the Atom feed cache file.
|
||||
*
|
||||
* @param string $content The content to be written to the Atom feed file.
|
||||
* @return void
|
||||
*/
|
||||
static function setAtomFeed(string $content): void {
|
||||
file_put_contents(self::$atomFileName, $content);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -199,6 +199,35 @@ class FileAndDir {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a list of the most recent image files, sorted by modification time.
|
||||
*
|
||||
* @return array An array of image files with their URLs and modification times.
|
||||
*/
|
||||
public function makeMoreRecentFile(): array {
|
||||
$allFile = [];
|
||||
$directory = new \RecursiveDirectoryIterator('photos/');
|
||||
foreach (new \RecursiveIteratorIterator($directory) as $file) {
|
||||
if (in_array($directory->getFilename(), $this->config['skipObjects'])) {
|
||||
continue;
|
||||
}
|
||||
if (in_array($file->getExtension(), $this->fileExtensions['img'])) {
|
||||
$allFile[] = [
|
||||
'url' => $this->appUrl . '/' . $file->getPathname(),
|
||||
'thumb' => $this->appUrl . '/' . $this->makeImageThumbUrl($file->getPathname()),
|
||||
'tdate' => $file->getMTime(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$order = $this->config['orderBy'] === 'asc' ? 1 : -1;
|
||||
|
||||
usort($allFile, function ($a, $b) use ($order) {
|
||||
return $order * ($a['tdate'] - $b['tdate']);
|
||||
});
|
||||
return array_slice($allFile, 0, $this->config['nbItemsAtom'], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the type of file based on its extension.
|
||||
*
|
||||
|
@ -285,9 +314,16 @@ class FileAndDir {
|
|||
$ext = strtolower($pathinfo['extension']);
|
||||
if (in_array($ext, $this->fileExtensions['img'])) {
|
||||
$imageName = $file;
|
||||
|
||||
if(empty($this->currentDir)){
|
||||
$path = $imageName;
|
||||
} else {
|
||||
$path = $this->currentDir . '/' . $imageName;
|
||||
}
|
||||
|
||||
$imgParams = 'createthumb.php?' . http_build_query(
|
||||
array(
|
||||
'filename' => $this->currentDir . '/' . $imageName
|
||||
'filename' => $path
|
||||
),
|
||||
'',
|
||||
'&'
|
||||
|
|
|
@ -15,10 +15,10 @@ if (file_exists('../datas/config.php')) {
|
|||
$config = array_merge($config, $userConfig);
|
||||
}
|
||||
|
||||
$get_filename = $_GET['filename'];
|
||||
$getFilename = $_GET['filename'];
|
||||
$baseDir = getcwd();
|
||||
|
||||
if (!Utils::isPathAuthorized($get_filename)) {
|
||||
if (!Utils::isPathAuthorized($getFilename)) {
|
||||
die("ERROR 01: Unauthorized access!");
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ if (!is_dir('../cache/thumbs') && is_writable('.')) {
|
|||
mkdir('../cache/thumbs', 0700);
|
||||
}
|
||||
|
||||
$pathInfos = pathinfo($get_filename);
|
||||
$pathInfos = pathinfo($getFilename);
|
||||
$dirname = '../cache/' . str_replace('photos', 'thumbs', $pathInfos['dirname']);
|
||||
$filename = $pathInfos['filename'];
|
||||
$thumbname = '../cache/' . $dirname . '/' . $filename . '.' . $pathInfos['extension'] . '.webp';
|
||||
|
@ -40,7 +40,7 @@ if (file_exists($thumbname)) {
|
|||
exit;
|
||||
}
|
||||
|
||||
if (!is_readable($get_filename) || !is_file($get_filename)) {
|
||||
if (!is_readable($getFilename) || !is_file($getFilename)) {
|
||||
header('Content-type: image/svg+xml');
|
||||
$cannotopenImg = file_get_contents('assets/images/cannotopen.svg');
|
||||
echo $cannotopenImg;
|
||||
|
@ -55,7 +55,7 @@ if (!file_exists($dirname)) {
|
|||
|
||||
$image = new Zebra_Image();
|
||||
$image->auto_handle_exif_orientation = true;
|
||||
$image->source_path = $get_filename;
|
||||
$image->source_path = $getFilename;
|
||||
$image->target_path = $thumbname;
|
||||
|
||||
if (!$image->resize($config['thumbSize'], $config['thumbSize'], ZEBRA_IMAGE_CROP_CENTER)) {
|
||||
|
|
84
public/feed.php
Normal file
84
public/feed.php
Normal file
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
date_default_timezone_set('Europe/Paris');
|
||||
require '../vendor/autoload.php';
|
||||
|
||||
use App\FileAndDir;
|
||||
use App\Cache;
|
||||
use Utils\Utils;
|
||||
|
||||
$config = [
|
||||
'templateFile' => 'board', // Template filename (must be placed in 'public/templates' folder)
|
||||
'title' => 'NanoGal', // Text to be displayed in browser titlebar
|
||||
'description' => 'My gallery', // Use in meta tag "description"
|
||||
'author' => 'NanoGal', // Your name
|
||||
'skipObjects' => ['comment.html', '.gitkeep', 'aFolder', 'aFile.ext'], //Those files and folders will not be displayed (affects the page and the RSS feed)
|
||||
'imageCaptionPosition' => 'right', // Position of caption in lightbox
|
||||
'sortBy' => 'name', // Sort by name or date
|
||||
'orderBy' => 'desc', // Order by asc or desc
|
||||
'thumbSize' => 250, // Thumbnail height/width (square thumbs)
|
||||
'displayExifInfo' => false, // Display Exif info in caption
|
||||
'disableCache' => false, // Enable or disable cache
|
||||
'showShareLink' => false, // Show link for thumb, full, markdown link (thumb + link to full)
|
||||
'nbItemsAtom' => 25 // Number of item in atom feed
|
||||
];
|
||||
|
||||
if (file_exists('../datas/config.php')) {
|
||||
include '../datas/config.php';
|
||||
$config = array_merge($config, $userConfig);
|
||||
}
|
||||
|
||||
header('Content-Type: text/xml');
|
||||
|
||||
if ($config['disableCache'] === false) {
|
||||
$cachedFeed = Cache::getAtomFeed();
|
||||
if ($cachedFeed) {
|
||||
echo $cachedFeed;
|
||||
exit();
|
||||
}
|
||||
} else {
|
||||
Cache::clearAtomFeed();
|
||||
}
|
||||
|
||||
$gallery_link = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'];
|
||||
|
||||
$fileList = new FileAndDir('', '/', $config);
|
||||
$filterList = $fileList->makeMoreRecentFile();
|
||||
|
||||
$date = date_create();
|
||||
$updated = $date->format(DateTimeInterface::ATOM);
|
||||
|
||||
$atom = '<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||
<title>' . $config['title'] . '</title>
|
||||
<link href="' . $gallery_link . '/feed.php" rel="self" />
|
||||
<link href="' . $gallery_link . '" />
|
||||
<id>' . $gallery_link . '</id>
|
||||
<icon>assets/favicons/favicon-96x96.png</icon>
|
||||
<logo>assets/favicons/favicon-310x310.png</logo>
|
||||
<generator>NanoGal</generator>
|
||||
<author>
|
||||
<name>' . $config['author'] . '</name>
|
||||
</author>
|
||||
<updated>' . $updated . '</updated>';
|
||||
|
||||
foreach ($filterList as $value) {
|
||||
|
||||
$atom .= '
|
||||
<entry>
|
||||
<title>' . basename($value['url']) . '</title>
|
||||
<link href="' . $value['url'] . '"/>
|
||||
<id>' . $value['url'] . '</id>
|
||||
<updated>' . date(DATE_ATOM, $value['tdate']) . '</updated>
|
||||
<published>' . date(DATE_ATOM, $value['tdate']) . '</published>
|
||||
<content type="html" xml:lang="en">
|
||||
<![CDATA[
|
||||
<a href="' . $value['url'] . '"><img src="' . $value['thumb'] . '"></a>
|
||||
]]>
|
||||
</content>
|
||||
</entry>';
|
||||
}
|
||||
$atom .= "</feed>";
|
||||
if ($config['disableCache'] === false) {
|
||||
Cache::setAtomFeed($atom);
|
||||
}
|
||||
echo $atom;
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
date_default_timezone_set('Europe/Paris');
|
||||
$time_start = microtime(true);
|
||||
require '../vendor/autoload.php';
|
||||
|
||||
|
@ -18,7 +19,7 @@ Not edit this param directly
|
|||
2 - Create $userconfig array like :
|
||||
|
||||
$userConfig = [
|
||||
'templateFile' => 'board', // Template filename (must be placed in 'templates' folder)
|
||||
'templateFile' => 'board', // Template filename (must be placed in 'public/templates' folder)
|
||||
'title' => 'NanoGal', // Text to be displayed in browser titlebar
|
||||
'description' => 'My gallery', // Use in meta tag "description"
|
||||
'author' => 'NanoGal', // Your name
|
||||
|
@ -26,9 +27,11 @@ $userConfig = [
|
|||
'imageCaptionPosition' => 'right', // Position of caption in lightbox
|
||||
'sortBy' => 'name', // Sort by name or date
|
||||
'orderBy' => 'desc', // Order by asc or desc
|
||||
'thumbSize' => 250, // Thumbnail height/width (square thumbs)
|
||||
'displayExifInfo' => false, // Display Exif info in caption
|
||||
'thumbSize' => 300, // Thumbnail height/width (square thumbs)
|
||||
'disableCache' => false, // Enable or disable cache
|
||||
'showShareLink' => false, // Show link for thumb, full, markdown link (thumb + link to full)
|
||||
'nbItemsAtom' => 25 // Number of item in atom feed
|
||||
];
|
||||
*/
|
||||
$config = [
|
||||
|
@ -43,7 +46,8 @@ $config = [
|
|||
'thumbSize' => 250, // Thumbnail height/width (square thumbs)
|
||||
'displayExifInfo' => false, // Display Exif info in caption
|
||||
'disableCache' => false, // Enable or disable cache
|
||||
'showShareLink' => false // Show link for thumb, full, markdown link (thumb + link to full)
|
||||
'showShareLink' => false, // Show link for thumb, full, markdown link (thumb + link to full)
|
||||
'nbItemsAtom' => 25 // Number of item in atom feed
|
||||
];
|
||||
|
||||
if (file_exists('../datas/config.php')) {
|
||||
|
@ -55,7 +59,7 @@ $messages = '';
|
|||
|
||||
if (!function_exists('exif_read_data') && $config['displayExifInfo'] === true) {
|
||||
$display_exif = 0;
|
||||
$messages = "Error: PHP EXIF is not available. Set $display_exif = 0; in config.php to remove this message";
|
||||
$messages = "Error: PHP EXIF is not available. Set $display_exif = 0; in config.php to remove this message";
|
||||
}
|
||||
|
||||
$requestedDir = '';
|
||||
|
@ -73,12 +77,15 @@ if ($config['disableCache'] === false) {
|
|||
}
|
||||
|
||||
if ($cache->changeFile() || $cache->changeConf() || !file_exists($cacheHash . '.html') || $config['disableCache'] === true) {
|
||||
|
||||
if ($cache->changeConf()) {
|
||||
$cache->clearCache();
|
||||
}
|
||||
|
||||
if ($config['disableCache'] !== true) {
|
||||
if($cache->changeFile() || $cache->changeConf()){
|
||||
Cache::clearAtomFeed();
|
||||
}
|
||||
|
||||
if ($config['disableCache'] === false) {
|
||||
$cache->save();
|
||||
}
|
||||
|
||||
|
@ -90,12 +97,12 @@ if ($cache->changeFile() || $cache->changeConf() || !file_exists($cacheHash . '.
|
|||
|
||||
ob_start();
|
||||
$userCss = '';
|
||||
// If user set personal css rule, load it
|
||||
|
||||
if (file_exists('../datas/user.css')) {
|
||||
$userCss = '<style>'.file_get_contents('../datas/user.css').'</style>';
|
||||
$userCss = '<style>' . file_get_contents('../datas/user.css') . '</style>';
|
||||
}
|
||||
|
||||
// If template exist load it or load default template
|
||||
|
||||
if (file_exists('templates/' . $config['templateFile'] . '/' . $config['templateFile'] . '.php')) {
|
||||
require 'templates/' . $config['templateFile'] . '/' . $config['templateFile'] . '.php';
|
||||
} else {
|
||||
|
|
|
@ -7,11 +7,17 @@ use App\FileAndDir;
|
|||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title><?= $config['title']; ?></title>
|
||||
|
||||
<meta name="author" content="<?= $config['author']; ?>">
|
||||
<meta name="generator" content="NanoGal">
|
||||
<title><?= $config['title']; ?></title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="<?= $config['description']; ?>">
|
||||
|
||||
<meta name="msapplication-TileImage" content="/assets/favicons/ms-icon-144x144.png">
|
||||
<meta name="msapplication-TileColor" content="#ffffff">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link href="assets/css/glightbox.min.css" rel="stylesheet">
|
||||
<link href="templates/board/board.css" rel="stylesheet">
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="/assets/favicons/apple-icon-57x57.png">
|
||||
|
@ -26,9 +32,9 @@ use App\FileAndDir;
|
|||
<link rel="icon" type="image/png" sizes="192x192" href="/assets/favicons/android-icon-192x192.png">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="/assets/favicons/favicon-96x96.png">
|
||||
<link rel="manifest" href="/assets/favicons/manifest.json">
|
||||
<meta name="msapplication-TileColor" content="#ffffff">
|
||||
<meta name="msapplication-TileImage" content="/assets/favicons/ms-icon-144x144.png">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="alternate" href="feed.php" type="application/atom+xml" title="Atom 0.3">
|
||||
|
||||
<?= $userCss; ?>
|
||||
</head>
|
||||
|
||||
|
|
Loading…
Reference in a new issue