1
0
mirror of https://github.com/naruxde/revpipycontrol.git synced 2025-11-08 15:43:52 +01:00

Mit revpislave zusammenf?hren

This commit is contained in:
2018-04-07 14:04:35 +02:00
32 changed files with 2688 additions and 497 deletions

256
doc/aclmanager.html Normal file
View File

@@ -0,0 +1,256 @@
<!DOCTYPE html>
<html><head>
<title>aclmanager</title>
<meta charset="UTF-8">
</head>
<body style="background-color:#FFFFFF;color:#000000"><a NAME="top" ID="top"></a>
<h1 style="background-color:#FFFFFF;color:#0000FF">
aclmanager</h1>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Global Attributes</h3>
<table>
<tr><td>_</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#AclManager">AclManager</a></td>
<td>Hauptfenster des ACL-Managers.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Functions</h3>
<table>
<tr><td>None</td></tr>
</table>
<hr /><hr />
<a NAME="AclManager" ID="AclManager"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">AclManager</h2>
<p>
Hauptfenster des ACL-Managers.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
ttk.Frame
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>acl</td></tr><tr><td>acltext</td></tr><tr><td>root</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Methods</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#AclManager.__init__">AclManager</a></td>
<td>Init RevPiOption-Class.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#AclManager.__get_acltext">__get_acltext</a></td>
<td>Getter fuer Leveltexte.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#AclManager.__set_acltext">__set_acltext</a></td>
<td>Setter fuer Leveltexte.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#AclManager._ask_delete">_ask_delete</a></td>
<td>L&#246;scht ein Eintrag der Liste.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#AclManager._changesdone">_changesdone</a></td>
<td>Pr&#252;ft ob sich die Einstellungen ge&#228;ndert haben.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#AclManager._checkback">_checkback</a></td>
<td>Springt bei Backspace in vorheriges Feld.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#AclManager._checkclose">_checkclose</a></td>
<td>Pr&#252;ft ob Fenster beendet werden soll.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#AclManager._checkdot">_checkdot</a></td>
<td>Pr&#252;ft auf .</td>
</tr><tr>
<td><a style="color:#0000FF" href="#AclManager._clearfields">_clearfields</a></td>
<td>Leert die Eingabefelder.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#AclManager._createwidgets">_createwidgets</a></td>
<td>Erstellt Widgets.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#AclManager._loadfields">_loadfields</a></td>
<td>&#220;bernimmt Listeneintrag in Editfelder.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#AclManager._refreshacls">_refreshacls</a></td>
<td>Leert die ACL Liste und f&#252;llt sie neu.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#AclManager._save">_save</a></td>
<td>&#220;bernimt die &#196;nderungen.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#AclManager._savefields">_savefields</a></td>
<td>&#220;bernimmt neuen ACL Eintrag.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#AclManager._status_editremove">_status_editremove</a></td>
<td>Setzt state der Buttons.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#AclManager.get_acl">get_acl</a></td>
<td>Gibt die Konfigurierten ACL zur&#252;ck.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="AclManager.__init__" ID="AclManager.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
AclManager (Constructor)</h3>
<b>AclManager</b>(<i>master, minlevel, maxlevel, acl_str="", readonly=False</i>)
<p>
Init RevPiOption-Class.
</p><dl>
<dt>Returns:</dt>
<dd>
None
</dd>
</dl><a NAME="AclManager.__get_acltext" ID="AclManager.__get_acltext"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
AclManager.__get_acltext</h3>
<b>__get_acltext</b>(<i></i>)
<p>
Getter fuer Leveltexte.
</p><dl>
<dt>Returns:</dt>
<dd>
Leveltexte als <class 'dict'>
</dd>
</dl><a NAME="AclManager.__set_acltext" ID="AclManager.__set_acltext"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
AclManager.__set_acltext</h3>
<b>__set_acltext</b>(<i>value</i>)
<p>
Setter fuer Leveltexte.
</p><dl>
<dt><i>value</i></dt>
<dd>
Leveltexte als <class 'dict'>
</dd>
</dl><a NAME="AclManager._ask_delete" ID="AclManager._ask_delete"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
AclManager._ask_delete</h3>
<b>_ask_delete</b>(<i></i>)
<p>
L&#246;scht ein Eintrag der Liste.
</p><a NAME="AclManager._changesdone" ID="AclManager._changesdone"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
AclManager._changesdone</h3>
<b>_changesdone</b>(<i></i>)
<p>
Pr&#252;ft ob sich die Einstellungen ge&#228;ndert haben.
</p><dl>
<dt>Returns:</dt>
<dd>
True, wenn min. eine Einstellung ge&#228;ndert wurde
</dd>
</dl><a NAME="AclManager._checkback" ID="AclManager._checkback"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
AclManager._checkback</h3>
<b>_checkback</b>(<i>event, tkvar, pretxt</i>)
<p>
Springt bei Backspace in vorheriges Feld.
</p><dl>
<dt><i>event</i></dt>
<dd>
TK Event
</dd><dt><i>tkvar</i></dt>
<dd>
TK Variable zum pr&#252;fen
</dd><dt><i>nexttxt</i></dt>
<dd>
Vorheriges IP Feld f&#252;r Fokus
</dd>
</dl><a NAME="AclManager._checkclose" ID="AclManager._checkclose"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
AclManager._checkclose</h3>
<b>_checkclose</b>(<i>event=None</i>)
<p>
Pr&#252;ft ob Fenster beendet werden soll.
</p><dl>
<dt><i>event</i></dt>
<dd>
tkinter-Event
</dd>
</dl><a NAME="AclManager._checkdot" ID="AclManager._checkdot"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
AclManager._checkdot</h3>
<b>_checkdot</b>(<i>event, tkvar, nexttxt</i>)
<p>
Pr&#252;ft auf . und geht weiter.
</p><dl>
<dt><i>event</i></dt>
<dd>
TK Event
</dd><dt><i>tkvar</i></dt>
<dd>
TK Variable zum pr&#252;fen
</dd><dt><i>nexttxt</i></dt>
<dd>
N&#228;chstes IP Feld f&#252;r Fokus
</dd>
</dl><a NAME="AclManager._clearfields" ID="AclManager._clearfields"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
AclManager._clearfields</h3>
<b>_clearfields</b>(<i></i>)
<p>
Leert die Eingabefelder.
</p><a NAME="AclManager._createwidgets" ID="AclManager._createwidgets"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
AclManager._createwidgets</h3>
<b>_createwidgets</b>(<i></i>)
<p>
Erstellt Widgets.
</p><a NAME="AclManager._loadfields" ID="AclManager._loadfields"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
AclManager._loadfields</h3>
<b>_loadfields</b>(<i></i>)
<p>
&#220;bernimmt Listeneintrag in Editfelder.
</p><a NAME="AclManager._refreshacls" ID="AclManager._refreshacls"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
AclManager._refreshacls</h3>
<b>_refreshacls</b>(<i></i>)
<p>
Leert die ACL Liste und f&#252;llt sie neu.
</p><a NAME="AclManager._save" ID="AclManager._save"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
AclManager._save</h3>
<b>_save</b>(<i></i>)
<p>
&#220;bernimt die &#196;nderungen.
</p><a NAME="AclManager._savefields" ID="AclManager._savefields"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
AclManager._savefields</h3>
<b>_savefields</b>(<i></i>)
<p>
&#220;bernimmt neuen ACL Eintrag.
</p><a NAME="AclManager._status_editremove" ID="AclManager._status_editremove"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
AclManager._status_editremove</h3>
<b>_status_editremove</b>(<i>tkevt</i>)
<p>
Setzt state der Buttons.
</p><a NAME="AclManager.get_acl" ID="AclManager.get_acl"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
AclManager.get_acl</h3>
<b>get_acl</b>(<i></i>)
<p>
Gibt die Konfigurierten ACL zur&#252;ck.
</p><dl>
<dt>Returns:</dt>
<dd>
ACL als <class 'str'>
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr />
</body></html>

View File

@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html><head>
<title>revpipycontrol.shared</title>
<meta charset="UTF-8">
</head>
<body style="background-color:#FFFFFF;color:#000000">
<h1 style="background-color:#FFFFFF;color:#0000FF">
revpipycontrol.shared</h1>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Modules</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="revpipycontrol.shared.ipaclmanager.html">ipaclmanager</a></td>
<td>Verwaltet IP Adressen und deren ACLs.</td>
</tr>
</table>
</body></html>

View File

@@ -8,20 +8,34 @@
Table of contents</h1>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Packages</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="index-revpipycontrol.shared.html">shared</a></td>
<td></td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Modules</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="mytools.html">mytools</a></td>
<td><a style="color:#0000FF" href="aclmanager.html">aclmanager</a></td>
<td></td>
</tr><tr>
<td><a style="color:#0000FF" href="mytools.html">mytools</a></td>
<td>Tools-Sammlung.</td>
</tr><tr>
<td><a style="color:#0000FF" href="revpicheckclient.html">revpicheckclient</a></td>
<td></td>
</tr><tr>
<td><a style="color:#0000FF" href="revpiinfo.html">revpiinfo</a></td>
<td></td>
</tr><tr>
<td><a style="color:#0000FF" href="revpilegacy.html">revpilegacy</a></td>
<td></td>
</tr><tr>
<td><a style="color:#0000FF" href="revpilogfile.html">revpilogfile</a></td>
<td></td>
</tr><tr>

View File

@@ -6,11 +6,13 @@
<body style="background-color:#FFFFFF;color:#000000"><a NAME="top" ID="top"></a>
<h1 style="background-color:#FFFFFF;color:#0000FF">
mytools</h1>
<p>
Tools-Sammlung.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Global Attributes</h3>
<table>
<tr><td>None</td></tr>
<tr><td>savefile_connections</td></tr><tr><td>savefile_programpath</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3>
@@ -25,7 +27,7 @@ Functions</h3>
<td>H&#228;ngt root-dir der Anwendung vor Dateinamen.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#gettrans">gettrans</a></td>
<td></td>
<td>Wertet die Sprache des OS aus und gibt &#220;bersetzung zur&#252;ck.</td>
</tr>
</table>
<hr /><hr />
@@ -53,7 +55,19 @@ root dir
<a NAME="gettrans" ID="gettrans"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">gettrans</h2>
<b>gettrans</b>(<i>proglang=None</i>)
<p>
Wertet die Sprache des OS aus und gibt &#220;bersetzung zur&#252;ck.
</p><dl>
<dt><i>proglang</i></dt>
<dd>
Bestimmte Sprache laden
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
gettext &#220;bersetzung f&#252;r Zuweisung an '_'
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr />
</body></html>

View File

@@ -17,7 +17,7 @@ Classes</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#RevPiCheckClient">RevPiCheckClient</a></td>
<td></td>
<td>Baut Fenstererweiterung f&#252;r 'watch modus'.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
@@ -28,7 +28,9 @@ Functions</h3>
<hr /><hr />
<a NAME="RevPiCheckClient" ID="RevPiCheckClient"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">RevPiCheckClient</h2>
<p>
Baut Fenstererweiterung f&#252;r 'watch modus'.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
tkinter.Frame

View File

@@ -17,7 +17,7 @@ Classes</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#RevPiInfo">RevPiInfo</a></td>
<td></td>
<td>Baut Frame f&#252;r Programminformationen.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
@@ -28,7 +28,9 @@ Functions</h3>
<hr /><hr />
<a NAME="RevPiInfo" ID="RevPiInfo"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">RevPiInfo</h2>
<p>
Baut Frame f&#252;r Programminformationen.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
tkinter.Frame

166
doc/revpilegacy.html Normal file
View File

@@ -0,0 +1,166 @@
<!DOCTYPE html>
<html><head>
<title>revpilegacy</title>
<meta charset="UTF-8">
</head>
<body style="background-color:#FFFFFF;color:#000000"><a NAME="top" ID="top"></a>
<h1 style="background-color:#FFFFFF;color:#0000FF">
revpilegacy</h1>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Global Attributes</h3>
<table>
<tr><td>_</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#RevPiOption">RevPiOption</a></td>
<td>Optionen f&#252;r RevPiPyload vor 0.6.0.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Functions</h3>
<table>
<tr><td>None</td></tr>
</table>
<hr /><hr />
<a NAME="RevPiOption" ID="RevPiOption"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">RevPiOption</h2>
<p>
Optionen f&#252;r RevPiPyload vor 0.6.0.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
tkinter.Frame
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Methods</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#RevPiOption.__init__">RevPiOption</a></td>
<td>Init RevPiOption-Class.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiOption._changesdone">_changesdone</a></td>
<td>Pr&#252;ft ob sich die Einstellungen ge&#228;ndert haben.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiOption._checkclose">_checkclose</a></td>
<td>Pr&#252;ft ob Fenster beendet werden soll.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiOption._createwidgets">_createwidgets</a></td>
<td>Erstellt Widgets.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiOption._loadappdata">_loadappdata</a></td>
<td>L&#228;d aktuelle Einstellungen vom RevPi.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiOption._setappdata">_setappdata</a></td>
<td>Speichert ge&#228;nderte Einstellungen auf RevPi.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiOption.askxmlon">askxmlon</a></td>
<td>Fragt Nuter, ob wirklicht abgeschaltet werden soll.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiOption.xmlmod2_tail">xmlmod2_tail</a></td>
<td>Passt XML-Optionszugriff an.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiOption.xmlmod_tail">xmlmod_tail</a></td>
<td>Passt XML-Optionszugriff an.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="RevPiOption.__init__" ID="RevPiOption.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiOption (Constructor)</h3>
<b>RevPiOption</b>(<i>master, xmlcli</i>)
<p>
Init RevPiOption-Class.
</p><dl>
<dt>Returns:</dt>
<dd>
None
</dd>
</dl><a NAME="RevPiOption._changesdone" ID="RevPiOption._changesdone"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiOption._changesdone</h3>
<b>_changesdone</b>(<i></i>)
<p>
Pr&#252;ft ob sich die Einstellungen ge&#228;ndert haben.
</p><dl>
<dt>Returns:</dt>
<dd>
True, wenn min. eine Einstellung ge&#228;ndert wurde
</dd>
</dl><a NAME="RevPiOption._checkclose" ID="RevPiOption._checkclose"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiOption._checkclose</h3>
<b>_checkclose</b>(<i>event=None</i>)
<p>
Pr&#252;ft ob Fenster beendet werden soll.
</p><dl>
<dt><i>event</i></dt>
<dd>
tkinter-Event
</dd>
</dl><a NAME="RevPiOption._createwidgets" ID="RevPiOption._createwidgets"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiOption._createwidgets</h3>
<b>_createwidgets</b>(<i></i>)
<p>
Erstellt Widgets.
</p><a NAME="RevPiOption._loadappdata" ID="RevPiOption._loadappdata"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiOption._loadappdata</h3>
<b>_loadappdata</b>(<i>refresh=False</i>)
<p>
L&#228;d aktuelle Einstellungen vom RevPi.
</p><dl>
<dt><i>refresh</i></dt>
<dd>
Wenn True, werden Einstellungen heruntergeladen.
</dd>
</dl><a NAME="RevPiOption._setappdata" ID="RevPiOption._setappdata"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiOption._setappdata</h3>
<b>_setappdata</b>(<i></i>)
<p>
Speichert ge&#228;nderte Einstellungen auf RevPi.
</p><dl>
<dt>Returns:</dt>
<dd>
None
</dd>
</dl><a NAME="RevPiOption.askxmlon" ID="RevPiOption.askxmlon"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiOption.askxmlon</h3>
<b>askxmlon</b>(<i></i>)
<p>
Fragt Nuter, ob wirklicht abgeschaltet werden soll.
</p><a NAME="RevPiOption.xmlmod2_tail" ID="RevPiOption.xmlmod2_tail"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiOption.xmlmod2_tail</h3>
<b>xmlmod2_tail</b>(<i></i>)
<p>
Passt XML-Optionszugriff an.
</p><a NAME="RevPiOption.xmlmod_tail" ID="RevPiOption.xmlmod_tail"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiOption.xmlmod_tail</h3>
<b>xmlmod_tail</b>(<i></i>)
<p>
Passt XML-Optionszugriff an.
</p>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr />
</body></html>

