all working i think
This commit is contained in:
78
files/app.py
78
files/app.py
@ -1,78 +0,0 @@
|
||||
# app.py
|
||||
from flask import Flask, request, jsonify
|
||||
import subprocess
|
||||
import requests
|
||||
import psycopg2
|
||||
import os
|
||||
import re
|
||||
from datetime import datetime, timedelta
|
||||
import io
|
||||
import json
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
# API endpoint for charge
|
||||
@app.route('/test', methods=['GET'])
|
||||
def test():
|
||||
return jsonify({"message": "Hello there"}), 200
|
||||
|
||||
# API endpoint for service status
|
||||
@app.route('/get-info', methods=['GET'])
|
||||
def get_info():
|
||||
result = service_status()
|
||||
print(result)
|
||||
return jsonify(result)
|
||||
|
||||
# # Stop Service
|
||||
# @app.route('/stop', methods=['GET'])
|
||||
# def stop_service():
|
||||
# result = stop_timelapse()
|
||||
# print(result)
|
||||
# return jsonify(result)
|
||||
#
|
||||
# # Start Service
|
||||
# @app.route('/start', methods=['GET'])
|
||||
# def start_service():
|
||||
# result = start_timelapse()
|
||||
# print(result)
|
||||
# return jsonify(result)
|
||||
|
||||
# get service status
|
||||
|
||||
def service_status():
|
||||
service_name = "timelapse.service"
|
||||
try:
|
||||
# Check the status of the service using systemctl
|
||||
result = subprocess.run(['systemctl', 'is-active', service_name], check=True, capture_output=True, text=True)
|
||||
|
||||
if result.returncode == 0:
|
||||
active_status = "running" if result.stdout.strip() == b'active\n' else "not running"
|
||||
|
||||
# Get the last message from the system log for this service
|
||||
logs_result = subprocess.run(['journalctl', '-u', service_name, '-xe'], check=True, capture_output=True, text=True)
|
||||
last_message = logs_result.stdout
|
||||
|
||||
response = {
|
||||
"service_status": active_status,
|
||||
"service_message": last_message.strip() if last_message else "No message available"
|
||||
}
|
||||
|
||||
return json.dumps(response)
|
||||
else:
|
||||
raise Exception("Service is not running")
|
||||
except subprocess.CalledProcessError as e:
|
||||
response = {
|
||||
"service_status": "error",
|
||||
"service_message": str(e)
|
||||
}
|
||||
return json.dumps(response)
|
||||
except Exception as e:
|
||||
response = {
|
||||
"service_status": "error",
|
||||
"service_message": str(e)
|
||||
}
|
||||
return json.dumps(response)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True, host='0.0.0.0', port=5000)
|
||||
@ -1,23 +0,0 @@
|
||||
# Use an official Node runtime as a parent image
|
||||
FROM node:14
|
||||
|
||||
# Create and change to the app directory
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Copy package.json and package-lock.json
|
||||
COPY package*.json ./
|
||||
|
||||
# Install any needed packages specified in package.json
|
||||
RUN npm install
|
||||
|
||||
# Bundle app source inside Docker container
|
||||
COPY . .
|
||||
|
||||
# Make port 3000 available to the world outside this container
|
||||
EXPOSE 3000
|
||||
|
||||
# Define environment variable
|
||||
ENV NAME World
|
||||
|
||||
# Run app.py when the container launches
|
||||
CMD ["node", "server.js"]
|
||||
@ -1,12 +0,0 @@
|
||||
{
|
||||
"name": "docker_web_app",
|
||||
"version": "1.0.0",
|
||||
"description": "A simple Docker Web app",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"start": "node server.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.17.1"
|
||||
}
|
||||
}
|
||||
@ -1,39 +0,0 @@
|
||||
const express = require('express');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const app = express();
|
||||
const port = 3000;
|
||||
|
||||
app.use(express.static('public')); // Serve static files from the 'public' directory
|
||||
|
||||
// Endpoint to get the most recent image
|
||||
app.get('/most-recent-image', (req, res) => {
|
||||
const imagesDirectory = path.join(__dirname, 'images');
|
||||
fs.readdir(imagesDirectory, (err, files) => {
|
||||
if (err) {
|
||||
return res.status(500).send('Unable to scan directory');
|
||||
}
|
||||
let mostRecentImage = null;
|
||||
let maxDate = Date.now();
|
||||
files.forEach(file => {
|
||||
const filePath = path.join(imagesDirectory, file);
|
||||
const stats = fs.statSync(filePath);
|
||||
if (stats.isFile() && /\.(jpg|jpeg|png|gif)$/i.test(file)) {
|
||||
const currentDate = new Date(stats.mtime).getTime();
|
||||
if (currentDate < maxDate) {
|
||||
mostRecentImage = file;
|
||||
maxDate = currentDate;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (mostRecentImage) {
|
||||
res.json({ imagePath: `/images/${mostRecentImage}` });
|
||||
} else {
|
||||
res.status(404).send('No images found');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Server running at http://localhost:${port}`);
|
||||
});
|
||||
85
files/service_control_api/app.py
Normal file
85
files/service_control_api/app.py
Normal file
@ -0,0 +1,85 @@
|
||||
import subprocess
|
||||
import requests
|
||||
from lxml import html
|
||||
from flask import Flask, request, jsonify
|
||||
import json
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
def start_service():
|
||||
command = "systemctl start timelapse.service"
|
||||
try:
|
||||
# Run the command using subprocess.run()
|
||||
process = subprocess.Popen(command, shell=True)
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
return {"Error": e.strip('\n')}
|
||||
|
||||
command = "systemctl status timelapse.service | grep Active | cut -d ':' -f 2- | cut -b 2-"
|
||||
try:
|
||||
# Run the command using subprocess.run()
|
||||
result = subprocess.run(command, shell=True, check=True, capture_output=True, text=True)
|
||||
return {"Message": result.stdout.strip('\n')}
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
return {"Error": e.strip('\n')}
|
||||
|
||||
def stop_service():
|
||||
command = "systemctl stop timelapse.service"
|
||||
try:
|
||||
# Run the command using subprocess.run()
|
||||
process = subprocess.Popen(command, shell=True)
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
return {"Error": e.strip('\n')}
|
||||
|
||||
command = "systemctl status timelapse.service | grep Active | cut -d ':' -f 2- | cut -b 2-"
|
||||
try:
|
||||
# Run the command using subprocess.run()
|
||||
result = subprocess.run(command, shell=True, check=True, capture_output=True, text=True)
|
||||
return {"Message": result.stdout.strip('\n')}
|
||||
except subprocess.CalledProcessError as e:
|
||||
return {"Error": e.strip('\n')}
|
||||
|
||||
def service_status():
|
||||
command = "systemctl status timelapse.service | grep Active | cut -d ':' -f 2- | cut -b 2-"
|
||||
try:
|
||||
# Run the command using subprocess.run()
|
||||
result = subprocess.run(command, shell=True, check=True, capture_output=True, text=True)
|
||||
command = "systemctl status timelapse.service | grep Active | cut -d ':' -f 2 | cut -d ' ' -f 2"
|
||||
status = subprocess.run(command, shell=True, check=True, capture_output=True, text=True)
|
||||
return {"Message": result.stdout.strip('\n'), "Status": status.stdout.strip('\n')}
|
||||
except subprocess.CalledProcessError as e:
|
||||
return {"Error": e.strip('\n')}
|
||||
|
||||
@app.route('/start', methods=['GET'])
|
||||
def start():
|
||||
try:
|
||||
return jsonify(start_service())
|
||||
except ValueError as e:
|
||||
print(e)
|
||||
return jsonify({'error': e}), 400
|
||||
|
||||
@app.route('/stop', methods=['GET'])
|
||||
def stop():
|
||||
try:
|
||||
return jsonify(stop_service())
|
||||
except ValueError as e:
|
||||
print(e)
|
||||
return jsonify({'error': e}), 400
|
||||
|
||||
@app.route('/status', methods=['GET'])
|
||||
def status():
|
||||
try:
|
||||
return jsonify(service_status())
|
||||
except ValueError as e:
|
||||
print(e)
|
||||
return jsonify({'error': e}), 400
|
||||
|
||||
@app.route('/test', methods=['GET'])
|
||||
def test():
|
||||
return jsonify({'message': 'Hello there'})
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True, host='0.0.0.0', port=5000)
|
||||
|
||||
203
files/service_control_api/website/index.php
Normal file
203
files/service_control_api/website/index.php
Normal file
@ -0,0 +1,203 @@
|
||||
<?php
|
||||
# set default values
|
||||
$status = "Unchecked";
|
||||
$message = "No attempt made yet.";
|
||||
$button_text = "Pending";
|
||||
$button_active = false;
|
||||
$button_recent = false;
|
||||
$button_action = "";
|
||||
$button_result = "";
|
||||
$http_host = $_SERVER['HTTP_HOST'];
|
||||
|
||||
$debug_string = "";
|
||||
|
||||
if (isset($_GET['action'])) {
|
||||
$debug_string = $debug_string."GET called, ".$_GET['action']."<br>";
|
||||
$button_recent = true;
|
||||
$button_result = runAPI($_GET['action']);
|
||||
$debug_string = $debug_string."Button Result: ".$button_result."<br>";
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
function runAPI($submitted_status) {
|
||||
if(!isset($debug_string)){
|
||||
$debug_string = "";
|
||||
}
|
||||
$debug_string = $debug_string."runAPI called, ".$submitted_status."<br>";
|
||||
switch ($submitted_status) {
|
||||
case "stop":
|
||||
$apiUrl = "http://172.17.0.1:5000/stop";
|
||||
break;
|
||||
case "start":
|
||||
$apiUrl = "http://172.17.0.1:5000/start";
|
||||
break;
|
||||
default:
|
||||
$apiUrl = "http://172.17.0.1:5000/status";
|
||||
break;
|
||||
}
|
||||
// API URL
|
||||
$debug_string = $debug_string."After switch, apiUrl is ".$apiUrl."<br>";
|
||||
// Use file_get_contents or cURL to fetch the API data
|
||||
$response = file_get_contents($apiUrl);
|
||||
|
||||
if ($response === FALSE) {
|
||||
$debug_string = $debug_string."Response ERROR!!<br>";
|
||||
return "error"; // API error
|
||||
}
|
||||
|
||||
// Decode the JSON response (assuming the API returns JSON)
|
||||
$data = json_decode($response, true);
|
||||
$debug_string = $debug_string."Data from API call: ".$data['Message']."<br>";
|
||||
// Assuming the API returns a single word result (like "success", "failure", etc.)
|
||||
return isset($data['Status']) ? $data['Status'] : 'unknown';
|
||||
}
|
||||
|
||||
// Check if the button was clicked via AJAX request
|
||||
// if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
// $button_recent = true;
|
||||
// $status_at_submit = $_POST['status'];
|
||||
// echo "Set when clicked, second in code - ".$status_at_submit."<br>";
|
||||
// // Get the API result
|
||||
// $apiResult = runAPI($status_at_submit);
|
||||
// // Return the result as a JSON response
|
||||
// echo json_encode(['status' => $apiResult]);
|
||||
// exit;
|
||||
// }
|
||||
|
||||
// URL of the external API
|
||||
$apiUrl = "http://172.17.0.1:5000/status";
|
||||
|
||||
// Use file_get_contents to fetch data from the API
|
||||
$response = file_get_contents($apiUrl);
|
||||
|
||||
// Check if the request was successful
|
||||
if ($response === FALSE) {
|
||||
$data = "Failed to fetch data.";
|
||||
}
|
||||
else {
|
||||
// Decode the JSON response (assuming the API returns JSON)
|
||||
$data = json_decode($response, true);
|
||||
// If you want to display specific data, adjust this part
|
||||
// For example, if the API returns a 'message' key, display it
|
||||
if (isset($data['Message'])) {
|
||||
$message = $data['Message'];
|
||||
} else {
|
||||
$message = "No message found in the response.";
|
||||
}
|
||||
if (isset($data['Status'])) {
|
||||
$status = $data['Status'];
|
||||
} else {
|
||||
$status = "None";
|
||||
}
|
||||
}
|
||||
|
||||
switch ($status) {
|
||||
case "active":
|
||||
$button_text = "Stop Service";
|
||||
$button_active = true;
|
||||
break;
|
||||
case "inactive":
|
||||
$button_text = "Start Service";
|
||||
$button_active = true;
|
||||
break;
|
||||
case "failed":
|
||||
$button_text = "Start Service - Warning";
|
||||
$button_active = true;
|
||||
break;
|
||||
case "deactivating":
|
||||
$button_text = "Service Stopping...";
|
||||
$button_active = false;
|
||||
break;
|
||||
default:
|
||||
$button_text = "Error, No Status";
|
||||
$button_active = false;
|
||||
$status="unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
if($button_active && !$button_recent){
|
||||
$action = "";
|
||||
if($status == "active"){
|
||||
$action = "stop";
|
||||
}
|
||||
else if($status == "inactive"){
|
||||
$action = "start";
|
||||
}
|
||||
else if($status == "failed"){
|
||||
$action = "start";
|
||||
}
|
||||
$button_action = ' onclick="location.href=\'/?action='.$action.'\'" ';
|
||||
}
|
||||
|
||||
if($button_recent){
|
||||
/*
|
||||
$delay = 5; // Number of seconds before redirection
|
||||
echo "You will be redirected in $delay seconds.";
|
||||
header("Refresh: $delay; url=https://example.com");
|
||||
exit();
|
||||
*/
|
||||
header("Location: http://".$http_host);
|
||||
exit(); // Always include exit() after headers are sent
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>API Data Display</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<div class="button-container">
|
||||
<button <?php echo $button_action; ?> class="<?php echo $status; ?>" id="phpButton"<?php if(!$button_active || $button_recent) {echo " disabled";} ?>>
|
||||
<?php echo $button_text; ?>
|
||||
</button>
|
||||
<p>
|
||||
</div>
|
||||
<p>
|
||||
<div class="api-data">
|
||||
<!-- PHP will inject the data here -->
|
||||
<?php
|
||||
echo "Full Message:<br>".htmlspecialchars($message)."<p>Current Date:<br>".date("F j, Y, g:i:s a")."<p>";
|
||||
?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<script>
|
||||
|
||||
// When the button is clicked, send an AJAX request to fetch new data
|
||||
document.getElementById('phpButton').addEventListener('click', function() {
|
||||
// Disable button to avoid multiple clicks
|
||||
this.disabled = true;
|
||||
this.innerText = 'Loading...';
|
||||
|
||||
// Make an AJAX request
|
||||
fetch('index.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
'status': '<?php echo $status; ?>'
|
||||
},
|
||||
body: 'action=fetch_data' // Trigger the PHP function via POST
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
<script>
|
||||
// Automatically refresh the page every second
|
||||
setTimeout(function() {
|
||||
location.reload();
|
||||
}, <?php if($button_recent){ echo "5000"; } else{ echo "1000"; } ?>); // Refresh interval (1000 ms = 1 second)
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
80
files/service_control_api/website/styles.css
Normal file
80
files/service_control_api/website/styles.css
Normal file
@ -0,0 +1,80 @@
|
||||
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: #2c3e50; /* Dark background color */
|
||||
color: #bdc3c7; /* Dimmer text color */
|
||||
zoom: 1.5
|
||||
}
|
||||
.container {
|
||||
max-width: 500px;
|
||||
margin: 0 auto;
|
||||
margin-top: 20px;
|
||||
padding: 20px;
|
||||
background-color: #34495e; /* Darker background for container */
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); /* Slightly darker shadow */
|
||||
}
|
||||
.api-data {
|
||||
font-size: 1.4rem;
|
||||
color: #bdc3c7; /* Dimmer text color */
|
||||
}
|
||||
.loading {
|
||||
font-size: 1.2rem;
|
||||
background-color: #34495e; /* Darker background for container-wide */
|
||||
}
|
||||
.status-button {
|
||||
padding: 10px 20px;
|
||||
font-size: 1.5rem;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
margin-top: 20px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.button-container {
|
||||
display: flex;
|
||||
justify-content: center; /* This centers the button horizontally */
|
||||
}
|
||||
button {
|
||||
background: radial-gradient(circle, #ff7e5f 0%, #feb47b 100%);
|
||||
border: none;
|
||||
color: white;
|
||||
font-size: 30px;
|
||||
padding: 25px 50px;
|
||||
text-align: center;
|
||||
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2);
|
||||
border-radius: 30px;
|
||||
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
|
||||
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
|
||||
}
|
||||
|
||||
button:hover {
|
||||
transform: scale(1.05);
|
||||
box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);
|
||||
}
|
||||
.inactive {
|
||||
background-color: #0b660e;
|
||||
background: radial-gradient(circle, #0b660e 0%, #2b922f 100%);
|
||||
color: #bdc3c7; /* Dimmer text color */
|
||||
}
|
||||
.active {
|
||||
background-color: #a5150b;
|
||||
background: radial-gradient(circle, #a5150b 0%, #d6382d 100%);
|
||||
color: #bdc3c7; /* Dimmer text color */
|
||||
}
|
||||
.failed {
|
||||
background-color: #671281;
|
||||
background: radial-gradient(circle, #671281 0%, #8423a1 100%);
|
||||
color: #bdc3c7; /* Dimmer text color */
|
||||
}
|
||||
.deactivating {
|
||||
background-color: #003699;
|
||||
background: radial-gradient(circle, #003699 0%, #337aff 100%);
|
||||
color: #bdc3c7; /* Dimmer text color */
|
||||
}
|
||||
.unknown {
|
||||
background-color: #ec701e;
|
||||
background: radial-gradient(circle, #c9580d 0%, #ec701e 100%);
|
||||
color: #bdc3c7; /* Dimmer text color */
|
||||
}
|
||||
Reference in New Issue
Block a user