This commit is contained in:
Miguel 2025-09-01 12:23:16 +02:00
commit 8bade258cc
12 changed files with 406 additions and 0 deletions

216
.gitignore vendored Normal file
View File

@ -0,0 +1,216 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[codz]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py.cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# UV
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
#uv.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
#poetry.toml
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
#pdm.lock
#pdm.toml
.pdm-python
.pdm-build/
# pixi
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
#pixi.lock
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
# in the .venv directory. It is recommended not to include this directory in version control.
.pixi
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# Redis
*.rdb
*.aof
*.pid
# RabbitMQ
mnesia/
rabbitmq/
rabbitmq-data/
# ActiveMQ
activemq-data/
# SageMath parsed files
*.sage.py
# Environments
.env
.envrc
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
# Abstra
# Abstra is an AI-powered process automation framework.
# Ignore directories containing user credentials, local state, and settings.
# Learn more at https://abstra.io/docs
.abstra/
# Visual Studio Code
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
# and can be added to the global gitignore or merged into this file. However, if you prefer,
# you could uncomment the following to ignore the entire vscode folder
# .vscode/
# Ruff stuff:
.ruff_cache/
# PyPI configuration file
.pypirc
# Marimo
marimo/_static/
marimo/_lsp/
__marimo__/
# Streamlit
.streamlit/secrets.toml

69
README.md Normal file
View File

@ -0,0 +1,69 @@
# AutoBackups Project
## Overview
AutoBackups is a Python application designed to automate the backup of Simatic S7 projects and other user-defined directories. The application leverages the Everything API to efficiently locate files and manage backups based on user-defined configurations.
## Features
- Monitors specified directories for Simatic S7 files (*.s7p) and other user-defined directories.
- Automatically compresses and backs up projects on a defined schedule (daily by default).
- Supports manual backup triggers.
- Skips projects with files in use and retries after one hour.
- Maintains a hash of file timestamps to avoid unnecessary backups.
- User-friendly web interface built with Flask and React for configuration and status monitoring.
## Project Structure
```
autobackups
├── src
│ ├── app.py # Main entry point of the Flask application
│ ├── models
│ │ └── __init__.py # Data models for configuration and directories
│ ├── routes
│ │ └── __init__.py # API routes for backup operations
│ ├── services
│ │ └── __init__.py # Business logic for backups
│ └── utils
│ └── __init__.py # Utility functions for hashing and file access
├── static
│ ├── css # CSS files for styling
│ └── js # JavaScript files for client-side functionality
├── templates
│ └── index.html # Main HTML template for the web interface
├── config.json # Configuration settings for the application
├── requirements.txt # Python dependencies
└── README.md # Project documentation
```
## Installation
1. Clone the repository:
```
git clone <repository-url>
cd autobackups
```
2. Create a Miniconda environment:
```
conda create --name autobackups python=3.12
conda activate autobackups
```
3. Install the required packages:
```
pip install -r requirements.txt
```
4. Configure the application by editing `config.json` to specify directories to monitor and backup settings.
## Usage
- Start the Flask application:
```
python src/app.py
```
- Access the web interface at `http://localhost:5000` to configure settings and monitor backup statuses.
## Contributing
Contributions are welcome! Please submit a pull request or open an issue for any enhancements or bug fixes.
## License
This project is licensed under the MIT License. See the LICENSE file for details.

15
config.json Normal file
View File

@ -0,0 +1,15 @@
{
"directories_to_monitor": [
"C:\\path\\to\\first\\directory",
"C:\\path\\to\\second\\directory"
],
"backup_destination": "C:\\path\\to\\backup\\destination",
"default_backup_schedule": {
"frequency": "daily",
"time": "02:00"
},
"manual_backup_directories": [],
"hashing_enabled": true,
"retry_interval": 3600,
"max_concurrent_backups": 1
}

8
requirements.txt Normal file
View File

@ -0,0 +1,8 @@
Flask
Flask-Cors
Flask-RESTful
requests
watchdog
pyzipper
hashlib
pyeverthing

38
src/app.py Normal file
View File

@ -0,0 +1,38 @@
from flask import Flask
from apscheduler.schedulers.background import BackgroundScheduler
import json
import os
app = Flask(__name__)
# Load configuration from config.json
with open('config.json') as config_file:
config = json.load(config_file)
# Initialize the scheduler
scheduler = BackgroundScheduler()
def backup_projects():
# Logic to scan directories and perform backups
pass
# Schedule the backup task
scheduler.add_job(backup_projects, 'interval', hours=config.get('backup_interval_hours', 24))
scheduler.start()
@app.route('/')
def index():
return "Welcome to the Auto Backup System"
@app.route('/backup', methods=['POST'])
def trigger_backup():
# Logic to manually trigger a backup
return "Backup triggered"
@app.route('/status', methods=['GET'])
def backup_status():
# Logic to check the status of backups
return "Backup status"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)

1
src/models/__init__.py Normal file
View File

@ -0,0 +1 @@
# This file is intentionally left blank.

5
src/routes/__init__.py Normal file
View File

@ -0,0 +1,5 @@
from flask import Blueprint
bp = Blueprint('routes', __name__)
from . import backup_routes, status_routes, config_routes

1
src/services/__init__.py Normal file
View File

@ -0,0 +1 @@
# This file is intentionally left blank.

19
src/utils/__init__.py Normal file
View File

@ -0,0 +1,19 @@
def hash_timestamps(file_paths):
# Implement hashing logic for file timestamps
pass
def check_file_access(file_path):
# Implement logic to check if a file is in use
pass
def get_everything_results(query):
# Implement interaction with the Everything API
pass
def compress_files(file_paths, destination):
# Implement file compression logic
pass
def log_backup_status(project_name, status):
# Implement logging of backup status
pass

1
static/css Normal file
View File

@ -0,0 +1 @@
/* This file is intentionally left blank. */

1
static/js Normal file
View File

@ -0,0 +1 @@
// This file is intentionally left blank.

32
templates/index.html Normal file
View File

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Auto Backups</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
<div class="container">
<h1>Auto Backups</h1>
<div id="backup-status">
<h2>Backup Status</h2>
<ul id="status-list">
<!-- Backup status items will be dynamically inserted here -->
</ul>
</div>
<div id="backup-controls">
<h2>Backup Controls</h2>
<button id="manual-backup">Force Backup Now</button>
<label for="backup-interval">Backup Interval:</label>
<select id="backup-interval">
<option value="hourly">Hourly</option>
<option value="daily" selected>Daily</option>
<option value="weekly">Weekly</option>
</select>
<button id="save-settings">Save Settings</button>
</div>
</div>
<script src="{{ url_for('static', filename='js/script.js') }}"></script>
</body>
</html>