View File

@@ -17,7 +17,7 @@ Classes</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#RevPiLogfile">RevPiLogfile</a></td>
<td></td>
<td>Baut Fenster f&#252;r Logfiles.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
@@ -28,7 +28,9 @@ Functions</h3>
<hr /><hr />
<a NAME="RevPiLogfile" ID="RevPiLogfile"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">RevPiLogfile</h2>
<p>
Baut Fenster f&#252;r Logfiles.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
tkinter.Frame

View File

@@ -17,7 +17,7 @@ Classes</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#RevPiOption">RevPiOption</a></td>
<td></td>
<td>Zeigt Optionen von RevPiPyLoad an.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
@@ -28,7 +28,9 @@ Functions</h3>
<hr /><hr />
<a NAME="RevPiOption" ID="RevPiOption"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">RevPiOption</h2>
<p>
Zeigt Optionen von RevPiPyLoad an.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
tkinter.Frame
@@ -55,6 +57,9 @@ Methods</h3>
<td><a style="color:#0000FF" href="#RevPiOption._checkclose">_checkclose</a></td>
<td>Pr&#252;ft ob Fenster beendet werden soll.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiOption._checkvalues">_checkvalues</a></td>
<td>Pr&#252;ft alle Werte auf G&#252;ltigkeit.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiOption._createwidgets">_createwidgets</a></td>
<td>Erstellt Widgets.</td>
</tr><tr>
@@ -67,11 +72,11 @@ Methods</h3>
<td><a style="color:#0000FF" href="#RevPiOption.askxmlon">askxmlon</a></td>
<td>Fragt Nuter, ob wirklicht abgeschaltet werden soll.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiOption.xmlmod2_tail">xmlmod2_tail</a></td>
<td>Passt XML-Optionszugriff an.</td>
<td><a style="color:#0000FF" href="#RevPiOption.btn_slaveacl">btn_slaveacl</a></td>
<td>&#214;ffnet Fenster f&#252;r ACL-Verwaltung.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiOption.xmlmod_tail">xmlmod_tail</a></td>
<td>Passt XML-Optionszugriff an.</td>
<td><a style="color:#0000FF" href="#RevPiOption.btn_xmlacl">btn_xmlacl</a></td>
<td>&#214;ffnet Fenster f&#252;r ACL-Verwaltung.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
@@ -112,6 +117,17 @@ Pr&#252;ft ob Fenster beendet werden soll.
<dd>
tkinter-Event
</dd>
</dl><a NAME="RevPiOption._checkvalues" ID="RevPiOption._checkvalues"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiOption._checkvalues</h3>
<b>_checkvalues</b>(<i></i>)
<p>
Pr&#252;ft alle Werte auf G&#252;ltigkeit.
</p><dl>
<dt>Returns:</dt>
<dd>
True, wenn alle Werte g&#252;ltig sind
</dd>
</dl><a NAME="RevPiOption._createwidgets" ID="RevPiOption._createwidgets"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiOption._createwidgets</h3>
@@ -146,18 +162,18 @@ RevPiOption.askxmlon</h3>
<b>askxmlon</b>(<i></i>)
<p>
Fragt Nuter, ob wirklicht abgeschaltet werden soll.
</p><a NAME="RevPiOption.xmlmod2_tail" ID="RevPiOption.xmlmod2_tail"></a>
</p><a NAME="RevPiOption.btn_slaveacl" ID="RevPiOption.btn_slaveacl"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiOption.xmlmod2_tail</h3>
<b>xmlmod2_tail</b>(<i></i>)
RevPiOption.btn_slaveacl</h3>
<b>btn_slaveacl</b>(<i></i>)
<p>
Passt XML-Optionszugriff an.
</p><a NAME="RevPiOption.xmlmod_tail" ID="RevPiOption.xmlmod_tail"></a>
&#214;ffnet Fenster f&#252;r ACL-Verwaltung.
</p><a NAME="RevPiOption.btn_xmlacl" ID="RevPiOption.btn_xmlacl"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiOption.xmlmod_tail</h3>
<b>xmlmod_tail</b>(<i></i>)
RevPiOption.btn_xmlacl</h3>
<b>btn_xmlacl</b>(<i></i>)
<p>
Passt XML-Optionszugriff an.
&#214;ffnet Fenster f&#252;r ACL-Verwaltung.
</p>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr />

164
doc/revpioptionlegacy.html Normal file
View File

@@ -0,0 +1,164 @@
<!DOCTYPE html>
<html><head>
<title>revpioptionlegacy</title>
<meta charset="UTF-8">
</head>
<body style="background-color:#FFFFFF;color:#000000"><a NAME="top" ID="top"></a>
<h1 style="background-color:#FFFFFF;color:#0000FF">
revpioptionlegacy</h1>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Global Attributes</h3>
<table>
<tr><td>_</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#RevPiOption">RevPiOption</a></td>
<td></td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Functions</h3>
<table>
<tr><td>None</td></tr>
</table>
<hr /><hr />
<a NAME="RevPiOption" ID="RevPiOption"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">RevPiOption</h2>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
tkinter.Frame
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Methods</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#RevPiOption.__init__">RevPiOption</a></td>
<td>Init RevPiOption-Class.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiOption._changesdone">_changesdone</a></td>
<td>Pr&#252;ft ob sich die Einstellungen ge&#228;ndert haben.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiOption._checkclose">_checkclose</a></td>
<td>Pr&#252;ft ob Fenster beendet werden soll.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiOption._createwidgets">_createwidgets</a></td>
<td>Erstellt Widgets.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiOption._loadappdata">_loadappdata</a></td>
<td>L&#228;d aktuelle Einstellungen vom RevPi.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiOption._setappdata">_setappdata</a></td>
<td>Speichert ge&#228;nderte Einstellungen auf RevPi.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiOption.askxmlon">askxmlon</a></td>
<td>Fragt Nuter, ob wirklicht abgeschaltet werden soll.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiOption.xmlmod2_tail">xmlmod2_tail</a></td>
<td>Passt XML-Optionszugriff an.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiOption.xmlmod_tail">xmlmod_tail</a></td>
<td>Passt XML-Optionszugriff an.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="RevPiOption.__init__" ID="RevPiOption.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiOption (Constructor)</h3>
<b>RevPiOption</b>(<i>master, xmlcli</i>)
<p>
Init RevPiOption-Class.
</p><dl>
<dt>Returns:</dt>
<dd>
None
</dd>
</dl><a NAME="RevPiOption._changesdone" ID="RevPiOption._changesdone"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiOption._changesdone</h3>
<b>_changesdone</b>(<i></i>)
<p>
Pr&#252;ft ob sich die Einstellungen ge&#228;ndert haben.
</p><dl>
<dt>Returns:</dt>
<dd>
True, wenn min. eine Einstellung ge&#228;ndert wurde
</dd>
</dl><a NAME="RevPiOption._checkclose" ID="RevPiOption._checkclose"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiOption._checkclose</h3>
<b>_checkclose</b>(<i>event=None</i>)
<p>
Pr&#252;ft ob Fenster beendet werden soll.
</p><dl>
<dt><i>event</i></dt>
<dd>
tkinter-Event
</dd>
</dl><a NAME="RevPiOption._createwidgets" ID="RevPiOption._createwidgets"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiOption._createwidgets</h3>
<b>_createwidgets</b>(<i></i>)
<p>
Erstellt Widgets.
</p><a NAME="RevPiOption._loadappdata" ID="RevPiOption._loadappdata"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiOption._loadappdata</h3>
<b>_loadappdata</b>(<i>refresh=False</i>)
<p>
L&#228;d aktuelle Einstellungen vom RevPi.
</p><dl>
<dt><i>refresh</i></dt>
<dd>
Wenn True, werden Einstellungen heruntergeladen.
</dd>
</dl><a NAME="RevPiOption._setappdata" ID="RevPiOption._setappdata"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiOption._setappdata</h3>
<b>_setappdata</b>(<i></i>)
<p>
Speichert ge&#228;nderte Einstellungen auf RevPi.
</p><dl>
<dt>Returns:</dt>
<dd>
None
</dd>
</dl><a NAME="RevPiOption.askxmlon" ID="RevPiOption.askxmlon"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiOption.askxmlon</h3>
<b>askxmlon</b>(<i></i>)
<p>
Fragt Nuter, ob wirklicht abgeschaltet werden soll.
</p><a NAME="RevPiOption.xmlmod2_tail" ID="RevPiOption.xmlmod2_tail"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiOption.xmlmod2_tail</h3>
<b>xmlmod2_tail</b>(<i></i>)
<p>
Passt XML-Optionszugriff an.
</p><a NAME="RevPiOption.xmlmod_tail" ID="RevPiOption.xmlmod_tail"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiOption.xmlmod_tail</h3>
<b>xmlmod_tail</b>(<i></i>)
<p>
Passt XML-Optionszugriff an.
</p>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr />
</body></html>

View File

@@ -10,14 +10,14 @@ revpiplclist</h1>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Global Attributes</h3>
<table>
<tr><td>_</td></tr><tr><td>savefile</td></tr>
<tr><td>_</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#RevPiPlcList">RevPiPlcList</a></td>
<td></td>
<td>TK Fenster.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
@@ -31,7 +31,9 @@ Functions</h3>
<hr /><hr />
<a NAME="RevPiPlcList" ID="RevPiPlcList"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">RevPiPlcList</h2>
<p>
TK Fenster.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
tkinter.Frame

View File

@@ -10,25 +10,33 @@ revpiprogram</h1>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Global Attributes</h3>
<table>
<tr><td>_</td></tr><tr><td>savefile</td></tr>
<tr><td>_</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#RevPiProgram">RevPiProgram</a></td>
<td></td>
<td>Zeigt Programmfenster an.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Functions</h3>
<table>
<tr><td>None</td></tr>
<tr>
<td><a style="color:#0000FF" href="#_loaddefaults">_loaddefaults</a></td>
<td>&#220;bernimmt f&#252;r den Pi die letzen Pfade.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#_savedefaults">_savedefaults</a></td>
<td>Schreibt fuer den Pi die letzen Pfade.</td>
</tr>
</table>
<hr /><hr />
<a NAME="RevPiProgram" ID="RevPiProgram"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">RevPiProgram</h2>
<p>
Zeigt Programmfenster an.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
tkinter.Frame
@@ -61,12 +69,6 @@ Methods</h3>
<td><a style="color:#0000FF" href="#RevPiProgram._evt_optup">_evt_optup</a></td>
<td>Passt je nach gew&#228;hlter Option den Status der Widgets an.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiProgram._loaddefault">_loaddefault</a></td>
<td>&#220;bernimmt f&#252;r den Pi die letzen Pfade.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiProgram._savedefaults">_savedefaults</a></td>
<td>Schreibt fuer den Pi die letzen Pfade.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiProgram.check_replacedir">check_replacedir</a></td>
<td>Gibt das rootdir von einem entpackten Verzeichnis zurueck.</td>
</tr><tr>
@@ -137,34 +139,7 @@ RevPiProgram._evt_optup</h3>
<b>_evt_optup</b>(<i>text=""</i>)
<p>
Passt je nach gew&#228;hlter Option den Status der Widgets an.
</p><a NAME="RevPiProgram._loaddefault" ID="RevPiProgram._loaddefault"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiProgram._loaddefault</h3>
<b>_loaddefault</b>(<i>full=False</i>)
<p>
&#220;bernimmt f&#252;r den Pi die letzen Pfade.
</p><dl>
<dt><i>full</i></dt>
<dd>
Einstellungen f&#252;r alle Verbindungen laden
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
dict() mit Einstellungen
</dd>
</dl><a NAME="RevPiProgram._savedefaults" ID="RevPiProgram._savedefaults"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiProgram._savedefaults</h3>
<b>_savedefaults</b>(<i></i>)
<p>
Schreibt fuer den Pi die letzen Pfade.
</p><dl>
<dt>Returns:</dt>
<dd>
True, bei erfolgreicher Verarbeitung
</dd>
</dl><a NAME="RevPiProgram.check_replacedir" ID="RevPiProgram.check_replacedir"></a>
</p><a NAME="RevPiProgram.check_replacedir" ID="RevPiProgram.check_replacedir"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiProgram.check_replacedir</h3>
<b>check_replacedir</b>(<i>rootdir</i>)
@@ -242,5 +217,44 @@ RevPiProgram.setpictoryrsc</h3>
&#220;bertr&#228;gt die angegebene piCtory-Konfiguration.
</p>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
<a NAME="_loaddefaults" ID="_loaddefaults"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">_loaddefaults</h2>
<b>_loaddefaults</b>(<i>revpiname=None</i>)
<p>
&#220;bernimmt f&#252;r den Pi die letzen Pfade.
</p><dl>
<dt><i>revpiname</i></dt>
<dd>
Einstellungen nur f&#252;r RevPi laden
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
<class 'dict'> mit Einstellungen
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
<a NAME="_savedefaults" ID="_savedefaults"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">_savedefaults</h2>
<b>_savedefaults</b>(<i>revpiname, settings</i>)
<p>
Schreibt fuer den Pi die letzen Pfade.
</p><dl>
<dt><i>revpiname</i></dt>
<dd>
Einstellungen sind f&#252;r diesen RevPi
</dd><dt><i>settings</i></dt>
<dd>
<class 'dict'> mit Einstellungen
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
True, bei erfolgreicher Verarbeitung
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr />
</body></html>

View File

@@ -17,7 +17,7 @@ Classes</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#RevPiPyControl">RevPiPyControl</a></td>
<td></td>
<td>Baut Hauptprogramm auf.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
@@ -28,7 +28,9 @@ Functions</h3>
<hr /><hr />
<a NAME="RevPiPyControl" ID="RevPiPyControl"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">RevPiPyControl</h2>
<p>
Baut Hauptprogramm auf.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
tkinter.Frame

View File

