moved some files
This commit is contained in:
265
old_code_documentation/IMPLEMENTATION_OPTIONAL_LIBREOFFICE.md
Normal file
265
old_code_documentation/IMPLEMENTATION_OPTIONAL_LIBREOFFICE.md
Normal file
@@ -0,0 +1,265 @@
|
||||
# Optional LibreOffice Installation - Implementation Summary
|
||||
|
||||
## Overview
|
||||
Implemented a system to install LibreOffice on-demand instead of including it in the base Docker image, reducing image size by 56% (~900MB → ~400MB).
|
||||
|
||||
## Changes Made
|
||||
|
||||
### 1. Backend Implementation
|
||||
|
||||
#### `/srv/digiserver-v2/app/blueprints/admin.py`
|
||||
Added two new routes:
|
||||
|
||||
- **`/admin/dependencies`** - Display dependency status page
|
||||
- Checks LibreOffice, Poppler, FFmpeg installation status
|
||||
- Uses subprocess to run version commands with 5s timeout
|
||||
- Passes status variables to template
|
||||
|
||||
- **`/admin/install_libreoffice`** (POST) - Install LibreOffice
|
||||
- Executes `install_libreoffice.sh` with sudo
|
||||
- 300s timeout for installation
|
||||
- Logs installation output
|
||||
- Flash messages for success/failure
|
||||
|
||||
#### `/srv/digiserver-v2/app/blueprints/content.py`
|
||||
Modified presentation file processing:
|
||||
|
||||
- **Changed behavior**: Now returns error instead of accepting PPTX without LibreOffice
|
||||
- **Error message**: "LibreOffice is not installed. Please install it from the Admin Panel → System Dependencies to upload PowerPoint files."
|
||||
- **User experience**: Clear guidance on how to enable PPTX support
|
||||
|
||||
### 2. Installation Script
|
||||
|
||||
#### `/srv/digiserver-v2/install_libreoffice.sh`
|
||||
Bash script to install LibreOffice:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Checks root privileges
|
||||
# Verifies if already installed
|
||||
# Updates package cache
|
||||
# Installs libreoffice and libreoffice-impress
|
||||
# Verifies installation success
|
||||
# Reports version
|
||||
```
|
||||
|
||||
Features:
|
||||
- Idempotent (safe to run multiple times)
|
||||
- Error handling and validation
|
||||
- Success/failure reporting
|
||||
- Version verification
|
||||
|
||||
### 3. Frontend Templates
|
||||
|
||||
#### `/srv/digiserver-v2/app/templates/admin/dependencies.html`
|
||||
New template showing:
|
||||
- LibreOffice status (✅ installed or ❌ not installed)
|
||||
- Poppler Utils status (always present)
|
||||
- FFmpeg status (always present)
|
||||
- Install button for LibreOffice when not present
|
||||
- Installation notes and guidance
|
||||
- Dark mode support
|
||||
|
||||
#### `/srv/digiserver-v2/app/templates/admin/admin.html`
|
||||
Added new card:
|
||||
- "System Dependencies" card with gradient background
|
||||
- Links to `/admin/dependencies` route
|
||||
- Matches existing admin panel styling
|
||||
|
||||
### 4. Docker Configuration
|
||||
|
||||
#### `/srv/digiserver-v2/Dockerfile`
|
||||
Key changes:
|
||||
- **Removed**: `libreoffice` from apt-get install
|
||||
- **Added**: `sudo` for installation script execution
|
||||
- **Added**: Sudoers entry for appuser to run installation script
|
||||
- **Added**: Script permissions (`chmod +x`)
|
||||
- **Added**: Comments explaining optional LibreOffice
|
||||
|
||||
Result:
|
||||
- Base image: ~400MB (down from ~900MB)
|
||||
- LibreOffice can be installed post-deployment
|
||||
- Maintains security with non-root user
|
||||
|
||||
### 5. Documentation
|
||||
|
||||
#### `/srv/digiserver-v2/OPTIONAL_DEPENDENCIES.md` (NEW)
|
||||
Comprehensive guide covering:
|
||||
- Why optional dependencies?
|
||||
- Installation methods (Web UI, Docker exec, direct)
|
||||
- Checking dependency status
|
||||
- File type support matrix
|
||||
- Upload behavior with/without LibreOffice
|
||||
- Technical details
|
||||
- Installation times
|
||||
- Troubleshooting
|
||||
- Production recommendations
|
||||
- FAQ
|
||||
|
||||
#### `/srv/digiserver-v2/README.md`
|
||||
Updated sections:
|
||||
- Features: Added "Optional Dependencies" bullet
|
||||
- Prerequisites: Marked LibreOffice as optional
|
||||
- Installation: Separated required vs optional dependencies
|
||||
- Troubleshooting: Enhanced PPTX troubleshooting with Web UI method
|
||||
- Documentation: Added links to OPTIONAL_DEPENDENCIES.md
|
||||
- Version History: Added v2.1 with optional LibreOffice feature
|
||||
|
||||
#### `/srv/digiserver-v2/DOCKER.md`
|
||||
Updated sections:
|
||||
- Overview: Added base image size and optional LibreOffice info
|
||||
- Maintenance: Added "Installing Optional Dependencies" section
|
||||
- System Requirements: Split into base vs with LibreOffice
|
||||
|
||||
## Benefits
|
||||
|
||||
### Image Size Reduction
|
||||
- **Before**: ~900MB (Python + Poppler + FFmpeg + LibreOffice)
|
||||
- **After**: ~400MB (Python + Poppler + FFmpeg only)
|
||||
- **Savings**: 500MB (56% reduction)
|
||||
|
||||
### Deployment Speed
|
||||
- Faster Docker pulls
|
||||
- Faster container starts
|
||||
- Lower bandwidth usage
|
||||
- Lower storage requirements
|
||||
|
||||
### Flexibility
|
||||
- Users without PPTX needs: smaller, faster image
|
||||
- Users with PPTX needs: install on-demand
|
||||
- Can be installed/uninstalled as needed
|
||||
- No rebuild required
|
||||
|
||||
### User Experience
|
||||
- Clear error messages when PPTX upload attempted
|
||||
- Easy installation via Web UI
|
||||
- Visual status indicators
|
||||
- Guided troubleshooting
|
||||
|
||||
## Technical Architecture
|
||||
|
||||
### Dependency Detection
|
||||
```python
|
||||
# Uses subprocess to check installation
|
||||
subprocess.run(['libreoffice', '--version'],
|
||||
capture_output=True, timeout=5)
|
||||
```
|
||||
|
||||
### Installation Flow
|
||||
1. User clicks "Install LibreOffice" button
|
||||
2. POST request to `/admin/install_libreoffice`
|
||||
3. Server runs `sudo /app/install_libreoffice.sh`
|
||||
4. Script installs packages via apt-get
|
||||
5. Server logs output and flashes message
|
||||
6. User refreshes to see updated status
|
||||
|
||||
### Upload Validation
|
||||
```python
|
||||
# In process_presentation_file()
|
||||
if not libreoffice_cmd:
|
||||
return False, "LibreOffice is not installed..."
|
||||
```
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
- [ ] Docker image builds successfully
|
||||
- [ ] Base image size is ~400MB
|
||||
- [ ] Server starts without LibreOffice
|
||||
- [ ] Dependencies page shows correct status
|
||||
- [ ] Install button appears when LibreOffice not present
|
||||
- [ ] PPTX upload fails with clear error message
|
||||
- [ ] Installation script runs successfully
|
||||
- [ ] PPTX upload works after installation
|
||||
- [ ] PDF uploads work without LibreOffice
|
||||
- [ ] Image/video uploads work without LibreOffice
|
||||
- [ ] Dark mode styling works on dependencies page
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Sudoers Configuration
|
||||
```dockerfile
|
||||
# Only allows running installation script, not arbitrary commands
|
||||
echo "appuser ALL=(ALL) NOPASSWD: /app/install_libreoffice.sh" >> /etc/sudoers
|
||||
```
|
||||
|
||||
### Installation Script
|
||||
- Requires root privileges
|
||||
- Validates installation success
|
||||
- Uses official apt repositories
|
||||
- No external downloads
|
||||
|
||||
### Application Security
|
||||
- Installation requires authenticated admin access
|
||||
- Non-root user for runtime
|
||||
- Timeouts prevent hanging processes
|
||||
|
||||
## Maintenance Notes
|
||||
|
||||
### Future Enhancements
|
||||
- Add uninstall functionality
|
||||
- Support for other optional dependencies
|
||||
- Installation progress indicator
|
||||
- Automatic dependency detection on upload
|
||||
|
||||
### Known Limitations
|
||||
- Installation requires sudo access
|
||||
- Docker containers need sudo configured
|
||||
- No progress feedback during installation (2-5 min wait)
|
||||
- Requires internet connection for apt packages
|
||||
|
||||
## Rollback Procedure
|
||||
|
||||
If optional installation causes issues:
|
||||
|
||||
1. **Restore LibreOffice to base image:**
|
||||
```dockerfile
|
||||
RUN apt-get update && apt-get install -y \
|
||||
poppler-utils \
|
||||
libreoffice \
|
||||
ffmpeg \
|
||||
libmagic1 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
```
|
||||
|
||||
2. **Remove sudo configuration:**
|
||||
```dockerfile
|
||||
# Remove this line
|
||||
echo "appuser ALL=(ALL) NOPASSWD: /app/install_libreoffice.sh" >> /etc/sudoers
|
||||
```
|
||||
|
||||
3. **Revert content.py error behavior:**
|
||||
```python
|
||||
if not libreoffice_cmd:
|
||||
return True, "Presentation accepted without conversion..."
|
||||
```
|
||||
|
||||
## Files Modified
|
||||
|
||||
1. `app/blueprints/admin.py` - Added dependency routes
|
||||
2. `app/blueprints/content.py` - Changed PPTX error handling
|
||||
3. `app/templates/admin/dependencies.html` - New status page
|
||||
4. `app/templates/admin/admin.html` - Added dependencies card
|
||||
5. `Dockerfile` - Removed LibreOffice, added sudo
|
||||
6. `install_libreoffice.sh` - New installation script
|
||||
7. `OPTIONAL_DEPENDENCIES.md` - New comprehensive guide
|
||||
8. `README.md` - Updated with optional dependency info
|
||||
9. `DOCKER.md` - Updated with installation instructions
|
||||
|
||||
## Next Steps
|
||||
|
||||
To complete the implementation:
|
||||
1. Test Docker build: `docker-compose build`
|
||||
2. Verify image size: `docker images | grep digiserver`
|
||||
3. Test installation flow in running container
|
||||
4. Update production deployment docs if needed
|
||||
5. Consider adding installation progress indicator
|
||||
6. Add metrics for tracking LibreOffice usage
|
||||
|
||||
## Success Metrics
|
||||
|
||||
- ✅ Docker image size reduced by >50%
|
||||
- ✅ All file types work without LibreOffice (except PPTX)
|
||||
- ✅ Clear error messages guide users to installation
|
||||
- ✅ Installation works via Web UI
|
||||
- ✅ Installation works via Docker exec
|
||||
- ✅ Comprehensive documentation provided
|
||||
181
old_code_documentation/PLAYER_EDIT_MEDIA_API.md
Normal file
181
old_code_documentation/PLAYER_EDIT_MEDIA_API.md
Normal file
@@ -0,0 +1,181 @@
|
||||
# Player Edit Media API
|
||||
|
||||
## Overview
|
||||
This API allows players to upload edited media files back to the server, maintaining version history and automatically updating playlists.
|
||||
|
||||
## Endpoint
|
||||
|
||||
### POST `/api/player-edit-media`
|
||||
|
||||
Upload an edited media file from a player device.
|
||||
|
||||
**Authentication Required:** Yes (Bearer token)
|
||||
|
||||
**Rate Limit:** 60 requests per 60 seconds
|
||||
|
||||
**Content-Type:** `multipart/form-data`
|
||||
|
||||
## Request
|
||||
|
||||
### Form Data
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `image_file` | File | Yes | The edited image file |
|
||||
| `metadata` | JSON String | Yes | Metadata about the edit (see below) |
|
||||
|
||||
### Metadata JSON Structure
|
||||
|
||||
```json
|
||||
{
|
||||
"time_of_modification": "2025-12-05T20:30:00Z",
|
||||
"original_name": "image.jpg",
|
||||
"new_name": "image_v1.jpg",
|
||||
"version": 1,
|
||||
"user": "player_user_name"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `time_of_modification` | ISO 8601 DateTime | Yes | When the edit was made |
|
||||
| `original_name` | String | Yes | Original filename (must exist in content) |
|
||||
| `new_name` | String | Yes | New filename with version suffix |
|
||||
| `version` | Integer | Yes | Version number (1, 2, 3, etc.) |
|
||||
| `user` | String | No | User who made the edit |
|
||||
|
||||
## Response
|
||||
|
||||
### Success (200 OK)
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "Edited media received and processed",
|
||||
"edit_id": 123,
|
||||
"version": 1,
|
||||
"new_playlist_version": 5
|
||||
}
|
||||
```
|
||||
|
||||
### Error Responses
|
||||
|
||||
#### 400 Bad Request
|
||||
```json
|
||||
{
|
||||
"error": "No image file provided"
|
||||
}
|
||||
```
|
||||
|
||||
#### 404 Not Found
|
||||
```json
|
||||
{
|
||||
"error": "Original content not found: image.jpg"
|
||||
}
|
||||
```
|
||||
|
||||
#### 500 Internal Server Error
|
||||
```json
|
||||
{
|
||||
"error": "Internal server error"
|
||||
}
|
||||
```
|
||||
|
||||
## Workflow
|
||||
|
||||
1. **Player edits media** - User edits an image/PDF/PPTX on the player device
|
||||
2. **Player uploads** - Player sends edited file + metadata to this endpoint
|
||||
3. **Server processes**:
|
||||
- Saves edited file to `/static/uploads/edited_media/<content_id>/<new_name>`
|
||||
- Saves metadata JSON to `/static/uploads/edited_media/<content_id>/<new_name>_metadata.json`
|
||||
- Replaces original file in `/static/uploads/` with edited version
|
||||
- Creates database record in `player_edit` table
|
||||
- Increments playlist version to trigger player refresh
|
||||
- Clears playlist cache
|
||||
4. **Player refreshes** - Next playlist check shows updated media
|
||||
|
||||
## Version History
|
||||
|
||||
Each edit is saved with a version number:
|
||||
- `image.jpg` → `image_v1.jpg` (first edit)
|
||||
- `image.jpg` → `image_v2.jpg` (second edit)
|
||||
- etc.
|
||||
|
||||
All versions are preserved in the `edited_media/<content_id>/` folder.
|
||||
|
||||
## Example cURL Request
|
||||
|
||||
```bash
|
||||
# First, authenticate to get token
|
||||
TOKEN=$(curl -X POST http://server/api/auth/authenticate \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"hostname": "player-1", "password": "password123"}' \
|
||||
| jq -r '.token')
|
||||
|
||||
# Upload edited media
|
||||
curl -X POST http://server/api/player-edit-media \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-F "image_file=@edited_image_v1.jpg" \
|
||||
-F 'metadata={"time_of_modification":"2025-12-05T20:30:00Z","original_name":"image.jpg","new_name":"image_v1.jpg","version":1,"user":"john"}'
|
||||
```
|
||||
|
||||
## Python Example
|
||||
|
||||
```python
|
||||
import requests
|
||||
import json
|
||||
|
||||
# Authenticate
|
||||
auth_response = requests.post(
|
||||
'http://server/api/auth/authenticate',
|
||||
json={'hostname': 'player-1', 'password': 'password123'}
|
||||
)
|
||||
token = auth_response.json()['token']
|
||||
|
||||
# Prepare metadata
|
||||
metadata = {
|
||||
'time_of_modification': '2025-12-05T20:30:00Z',
|
||||
'original_name': 'image.jpg',
|
||||
'new_name': 'image_v1.jpg',
|
||||
'version': 1,
|
||||
'user': 'john'
|
||||
}
|
||||
|
||||
# Upload edited file
|
||||
with open('edited_image_v1.jpg', 'rb') as f:
|
||||
response = requests.post(
|
||||
'http://server/api/player-edit-media',
|
||||
headers={'Authorization': f'Bearer {token}'},
|
||||
files={'image_file': f},
|
||||
data={'metadata': json.dumps(metadata)}
|
||||
)
|
||||
|
||||
print(response.json())
|
||||
```
|
||||
|
||||
## Database Schema
|
||||
|
||||
### player_edit Table
|
||||
|
||||
| Column | Type | Description |
|
||||
|--------|------|-------------|
|
||||
| id | INTEGER | Primary key |
|
||||
| player_id | INTEGER | Foreign key to player |
|
||||
| content_id | INTEGER | Foreign key to content |
|
||||
| original_name | VARCHAR(255) | Original filename |
|
||||
| new_name | VARCHAR(255) | New filename with version |
|
||||
| version | INTEGER | Version number |
|
||||
| user | VARCHAR(255) | User who made the edit |
|
||||
| time_of_modification | DATETIME | When edit was made |
|
||||
| metadata_path | VARCHAR(512) | Path to metadata JSON |
|
||||
| edited_file_path | VARCHAR(512) | Path to edited file |
|
||||
| created_at | DATETIME | Record creation time |
|
||||
|
||||
## UI Display
|
||||
|
||||
Edited media history is displayed on the player management page under the "Edited Media on the Player" card, showing:
|
||||
- Original filename
|
||||
- Version number
|
||||
- Editor name
|
||||
- Modification time
|
||||
- Link to view edited file
|
||||
Reference in New Issue
Block a user