allow zip upload for AC sw
This commit is contained in:
parent
b47d2bd174
commit
2f4841be72
101
app.py
101
app.py
@ -1,66 +1,93 @@
|
|||||||
import os
|
import os
|
||||||
|
import re
|
||||||
|
import tempfile
|
||||||
|
import subprocess
|
||||||
import shutil
|
import shutil
|
||||||
from flask import Flask, request, render_template, jsonify
|
from flask import Flask, request, render_template, jsonify
|
||||||
import subprocess
|
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
# Load environment variables from .env (if available)
|
# Load environment variables
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
app = Flask(__name__, static_folder='.', template_folder='.')
|
app = Flask(__name__, static_folder='.', template_folder='.')
|
||||||
|
|
||||||
# Define target directories (relative to the script’s folder)
|
# Directories for sys02.lib
|
||||||
TARGET_DIRS = [
|
TARGET_DIRS = [
|
||||||
os.path.join("software", "."),
|
os.path.join('software', '.'),
|
||||||
os.path.join("software", "VAT_LATEST", "Data"),
|
os.path.join('software', 'VAT_LATEST', 'Data'),
|
||||||
os.path.join("software", "VAT_LATEST_DUREMOTE", "Data"),
|
os.path.join('software', 'VAT_LATEST_DUREMOTE', 'Data'),
|
||||||
os.path.join("software", "GENERAL8.0.5.6", "Data")
|
os.path.join('software', 'GENERAL8.0.5.6', 'Data')
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Archive rules
|
||||||
|
ARCHIVE_PATTERN = re.compile(r'^AIR 3\.verison July2019 .+\.(zip|rar)$', re.IGNORECASE)
|
||||||
|
EXTRACT_SUBDIR = 'AIR 3.verison July2019 pouzivat tento'
|
||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
def index():
|
def index():
|
||||||
# Render the HTML file; ensure index.html is in the same folder as app.py
|
|
||||||
return render_template('index.html')
|
return render_template('index.html')
|
||||||
|
|
||||||
@app.route('/test')
|
|
||||||
def test():
|
|
||||||
# Render the HTML file; ensure index.html is in the same folder as app.py
|
|
||||||
return render_template('test.html')
|
|
||||||
|
|
||||||
@app.route('/upload', methods=['POST'])
|
@app.route('/upload', methods=['POST'])
|
||||||
def upload():
|
def upload():
|
||||||
if 'file' not in request.files:
|
if 'file' not in request.files:
|
||||||
return jsonify({'error': 'No file provided'}), 400
|
return jsonify({'error': 'No file provided'}), 400
|
||||||
|
|
||||||
file = request.files['file']
|
file = request.files['file']
|
||||||
commit_msg = request.form.get('commit_msg', '')
|
filename = file.filename.strip()
|
||||||
|
commit_msg = request.form.get('commit_msg', '').strip()
|
||||||
# Check file name
|
if not commit_msg:
|
||||||
if file.filename != "sys02.lib":
|
return jsonify({'error': 'Commit message is required.'}), 400
|
||||||
return jsonify({'error': 'Uploaded file must be named sys02.lib'}), 400
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Read file content into memory so we can write to multiple locations
|
# sys02.lib branch
|
||||||
file_data = file.read()
|
if filename.lower() == 'sys02.lib':
|
||||||
for target in TARGET_DIRS:
|
data = file.read()
|
||||||
# Ensure the target directory exists
|
for target in TARGET_DIRS:
|
||||||
os.makedirs(target, exist_ok=True)
|
os.makedirs(target, exist_ok=True)
|
||||||
filepath = os.path.join(target, file.filename)
|
with open(os.path.join(target, 'sys02.lib'), 'wb') as f:
|
||||||
with open(filepath, 'wb') as f:
|
f.write(data)
|
||||||
f.write(file_data)
|
|
||||||
|
|
||||||
# Run git commands: stage changes, commit, and push.
|
# ZIP archive branch
|
||||||
# (Make sure that the working directory is already a git repository.)
|
elif filename.lower().endswith('.zip'):
|
||||||
os.chdir("software")
|
if not ARCHIVE_PATTERN.match(filename):
|
||||||
subprocess.check_call(["git", "add", "."])
|
return jsonify({
|
||||||
subprocess.check_call(["git", "commit", "-m", commit_msg])
|
'error': 'Archive name must match "AIR 3.verison July2019 XXXX.zip"'
|
||||||
subprocess.check_call(["git", "push"])
|
}), 400
|
||||||
|
|
||||||
return jsonify({'message': 'File uploaded and git commit/push successful.'})
|
with tempfile.TemporaryDirectory() as tmp:
|
||||||
|
temp_path = os.path.join(tmp, filename)
|
||||||
|
file.save(temp_path)
|
||||||
|
|
||||||
|
extract_dir = os.path.join('software', EXTRACT_SUBDIR)
|
||||||
|
os.makedirs(extract_dir, exist_ok=True)
|
||||||
|
|
||||||
|
shutil.unpack_archive(temp_path, extract_dir)
|
||||||
|
|
||||||
|
else:
|
||||||
|
return jsonify({
|
||||||
|
'error': 'Unsupported file type. Provide sys02.lib or a valid .zip archive.'
|
||||||
|
}), 400
|
||||||
|
|
||||||
|
# Git operations
|
||||||
|
os.chdir('software')
|
||||||
|
subprocess.check_call(['git', 'add', '.'])
|
||||||
|
subprocess.check_call(['git', 'commit', '-m', commit_msg])
|
||||||
|
subprocess.check_call(['git', 'push'])
|
||||||
|
|
||||||
|
return jsonify({'message': 'Upload processed and git commit/push successful.'})
|
||||||
|
|
||||||
|
except shutil.ReadError:
|
||||||
|
return jsonify({'error': 'Failed to unpack ZIP archive'}), 400
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
return jsonify({'error': 'Git command failed', 'details': str(e)}), 500
|
return jsonify({
|
||||||
|
'error': 'Git command failed',
|
||||||
|
'details': str(e)
|
||||||
|
}), 500
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return jsonify({'error': 'An error occurred', 'details': str(e)}), 500
|
return jsonify({
|
||||||
|
'error': 'An unexpected error occurred',
|
||||||
|
'details': str(e)
|
||||||
|
}), 500
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == '__main__':
|
||||||
app.run(host="0.0.0.0", port=5001, debug=True)
|
app.run(host='0.0.0.0', port=5002, debug=True)
|
64
index.html
64
index.html
@ -11,14 +11,33 @@
|
|||||||
</head>
|
</head>
|
||||||
<body class="bg-gray-100 flex items-center justify-center min-h-screen">
|
<body class="bg-gray-100 flex items-center justify-center min-h-screen">
|
||||||
<div class="bg-white p-8 rounded shadow-md w-full max-w-md">
|
<div class="bg-white p-8 rounded shadow-md w-full max-w-md">
|
||||||
<h1 class="text-2xl font-bold mb-6">Upload sys02.lib</h1>
|
<h1 class="text-2xl font-bold mb-6">Upload sys02.lib or Archive</h1>
|
||||||
|
|
||||||
|
<!-- Tabs -->
|
||||||
|
<ul class="flex border-b mb-4" id="tabs">
|
||||||
|
<li class="-mb-px mr-1">
|
||||||
|
<button class="bg-white inline-block py-2 px-4 font-semibold text-blue-600 border-l border-t border-r rounded-t active" data-tab="lib">sys02.lib</button>
|
||||||
|
</li>
|
||||||
|
<li class="mr-1">
|
||||||
|
<button class="bg-white inline-block py-2 px-4 font-semibold text-gray-600 hover:text-blue-600" data-tab="archive">AC software zip</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<form id="uploadForm">
|
<form id="uploadForm">
|
||||||
<div class="mb-4">
|
<!-- sys02.lib Panel -->
|
||||||
<label class="block text-gray-700">Select file (must be sys02.lib):</label>
|
<div id="panel-lib" class="tab-panel mb-4">
|
||||||
<input type="file" name="file" class="mt-1 p-2 border border-gray-300 rounded w-full" required>
|
<label class="block text-gray-700">Select sys02.lib file:</label>
|
||||||
|
<input type="file" name="file" accept=".lib" class="mt-1 p-2 border border-gray-300 rounded w-full" required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Archive Panel -->
|
||||||
|
<div id="panel-archive" class="tab-panel mb-4 hidden">
|
||||||
|
<label class="block text-gray-700">Select ZIP archive:</label>
|
||||||
|
<input type="file" name="file" accept=".zip" class="mt-1 p-2 border border-gray-300 rounded w-full" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="block text-gray-700">Commit Message (cislo noveho protokolu nebo jiny popis):</label>
|
<label class="block text-gray-700">Commit Message:</label>
|
||||||
<input type="text" name="commit_msg" class="mt-1 p-2 border border-gray-300 rounded w-full" placeholder="Enter commit message" required>
|
<input type="text" name="commit_msg" class="mt-1 p-2 border border-gray-300 rounded w-full" placeholder="Enter commit message" required>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600">Submit</button>
|
<button type="submit" class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600">Submit</button>
|
||||||
@ -27,8 +46,37 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function () {
|
|
||||||
$('#uploadForm').on('submit', function (e) {
|
$(function() {
|
||||||
|
// Tab switching
|
||||||
|
$('#tabs button').click(function() {
|
||||||
|
var tab = $(this).data('tab');
|
||||||
|
|
||||||
|
// Remove all active styles, apply inactive style
|
||||||
|
$('#tabs button')
|
||||||
|
.removeClass('text-blue-600 border-l border-t border-r rounded-t')
|
||||||
|
.addClass('text-gray-600 hover:text-blue-600');
|
||||||
|
|
||||||
|
// Add active styles to the clicked tab
|
||||||
|
$(this)
|
||||||
|
.removeClass('text-gray-600 hover:text-blue-600')
|
||||||
|
.addClass('text-blue-600 border-l border-t border-r rounded-t');
|
||||||
|
|
||||||
|
// Show the panel
|
||||||
|
$('.tab-panel').addClass('hidden');
|
||||||
|
$('#panel-' + tab).removeClass('hidden');
|
||||||
|
|
||||||
|
// Enable/disable file inputs
|
||||||
|
$('#panel-lib input[type=file]')
|
||||||
|
.prop('disabled', tab !== 'lib')
|
||||||
|
.prop('required', tab === 'lib');
|
||||||
|
$('#panel-archive input[type=file]')
|
||||||
|
.prop('disabled', tab !== 'archive')
|
||||||
|
.prop('required', tab === 'archive');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Form submit
|
||||||
|
$('#uploadForm').on('submit', function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var formData = new FormData(this);
|
var formData = new FormData(this);
|
||||||
$.ajax({
|
$.ajax({
|
||||||
@ -42,7 +90,7 @@
|
|||||||
},
|
},
|
||||||
error: function (xhr) {
|
error: function (xhr) {
|
||||||
var error = (xhr.responseJSON && xhr.responseJSON.error) ? xhr.responseJSON.error : 'An error occurred';
|
var error = (xhr.responseJSON && xhr.responseJSON.error) ? xhr.responseJSON.error : 'An error occurred';
|
||||||
$('#result').html('<p class="text-red-600">' + error + '</p>');
|
$('#result').html('<p class="text-red-600">' + error + '</p><p class="text-red-600">' + xhr.responseJSON.details + '</p>');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user