@@ -0,0 +1,239 @@
<!DOCTYPE html>
<html><head>
<title>revpipycontrol.shared.ipaclmanager</title>
<meta charset="UTF-8">
</head>
<body style="background-color:#FFFFFF;color:#000000"><a NAME="top" ID="top"></a>
<h1 style="background-color:#FFFFFF;color:#0000FF">
revpipycontrol.shared.ipaclmanager</h1>
<p>
Verwaltet IP Adressen und deren ACLs.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Global Attributes</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#IpAclManager">IpAclManager</a></td>
<td>Verwaltung fuer IP Adressen und deren ACL Level.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Functions</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#refullmatch">refullmatch</a></td>
<td>re.fullmatch wegen alter python version aus wheezy nachgebaut.</td>
</tr>
</table>
<hr /><hr />
<a NAME="IpAclManager" ID="IpAclManager"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">IpAclManager</h2>
<p>
Verwaltung fuer IP Adressen und deren ACL Level.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
None
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>acl</td></tr><tr><td>filename</td></tr><tr><td>regex_acl</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Methods</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#IpAclManager.__init__">IpAclManager</a></td>
<td>Init IpAclManager class.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IpAclManager.__get_acl">__get_acl</a></td>
<td>Getter fuer den rohen ACL-String.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IpAclManager.__get_filename">__get_filename</a></td>
<td>Getter fuer Dateinamen.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IpAclManager.__get_regex_acl">__get_regex_acl</a></td>
<td>Gibt formatierten RegEx-String zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IpAclManager.__iter__">__iter__</a></td>
<td>Gibt einzelne ACLs als <class 'tuple'> aus.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IpAclManager.__set_acl">__set_acl</a></td>
<td>Uebernimmt neue ACL-Liste fuer die Ausertung der Level.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IpAclManager.get_acllevel">get_acllevel</a></td>
<td>Prueft IP gegen ACL List und gibt ACL-Wert aus.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IpAclManager.loadacl">loadacl</a></td>
<td>Laed ACL String und gibt erfolg zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IpAclManager.loadaclfile">loadaclfile</a></td>
<td>Laed ACL Definitionen aus Datei.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IpAclManager.writeaclfile">writeaclfile</a></td>
<td>Schreibt ACL Definitionen in Datei.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="IpAclManager.__init__" ID="IpAclManager.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IpAclManager (Constructor)</h3>
<b>IpAclManager</b>(<i>minlevel, maxlevel, acl=None</i>)
<p>
Init IpAclManager class.
</p><dl>
<dt><i>minlevel</i></dt>
<dd>
Smallest access level (min. 0)
</dd><dt><i>maxlevel</i></dt>
<dd>
Biggest access level (max. 9)
</dd><dt><i>acl</i></dt>
<dd>
ACL Liste fuer Berechtigungen als <class 'str'>
</dd>
</dl><a NAME="IpAclManager.__get_acl" ID="IpAclManager.__get_acl"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IpAclManager.__get_acl</h3>
<b>__get_acl</b>(<i></i>)
<p>
Getter fuer den rohen ACL-String.
return ACLs als <class 'str'>
</p><a NAME="IpAclManager.__get_filename" ID="IpAclManager.__get_filename"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IpAclManager.__get_filename</h3>
<b>__get_filename</b>(<i></i>)
<p>
Getter fuer Dateinamen.
</p><dl>
<dt>Returns:</dt>
<dd>
Filename der ACL <class 'str'>
</dd>
</dl><a NAME="IpAclManager.__get_regex_acl" ID="IpAclManager.__get_regex_acl"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IpAclManager.__get_regex_acl</h3>
<b>__get_regex_acl</b>(<i></i>)
<p>
Gibt formatierten RegEx-String zurueck.
return RegEx Code als <class 'str'>
</p><a NAME="IpAclManager.__iter__" ID="IpAclManager.__iter__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IpAclManager.__iter__</h3>
<b>__iter__</b>(<i></i>)
<p>
Gibt einzelne ACLs als <class 'tuple'> aus.
</p><a NAME="IpAclManager.__set_acl" ID="IpAclManager.__set_acl"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IpAclManager.__set_acl</h3>
<b>__set_acl</b>(<i>value</i>)
<p>
Uebernimmt neue ACL-Liste fuer die Ausertung der Level.
</p><dl>
<dt><i>value</i></dt>
<dd>
Neue ACL-Liste als <class 'str'>
</dd>
</dl><a NAME="IpAclManager.get_acllevel" ID="IpAclManager.get_acllevel"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IpAclManager.get_acllevel</h3>
<b>get_acllevel</b>(<i>ipaddress</i>)
<p>
Prueft IP gegen ACL List und gibt ACL-Wert aus.
</p><dl>
<dt><i>ipaddress</i></dt>
<dd>
zum pruefen
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
<class 'int'> ACL Wert oder -1 wenn nicht gefunden
</dd>
</dl><a NAME="IpAclManager.loadacl" ID="IpAclManager.loadacl"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IpAclManager.loadacl</h3>
<b>loadacl</b>(<i>str_acl</i>)
<p>
Laed ACL String und gibt erfolg zurueck.
</p><dl>
<dt><i>str_acl</i></dt>
<dd>
ACL als <class 'str'>
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
True, wenn erfolgreich uebernommen
</dd>
</dl><a NAME="IpAclManager.loadaclfile" ID="IpAclManager.loadaclfile"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IpAclManager.loadaclfile</h3>
<b>loadaclfile</b>(<i>filename</i>)
<p>
Laed ACL Definitionen aus Datei.
</p><dl>
<dt><i>filename</i></dt>
<dd>
Dateiname fuer Definitionen
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
True, wenn Laden erfolgreich war
</dd>
</dl><a NAME="IpAclManager.writeaclfile" ID="IpAclManager.writeaclfile"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IpAclManager.writeaclfile</h3>
<b>writeaclfile</b>(<i>filename=None, aclname=None</i>)
<p>
Schreibt ACL Definitionen in Datei.
</p><dl>
<dt><i>filename</i></dt>
<dd>
Dateiname fuer Definitionen
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
True, wenn Schreiben erfolgreich war
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
<a NAME="refullmatch" ID="refullmatch"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">refullmatch</h2>
<b>refullmatch</b>(<i>regex, string</i>)
<p>
re.fullmatch wegen alter python version aus wheezy nachgebaut.
</p><dl>
<dt><i>regex</i></dt>
<dd>
RegEx Statement
</dd><dt><i>string</i></dt>
<dd>
Zeichenfolge gegen die getestet wird
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
True, wenn komplett passt sonst False
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr />
</body></html>

View File

@@ -1,5 +1,27 @@
aclmanager.AclManager.__get_acltext?6()
aclmanager.AclManager.__set_acltext?6(value)
aclmanager.AclManager._ask_delete?5()
aclmanager.AclManager._changesdone?5()
aclmanager.AclManager._checkback?5(event, tkvar, pretxt)
aclmanager.AclManager._checkclose?5(event=None)
aclmanager.AclManager._checkdot?5(event, tkvar, nexttxt)
aclmanager.AclManager._clearfields?5()
aclmanager.AclManager._createwidgets?5()
aclmanager.AclManager._loadfields?5()
aclmanager.AclManager._refreshacls?5()
aclmanager.AclManager._save?5()
aclmanager.AclManager._savefields?5()
aclmanager.AclManager._status_editremove?5(tkevt)
aclmanager.AclManager.acl?7
aclmanager.AclManager.acltext?7
aclmanager.AclManager.get_acl?4()
aclmanager.AclManager.root?7
aclmanager.AclManager?1(master, minlevel, maxlevel, acl_str="", readonly=False)
aclmanager._?8
mytools.addroot?4(filename)
mytools.gettrans?4(proglang=None)
mytools.savefile_connections?7
mytools.savefile_programpath?7
revpicheckclient.RevPiCheckClient.__chval?6(device, io, event=None)
revpicheckclient.RevPiCheckClient.__hidewin?6(win, event=None)
revpicheckclient.RevPiCheckClient.__saveoldvalue?6(event, tkvar)
@@ -26,6 +48,16 @@ revpiinfo.RevPiInfo._createwidgets?5(extended=False)
revpiinfo.RevPiInfo.visitwebsite?4(event=None)
revpiinfo.RevPiInfo?1(master, xmlcli, version)
revpiinfo._?8
revpilegacy.RevPiOption._changesdone?5()
revpilegacy.RevPiOption._checkclose?5(event=None)
revpilegacy.RevPiOption._createwidgets?5()
revpilegacy.RevPiOption._loadappdata?5(refresh=False)
revpilegacy.RevPiOption._setappdata?5()
revpilegacy.RevPiOption.askxmlon?4()
revpilegacy.RevPiOption.xmlmod2_tail?4()
revpilegacy.RevPiOption.xmlmod_tail?4()
revpilegacy.RevPiOption?1(master, xmlcli)
revpilegacy._?8
revpilogfile.RevPiLogfile._checkclose?5(event=None)
revpilogfile.RevPiLogfile._createwidgets?5()
revpilogfile.RevPiLogfile._load_log?5(textwidget, xmlcall, startposition, full)
@@ -37,12 +69,13 @@ revpilogfile.RevPiLogfile?1(master, xmlcli)
revpilogfile._?8
revpioption.RevPiOption._changesdone?5()
revpioption.RevPiOption._checkclose?5(event=None)
revpioption.RevPiOption._checkvalues?5()
revpioption.RevPiOption._createwidgets?5()
revpioption.RevPiOption._loadappdata?5(refresh=False)
revpioption.RevPiOption._setappdata?5()
revpioption.RevPiOption.askxmlon?4()
revpioption.RevPiOption.xmlmod2_tail?4()
revpioption.RevPiOption.xmlmod_tail?4()
revpioption.RevPiOption.btn_slaveacl?4()
revpioption.RevPiOption.btn_xmlacl?4()
revpioption.RevPiOption?1(master, xmlcli)
revpioption._?8
revpiplclist.RevPiPlcList._checkclose?5(event=None)
@@ -60,13 +93,10 @@ revpiplclist.RevPiPlcList.root?7
revpiplclist.RevPiPlcList?1(master)
revpiplclist._?8
revpiplclist.get_connections?4()
revpiplclist.savefile?7
revpiprogram.RevPiProgram._checkclose?5(event=None)
revpiprogram.RevPiProgram._createwidgets?5()
revpiprogram.RevPiProgram._evt_optdown?5(text="")
revpiprogram.RevPiProgram._evt_optup?5(text="")
revpiprogram.RevPiProgram._loaddefault?5(full=False)
revpiprogram.RevPiProgram._savedefaults?5()
revpiprogram.RevPiProgram.check_replacedir?4(rootdir)
revpiprogram.RevPiProgram.create_filelist?4(rootdir)
revpiprogram.RevPiProgram.getpictoryrsc?4()
@@ -77,7 +107,8 @@ revpiprogram.RevPiProgram.plcupload?4()
revpiprogram.RevPiProgram.setpictoryrsc?4(filename=None)
revpiprogram.RevPiProgram?1(master, xmlcli, xmlmode, revpi)
revpiprogram._?8
revpiprogram.savefile?7
revpiprogram._loaddefaults?5(revpiname=None)
revpiprogram._savedefaults?5(revpiname, settings)
revpipycontrol.RevPiPyControl._btnstate?5()
revpipycontrol.RevPiPyControl._closeall?5()
revpipycontrol.RevPiPyControl._closeapp?5(event=None)
@@ -103,3 +134,17 @@ revpipycontrol.RevPiPyControl.visitwebsite?4()
revpipycontrol.RevPiPyControl?1(master=None)
revpipycontrol._?8
revpipycontrol.pycontrolversion?7
revpipycontrol.shared.ipaclmanager.IpAclManager.__get_acl?6()
revpipycontrol.shared.ipaclmanager.IpAclManager.__get_filename?6()
revpipycontrol.shared.ipaclmanager.IpAclManager.__get_regex_acl?6()
revpipycontrol.shared.ipaclmanager.IpAclManager.__iter__?6()
revpipycontrol.shared.ipaclmanager.IpAclManager.__set_acl?6(value)
revpipycontrol.shared.ipaclmanager.IpAclManager.acl?7
revpipycontrol.shared.ipaclmanager.IpAclManager.filename?7
revpipycontrol.shared.ipaclmanager.IpAclManager.get_acllevel?4(ipaddress)
revpipycontrol.shared.ipaclmanager.IpAclManager.loadacl?4(str_acl)
revpipycontrol.shared.ipaclmanager.IpAclManager.loadaclfile?4(filename)
revpipycontrol.shared.ipaclmanager.IpAclManager.regex_acl?7
revpipycontrol.shared.ipaclmanager.IpAclManager.writeaclfile?4(filename=None, aclname=None)
revpipycontrol.shared.ipaclmanager.IpAclManager?1(minlevel, maxlevel, acl=None)
revpipycontrol.shared.ipaclmanager.refullmatch?4(regex, string)

View File

@@ -1,3 +1,4 @@
AclManager ttk.Frame
RevPiCheckClient tkinter.Frame
RevPiInfo tkinter.Frame
RevPiLogfile tkinter.Frame

View File

@@ -1,18 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Project SYSTEM "Project-5.1.dtd">
<!-- eric project file for project revpipycontrol -->
<!-- Saved: 2017-07-06, 13:33:38 -->
<!-- Copyright (C) 2017 Sven Sager, akira@narux.de -->
<!-- Saved: 2018-04-04, 15:41:50 -->
<!-- Copyright (C) 2018 Sven Sager, akira@narux.de -->
<Project version="5.1">
<Language>en_US</Language>
<Hash>66103e2eaf8a762f14d1fd51d8b1c9dcaf35a275</Hash>
<ProgLanguage mixed="0">Python3</ProgLanguage>
<ProjectType>Console</ProjectType>
<Description></Description>
<Version>0.4.2</Version>
<Version>0.6.0</Version>
<Author>Sven Sager</Author>
<Email>akira@narux.de</Email>
<Eol index="-1"/>
<Eol index="1"/>
<Sources>
<Source>revpipycontrol/revpipycontrol.py</Source>
<Source>revpipycontrol/revpicheckclient.py</Source>
@@ -23,6 +23,10 @@
<Source>revpipycontrol/revpiprogram.py</Source>
<Source>revpipycontrol/mytools.py</Source>
<Source>revpipycontrol/revpiinfo.py</Source>
<Source>revpipycontrol/aclmanager.py</Source>
<Source>revpipycontrol/revpilegacy.py</Source>
<Source>revpipycontrol/shared/ipaclmanager.py</Source>
<Source>revpipycontrol/shared/__init__.py</Source>
</Sources>
<Forms/>
<Translations/>

View File

