Initial commit
This commit is contained in:
commit
74ff514a6e
47
.gitignore
vendored
Normal file
47
.gitignore
vendored
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
config.php
|
||||||
|
|
||||||
|
# Created by https://www.toptal.com/developers/gitignore/api/macos,composer
|
||||||
|
# Edit at https://www.toptal.com/developers/gitignore?templates=macos,composer
|
||||||
|
|
||||||
|
### Composer ###
|
||||||
|
composer.phar
|
||||||
|
/vendor/
|
||||||
|
|
||||||
|
# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control
|
||||||
|
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
|
||||||
|
# composer.lock
|
||||||
|
|
||||||
|
### macOS ###
|
||||||
|
# General
|
||||||
|
.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
|
||||||
|
# Icon must end with two \r
|
||||||
|
Icon
|
||||||
|
|
||||||
|
|
||||||
|
# Thumbnails
|
||||||
|
._*
|
||||||
|
|
||||||
|
# Files that might appear in the root of a volume
|
||||||
|
.DocumentRevisions-V100
|
||||||
|
.fseventsd
|
||||||
|
.Spotlight-V100
|
||||||
|
.TemporaryItems
|
||||||
|
.Trashes
|
||||||
|
.VolumeIcon.icns
|
||||||
|
.com.apple.timemachine.donotpresent
|
||||||
|
|
||||||
|
# Directories potentially created on remote AFP share
|
||||||
|
.AppleDB
|
||||||
|
.AppleDesktop
|
||||||
|
Network Trash Folder
|
||||||
|
Temporary Items
|
||||||
|
.apdisk
|
||||||
|
|
||||||
|
### macOS Patch ###
|
||||||
|
# iCloud generated files
|
||||||
|
*.icloud
|
||||||
|
|
||||||
|
# End of https://www.toptal.com/developers/gitignore/api/macos,composer
|
25
composer.json
Normal file
25
composer.json
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"name": "phlaym/photoprism-slideshow",
|
||||||
|
"require": {
|
||||||
|
"php": "^8.0",
|
||||||
|
"phlaym/photoprism-api": "dev-main"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"PhotoPrismUpload\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Max Nuding",
|
||||||
|
"email": "max.nuding@icloud.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repositories": [
|
||||||
|
{
|
||||||
|
"type": "vcs",
|
||||||
|
"url": "https://phlaym.net/git/phlaym/photoprism-api.git"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
}
|
7
config.php.EXAMPLE
Normal file
7
config.php.EXAMPLE
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'username' => 'admin',
|
||||||
|
'password' => '',
|
||||||
|
'host' => 'https://photos.phlaym.net'
|
||||||
|
];
|
403
index.html
Normal file
403
index.html
Normal file
@ -0,0 +1,403 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="theme-color" content="#ffffff" />
|
||||||
|
<script>
|
||||||
|
const darkModePreference = window.matchMedia("(prefers-color-scheme: dark)");
|
||||||
|
document.querySelector('head meta[name=theme-color]').content = darkModePreference ? '#000' : '#fff';
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--foreground: #000;
|
||||||
|
--background: #fff;
|
||||||
|
--border-light: #999;
|
||||||
|
--border-dark: #000;
|
||||||
|
}
|
||||||
|
.dark {
|
||||||
|
--foreground: #fff;
|
||||||
|
--background: #000;
|
||||||
|
--border-dark: #999;
|
||||||
|
--border-light: #fff;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
overflow-x: hidden;
|
||||||
|
max-width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
background-color: var(--background);
|
||||||
|
color: var(--foreground);
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
border-top: 2px solid var(--border-light);
|
||||||
|
border-left: 2px solid var(--border-light);
|
||||||
|
border-right: 2px solid var(--border-dark);
|
||||||
|
border-bottom: 2px solid var(--border-dark);
|
||||||
|
background-color: var(--background);
|
||||||
|
color: var(--foreground);
|
||||||
|
transition: transform 0.5s ease-in-out;
|
||||||
|
cursor: grab;
|
||||||
|
}
|
||||||
|
button:hover {
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
form {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto auto 1fr;
|
||||||
|
justify-items: left;
|
||||||
|
}
|
||||||
|
form label {
|
||||||
|
grid-column: 1/2;
|
||||||
|
}
|
||||||
|
form input {
|
||||||
|
grid-column: 2/3;
|
||||||
|
}
|
||||||
|
#headline {
|
||||||
|
grid-column: 1/4;
|
||||||
|
}
|
||||||
|
fieldset {
|
||||||
|
grid-row: 6;
|
||||||
|
}
|
||||||
|
form button[name="submit"] {
|
||||||
|
grid-column: 1;
|
||||||
|
grid-row: 7;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
input[type="number"] {
|
||||||
|
max-width: 50px;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
object-fit: contain;
|
||||||
|
transition-property: translate;
|
||||||
|
transition-timing-function: ease-in-out;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
.fast {
|
||||||
|
transition-duration: 0.5s;
|
||||||
|
}
|
||||||
|
.normal {
|
||||||
|
transition-duration: 1s;
|
||||||
|
}
|
||||||
|
.slow {
|
||||||
|
transition-duration: 2s;
|
||||||
|
}
|
||||||
|
img.instant {
|
||||||
|
transition-duration: 0s;
|
||||||
|
transition-delay: 0s;
|
||||||
|
}
|
||||||
|
.right {
|
||||||
|
translate: 200%;
|
||||||
|
}
|
||||||
|
.left {
|
||||||
|
translate: -200%;
|
||||||
|
}
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const controls = document.getElementById('controls');
|
||||||
|
initControls(controls);
|
||||||
|
|
||||||
|
const firstImage = document.getElementById('first');
|
||||||
|
const secondImage = document.getElementById('second');
|
||||||
|
const marginInput = document.getElementById('margin');
|
||||||
|
window.showTimeSeconds = 1;
|
||||||
|
window.nextPhotoOffset = 0;
|
||||||
|
window.shuffle = false;
|
||||||
|
window.photoCount = 2;
|
||||||
|
window.displayed = [];
|
||||||
|
|
||||||
|
loadNextPhoto(firstImage);
|
||||||
|
loadNextPhoto(secondImage);
|
||||||
|
|
||||||
|
marginInput.addEventListener('change', (event) => {
|
||||||
|
updateMargins(event.target.value);
|
||||||
|
});
|
||||||
|
updateMargins(marginInput.value);
|
||||||
|
|
||||||
|
document.addEventListener("keyup", (event) => {
|
||||||
|
if (event.isComposing || event.keyCode === 229) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (controls.elements['submit'].value === 'go') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (event.key) {
|
||||||
|
case 's':
|
||||||
|
controls.classList.toggle('hidden');
|
||||||
|
break;
|
||||||
|
case ' ':
|
||||||
|
if (window.isPaused) {
|
||||||
|
const first = document.getElementById('first');
|
||||||
|
const second = document.getElementById('second');
|
||||||
|
first.style.transitionDelay = window.showTimeSeconds + 's';
|
||||||
|
second.style.transitionDelay = window.showTimeSeconds + 's';
|
||||||
|
|
||||||
|
let leftElement, rightElement;
|
||||||
|
if (first.className.includes('right')) {
|
||||||
|
leftElement = second;
|
||||||
|
rightElement = first;
|
||||||
|
} else {
|
||||||
|
leftElement = first;
|
||||||
|
rightElement = second;
|
||||||
|
}
|
||||||
|
leftElement.classList.add('left');
|
||||||
|
rightElement.classList.remove('right');
|
||||||
|
window.isPaused = false;
|
||||||
|
} else {
|
||||||
|
const { left: leftElement, right: rightElement} = getImagePositions();
|
||||||
|
leftElement.style.transitionDelay = '0s';
|
||||||
|
rightElement.style.transitionDelay = '0s';
|
||||||
|
leftElement.classList.remove('left');
|
||||||
|
rightElement.classList.add('right');
|
||||||
|
window.isPaused = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'ArrowRight':
|
||||||
|
const { left: leftElement, right: rightElement} = getImagePositions();
|
||||||
|
leftElement.classList.remove('left');
|
||||||
|
rightElement.classList.add('right');
|
||||||
|
|
||||||
|
first.style.transitionDelay = '0s';
|
||||||
|
second.style.transitionDelay = '0s';
|
||||||
|
setTimeout(() => {
|
||||||
|
leftElement.classList.add('left');
|
||||||
|
rightElement.classList.remove('right');
|
||||||
|
setTimeout(() => {
|
||||||
|
first.style.transitionDelay = window.showTimeSeconds + 's';
|
||||||
|
second.style.transitionDelay = window.showTimeSeconds + 's';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'r': {
|
||||||
|
window.shuffle = !window.shuffle;
|
||||||
|
if (!window.shuffle) {
|
||||||
|
window.nextPhotoOffset;
|
||||||
|
}
|
||||||
|
const searchParams = new URLSearchParams(window.location.search);
|
||||||
|
searchParams.set('random', window.shuffle);
|
||||||
|
history.pushState(
|
||||||
|
null,
|
||||||
|
'',
|
||||||
|
window.location.pathname + '?' + searchParams.toString()
|
||||||
|
);
|
||||||
|
document.getElementById('controls').elements['random'].checked = window.shuffle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.querySelectorAll('input[name=theme]')
|
||||||
|
.forEach(i => i.addEventListener('change', (e) => setDarkMode(e.target.value === 'dark')));
|
||||||
|
|
||||||
|
controls.addEventListener('submit', (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
const data = new FormData(event.target);
|
||||||
|
window.showTimeSeconds = parseInt(data.get('showTime'));
|
||||||
|
window.shuffle = data.get('random') === 'true';
|
||||||
|
const margin = parseInt(data.get('margin'));
|
||||||
|
const speed = data.get('speed');
|
||||||
|
const theme = data.get('theme');
|
||||||
|
|
||||||
|
window.nextPhotoOffset--;
|
||||||
|
loadNextPhoto(secondImage);
|
||||||
|
|
||||||
|
document.querySelectorAll('img').forEach(i => {
|
||||||
|
i.classList.remove('normal');
|
||||||
|
i.classList.remove('slow');
|
||||||
|
i.classList.remove('fast');
|
||||||
|
i.classList.add(speed);
|
||||||
|
});
|
||||||
|
|
||||||
|
const searchParams = new URLSearchParams(window.location.search);
|
||||||
|
searchParams.set('showTime', window.showTimeSeconds);
|
||||||
|
searchParams.set('random', window.shuffle);
|
||||||
|
searchParams.set('margin', margin);
|
||||||
|
searchParams.set('speed', speed);
|
||||||
|
searchParams.set('theme', theme);
|
||||||
|
history.pushState(
|
||||||
|
null,
|
||||||
|
'',
|
||||||
|
window.location.pathname + '?' + searchParams.toString()
|
||||||
|
);
|
||||||
|
|
||||||
|
controls.classList.add('hidden');
|
||||||
|
|
||||||
|
document.getElementById('first').style.transitionDelay = window.showTimeSeconds + 's';
|
||||||
|
document.getElementById('second').style.transitionDelay = window.showTimeSeconds + 's';
|
||||||
|
|
||||||
|
if (controls.elements['submit'].value === 'save') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
firstImage.classList.remove('hidden');
|
||||||
|
secondImage.classList.remove('hidden');
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
document.getElementById('first').classList.add('left');
|
||||||
|
document.getElementById('second').classList.remove('right');
|
||||||
|
});
|
||||||
|
controls.elements['submit'].value = 'save';
|
||||||
|
controls.elements['submit'].innerText = 'Speichern';
|
||||||
|
});
|
||||||
|
|
||||||
|
let remainingTransitions = document.querySelectorAll('img').length;
|
||||||
|
addEventListener('transitionend', (event) => {
|
||||||
|
if (event.target.tagName !== 'IMG') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
remainingTransitions--;
|
||||||
|
if (remainingTransitions > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
remainingTransitions = document.querySelectorAll('img').length;
|
||||||
|
const leftElement = document.querySelector('.left');
|
||||||
|
const rightElement = document.querySelector('img:not([class~=left])');
|
||||||
|
leftElement.classList.add('instant');
|
||||||
|
leftElement.style.transitionDelay = '0s';
|
||||||
|
// Wait until 'instant' and transitionDelay are applied
|
||||||
|
setTimeout(() => {
|
||||||
|
leftElement.classList.remove('left');
|
||||||
|
leftElement.classList.add('right');
|
||||||
|
// Wait until element is moved
|
||||||
|
setTimeout(() => {
|
||||||
|
leftElement.classList.remove('instant');
|
||||||
|
leftElement.style.transitionDelay = window.showTimeSeconds + 's';
|
||||||
|
// Wait until 'instant' is removed and transitionDelay applied
|
||||||
|
setTimeout(() => {
|
||||||
|
leftElement.classList.remove('right');
|
||||||
|
rightElement.classList.add('left');
|
||||||
|
loadNextPhoto(leftElement);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function loadNextPhoto(element, overwriteOffset) {
|
||||||
|
let offset = window.nextPhotoOffset;
|
||||||
|
if (window.shuffle) {
|
||||||
|
if (window.displayed.length >= window.photoCount * 0.75) {
|
||||||
|
window.displayed = [];
|
||||||
|
}
|
||||||
|
let count = Math.floor(window.photoCount * 0.5);
|
||||||
|
do {
|
||||||
|
offset = Math.floor(Math.random() * (window.photoCount + 1));
|
||||||
|
count--;
|
||||||
|
} while (count > 0 && window.displayed.includes(offset));
|
||||||
|
}
|
||||||
|
if (overwriteOffset !== undefined) {
|
||||||
|
offset = overwriteOffset
|
||||||
|
}
|
||||||
|
const album = (new URLSearchParams(window.location.search)).get('album');
|
||||||
|
fetch(`photos.php?album=${album}&offset=${offset}`)
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((data) => {
|
||||||
|
if (data['error']) {
|
||||||
|
console.error('Error fetching photo', data['error']);
|
||||||
|
} else {
|
||||||
|
document.getElementById('headline').innerText = `Zeige Album: ${data.album}`;
|
||||||
|
element.src = data.src;
|
||||||
|
window.photoCount = data.count;
|
||||||
|
window.displayed.push(offset);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error fetching photo', error);
|
||||||
|
});
|
||||||
|
window.nextPhotoOffset = offset + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getImagePositions() {
|
||||||
|
const first = document.getElementById('first');
|
||||||
|
const second = document.getElementById('second');
|
||||||
|
|
||||||
|
let leftElement, rightElement;
|
||||||
|
if (first.className.includes('left')) {
|
||||||
|
leftElement = first;
|
||||||
|
rightElement = second;
|
||||||
|
} else {
|
||||||
|
leftElement = second;
|
||||||
|
rightElement = first;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
left: leftElement,
|
||||||
|
right: rightElement
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateMargins(margin) {
|
||||||
|
document.querySelectorAll('img').forEach(i => {
|
||||||
|
i.style.margin = margin + 'px';
|
||||||
|
i.style.width = `calc(100% - ${2*margin}px)`;
|
||||||
|
i.style.maxHeight = `calc(100% - ${2*margin}px)`;
|
||||||
|
i.style.maxWidth = `calc(100% - ${2*margin}px)`;
|
||||||
|
});
|
||||||
|
controls.style.margin = margin + 'px';
|
||||||
|
}
|
||||||
|
|
||||||
|
function initControls(form) {
|
||||||
|
const initialParams = new URLSearchParams(window.location.search);
|
||||||
|
for (const [key, val] of initialParams.entries()) {
|
||||||
|
const input = form.elements[key];
|
||||||
|
if (input === undefined) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (input.type) {
|
||||||
|
case 'checkbox':
|
||||||
|
input.checked = val === 'true';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
input.value = val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let theme =initialParams.get('theme');
|
||||||
|
if (theme === undefined || theme === null) {
|
||||||
|
const darkModePreference = window.matchMedia("(prefers-color-scheme: dark)");
|
||||||
|
theme = darkModePreference ? 'dark' : 'light';
|
||||||
|
}
|
||||||
|
form.elements['theme'].value = theme;
|
||||||
|
setDarkMode(theme === 'dark');
|
||||||
|
}
|
||||||
|
function setDarkMode(mode) {
|
||||||
|
if (mode) {
|
||||||
|
document.body.classList.add('dark');
|
||||||
|
} else {
|
||||||
|
document.body.classList.remove('dark');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<form id="controls">
|
||||||
|
<h3 id="headline">Zeige Album: </h3>
|
||||||
|
<label for="random">Zufällig</label>
|
||||||
|
<input type="checkbox" name="random" id="random" value="true"/>
|
||||||
|
<label for="showTime">Zeit zwischen Bildern (Sekunden)</label>
|
||||||
|
<input type="number" name="showTime" id="showTime" value="5" required min=1/>
|
||||||
|
<label for="margin">Seitenrand</label>
|
||||||
|
<input type="number" name="margin" id="margin" value="30" required min=0/>
|
||||||
|
<label for="margin">Animationsgeschwindigkeit</label>
|
||||||
|
<select name="speed" id="speed">
|
||||||
|
<option value="slow">Langsam</option>
|
||||||
|
<option value="normal" selected>Normal</option>
|
||||||
|
<option value="fast">Schnell</option>
|
||||||
|
</select>
|
||||||
|
<fieldset>
|
||||||
|
<legend>Hintergrundfarbe</legend>
|
||||||
|
<label for="lightRadio">Hell</label>
|
||||||
|
<input id="lightRadio" type="radio" name="theme" value="light" />
|
||||||
|
<label for="darkRadio">Dunkel</label>
|
||||||
|
<input id="darkRadio" type="radio" name="theme" value="dark" />
|
||||||
|
</fieldset>
|
||||||
|
<button type="submit" name="submit" value="go">Los</button>
|
||||||
|
</form>
|
||||||
|
<img src="" id="first" class="hidden normal" />
|
||||||
|
<img src="" id="second" class="hidden right normal" />
|
||||||
|
</body>
|
||||||
|
</html>
|
69
photos.php
Normal file
69
photos.php
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
|
||||||
|
/* require autoloading to manage namespaces */
|
||||||
|
require __DIR__ . '/vendor/autoload.php';
|
||||||
|
|
||||||
|
use Phlaym\PhotoprismApi\API\PhotoPrism;
|
||||||
|
$config = include __DIR__ . '/config.php';
|
||||||
|
|
||||||
|
function goodbye($message)
|
||||||
|
{
|
||||||
|
die(json_encode(['error' => ['message' => $message]]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($_GET['album'])) {
|
||||||
|
goodbye('Kein Album angegeben!');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($config['host'])) {
|
||||||
|
$config['host'] = 'https://photos.phlaym.net';
|
||||||
|
}
|
||||||
|
$album_token = $_GET['album'];
|
||||||
|
$offset = $_GET['offset'] ?? 0;
|
||||||
|
|
||||||
|
$api = new PhotoPrism($config);
|
||||||
|
try {
|
||||||
|
$api->login();
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
goodbye('Login bei Photoprism fehlgeschlagen');
|
||||||
|
}
|
||||||
|
$album = null;
|
||||||
|
try {
|
||||||
|
if (isset($_SESSION[$album_token])) {
|
||||||
|
$album = $api->getAlbumById($_SESSION[$album_token], $album_token);
|
||||||
|
if (is_null($album)) {
|
||||||
|
goodbye('Fotoalbum konnte nicht gefunden werden');
|
||||||
|
}
|
||||||
|
$album->photoCount = $_SESSION[$album_token . '_count'];
|
||||||
|
} else {
|
||||||
|
$album = $api->getAlbumByToken($album_token);
|
||||||
|
if (is_null($album)) {
|
||||||
|
goodbye('Fotoalbum konnte nicht gefunden werden');
|
||||||
|
}
|
||||||
|
$_SESSION[$album_token] = $album->uid;
|
||||||
|
$_SESSION[$album_token . '_count'] = $album->photoCount;
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
goodbye('Login bei Photoprism fehlgeschlagen');
|
||||||
|
}
|
||||||
|
|
||||||
|
$photo = null;
|
||||||
|
try {
|
||||||
|
$photos = $api->getAlbumPhotos($album, 1, $offset % $album->photoCount);
|
||||||
|
if (is_null($photos) || empty($photos)) {
|
||||||
|
goodbye('Fotos konnten nicht gefunden werden');
|
||||||
|
}
|
||||||
|
$photo = $photos[0];
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
goodbye('Laden des nächstes Fotos fehlgeschlagen');
|
||||||
|
}
|
||||||
|
echo json_encode(
|
||||||
|
[
|
||||||
|
'src' => $config['host'] . $photo->getEmbedUrl('fit_1920'),
|
||||||
|
'count' => $album->photoCount,
|
||||||
|
'album' => $album->title
|
||||||
|
]
|
||||||
|
);
|
19
update.sh
Normal file
19
update.sh
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
LATEST_RELEASE=$(curl -X 'GET' -H 'accept: application/json' 'https://phlaym.net/git/api/v1/repos/phlaym/photoprism-slideshow/releases' | jq .[0].tag_name -r)
|
||||||
|
CURRENT=$(cat version.txt 2> /dev/null)
|
||||||
|
SUCCESS=$?
|
||||||
|
if [[ $SUCCESS != 0 ]]
|
||||||
|
then
|
||||||
|
CURRENT='v0.0.0'
|
||||||
|
fi
|
||||||
|
if [[ $LATEST_RELEASE < $CURRENT ]]
|
||||||
|
then
|
||||||
|
echo "New version ${LATEST_RELEASE} is up to date with currently installed ${CURRENT}"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "New version ${LATEST_RELEASE} detected, updating from ${CURRENT}"
|
||||||
|
wget "https://phlaym.net/git/phlaym/photoprism-slideshow/archive/${LATEST_RELEASE}.tar.gz" -O release.tar.gz
|
||||||
|
|
||||||
|
tar xvf release.tar.gz
|
Loading…
Reference in New Issue
Block a user