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> 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"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Modules</h3> Modules</h3>
<table> <table>
<tr> <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> <td></td>
</tr><tr> </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><a style="color:#0000FF" href="revpicheckclient.html">revpicheckclient</a></td>
<td></td> <td></td>
</tr><tr> </tr><tr>
<td><a style="color:#0000FF" href="revpiinfo.html">revpiinfo</a></td> <td><a style="color:#0000FF" href="revpiinfo.html">revpiinfo</a></td>
<td></td> <td></td>
</tr><tr> </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><a style="color:#0000FF" href="revpilogfile.html">revpilogfile</a></td>
<td></td> <td></td>
</tr><tr> </tr><tr>

View File

@@ -6,11 +6,13 @@
<body style="background-color:#FFFFFF;color:#000000"><a NAME="top" ID="top"></a> <body style="background-color:#FFFFFF;color:#000000"><a NAME="top" ID="top"></a>
<h1 style="background-color:#FFFFFF;color:#0000FF"> <h1 style="background-color:#FFFFFF;color:#0000FF">
mytools</h1> mytools</h1>
<p>
Tools-Sammlung.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Global Attributes</h3> Global Attributes</h3>
<table> <table>
<tr><td>None</td></tr> <tr><td>savefile_connections</td></tr><tr><td>savefile_programpath</td></tr>
</table> </table>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3> Classes</h3>
@@ -25,7 +27,7 @@ Functions</h3>
<td>H&#228;ngt root-dir der Anwendung vor Dateinamen.</td> <td>H&#228;ngt root-dir der Anwendung vor Dateinamen.</td>
</tr><tr> </tr><tr>
<td><a style="color:#0000FF" href="#gettrans">gettrans</a></td> <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> </tr>
</table> </table>
<hr /><hr /> <hr /><hr />
@@ -53,7 +55,19 @@ root dir
<a NAME="gettrans" ID="gettrans"></a> <a NAME="gettrans" ID="gettrans"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">gettrans</h2> <h2 style="background-color:#FFFFFF;color:#0000FF">gettrans</h2>
<b>gettrans</b>(<i>proglang=None</i>) <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> <div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /> <hr />
</body></html> </body></html>

View File

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

View File

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

View File

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

View File

@@ -10,25 +10,33 @@ revpiprogram</h1>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Global Attributes</h3> Global Attributes</h3>
<table> <table>
<tr><td>_</td></tr><tr><td>savefile</td></tr> <tr><td>_</td></tr>
</table> </table>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3> Classes</h3>
<table> <table>
<tr> <tr>
<td><a style="color:#0000FF" href="#RevPiProgram">RevPiProgram</a></td> <td><a style="color:#0000FF" href="#RevPiProgram">RevPiProgram</a></td>
<td></td> <td>Zeigt Programmfenster an.</td>
</tr> </tr>
</table> </table>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Functions</h3> Functions</h3>
<table> <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> </table>
<hr /><hr /> <hr /><hr />
<a NAME="RevPiProgram" ID="RevPiProgram"></a> <a NAME="RevPiProgram" ID="RevPiProgram"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">RevPiProgram</h2> <h2 style="background-color:#FFFFFF;color:#0000FF">RevPiProgram</h2>
<p>
Zeigt Programmfenster an.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3> Derived from</h3>
tkinter.Frame tkinter.Frame
@@ -61,12 +69,6 @@ Methods</h3>
<td><a style="color:#0000FF" href="#RevPiProgram._evt_optup">_evt_optup</a></td> <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> <td>Passt je nach gew&#228;hlter Option den Status der Widgets an.</td>
</tr><tr> </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><a style="color:#0000FF" href="#RevPiProgram.check_replacedir">check_replacedir</a></td>
<td>Gibt das rootdir von einem entpackten Verzeichnis zurueck.</td> <td>Gibt das rootdir von einem entpackten Verzeichnis zurueck.</td>
</tr><tr> </tr><tr>
@@ -137,34 +139,7 @@ RevPiProgram._evt_optup</h3>
<b>_evt_optup</b>(<i>text=""</i>) <b>_evt_optup</b>(<i>text=""</i>)
<p> <p>
Passt je nach gew&#228;hlter Option den Status der Widgets an. Passt je nach gew&#228;hlter Option den Status der Widgets an.
</p><a NAME="RevPiProgram._loaddefault" ID="RevPiProgram._loaddefault"></a> </p><a NAME="RevPiProgram.check_replacedir" ID="RevPiProgram.check_replacedir"></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>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiProgram.check_replacedir</h3> RevPiProgram.check_replacedir</h3>
<b>check_replacedir</b>(<i>rootdir</i>) <b>check_replacedir</b>(<i>rootdir</i>)
@@ -242,5 +217,44 @@ RevPiProgram.setpictoryrsc</h3>
&#220;bertr&#228;gt die angegebene piCtory-Konfiguration. &#220;bertr&#228;gt die angegebene piCtory-Konfiguration.
</p> </p>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div> <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 /> <hr />
</body></html> </body></html>