@@ -0,0 +1,393 @@
# -*- coding: utf-8 -*-
#
# RevPiPyControl
#
# Webpage: https://revpimodio.org/revpipyplc/
# (c) Sven Sager, License: LGPLv3
#
u"""Manager für ACL Einträge."""
import tkinter
import tkinter.messagebox as tkmsg
from mytools import gettrans
from shared.ipaclmanager import IpAclManager
from tkinter import ttk
# Übersetzung laden
_ = gettrans()
class AclManager(ttk.Frame):
u"""Hauptfenster des ACL-Managers."""
def __init__(self, master, minlevel, maxlevel, acl_str="", readonly=False):
u"""Init RevPiOption-Class.
@return None"""
super().__init__(master)
self.master.bind("<KeyPress-Escape>", self._checkclose)
self.master.protocol("WM_DELETE_WINDOW", self._checkclose)
self.pack(expand=True, fill="both")
# Daten laden
self.__acl = IpAclManager(minlevel, maxlevel, acl_str)
self.__dict_acltext = {}
self.__oldacl = self.__acl.acl
self.__ro = "disabled" if readonly else "normal"
self.maxlevel = maxlevel
self.minlevel = minlevel
# Fenster bauen
self._createwidgets()
def __get_acltext(self):
"""Getter fuer Leveltexte.
@return Leveltexte als <class 'dict'>"""
return self.__dict_acltext.copy()
def __set_acltext(self, value):
"""Setter fuer Leveltexte.
@param value Leveltexte als <class 'dict'>"""
if type(value) != dict:
raise ValueError("value must be <class 'dict'>")
self.__dict_acltext = value.copy()
# Infotexte aufbauen
self.aclinfo.destroy()
self.aclinfo = ttk.Frame(self)
for acltext in self.__dict_acltext:
lbl = ttk.Label(self.aclinfo)
lbl["text"] = _("Level") + " {}: {}".format(
acltext, self.__dict_acltext[acltext]
)
lbl.pack(anchor="w")
self.aclinfo.pack(anchor="w", padx=4, pady=4)
def _changesdone(self):
u"""Prüft ob sich die Einstellungen geändert haben.
@return True, wenn min. eine Einstellung geändert wurde"""
return not self.__acl.acl == self.__oldacl
def _checkclose(self, event=None):
u"""Prüft ob Fenster beendet werden soll.
@param event tkinter-Event"""
ask = True
if self._changesdone():
ask = tkmsg.askyesno(
_("Question"),
_("Do you really want to quit? \nUnsaved changes will "
"be lost"),
parent=self.master, default="no"
)
if ask:
self.master.destroy()
def _createwidgets(self):
u"""Erstellt Widgets."""
self.master.wm_title(_("IP access control list"))
self.master.wm_resizable(width=False, height=False)
cpadw = {"padx": 4, "pady": 2, "sticky": "w"}
# Gruppe Bestehende ACL ######################################
gb_acl = ttk.LabelFrame(self)
gb_acl["text"] = _("Existing ACLs")
gb_acl.columnconfigure(0, weight=1)
gb_acl.columnconfigure(1, weight=1)
gb_acl.pack(expand=True, fill="both", padx=4, pady=4)
row = 0
frame = ttk.Frame(gb_acl)
frame.columnconfigure(0, weight=1)
scb_acl = ttk.Scrollbar(frame)
self.trv_acl = ttk.Treeview(frame)
self.trv_acl["columns"] = ("level")
self.trv_acl["yscrollcommand"] = scb_acl.set
self.trv_acl.heading("level", text=_("Access level"))
self.trv_acl.column("level", width=100)
self.trv_acl.bind("<<TreeviewSelect>>", self._status_editremove)
self._refreshacls()
self.trv_acl.grid(row=0, column=0, sticky="we")
scb_acl["command"] = self.trv_acl.yview
scb_acl.grid(row=0, column=1, sticky="ns")
frame.grid(row=row, columnspan=2, sticky="we")
row = 1
# Edit / Remove button
self.btn_edit = ttk.Button(gb_acl)
self.btn_edit["command"] = self._loadfields
self.btn_edit["text"] = _("load entry")
self.btn_edit["state"] = "disabled"
self.btn_edit.grid(row=row, column=0, pady=4)
self.btn_remove = ttk.Button(gb_acl)
self.btn_remove["command"] = self._ask_delete
self.btn_remove["text"] = _("remove entry")
self.btn_remove["state"] = "disabled"
self.btn_remove.grid(row=row, column=1, pady=4)
# ############################################################
# Gruppe Bearbeiten ##########################################
gb_edit = ttk.LabelFrame(self)
gb_edit["text"] = _("Edit acess control list")
gb_edit.pack(expand=True, fill="both", padx=4, pady=4)
frame = ttk.Frame(gb_edit)
frame.grid()
row = 0
lbl = ttk.Label(frame)
lbl["text"] = _("IP address") + ": "
lbl.grid(row=row, column=0, **cpadw)
# Variablen IP / Level
self.var_ip1 = tkinter.StringVar(frame)
self.var_ip2 = tkinter.StringVar(frame)
self.var_ip3 = tkinter.StringVar(frame)
self.var_ip4 = tkinter.StringVar(frame)
self.var_acl = tkinter.StringVar(frame, self.minlevel)
ip_block1 = ttk.Entry(frame, width=4)
ip_block2 = ttk.Entry(frame, width=4)
ip_block3 = ttk.Entry(frame, width=4)
ip_block4 = ttk.Entry(frame, width=4)
ip_block1.bind(
"<KeyRelease>",
lambda event, tkvar=self.var_ip1: self._checkdot(
event, tkvar, ip_block2
)
)
ip_block1["state"] = self.__ro
ip_block1["textvariable"] = self.var_ip1
ip_block1.grid(row=row, column=1)
ip_block2.bind(
"<KeyRelease>",
lambda event, tkvar=self.var_ip2: self._checkdot(
event, tkvar, ip_block3
)
)
ip_block2.bind(
"<Key>",
lambda event, tkvar=self.var_ip2: self._checkback(
event, tkvar, ip_block1
)
)
ip_block2["state"] = self.__ro
ip_block2["textvariable"] = self.var_ip2
ip_block2.grid(row=row, column=3)
ip_block3.bind(
"<KeyRelease>",
lambda event, tkvar=self.var_ip3: self._checkdot(
event, tkvar, ip_block4
)
)
ip_block3.bind(
"<Key>",
lambda event, tkvar=self.var_ip3: self._checkback(
event, tkvar, ip_block2
)
)
ip_block3["state"] = self.__ro
ip_block3["textvariable"] = self.var_ip3
ip_block3.grid(row=row, column=5)
ip_block4.bind(
"<KeyRelease>",
lambda event, tkvar=self.var_ip4: self._checkdot(
event, tkvar, None
)
)
ip_block4.bind(
"<Key>",
lambda event, tkvar=self.var_ip4: self._checkback(
event, tkvar, ip_block3
)
)
ip_block4["state"] = self.__ro
ip_block4["textvariable"] = self.var_ip4
ip_block4.grid(row=row, column=7)
# Punkte zwischen IP-Feldern
for i in range(2, 7, 2):
lbl = ttk.Label(frame, text=".")
lbl.grid(row=row, column=i)
row = 1
lbl = ttk.Label(frame)
lbl["text"] = _("Access level") + ": "
lbl.grid(row=row, column=0, **cpadw)
self.sb_level = tkinter.Spinbox(frame, width=4)
self.sb_level["from_"] = self.minlevel
self.sb_level["to"] = self.maxlevel
self.sb_level["state"] = self.__ro
self.sb_level["textvariable"] = self.var_acl
self.sb_level.grid(row=row, column=1, columnspan=8, sticky="w")
# Buttons neben IP-Eintrag
self.btn_add = ttk.Button(gb_edit)
self.btn_add["command"] = self._savefields
self.btn_add["state"] = self.__ro
self.btn_add["text"] = _("add to list")
self.btn_add.grid(column=0, row=1, sticky="e", padx=4, pady=4)
self.btn_clear = ttk.Button(gb_edit)
self.btn_clear["command"] = self._clearfields
self.btn_clear["state"] = self.__ro
self.btn_clear["text"] = _("clear")
self.btn_clear.grid(column=1, row=1, padx=4, pady=4)
# ############################################################
frame = ttk.Frame(self)
frame.columnconfigure(0, weight=1)
frame.columnconfigure(1, weight=1)
frame.pack(expand=True, fill="both", pady=4)
# Buttons
btn_save = ttk.Button(frame)
btn_save["command"] = self._save
btn_save["state"] = self.__ro
btn_save["text"] = _("Save")
btn_save.grid(column=0, row=0)
btn_close = ttk.Button(frame)
btn_close["command"] = self._checkclose
btn_close["text"] = _("Close")
btn_close.grid(column=1, row=0)
# Infotexte vorbereiten
self.aclinfo = ttk.Frame(self)
def _ask_delete(self):
u"""Löscht ein Eintrag der Liste."""
str_acl = self.trv_acl.focus()
if str_acl != "":
lst_ipacl = str_acl.split()
ask = tkmsg.askyesno(
_("Question"),
_("Do you really want to delete the following item? \n"
"\nIP: {} / Level: {}").format(*lst_ipacl),
parent=self.master, default="no"
)
if ask:
new_acl = self.__acl.acl.replace(
"{},{}".format(*lst_ipacl), ""
).replace(" ", " ")
if self.__acl.loadacl(new_acl.strip()):
# Liste neu aufbauen
self._refreshacls()
else:
tkmsg.showerror(
_("Error"),
_("Can not delete ACL! Check format."),
parent=self.master
)
def _checkback(self, event, tkvar, pretxt):
u"""Springt bei Backspace in vorheriges Feld.
@param event TK Event
@param tkvar TK Variable zum prüfen
@param nexttxt Vorheriges IP Feld für Fokus
"""
if pretxt is not None and event.keycode == 22 and tkvar.get() == "":
pretxt.focus_set()
def _checkdot(self, event, tkvar, nexttxt):
u"""Prüft auf . und geht weiter.
@param event TK Event
@param tkvar TK Variable zum prüfen
@param nexttxt Nächstes IP Feld für Fokus
"""
val = tkvar.get()
if val.find(".") >= 0:
tkvar.set(val[:-1])
if nexttxt is not None:
nexttxt.focus_set()
def _clearfields(self):
u"""Leert die Eingabefelder."""
self.var_ip1.set("")
self.var_ip2.set("")
self.var_ip3.set("")
self.var_ip4.set("")
self.var_acl.set(self.minlevel)
def _loadfields(self):
u"""Übernimmt Listeneintrag in Editfelder."""
str_acl = self.trv_acl.focus()
if str_acl != "":
lst_ip, acl = str_acl.split()
lst_ip = lst_ip.split(".")
self.var_ip1.set(lst_ip[0])
self.var_ip2.set(lst_ip[1])
self.var_ip3.set(lst_ip[2])
self.var_ip4.set(lst_ip[3])
self.var_acl.set(acl)
def _refreshacls(self):
u"""Leert die ACL Liste und füllt sie neu."""
self.trv_acl.delete(*self.trv_acl.get_children())
for tup_acl in self.__acl:
self.trv_acl.insert(
"", "end", tup_acl, text=tup_acl[0], values=tup_acl[1]
)
def _save(self):
u"""Übernimt die Änderungen."""
self.__oldacl = self.__acl.acl
self._checkclose()
def _savefields(self):
u"""Übernimmt neuen ACL Eintrag."""
new_acl = "{}.{}.{}.{},{}".format(
self.var_ip1.get(),
self.var_ip2.get(),
self.var_ip3.get(),
self.var_ip4.get(),
self.var_acl.get()
)
if self.__acl.loadacl((self.__acl.acl + " " + new_acl).strip()):
self._refreshacls()
else:
tkmsg.showerror(
_("Error"),
_("Can not load new ACL! Check format."),
parent=self.master
)
def _status_editremove(self, tkevt):
u"""Setzt state der Buttons."""
if self.__ro == "normal":
status = "disabled" if self.trv_acl.focus() == "" else "normal"
self.btn_edit["state"] = status
self.btn_remove["state"] = status
def get_acl(self):
u"""Gibt die Konfigurierten ACL zurück.
@return ACL als <class 'str'>"""
return self.__oldacl
acl = property(get_acl)
acltext = property(__get_acltext, __set_acltext)
if __name__ == "__main__":
root = AclManager(tkinter.Tk(), 0, 9, " 192.168.50.100,2 127.0.0.*,1")
root.acltext = {0: "Keine Rechte", 1: "Hohe Rechte"}
root.mainloop()
print(root.acl)

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +1,28 @@
# -*- coding: utf-8 -*-
#
# RevPiPyControl
#
# Webpage: https://revpimodio.org/revpipyplc/
# (c) Sven Sager, License: LGPLv3
#
# -*- coding: utf-8 -*-
"""Tools-Sammlung."""
import gettext
import locale
import sys
from os import environ
from os.path import dirname
from os.path import join as pathjoin
from sys import platform
# Systemwerte und SaveFiles
if platform == "linux":
homedir = environ["HOME"]
else:
homedir = environ["APPDATA"]
savefile_connections = pathjoin(
homedir, ".revpipyplc", "connections.dat")
savefile_programpath = pathjoin(
homedir, ".revpipyplc", "programpath.dat")
def addroot(filename):
@@ -29,7 +42,12 @@ def addroot(filename):
def gettrans(proglang=None):
u"""Wertet die Sprache des OS aus und gibt Übersetzung zurück.
@param proglang Bestimmte Sprache laden
@return gettext Übersetzung für Zuweisung an '_'
"""
# Sprache auswählen
if proglang is None:
# Autodetect Language or switch to static

View File

@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
#
# RevPiPyControl
#
@@ -6,7 +7,7 @@
#
# Thranks to: http://stackoverflow.com/questions/3085696/adding-a-
# scrollbar-to-a-group-of-widgets-in-tkinter
u"""Fenstererweiterung für den 'watch modus'."""
import pickle
import tkinter
import tkinter.messagebox as tkmsg
@@ -20,6 +21,8 @@ _ = gettrans()
class RevPiCheckClient(tkinter.Frame):
u"""Baut Fenstererweiterung für 'watch modus'."""
def __init__(self, master, xmlcli, xmlmode=0):
"""Instantiiert MyApp-Klasse."""
super().__init__(master)
@@ -202,7 +205,7 @@ class RevPiCheckClient(tkinter.Frame):
def _createwidgets(self):
"""Erstellt den Fensterinhalt."""
cFxPxy53 = {"fill": "x", "padx": 5, "pady": 3}
cfxpxy53 = {"fill": "x", "padx": 5, "pady": 3}
devgrp = tkinter.LabelFrame(self)
devgrp["text"] = _("Devices of RevPi")
@@ -233,7 +236,7 @@ class RevPiCheckClient(tkinter.Frame):
btn = tkinter.Button(devgrp)
btn["command"] = lambda win=win: self.__showwin(win)
btn["text"] = "{} | {}".format(dev, self.dict_devices[dev])
btn.pack(**cFxPxy53)
btn.pack(**cfxpxy53)
# Steuerungsfunktionen
cntgrp = tkinter.LabelFrame(self)
@@ -243,19 +246,19 @@ class RevPiCheckClient(tkinter.Frame):
self.btn_refresh = tkinter.Button(cntgrp)
self.btn_refresh["text"] = _("Read all IOs")
self.btn_refresh["command"] = self.refreshvalues
self.btn_refresh.pack(**cFxPxy53)
self.btn_refresh.pack(**cfxpxy53)
self.btn_read = tkinter.Button(cntgrp)
self.btn_read["text"] = _("Read just Inputs")
self.btn_read["command"] = self.readvalues
self.btn_read.pack(**cFxPxy53)
self.btn_read.pack(**cfxpxy53)
self.btn_write = tkinter.Button(cntgrp)
self.btn_write["state"] = "normal" if self.xmlmode >= 3 \
else "disabled"
self.btn_write["text"] = _("Write Outputs")
self.btn_write["command"] = self.writevalues
self.btn_write.pack(**cFxPxy53)
self.btn_write.pack(**cfxpxy53)
self.chk_auto = tkinter.Checkbutton(cntgrp)
self.chk_auto["command"] = self.toggleauto

