source: ogClient-Git/src/windows/ogOperations.py @ fa0e48a

Last change on this file since fa0e48a was 355e6ca, checked in by Jose M. Guisado <jguisado@…>, 3 years ago

#1065 windows: use shutdown for poweroff and reboot operations

Running ogClient as a service (non interactive user) breaks
poweroff and reboot using ExitWindowsEx? function in user32.dll.

Spawn a subshell using os.system and use the 'shutdown' command
instead.

This is a terminating command, we don't need fine grain from
subprocess module.

  • Property mode set to 100644
File size: 3.1 KB
Line 
1#
2# Copyright (C) 2021 Soleta Networks <info@soleta.eu>
3#
4# This program is free software: you can redistribute it and/or modify it under
5# the terms of the GNU Affero General Public License as published by the
6# Free Software Foundation; either version 3 of the License, or
7# (at your option) any later version.
8
9import os
10import ctypes
11import subprocess
12from subprocess import CalledProcessError
13import multiprocessing as mp
14from multiprocessing import Process, freeze_support
15
16from PIL import Image, ImageDraw
17from pystray import Icon, Menu, MenuItem
18
19from src.ogRest import ThreadState
20
21
22def _create_default_image():
23    """
24    Creates a default image for the tray icon. Use in case
25    no favicon.ico is found.
26    """
27    width = height = 250
28    color1 = (255, 255, 255)
29    color2 = (255, 0, 255)
30
31    image = Image.new('RGB', (width, height), color1)
32    dc = ImageDraw.Draw(image)
33    dc.rectangle(
34        (width // 2, 0, width, height // 2),
35        fill=color2)
36    dc.rectangle(
37        (0, height // 2, width // 2, height),
38        fill=color2)
39
40    return image
41
42
43def create_image():
44    try:
45        image = Image.open(r'./favicon.ico')
46        image = Image.composite(image, Image.new('RGB', image.size, 'white'), image)
47    except:
48        image = _create_default_image()
49    return image
50
51
52def create_systray():
53    menu = Menu(MenuItem('Powered by Soleta Networks!',
54                         lambda icon, item: 1))
55    icon = Icon('ogClient', create_image(), menu=menu)
56    assert icon.icon
57    icon.run()
58
59
60systray_p = Process(target=create_systray)
61
62
63class OgWindowsOperations:
64
65    def __init__(self):
66        freeze_support()
67        mp.set_start_method('spawn')
68        systray_p.start()
69
70    def _restartBrowser(self, url):
71        raise NotImplementedError
72
73    def poweroff(self):
74        systray_p.terminate()
75        os.system('shutdown -s -t 0')
76
77    def reboot(self):
78        systray_p.terminate()
79        os.system('shutdown -r -t 0')
80
81    def shellrun(self, request, ogRest):
82        cmd = request.getrun()
83        try:
84            result = subprocess.run(cmd,
85                                    shell=True,
86                                    stdin=subprocess.DEVNULL,
87                                    capture_output=True,
88                                    text=True,
89                                    check=True)
90        except CalledProcessError as error:
91            if error.stderr:
92                return error.stderr
93            if error.stdout:
94                return error.stdout
95            return "{Non zero exit code and empty output}"
96        return result.stdout
97
98    def session(self, request, ogRest):
99        raise NotImplementedError
100
101    def hardware(self, path, ogRest):
102        raise NotImplementedError
103
104    def setup(self, request, ogRest):
105        raise NotImplementedError
106
107    def image_restore(self, request, ogRest):
108        raise NotImplementedError
109
110    def image_create(self, path, request, ogRest):
111        raise NotImplementedError
112
113    def refresh(self, ogRest):
114        return {"status": "WIN"}
115
116    def probe(self, ogRest):
117        return {'status': 'WIN' if ogRest.state != ThreadState.BUSY else 'BSY'}
Note: See TracBrowser for help on using the repository browser.