View File

@@ -17,7 +17,7 @@ Classes</h3>
<table> <table>
<tr> <tr>
<td><a style="color:#0000FF" href="#RevPiPyControl">RevPiPyControl</a></td> <td><a style="color:#0000FF" href="#RevPiPyControl">RevPiPyControl</a></td>
<td></td> <td>Baut Hauptprogramm auf.</td>
</tr> </tr>
</table> </table>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
@@ -28,7 +28,9 @@ Functions</h3>
<hr /><hr /> <hr /><hr />
<a NAME="RevPiPyControl" ID="RevPiPyControl"></a> <a NAME="RevPiPyControl" ID="RevPiPyControl"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">RevPiPyControl</h2> <h2 style="background-color:#FFFFFF;color:#0000FF">RevPiPyControl</h2>
<p>
Baut Hauptprogramm auf.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3> Derived from</h3>
tkinter.Frame 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.addroot?4(filename)
mytools.gettrans?4(proglang=None) mytools.gettrans?4(proglang=None)
mytools.savefile_connections?7
mytools.savefile_programpath?7
revpicheckclient.RevPiCheckClient.__chval?6(device, io, event=None) revpicheckclient.RevPiCheckClient.__chval?6(device, io, event=None)
revpicheckclient.RevPiCheckClient.__hidewin?6(win, event=None) revpicheckclient.RevPiCheckClient.__hidewin?6(win, event=None)
revpicheckclient.RevPiCheckClient.__saveoldvalue?6(event, tkvar) revpicheckclient.RevPiCheckClient.__saveoldvalue?6(event, tkvar)
@@ -26,6 +48,16 @@ revpiinfo.RevPiInfo._createwidgets?5(extended=False)
revpiinfo.RevPiInfo.visitwebsite?4(event=None) revpiinfo.RevPiInfo.visitwebsite?4(event=None)
revpiinfo.RevPiInfo?1(master, xmlcli, version) revpiinfo.RevPiInfo?1(master, xmlcli, version)
revpiinfo._?8 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._checkclose?5(event=None)
revpilogfile.RevPiLogfile._createwidgets?5() revpilogfile.RevPiLogfile._createwidgets?5()
revpilogfile.RevPiLogfile._load_log?5(textwidget, xmlcall, startposition, full) revpilogfile.RevPiLogfile._load_log?5(textwidget, xmlcall, startposition, full)
@@ -37,12 +69,13 @@ revpilogfile.RevPiLogfile?1(master, xmlcli)
revpilogfile._?8 revpilogfile._?8
revpioption.RevPiOption._changesdone?5() revpioption.RevPiOption._changesdone?5()
revpioption.RevPiOption._checkclose?5(event=None) revpioption.RevPiOption._checkclose?5(event=None)
revpioption.RevPiOption._checkvalues?5()
revpioption.RevPiOption._createwidgets?5() revpioption.RevPiOption._createwidgets?5()
revpioption.RevPiOption._loadappdata?5(refresh=False) revpioption.RevPiOption._loadappdata?5(refresh=False)
revpioption.RevPiOption._setappdata?5() revpioption.RevPiOption._setappdata?5()
revpioption.RevPiOption.askxmlon?4() revpioption.RevPiOption.askxmlon?4()
revpioption.RevPiOption.xmlmod2_tail?4() revpioption.RevPiOption.btn_slaveacl?4()
revpioption.RevPiOption.xmlmod_tail?4() revpioption.RevPiOption.btn_xmlacl?4()
revpioption.RevPiOption?1(master, xmlcli) revpioption.RevPiOption?1(master, xmlcli)
revpioption._?8 revpioption._?8
revpiplclist.RevPiPlcList._checkclose?5(event=None) revpiplclist.RevPiPlcList._checkclose?5(event=None)
@@ -60,13 +93,10 @@ revpiplclist.RevPiPlcList.root?7
revpiplclist.RevPiPlcList?1(master) revpiplclist.RevPiPlcList?1(master)
revpiplclist._?8 revpiplclist._?8
revpiplclist.get_connections?4() revpiplclist.get_connections?4()
revpiplclist.savefile?7
revpiprogram.RevPiProgram._checkclose?5(event=None) revpiprogram.RevPiProgram._checkclose?5(event=None)
revpiprogram.RevPiProgram._createwidgets?5() revpiprogram.RevPiProgram._createwidgets?5()
revpiprogram.RevPiProgram._evt_optdown?5(text="") revpiprogram.RevPiProgram._evt_optdown?5(text="")
revpiprogram.RevPiProgram._evt_optup?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.check_replacedir?4(rootdir)
revpiprogram.RevPiProgram.create_filelist?4(rootdir) revpiprogram.RevPiProgram.create_filelist?4(rootdir)
revpiprogram.RevPiProgram.getpictoryrsc?4() revpiprogram.RevPiProgram.getpictoryrsc?4()
@@ -77,7 +107,8 @@ revpiprogram.RevPiProgram.plcupload?4()
revpiprogram.RevPiProgram.setpictoryrsc?4(filename=None) revpiprogram.RevPiProgram.setpictoryrsc?4(filename=None)
revpiprogram.RevPiProgram?1(master, xmlcli, xmlmode, revpi) revpiprogram.RevPiProgram?1(master, xmlcli, xmlmode, revpi)
revpiprogram._?8 revpiprogram._?8
revpiprogram.savefile?7 revpiprogram._loaddefaults?5(revpiname=None)
revpiprogram._savedefaults?5(revpiname, settings)
revpipycontrol.RevPiPyControl._btnstate?5() revpipycontrol.RevPiPyControl._btnstate?5()
revpipycontrol.RevPiPyControl._closeall?5() revpipycontrol.RevPiPyControl._closeall?5()
revpipycontrol.RevPiPyControl._closeapp?5(event=None) revpipycontrol.RevPiPyControl._closeapp?5(event=None)
@@ -103,3 +134,17 @@ revpipycontrol.RevPiPyControl.visitwebsite?4()
revpipycontrol.RevPiPyControl?1(master=None) revpipycontrol.RevPiPyControl?1(master=None)
revpipycontrol._?8 revpipycontrol._?8
revpipycontrol.pycontrolversion?7 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 RevPiCheckClient tkinter.Frame
RevPiInfo tkinter.Frame RevPiInfo tkinter.Frame
RevPiLogfile tkinter.Frame RevPiLogfile tkinter.Frame