View File

@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
#
# RevPiPyControl
#
# Webpage: https://revpimodio.org/revpipyplc/
# (c) Sven Sager, License: LGPLv3
#
# -*- coding: utf-8 -*-
u"""Programminformationen anzeigen."""
import tkinter
import tkinter.font as tkf
import webbrowser
@@ -16,6 +17,8 @@ _ = gettrans()
class RevPiInfo(tkinter.Frame):
u"""Baut Frame für Programminformationen."""
def __init__(self, master, xmlcli, version):
u"""Init RevPiLogfile-Class."""
self.master = master

View File

@@ -0,0 +1,358 @@
# -*- coding: utf-8 -*-
#
# RevPiPyControl
#
# Webpage: https://revpimodio.org/revpipyplc/
# (c) Sven Sager, License: LGPLv3
#
u"""Alte Klassen laden hier, bevor sie entsorgt werden."""
import tkinter
import tkinter.messagebox as tkmsg
from mytools import gettrans
# Übersetzung laden
_ = gettrans()
class RevPiOption(tkinter.Frame):
u"""Optionen für RevPiPyload vor 0.6.0."""
def __init__(self, master, xmlcli):
u"""Init RevPiOption-Class.
@return None"""
try:
self.dc = xmlcli.get_config()
except:
self.dc = None
return None
super().__init__(master)
self.master.bind("<KeyPress-Escape>", self._checkclose)
self.master.protocol("WM_DELETE_WINDOW", self._checkclose)
self.pack(expand=True, fill="both")
self.xmlcli = xmlcli
self.mrk_var_xmlmod2 = False
self.mrk_var_xmlmod3 = False
self.mrk_xmlmodask = False
self.dorestart = False
# Fenster bauen
self._createwidgets()
self._loadappdata()
def _changesdone(self):
u"""Prüft ob sich die Einstellungen geändert haben.
@return True, wenn min. eine Einstellung geändert wurde"""
return (
self.var_start.get() != self.dc.get("autostart", "1")
or self.var_reload.get() != self.dc.get("autoreload", "1")
or self.var_zexit.get() != self.dc.get("zeroonexit", "0")
or self.var_zerr.get() != self.dc.get("zeroonerror", "0")
or self.var_startpy.get() != self.dc.get("plcprogram", "none.py")
or self.var_startargs.get() != self.dc.get("plcarguments", "")
or self.var_pythonver.get() != self.dc.get("pythonversion", "3")
or self.var_slave.get() != self.dc.get("plcslave", "0")
or self.var_xmlon.get() != (self.dc.get("xmlrpc", 0) >= 1)
or self.var_xmlmod2.get() != (self.dc.get("xmlrpc", 0) >= 2)
or self.var_xmlmod3.get() != (self.dc.get("xmlrpc", 0) >= 3)
# or self.var_xmlport.get() != self.dc.get("xmlrpcport", "55123")
)
def _checkclose(self, event=None):
u"""Prüft ob Fenster beendet werden soll.
@param event tkinter-Event"""
ask = True
if self._changesdone():
ask = tkmsg.askyesno(
_("Question"),
_("Do you really want to quit? \nUnsaved changes will "
"be lost"),
parent=self.master, default="no"
)
if ask:
self.master.destroy()
def _createwidgets(self):
u"""Erstellt Widgets."""
self.master.wm_title(_("RevPi Python PLC Options"))
self.master.wm_resizable(width=False, height=False)
xmlstate = "normal" if self.dc["xmlrpc"] >= 3 else "disabled"
cpadw = {"padx": 4, "pady": 2, "sticky": "w"}
cpadwe = {"padx": 4, "pady": 2, "sticky": "we"}
# Gruppe Start/Stop
stst = tkinter.LabelFrame(self)
stst["text"] = _("Start / Stop behavior")
stst.grid(columnspan=2, pady=2, sticky="we")
self.var_start = tkinter.BooleanVar(stst)
self.var_reload = tkinter.BooleanVar(stst)
self.var_zexit = tkinter.BooleanVar(stst)
self.var_zerr = tkinter.BooleanVar(stst)
ckb_start = tkinter.Checkbutton(stst)
ckb_start["text"] = _("Start program automatically")
ckb_start["state"] = xmlstate
ckb_start["variable"] = self.var_start
ckb_start.grid(**cpadw)
ckb_reload = tkinter.Checkbutton(stst)
ckb_reload["text"] = _("Restart program after exit")
ckb_reload["state"] = xmlstate
ckb_reload["variable"] = self.var_reload
ckb_reload.grid(**cpadw)
lbl = tkinter.Label(stst)
lbl["text"] = _("Set process image to NULL if program terminates...")
lbl.grid(**cpadw)
ckb_zexit = tkinter.Checkbutton(stst, justify="left")
ckb_zexit["state"] = xmlstate
ckb_zexit["text"] = _("... successfully")
ckb_zexit["variable"] = self.var_zexit
ckb_zexit.grid(**cpadw)
ckb_zerr = tkinter.Checkbutton(stst, justify="left")
ckb_zerr["state"] = xmlstate
ckb_zerr["text"] = _("... with errors")
ckb_zerr["variable"] = self.var_zerr
ckb_zerr.grid(**cpadw)
# Gruppe Programm
prog = tkinter.LabelFrame(self)
prog["text"] = _("PLC program")
prog.grid(columnspan=2, pady=2, sticky="we")
self.var_pythonver = tkinter.IntVar(prog)
self.var_startpy = tkinter.StringVar(prog)
self.var_startargs = tkinter.StringVar(prog)
self.var_slave = tkinter.BooleanVar(prog)
self.var_pythonver.set(3)
lbl = tkinter.Label(prog)
lbl["text"] = _("Python version")
lbl.grid(columnspan=2, row=0, **cpadw)
rbn = tkinter.Radiobutton(prog)
rbn["state"] = xmlstate
rbn["text"] = "Python2"
rbn["value"] = 2
rbn["variable"] = self.var_pythonver
rbn.grid(column=0, row=1, **cpadw)
rbn = tkinter.Radiobutton(prog)
rbn["state"] = xmlstate
rbn["text"] = "Python3"
rbn["value"] = 3
rbn["variable"] = self.var_pythonver
rbn.grid(column=1, row=1, **cpadw)
# Row 2
lbl = tkinter.Label(prog)
lbl["text"] = _("Python PLC program name")
lbl.grid(columnspan=2, **cpadw)
# Row 3
lst = self.xmlcli.get_filelist()
if len(lst) == 0:
lst.append("none")
opt_startpy = tkinter.OptionMenu(
prog, self.var_startpy, *lst
)
opt_startpy["state"] = xmlstate
opt_startpy.grid(columnspan=2, **cpadwe)
# Row 4
lbl = tkinter.Label(prog)
lbl["text"] = _("Program arguments")
lbl.grid(columnspan=2, **cpadw)
# Row 5
txt = tkinter.Entry(prog)
txt["textvariable"] = self.var_startargs
txt.grid(columnspan=2, **cpadw)
# Row 6
ckb_slave = tkinter.Checkbutton(prog, justify="left")
ckb_slave["state"] = xmlstate
ckb_slave["text"] = _("Use RevPi as PLC-Slave")
ckb_slave["variable"] = self.var_slave
ckb_slave.grid(column=0, **cpadw)
# Gruppe XMLRPC
xmlrpc = tkinter.LabelFrame(self)
xmlrpc["text"] = _("XML-RPC server")
xmlrpc.grid(columnspan=2, pady=2, sticky="we")
self.var_xmlon = tkinter.BooleanVar(xmlrpc)
self.var_xmlmod2 = tkinter.BooleanVar(xmlrpc)
self.var_xmlmod3 = tkinter.BooleanVar(xmlrpc)
# self.var_xmlport = tkinter.StringVar(xmlrpc)
# self.var_xmlport.set("55123")
ckb_xmlon = tkinter.Checkbutton(xmlrpc)
ckb_xmlon["command"] = self.askxmlon
ckb_xmlon["state"] = xmlstate
ckb_xmlon["text"] = _("Activate XML-RPC server on RevPi")
ckb_xmlon["variable"] = self.var_xmlon
ckb_xmlon.grid(**cpadw)
self.ckb_xmlmod2 = tkinter.Checkbutton(xmlrpc, justify="left")
self.ckb_xmlmod2["command"] = self.xmlmod2_tail
self.ckb_xmlmod2["state"] = xmlstate
self.ckb_xmlmod2["text"] = \
_("Allow download of piCtory configuration and\nPLC programm")
self.ckb_xmlmod2["variable"] = self.var_xmlmod2
self.ckb_xmlmod2.grid(**cpadw)
self.ckb_xmlmod3 = tkinter.Checkbutton(xmlrpc, justify="left")
self.ckb_xmlmod3["state"] = xmlstate
self.ckb_xmlmod3["text"] = \
_("Allow upload of piCtory configuration and\nPLC programm")
self.ckb_xmlmod3["variable"] = self.var_xmlmod3
self.ckb_xmlmod3.grid(**cpadw)
lbl = tkinter.Label(xmlrpc)
lbl["text"] = _("XML-RPC server port")
lbl.grid(**cpadw)
# spb_xmlport = tkinter.Spinbox(xmlrpc)
# spb_xmlport["to"] = 65535
# spb_xmlport["from"] = 1024
# spb_xmlport["state"] = xmlstate
# spb_xmlport["textvariable"] = self.var_xmlport
# spb_xmlport.grid(**cpadwe)
# Buttons
btn_save = tkinter.Button(self)
btn_save["command"] = self._setappdata
btn_save["state"] = xmlstate
btn_save["text"] = _("Save")
btn_save.grid(column=0, row=3)
btn_close = tkinter.Button(self)
btn_close["command"] = self._checkclose
btn_close["text"] = _("Close")
btn_close.grid(column=1, row=3)
def _loadappdata(self, refresh=False):
u"""Läd aktuelle Einstellungen vom RevPi.
@param refresh Wenn True, werden Einstellungen heruntergeladen."""
if refresh:
self.dc = self.xmlcli.get_config()
self.var_start.set(self.dc.get("autostart", "1"))
self.var_reload.set(self.dc.get("autoreload", "1"))
self.var_zexit.set(self.dc.get("zeroonexit", "0"))
self.var_zerr.set(self.dc.get("zeroonerror", "0"))
self.var_startpy.set(self.dc.get("plcprogram", "none.py"))
self.var_startargs.set(self.dc.get("plcarguments", ""))
self.var_pythonver.set(self.dc.get("pythonversion", "3"))
self.var_slave.set(self.dc.get("plcslave", "0"))
self.var_xmlon.set(self.dc.get("xmlrpc", 0) >= 1)
self.var_xmlmod2.set(self.dc.get("xmlrpc", 0) >= 2)
self.mrk_var_xmlmod2 = self.var_xmlmod2.get()
self.var_xmlmod3.set(self.dc.get("xmlrpc", 0) >= 3)
self.mrk_var_xmlmod3 = self.var_xmlmod3.get()
# self.var_xmlport.set(self.dc.get("xmlrpcport", "55123"))
def _setappdata(self):
u"""Speichert geänderte Einstellungen auf RevPi.
@return None"""
if not self._changesdone():
tkmsg.showinfo(
_("Information"),
_("You have not made any changes to save."),
)
self._checkclose()
return None
ask = tkmsg.askyesnocancel(
_("Question"),
_("The settings are now saved on the Revolution Pi. \n\n"
"Should the new settings take effect immediately? \nThis "
"means a restart of the service and the PLC program!"),
parent=self.master
)
if ask is not None:
self.dc["autostart"] = int(self.var_start.get())
self.dc["autoreload"] = int(self.var_reload.get())
self.dc["zeroonexit"] = int(self.var_zexit.get())
self.dc["zeroonerror"] = int(self.var_zerr.get())
self.dc["plcprogram"] = self.var_startpy.get()
self.dc["plcarguments"] = self.var_startargs.get()
self.dc["pythonversion"] = self.var_pythonver.get()
self.dc["plcslave"] = int(self.var_slave.get())
self.dc["xmlrpc"] = 0
if self.var_xmlon.get():
self.dc["xmlrpc"] += 1
if self.var_xmlmod2.get():
self.dc["xmlrpc"] += 1
if self.var_xmlmod3.get():
self.dc["xmlrpc"] += 1
# self.dc["xmlrpcport"] = self.var_xmlport.get()
if self.xmlcli.set_config(self.dc, ask):
tkmsg.showinfo(
_("Information"),
_("Settings saved"),
parent=self.master
)
self.dorestart = ask
self._checkclose()
else:
tkmsg.showerror(
_("Error"),
_("The settings could not be saved. This can happen if "
"values are wrong!"),
parent=self.master
)
def askxmlon(self):
u"""Fragt Nuter, ob wirklicht abgeschaltet werden soll."""
if not (self.var_xmlon.get() or self.mrk_xmlmodask):
self.mrk_xmlmodask = tkmsg.askyesno(
_("Question"),
_("Are you sure you want to deactivate the XML-RPC server? "
"You will NOT be able to access the Revolution Pi with "
"this program."),
parent=self.master
)
if not self.mrk_xmlmodask:
self.var_xmlon.set(True)
self.xmlmod_tail()
def xmlmod_tail(self):
u"""Passt XML-Optionszugriff an."""
if self.var_xmlon.get():
self.var_xmlmod2.set(self.mrk_var_xmlmod2)
self.ckb_xmlmod2["state"] = "normal"
else:
self.mrk_var_xmlmod2 = self.var_xmlmod2.get()
self.var_xmlmod2.set(False)
self.ckb_xmlmod2["state"] = "disabled"
self.xmlmod2_tail()
def xmlmod2_tail(self):
u"""Passt XML-Optionszugriff an."""
if self.var_xmlmod2.get():
self.var_xmlmod3.set(self.mrk_var_xmlmod3)
self.ckb_xmlmod3["state"] = "normal"
else:
self.mrk_var_xmlmod3 = self.var_xmlmod3.get()
self.var_xmlmod3.set(False)
self.ckb_xmlmod3["state"] = "disabled"

View File

