IMP: Eigene Verzeichnisse für Uploads und Datenbank
- README aktualisiert, um die neuen Verzeichnisse zu reflektieren - Konstanten für Verzeichnispfade in 'constants.js' hinzugefügt - 'DatabaseManager.js' angepasst, um die neuen Datenbankverzeichnisse zu verwenden - Routen für Batch-Upload, Download und Upload aktualisiert, um die neuen Pfade zu berücksichtigen - 'MigrationService.js' hinzugefügt, um vorhandene Daten in die neuen Verzeichnisse zu migrieren - Hilfsfunktionen in 'groupStorage.js' und 'initiate-resources.js' angepasst - 'docker-compose.yml' und 'prod.sh' aktualisiert, um die neuen Verzeichnisse zu berücksichtigen
This commit is contained in:
parent
0ec8a7590e
commit
24c1de1666
17
README.md
17
README.md
|
|
@ -19,7 +19,7 @@ This project extends the original [Image-Uploader by vallezw](https://github.com
|
|||
- Image grouping with descriptions
|
||||
- Random slideshow rotation
|
||||
- Keyboard navigation support
|
||||
- Mobile-responsive design- Mobile-responsive design
|
||||
- Mobile-responsive design
|
||||
|
||||
## Quick Start
|
||||
|
||||
|
|
@ -79,8 +79,6 @@ docker compose up -d
|
|||
- Backend: `http://localhost:5000`
|
||||
- Slideshow Mode: `http://localhost/slideshow`
|
||||
|
||||
|
||||
|
||||
### Multi-Image Upload
|
||||
|
||||
1. Visit `http://localhost`
|
||||
|
|
@ -115,9 +113,8 @@ docker compose up -d
|
|||
- View group details (title, creator, description, image count)
|
||||
- Bulk moderation actions
|
||||
|
||||
- **Group Management**: Navigate to `http://localhost/groups` (requires authentication)
|
||||
- **Group Management**: Navigate to `http://localhost/groups`
|
||||
- Overview of all approved slideshow collections
|
||||
- Delete entire groups
|
||||
- Launch slideshow mode from any group
|
||||
- View group statistics and metadata
|
||||
|
||||
|
|
@ -230,22 +227,17 @@ Docker Volume (app-data)
|
|||
## Configuration
|
||||
### Environment Variables
|
||||
|
||||
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `API_URL` | `http://localhost:5000` | Backend API endpoint |
|
||||
| `CLIENT_URL` | `http://localhost` | Frontend application URL |
|
||||
|
||||
|
||||
### Volume Configuration
|
||||
|
||||
- **Data Persistence**: `/usr/src/app/src/upload` and `/usr/src/app/src/data` mounted to `app-data`
|
||||
- **Upload Limits**: 100MB maximum file size for batch uploads
|
||||
- **Supported Formats**: JPG, JPEG, PNG, GIF, WebP
|
||||
|
||||
|
||||
|
||||
### Custom Deployment
|
||||
For production deployment, modify the docker-compose configuration:
|
||||
|
||||
|
|
@ -263,17 +255,14 @@ environment:
|
|||
### Backup & Restore
|
||||
#### Backup slideshow data
|
||||
```sh
|
||||
docker cp backend:/usr/src/app/src/data ./backup-data
|
||||
docker cp backend:/usr/src/app/src/upload ./backup-images
|
||||
docker cp backend:/usr/src/app/src/data/ ./backup-data
|
||||
```
|
||||
|
||||
#### Restore slideshow data
|
||||
```sh
|
||||
docker cp ./backup-data backend:/usr/src/app/src/data
|
||||
docker cp ./backup-images backend:/usr/src/app/src/upload
|
||||
```
|
||||
|
||||
|
||||
## Contributing
|
||||
Contributions are welcome!
|
||||
This project extends the original work by [vallezw](https://github.com/vallezw/Image-Uploader).
|
||||
|
|
|
|||
|
|
@ -8,9 +8,13 @@ const endpoints = {
|
|||
DELETE_GROUP: '/groups/:groupId'
|
||||
};
|
||||
|
||||
// Filesystem directory (relative to backend/src) where uploaded images will be stored
|
||||
// Use path.join(__dirname, '..', UPLOAD_FS_DIR, fileName) in code
|
||||
const UPLOAD_FS_DIR = 'data/images';
|
||||
|
||||
const time = {
|
||||
HOURS_24: 86400000,
|
||||
WEEK_1: 604800000
|
||||
};
|
||||
|
||||
module.exports = { endpoints, time };
|
||||
module.exports = { endpoints, time, UPLOAD_FS_DIR };
|
||||
|
|
@ -5,7 +5,8 @@ const fs = require('fs');
|
|||
class DatabaseManager {
|
||||
constructor() {
|
||||
this.db = null;
|
||||
this.dbPath = path.join(__dirname, '../data/image_uploader.db'); // FIX: ../data statt ../../data
|
||||
// Place database file under data/db
|
||||
this.dbPath = path.join(__dirname, '../data/db/image_uploader.db');
|
||||
this.schemaPath = path.join(__dirname, 'schema.sql');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,8 +45,10 @@ router.post(endpoints.UPLOAD_BATCH, async (req, res) => {
|
|||
const fileEnding = file.name.split(".").pop();
|
||||
const fileName = generateId() + '.' + fileEnding;
|
||||
|
||||
// Speichere Datei
|
||||
const uploadPath = `${__dirname}/..${endpoints.UPLOAD_STATIC_DIRECTORY}/${fileName}`;
|
||||
// Speichere Datei unter data/images
|
||||
const path = require('path');
|
||||
const { UPLOAD_FS_DIR } = require('../constants');
|
||||
const uploadPath = path.join(__dirname, '..', UPLOAD_FS_DIR, fileName);
|
||||
file.mv(uploadPath, (err) => {
|
||||
if (err) {
|
||||
console.error('Error saving file:', err);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
const { Router } = require('express');
|
||||
const { endpoints } = require('../constants');
|
||||
const { endpoints, UPLOAD_FS_DIR } = require('../constants');
|
||||
const path = require('path');
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.get(endpoints.DOWNLOAD_FILE, (req, res) => {
|
||||
res.download(`${__dirname}/..${endpoints.UPLOAD_STATIC_DIRECTORY}/${req.params.id}`);
|
||||
const filePath = path.join(__dirname, '..', UPLOAD_FS_DIR, req.params.id);
|
||||
res.download(filePath);
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
const generateId = require("shortid");
|
||||
const express = require('express');
|
||||
const { Router } = require('express');
|
||||
const { endpoints } = require('../constants');
|
||||
const { endpoints, UPLOAD_FS_DIR } = require('../constants');
|
||||
const path = require('path');
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.use(endpoints.UPLOAD_STATIC_DIRECTORY, express.static( __dirname + endpoints.UPLOAD_STATIC_DIRECTORY));
|
||||
// Serve uploaded images via URL /upload but store files under data/images
|
||||
router.use(endpoints.UPLOAD_STATIC_DIRECTORY, express.static( path.join(__dirname, '..', UPLOAD_FS_DIR) ));
|
||||
|
||||
router.post(endpoints.UPLOAD_FILE, (req, res) => {
|
||||
if(req.files === null){
|
||||
|
|
@ -19,7 +21,8 @@ router.post(endpoints.UPLOAD_FILE, (req, res) => {
|
|||
fileEnding = fileEnding[fileEnding.length - 1]
|
||||
fileName = generateId() + '.' + fileEnding
|
||||
|
||||
file.mv(`${__dirname}/..` + endpoints.UPLOAD_STATIC_DIRECTORY + `/${fileName}`, err => {
|
||||
const savePath = path.join(__dirname, '..', UPLOAD_FS_DIR, fileName);
|
||||
file.mv(savePath, err => {
|
||||
if(err) {
|
||||
console.error(err);
|
||||
return res.status(500).send(err);
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@ const dbManager = require('../database/DatabaseManager');
|
|||
|
||||
class MigrationService {
|
||||
constructor() {
|
||||
this.jsonDataPath = path.join(__dirname, '../data');
|
||||
this.backupPath = path.join(__dirname, '../data/backup');
|
||||
// JSON metadata and backups now live under data/db
|
||||
this.jsonDataPath = path.join(__dirname, '../data/db');
|
||||
this.backupPath = path.join(__dirname, '../data/db/backup');
|
||||
}
|
||||
|
||||
// Hauptmigration von JSON zu SQLite
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const GROUPS_FILE = path.join(__dirname, '../data/upload-groups.json');
|
||||
// Store JSON metadata under data/db
|
||||
const GROUPS_FILE = path.join(__dirname, '../data/db/upload-groups.json');
|
||||
|
||||
class GroupStorage {
|
||||
// Initialisiere die JSON-Datei falls sie nicht existiert
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ const { applyMiddlewares } = require('../middlewares');
|
|||
const { renderRoutes } = require('../routes/index');
|
||||
const removeImages = require('./remove-images');
|
||||
const fs = require('fs');
|
||||
const { endpoints } = require('../constants');
|
||||
const path = require('path');
|
||||
const { endpoints, UPLOAD_FS_DIR } = require('../constants');
|
||||
|
||||
|
||||
const initiateResources = (app) => {
|
||||
|
|
@ -10,10 +11,16 @@ const initiateResources = (app) => {
|
|||
|
||||
renderRoutes(app);
|
||||
|
||||
const dir = `${__dirname}/..` + endpoints.UPLOAD_STATIC_DIRECTORY
|
||||
// Ensure upload images directory exists: backend/src/../data/images
|
||||
const imagesDir = path.join(__dirname, '..', UPLOAD_FS_DIR);
|
||||
if (!fs.existsSync(imagesDir)){
|
||||
fs.mkdirSync(imagesDir, { recursive: true });
|
||||
}
|
||||
|
||||
if (!fs.existsSync(dir)){
|
||||
fs.mkdirSync(dir);
|
||||
// Ensure db directory exists: backend/src/../data/db
|
||||
const dbDir = path.join(__dirname, '..', 'data', 'db');
|
||||
if (!fs.existsSync(dbDir)){
|
||||
fs.mkdirSync(dbDir, { recursive: true });
|
||||
}
|
||||
|
||||
if(process.env.REMOVE_IMAGES === 'true') {
|
||||
|
|
|
|||
|
|
@ -27,8 +27,7 @@ services:
|
|||
networks:
|
||||
- image-uploader-internal
|
||||
volumes:
|
||||
- app-data:/usr/src/app/src/upload
|
||||
- app-data:/usr/src/app/src/data
|
||||
- app-data:/usr/src/app/data
|
||||
|
||||
volumes:
|
||||
app-data:
|
||||
|
|
|
|||
8
prod.sh
8
prod.sh
|
|
@ -109,11 +109,11 @@ case $choice in
|
|||
12)
|
||||
echo -e "${GREEN}Upload-Verzeichnis Inhalt:${NC}"
|
||||
if docker compose ps -q image-uploader-backend > /dev/null 2>&1; then
|
||||
echo -e "${BLUE}Hochgeladene Bilder:${NC}"
|
||||
docker compose exec image-uploader-backend ls -la /usr/src/app/src/upload/ || echo "Upload-Verzeichnis ist leer"
|
||||
echo -e "${BLUE}Hochgeladene Bilder (data/images):${NC}"
|
||||
docker compose exec image-uploader-backend ls -la /usr/src/app/data/images/ || echo "Upload-Verzeichnis ist leer"
|
||||
echo
|
||||
echo -e "${BLUE}JSON Metadaten:${NC}"
|
||||
docker compose exec image-uploader-backend ls -la /usr/src/app/src/data/ || echo "Keine Metadaten vorhanden"
|
||||
echo -e "${BLUE}JSON Metadaten (data/db):${NC}"
|
||||
docker compose exec image-uploader-backend ls -la /usr/src/app/data/db/ || echo "Keine Metadaten vorhanden"
|
||||
else
|
||||
echo -e "${YELLOW}Backend Container ist nicht gestartet.${NC}"
|
||||
fi
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user