refs #247 merge pull request 'migrate agent from py2 & qt4/qt5 to py3 & qt6' (#1) from python3 into main
commit
5294919c98
|
@ -0,0 +1,20 @@
|
|||
.DS_Store
|
||||
.editorconfig
|
||||
.idea
|
||||
**/*.swp
|
||||
__pycache__/
|
||||
linux/debian/.debhelper/
|
||||
linux/debian/files
|
||||
linux/debian/ogagent/
|
||||
linux/debian/ogagent.debhelper.log
|
||||
linux/debian/ogagent.postinst.debhelper
|
||||
linux/debian/ogagent.postrm.debhelper
|
||||
linux/configure-stamp
|
||||
linux/build-stamp
|
||||
ogagent_*_all.deb
|
||||
ogagent_*_amd64.buildinfo
|
||||
ogagent_*_amd64.changes
|
||||
ogagent_*_amd64.build
|
||||
src/about_dialog_ui.py
|
||||
src/message_dialog_ui.py
|
||||
src/OGAgent_rc.py
|
|
@ -1,25 +1,22 @@
|
|||
OGAgent: agente OpenGnsys para sistemas operativos INSTALL.es.txt
|
||||
====================================================================
|
||||
|
||||
|
||||
Requisitos de creación
|
||||
----------------------
|
||||
Sisitema operativo Linux con los siguientes paquetes instalados:
|
||||
- Subversion
|
||||
- GNU C++, Python, librerías PyQt4
|
||||
Sistema operativo Linux con los siguientes paquetes instalados:
|
||||
- GNU C++, Python, librerías PyQt6
|
||||
- Creación de instalador Exe (Wine 32 bits, Wine Gecko, Wine Mono, Samba Winbind, Cabextrct)
|
||||
- Creación de paquetes Deb (debhelper, dpkg-dev)
|
||||
- Creación de paquetes RPM (rpm-build)
|
||||
- Creación de paquetes Pkg (xar, bomutils)
|
||||
|
||||
|
||||
Crear instaladores de OGAgent
|
||||
-----------------------------
|
||||
- Paso previo: actaulizar componentes gráficos de PyQt para OGAgnet:
|
||||
- Paso previo: actualizar componentes gráficos de PyQt para OGAgent:
|
||||
src/update.sh
|
||||
|
||||
- Crear paquetes Deb y RPM para distribuciones Linux (requiere permisos de "root"):
|
||||
sudo linux/build-packages.sh
|
||||
- Crear paquetes Deb distribuciones debian/ubuntu
|
||||
linux/build-packages.sh
|
||||
|
||||
- Crear paquete Pkg para sistemas operativos macOS X:
|
||||
sudo macos/build-pkg.sh
|
||||
|
@ -27,8 +24,8 @@ Crear instaladores de OGAgent
|
|||
- Crear el programa instalador para sistemas operativos Windows:
|
||||
windows/build-windows.sh
|
||||
|
||||
- Subir los nuevos ficheros .deb, .rpm, .pkg y .exe generados al directorio
|
||||
/opt/opengnsys/www/descargas del servidor OpenGnsys.
|
||||
- Subir los nuevos ficheros .deb, .pkg y .exe generados al directorio
|
||||
/opt/opengnsys/www/descargas del servidor OpenGnsys.
|
||||
|
||||
|
||||
Instalar OGAgent en cliente modelo
|
||||
|
@ -43,20 +40,6 @@ Instalar OGAgent en cliente modelo
|
|||
- Iniciar el servicio (se iniciará automáticamente en el proceso de arranque):
|
||||
sudo service ogagent start
|
||||
|
||||
- Red Hat, Fedora y derivados (como root):
|
||||
- Descargar e instalar el agente:
|
||||
yum install ogagent-Version.noarch.rpm (Red Hat/CentOS)
|
||||
dnf install ogagent-Version.noarch.rpm (Fedora)
|
||||
- Configurar el agente:
|
||||
sed -i "0,/remote=/ s,remote=.*,remote=https://IPServidorOpenGnsys/opengnsys/rest/," /usr/share/OGAgent/cfg/ogagent.cfg
|
||||
- Puede ser necesario corregir permisos antes de iniciar el servicio:
|
||||
chmod +x /etc/init.d/ogagent
|
||||
- Iniciar el servicio (se iniciará automáticamente en el proceso de arranque):
|
||||
service ogagent start
|
||||
|
||||
- OpenSuSE:
|
||||
(en preparación)
|
||||
|
||||
- Windows (como usuario administrador):
|
||||
- Descargar e instalar el agente ejecutando:
|
||||
OGAgentSetup-Version.exe
|
||||
|
@ -83,5 +66,3 @@ Postconfiguración para clientes clonados
|
|||
- Ejecutar manualmente o configurar automáticamente OGAgent en los clientes clonados
|
||||
en el script de postconfiguración tras restuarar imagen:
|
||||
ogConfigureOgagent NDisco Npart
|
||||
|
||||
|
||||
|
|
|
@ -1,37 +1,6 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd $(dirname "$0")
|
||||
top=$(pwd)
|
||||
|
||||
VERSION="$(cat ../src/VERSION 2>/dev/null)" || VERSION="1.1.1"
|
||||
RELEASE="1"
|
||||
|
||||
# Debian based
|
||||
dpkg-buildpackage -b -d
|
||||
|
||||
# Fix version number.
|
||||
sed -e "s/version 0.0.0/version ${VERSION}/g" \
|
||||
-e "s/release 1/release ${RELEASE}/g" ogagent-template.spec > ogagent-$VERSION.spec
|
||||
|
||||
# Now fix dependencies for opensuse
|
||||
sed -e "s/name ogagent/name ogagent-opensuse/g" \
|
||||
-e "s/version 0.0.0/version ${VERSION}/g" \
|
||||
-e "s/release 1/release ${RELEASE}/g" \
|
||||
-e "s/chkconfig//g" \
|
||||
-e "s/initscripts/insserv/g" \
|
||||
-e "s/PyQt4/python-qt4/g" \
|
||||
-e "s/libXScrnSaver/libXss1/g" ogagent-template.spec > ogagent-opensuse-$VERSION.spec
|
||||
|
||||
|
||||
# Right now, ogagent-xrdp-1.7.0.spec is not needed
|
||||
for pkg in ogagent-$VERSION.spec ogagent-opensuse-$VERSION.spec; do
|
||||
|
||||
rm -rf rpm
|
||||
for folder in SOURCES BUILD RPMS SPECS SRPMS; do
|
||||
mkdir -p rpm/$folder
|
||||
done
|
||||
|
||||
rpmbuild -v -bb --clean --buildroot=$top/rpm/BUILD/$pkg-root --target noarch $pkg 2>&1
|
||||
done
|
||||
|
||||
#rm ogagent-$VERSION
|
||||
debuild -D --build=binary --post-clean --lintian-opts --profile debian
|
||||
|
|
|
@ -1,3 +1,21 @@
|
|||
ogagent (1.3.0-2) stable; urgency=medium
|
||||
|
||||
* Add missing dependency on zenity
|
||||
|
||||
-- OpenGnsys developers <info@opengnsys.es> Thu, 25 Apr 2024 15:53:16 +0200
|
||||
|
||||
ogagent (1.3.0-1) stable; urgency=medium
|
||||
|
||||
* Upgrade to Qt 6
|
||||
|
||||
-- OpenGnsys developers <info@opengnsys.es> Thu, 25 Apr 2024 12:50:20 +0200
|
||||
|
||||
ogagent (1.2.0) unstable; urgency=medium
|
||||
|
||||
* Python 3 and Qt 5 compatibility
|
||||
|
||||
-- OpenGnsys developers <info@opengnsys.es> Mon, 4 May 2020 18:00:00 +0100
|
||||
|
||||
ogagent (1.1.1b) stable; urgency=medium
|
||||
|
||||
* Use python-distro to detect the distribution version
|
||||
|
|
|
@ -1 +1 @@
|
|||
9
|
||||
10
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
Source: ogagent
|
||||
Section: admin
|
||||
Priority: optional
|
||||
Maintainer: Ramón M. Gómez <ramongomez@us.es>
|
||||
Maintainer: OpenGnsys developers <info@opengnsys.es>
|
||||
Build-Depends: debhelper (>= 7), po-debconf
|
||||
Standards-Version: 3.9.2
|
||||
Homepage: https://opengnsys.es/
|
||||
|
@ -11,8 +11,7 @@ Section: admin
|
|||
Priority: optional
|
||||
Architecture: all
|
||||
Depends:
|
||||
policykit-1 (>= 0.100), python2 (>=2.7) | python (>= 2.7), python-qt4 (>= 4.9),, python-requests (>= 0.8.2),
|
||||
python-six (>= 1.1), python-prctl (>= 1.1.1), python-distro, libxss1, ${misc:Depends}
|
||||
Suggests: gnome-shell-extension-top-icons-plus
|
||||
policykit-1 (>= 0.100), python3 (>=3.4) | python (>= 3.4), python3-pyqt6, python3-requests,
|
||||
python3-six, python3-prctl, python3-distro, libxss1, zenity, ${misc:Depends}
|
||||
Description: OpenGnsys Agent for Operating Systems
|
||||
This package provides the required components to allow this machine to work on an environment managed by OpenGnsys.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
Format-Specification: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?op=file&rev=135
|
||||
Name: ogagent
|
||||
Maintainer: Ramón M. Gómez
|
||||
Maintainer: OpenGnsys developers
|
||||
Source: https://opengnsys.es
|
||||
|
||||
Copyright: 2014 Virtual Cable S.L.U.
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
# Automatically added by dh_installinit
|
||||
if [ -x "/etc/init.d/ogagent" ]; then
|
||||
update-rc.d ogagent defaults >/dev/null || exit $?
|
||||
fi
|
||||
# End automatically added section
|
|
@ -1,12 +0,0 @@
|
|||
# Automatically added by dh_installinit
|
||||
if [ "$1" = "purge" ] ; then
|
||||
update-rc.d ogagent remove >/dev/null
|
||||
fi
|
||||
|
||||
|
||||
# In case this system is running systemd, we make systemd reload the unit files
|
||||
# to pick up changes.
|
||||
if [ -d /run/systemd/system ] ; then
|
||||
systemctl --system daemon-reload >/dev/null || true
|
||||
fi
|
||||
# End automatically added section
|
|
@ -1,2 +0,0 @@
|
|||
misc:Depends=
|
||||
misc:Pre-Depends=
|
|
@ -31,7 +31,7 @@ binary-indep: build install
|
|||
dh_installdocs
|
||||
dh_installdebconf
|
||||
dh_installinit --no-start
|
||||
dh_python2=python
|
||||
dh_python3=python
|
||||
dh_compress
|
||||
dh_link
|
||||
dh_fixperms
|
||||
|
|
|
@ -1,83 +0,0 @@
|
|||
%define _topdir %(echo $PWD)/rpm
|
||||
%define name ogagent
|
||||
%define version 0.0.0
|
||||
%define release 1
|
||||
%define buildroot %{_topdir}/%{name}-%{version}-%{release}-root
|
||||
|
||||
BuildRoot: %{buildroot}
|
||||
Name: %{name}
|
||||
Version: %{version}
|
||||
Release: %{release}
|
||||
Summary: OpenGnsys Agent for Operating Systems
|
||||
License: BSD3
|
||||
Group: Admin
|
||||
Requires: chkconfig initscripts python-six python-requests python-distro PyQt4 libXScrnSaver
|
||||
Vendor: OpenGnsys Project
|
||||
URL: https://opengnsys.es/
|
||||
Provides: ogagent
|
||||
|
||||
%define _rpmdir ../
|
||||
%define _rpmfilename %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm
|
||||
|
||||
|
||||
%install
|
||||
curdir=`pwd`
|
||||
cd ../..
|
||||
make DESTDIR=$RPM_BUILD_ROOT DISTRO=rh install-ogagent
|
||||
cd $curdir
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
curdir=`pwd`
|
||||
cd ../..
|
||||
make DESTDIR=$RPM_BUILD_ROOT DISTRO=rh clean
|
||||
cd $curdir
|
||||
|
||||
|
||||
%post
|
||||
systemctl enable ogagent.service > /dev/null 2>&1
|
||||
|
||||
%preun
|
||||
systemctl disable ogagent.service > /dev/null 2>&1
|
||||
systemctl stop ogagent.service > /dev/null 2>&1
|
||||
|
||||
%postun
|
||||
# $1 == 0 on uninstall, == 1 on upgrade for preun and postun (just a reminder for me... :) )
|
||||
if [ $1 -eq 0 ]; then
|
||||
rm -rf /etc/ogagent
|
||||
rm /var/log/ogagent.log
|
||||
fi
|
||||
# And, posibly, the .pyc leaved behind on /usr/share/OGAgent
|
||||
rm -rf /usr/share/OGAgent > /dev/null 2>&1
|
||||
|
||||
%description
|
||||
This package provides the required components to allow this machine to work on an environment managed by OpenGnsys.
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
/etc/ogagent
|
||||
/etc/xdg/autostart/OGAgentTool.desktop
|
||||
/etc/init.d/ogagent
|
||||
/usr/bin/OGAgentTool-startup
|
||||
/usr/bin/ogagent
|
||||
/usr/bin/OGAgentTool
|
||||
/usr/share/OGAgent/*
|
||||
/usr/share/autostart/OGAgentTool.desktop
|
||||
|
||||
%changelog
|
||||
* Fri Feb 07 2020 Ramón M. Gómez <ramongomez@us.es> - 1.1.1b-1
|
||||
- Use python-distro to detect the distribution version
|
||||
|
||||
* Thu May 23 2019 Ramón M. Gómez <ramongomez@us.es> - 1.1.1-1
|
||||
- Set connection timeout
|
||||
- Compatibility with "Exam Mode" from the University of Seville
|
||||
|
||||
* Wed May 22 2019 Ramón M. Gómez <ramongomez@us.es> - 1.1.0a-1
|
||||
- Fix a bug when activating the agent with some network devices
|
||||
|
||||
* Tue Oct 13 2016 Ramón M. Gómez <ramongomez@us.es> - 1.1.0-1
|
||||
- Functional OpenGnsys Agent interacting with OpenGnsys Server 1.1.0
|
||||
|
||||
* Tue Jul 18 2015 Adolfo Gómez García <agomez@virtualcable.es> - 1.0.0-1
|
||||
- Initial release for OpenGnsys Agent
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
#!/bin/sh
|
||||
|
||||
for p in python python2; do
|
||||
[ -z "$PYTHON" ] && [ $($p -c 'import sys; print(sys.version_info[0])') -eq 2 ] && PYTHON=$p
|
||||
for p in python python3; do
|
||||
[ "$(command -v $p)" ] && [ -z "$PYTHON" ] && [ $($p -c 'import sys; print(sys.version_info[0])') -eq 3 ] && PYTHON=$p
|
||||
done
|
||||
if [ -z "$PYTHON" ]; then
|
||||
echo "ERROR: OGAgent needs Python 2" &>2
|
||||
echo "ERROR: OGAgent needs Python 3" &>2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#!/bin/sh
|
||||
|
||||
for p in python python2; do
|
||||
[ -z "$PYTHON" ] && [ $($p -c 'import sys; print(sys.version_info[0])') -eq 2 ] && PYTHON=$p
|
||||
for p in python python3; do
|
||||
[ "$(command -v $p)" ] && [ -z "$PYTHON" ] && [ $($p -c 'import sys; print(sys.version_info[0])') -eq 3 ] && PYTHON=$p
|
||||
done
|
||||
if [ -z "$PYTHON" ]; then
|
||||
echo "ERROR: OGAgent needs Python 2" &>2
|
||||
echo "ERROR: OGAgent needs Python 3" &>2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
six
|
||||
requests
|
||||
|
|
@ -29,7 +29,6 @@
|
|||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import win32service
|
||||
import win32serviceutil
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
|
@ -29,28 +29,21 @@
|
|||
"""
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import atexit
|
||||
import base64
|
||||
import json
|
||||
import sys
|
||||
import time
|
||||
import json
|
||||
import six
|
||||
import atexit
|
||||
from PyQt4 import QtCore, QtGui # @UnresolvedImport
|
||||
from PyQt6 import QtCore, QtGui, QtWidgets
|
||||
|
||||
from opengnsys import VERSION, ipc, operations, utils
|
||||
from opengnsys.log import logger
|
||||
from opengnsys.service import IPC_PORT
|
||||
from about_dialog_ui import Ui_OGAAboutDialog
|
||||
from message_dialog_ui import Ui_OGAMessageDialog
|
||||
from opengnsys.scriptThread import ScriptExecutorThread
|
||||
from opengnsys import VERSION, ipc, operations, utils
|
||||
from opengnsys.config import readConfig
|
||||
from opengnsys.loader import loadModules
|
||||
|
||||
# Set default characters encoding to UTF-8
|
||||
reload(sys)
|
||||
if hasattr(sys, 'setdefaultencoding'):
|
||||
sys.setdefaultencoding('utf-8')
|
||||
from opengnsys.log import logger
|
||||
from opengnsys.scriptThread import ScriptExecutorThread
|
||||
from opengnsys.service import IPC_PORT
|
||||
|
||||
trayIcon = None
|
||||
|
||||
|
@ -61,9 +54,9 @@ def sigAtExit():
|
|||
|
||||
|
||||
# About dialog
|
||||
class OGAAboutDialog(QtGui.QDialog):
|
||||
class OGAAboutDialog(QtWidgets.QDialog):
|
||||
def __init__(self, parent=None):
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
QtWidgets.QDialog.__init__(self, parent)
|
||||
self.ui = Ui_OGAAboutDialog()
|
||||
self.ui.setupUi(self)
|
||||
self.ui.VersionLabel.setText("Version " + VERSION)
|
||||
|
@ -72,9 +65,9 @@ class OGAAboutDialog(QtGui.QDialog):
|
|||
self.hide()
|
||||
|
||||
|
||||
class OGAMessageDialog(QtGui.QDialog):
|
||||
class OGAMessageDialog(QtWidgets.QDialog):
|
||||
def __init__(self, parent=None):
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
QtWidgets.QDialog.__init__(self, parent)
|
||||
self.ui = Ui_OGAMessageDialog()
|
||||
self.ui.setupUi(self)
|
||||
|
||||
|
@ -89,7 +82,7 @@ class OGAMessageDialog(QtGui.QDialog):
|
|||
class MessagesProcessor(QtCore.QThread):
|
||||
logoff = QtCore.pyqtSignal(name='logoff')
|
||||
message = QtCore.pyqtSignal(tuple, name='message')
|
||||
script = QtCore.pyqtSignal(QtCore.QString, name='script')
|
||||
script = QtCore.pyqtSignal(str, name='script')
|
||||
exit = QtCore.pyqtSignal(name='exit')
|
||||
|
||||
def __init__(self, port):
|
||||
|
@ -119,9 +112,9 @@ class MessagesProcessor(QtCore.QThread):
|
|||
if self.ipc:
|
||||
self.ipc.sendLogin(user_data)
|
||||
|
||||
def sendLogout(self, userName):
|
||||
def sendLogout(self, username):
|
||||
if self.ipc:
|
||||
self.ipc.sendLogout(userName)
|
||||
self.ipc.sendLogout(username)
|
||||
|
||||
def run(self):
|
||||
if self.ipc is None:
|
||||
|
@ -136,20 +129,17 @@ class MessagesProcessor(QtCore.QThread):
|
|||
msg = self.ipc.getMessage()
|
||||
if msg is None:
|
||||
break
|
||||
msgId, data = msg
|
||||
logger.debug('Got Message on User Space: {}:{}'.format(msgId, data))
|
||||
if msgId == ipc.MSG_MESSAGE:
|
||||
module, message, data = data.split('\0')
|
||||
msg_id, data = msg
|
||||
logger.debug('Got Message on User Space: {}:{}'.format(msg_id, data))
|
||||
if msg_id == ipc.MSG_MESSAGE:
|
||||
module, message, data = data.decode('utf-8').split('\0')
|
||||
self.message.emit((module, message, data))
|
||||
elif msgId == ipc.MSG_LOGOFF:
|
||||
elif msg_id == ipc.MSG_LOGOFF:
|
||||
self.logoff.emit()
|
||||
elif msgId == ipc.MSG_SCRIPT:
|
||||
self.script.emit(QtCore.QString.fromUtf8(data))
|
||||
elif msg_id == ipc.MSG_SCRIPT:
|
||||
self.script.emit(data.decode('utf-8'))
|
||||
except Exception as e:
|
||||
try:
|
||||
logger.error('Got error on IPC thread {}'.format(utils.exceptionToMessage(e)))
|
||||
except:
|
||||
logger.error('Got error on IPC thread (an unicode error??)')
|
||||
logger.error('Got error on IPC thread {}'.format(utils.exceptionToMessage(e)))
|
||||
|
||||
if self.ipc.running is False and self.running is True:
|
||||
logger.warn('Lost connection with Service, closing program')
|
||||
|
@ -157,27 +147,24 @@ class MessagesProcessor(QtCore.QThread):
|
|||
self.exit.emit()
|
||||
|
||||
|
||||
class OGASystemTray(QtGui.QSystemTrayIcon):
|
||||
class OGASystemTray(QtWidgets.QSystemTrayIcon):
|
||||
def __init__(self, app_, parent=None):
|
||||
self.app = app_
|
||||
self.config = readConfig(client=True)
|
||||
|
||||
self.modules = None
|
||||
# Get opengnsys section as dict
|
||||
cfg = dict(self.config.items('opengnsys'))
|
||||
|
||||
# Set up log level
|
||||
logger.setLevel(cfg.get('log', 'INFO'))
|
||||
|
||||
self.ipcport = int(cfg.get('ipc_port', IPC_PORT))
|
||||
|
||||
# style = app.style()
|
||||
# icon = QtGui.QIcon(style.standardPixmap(QtGui.QStyle.SP_ComputerIcon))
|
||||
icon = QtGui.QIcon(':/images/img/oga.png')
|
||||
|
||||
QtGui.QSystemTrayIcon.__init__(self, icon, parent)
|
||||
self.menu = QtGui.QMenu(parent)
|
||||
exitAction = self.menu.addAction("About")
|
||||
exitAction.triggered.connect(self.about)
|
||||
QtWidgets.QSystemTrayIcon.__init__(self, icon, parent)
|
||||
self.menu = QtWidgets.QMenu(parent)
|
||||
exit_action = self.menu.addAction("About")
|
||||
exit_action.triggered.connect(self.about)
|
||||
self.setContextMenu(self.menu)
|
||||
self.ipc = MessagesProcessor(self.ipcport)
|
||||
|
||||
|
@ -208,18 +195,16 @@ class OGASystemTray(QtGui.QSystemTrayIcon):
|
|||
logger.debug('Modules: {}'.format(list(v.name for v in self.modules)))
|
||||
|
||||
# Send init to all modules
|
||||
validMods = []
|
||||
valid_mods = []
|
||||
for mod in self.modules:
|
||||
try:
|
||||
logger.debug('Activating module {}'.format(mod.name))
|
||||
mod.activate()
|
||||
validMods.append(mod)
|
||||
valid_mods.append(mod)
|
||||
except Exception as e:
|
||||
logger.exception()
|
||||
logger.error("Activation of {} failed: {}".format(mod.name, utils.exceptionToMessage(e)))
|
||||
|
||||
self.modules[:] = validMods # copy instead of assignment
|
||||
|
||||
self.modules[:] = valid_mods # copy instead of assignment
|
||||
# If this is running, it's because he have logged in, inform service of this fact
|
||||
self.ipc.sendLogin((operations.getCurrentUser(), operations.getSessionLanguage(),
|
||||
operations.get_session_type()))
|
||||
|
@ -260,7 +245,7 @@ class OGASystemTray(QtGui.QSystemTrayIcon):
|
|||
|
||||
def executeScript(self, script):
|
||||
logger.debug('Executing script')
|
||||
script = six.text_type(script.toUtf8()).decode('base64')
|
||||
script = base64.b64decode(script.encode('ascii'))
|
||||
th = ScriptExecutorThread(script)
|
||||
th.start()
|
||||
|
||||
|
@ -269,7 +254,7 @@ class OGASystemTray(QtGui.QSystemTrayIcon):
|
|||
operations.logoff() # Invoke log off
|
||||
|
||||
def about(self):
|
||||
self.aboutDlg.exec_()
|
||||
self.aboutDlg.exec()
|
||||
|
||||
def cleanup(self):
|
||||
logger.debug('Quit invoked')
|
||||
|
@ -311,14 +296,14 @@ class OGASystemTray(QtGui.QSystemTrayIcon):
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = QtGui.QApplication(sys.argv)
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
|
||||
if not QtGui.QSystemTrayIcon.isSystemTrayAvailable():
|
||||
if not QtWidgets.QSystemTrayIcon.isSystemTrayAvailable():
|
||||
# QtGui.QMessageBox.critical(None, "Systray", "I couldn't detect any system tray on this system.")
|
||||
sys.exit(1)
|
||||
|
||||
# This is important so our app won't close on messages windows (alerts, etc...)
|
||||
QtGui.QApplication.setQuitOnLastWindowClosed(False)
|
||||
QtWidgets.QApplication.setQuitOnLastWindowClosed(False)
|
||||
|
||||
try:
|
||||
trayIcon = OGASystemTray(app)
|
||||
|
@ -342,7 +327,7 @@ if __name__ == '__main__':
|
|||
# Catch kill and logout user :)
|
||||
atexit.register(sigAtExit)
|
||||
|
||||
res = app.exec_()
|
||||
res = app.exec()
|
||||
|
||||
logger.debug('Exiting')
|
||||
trayIcon.quit()
|
||||
|
|
|
@ -1,292 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Resource object code
|
||||
#
|
||||
# Created by: The Resource Compiler for PyQt4 (Qt v4.8.6)
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt4 import QtCore
|
||||
|
||||
qt_resource_data = b"\
|
||||
\x00\x00\x0f\x42\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
\x00\x00\x30\x00\x00\x00\x30\x08\x06\x00\x00\x01\x20\x05\xc9\x11\
|
||||
\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0e\xc7\x00\x00\x0e\xc7\
|
||||
\x01\x38\x92\x2f\x76\x00\x00\x0e\xf4\x49\x44\x41\x54\x78\xda\xc5\
|
||||
\x59\x07\x58\x53\xd9\x12\xbe\x29\xd4\x84\x12\x21\xf4\x22\x08\x08\
|
||||
\x02\x22\xa2\x22\x22\x22\x8a\xa0\xa0\x14\x1b\xae\x62\x05\xac\xb8\
|
||||
\x76\xd7\xde\xd6\xde\x15\xf5\xd9\x7b\x17\x51\x41\x50\x14\x10\x04\
|
||||
\x44\x94\x8e\xd2\x25\x80\x80\x48\xef\x24\xb4\xbc\x39\x59\x6e\x4c\
|
||||
\x42\xe2\x0a\xea\x7b\xf3\x7d\xe1\xde\x7b\xca\xcc\x9c\x73\xe6\xcc\
|
||||
\xfc\x33\x90\xd9\x6c\x36\x86\xe8\xe8\xe9\x9b\xe9\xab\x97\x79\x9a\
|
||||
\x62\x5d\x44\x46\x7f\xd6\x6f\x3f\xc1\xb6\xb7\x1d\xf6\xf7\xc3\xc0\
|
||||
\xf0\xf3\x53\x5c\xc6\x2e\xe4\x74\x9c\xbe\x78\xff\xcd\xc1\x9d\x2b\
|
||||
\x08\xf8\x48\x34\x48\x55\x85\x9e\x4a\x5e\xe6\x3d\x7d\x04\xfa\x40\
|
||||
\x8d\xd3\xdd\xc6\x6d\x73\x1c\x6b\x55\xd8\xd9\xd1\xf9\x88\xc3\x0a\
|
||||
\x9f\x11\x19\x93\xc8\x4e\x4e\xcb\xce\x5e\xeb\x3b\x7b\x07\x19\xe3\
|
||||
\xa1\xd1\x23\x2d\x08\xd0\x91\xcc\x91\x81\x6b\x15\x15\x9b\xb4\xd6\
|
||||
\xd6\x7a\xf0\x61\xae\x56\x1b\x77\x9d\x62\xed\xdb\xe6\x2b\x11\xfc\
|
||||
\x22\xfa\x10\x5f\x47\x47\x47\x87\x38\xc6\x4f\x6c\xee\x3a\x0e\x9f\
|
||||
\xba\x91\xd1\xa5\x00\x6a\x24\x30\x99\x2c\x39\x32\xef\x1a\x10\xed\
|
||||
\x3e\x7c\x91\xb5\x65\xad\xb7\x38\x9f\x56\x57\x6f\x3f\x79\xda\xd9\
|
||||
\xc9\x76\xae\xaa\xae\xd5\xe7\x6a\x85\x2f\x12\x71\x40\xef\x82\x9c\
|
||||
\xba\xed\xe1\x9c\x19\x13\x27\x9b\x18\xf5\x7b\x84\x77\xf8\x07\x86\
|
||||
\x5f\x98\xea\x32\xd6\x07\xbd\x57\xd7\xd4\xe9\xef\x3f\x7e\x35\x47\
|
||||
\x4d\x85\xde\x40\x3e\x70\xe2\x6a\x1e\x6a\xec\xec\xec\xe4\x4c\x6e\
|
||||
\x6f\xef\x90\x44\x4f\x34\xf8\xaf\x1d\x27\xd8\x07\x76\xac\xc0\x52\
|
||||
\xd3\x73\x36\x4d\x18\x67\x1d\x6a\x37\x72\x88\x23\xf9\xaf\x15\xf3\
|
||||
\xf4\xf8\x44\x92\x49\x4c\xa4\xce\xd5\xdb\x81\x9c\xc1\x70\x58\x71\
|
||||
\x70\x2e\xfb\x22\x5e\xbf\xdb\xcb\x55\x49\x18\x95\x55\xd4\xb4\xc0\
|
||||
\x43\x0a\x06\x5b\x9d\xba\x70\xaf\xc8\xd7\xc7\x03\xdb\xb0\xd3\xaf\
|
||||
\x43\xe4\x84\x0d\x2b\xe6\x4a\x27\xa5\x64\xb2\x07\x0f\x32\xc2\x5c\
|
||||
\x27\xd8\x6a\xc2\xc9\xb4\xed\xdf\xbe\x5c\x9c\xbb\x4b\x88\x92\xd3\
|
||||
\xb2\x66\xdd\x79\x18\x7a\x53\xd4\x0e\x71\x55\x82\x3d\x26\x6d\xd8\
|
||||
\x79\xb2\x7d\xa9\xd7\x34\x9b\x95\x4b\x66\x9a\xff\xeb\xb6\xa2\xc1\
|
||||
\x5b\xd7\xf9\xa8\xca\x50\xa5\xcb\xf0\xf3\x10\x29\x01\x1f\x80\x06\
|
||||
\xa3\xe7\xd0\xc1\xc6\x97\xdf\x27\x7d\x5c\xc0\x3b\x68\xdf\xb1\xcb\
|
||||
\x0d\x34\x79\x39\xaa\x89\xa1\xee\xca\x6e\x8b\xd6\xd3\xd1\x88\xc0\
|
||||
\x27\x7c\x29\xab\x1c\x25\x2f\x27\x13\x45\xa5\x50\x72\x86\x0e\x32\
|
||||
\x32\xa0\x50\xa4\x8f\x77\x9b\x80\x16\xbd\x69\xf5\x02\xed\xd6\xd6\
|
||||
\x36\x8a\xaa\x8a\x62\x14\xd8\x6b\xd6\xf2\x85\x1e\x46\x99\xd9\x05\
|
||||
\xec\x80\xa7\xaf\x0a\xc9\x72\xb2\xd4\xe2\xba\xfa\x46\x0d\x5c\x35\
|
||||
\xdd\xbe\xea\x51\xc0\xb5\x28\xe8\xf9\x6b\xf6\xa4\xf1\xa3\x30\x65\
|
||||
\xba\xc2\x01\xd4\x2e\x21\x21\x6e\xeb\x3e\xd1\x4e\x86\xbc\x79\x8d\
|
||||
\x97\xa6\xb0\xc5\xa1\xc1\x88\x86\x98\x0f\xb8\xfa\x22\x22\x2e\xc8\
|
||||
\x61\x8c\xd5\xc4\x80\xa0\x08\x86\xd0\x83\xcb\xc9\x2b\x74\x34\xd0\
|
||||
\xd3\xe6\x7e\x9b\x9b\x19\x4d\x44\xcf\xf8\xc4\xf4\xbe\x42\x27\xc0\
|
||||
\xe0\x50\xde\x2b\x95\x5f\x50\x82\xd1\x15\xe4\x31\xb0\x2d\xa2\x48\
|
||||
\xd3\x68\x6a\x6e\xa1\x1f\x3e\x75\x93\xb1\x75\xad\x17\xcd\xd2\xc2\
|
||||
\xb8\xcd\xef\xfc\xbd\x42\x58\xbc\x68\xe3\xcb\x67\x14\x8f\xd9\xbe\
|
||||
\xde\x87\xfa\x24\x24\xaa\xcd\xd5\xc9\x16\xf3\x99\xe3\x66\xc6\xe7\
|
||||
\x07\x78\xe9\xdc\xd5\x87\x11\x9f\x18\xc5\x76\xf8\xb7\xa6\xba\xf2\
|
||||
\xfb\xe5\x0b\x67\x0c\xc3\x7a\x41\x7c\x1a\xf1\x9a\x11\x5a\x1f\x81\
|
||||
\x80\xb1\x13\x53\x32\xe7\xdc\x7b\xf4\xe2\x1a\xde\xb7\x78\xfe\xd4\
|
||||
\xd1\xe8\xa8\x7a\x24\x20\x2a\x36\x71\x5d\xf0\x8b\x98\x83\xe8\x5d\
|
||||
\x52\x52\xa2\x6e\xd7\xc6\xc5\xf2\xf8\x00\x8b\x41\x46\xd7\x91\x00\
|
||||
\xfc\x1b\x8d\xed\x91\x80\xbc\xfc\xcf\x63\x71\xe6\x88\x78\x99\xe3\
|
||||
\xb4\x68\xfe\x14\xbb\x73\x57\x1e\xbe\xfa\xc7\xf6\x07\x5c\xe6\xf3\
|
||||
\x92\x6c\x36\x71\xcb\x9e\x33\x6d\xfa\xba\x5a\xc4\xd9\x1e\xce\x18\
|
||||
\x89\x44\xe4\xf1\x7e\x81\x35\xe4\xf3\xd7\x02\xc2\x04\x27\x10\x08\
|
||||
\x84\x4e\x3e\x73\xf7\x7f\x7e\x0b\x3d\x89\x44\x62\xbb\x89\x91\x5e\
|
||||
\x00\x7a\x2f\x2a\x2e\x73\x3a\x7b\xc5\x3f\x78\xef\x56\x5f\x6c\xcf\
|
||||
\x96\x65\xd8\xf6\xfd\x67\xeb\xd3\x3e\xe6\x2c\x95\x92\x92\x6c\xaf\
|
||||
\xab\x6f\xba\x0b\x96\x81\xa9\xa9\x2a\x7d\x21\x7b\xcf\x76\x1b\x7f\
|
||||
\xf1\xc6\xe3\xe7\x5c\xcf\xb2\xd3\xaf\xed\xc0\x8e\x3f\x49\x82\xe7\
|
||||
\x62\xa8\xdf\x37\x64\x81\xa7\xab\x33\xde\x06\xde\x06\x43\xcc\xbb\
|
||||
\xbe\x91\x3b\x96\xe3\x84\xb2\x33\x37\xd9\x43\x06\x0d\xa8\xdd\xba\
|
||||
\xe7\x0c\x79\xc3\xca\x79\xa3\xc9\xc8\x88\x91\x33\x89\x8e\x4b\x5e\
|
||||
\x05\xf7\xeb\x28\x5a\x01\xce\x14\x1d\xf2\x8a\xc5\x33\x07\xab\xab\
|
||||
\xd2\x93\x79\x05\xc2\x78\x5e\xc3\xc0\x78\x9d\x51\x7f\x3d\xed\xa0\
|
||||
\xa7\xa1\xd1\x93\xf4\x74\x34\xb1\xf8\x84\x8f\xe5\x5c\x2b\xb2\xb1\
|
||||
\x32\x3f\x86\x7e\xdf\x3b\xb0\x82\xa2\x52\x6b\xfb\xd1\x96\x22\xfb\
|
||||
\x71\x37\xef\xec\x60\xc3\x15\x4e\xee\x89\x4d\xab\x2a\xd3\xd3\xc2\
|
||||
\xa3\xde\xf3\xb5\x59\x5a\x98\x60\x17\xae\x3d\xea\xd4\xd6\x54\x21\
|
||||
\xcc\xfd\x63\x12\x8f\x7f\xce\xae\x9a\x60\x3f\xe2\x48\x8f\x04\x48\
|
||||
\x48\x88\x35\x8c\xb2\x1e\x3c\xee\xef\x43\x17\x43\x60\x7f\xc5\xc4\
|
||||
\xc4\xc8\x10\xbd\x87\x74\x1c\xf2\xbb\xce\xae\xad\xab\xaf\xb6\xb6\
|
||||
\x1c\xa4\xd4\x15\xc4\xc0\xb1\x7c\x48\x5f\x3c\x7f\xca\x3e\x72\x4f\
|
||||
\x6f\xa6\xbe\xae\x66\x18\xc4\x22\x83\x0b\xd7\x1f\x31\x1c\xc7\x58\
|
||||
\x61\xe9\x19\xb9\x24\x63\xc3\x7e\xfe\x39\x9f\x0a\xa7\x52\x28\x52\
|
||||
\x1c\xe6\x7b\x8f\x5e\x29\xdd\xb2\xd6\xcb\xee\xbb\x81\xed\x7b\xd4\
|
||||
\x87\x26\x5b\x00\x91\xfd\x6b\x42\x4a\x46\x2b\xf8\x4f\xcd\xe6\x66\
|
||||
\xe6\x54\x3b\x1b\x8b\x57\x87\xfd\xae\xab\x8d\xb7\xb7\xde\x08\xcc\
|
||||
\xb9\x31\x5b\xa8\x2f\x42\x04\x93\x14\x82\x42\x5f\x1f\x49\xfb\x98\
|
||||
\x3b\x8d\x4c\x22\xb5\xee\xdc\xb8\x98\xf6\xd3\xbe\x88\x13\x92\xbf\
|
||||
\x56\x9a\x1e\x3d\x73\x2b\x8d\xb7\x0d\xc5\x47\xac\x97\xc4\x27\xe0\
|
||||
\xc1\x93\xb0\x4b\x78\x44\x43\xb6\x8f\xee\x00\x7a\x87\xd8\x1f\x07\
|
||||
\x37\x77\xb8\xcb\x04\xdb\x15\x23\x87\x0f\x3a\xd9\x2b\x01\x8f\x9e\
|
||||
\xbe\x3a\x83\x33\x47\x0e\xce\xc3\xdd\x61\xae\xa0\x87\x0d\x7c\x16\
|
||||
\x75\xa2\x57\x02\x8a\x4b\xcb\x2d\xe2\xde\xa7\x2d\x41\xef\x52\x92\
|
||||
\x12\xb5\x38\xf3\x5f\x41\x1c\x01\x27\xcf\xdd\x49\xc0\x1b\x04\xa3\
|
||||
\xae\x9b\xd3\xe8\xe5\x8f\x43\x22\xfd\x7a\x2d\x20\x3c\xea\xdd\x16\
|
||||
\xde\x06\x71\x71\xb1\x46\xde\xef\x11\x96\x66\xa7\x7e\x44\x40\xc8\
|
||||
\xcb\xd8\x07\x1f\x33\x3f\xb9\x56\x54\xd5\x88\x71\x6e\xbd\x0a\x3d\
|
||||
\x6f\xd5\x92\x99\xfa\xe4\xd0\x88\xb8\xbf\xf1\x41\x70\x33\x5b\x7a\
|
||||
\xaa\xe1\xeb\x37\x49\x67\x82\x43\xa3\x97\x78\x7a\x38\x61\x4e\xe3\
|
||||
\xac\xb9\xed\x8d\x8d\x2d\x7a\x27\xcf\xde\x49\xe0\xb3\x22\x8a\xb4\
|
||||
\x54\xc5\xf7\x98\xa9\x28\x2b\xa6\xf3\x7e\xef\x39\x72\x89\xa9\xa3\
|
||||
\xad\x2e\x71\x00\xbc\x6b\x65\x55\x6d\x33\x18\x84\xb4\x9a\x32\xbd\
|
||||
\x73\xe5\xd2\x99\x44\x2a\x55\x0a\x6b\x6d\x6f\x97\xe1\x13\xd0\xd0\
|
||||
\xd8\xa4\x2a\xc8\x14\x07\xc7\x88\x16\xcc\x72\x71\xc6\xdf\xc1\xc1\
|
||||
\x35\xb9\x39\xdb\x49\x18\x1b\xea\x62\xe5\x15\xd5\x0d\xc7\xfe\x73\
|
||||
\x5b\x02\xb9\xed\x93\xe7\xef\x72\xad\x8e\x2a\x2d\x55\xc6\x27\xa0\
|
||||
\xa3\xa3\x53\x4c\x50\x00\x4a\x17\xba\xb6\xaf\x19\x30\xd9\x67\xf4\
|
||||
\x7e\xe4\xf4\xcd\xba\x31\x36\x43\xa4\x11\x73\x8e\xb0\xeb\x01\xf5\
|
||||
\x90\x88\x68\x7c\xcb\x34\x30\xec\xfe\xe3\x97\x59\x66\x03\x0d\xee\
|
||||
\x74\xbb\xc9\x9f\x4b\xbe\x0e\x45\x30\xa5\x6b\x7f\x57\xc3\xd2\xf5\
|
||||
\x39\x29\xc7\xe6\x65\xd4\x2e\x58\xe6\x29\x21\x2e\x26\x6b\x3e\xd0\
|
||||
\x90\x33\x1e\x00\x41\xb6\xfb\xc4\x31\xeb\xd1\x7b\x62\x6a\xe6\x5e\
|
||||
\x2a\x45\x1a\xbb\x7c\x2b\x30\xbd\xae\xbe\xa1\x13\x32\xab\xb3\x1c\
|
||||
\x30\x08\x7b\xf9\x19\x17\xe0\x77\xfe\xee\x3b\x04\x6e\x11\xf2\x42\
|
||||
\x50\x1a\xb5\x21\x3f\x84\xa2\x1b\x7a\x87\xf0\x7a\x83\x37\xa2\x01\
|
||||
\xac\xe9\x0f\xf7\x26\x90\x83\x3c\xb5\xd5\xcf\x41\x40\xcf\x30\x32\
|
||||
\xd0\x09\x2a\xfd\x5a\x69\xd6\xd8\xd8\xac\xc4\x81\xa7\x28\xcf\x82\
|
||||
\xcc\x24\x1f\x60\xaa\xfa\x3f\x67\xd1\xac\xc2\xc1\x84\xfd\xb4\x5e\
|
||||
\x78\xcf\x71\x77\xc4\x99\x65\xe5\x16\x4c\x1b\x31\xcc\x8c\xcb\xbc\
|
||||
\xbc\xb2\x06\x1b\x64\xda\xff\x0e\xfe\x2d\x29\x21\x51\xff\x30\x28\
|
||||
\xe2\x9a\x96\x9a\x32\xb1\xbf\x7e\x5f\x2c\x3c\x22\x21\x9a\xb3\x45\
|
||||
\x24\xf0\x96\xb0\x12\x8d\x7f\x33\xc9\x98\xf8\x94\x63\xde\x9e\x6e\
|
||||
\xdc\xef\xac\x1c\x46\xae\xf5\x70\x33\xee\x1d\xb9\xf7\xf8\x65\xf5\
|
||||
\xce\x0d\x8b\x10\x3f\xce\x77\xf0\xcb\x18\x9b\x1e\xc5\x83\x9c\xdc\
|
||||
\x42\x75\xde\x6f\x70\x2b\xc5\xb5\xb5\x0d\x5a\xda\x1a\xaa\x71\x57\
|
||||
\x6e\x05\x66\x8f\xb2\xb6\xe0\x32\xaf\xad\x6b\xc0\x10\xc4\x21\xff\
|
||||
\x8c\x9f\xa9\x6f\x68\x1a\x06\xfb\xbd\xa6\xa9\xa9\x45\xad\xb0\xf8\
|
||||
\x8b\x41\xbf\xbe\xdf\xe4\x83\xf3\xcc\x07\xc4\xbf\xb2\x47\x02\xe8\
|
||||
\x8a\xb4\x6a\x14\xd0\xbe\x21\x91\xc1\x94\x4b\x37\x1f\x27\x12\xe1\
|
||||
\x64\xb7\xad\x5b\xc8\x37\x36\x33\x87\xa1\x3b\x5f\xce\xe5\x73\x8f\
|
||||
\x04\x8c\xb2\x1a\xbc\xf1\x55\x74\xc2\x39\x3b\x9b\x21\x5d\x7e\x8b\
|
||||
\x8c\x2d\x59\x30\x95\xc0\x62\xb5\xb2\xf7\x1f\xbf\x4c\xd8\xb4\xda\
|
||||
\xab\xeb\xc2\x36\x63\xda\x9a\xaa\x6f\x7a\x1c\x93\x2d\x87\x98\x9c\
|
||||
\xdf\xb4\xeb\x94\x9f\xa4\xb8\xb8\xb8\x95\xe5\x40\x4e\x5b\x58\x64\
|
||||
\x7c\xea\xcb\xc8\x78\x53\x49\x09\x71\x2e\xf8\xba\x1b\x10\x9a\xe6\
|
||||
\x33\xc7\xdd\xa1\x57\x41\x7f\x2f\x98\x34\x30\xdd\xb6\x69\xf7\xa9\
|
||||
\x8d\x04\x36\x81\x34\xc5\x65\xec\x11\x40\x19\x0c\xd8\x92\x68\x7c\
|
||||
\x0c\xe4\x16\x03\xc0\x2b\x37\xf5\x1a\x55\xa4\x7e\xcc\x5d\xa4\xad\
|
||||
\xa1\x26\xe9\x3d\xdb\x1d\xdb\xb8\xeb\xe4\x75\x45\x05\x5a\xdd\xea\
|
||||
\xa5\xb3\x38\x7d\x37\xef\x3f\x7b\xb7\x7a\x99\xe7\x5c\x91\x41\xff\
|
||||
\x47\x48\xa1\x8f\x9c\xfc\xbc\x2e\x14\xb7\x6f\xdb\x72\xec\xdc\xb5\
|
||||
\x00\x39\x48\xfc\x31\x46\x61\x49\x45\x51\xf1\x17\x55\x25\x45\x5a\
|
||||
\xd6\x4f\x09\xb0\x1e\x66\xe6\x76\xe6\xd2\xfd\x13\x0e\x76\x23\x34\
|
||||
\x5a\x98\x4c\x19\x27\xfb\x11\xf5\x00\x9e\x1f\x46\xc6\x24\x4c\x80\
|
||||
\xa4\x5b\x8b\x2f\xa2\x89\xc2\x45\xc2\xe8\x53\x41\xf1\xe8\x98\xb8\
|
||||
\x94\x15\x59\xb9\x0c\x67\x61\x9e\x17\x05\x2c\x2f\x4f\xb7\x09\x3d\
|
||||
\xc9\x80\x7e\x49\xcc\xff\x1e\xa1\xb4\xe1\x59\x58\xec\xbe\xf6\xf6\
|
||||
\x0e\x89\x6e\x01\x4e\x49\xe1\x83\xa9\xb1\xbe\x3f\x84\x85\x27\x6a\
|
||||
\x2a\xf4\x14\xd8\x0b\x42\x76\x5e\xc1\xf8\xd0\xf0\xb8\xdd\xda\x5a\
|
||||
\xaa\xb1\x90\xb3\x3c\xfb\xbf\x2c\x00\x45\x81\x3b\x0f\x9f\xdf\x4a\
|
||||
\xfd\x90\xe3\x21\xd8\x87\x20\xd9\x94\x49\x63\x17\x82\xcd\xb0\xf0\
|
||||
\xb6\xf8\x84\x0f\x0b\x01\xfb\xbd\x15\x5c\x24\x44\xf8\xca\x2d\x6b\
|
||||
\xbd\xd5\x20\x2d\x6c\xfb\x9f\x2d\x20\xe6\x6d\xca\x9f\x08\x1f\x76\
|
||||
\x4f\x0a\xb4\xc2\xbc\x20\x5b\x04\xaf\xd6\xc1\xdb\x8e\x83\x56\x11\
|
||||
\xc5\x08\x45\x74\x82\xa3\x47\x5a\x1c\xfc\xed\x0b\x40\x36\x7d\xfc\
|
||||
\xec\xed\xe4\xaf\xe5\x55\xc6\x82\x83\x20\xcf\xda\x64\x67\x33\x74\
|
||||
\x9f\x30\x06\x28\x05\x3e\x70\xf2\x5a\x2e\xc4\x03\xba\xb0\x7e\xb8\
|
||||
\xd5\xc3\x7f\xbb\x09\xb5\x30\x59\xf2\xfb\x8f\x5d\x61\xa0\x67\x37\
|
||||
\xef\x6c\x61\x72\x41\x94\xf2\x78\x59\x63\xd3\xaa\x05\xda\x00\x4a\
|
||||
\x8a\x9b\x5b\x98\x7d\xba\x8f\x20\xb0\x7b\xab\x5c\x45\x65\xad\x41\
|
||||
\x69\x59\xb9\x65\x6d\x5d\xa3\xa1\x18\x99\xc4\x6c\xef\xe8\x60\x2a\
|
||||
\xd1\x69\x19\xba\xda\x1a\x91\x5c\x47\x8d\xec\x1d\xd5\xb0\x85\x29\
|
||||
\x8f\x08\x52\xee\x9d\xff\x26\x08\x79\x9f\x49\xe3\x47\xad\x06\xf8\
|
||||
\x75\x55\xb0\x4f\x5d\x8d\x9e\xf4\x23\xca\x02\x3c\xe8\x17\x1b\x9f\
|
||||
\x72\x36\x3a\x2e\xc5\x1e\xe5\xa8\x70\x7f\x50\xb9\x11\xa3\xc9\xcb\
|
||||
\x00\x1a\x56\x40\xd0\x02\x83\x0d\x42\xe8\x17\x8b\x7e\x9b\xca\x66\
|
||||
\xb6\xb0\xb2\x2d\xcc\x0c\x4f\x93\x43\x5e\xc6\x1c\x44\x05\x41\x61\
|
||||
\x4c\x11\x1a\x83\x5f\xc9\x8f\x28\x40\xa3\xc9\x32\x84\xb5\x0f\x35\
|
||||
\x37\xbe\x22\x6a\x0e\x04\x6d\xcd\xdb\xfe\xcf\x62\x21\xf4\x69\xca\
|
||||
\xca\x50\xb0\x89\x8e\x36\x9c\xc0\x02\xf0\x11\x4c\xba\x03\x7b\x9f\
|
||||
\x94\x91\x99\x99\xcb\xc0\xc0\xbb\x19\x59\x0f\x1b\x84\x2a\x31\x70\
|
||||
\x19\x31\x0c\xf2\x37\x42\xf4\x9b\x64\x03\x94\xb0\x90\x01\xa8\xce\
|
||||
\x16\x25\x00\xee\x85\xf8\x8f\x1e\x37\xca\xa3\x05\xdb\x1c\xc6\x58\
|
||||
\x6d\x03\xc5\x4a\x85\x14\x53\xdc\x01\x18\xfb\xb7\xb6\xb6\x12\x27\
|
||||
\x3a\x8e\xc2\x16\xcd\x9b\xc2\xed\x2b\x2e\xfd\x5a\x7d\xf1\xfa\x63\
|
||||
\x12\x84\xdf\x4c\x4d\x75\xa5\xf7\x03\x8d\xf5\x13\x60\x21\x57\x5a\
|
||||
\x5b\x59\x44\x5e\x1e\xb2\xb2\x14\xe4\x05\xa5\xc8\x4c\x66\xab\x9c\
|
||||
\x28\xa5\x1a\x9b\x9a\x95\xe0\x68\xb5\x50\x89\xf6\x7b\xca\xa7\xa4\
|
||||
\xe7\xcc\x78\x13\x9f\xea\x2b\xe8\x6e\xd1\x7f\x51\x78\xdb\xaa\xaa\
|
||||
\x6b\x4d\x4f\x5d\xbc\x9f\x04\x32\xc9\x0b\x3c\x5d\x51\xb9\x83\xdb\
|
||||
\xd7\xda\xda\x86\x9d\xbd\xe2\xff\xa9\xe4\x4b\xb9\xee\x8c\xc9\x8e\
|
||||
\xb3\x21\x2b\xe0\x14\xd7\xb2\x73\x0b\xd6\x80\x1e\xc4\xc6\x26\x26\
|
||||
\x77\x2c\x93\xc9\x62\x07\x3e\x7b\xdd\x02\x9b\x53\x4b\x36\x33\xd1\
|
||||
\xbf\x9f\x94\x9a\xe5\x29\x4a\xb9\xa0\xe7\xd1\x47\x66\x7b\x38\x4d\
|
||||
\x13\xd5\x8f\x5c\x2e\x72\xbd\x02\xe5\xe5\xd5\x82\x25\x2d\xff\x27\
|
||||
\x61\x31\xef\x92\x3e\x5a\x83\x4b\x85\x14\x71\x24\x1f\x0f\xb0\xeb\
|
||||
\xd6\x23\xa7\x6f\x10\x15\x68\x72\x6d\x7b\xb6\xf8\x4a\xe1\x31\x06\
|
||||
\xcc\x48\x02\x92\x80\x7d\x80\x17\x61\x43\x0c\x51\x7c\xc2\x9e\x85\
|
||||
\xc5\x64\x15\x7d\x2e\xab\xea\x43\x93\x25\x2e\x9e\x3f\xd5\x96\xec\
|
||||
\xe1\xee\x38\xa7\xae\xae\x51\x03\xc1\x04\x61\x0a\xa6\x67\xe4\x4e\
|
||||
\xdd\x7d\xf8\x62\x29\xda\x15\x3d\x5d\xcd\x70\x3c\x2b\x81\xe8\xbc\
|
||||
\x37\x21\x39\x63\x3e\xef\x58\x0d\x35\xe5\x84\x85\x73\xdd\xed\x91\
|
||||
\x67\xe2\x75\xcf\xe0\x24\x60\xf3\xeb\x64\xd6\xf8\xce\xc6\x94\xe9\
|
||||
\x7d\x04\x61\x39\x1b\x92\xb8\x0f\x06\x7a\x7d\x8b\xe7\xcf\x9c\xe4\
|
||||
\xca\xdb\xf7\x34\x34\xe6\x04\x91\x4d\xac\x01\x07\xa3\x04\xe9\x54\
|
||||
\x2c\x89\x48\x68\xd7\xd1\xd6\x78\x0d\xf1\xe8\x20\x9e\xc4\x93\x51\
|
||||
\xbe\x85\x8a\xad\xd5\x35\xf5\x3a\x37\xee\x3d\x7d\x58\xf2\xa5\xc2\
|
||||
\x5c\x08\xf6\x57\x15\xac\xa9\x72\x9d\x24\x81\xd0\x39\x6a\xc4\xe0\
|
||||
\x23\xe3\xc7\x8e\xd8\x2c\x18\x71\x51\xd5\x12\x32\xd3\x2a\x29\x49\
|
||||
\x71\x99\xcd\x6b\xbc\x31\x2a\x45\x4a\x58\x6d\xbc\x02\xf8\xeb\x6f\
|
||||
\x5b\xe7\xd3\xad\x4c\xe4\xea\x64\xbb\x18\xfd\x5a\x5a\x58\x34\xb8\
|
||||
\xab\x9b\xe0\xee\x38\x47\x44\xbf\xdb\x12\x9f\x98\xbe\x59\x49\x51\
|
||||
\xa1\x91\x4a\x95\x7c\x41\xe6\xa9\x8c\x31\xf0\x92\x10\xda\xb5\xdc\
|
||||
\xfc\x22\x7b\xb0\xbf\x09\x5f\xca\x2a\xcd\xea\x1a\x1a\xd5\x11\xce\
|
||||
\x41\xee\x52\xb1\x8f\x5c\x9e\x96\x86\xea\x5b\x93\x01\xfd\x02\xe8\
|
||||
\x0a\xb4\x9c\xef\xdd\x8d\x07\x4f\xc2\xa2\x60\xeb\x65\x56\x2c\xfe\
|
||||
\x43\xa8\xf2\xef\x12\x33\xea\xc0\x5d\xe6\x3a\xd8\x59\xf9\xa1\xd4\
|
||||
\x5b\xa0\xc8\xa6\x88\xee\x04\x89\x48\x92\x6d\x61\xb1\x50\xa5\x15\
|
||||
\x9b\x3c\x69\x0c\xe6\x39\xdd\x89\xb3\x6f\xc9\x69\xd9\x84\xc4\xd4\
|
||||
\x2c\xaa\x50\x2c\x84\x76\x12\x01\xb1\x9f\x01\x63\xb0\xab\x6a\x60\
|
||||
\x62\x23\xcd\x4c\x0c\x30\x75\x55\x25\xa1\x63\x5a\x98\x2d\x79\xa8\
|
||||
\xbc\xeb\x60\x37\x7c\x3b\x6f\xfb\x97\xaf\x95\x56\xfe\x81\x61\x51\
|
||||
\x10\x43\xc4\xa6\xb9\x3a\x60\x00\x5f\xba\xcd\x85\xac\xa4\x05\xa0\
|
||||
\xca\x30\xf2\xef\x0a\xf1\xa0\x84\x29\x28\xde\x01\xf7\x86\x24\xba\
|
||||
\xb2\x2b\x4e\xfc\x67\x21\x4c\x6e\x09\x13\x4e\x7e\xd6\xbd\x80\x17\
|
||||
\x37\x54\x94\x15\x09\x1e\xdf\x92\x7e\x3e\x8a\x4f\xfc\x50\x51\x51\
|
||||
\x55\xa3\x04\xa0\x72\xd1\x6f\x5b\x00\x95\x22\x5d\x0e\x2e\x91\x54\
|
||||
\x59\x55\x23\x7a\x10\x9b\x68\x0e\xc9\x74\xc9\xe7\xe2\x72\x6b\x22\
|
||||
\x81\x44\x09\x7f\x1d\x7f\x1c\x2e\xa7\xfc\xe8\x91\x43\x21\x58\x99\
|
||||
\x09\x9d\x82\x3c\xd2\x93\x90\x48\x39\x0d\x35\xa5\x44\x94\x84\xfe\
|
||||
\xb6\x05\xa0\x32\x2b\x78\xa5\xcc\x37\xef\xd2\x8c\xc6\xd8\x58\x62\
|
||||
\x52\x52\xdd\x63\xe2\xf0\xa1\xc6\x90\x09\x1b\xab\x17\x14\x95\xac\
|
||||
\xac\xa9\x6b\xc0\xa6\xbb\x39\x40\x6e\x2f\x0f\x59\xef\x0b\x80\x16\
|
||||
\xf5\x9c\xc8\x2c\x48\xb7\x1e\x3c\xfb\x04\xee\x55\x17\xee\xc2\xf4\
|
||||
\x5e\xa7\x7c\x3f\x4a\x8b\xe6\x4d\xb6\x3c\xe4\x77\x3d\xef\xf2\xad\
|
||||
\xc7\x34\xf0\x26\x62\xb0\x20\x21\x5e\x0c\xc3\x74\xb4\xd5\x31\xc9\
|
||||
\xb2\xca\xfa\x9b\xf7\x83\xeb\xcb\x2b\x6b\x38\xb0\x66\xde\x4c\x97\
|
||||
\x6e\x63\x23\x5e\xbf\x67\x64\xe5\x16\xf4\x9b\xe6\x6a\xef\xd5\x87\
|
||||
\x26\x97\xff\xdb\x17\x00\x36\xde\x00\x09\x8d\x32\xa4\xfc\xce\x90\
|
||||
\xa5\x2d\xcf\xce\x2b\x74\xd4\xd3\xd5\xca\x07\x08\x41\x55\x52\xec\
|
||||
\x53\x0d\xb0\x41\x16\x14\x56\x42\xa5\x65\x9a\x1c\xb5\xc8\xd5\xc9\
|
||||
\x6e\xfd\xad\x07\x21\x21\x14\x8a\x94\xf8\x80\xfe\x3a\xfc\x99\xfe\
|
||||
\x87\xdc\xca\xe7\xe1\x6f\x74\x00\x07\x9d\x40\xff\x53\xfe\xa9\xa4\
|
||||
\xbb\xa7\x64\x64\xa0\x13\x8c\x7e\x2c\x56\x1b\x35\x22\xfa\xfd\xc5\
|
||||
\x9c\xbc\xc2\xc9\x48\x71\x0d\xf0\x4e\x54\xaa\x74\xbe\x32\x5d\x21\
|
||||
\x04\xa2\xf7\xca\x97\x91\x6f\xaf\x01\xe2\x14\xf7\x98\xec\x20\x58\
|
||||
\x06\xaa\x84\x85\x29\x9a\x0f\xec\x7f\xdb\x65\x82\xed\xca\x1e\xe5\
|
||||
\xc4\xbf\x8a\x62\xe3\x53\xd7\x31\x0a\x4b\xf6\xd3\x15\xe4\x89\xbe\
|
||||
\x3e\xd3\xb9\x55\xb6\xb6\xb6\x76\xdd\xab\xb7\x83\x7c\x37\xec\x3c\
|
||||
\xe9\xdb\x85\xa1\xd0\x82\xb9\xf3\x22\x63\x12\xf2\x42\x5e\xc6\xea\
|
||||
\x41\x1c\x38\x0e\x8b\x5c\xd5\xe3\xa4\xfe\x57\xd1\x40\x63\xbd\x1b\
|
||||
\x99\xd9\x0c\x97\xe2\xd2\x0a\xd3\x8c\x6c\x86\x9c\xe9\x00\x3d\x3c\
|
||||
\x97\xc0\x7c\xe6\xba\xe3\x48\x14\xc3\xef\xc9\xe7\x92\xaf\x99\x37\
|
||||
\xee\x05\xcb\x4b\x4b\x4b\x36\x2c\xf5\x9a\x36\xb2\xaf\x96\x5a\x6c\
|
||||
\xaf\xaa\x12\xbf\x8a\x64\xa8\x94\x32\xef\x39\x6e\x36\xa8\x26\xfd\
|
||||
\x28\xf8\xd5\x19\x00\x81\x86\x60\x52\xb2\x4c\x16\x4b\x16\xb0\x53\
|
||||
\x23\x20\x4c\x4e\x8d\x1a\xd5\xaf\xc5\xc4\xc4\x9a\xca\x2b\xaa\x07\
|
||||
\xfc\x31\xc5\x71\xa6\x7e\x3f\xad\xf0\xef\xf1\xfd\x2f\x9a\x21\xe5\
|
||||
\x2e\x6b\x8c\x93\x5e\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\
|
||||
\x82\
|
||||
"
|
||||
|
||||
qt_resource_name = b"\
|
||||
\x00\x06\
|
||||
\x07\x03\x7d\xc3\
|
||||
\x00\x69\
|
||||
\x00\x6d\x00\x61\x00\x67\x00\x65\x00\x73\
|
||||
\x00\x03\
|
||||
\x00\x00\x70\x37\
|
||||
\x00\x69\
|
||||
\x00\x6d\x00\x67\
|
||||
\x00\x07\
|
||||
\x05\xd4\x57\xa7\
|
||||
\x00\x6f\
|
||||
\x00\x67\x00\x61\x00\x2e\x00\x70\x00\x6e\x00\x67\
|
||||
"
|
||||
|
||||
qt_resource_struct = b"\
|
||||
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
|
||||
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\
|
||||
\x00\x00\x00\x12\x00\x02\x00\x00\x00\x01\x00\x00\x00\x03\
|
||||
\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
|
||||
"
|
||||
|
||||
|
||||
def qInitResources():
|
||||
QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
|
||||
|
||||
|
||||
def qCleanupResources():
|
||||
QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
|
||||
|
||||
|
||||
qInitResources()
|
|
@ -1 +1 @@
|
|||
1.1.1b
|
||||
1.3.0
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
<item>
|
||||
<widget class="QLabel" name="VersionLabel">
|
||||
<property name="text">
|
||||
<string>Version 1.1.0</string>
|
||||
<string>Version 1.3.0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -11,7 +11,10 @@ remote=https://192.168.2.10/opengnsys/rest
|
|||
# Alternate OpenGnsys Service (comment out to enable this option)
|
||||
#altremote=https://10.0.2.2/opengnsys/rest
|
||||
|
||||
# Log Level, if ommited, will be set to INFO
|
||||
# Execution level (permitted operations): status, halt, full
|
||||
level=full
|
||||
|
||||
# Log Level, if omitted, will be set to INFO
|
||||
log=DEBUG
|
||||
|
||||
# Module specific
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
# pylint: disable-msg=E1101,W0703
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
import requests
|
||||
import logging
|
||||
|
|
|
@ -29,19 +29,15 @@
|
|||
"""
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
# On centos, old six release does not includes byte2int, nor six.PY2
|
||||
import six
|
||||
|
||||
import modules
|
||||
from RESTApi import REST, RESTError
|
||||
from . import modules
|
||||
from .RESTApi import REST, RESTError
|
||||
|
||||
try:
|
||||
with open('../VERSION', 'r') as v:
|
||||
VERSION = v.read().strip()
|
||||
except IOError:
|
||||
VERSION = '1.1.1b'
|
||||
VERSION='1.3.0'
|
||||
|
||||
__title__ = 'OpenGnsys Agent'
|
||||
__version__ = VERSION
|
||||
|
|
|
@ -26,24 +26,25 @@
|
|||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
"""
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
"""
|
||||
# pylint: disable=unused-wildcard-import, wildcard-import
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from ConfigParser import SafeConfigParser
|
||||
|
||||
from configparser import SafeConfigParser
|
||||
|
||||
config = None
|
||||
|
||||
|
||||
def readConfig(client=False):
|
||||
'''
|
||||
"""
|
||||
Reads configuration file
|
||||
If client is False, will read ogagent.cfg as configuration
|
||||
If client is True, will read ogclient.cfg as configuration
|
||||
|
||||
This is this way so we can protect ogagent.cfg against reading for non admin users on all platforms.
|
||||
'''
|
||||
"""
|
||||
cfg = SafeConfigParser()
|
||||
if client is True:
|
||||
fname = 'ogclient.cfg'
|
||||
|
@ -55,4 +56,3 @@ def readConfig(client=False):
|
|||
return None
|
||||
|
||||
return cfg
|
||||
|
|
@ -25,27 +25,24 @@
|
|||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
'''
|
||||
"""
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
# pylint: disable=unused-wildcard-import,wildcard-import
|
||||
from __future__ import unicode_literals, print_function
|
||||
"""
|
||||
|
||||
# Pydev can't parse "six.moves.xxxx" because it is loaded lazy
|
||||
import six
|
||||
|
||||
import json
|
||||
import ssl
|
||||
import threading
|
||||
from six.moves.socketserver import ThreadingMixIn # @UnresolvedImport
|
||||
from six.moves.BaseHTTPServer import BaseHTTPRequestHandler # @UnresolvedImport
|
||||
from six.moves.BaseHTTPServer import HTTPServer # @UnresolvedImport
|
||||
from six.moves.urllib.parse import unquote # @UnresolvedImport
|
||||
|
||||
import json
|
||||
import threading
|
||||
import ssl
|
||||
|
||||
from .utils import exceptionToMessage
|
||||
from .certs import createSelfSignedCert
|
||||
from .log import logger
|
||||
|
||||
|
||||
class HTTPServerHandler(BaseHTTPRequestHandler):
|
||||
service = None
|
||||
protocol_version = 'HTTP/1.0'
|
||||
|
@ -56,22 +53,22 @@ class HTTPServerHandler(BaseHTTPRequestHandler):
|
|||
self.send_response(code)
|
||||
self.send_header('Content-type', 'application/json')
|
||||
self.end_headers()
|
||||
self.wfile.write(json.dumps({'error': message}))
|
||||
self.wfile.write(str.encode(json.dumps({'error': message})))
|
||||
return
|
||||
|
||||
def sendJsonResponse(self, data):
|
||||
self.send_response(200)
|
||||
data = json.dumps(data)
|
||||
self.send_header('Content-type', 'application/json')
|
||||
self.send_header('Content-Length', len(data))
|
||||
self.send_header('Content-Length', str(len(data)))
|
||||
self.end_headers()
|
||||
# Send the html message
|
||||
self.wfile.write(data)
|
||||
|
||||
|
||||
# parseURL
|
||||
self.wfile.write(str.encode(data))
|
||||
|
||||
def parseUrl(self):
|
||||
# Very simple path & params splitter
|
||||
"""
|
||||
Very simple path & params splitter
|
||||
"""
|
||||
path = self.path.split('?')[0][1:].split('/')
|
||||
|
||||
try:
|
||||
|
@ -81,16 +78,16 @@ class HTTPServerHandler(BaseHTTPRequestHandler):
|
|||
|
||||
for v in self.service.modules:
|
||||
if v.name == path[0]: # Case Sensitive!!!!
|
||||
return (v, path[1:], params)
|
||||
return v, path[1:], params
|
||||
|
||||
return (None, path, params)
|
||||
return None, path, params
|
||||
|
||||
def notifyMessage(self, module, path, getParams, postParams):
|
||||
'''
|
||||
def notifyMessage(self, module, path, get_params, post_params):
|
||||
"""
|
||||
Locates witch module will process the message based on path (first folder on url path)
|
||||
'''
|
||||
"""
|
||||
try:
|
||||
data = module.processServerMessage(path, getParams, postParams, self)
|
||||
data = module.processServerMessage(path, get_params, post_params, self)
|
||||
self.sendJsonResponse(data)
|
||||
except Exception as e:
|
||||
logger.exception()
|
||||
|
@ -102,19 +99,19 @@ class HTTPServerHandler(BaseHTTPRequestHandler):
|
|||
self.notifyMessage(module, path, params, None)
|
||||
|
||||
def do_POST(self):
|
||||
module, path, getParams = self.parseUrl()
|
||||
module, path, get_params = self.parseUrl()
|
||||
post_params = None
|
||||
|
||||
# Tries to get JSON content (UTF-8 encoded)
|
||||
try:
|
||||
length = int(self.headers.getheader('content-length'))
|
||||
length = int(self.headers.get('content-length'))
|
||||
content = self.rfile.read(length).decode('utf-8')
|
||||
logger.debug('length: {}, content >>{}<<'.format(length, content))
|
||||
postParams = json.loads(content)
|
||||
logger.debug('length: {0}, content >>{1}<<'.format(length, content))
|
||||
post_params = json.loads(content)
|
||||
except Exception as e:
|
||||
self.sendJsonError(500, exceptionToMessage(e))
|
||||
|
||||
self.notifyMessage(module, path, getParams, postParams)
|
||||
|
||||
self.notifyMessage(module, path, get_params, post_params)
|
||||
|
||||
def log_error(self, fmt, *args):
|
||||
logger.error('HTTP ' + fmt % args)
|
||||
|
@ -126,6 +123,7 @@ class HTTPServerHandler(BaseHTTPRequestHandler):
|
|||
class HTTPThreadingServer(ThreadingMixIn, HTTPServer):
|
||||
pass
|
||||
|
||||
|
||||
class HTTPServerThread(threading.Thread):
|
||||
def __init__(self, address, service):
|
||||
super(self.__class__, self).__init__()
|
||||
|
@ -146,5 +144,3 @@ class HTTPServerThread(threading.Thread):
|
|||
|
||||
def run(self):
|
||||
self.server.serve_forever()
|
||||
|
||||
|
||||
|
|
|
@ -25,16 +25,16 @@
|
|||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
'''
|
||||
"""
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
"""
|
||||
|
||||
|
||||
import json
|
||||
import queue
|
||||
import socket
|
||||
import threading
|
||||
import six
|
||||
import traceback
|
||||
import json
|
||||
|
||||
from opengnsys.utils import toUnicode
|
||||
from opengnsys.log import logger
|
||||
|
@ -59,7 +59,7 @@ from opengnsys.log import logger
|
|||
# BYTE
|
||||
# 0 1-2 3 4 ...
|
||||
# MSG_ID DATA_LENGTH (little endian) Data (can be 0 length)
|
||||
# With a previos "MAGIC" header in fron of each message
|
||||
# With a previous "MAGIC" header in front of each message
|
||||
|
||||
# Client messages
|
||||
MSG_LOGOFF = 0xA1 # Request log off from an user
|
||||
|
@ -84,7 +84,7 @@ REV_DICT = {
|
|||
REQ_MESSAGE: 'REQ_MESSAGE'
|
||||
}
|
||||
|
||||
MAGIC = b'\x4F\x47\x41\x00' # OGA in hexa with a padded 0 to the right
|
||||
MAGIC = b'\x4F\x47\x41\x00' # OGA in hex with a padded 0 to the right
|
||||
|
||||
|
||||
# States for client processor
|
||||
|
@ -99,10 +99,10 @@ class ClientProcessor(threading.Thread):
|
|||
self.parent = parent
|
||||
self.clientSocket = clientSocket
|
||||
self.running = False
|
||||
self.messages = six.moves.queue.Queue(32) # @UndefinedVariable
|
||||
self.messages = queue.Queue(32)
|
||||
|
||||
def stop(self):
|
||||
logger.debug('Stoping client processor')
|
||||
logger.debug('Stopping client processor')
|
||||
self.running = False
|
||||
|
||||
def processRequest(self, msg, data):
|
||||
|
@ -117,6 +117,7 @@ class ClientProcessor(threading.Thread):
|
|||
state = None
|
||||
recv_msg = None
|
||||
recv_data = None
|
||||
msg_len = 0
|
||||
while self.running:
|
||||
try:
|
||||
counter = 1024
|
||||
|
@ -127,7 +128,7 @@ class ClientProcessor(threading.Thread):
|
|||
# Client disconnected
|
||||
self.running = False
|
||||
break
|
||||
buf = six.byte2int(b) # Empty buffer, this is set as non-blocking
|
||||
buf = int.from_bytes(b, 'big') # Empty buffer, this is set as non-blocking
|
||||
if state is None:
|
||||
if buf in (REQ_MESSAGE, REQ_LOGIN, REQ_LOGOUT):
|
||||
logger.debug('State set to {}'.format(buf))
|
||||
|
@ -152,7 +153,7 @@ class ClientProcessor(threading.Thread):
|
|||
recv_data = b''
|
||||
continue
|
||||
elif state == ST_RECEIVING:
|
||||
recv_data += six.int2byte(buf)
|
||||
recv_data += bytes([buf])
|
||||
msg_len -= 1
|
||||
if msg_len == 0:
|
||||
self.processRequest(recv_msg, recv_data)
|
||||
|
@ -173,7 +174,7 @@ class ClientProcessor(threading.Thread):
|
|||
|
||||
try:
|
||||
msg = self.messages.get(block=True, timeout=1)
|
||||
except six.moves.queue.Empty: # No message got in time @UndefinedVariable
|
||||
except queue.Empty: # No message got in time @UndefinedVariable
|
||||
continue
|
||||
|
||||
logger.debug('Got message {}={}'.format(msg, REV_DICT.get(msg[0])))
|
||||
|
@ -181,7 +182,7 @@ class ClientProcessor(threading.Thread):
|
|||
try:
|
||||
m = msg[1] if msg[1] is not None else b''
|
||||
l = len(m)
|
||||
data = MAGIC + six.int2byte(msg[0]) + six.int2byte(l & 0xFF) + six.int2byte(l >> 8) + m
|
||||
data = MAGIC + bytes([msg[0]]) + bytes([l & 0xFF]) + bytes([l >> 8]) + m
|
||||
try:
|
||||
self.clientSocket.sendall(data)
|
||||
except socket.error as e:
|
||||
|
@ -220,20 +221,20 @@ class ServerIPC(threading.Thread):
|
|||
for t in self.threads:
|
||||
t.join()
|
||||
|
||||
def sendMessage(self, msgId, msgData):
|
||||
'''
|
||||
def sendMessage(self, msg_id, msg_data):
|
||||
"""
|
||||
Notify message to all listening threads
|
||||
'''
|
||||
logger.debug('Sending message {}({}),{} to all clients'.format(msgId, REV_DICT.get(msgId), msgData))
|
||||
"""
|
||||
logger.debug('Sending message {}({}),{} to all clients'.format(msg_id, REV_DICT.get(msg_id), msg_data))
|
||||
|
||||
# Convert to bytes so length is correctly calculated
|
||||
if isinstance(msgData, six.text_type):
|
||||
msgData = msgData.encode('utf8')
|
||||
if isinstance(msg_data, str):
|
||||
msg_data = str.encode(msg_data)
|
||||
|
||||
for t in self.threads:
|
||||
if t.isAlive():
|
||||
if t.is_alive():
|
||||
logger.debug('Sending to {}'.format(t))
|
||||
t.messages.put((msgId, msgData))
|
||||
t.messages.put((msg_id, msg_data))
|
||||
|
||||
def sendLoggofMessage(self):
|
||||
self.sendMessage(MSG_LOGOFF, '')
|
||||
|
@ -242,18 +243,18 @@ class ServerIPC(threading.Thread):
|
|||
self.sendMessage(MSG_MESSAGE, message)
|
||||
|
||||
def sendPopupMessage(self, title, message):
|
||||
self.sendMessage(MSG_POPUP, {'title':title, 'message':message})
|
||||
self.sendMessage(MSG_POPUP, {'title': title, 'message': message})
|
||||
|
||||
def sendScriptMessage(self, script):
|
||||
self.sendMessage(MSG_SCRIPT, script)
|
||||
|
||||
def cleanupFinishedThreads(self):
|
||||
'''
|
||||
"""
|
||||
Cleans up current threads list
|
||||
'''
|
||||
"""
|
||||
aliveThreads = []
|
||||
for t in self.threads:
|
||||
if t.isAlive():
|
||||
if t.is_alive():
|
||||
logger.debug('Thread {} is alive'.format(t))
|
||||
aliveThreads.append(t)
|
||||
self.threads[:] = aliveThreads
|
||||
|
@ -262,7 +263,7 @@ class ServerIPC(threading.Thread):
|
|||
self.running = True
|
||||
|
||||
self.serverSocket.bind(('localhost', self.port))
|
||||
self.serverSocket.setblocking(1)
|
||||
self.serverSocket.setblocking(True)
|
||||
self.serverSocket.listen(4)
|
||||
|
||||
while True:
|
||||
|
@ -289,7 +290,7 @@ class ClientIPC(threading.Thread):
|
|||
self.port = listenPort
|
||||
self.running = False
|
||||
self.clientSocket = None
|
||||
self.messages = six.moves.queue.Queue(32) # @UndefinedVariable
|
||||
self.messages = queue.Queue(32) # @UndefinedVariable
|
||||
|
||||
self.connect()
|
||||
|
||||
|
@ -300,7 +301,7 @@ class ClientIPC(threading.Thread):
|
|||
while self.running:
|
||||
try:
|
||||
return self.messages.get(timeout=1)
|
||||
except six.moves.queue.Empty: # @UndefinedVariable
|
||||
except queue.Empty:
|
||||
continue
|
||||
|
||||
return None
|
||||
|
@ -310,11 +311,11 @@ class ClientIPC(threading.Thread):
|
|||
if data is None:
|
||||
data = b''
|
||||
|
||||
if isinstance(data, six.text_type): # Convert to bytes if necessary
|
||||
data = data.encode('utf-8')
|
||||
if isinstance(data, str):
|
||||
data = str.encode(data)
|
||||
|
||||
l = len(data)
|
||||
msg = six.int2byte(msg) + six.int2byte(l & 0xFF) + six.int2byte(l >> 8) + data
|
||||
msg = bytes([msg]) + bytes([l & 0xFF]) + bytes([l >> 8]) + data
|
||||
self.clientSocket.sendall(msg)
|
||||
|
||||
def sendLogin(self, user_data):
|
||||
|
@ -324,20 +325,20 @@ class ClientIPC(threading.Thread):
|
|||
self.sendRequestMessage(REQ_LOGOUT, username)
|
||||
|
||||
def sendMessage(self, module, message, data=None):
|
||||
'''
|
||||
"""
|
||||
Sends a message "message" with data (data will be encoded as json, so ensure that it is serializable)
|
||||
@param module: Module that will receive this message
|
||||
@param message: Message to send. This message is "customized", and understand by modules
|
||||
@param data: Data to be send as message companion
|
||||
'''
|
||||
"""
|
||||
msg = '\0'.join((module, message, json.dumps(data)))
|
||||
self.sendRequestMessage(REQ_MESSAGE, msg)
|
||||
|
||||
def messageReceived(self):
|
||||
'''
|
||||
"""
|
||||
Override this method to automatically get notified on new message
|
||||
received. Message is at self.messages queue
|
||||
'''
|
||||
"""
|
||||
pass
|
||||
|
||||
def receiveBytes(self, number):
|
||||
|
@ -420,4 +421,3 @@ class ClientIPC(threading.Thread):
|
|||
self.clientSocket.close()
|
||||
except Exception:
|
||||
pass # If can't close, nothing happens, just end thread
|
||||
|
||||
|
|
|
@ -26,10 +26,10 @@
|
|||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
"""
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
"""
|
||||
|
||||
|
||||
from opengnsys.service import CommonService
|
||||
from opengnsys.service import IPC_PORT
|
||||
|
@ -45,7 +45,7 @@ import json
|
|||
|
||||
try:
|
||||
from prctl import set_proctitle # @UnresolvedImport
|
||||
except Exception: # Platform may not include prctl, so in case it's not available, we let the "name" as is
|
||||
except ImportError: # Platform may not include prctl, so in case it's not available, we let the "name" as is
|
||||
def set_proctitle(_):
|
||||
pass
|
||||
|
||||
|
@ -63,7 +63,6 @@ class OGAgentSvc(Daemon, CommonService):
|
|||
|
||||
# Call modules initialization
|
||||
# They are called in sequence, no threading is done at this point, so ensure modules onActivate always returns
|
||||
|
||||
|
||||
# *********************
|
||||
# * Main Service loop *
|
||||
|
@ -93,6 +92,7 @@ def usage():
|
|||
sys.stderr.write("usage: {} start|stop|restart|fg|login 'username'|logout 'username'|message 'module' 'message' 'json'\n".format(sys.argv[0]))
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
logger.setLevel('INFO')
|
||||
|
||||
|
@ -105,7 +105,6 @@ if __name__ == '__main__':
|
|||
sys.exit(0)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
|
||||
|
||||
if len(sys.argv) == 3 and sys.argv[1] in ('login', 'logout'):
|
||||
logger.debug('Running client opengnsys')
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
"""
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
"""
|
||||
|
|
|
@ -25,18 +25,16 @@
|
|||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
'''
|
||||
"""
|
||||
@author: : http://www.jejik.com/authors/sander_marechal/
|
||||
@see: : http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/
|
||||
'''
|
||||
"""
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
import atexit
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
from opengnsys.log import logger
|
||||
|
||||
from signal import SIGTERM
|
||||
|
||||
|
||||
|
@ -89,7 +87,7 @@ class Daemon:
|
|||
sys.stderr.flush()
|
||||
si = open(self.stdin, 'r')
|
||||
so = open(self.stdout, 'a+')
|
||||
se = open(self.stderr, 'a+', 0)
|
||||
se = open(self.stderr, 'a+')
|
||||
os.dup2(si.fileno(), sys.stdin.fileno())
|
||||
os.dup2(so.fileno(), sys.stdout.fileno())
|
||||
os.dup2(se.fileno(), sys.stderr.fileno())
|
||||
|
|
|
@ -26,18 +26,16 @@
|
|||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
"""
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
"""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import tempfile
|
||||
import six
|
||||
|
||||
# Valid logging levels, from UDS Broker (uds.core.utils.log)
|
||||
OTHER, DEBUG, INFO, WARN, ERROR, FATAL = (10000 * (x + 1) for x in six.moves.xrange(6)) # @UndefinedVariable
|
||||
# Logging levels
|
||||
OTHER, DEBUG, INFO, WARN, ERROR, FATAL = (10000 * (x + 1) for x in range(6))
|
||||
|
||||
|
||||
class LocalLogger(object):
|
||||
|
@ -46,7 +44,7 @@ class LocalLogger(object):
|
|||
# service wil get c:\windows\temp, while user will get c:\users\XXX\temp
|
||||
# Try to open logger at /var/log path
|
||||
# If it fails (access denied normally), will try to open one at user's home folder, and if
|
||||
# agaim it fails, open it at the tmpPath
|
||||
# again it fails, open it at the tmpPath
|
||||
|
||||
for logDir in ('/var/log', os.path.expanduser('~'), tempfile.gettempdir()):
|
||||
try:
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
import socket
|
||||
import platform
|
||||
|
@ -104,7 +104,7 @@ def _getInterfaces():
|
|||
0x8912, # SIOCGIFCONF
|
||||
struct.pack(str('iL'), space, names.buffer_info()[0])
|
||||
))[0]
|
||||
namestr = names.tostring()
|
||||
namestr = names.tobytes()
|
||||
# return namestr, outbytes
|
||||
return [namestr[i:i + offset].split(b'\0', 1)[0].decode('utf-8') for i in range(0, outbytes, length)]
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
import platform
|
||||
import os
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
from opengnsys.linux.renamer import renamers
|
||||
from opengnsys.log import logger
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
from opengnsys.linux.renamer import renamers
|
||||
from opengnsys.log import logger
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
from opengnsys.linux.renamer import renamers
|
||||
from opengnsys.log import logger
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
# This is a simple module loader, so we can add "external opengnsys" modules as addons
|
||||
# Modules under "opengsnsys/modules" are always autoloaded
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
import pkgutil
|
||||
import os.path
|
||||
|
|
|
@ -26,22 +26,21 @@
|
|||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
"""
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
"""
|
||||
|
||||
|
||||
import traceback
|
||||
import sys
|
||||
import six
|
||||
import traceback
|
||||
|
||||
if sys.platform == 'win32':
|
||||
from opengnsys.windows.log import LocalLogger # @UnusedImport
|
||||
from opengnsys.windows.log import LocalLogger
|
||||
else:
|
||||
from opengnsys.linux.log import LocalLogger # @Reimport
|
||||
from opengnsys.linux.log import LocalLogger
|
||||
|
||||
# Valid logging levels, from UDS Broker (uds.core.utils.log)
|
||||
OTHER, DEBUG, INFO, WARN, ERROR, FATAL = (10000 * (x + 1) for x in six.moves.xrange(6)) # @UndefinedVariable
|
||||
OTHER, DEBUG, INFO, WARN, ERROR, FATAL = (10000 * (x + 1) for x in range(6))
|
||||
|
||||
_levelName = {
|
||||
'OTHER': OTHER,
|
||||
|
@ -52,17 +51,18 @@ _levelName = {
|
|||
'FATAL': FATAL
|
||||
}
|
||||
|
||||
|
||||
class Logger(object):
|
||||
def __init__(self):
|
||||
self.logLevel = INFO
|
||||
self.logger = LocalLogger()
|
||||
|
||||
def setLevel(self, level):
|
||||
'''
|
||||
"""
|
||||
Sets log level filter (minimum level required for a log message to be processed)
|
||||
:param level: Any message with a level below this will be filtered out
|
||||
'''
|
||||
if isinstance(level, six.string_types):
|
||||
"""
|
||||
if isinstance(level, str):
|
||||
level = _levelName.get(level, INFO)
|
||||
|
||||
self.logLevel = level # Ensures level is an integer or fails
|
||||
|
|
|
@ -29,4 +29,4 @@
|
|||
'''
|
||||
@author: Ramón M. Gómez, ramongomez at us dot es
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
import socket
|
||||
import platform
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
"""
|
||||
@author: Ramón M. Gómez, ramongomez at us dot es
|
||||
"""
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
from opengnsys.workers import ClientWorker
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
|
@ -28,22 +29,24 @@
|
|||
"""
|
||||
@author: Ramón M. Gómez, ramongomez at us dot es
|
||||
"""
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import threading
|
||||
|
||||
import base64
|
||||
import os
|
||||
import platform
|
||||
import time
|
||||
import random
|
||||
import shutil
|
||||
import string
|
||||
import urllib
|
||||
import threading
|
||||
import time
|
||||
import urllib.error
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
|
||||
from opengnsys.workers import ServerWorker
|
||||
from opengnsys import REST, RESTError
|
||||
from opengnsys import operations
|
||||
from configparser import NoOptionError
|
||||
from opengnsys import REST, operations, VERSION
|
||||
from opengnsys.log import logger
|
||||
from opengnsys.scriptThread import ScriptExecutorThread
|
||||
from opengnsys.workers import ServerWorker
|
||||
|
||||
|
||||
# Check authorization header decorator
|
||||
|
@ -53,9 +56,12 @@ def check_secret(fnc):
|
|||
"""
|
||||
def wrapper(*args, **kwargs):
|
||||
try:
|
||||
this, path, get_params, post_params, server = args # @UnusedVariable
|
||||
if this.random == server.headers['Authorization']:
|
||||
fnc(*args, **kwargs)
|
||||
this, path, get_params, post_params, server = args
|
||||
# Accept "status" operation with no arguments or any function with Authorization header
|
||||
if fnc.__name__ == 'process_status' and not get_params:
|
||||
return fnc(*args, **kwargs)
|
||||
elif this.random == server.headers['Authorization']:
|
||||
return fnc(*args, **kwargs)
|
||||
else:
|
||||
raise Exception('Unauthorized operation')
|
||||
except Exception as e:
|
||||
|
@ -65,6 +71,26 @@ def check_secret(fnc):
|
|||
return wrapper
|
||||
|
||||
|
||||
# Check if operation is permitted
|
||||
def execution_level(level):
|
||||
def check_permitted(fnc):
|
||||
def wrapper(*args, **kwargs):
|
||||
levels = ['status', 'halt', 'full']
|
||||
this = args[0]
|
||||
try:
|
||||
if levels.index(level) <= levels.index(this.exec_level):
|
||||
return fnc(*args, **kwargs)
|
||||
else:
|
||||
raise Exception('Unauthorized operation')
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
raise Exception(e)
|
||||
|
||||
return wrapper
|
||||
|
||||
return check_permitted
|
||||
|
||||
|
||||
# Error handler decorator.
|
||||
def catch_background_error(fnc):
|
||||
def wrapper(*args, **kwargs):
|
||||
|
@ -77,31 +103,43 @@ def catch_background_error(fnc):
|
|||
|
||||
|
||||
class OpenGnSysWorker(ServerWorker):
|
||||
name = 'opengnsys'
|
||||
name = 'opengnsys' # Module name
|
||||
interface = None # Bound interface for OpenGnsys
|
||||
REST = None # REST object
|
||||
logged_in = False # User session flag
|
||||
user = [] # User sessions
|
||||
session_type = '' # User session type
|
||||
locked = {}
|
||||
random = None # Random string for secure connections
|
||||
length = 32 # Random string length
|
||||
exec_level = None # Execution level (permitted operations)
|
||||
|
||||
def onActivation(self):
|
||||
"""
|
||||
Sends OGAgent activation notification to OpenGnsys server
|
||||
"""
|
||||
t = 0
|
||||
e = None # Error info
|
||||
t = 0 # Count of time
|
||||
# Generate random secret to send on activation
|
||||
self.random = ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(self.length))
|
||||
# Ensure cfg has required configuration variables or an exception will be thrown
|
||||
url = self.service.config.get('opengnsys', 'remote')
|
||||
try:
|
||||
url = self.service.config.get('opengnsys', 'remote')
|
||||
except NoOptionError as e:
|
||||
logger.error("Configuration error: {}".format(e))
|
||||
raise e
|
||||
self.REST = REST(url)
|
||||
# Execution level ('full' by default)
|
||||
try:
|
||||
self.exec_level = self.service.config.get('opengnsys', 'level')
|
||||
except NoOptionError:
|
||||
self.exec_level = 'full'
|
||||
# Get network interfaces until they are active or timeout (5 minutes)
|
||||
for t in range(0, 300):
|
||||
try:
|
||||
self.interface = list(operations.getNetworkInfo())[0] # Get first network interface
|
||||
# Get the first network interface
|
||||
self.interface = list(operations.getNetworkInfo())[0]
|
||||
except Exception as e:
|
||||
# Wait 1 sec. and retry
|
||||
logger.warn (e)
|
||||
time.sleep(1)
|
||||
finally:
|
||||
# Exit loop if interface is active
|
||||
|
@ -112,29 +150,36 @@ class OpenGnSysWorker(ServerWorker):
|
|||
# Raise error after timeout
|
||||
if not self.interface:
|
||||
raise e
|
||||
|
||||
# Loop to send initialization message
|
||||
for t in range(0, 100):
|
||||
init_retries = 100
|
||||
for t in range(0, init_retries):
|
||||
try:
|
||||
try:
|
||||
self.REST.sendMessage('ogagent/started', {'mac': self.interface.mac, 'ip': self.interface.ip,
|
||||
'secret': self.random, 'ostype': operations.os_type,
|
||||
'osversion': operations.os_version})
|
||||
'osversion': operations.os_version,
|
||||
'agent_version': VERSION})
|
||||
break
|
||||
except:
|
||||
except Exception as e:
|
||||
logger.warn (str (e))
|
||||
# Trying to initialize on alternative server, if defined
|
||||
# (used in "exam mode" from the University of Seville)
|
||||
self.REST = REST(self.service.config.get('opengnsys', 'altremote'))
|
||||
self.REST.sendMessage('ogagent/started', {'mac': self.interface.mac, 'ip': self.interface.ip,
|
||||
'secret': self.random, 'ostype': operations.os_type,
|
||||
'osversion': operations.os_version, 'alt_url': True})
|
||||
'osversion': operations.os_version, 'alt_url': True,
|
||||
'agent_version': VERSION})
|
||||
break
|
||||
except:
|
||||
except Exception as e:
|
||||
logger.warn (str (e))
|
||||
time.sleep(3)
|
||||
# Raise error after timeout
|
||||
if 0 < t < 100:
|
||||
if t < init_retries-1:
|
||||
logger.debug('Successful connection after {} tries'.format(t))
|
||||
elif t == 100:
|
||||
elif t == init_retries-1:
|
||||
raise Exception('Initialization error: Cannot connect to remote server')
|
||||
|
||||
# Delete marking files
|
||||
for f in ['ogboot.me', 'ogboot.firstboot', 'ogboot.secondboot']:
|
||||
try:
|
||||
|
@ -165,7 +210,7 @@ class OpenGnSysWorker(ServerWorker):
|
|||
"""
|
||||
user, language, self.session_type = tuple(data.split(','))
|
||||
logger.debug('Received login for {0} using {2} with language {1}'.format(user, language, self.session_type))
|
||||
self.logged_in = True
|
||||
self.user.append(user)
|
||||
self.REST.sendMessage('ogagent/loggedin', {'ip': self.interface.ip, 'user': user, 'language': language,
|
||||
'session': self.session_type,
|
||||
'ostype': operations.os_type, 'osversion': operations.os_version})
|
||||
|
@ -175,7 +220,10 @@ class OpenGnSysWorker(ServerWorker):
|
|||
Sends session logout notification to OpenGnsys server
|
||||
"""
|
||||
logger.debug('Received logout for {}'.format(user))
|
||||
self.logged_in = False
|
||||
try:
|
||||
self.user.pop()
|
||||
except IndexError:
|
||||
pass
|
||||
self.REST.sendMessage('ogagent/loggedout', {'ip': self.interface.ip, 'user': user})
|
||||
|
||||
def process_ogclient(self, path, get_params, post_params, server):
|
||||
|
@ -206,34 +254,34 @@ class OpenGnSysWorker(ServerWorker):
|
|||
raise Exception('Message processor for "{}" not found'.format(path[0]))
|
||||
return operation(path[1:], get_params, post_params)
|
||||
|
||||
# Warning: the order of the decorators matters
|
||||
@execution_level('status')
|
||||
@check_secret
|
||||
def process_status(self, path, get_params, post_params, server):
|
||||
"""
|
||||
Returns client status (OS type or execution status) and login status
|
||||
:param path:
|
||||
:param get_params:
|
||||
:param get_params: optional parameter "detail" to show extended status
|
||||
:param post_params:
|
||||
:param server:
|
||||
:return: JSON object {"status": "status_code", "loggedin": boolean}
|
||||
:return: JSON object {"status": "status_code", "loggedin": boolean, ...}
|
||||
"""
|
||||
res = {'status': '', 'loggedin': self.logged_in, 'session': self.session_type}
|
||||
if platform.system() == 'Linux': # GNU/Linux
|
||||
# Check if it's OpenGnsys Client.
|
||||
if os.path.exists('/scripts/oginit'):
|
||||
# Check if OpenGnsys Client is busy.
|
||||
if self.locked:
|
||||
res['status'] = 'BSY'
|
||||
else:
|
||||
res['status'] = 'OPG'
|
||||
else:
|
||||
# Check if there is an active session.
|
||||
res['status'] = 'LNX'
|
||||
elif platform.system() == 'Windows': # Windows
|
||||
# Check if there is an active session.
|
||||
res['status'] = 'WIN'
|
||||
elif platform.system() == 'Darwin': # Mac OS X ??
|
||||
res['status'] = 'OSX'
|
||||
st = {'linux': 'LNX', 'macos': 'OSX', 'windows': 'WIN'}
|
||||
try:
|
||||
# Standard status
|
||||
res = {'status': st[operations.os_type.lower()], 'loggedin': len(self.user) > 0,
|
||||
'session': self.session_type}
|
||||
# Detailed status
|
||||
if get_params.get('detail', 'false') == 'true':
|
||||
res.update({'agent_version': VERSION, 'os_version': operations.os_version, 'sys_load': os.getloadavg()})
|
||||
if res['loggedin']:
|
||||
res.update({'sessions': len(self.user), 'current_user': self.user[-1]})
|
||||
except KeyError:
|
||||
# Unknown operating system
|
||||
res = {'status': 'UNK'}
|
||||
return res
|
||||
|
||||
@execution_level('halt')
|
||||
@check_secret
|
||||
def process_reboot(self, path, get_params, post_params, server):
|
||||
"""
|
||||
|
@ -252,6 +300,7 @@ class OpenGnSysWorker(ServerWorker):
|
|||
threading.Thread(target=rebt).start()
|
||||
return {'op': 'launched'}
|
||||
|
||||
@execution_level('halt')
|
||||
@check_secret
|
||||
def process_poweroff(self, path, get_params, post_params, server):
|
||||
"""
|
||||
|
@ -271,6 +320,7 @@ class OpenGnSysWorker(ServerWorker):
|
|||
threading.Thread(target=pwoff).start()
|
||||
return {'op': 'launched'}
|
||||
|
||||
@execution_level('full')
|
||||
@check_secret
|
||||
def process_script(self, path, get_params, post_params, server):
|
||||
"""
|
||||
|
@ -283,7 +333,7 @@ class OpenGnSysWorker(ServerWorker):
|
|||
"""
|
||||
logger.debug('Processing script request')
|
||||
# Decoding script (Windows scripts need a subprocess call per line)
|
||||
script = urllib.unquote(post_params.get('script').decode('base64')).decode('utf8')
|
||||
script = urllib.parse.unquote(base64.b64decode(post_params.get('script')).decode('utf-8'))
|
||||
if operations.os_type == 'Windows':
|
||||
script = 'import subprocess; {0}'.format(
|
||||
';'.join(['subprocess.check_output({0},shell=True)'.format(repr(c)) for c in script.split('\n')]))
|
||||
|
@ -297,6 +347,7 @@ class OpenGnSysWorker(ServerWorker):
|
|||
self.sendClientMessage('script', {'code': script})
|
||||
return {'op': 'launched'}
|
||||
|
||||
@execution_level('full')
|
||||
@check_secret
|
||||
def process_logoff(self, path, get_params, post_params, server):
|
||||
"""
|
||||
|
@ -307,6 +358,7 @@ class OpenGnSysWorker(ServerWorker):
|
|||
self.sendClientMessage('logoff', {})
|
||||
return {'op': 'sent to client'}
|
||||
|
||||
@execution_level('full')
|
||||
@check_secret
|
||||
def process_popup(self, path, get_params, post_params, server):
|
||||
"""
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
"""
|
||||
# pylint: disable=unused-wildcard-import,wildcard-import
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import sys
|
||||
|
||||
# Importing platform operations and getting operating system data.
|
||||
|
|
|
@ -26,23 +26,21 @@
|
|||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
"""
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
"""
|
||||
|
||||
from .log import logger
|
||||
from .config import readConfig
|
||||
from .utils import exceptionToMessage
|
||||
import json
|
||||
import socket
|
||||
import time
|
||||
|
||||
from . import ipc
|
||||
from . import httpserver
|
||||
from .config import readConfig
|
||||
from .loader import loadModules
|
||||
from .log import logger
|
||||
from .utils import exceptionToMessage
|
||||
|
||||
import socket
|
||||
import time
|
||||
import json
|
||||
import six
|
||||
|
||||
IPC_PORT = 10398
|
||||
|
||||
|
@ -58,21 +56,17 @@ class CommonService(object):
|
|||
logger.info('Initializing OpenGnsys Agent')
|
||||
|
||||
# Read configuration file before proceding & ensures minimal config is there
|
||||
|
||||
self.config = readConfig()
|
||||
|
||||
# Get opengnsys section as dict
|
||||
# Get opengnsys section as dict
|
||||
cfg = dict(self.config.items('opengnsys'))
|
||||
|
||||
# Set up log level
|
||||
logger.setLevel(cfg.get('log', 'INFO'))
|
||||
|
||||
|
||||
logger.debug('Loaded configuration from opengnsys.cfg:')
|
||||
for section in self.config.sections():
|
||||
logger.debug('Section {} = {}'.format(section, self.config.items(section)))
|
||||
|
||||
|
||||
|
||||
if logger.logger.isWindows():
|
||||
# Logs will also go to windows event log for services
|
||||
logger.logger.serviceLogger = True
|
||||
|
@ -90,15 +84,16 @@ class CommonService(object):
|
|||
logger.debug('Modules: {}'.format(list(v.name for v in self.modules)))
|
||||
|
||||
def stop(self):
|
||||
'''
|
||||
"""
|
||||
Requests service termination
|
||||
'''
|
||||
"""
|
||||
self.isAlive = False
|
||||
|
||||
# ********************************
|
||||
# * Internal messages processors *
|
||||
# ********************************
|
||||
def notifyLogin(self, username):
|
||||
def notifyLogin(self, data):
|
||||
username = data.decode('utf-8')
|
||||
for v in self.modules:
|
||||
try:
|
||||
logger.debug('Notifying login of user {} to module {}'.format(username, v.name))
|
||||
|
@ -106,7 +101,8 @@ class CommonService(object):
|
|||
except Exception as e:
|
||||
logger.error('Got exception {} processing login message on {}'.format(e, v.name))
|
||||
|
||||
def notifyLogout(self, username):
|
||||
def notifyLogout(self, data):
|
||||
username = data.decode('utf-8')
|
||||
for v in self.modules:
|
||||
try:
|
||||
logger.debug('Notifying logout of user {} to module {}'.format(username, v.name))
|
||||
|
@ -115,7 +111,7 @@ class CommonService(object):
|
|||
logger.error('Got exception {} processing logout message on {}'.format(e, v.name))
|
||||
|
||||
def notifyMessage(self, data):
|
||||
module, message, data = data.split('\0')
|
||||
module, message, data = data.decode('utf-8').split('\0')
|
||||
for v in self.modules:
|
||||
if v.name == module: # Case Sensitive!!!!
|
||||
try:
|
||||
|
@ -126,13 +122,12 @@ class CommonService(object):
|
|||
logger.error('Got exception {} processing generic message on {}'.format(e, v.name))
|
||||
|
||||
logger.error('Module {} not found, messsage {} not sent'.format(module, message))
|
||||
|
||||
|
||||
def clientMessageProcessor(self, msg, data):
|
||||
'''
|
||||
"""
|
||||
Callback, invoked from IPC, on its own thread (not the main thread).
|
||||
This thread will "block" communication with agent untill finished, but this should be no problem
|
||||
'''
|
||||
"""
|
||||
logger.debug('Got message {}'.format(msg))
|
||||
|
||||
if msg == ipc.REQ_LOGIN:
|
||||
|
@ -143,14 +138,9 @@ class CommonService(object):
|
|||
self.notifyMessage(data)
|
||||
|
||||
def initialize(self):
|
||||
# ******************************************
|
||||
# * Initialize listeners, modules, etc...
|
||||
# ******************************************
|
||||
|
||||
if six.PY3 is False:
|
||||
import threading
|
||||
threading._DummyThread._Thread__stop = lambda x: 42
|
||||
|
||||
"""
|
||||
Initialize listeners, modules, etc...
|
||||
"""
|
||||
logger.debug('Starting IPC listener at {}'.format(IPC_PORT))
|
||||
self.ipc = ipc.ServerIPC(self.ipcport, clientMessageProcessor=self.clientMessageProcessor)
|
||||
self.ipc.start()
|
||||
|
@ -203,47 +193,47 @@ class CommonService(object):
|
|||
# Methods that CAN BE overridden by agents
|
||||
# ****************************************
|
||||
def doWait(self, miliseconds):
|
||||
'''
|
||||
"""
|
||||
Invoked to wait a bit
|
||||
CAN be OVERRIDDEN
|
||||
'''
|
||||
"""
|
||||
time.sleep(float(miliseconds) / 1000)
|
||||
|
||||
def notifyStop(self):
|
||||
'''
|
||||
"""
|
||||
Overridden to log stop
|
||||
'''
|
||||
"""
|
||||
logger.info('Service is being stopped')
|
||||
|
||||
# ***************************************************
|
||||
# * Helpers, convenient methods to facilitate comms *
|
||||
# ***************************************************
|
||||
def sendClientMessage(self, toModule, message, data):
|
||||
'''
|
||||
"""
|
||||
Sends a message to the clients using IPC
|
||||
The data is converted to json, so ensure that it is serializable.
|
||||
All IPC is asynchronous, so if you expect a response, this will be sent by client using another message
|
||||
|
||||
|
||||
@param toModule: Module that will receive this message
|
||||
@param message: Message to send
|
||||
@param data: data to send
|
||||
'''
|
||||
@param data: data to send
|
||||
"""
|
||||
self.ipc.sendMessageMessage('\0'.join((toModule, message, json.dumps(data))))
|
||||
|
||||
def sendScriptMessage(self, script):
|
||||
'''
|
||||
"""
|
||||
Sends an script to be executed by client
|
||||
'''
|
||||
"""
|
||||
self.ipc.sendScriptMessage(script)
|
||||
|
||||
def sendLogoffMessage(self):
|
||||
'''
|
||||
"""
|
||||
Sends a logoff message to client
|
||||
'''
|
||||
"""
|
||||
self.ipc.sendLoggofMessage()
|
||||
|
||||
def sendPopupMessage(self, title, message):
|
||||
'''
|
||||
Sends a poup box to be displayed by client
|
||||
'''
|
||||
"""
|
||||
Sends a popup box to be displayed by client
|
||||
"""
|
||||
self.ipc.sendPopupMessage(title, message)
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
import sys
|
||||
import six
|
||||
|
|
|
@ -25,25 +25,25 @@
|
|||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
'''
|
||||
"""
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
"""
|
||||
# pylint: disable=unused-wildcard-import,wildcard-import
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
class ClientWorker(object):
|
||||
'''
|
||||
"""
|
||||
A ServerWorker is a server module that "works" for service
|
||||
Most method are invoked inside their own thread, except onActivation & onDeactivation.
|
||||
Most method are invoked inside their own thread, except onActivation & onDeactivation.
|
||||
This two methods are invoked inside main service thread, take that into account when creating them
|
||||
|
||||
|
||||
* You must provide a module name (override name on your class), so we can identify the module by a "valid" name.
|
||||
A valid name is like a valid python variable (do not use spaces, etc...)
|
||||
* The name of the module is used as REST message destination id:
|
||||
https://sampleserver:8888/[name]/....
|
||||
Remember that module names and REST path are case sensitive!!!
|
||||
|
||||
'''
|
||||
|
||||
"""
|
||||
name = None
|
||||
service = None
|
||||
|
||||
|
@ -51,15 +51,15 @@ class ClientWorker(object):
|
|||
self.service = service
|
||||
|
||||
def activate(self):
|
||||
'''
|
||||
"""
|
||||
Convenient method to wrap onActivation, so we can include easyly custom common logic for activation in a future
|
||||
'''
|
||||
"""
|
||||
self.onActivation()
|
||||
|
||||
def deactivate(self):
|
||||
'''
|
||||
"""
|
||||
Convenient method to wrap onActivation, so we can include easyly custom common logic for deactivation in a future
|
||||
'''
|
||||
"""
|
||||
self.onDeactivation()
|
||||
|
||||
def processMessage(self, message, params):
|
||||
|
@ -83,32 +83,31 @@ class ClientWorker(object):
|
|||
return operation(params)
|
||||
|
||||
def onActivation(self):
|
||||
'''
|
||||
"""
|
||||
Invoked by Service for activation.
|
||||
This MUST be overridden by modules!
|
||||
This method is invoked inside main thread, so if it "hangs", complete service will hang
|
||||
This should be no problem, but be advised about this
|
||||
'''
|
||||
"""
|
||||
pass
|
||||
|
||||
def onDeactivation(self):
|
||||
'''
|
||||
"""
|
||||
Invoked by Service before unloading service
|
||||
This MUST be overridden by modules!
|
||||
This method is invoked inside main thread, so if it "hangs", complete service will hang
|
||||
This should be no problem, but be advised about this
|
||||
'''
|
||||
"""
|
||||
pass
|
||||
|
||||
# *************************************
|
||||
# * Helper, convenient helper methods *
|
||||
# *************************************
|
||||
def sendServerMessage(self, message, data):
|
||||
'''
|
||||
"""
|
||||
Sends a message to connected ipc clients
|
||||
By convenience, it uses the "current" moduel name as destination module name also.
|
||||
If you need to send a message to a different module, you can use self.service.sendClientMessage(module, message, data) instead
|
||||
og this helmer
|
||||
'''
|
||||
"""
|
||||
self.service.ipc.sendMessage(self.name, message, data)
|
||||
|
|
@ -25,25 +25,25 @@
|
|||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
'''
|
||||
"""
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
"""
|
||||
# pylint: disable=unused-wildcard-import,wildcard-import
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
class ServerWorker(object):
|
||||
'''
|
||||
"""
|
||||
A ServerWorker is a server module that "works" for service
|
||||
Most method are invoked inside their own thread, except onActivation & onDeactivation.
|
||||
Most method are invoked inside their own thread, except onActivation & onDeactivation.
|
||||
This two methods are invoked inside main service thread, take that into account when creating them
|
||||
|
||||
|
||||
* You must provide a module name (override name on your class), so we can identify the module by a "valid" name.
|
||||
A valid name is like a valid python variable (do not use spaces, etc...)
|
||||
* The name of the module is used as REST message destination id:
|
||||
https://sampleserver:8888/[name]/....
|
||||
Remember that module names and REST path are case sensitive!!!
|
||||
|
||||
'''
|
||||
|
||||
"""
|
||||
name = None
|
||||
service = None
|
||||
locked = False
|
||||
|
@ -52,43 +52,43 @@ class ServerWorker(object):
|
|||
self.service = service
|
||||
|
||||
def activate(self):
|
||||
'''
|
||||
"""
|
||||
Convenient method to wrap onActivation, so we can include easyly custom common logic for activation in a future
|
||||
'''
|
||||
"""
|
||||
self.onActivation()
|
||||
|
||||
def deactivate(self):
|
||||
'''
|
||||
"""
|
||||
Convenient method to wrap onActivation, so we can include easyly custom common logic for deactivation in a future
|
||||
'''
|
||||
"""
|
||||
self.onDeactivation()
|
||||
|
||||
def process(self, getParams, postParams, server):
|
||||
'''
|
||||
"""
|
||||
This method is invoked on a message received with an empty path (that means a message with only the module name, like in "http://example.com/Sample"
|
||||
Override it if you expect messages with that pattern
|
||||
|
||||
|
||||
Overriden method must return data that can be serialized to json (i.e. Ojects are not serializable to json, basic type are)
|
||||
'''
|
||||
"""
|
||||
raise NotImplementedError('Generic message processor is not supported')
|
||||
|
||||
def processServerMessage(self, path, getParams, postParams, server):
|
||||
'''
|
||||
"""
|
||||
This method can be overriden to provide your own message proccessor, or better you can
|
||||
implement a method that is called exactly as "process_" + path[0] (module name has been removed from path array) and this default processMessage will invoke it
|
||||
* Example:
|
||||
Imagine this invocation url (no matter if GET or POST): http://example.com:9999/Sample/mazinger/Z
|
||||
The HTTP Server will remove "Sample" from path, parse arguments and invoke this method as this:
|
||||
module.processMessage(["mazinger","Z"], getParams, postParams)
|
||||
|
||||
|
||||
This method will process "mazinguer", and look for a "self" method that is called "process_mazinger", and invoke it this way:
|
||||
return self.process_mazinger(["Z"], getParams, postParams)
|
||||
|
||||
|
||||
In the case path is empty (that is, the path is composed only by the module name, like in "http://example.com/Sample", the "process" method
|
||||
will be invoked directly
|
||||
|
||||
|
||||
The methods must return data that can be serialized to json (i.e. Ojects are not serializable to json, basic type are)
|
||||
'''
|
||||
"""
|
||||
if self.locked is True:
|
||||
raise Exception('system is busy')
|
||||
|
||||
|
@ -103,20 +103,20 @@ class ServerWorker(object):
|
|||
|
||||
|
||||
def processClientMessage(self, message, data):
|
||||
'''
|
||||
"""
|
||||
Invoked by Service when a client message is received (A message from user space Agent)
|
||||
|
||||
|
||||
This method can be overriden to provide your own message proccessor, or better you can
|
||||
implement a method that is called exactly "process_client_" + message (module name has been removed from path) and this default processMessage will invoke it
|
||||
* Example:
|
||||
We got a message from OGAgent "Mazinger", with json params
|
||||
module.processClientMessage("mazinger", jsonParams)
|
||||
|
||||
|
||||
This method will process "mazinguer", and look for a "self" method that is called "process_client_mazinger", and invoke it this way:
|
||||
self.process_client_mazinger(jsonParams)
|
||||
|
||||
|
||||
The methods returns nothing (client communications are done asynchronously)
|
||||
'''
|
||||
"""
|
||||
try:
|
||||
operation = getattr(self, 'process_client_' + message)
|
||||
except Exception:
|
||||
|
@ -128,52 +128,52 @@ class ServerWorker(object):
|
|||
|
||||
|
||||
def onActivation(self):
|
||||
'''
|
||||
"""
|
||||
Invoked by Service for activation.
|
||||
This MUST be overridden by modules!
|
||||
This method is invoked inside main thread, so if it "hangs", complete service will hang
|
||||
This should be no problem, but be advised about this
|
||||
'''
|
||||
"""
|
||||
pass
|
||||
|
||||
def onDeactivation(self):
|
||||
'''
|
||||
"""
|
||||
Invoked by Service before unloading service
|
||||
This MUST be overridden by modules!
|
||||
This method is invoked inside main thread, so if it "hangs", complete service will hang
|
||||
This should be no problem, but be advised about this
|
||||
'''
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def onLogin(self, user):
|
||||
'''
|
||||
"""
|
||||
Invoked by Service when an user login is detected
|
||||
This CAN be overridden by modules
|
||||
This method is invoked whenever the client (user space agent) notifies the server (Service) that a user has logged in.
|
||||
This method is run on its own thread
|
||||
'''
|
||||
"""
|
||||
pass
|
||||
|
||||
def onLogout(self, user):
|
||||
'''
|
||||
"""
|
||||
Invoked by Service when an user login is detected
|
||||
This CAN be overridden by modules
|
||||
This method is invoked whenever the client (user space agent) notifies the server (Service) that a user has logged in.
|
||||
This method is run on its own thread
|
||||
'''
|
||||
"""
|
||||
pass
|
||||
|
||||
# *************************************
|
||||
# * Helper, convenient helper methods *
|
||||
# *************************************
|
||||
def sendClientMessage(self, message, data):
|
||||
'''
|
||||
"""
|
||||
Sends a message to connected ipc clients
|
||||
By convenience, it uses the "current" moduel name as destination module name also.
|
||||
If you need to send a message to a different module, you can use self.service.sendClientMessage(module, message, data) instead
|
||||
og this helmer
|
||||
'''
|
||||
"""
|
||||
self.service.sendClientMessage(self.name, message, data)
|
||||
|
||||
def sendScriptMessage(self, script):
|
||||
|
|
|
@ -3,7 +3,7 @@ Created on Jul 9, 2015
|
|||
|
||||
@author: dkmaster
|
||||
'''
|
||||
from __future__ import unicode_literals, print_function
|
||||
|
||||
|
||||
# Pydev can't parse "six.moves.xxxx" because it is loaded lazy
|
||||
from six.moves.socketserver import ThreadingMixIn # @UnresolvedImport
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
netifaces
|
||||
requests
|
||||
urllib3
|
14
src/setup.py
14
src/setup.py
|
@ -60,12 +60,8 @@ from distutils.core import setup
|
|||
import py2exe
|
||||
import sys
|
||||
|
||||
# Reading version file:
|
||||
try:
|
||||
with open('VERSION', 'r') as v:
|
||||
VERSION = v.read().rstrip()
|
||||
except IOError:
|
||||
VERSION = '1.1.0'
|
||||
# update.sh changes this value
|
||||
VERSION='1.3.0'
|
||||
|
||||
sys.argv.append('py2exe')
|
||||
|
||||
|
@ -99,7 +95,7 @@ class Target:
|
|||
# thus don't need to run in a console.
|
||||
|
||||
|
||||
udsservice = Target(
|
||||
ogaservice = Target(
|
||||
description='OpenGnsys Agent Service',
|
||||
modules=['opengnsys.windows.OGAgentService'],
|
||||
icon_resources=[(0, 'img\\oga.ico'), (1, 'img\\oga.ico')],
|
||||
|
@ -112,7 +108,7 @@ HIDDEN_BY_SIX = ['SocketServer', 'SimpleHTTPServer', 'urllib']
|
|||
setup(
|
||||
windows=[
|
||||
{
|
||||
'script': 'OGAgentUser.py',
|
||||
'script': 'OGAgentUser-qt4.py',
|
||||
'icon_resources': [(0, 'img\\oga.ico'), (1, 'img\\oga.ico')]
|
||||
},
|
||||
],
|
||||
|
@ -121,7 +117,7 @@ setup(
|
|||
'script': 'OGAServiceHelper.py'
|
||||
}
|
||||
],
|
||||
service=[udsservice],
|
||||
service=[ogaservice],
|
||||
data_files=[('', [get_requests_cert_file()]), ('cfg', ['cfg/ogagent.cfg', 'cfg/ogclient.cfg'])],
|
||||
options={
|
||||
'py2exe': {
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
from opengnsys.workers import ClientWorker
|
||||
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
# Module must be imported on package, so we can initialize and load it
|
||||
from sample1 import Sample1
|
||||
from .sample1 import Sample1
|
|
@ -29,7 +29,7 @@
|
|||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
from opengnsys.workers import ServerWorker
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
|
||||
def test():
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
# pylint: disable=unused-wildcard-import,wildcard-import
|
||||
from __future__ import unicode_literals, print_function
|
||||
|
||||
|
||||
# Pydev can't parse "six.moves.xxxx" because it is loaded lazy
|
||||
from six.moves.socketserver import ThreadingMixIn # @UnresolvedImport
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# Copyright (c) 2024 Qindel Formación y Servicios S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -27,16 +28,32 @@
|
|||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
function process {
|
||||
pyuic4 about-dialog.ui -o about_dialog_ui.py -x
|
||||
pyuic4 message-dialog.ui -o message_dialog_ui.py -x
|
||||
}
|
||||
function update_version {
|
||||
if [[ -r VERSION ]]; then
|
||||
V="$(cat VERSION)"
|
||||
sed -i "s/Version [^<]*/Version $V/" about-dialog.ui
|
||||
sed -i "s/^VERSION='.*'$/VERSION='$V'/" setup.py
|
||||
sed -i "s/^VERSION='.*'$/VERSION='$V'/" opengnsys/__init__.py
|
||||
else
|
||||
echo 'src/VERSION: No such file or directory'
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function process_ui {
|
||||
pyuic6 about-dialog.ui -o about_dialog_ui.py -x
|
||||
pyuic6 message-dialog.ui -o message_dialog_ui.py -x
|
||||
}
|
||||
|
||||
function process_resources {
|
||||
## requires a virtualenv with pyside6
|
||||
## you can create it by doing 'mkvirtualenv -p python3 ogpyside6'
|
||||
## this will obviously go away in the future, but we need to merge the py3/qt6 change now
|
||||
~/.virtualenvs/ogpyside6/bin/pyside6-rcc -o OGAgent_rc.py OGAgent.qrc
|
||||
sed -i -e '/^from PySide6 import QtCore/s/PySide6/PyQt6/' OGAgent_rc.py
|
||||
}
|
||||
|
||||
cd $(dirname "$0")
|
||||
[ -r VERSION ] && sed -i "s/Version [^<]*/Version $(cat VERSION)/" about-dialog.ui
|
||||
pyrcc4 -py3 OGAgent.qrc -o OGAgent_rc.py
|
||||
|
||||
|
||||
# process current directory ui's
|
||||
process
|
||||
|
||||
update_version
|
||||
process_ui
|
||||
process_resources
|
||||
|
|
|
@ -2,5 +2,6 @@ C:
|
|||
CD \ogagent\src
|
||||
python setup.py
|
||||
CD ..
|
||||
RENAME bin\OGAgentUser-qt4.exe OGAgentUser.exe
|
||||
"C:\Program Files\NSIS\makensis.exe" ogagent.nsi
|
||||
|
||||
|
|
Loading…
Reference in New Issue