@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
#
# RevPiPyControl
#
# Webpage: https://revpimodio.org/revpipyplc/
# (c) Sven Sager, License: LGPLv3
#
# -*- coding: utf-8 -*-
u"""Zeigt die Logfiles an."""
import tkinter
from mytools import gettrans
@@ -14,6 +15,8 @@ _ = gettrans()
class RevPiLogfile(tkinter.Frame):
u"""Baut Fenster für Logfiles."""
def __init__(self, master, xmlcli):
u"""Init RevPiLogfile-Class."""
super().__init__(master)
@@ -57,6 +60,7 @@ class RevPiLogfile(tkinter.Frame):
self.btnapplog["command"] = self.btn_clearplc
self.btnapplog["text"] = _("Clear screen")
self.btnapplog.grid(column=1, row=0, sticky="e")
self.plclog = tkinter.Text(self)
self.plcscr = tkinter.Scrollbar(self)
self.plclog.grid(sticky="wnse", columnspan=2, column=0, row=1)
@@ -72,6 +76,7 @@ class RevPiLogfile(tkinter.Frame):
self.btnapplog["command"] = self.btn_clearapp
self.btnapplog["text"] = _("Clear screen")
self.btnapplog.grid(column=4, row=0, sticky="e")
self.applog = tkinter.Text(self)
self.appscr = tkinter.Scrollbar(self)
self.applog.grid(sticky="nesw", columnspan=2, column=3, row=1)
@@ -150,13 +155,13 @@ class RevPiLogfile(tkinter.Frame):
if full:
textwidget.delete(1.0, tkinter.END)
if bytebuff == b'\x16': # 
if bytebuff == b'\x16': # 'ESC'
# Kein Zugriff auf Logdatei
textwidget.delete(1.0, tkinter.END)
textwidget.insert(
tkinter.END, _("Can not access log file on the RevPi")
)
elif bytebuff == b'\x19': # 
elif bytebuff == b'\x19': # 'EndOfMedia'
# Logdatei neu begonnen
startposition = 0
else:

View File

@@ -1,12 +1,14 @@
# -*- coding: utf-8 -*-
#
# RevPiPyControl
#
# Webpage: https://revpimodio.org/revpipyplc/
# (c) Sven Sager, License: LGPLv3
#
# -*- coding: utf-8 -*-
u"""Optionsfenster."""
import tkinter
import tkinter.messagebox as tkmsg
from aclmanager import AclManager
from mytools import gettrans
# Übersetzung laden
@@ -15,6 +17,8 @@ _ = gettrans()
class RevPiOption(tkinter.Frame):
u"""Zeigt Optionen von RevPiPyLoad an."""
def __init__(self, master, xmlcli):
u"""Init RevPiOption-Class.
@return None"""
@@ -29,9 +33,10 @@ class RevPiOption(tkinter.Frame):
self.master.protocol("WM_DELETE_WINDOW", self._checkclose)
self.pack(expand=True, fill="both")
# XML-RPC Server konfigurieren
self.xmlcli = xmlcli
self.mrk_var_xmlmod2 = False
self.mrk_var_xmlmod3 = False
self.xmlmodus = self.xmlcli.xmlmodus()
self.mrk_xmlmodask = False
self.dorestart = False
@@ -43,18 +48,20 @@ class RevPiOption(tkinter.Frame):
u"""Prüft ob sich die Einstellungen geändert haben.
@return True, wenn min. eine Einstellung geändert wurde"""
return (
self.var_start.get() != self.dc.get("autostart", "1")
or self.var_reload.get() != self.dc.get("autoreload", "1")
or self.var_zexit.get() != self.dc.get("zeroonexit", "0")
or self.var_zerr.get() != self.dc.get("zeroonerror", "0")
self.var_start.get() != self.dc.get("autostart", 1)
or self.var_reload.get() != self.dc.get("autoreload", 1)
or self.var_reload_delay.get() !=
str(self.dc.get("autoreloaddelay", 5))
or self.var_zexit.get() != self.dc.get("zeroonexit", 0)
or self.var_zerr.get() != self.dc.get("zeroonerror", 0)
# TODO: rtlevel (0)
or self.var_startpy.get() != self.dc.get("plcprogram", "none.py")
or self.var_startargs.get() != self.dc.get("plcarguments", "")
or self.var_pythonver.get() != self.dc.get("pythonversion", "3")
or self.var_slave.get() != self.dc.get("plcslave", "0")
or self.var_xmlon.get() != (self.dc.get("xmlrpc", 0) >= 1)
or self.var_xmlmod2.get() != (self.dc.get("xmlrpc", 0) >= 2)
or self.var_xmlmod3.get() != (self.dc.get("xmlrpc", 0) >= 3)
or self.var_xmlport.get() != self.dc.get("xmlrpcport", "55123")
or self.var_pythonver.get() != self.dc.get("pythonversion", 3)
or self.var_slave.get() != self.dc.get("plcslave", 0)
or self.var_slaveacl.get() != self.dc.get("plcslaveacl", "")
or self.var_xmlon.get() != self.dc.get("xmlrpc", 0)
or self.var_xmlacl.get() != self.dc.get("xmlrpcacl", "")
)
def _checkclose(self, event=None):
@@ -72,13 +79,27 @@ class RevPiOption(tkinter.Frame):
if ask:
self.master.destroy()
def _checkvalues(self):
u"""Prüft alle Werte auf Gültigkeit.
@return True, wenn alle Werte gültig sind"""
if not self.var_reload_delay.get().isdigit():
tkmsg.showerror(
_("Error"),
_("The value of 'restart delay' ist not valid."),
parent=self.master
)
return False
return True
def _createwidgets(self):
u"""Erstellt Widgets."""
self.master.wm_title(_("RevPi Python PLC Options"))
self.master.wm_resizable(width=False, height=False)
xmlstate = "normal" if self.dc["xmlrpc"] >= 3 else "disabled"
xmlstate = "normal" if self.xmlmodus >= 4 else "disabled"
cpade = {"padx": 4, "pady": 2, "sticky": "e"}
cpadw = {"padx": 4, "pady": 2, "sticky": "w"}
cpadwe = {"padx": 4, "pady": 2, "sticky": "we"}
@@ -89,6 +110,7 @@ class RevPiOption(tkinter.Frame):
self.var_start = tkinter.BooleanVar(stst)
self.var_reload = tkinter.BooleanVar(stst)
self.var_reload_delay = tkinter.StringVar(stst)
self.var_zexit = tkinter.BooleanVar(stst)
self.var_zerr = tkinter.BooleanVar(stst)
@@ -96,51 +118,64 @@ class RevPiOption(tkinter.Frame):
ckb_start["text"] = _("Start program automatically")
ckb_start["state"] = xmlstate
ckb_start["variable"] = self.var_start
ckb_start.grid(**cpadw)
ckb_start.grid(columnspan=2, **cpadw)
ckb_reload = tkinter.Checkbutton(stst)
ckb_reload["text"] = _("Restart program after exit")
ckb_reload["state"] = xmlstate
ckb_reload["variable"] = self.var_reload
ckb_reload.grid(**cpadw)
ckb_reload.grid(columnspan=2, **cpadw)
lbl = tkinter.Label(stst)
lbl["text"] = _("Restart after n seconds of delay")
lbl.grid(**cpadw)
sbx = tkinter.Spinbox(stst)
sbx["to"] = 60
sbx["from_"] = 5
sbx["textvariable"] = self.var_reload_delay
sbx["width"] = 4
sbx.grid(column=1, row=2, **cpade)
lbl = tkinter.Label(stst)
lbl["text"] = _("Set process image to NULL if program terminates...")
lbl.grid(columnspan=2, **cpadw)
ckb_zexit = tkinter.Checkbutton(stst, justify="left")
ckb_zexit["state"] = xmlstate
ckb_zexit["text"] = _(
"Set process image to NULL if program\n"
"terminates successfully")
ckb_zexit["text"] = _("... successfully")
ckb_zexit["variable"] = self.var_zexit
ckb_zexit.grid(**cpadw)
ckb_zerr = tkinter.Checkbutton(stst, justify="left")
ckb_zerr["state"] = xmlstate
ckb_zerr["text"] = _(
"Set process image to NULL if program\n"
"terminates with errors")
ckb_zerr["text"] = _("... with errors")
ckb_zerr["variable"] = self.var_zerr
ckb_zerr.grid(**cpadw)
# Gruppe Programm
prog = tkinter.LabelFrame(self)
prog.columnconfigure(0, weight=1)
prog.columnconfigure(1, weight=1)
prog["text"] = _("PLC program")
prog.grid(columnspan=2, pady=2, sticky="we")
self.var_pythonver = tkinter.IntVar(prog)
self.var_startpy = tkinter.StringVar(prog)
self.var_startargs = tkinter.StringVar(prog)
self.var_slave = tkinter.BooleanVar(prog)
self.var_slaveacl = tkinter.StringVar(prog)
self.var_pythonver.set(3)
lbl = tkinter.Label(prog)
lbl["text"] = _("Python version")
lbl["text"] = _("Python version") + ":"
lbl.grid(columnspan=2, row=0, **cpadw)
rbn = tkinter.Radiobutton(prog)
rbn["state"] = xmlstate
rbn["text"] = "Python2"
rbn["value"] = 2
rbn["variable"] = self.var_pythonver
rbn.grid(column=0, row=1, **cpadw)
rbn.grid(column=0, row=1, **cpade)
rbn = tkinter.Radiobutton(prog)
rbn["state"] = xmlstate
@@ -149,78 +184,79 @@ class RevPiOption(tkinter.Frame):
rbn["variable"] = self.var_pythonver
rbn.grid(column=1, row=1, **cpadw)
# Row 2
lbl = tkinter.Label(prog)
lbl["text"] = _("Python PLC program name")
lbl.grid(columnspan=2, **cpadw)
# Row 3
lst = self.xmlcli.get_filelist()
if len(lst) == 0:
lst.append("none")
opt_startpy = tkinter.OptionMenu(
prog, self.var_startpy, *lst)
prog, self.var_startpy, *lst
)
opt_startpy["state"] = xmlstate
opt_startpy.grid(columnspan=2, **cpadwe)
# Row 4
lbl = tkinter.Label(prog)
lbl["text"] = _("Program arguments")
lbl.grid(columnspan=2, **cpadw)
# Row 5
txt = tkinter.Entry(prog)
txt["textvariable"] = self.var_startargs
txt.grid(columnspan=2, **cpadw)
ckb_slave = tkinter.Checkbutton(prog, justify="left")
# Gruppe Services
services = tkinter.LabelFrame(self)
services["text"] = _("RevPiPyLoad server services")
services.grid(columnspan=2, pady=2, sticky="we")
self.var_slave = tkinter.BooleanVar(services)
self.var_xmlon = tkinter.BooleanVar(services)
self.var_xmlacl = tkinter.StringVar(services)
# RevPiSlave Service
row = 0
ckb_slave = tkinter.Checkbutton(services, justify="left")
ckb_slave["state"] = xmlstate
ckb_slave["text"] = _("Use RevPi as PLC-Slave")
ckb_slave["state"] = "disabled"
ckb_slave["variable"] = self.var_slave
ckb_slave.grid(columnspan=2, **cpadw)
ckb_slave.grid(column=0, **cpadw)
# Gruppe XMLRPC
xmlrpc = tkinter.LabelFrame(self)
xmlrpc["text"] = _("XML-RPC server")
xmlrpc.grid(columnspan=2, pady=2, sticky="we")
btn_slaveacl = tkinter.Button(services, justify="center")
btn_slaveacl["command"] = self.btn_slaveacl
btn_slaveacl["text"] = _("Edit ACL")
btn_slaveacl.grid(column=1, row=row, **cpade)
self.var_xmlon = tkinter.BooleanVar(xmlrpc)
self.var_xmlmod2 = tkinter.BooleanVar(xmlrpc)
self.var_xmlmod3 = tkinter.BooleanVar(xmlrpc)
self.var_xmlport = tkinter.StringVar(xmlrpc)
self.var_xmlport.set("55123")
row = 1
lbl = tkinter.Label(services)
lbl["text"] = _("RevPi-Slave service is:")
lbl.grid(column=0, **cpade)
ckb_xmlon = tkinter.Checkbutton(xmlrpc)
status = self.xmlcli.plcslaverunning()
lbl = tkinter.Label(services)
lbl["fg"] = "green" if status else "red"
lbl["text"] = _("running") if status else _("stopped")
lbl.grid(column=1, row=row, **cpadwe)
# XML-RPC Service
row = 2
ckb_xmlon = tkinter.Checkbutton(services)
ckb_xmlon["command"] = self.askxmlon
ckb_xmlon["state"] = xmlstate
ckb_xmlon["text"] = _("Activate XML-RPC server on RevPi")
ckb_xmlon["variable"] = self.var_xmlon
ckb_xmlon.grid(**cpadw)
self.ckb_xmlmod2 = tkinter.Checkbutton(xmlrpc, justify="left")
self.ckb_xmlmod2["command"] = self.xmlmod2_tail
self.ckb_xmlmod2["state"] = xmlstate
self.ckb_xmlmod2["text"] = \
_("Allow download of piCtory configuration and\nPLC programm")
self.ckb_xmlmod2["variable"] = self.var_xmlmod2
self.ckb_xmlmod2.grid(**cpadw)
btn_slaveacl = tkinter.Button(services, justify="center")
btn_slaveacl["command"] = self.btn_xmlacl
btn_slaveacl["text"] = _("Edit ACL")
btn_slaveacl.grid(column=1, row=row, **cpade)
self.ckb_xmlmod3 = tkinter.Checkbutton(xmlrpc, justify="left")
self.ckb_xmlmod3["state"] = xmlstate
self.ckb_xmlmod3["text"] = \
_("Allow upload of piCtory configuration and\nPLC programm")
self.ckb_xmlmod3["variable"] = self.var_xmlmod3
self.ckb_xmlmod3.grid(**cpadw)
lbl = tkinter.Label(xmlrpc)
lbl["text"] = _("XML-RPC server port")
lbl.grid(**cpadw)
spb_xmlport = tkinter.Spinbox(xmlrpc)
spb_xmlport["to"] = 65535
spb_xmlport["from"] = 1024
spb_xmlport["state"] = xmlstate
spb_xmlport["textvariable"] = self.var_xmlport
spb_xmlport.grid(**cpadwe)
# Buttons
# Buttons am Ende
btn_save = tkinter.Button(self)
btn_save["command"] = self._setappdata
btn_save["state"] = xmlstate
@@ -238,23 +274,22 @@ class RevPiOption(tkinter.Frame):
if refresh:
self.dc = self.xmlcli.get_config()
self.var_start.set(self.dc.get("autostart", "1"))
self.var_reload.set(self.dc.get("autoreload", "1"))
self.var_zexit.set(self.dc.get("zeroonexit", "0"))
self.var_zerr.set(self.dc.get("zeroonerror", "0"))
self.var_start.set(self.dc.get("autostart", 1))
self.var_reload.set(self.dc.get("autoreload", 1))
self.var_reload_delay.set(self.dc.get("autoreloaddelay", 5))
self.var_zexit.set(self.dc.get("zeroonexit", 0))
self.var_zerr.set(self.dc.get("zeroonerror", 0))
# TODO: rtlevel (0)
self.var_startpy.set(self.dc.get("plcprogram", "none.py"))
self.var_startargs.set(self.dc.get("plcarguments", ""))
self.var_pythonver.set(self.dc.get("pythonversion", "3"))
self.var_slave.set(self.dc.get("plcslave", "0"))
self.var_pythonver.set(self.dc.get("pythonversion", 3))
self.var_xmlon.set(self.dc.get("xmlrpc", 0) >= 1)
self.var_xmlmod2.set(self.dc.get("xmlrpc", 0) >= 2)
self.mrk_var_xmlmod2 = self.var_xmlmod2.get()
self.var_xmlmod3.set(self.dc.get("xmlrpc", 0) >= 3)
self.mrk_var_xmlmod3 = self.var_xmlmod3.get()
self.var_slave.set(self.dc.get("plcslave", 0))
self.var_slaveacl.set(self.dc.get("plcslaveacl", ""))
self.var_xmlport.set(self.dc.get("xmlrpcport", "55123"))
self.var_xmlon.set(self.dc.get("xmlrpc", 0))
self.var_xmlacl.set(self.dc.get("xmlrpcacl", ""))
def _setappdata(self):
u"""Speichert geänderte Einstellungen auf RevPi.
@@ -268,33 +303,41 @@ class RevPiOption(tkinter.Frame):
self._checkclose()
return None
ask = tkmsg.askyesnocancel(
# Gültigkeitsprüfung
if not self._checkvalues():
return None
# ask = tkmsg.askyesnocancel(
# _("Question"),
# _("The settings are now saved on the Revolution Pi. \n\n"
# "Should the new settings take effect immediately? \nThis "
# "means a restart of the service and the PLC program!"),
# parent=self.master
# )
ask = tkmsg.askokcancel(
_("Question"),
_("The settings are now saved on the Revolution Pi. \n\n"
"Should the new settings take effect immediately? \nThis "
"means a restart of the service and the PLC program!"),
_("The settings will be set on the Revolution Pi now. \n\n"
"If you made changes on the 'PCL Program' section, your plc "
"program will restart! \n"
"ACL changes and service settings are applied immediately."),
parent=self.master
)
if ask is not None:
self.dc["autostart"] = int(self.var_start.get())
if ask:
self.dc["autoreload"] = int(self.var_reload.get())
self.dc["zeroonexit"] = int(self.var_zexit.get())
self.dc["zeroonerror"] = int(self.var_zerr.get())
self.dc["autoreloaddelay"] = int(self.var_reload_delay.get())
self.dc["autostart"] = int(self.var_start.get())
self.dc["plcprogram"] = self.var_startpy.get()
self.dc["plcarguments"] = self.var_startargs.get()
self.dc["pythonversion"] = self.var_pythonver.get()
# TODO: rtlevel (0)
self.dc["zeroonerror"] = int(self.var_zerr.get())
self.dc["zeroonexit"] = int(self.var_zexit.get())
self.dc["plcslave"] = int(self.var_slave.get())
self.dc["plcslaveacl"] = self.var_slaveacl.get()
self.dc["xmlrpc"] = 0
if self.var_xmlon.get():
self.dc["xmlrpc"] += 1
if self.var_xmlmod2.get():
self.dc["xmlrpc"] += 1
if self.var_xmlmod3.get():
self.dc["xmlrpc"] += 1
self.dc["xmlrpcport"] = self.var_xmlport.get()
self.dc["xmlrpc"] = int(self.var_xmlon.get())
self.dc["xmlrpcacl"] = self.var_xmlacl.get()
if self.xmlcli.set_config(self.dc, ask):
tkmsg.showinfo(
@@ -325,25 +368,39 @@ class RevPiOption(tkinter.Frame):
if not self.mrk_xmlmodask:
self.var_xmlon.set(True)
self.xmlmod_tail()
def btn_slaveacl(self):
u"""Öffnet Fenster für ACL-Verwaltung."""
win = tkinter.Toplevel(self)
win.focus_set()
win.grab_set()
slaveacl = AclManager(
win, 0, 1,
self.var_slaveacl.get(),
readonly=self.xmlmodus < 4
)
slaveacl.acltext = {
0: _("read only"),
1: _("read and write")
}
self.wait_window(win)
self.var_slaveacl.set(slaveacl.acl)
def xmlmod_tail(self):
u"""Passt XML-Optionszugriff an."""
if self.var_xmlon.get():
self.var_xmlmod2.set(self.mrk_var_xmlmod2)
self.ckb_xmlmod2["state"] = "normal"
else:
self.mrk_var_xmlmod2 = self.var_xmlmod2.get()
self.var_xmlmod2.set(False)
self.ckb_xmlmod2["state"] = "disabled"
self.xmlmod2_tail()
def xmlmod2_tail(self):
u"""Passt XML-Optionszugriff an."""
if self.var_xmlmod2.get():
self.var_xmlmod3.set(self.mrk_var_xmlmod3)
self.ckb_xmlmod3["state"] = "normal"
else:
self.mrk_var_xmlmod3 = self.var_xmlmod3.get()
self.var_xmlmod3.set(False)
self.ckb_xmlmod3["state"] = "disabled"
def btn_xmlacl(self):
u"""Öffnet Fenster für ACL-Verwaltung."""
win = tkinter.Toplevel(self)
win.focus_set()
win.grab_set()
slaveacl = AclManager(
win, 0, 4,
self.var_xmlacl.get(),
readonly=self.xmlmodus < 4
)
slaveacl.acltext = {
0: _("Start/Stop PLC program and read logs"),
1: _("+ read IOs in watch modus"),
2: _("+ read properties and download PLC program"),
3: _("+ upload PLC program"),
4: _("+ set properties")
}
self.wait_window(win)
self.var_xmlacl.set(slaveacl.acl)

View File

@@ -1,36 +1,32 @@
# -*- coding: utf-8 -*-
#
# RevPiPyControl
#
# Webpage: https://revpimodio.org/revpipyplc/
# (c) Sven Sager, License: LGPLv3
#
# -*- coding: utf-8 -*-
u"""Fenster um RevPi-Verbindungen einzurichten."""
import os.path
import pickle
import tkinter
import tkinter.messagebox as tkmsg
from mytools import gettrans
from os import environ
from mytools import savefile_connections as savefile
from revpiprogram import _loaddefaults as programloaddefaults
from revpiprogram import _savedefaults as programsavedefaults
from os import makedirs
from sys import platform
# Übersetzungen laden
_ = gettrans()
# Systemwerte
if platform == "linux":
homedir = environ["HOME"]
else:
homedir = environ["APPDATA"]
savefile = os.path.join(homedir, ".revpipyplc", "connections.dat")
def get_connections():
u"""Verbindungen aus Datei laden.
@return dict() mit Verbindungen"""
if os.path.exists(savefile):
fh = open(savefile, "rb")
connections = pickle.load(fh)
with open(savefile, "rb") as fh:
connections = pickle.load(fh)
return connections
else:
return {}
@@ -38,6 +34,8 @@ def get_connections():
class RevPiPlcList(tkinter.Frame):
u"""TK Fenster."""
def __init__(self, master):
u"""Init RevPiPlcList-class.
@param master tkinter master"""
@@ -92,11 +90,13 @@ class RevPiPlcList(tkinter.Frame):
# Eingabefelder für Adresse und Namen
tkinter.Label(self, text=_("Name")).grid(
column=2, row=0, sticky="wn", padx=5, pady=5)
column=2, row=0, sticky="wn", padx=5, pady=5
)
self.txt_name = tkinter.Entry(self, textvariable=self.var_name)
self.txt_name.bind("<KeyRelease>", self.evt_keypress)
self.txt_name.grid(
column=3, row=0, columnspan=3, sticky="n", padx=5, pady=5)
column=3, row=0, columnspan=3, sticky="n", padx=5, pady=5
)
tkinter.Label(self, text=_("IP address")).grid(
column=2, row=1, sticky="wn", padx=5, pady=5
@@ -104,34 +104,42 @@ class RevPiPlcList(tkinter.Frame):
self.txt_address = tkinter.Entry(self, textvariable=self.var_address)
self.txt_address.bind("<KeyRelease>", self.evt_keypress)
self.txt_address.grid(
column=3, row=1, columnspan=3, sticky="n", padx=5, pady=5)
column=3, row=1, columnspan=3, sticky="n", padx=5, pady=5
)
tkinter.Label(self, text=_("Port")).grid(
column=2, row=2, sticky="wn", padx=5, pady=5)
column=2, row=2, sticky="wn", padx=5, pady=5
)
self.txt_port = tkinter.Entry(self, textvariable=self.var_port)
self.txt_port.bind("<KeyRelease>", self.evt_keypress)
self.txt_port.grid(
column=3, row=2, columnspan=3, sticky="n", padx=5, pady=5)
column=3, row=2, columnspan=3, sticky="n", padx=5, pady=5
)
# Listenbutton
self.btn_new = tkinter.Button(
self, text=_("New"), command=self.evt_btnnew)
self, text=_("New"), command=self.evt_btnnew
)
self.btn_new.grid(column=2, row=3, sticky="s")
self.btn_add = tkinter.Button(
self, text=_("Apply"), command=self.evt_btnadd,
state="disabled")
self, text=_("Apply"),
command=self.evt_btnadd, state="disabled"
)
self.btn_add.grid(column=3, row=3, sticky="s")
self.btn_remove = tkinter.Button(
self, text=_("Remove"), command=self.evt_btnremove,
state="disabled")
self, text=_("Remove"),
command=self.evt_btnremove, state="disabled"
)
self.btn_remove.grid(column=4, row=3, sticky="s")
# Fensterbuttons
self.btn_save = tkinter.Button(
self, text=_("Save"), command=self.evt_btnsave)
self, text=_("Save"), command=self.evt_btnsave
)
self.btn_save.grid(column=3, row=9, sticky="se")
self.btn_close = tkinter.Button(
self, text=_("Close"), command=self._checkclose)
self, text=_("Close"), command=self._checkclose
)
self.btn_close.grid(column=4, row=9, sticky="se")
def _saveappdata(self):
@@ -139,11 +147,19 @@ class RevPiPlcList(tkinter.Frame):
@return True, bei erfolgreicher Verarbeitung"""
try:
makedirs(os.path.dirname(savefile), exist_ok=True)
fh = open(savefile, "wb")
pickle.dump(self._connections, fh)
with open(savefile, "wb") as fh:
pickle.dump(self._connections, fh)
self.changes = False
except:
return False
# Andere Einstellungen aufräumen
dict = programloaddefaults()
for revpi in tuple(dict.keys()):
if revpi not in self._connections:
del dict[revpi]
programsavedefaults(None, dict)
return True
def build_listconn(self):
@@ -220,7 +236,6 @@ class RevPiPlcList(tkinter.Frame):
self.var_port.set(self._connections[item][1])
self.btn_add["state"] == "normal"
self.btn_remove["state"] = "normal"
else:
self.btn_remove["state"] = "disabled"

