client api updated
This commit is contained in:
@ -1,3 +1,4 @@
|
||||
# this got big...
|
||||
from flask import Flask, jsonify
|
||||
from flask_apscheduler import APScheduler
|
||||
import psutil
|
||||
@ -6,12 +7,20 @@ import requests
|
||||
from requests import RequestException, Response
|
||||
import json
|
||||
from subprocess import check_output
|
||||
import win32api
|
||||
from datetime import datetime, timedelta
|
||||
import sys
|
||||
from pathlib import Path
|
||||
import wmi
|
||||
import pythoncom
|
||||
import ctypes
|
||||
from ctypes import wintypes
|
||||
|
||||
app = Flask(__name__)
|
||||
scheduler = APScheduler()
|
||||
app.config['JSONIFY_PRETTYPRINT_REGULAR'] = True
|
||||
|
||||
# Bits to Bytes etc
|
||||
# human readable bytes
|
||||
def bytes_to_human_readable(bytes):
|
||||
for unit in ['B', 'KB', 'MB', 'GB', 'TB']:
|
||||
if bytes < 1024.0:
|
||||
@ -111,8 +120,10 @@ def get_disk_info():
|
||||
partitions = psutil.disk_partitions()
|
||||
for partition in partitions:
|
||||
usage = psutil.disk_usage(partition.mountpoint)
|
||||
drive_letter = partition.device.replace('\\\\', '\\').rstrip('\\')
|
||||
disk_info.append({
|
||||
'device': partition.device.replace('\\\\', '\\').rstrip('\\'),
|
||||
'device': drive_letter,
|
||||
'label': get_drive_label(drive_letter),
|
||||
#'mountpoint': partition.mountpoint,
|
||||
'fstype': partition.fstype,
|
||||
'total': bytes_to_human_readable(usage.total),
|
||||
@ -122,6 +133,101 @@ def get_disk_info():
|
||||
})
|
||||
return disk_info
|
||||
|
||||
# drive label function
|
||||
def get_drive_label(drive_letter: str) -> str:
|
||||
result = "none"
|
||||
root = drive_letter.strip()
|
||||
if not root.endswith(':'):
|
||||
root += ':'
|
||||
if not root.endswith('\\'):
|
||||
root += '\\'
|
||||
|
||||
# Make sure the drive actually exists
|
||||
if not os.path.exists(root):
|
||||
# Not a valid drive letter, return None so the caller can decide what to do.
|
||||
print(f"[DEBUG] Drive '{root}' does not exist.")
|
||||
result = "drive does not exist 0_o"
|
||||
|
||||
# Prepare buffers for the Win32 API call
|
||||
volume_name_buf = ctypes.create_unicode_buffer(260) # MAX_PATH
|
||||
fs_name_buf = ctypes.create_unicode_buffer(260)
|
||||
|
||||
serial_number = wintypes.DWORD()
|
||||
max_component_len = wintypes.DWORD()
|
||||
file_system_flags = wintypes.DWORD()
|
||||
|
||||
# Call GetVolumeInformationW
|
||||
res = ctypes.windll.kernel32.GetVolumeInformationW(
|
||||
ctypes.c_wchar_p(root), # lpRootPathName
|
||||
volume_name_buf, # lpVolumeNameBuffer
|
||||
ctypes.sizeof(volume_name_buf), # nVolumeNameSize
|
||||
ctypes.byref(serial_number), # lpVolumeSerialNumber
|
||||
ctypes.byref(max_component_len), # lpMaximumComponentLength
|
||||
ctypes.byref(file_system_flags), # lpFileSystemFlags
|
||||
fs_name_buf, # lpFileSystemNameBuffer
|
||||
ctypes.sizeof(fs_name_buf) # nFileSystemNameSize
|
||||
)
|
||||
if res == 0: # The call failed
|
||||
err = ctypes.get_last_error()
|
||||
print(f"[ERROR] GetVolumeInformationW failed for '{root}'. "
|
||||
f"Win32 error code: {err}")
|
||||
result = "label error"
|
||||
else:
|
||||
result = volume_name_buf.value
|
||||
if volume_name_buf.value == '':
|
||||
result = "no_label"
|
||||
|
||||
return result
|
||||
|
||||
|
||||
# os info function
|
||||
def get_os_info() -> str:
|
||||
result = "windows"
|
||||
pythoncom.CoInitialize()
|
||||
#try:
|
||||
wmi_data = wmi.WMI()
|
||||
os_info = wmi_data.Win32_OperatingSystem()[0]
|
||||
#return {
|
||||
# "Name" : os_info.Name,
|
||||
# "Version" : os_info.Version,
|
||||
# "BuildNumber": os_info.BuildNumber,
|
||||
# "InstallDate": os_info.InstallDate,
|
||||
# "ProductType": int(os_info.ProductType)
|
||||
#}
|
||||
# 1. Major version + edition (e.g. "10 Pro")
|
||||
# os_info.Caption → "Microsoft Windows 10 Pro"
|
||||
parts = os_info.Caption.split()
|
||||
major = parts[2] # "10"
|
||||
edition = parts[3] # "Pro" (for server: "2019", etc.)
|
||||
major_edition = f"{major} {edition}"
|
||||
# 2. Build number
|
||||
build = os_info.BuildNumber
|
||||
# 3. Install date (WMI gives an ISO‑8601 string)
|
||||
# e.g. "20210930142300.000000+000"
|
||||
install_ts = os_info.InstallDate[:14] # "20210930142300"
|
||||
dt = datetime.strptime(install_ts, "%Y%m%d%H%M%S")
|
||||
install_date = f"{dt.month}-{dt.day}-{dt.year}"
|
||||
result = f"Windows {major_edition} - Build {build} - Installed {install_date}"
|
||||
#except Exception as e:
|
||||
# print(e)
|
||||
# result = "wmi_error"
|
||||
return result
|
||||
|
||||
# server reporter info
|
||||
def get_server_info() -> dict:
|
||||
result = {}
|
||||
drives_dict = get_crystal_disk_info()
|
||||
data_dict = {
|
||||
"hostname": "{{ hostname_output.stdout_lines[0] }}",
|
||||
"os_string": get_os_info(),
|
||||
"drives": drives_dict["drives"],
|
||||
"API_KEY": "deadbeef",
|
||||
"storage_summary": get_disk_info()
|
||||
|
||||
}
|
||||
result = data_dict
|
||||
return result
|
||||
|
||||
# Flask endpoints
|
||||
|
||||
@app.route('/disk', methods=['GET'])
|
||||
@ -132,18 +238,23 @@ def disk():
|
||||
def drive_health():
|
||||
return jsonify(get_crystal_disk_info())
|
||||
|
||||
@app.route('/full', methods=['GET'])
|
||||
def full_summary():
|
||||
return jsonify(get_server_info())
|
||||
|
||||
@app.route('/test', methods=['GET'])
|
||||
def test_flask():
|
||||
return jsonify({
|
||||
"message": "hello world",
|
||||
"os_string": get_os_info()
|
||||
})
|
||||
|
||||
|
||||
def server_reporter():
|
||||
#base_url="https://cosmostat.matt-cloud.com"
|
||||
base_url="http://10.200.27.20:5001"
|
||||
url = f"{base_url}/storage_client_update"
|
||||
drives_dict = get_crystal_disk_info()
|
||||
data_dict = {
|
||||
"hostname": "{{ hostname_output.stdout_lines[0] }}",
|
||||
"drives": drives_dict["drives"],
|
||||
"API_KEY": "deadbeef",
|
||||
"storage_summary": get_disk_info()
|
||||
|
||||
}
|
||||
data_dict = get_server_info()
|
||||
result = []
|
||||
try:
|
||||
response = requests.post(url, json=data_dict)
|
||||
@ -170,6 +281,13 @@ if __name__ == '__main__':
|
||||
return result
|
||||
|
||||
# gonna try something wild
|
||||
|
||||
run_date = datetime.now() + timedelta(seconds=15)
|
||||
scheduler.add_job(id='init_disk_info',
|
||||
func=update_disk_info,
|
||||
trigger='date',
|
||||
run_date=run_date)
|
||||
|
||||
scheduler.add_job(id='update_disk_info',
|
||||
func=update_disk_info,
|
||||
trigger='interval',
|
||||
@ -183,6 +301,6 @@ if __name__ == '__main__':
|
||||
scheduler.init_app(app)
|
||||
scheduler.start()
|
||||
|
||||
update_disk_info()
|
||||
#update_disk_info()
|
||||
|
||||
app.run(host='0.0.0.0', port={{ api_service_port }})
|
||||
|
||||
Reference in New Issue
Block a user