View File

@@ -1,18 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Project SYSTEM "Project-5.1.dtd"> <!DOCTYPE Project SYSTEM "Project-5.1.dtd">
<!-- eric project file for project revpipycontrol --> <!-- eric project file for project revpipycontrol -->
<!-- Saved: 2017-07-06, 13:33:38 --> <!-- Saved: 2018-04-04, 15:41:50 -->
<!-- Copyright (C) 2017 Sven Sager, akira@narux.de --> <!-- Copyright (C) 2018 Sven Sager, akira@narux.de -->
<Project version="5.1"> <Project version="5.1">
<Language>en_US</Language> <Language>en_US</Language>
<Hash>66103e2eaf8a762f14d1fd51d8b1c9dcaf35a275</Hash> <Hash>66103e2eaf8a762f14d1fd51d8b1c9dcaf35a275</Hash>
<ProgLanguage mixed="0">Python3</ProgLanguage> <ProgLanguage mixed="0">Python3</ProgLanguage>
<ProjectType>Console</ProjectType> <ProjectType>Console</ProjectType>
<Description></Description> <Description></Description>
<Version>0.4.2</Version> <Version>0.6.0</Version>
<Author>Sven Sager</Author> <Author>Sven Sager</Author>
<Email>akira@narux.de</Email> <Email>akira@narux.de</Email>
<Eol index="-1"/> <Eol index="1"/>
<Sources> <Sources>
<Source>revpipycontrol/revpipycontrol.py</Source> <Source>revpipycontrol/revpipycontrol.py</Source>
<Source>revpipycontrol/revpicheckclient.py</Source> <Source>revpipycontrol/revpicheckclient.py</Source>
@@ -23,6 +23,10 @@
<Source>revpipycontrol/revpiprogram.py</Source> <Source>revpipycontrol/revpiprogram.py</Source>
<Source>revpipycontrol/mytools.py</Source> <Source>revpipycontrol/mytools.py</Source>
<Source>revpipycontrol/revpiinfo.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> </Sources>
<Forms/> <Forms/>
<Translations/> <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 # RevPiPyControl
# #
# Webpage: https://revpimodio.org/revpipyplc/ # Webpage: https://revpimodio.org/revpipyplc/
# (c) Sven Sager, License: LGPLv3 # (c) Sven Sager, License: LGPLv3
# #
# -*- coding: utf-8 -*- """Tools-Sammlung."""
import gettext import gettext
import locale import locale
import sys import sys
from os import environ
from os.path import dirname from os.path import dirname
from os.path import join as pathjoin 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): def addroot(filename):
@@ -29,7 +42,12 @@ def addroot(filename):
def gettrans(proglang=None): 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 # Sprache auswählen
if proglang is None: if proglang is None:
# Autodetect Language or switch to static # Autodetect Language or switch to static

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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