View File

@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
#
# RevPiPyControl
#
# Webpage: https://revpimodio.org/revpipyplc/
# (c) Sven Sager, License: LGPLv3
#
# -*- coding: utf-8 -*-
u"""PLC Programm und Konfig hoch und runterladen."""
import gzip
import os
import pickle
@@ -14,26 +15,56 @@ import tkinter.filedialog as tkfd
import tkinter.messagebox as tkmsg
import zipfile
from mytools import gettrans
from os import environ
from mytools import savefile_programpath as savefile
from os import makedirs
from shutil import rmtree
from sys import platform
from tempfile import mkstemp, mkdtemp
from xmlrpc.client import Binary
# Übersetzung laden
_ = gettrans()
# Systemwerte
if platform == "linux":
homedir = environ["HOME"]
else:
homedir = environ["APPDATA"]
savefile = os.path.join(homedir, ".revpipyplc", "programpath.dat")
def _loaddefaults(revpiname=None):
u"""Übernimmt für den Pi die letzen Pfade.
@param revpiname Einstellungen nur für RevPi laden
@return <class 'dict'> mit Einstellungen"""
if os.path.exists(savefile):
with open(savefile, "rb") as fh:
dict_all = pickle.load(fh)
if revpiname is None:
return dict_all
else:
return dict_all.get(revpiname, {})
return {}
def _savedefaults(revpiname, settings):
u"""Schreibt fuer den Pi die letzen Pfade.
@param revpiname Einstellungen sind für diesen RevPi
@param settings <class 'dict'> mit Einstellungen
@return True, bei erfolgreicher Verarbeitung
"""
try:
makedirs(os.path.dirname(savefile), exist_ok=True)
if revpiname is None:
dict_all = settings
else:
dict_all = _loaddefaults()
dict_all[revpiname] = settings
with open(savefile, "wb") as fh:
pickle.dump(dict_all, fh)
except:
return False
return True
class RevPiProgram(tkinter.Frame):
u"""Zeigt Programmfenster an."""
def __init__(self, master, xmlcli, xmlmode, revpi):
u"""Init RevPiProgram-Class.
@return None"""
@@ -48,11 +79,10 @@ class RevPiProgram(tkinter.Frame):
self.uploaded = False
self.revpi = revpi
self.xmlcli = xmlcli
self.xmlmode = xmlmode
self.xmlstate = "normal" if xmlmode == 3 else "disabled"
self.xmlstate = "normal" if xmlmode >= 3 else "disabled"
# Letzte Einstellungen übernehmen
self.opt = self._loaddefault()
self.opt = _loaddefaults()
# Fenster bauen
self._createwidgets()
@@ -121,8 +151,9 @@ class RevPiProgram(tkinter.Frame):
lbl["text"] = _("Download PLC program as:")
lbl.grid(column=0, row=r, **cpadw)
opt = tkinter.OptionMenu(
prog, self.var_typedown, *self.lst_typedown,
command=self._evt_optdown)
prog, self.var_typedown, command=self._evt_optdown,
*self.lst_typedown
)
opt["width"] = 10
opt.grid(column=1, row=r, **cpad)
@@ -131,6 +162,7 @@ class RevPiProgram(tkinter.Frame):
self.ckb_picdown["text"] = _("include piCtory configuration")
self.ckb_picdown["variable"] = self.var_picdown
self.ckb_picdown.grid(column=0, row=r, **cpadw)
btn = tkinter.Button(prog)
btn["command"] = self.plcdownload
btn["text"] = _("Download")
@@ -140,9 +172,11 @@ class RevPiProgram(tkinter.Frame):
lbl = tkinter.Label(prog)
lbl["text"] = _("Upload PLC program as:")
lbl.grid(column=0, row=r, **cpadw)
opt = tkinter.OptionMenu(
prog, self.var_typeup, *self.lst_typeup,
command=self._evt_optup)
prog, self.var_typeup, command=self._evt_optup,
*self.lst_typeup
)
opt["state"] = self.xmlstate
opt["width"] = 10
opt.grid(column=1, row=r, **cpad)
@@ -160,6 +194,7 @@ class RevPiProgram(tkinter.Frame):
self.ckb_picup["text"] = _("includes piCtory configuration")
self.ckb_picup["variable"] = self.var_picup
self.ckb_picup.grid(column=0, row=r, **cpadw)
btn = tkinter.Button(prog)
btn["command"] = self.plcupload
btn["state"] = self.xmlstate
@@ -175,13 +210,16 @@ class RevPiProgram(tkinter.Frame):
lbl = tkinter.Label(picto)
lbl["text"] = _("Download piCtory configuration")
lbl.grid(column=0, row=0, **cpadw)
btn = tkinter.Button(picto)
btn["command"] = self.getpictoryrsc
btn["text"] = _("Download")
btn.grid(column=1, row=0, **cpad)
lbl = tkinter.Label(picto)
lbl["text"] = _("Upload piCtory configuration")
lbl.grid(column=0, row=1, **cpadw)
btn = tkinter.Button(picto)
btn["command"] = self.setpictoryrsc
btn["state"] = self.xmlstate
@@ -193,9 +231,11 @@ class RevPiProgram(tkinter.Frame):
proc.columnconfigure(0, weight=1)
proc["text"] = _("piControl0 process image")
proc.grid(columnspan=2, pady=2, sticky="we")
lbl = tkinter.Label(proc)
lbl["text"] = _("Download process image dump")
lbl.grid(column=0, row=0, **cpadw)
btn = tkinter.Button(proc)
btn["command"] = self.getprocimg
btn["text"] = _("Download")
@@ -206,9 +246,11 @@ class RevPiProgram(tkinter.Frame):
picon.columnconfigure(0, weight=1)
picon["text"] = _("Reset piControl")
picon.grid(columnspan=2, pady=2, sticky="we")
lbl = tkinter.Label(picon)
lbl["text"] = _("Execute piControlReset")
lbl.grid(column=0, row=0, **cpadw)
btn = tkinter.Button(picon)
btn["command"] = self.picontrolreset
btn["text"] = _("execute")
@@ -236,33 +278,6 @@ class RevPiProgram(tkinter.Frame):
else:
self.ckb_picup["state"] = "normal"
def _loaddefault(self, full=False):
u"""Übernimmt für den Pi die letzen Pfade.
@param full Einstellungen für alle Verbindungen laden
@return dict() mit Einstellungen"""
if os.path.exists(savefile):
fh = open(savefile, "rb")
dict_all = pickle.load(fh)
if full:
return dict_all
else:
return dict_all.get(self.revpi, {})
return {}
def _savedefaults(self):
u"""Schreibt fuer den Pi die letzen Pfade.
@return True, bei erfolgreicher Verarbeitung"""
try:
makedirs(os.path.dirname(savefile), exist_ok=True)
dict_all = self._loaddefault(full=True)
dict_all[self.revpi] = self.opt
fh = open(savefile, "wb")
pickle.dump(dict_all, fh)
self.changes = False
except:
return False
return True
def create_filelist(self, rootdir):
u"""Erstellt eine Dateiliste von einem Verzeichnis.
@param rootdir Verzeichnis fuer das eine Liste erstellt werden soll
@@ -324,7 +339,7 @@ class RevPiProgram(tkinter.Frame):
)
# Einstellungen speichern
self.opt["getpictoryrsc_dir"] = os.path.dirname(fh.name)
self._savedefaults()
self._savedefaults(self.revpi, self.opt)
finally:
fh.close()
@@ -355,7 +370,7 @@ class RevPiProgram(tkinter.Frame):
)
# Einstellungen speichern
self.opt["getprocimg_dir"] = os.path.dirname(fh.name)
self._savedefaults()
self._savedefaults(self.revpi, self.opt)
finally:
fh.close()
@@ -403,7 +418,7 @@ class RevPiProgram(tkinter.Frame):
# Einstellungen speichern
self.opt["setpictoryrsc_dir"] = os.path.dirname(fh.name)
self._savedefaults()
self._savedefaults(self.revpi, self.opt)
elif ec == -1:
tkmsg.showerror(
_("Error"),
@@ -561,7 +576,7 @@ class RevPiProgram(tkinter.Frame):
)
# Einstellungen speichern
self._savedefaults()
self._savedefaults(self.revpi, self.opt)
finally:
fh.close()
@@ -737,7 +752,7 @@ class RevPiProgram(tkinter.Frame):
self.opt["typeup"] = self.var_typeup.get()
self.opt["picup"] = self.var_picup.get()
self._savedefaults()
self._savedefaults(self.revpi, self.opt)
elif ec == -1:
tkmsg.showerror(

View File

@@ -1,4 +1,5 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# RevPiPyControl
# Version: see global var pycontrolverion
@@ -6,11 +7,12 @@
# Webpage: https://revpimodio.org/revpipyplc/
# (c) Sven Sager, License: LGPLv3
#
# -*- coding: utf-8 -*-
u"""Hauptprogramm."""
import revpicheckclient
import revpiinfo
import revpilogfile
import revpioption
import revpilegacy
import revpiplclist
import revpiprogram
import socket
@@ -23,11 +25,13 @@ from xmlrpc.client import ServerProxy
# Übersetzung laden
_ = gettrans()
pycontrolversion = "0.4.2"
pycontrolversion = "0.6.0"
class RevPiPyControl(tkinter.Frame):
u"""Baut Hauptprogramm auf."""
def __init__(self, master=None):
u"""Init RevPiPyControl-Class.
@param master tkinter master"""
@@ -39,6 +43,7 @@ class RevPiPyControl(tkinter.Frame):
self.dict_conn = revpiplclist.get_connections()
self.errcount = 0
self.revpiname = None
self.revpipyversion = [0, 0, 0]
self.xmlfuncs = []
self.xmlmode = 0
@@ -202,6 +207,7 @@ class RevPiPyControl(tkinter.Frame):
try:
self.xmlfuncs = sp.system.listMethods()
self.xmlmode = sp.xmlmodus()
self.revpipyversion = list(map(int, sp.version().split(".")))
except:
self.servererror()
else:
@@ -238,8 +244,8 @@ class RevPiPyControl(tkinter.Frame):
_("Warning"),
_("The watch mode ist not supported in version {} "
"of RevPiPyLoad on your RevPi! You need at least version "
"0.4.0. Or the python3-revpimodio module is not installt"
"on your RevPi at least version 0.15.0."
"0.5.3! Maybe the python3-revpimodio2 module is not "
"installed on your RevPi at least version 2.0.0."
"").format(self.cli.version()),
parent=self.master
)
@@ -256,7 +262,7 @@ class RevPiPyControl(tkinter.Frame):
tkmsg.showwarning(
_("Error"),
_("Can not load piCtory configuration. \n"
"Have you created a hardware configuration? "
"Did you create a hardware configuration? "
"Please check this in piCtory!"),
parent=self.master
)
@@ -318,13 +324,20 @@ class RevPiPyControl(tkinter.Frame):
win = tkinter.Toplevel(self)
win.focus_set()
win.grab_set()
self.tkoptions = \
revpioption.RevPiOption(win, self.cli)
# Gegenstelle prüfen und passende Optionen laden
if self.revpipyversion[0] == 0 and self.revpipyversion[1] < 6:
self.tkoptions = \
revpilegacy.RevPiOption(win, self.cli)
else:
self.tkoptions = \
revpioption.RevPiOption(win, self.cli)
self.wait_window(win)
if self.tkoptions.dc is not None and self.tkoptions.dorestart:
# Wenn XML-Modus anders und Dienstneustart
if self.xmlmode != self.tkoptions.dc["xmlrpc"]:
if self.xmlmode != self.cli.xmlmodus():
self.serverdisconnect()
self._opt_conn(self.revpiname, True)

View File

@@ -0,0 +1 @@
"""Shared modules."""

View File

@@ -0,0 +1,189 @@
# -*- coding: utf-8 -*-
#
# IpAclManager
#
# (c) Sven Sager, License: LGPLv3
# Version 0.1.0
#
"""Verwaltet IP Adressen und deren ACLs."""
from os import access, R_OK, W_OK
from re import match as rematch
def refullmatch(regex, string):
"""re.fullmatch wegen alter python version aus wheezy nachgebaut.
@param regex RegEx Statement
@param string Zeichenfolge gegen die getestet wird
@return True, wenn komplett passt sonst False
"""
m = rematch(regex, string)
return m is not None and m.end() == len(string)
class IpAclManager():
"""Verwaltung fuer IP Adressen und deren ACL Level."""
def __init__(self, minlevel, maxlevel, acl=None):
"""Init IpAclManager class.
@param minlevel Smallest access level (min. 0)
@param maxlevel Biggest access level (max. 9)
@param acl ACL Liste fuer Berechtigungen als <class 'str'>
"""
if type(minlevel) != int:
raise ValueError("parameter minlevel must be <class 'int'>")
if type(maxlevel) != int:
raise ValueError("parameter maxlevel must be <class 'int'>")
if minlevel < 0:
raise ValueError("minlevel must be 0 or more")
if maxlevel > 9:
raise ValueError("maxlevel maximum is 9")
if minlevel > maxlevel:
raise ValueError("minlevel is smaller than maxlevel")
self.__dict_acl = {}
self.__dict_regex = {}
self.__dict_knownips = {}
self.__filename = None
self.__re_ipacl = "(([\\d\\*]{1,3}\\.){3}[\\d\\*]{1,3},[" \
+ str(minlevel) + "-" + str(maxlevel) + "] ?)*"
# Liste erstellen, wenn übergeben
if acl is not None:
self.__set_acl(acl)
def __iter__(self):
"""Gibt einzelne ACLs als <class 'tuple'> aus."""
for aclip in sorted(self.__dict_acl):
yield (aclip, self.__dict_acl[aclip])
def __get_acl(self):
"""Getter fuer den rohen ACL-String.
return ACLs als <class 'str'>"""
str_acl = ""
for aclip in sorted(self.__dict_acl):
str_acl += "{},{} ".format(aclip, self.__dict_acl[aclip])
return str_acl.strip()
def __get_filename(self):
"""Getter fuer Dateinamen.
@return Filename der ACL <class 'str'>"""
return "" if self.__filename is None else self.__filename
def __get_regex_acl(self):
"""Gibt formatierten RegEx-String zurueck.
return RegEx Code als <class 'str'>"""
return self.__re_ipacl
def __set_acl(self, value):
"""Uebernimmt neue ACL-Liste fuer die Ausertung der Level.
@param value Neue ACL-Liste als <class 'str'>"""
if type(value) != str:
raise ValueError("parameter acl must be <class 'str'>")
value = value.strip()
if not refullmatch(self.__re_ipacl, value):
raise ValueError("acl format ist not okay - 1.2.3.4,0 5.6.7.8,1")
# Klassenwerte übernehmen
self.__dict_acl = {}
self.__dict_regex = {}
self.__dict_knownips = {}
# Liste neu füllen mit regex Strings
for ip_level in value.split():
ip, level = ip_level.split(",", 1)
self.__dict_acl[ip] = int(level)
self.__dict_regex[ip] = \
ip.replace(".", "\\.").replace("*", "\\d{1,3}")
def get_acllevel(self, ipaddress):
"""Prueft IP gegen ACL List und gibt ACL-Wert aus.
@param ipaddress zum pruefen
@return <class 'int'> ACL Wert oder -1 wenn nicht gefunden"""
# Bei bereits aufgelösten IPs direkt ACL auswerten
if ipaddress in self.__dict_knownips:
return self.__dict_knownips[ipaddress]
for aclip in sorted(self.__dict_acl, reverse=True):
if refullmatch(self.__dict_regex[aclip], ipaddress):
# IP und Level merken
self.__dict_knownips[ipaddress] = self.__dict_acl[aclip]
# Level zurückgeben
return self.__dict_acl[aclip]
return -1
def loadacl(self, str_acl):
"""Laed ACL String und gibt erfolg zurueck.
@param str_acl ACL als <class 'str'>
@return True, wenn erfolgreich uebernommen"""
if not refullmatch(self.__re_ipacl, str_acl):
return False
self.__set_acl(str_acl)
return True
def loadaclfile(self, filename):
"""Laed ACL Definitionen aus Datei.
@param filename Dateiname fuer Definitionen
@return True, wenn Laden erfolgreich war"""
if type(filename) != str:
raise ValueError("parameter filename must be <class 'str'>")
# Zugriffsrecht prüfen
if not access(filename, R_OK):
return False
str_acl = ""
with open(filename, "r") as fh:
while True:
buff = fh.readline()
if buff == "":
break
buff = buff.split("#")[0].strip()
if len(buff) > 0:
str_acl += buff + " "
acl_okay = self.loadacl(str_acl.strip())
if acl_okay:
# Dateinamen für Schreiben übernehmen
self.__filename = filename
return acl_okay
def writeaclfile(self, filename=None, aclname=None):
"""Schreibt ACL Definitionen in Datei.
@param filename Dateiname fuer Definitionen
@return True, wenn Schreiben erfolgreich war"""
if filename is not None and type(filename) != str:
raise ValueError("parameter filename must be <class 'str'>")
if aclname is not None and type(aclname) != str:
raise ValueError("parameter aclname must be <class 'str'>")
# Dateinamen prüfen
if filename is None and self.__filename is not None:
filename = self.__filename
# Zugriffsrecht prüfen
if not access(filename, W_OK):
return False
header = "# {}Access Control List (acl)\n" \
"# One entry per Line IPADRESS,LEVEL\n" \
"#\n".format("" if aclname is None else aclname + " ")
with open(filename, "w") as fh:
fh.write(header)
for aclip in sorted(self.__dict_acl):
fh.write("{},{}\n".format(aclip, self.__dict_acl[aclip]))
return True
acl = property(__get_acl, __set_acl)
filename = property(__get_filename)
regex_acl = property(__get_regex_acl)

View File

@@ -1,8 +1,7 @@
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
#
# (c) Sven Sager, License: LGPLv3
#
# -*- coding: utf-8 -*-
"""Setupscript fuer RevPiPyLoad."""
import distutils.command.install_egg_info
from sys import platform
@@ -23,7 +22,7 @@ globsetup = {
"author_email": "akira@narux.de",
"url": "https://revpimodio.org/revpipyplc/",
"license": "LGPLv3",
"version": "0.4.2",
"version": "0.6.0",
"name": "revpipycontrol",
@@ -49,6 +48,7 @@ if platform == "linux":
("share/applications", ["data/revpipycontrol.desktop"]),
("share/icons/hicolor/32x32/apps", ["data/revpipycontrol.png"]),
("share/revpipycontrol", glob("revpipycontrol/*.*")),
("share/revpipycontrol/shared", glob("revpipycontrol/shared/*.*")),
(
"share/revpipycontrol/locale/de/LC_MESSAGES",
glob("revpipycontrol/locale/de/LC_MESSAGES/*.mo")

View File

@@ -3,3 +3,4 @@ Debian-Version=1
Depends3=python3-tk
Section=universe/x11
Suite=stable
X-Python3-Version: >=3.4