diff --git a/.gitignore b/.gitignore
index 6e62b41..9167756 100644
--- a/.gitignore
+++ b/.gitignore
@@ -114,6 +114,5 @@ dmypy.json
# Pyre type checker
.pyre/
-/test/
+/test_local/
/make.conf
-/lib/
diff --git a/.idea/revpipyload.iml b/.idea/revpipyload.iml
index 0dc1149..e32621b 100644
--- a/.idea/revpipyload.iml
+++ b/.idea/revpipyload.iml
@@ -2,11 +2,13 @@
-
-
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index 94a25f7..029a1a8 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -1,5 +1,12 @@
+
+
+
+
+
+
+
diff --git a/LICENSE.txt b/LICENSE.txt
index 0a04128..d159169 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,165 +1,339 @@
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
- Copyright (C) 2007 Free Software Foundation, Inc.
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
+ Preamble
- This version of the GNU Lesser General Public License incorporates
-the terms and conditions of version 3 of the GNU General Public
-License, supplemented by the additional permissions listed below.
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
- 0. Additional Definitions.
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
- As used herein, "this License" refers to version 3 of the GNU Lesser
-General Public License, and the "GNU GPL" refers to version 3 of the GNU
-General Public License.
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
- "The Library" refers to a covered work governed by this License,
-other than an Application or a Combined Work as defined below.
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
- An "Application" is any work that makes use of an interface provided
-by the Library, but which is not otherwise based on the Library.
-Defining a subclass of a class defined by the Library is deemed a mode
-of using an interface provided by the Library.
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
- A "Combined Work" is a work produced by combining or linking an
-Application with the Library. The particular version of the Library
-with which the Combined Work was made is also called the "Linked
-Version".
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
- The "Minimal Corresponding Source" for a Combined Work means the
-Corresponding Source for the Combined Work, excluding any source code
-for portions of the Combined Work that, considered in isolation, are
-based on the Application, and not on the Linked Version.
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
- The "Corresponding Application Code" for a Combined Work means the
-object code and/or source code for the Application, including any data
-and utility programs needed for reproducing the Combined Work from the
-Application, but excluding the System Libraries of the Combined Work.
+ The precise terms and conditions for copying, distribution and
+modification follow.
- 1. Exception to Section 3 of the GNU GPL.
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
- You may convey a covered work under sections 3 and 4 of this License
-without being bound by section 3 of the GNU GPL.
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
- 2. Conveying Modified Versions.
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
- If you modify a copy of the Library, and, in your modifications, a
-facility refers to a function or data to be supplied by an Application
-that uses the facility (other than as an argument passed when the
-facility is invoked), then you may convey a copy of the modified
-version:
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
- a) under this License, provided that you make a good faith effort to
- ensure that, in the event an Application does not supply the
- function or data, the facility still operates, and performs
- whatever part of its purpose remains meaningful, or
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
- b) under the GNU GPL, with none of the additional permissions of
- this License applicable to that copy.
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
- 3. Object Code Incorporating Material from Library Header Files.
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
- The object code form of an Application may incorporate material from
-a header file that is part of the Library. You may convey such object
-code under terms of your choice, provided that, if the incorporated
-material is not limited to numerical parameters, data structure
-layouts and accessors, or small macros, inline functions and templates
-(ten or fewer lines in length), you do both of the following:
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
- a) Give prominent notice with each copy of the object code that the
- Library is used in it and that the Library and its use are
- covered by this License.
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
- b) Accompany the object code with a copy of the GNU GPL and this license
- document.
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
- 4. Combined Works.
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
- You may convey a Combined Work under terms of your choice that,
-taken together, effectively do not restrict modification of the
-portions of the Library contained in the Combined Work and reverse
-engineering for debugging such modifications, if you also do each of
-the following:
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
- a) Give prominent notice with each copy of the Combined Work that
- the Library is used in it and that the Library and its use are
- covered by this License.
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
- b) Accompany the Combined Work with a copy of the GNU GPL and this license
- document.
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
- c) For a Combined Work that displays copyright notices during
- execution, include the copyright notice for the Library among
- these notices, as well as a reference directing the user to the
- copies of the GNU GPL and this license document.
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
- d) Do one of the following:
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
- 0) Convey the Minimal Corresponding Source under the terms of this
- License, and the Corresponding Application Code in a form
- suitable for, and under terms that permit, the user to
- recombine or relink the Application with a modified version of
- the Linked Version to produce a modified Combined Work, in the
- manner specified by section 6 of the GNU GPL for conveying
- Corresponding Source.
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
- 1) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (a) uses at run time
- a copy of the Library already present on the user's computer
- system, and (b) will operate properly with a modified version
- of the Library that is interface-compatible with the Linked
- Version.
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
- e) Provide Installation Information, but only if you would otherwise
- be required to provide such information under section 6 of the
- GNU GPL, and only to the extent that such information is
- necessary to install and execute a modified version of the
- Combined Work produced by recombining or relinking the
- Application with a modified version of the Linked Version. (If
- you use option 4d0, the Installation Information must accompany
- the Minimal Corresponding Source and Corresponding Application
- Code. If you use option 4d1, you must provide the Installation
- Information in the manner specified by section 6 of the GNU GPL
- for conveying Corresponding Source.)
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
- 5. Combined Libraries.
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
- You may place library facilities that are a work based on the
-Library side by side in a single library together with other library
-facilities that are not Applications and are not covered by this
-License, and convey such a combined library under terms of your
-choice, if you do both of the following:
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
- a) Accompany the combined library with a copy of the same work based
- on the Library, uncombined with any other library facilities,
- conveyed under the terms of this License.
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
- b) Give prominent notice with the combined library that part of it
- is a work based on the Library, and explaining where to find the
- accompanying uncombined form of the same work.
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
- 6. Revised Versions of the GNU Lesser General Public License.
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
- The Free Software Foundation may publish revised and/or new versions
-of the GNU Lesser General Public License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns.
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
- Each version is given a distinguishing version number. If the
-Library as you received it specifies that a certain numbered version
-of the GNU Lesser General Public License "or any later version"
-applies to it, you have the option of following the terms and
-conditions either of that published version or of any later version
-published by the Free Software Foundation. If the Library as you
-received it does not specify a version number of the GNU Lesser
-General Public License, you may choose any version of the GNU Lesser
-General Public License ever published by the Free Software Foundation.
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
- If the Library as you received it specifies that a proxy can decide
-whether future versions of the GNU Lesser General Public License shall
-apply, that proxy's public statement of acceptance of any version is
-permanent authorization for you to choose that version for the
-Library.
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ , 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/MANIFEST.in b/MANIFEST.in
index 91e542f..30b3b7f 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,7 +1,6 @@
-include MANIFEST.in
-include stdeb.cfg
recursive-include data *
-recursive-include debian *
-recursive-include revpipyload *
-global-exclude test/*
-global-exclude *.pyc
+include LICENSE.txt
+include Makefile
+include MANIFEST.in
+include requirements.txt
+include setup.py
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..25345b1
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,43 @@
+SHELL := bash
+MAKEFLAGS = --no-print-directory --no-builtin-rules
+.DEFAULT_GOAL = all
+
+# Variables
+PACKAGE = revpipyload
+
+# If virtualenv exists, use it. If not, use PATH to find, except python3
+SYSTEM_PYTHON = /usr/bin/python3
+PYTHON = $(or $(wildcard venv/bin/python), $(SYSTEM_PYTHON))
+
+all: build
+
+.PHONY: all
+
+## Environment
+venv:
+ $(SYSTEM_PYTHON) -m venv venv
+ source venv/bin/activate && \
+ python3 -m pip install --upgrade pip && \
+ python3 -m pip install -r requirements.txt
+ exit 0
+
+.PHONY: venv
+
+## Build, install
+build:
+ $(PYTHON) -m setup sdist
+ $(PYTHON) -m setup bdist_wheel
+
+install: build
+ $(PYTHON) -m pip install dist/$(PACKAGE)-*.whl
+
+.PHONY: build install
+
+## Clean
+clean:
+ rm -rf build dist src/*.egg-info *.spec
+
+clean-all: clean
+ rm -R venv
+
+.PHONY: clean clean-all
diff --git a/debian/postinst b/debian/postinst
deleted file mode 100755
index a61d0cc..0000000
--- a/debian/postinst
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-
-set -e
-
-PATH=/bin:/sbin:/usr/bin:/usr/sbin
-
-case "$1" in
- configure)
- cat <<-END
-
- ========== Important RevPiPyLoad post-installation note ==========
-
- The XML-RPC service is bind to localhost, only. To access the
- daemon via RevPiCommander from your network, please change the
- bindip in /etc/revpipyload/revpipyload.conf or execute:
-
- sudo revpipyload_secure_installation
-
- END
- ;;
-esac
-
-#DEBHELPER#
-
-exit 0
diff --git a/debian/revpipyload.default b/debian/revpipyload.default
deleted file mode 100644
index 41d49e5..0000000
--- a/debian/revpipyload.default
+++ /dev/null
@@ -1,11 +0,0 @@
-# Defaults for revpipyload initscript
-# sourced by /etc/init.d/revpipyload
-# installed at /etc/default/revpipyload by the maintainer scripts
-
-#
-# This is a POSIX shell fragment
-#
-
-# Additional options that are passed to the Daemon.
-# For verbose logging add -v or -vv
-DAEMON_ARGS=""
diff --git a/debian/revpipyload.init b/debian/revpipyload.init
deleted file mode 100755
index 8cbad9f..0000000
--- a/debian/revpipyload.init
+++ /dev/null
@@ -1,128 +0,0 @@
-#! /bin/sh
-### BEGIN INIT INFO
-# Provides: revpipyload
-# Required-Start: $remote_fs $syslog $piControl
-# Required-Stop: $remote_fs $syslog $piControl
-# Default-Start: 2 3 4 5
-# Default-Stop: 0 1 6
-# Short-Description: PLC services for RevolutionPi
-# Description: This file manages the RevPiPyLoad on system
-# boot. The Loader starts and monitors your python plc
-# program and other PLC services.
-### END INIT INFO
-
-# Author: Akira Naru Takizawa
-
-PATH=/sbin:/usr/sbin:/bin:/usr/bin
-DESC="PLC services for RevolutionPi"
-NAME=revpipyload
-DAEMON_ARGS=""
-PIDFILE=/var/run/$NAME.pid
-SCRIPTNAME=/etc/init.d/$NAME
-DAEMON=/usr/share/revpipyload/revpipyload.py
-
-# Exit if the package is not installed
-[ -x "$DAEMON" ] || exit 0
-
-# Read configuration variable file if it is present
-[ -r /etc/default/$NAME ] && . /etc/default/$NAME
-
-# Load the VERBOSE setting and other rcS variables
-. /lib/init/vars.sh
-
-# Define LSB log_* functions.
-# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
-# and status_of_proc is working.
-. /lib/lsb/init-functions
-
-# Codepage for Python (do not change)
-export LANG=C.UTF-8
-
-#
-# Function that starts the daemon/service
-#
-do_start()
-{
- # Return
- # 0 if daemon has been started
- # 1 if daemon was already running
- # 2 if daemon could not be started
- start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null || return 1
- start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- -d $DAEMON_ARGS || return 2
-}
-
-#
-# Function that stops the daemon/service
-#
-do_stop()
-{
- # Return
- # 0 if daemon has been stopped
- # 1 if daemon was already stopped
- # 2 if daemon could not be stopped
- # other if a failure occurred
- start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE
- RETVAL="$?"
- [ "$RETVAL" = 2 ] && return 2
- start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
- [ "$?" = 2 ] && return 2
- rm -f $PIDFILE
- return 0
-}
-
-#
-# Function that sends a SIGHUP to the daemon/service
-#
-do_reload() {
- start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE
- return 0
-}
-
-case "$1" in
- start)
- [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
- do_start
-# case "$?" in
-# 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
-# 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
-# esac
- ;;
- stop)
- [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
- do_stop
-# case "$?" in
-# 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
-# 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
-# esac
- ;;
- status)
- status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
- ;;
- reload|force-reload)
- log_daemon_msg "Reloading $DESC" "$NAME"
- do_reload
- log_end_msg $?
- ;;
- restart)
- log_daemon_msg "Restarting $DESC" "$NAME"
- do_stop
- case "$?" in
- 0|1)
- do_start
- case "$?" in
- 0) log_end_msg 0 ;;
- 1) log_end_msg 1 ;; # Old process is still running
- *) log_end_msg 1 ;; # Failed to start
- esac
- ;;
- *)
- # Failed to stop
- log_end_msg 1
- ;;
- esac
- ;;
- *)
- echo "Usage: $SCRIPTNAME {start|stop|status|restart|reload}" >&2
- exit 3
- ;;
-esac
diff --git a/debian/revpipyload.logrotate b/debian/revpipyload.logrotate
deleted file mode 100644
index 252c34e..0000000
--- a/debian/revpipyload.logrotate
+++ /dev/null
@@ -1,15 +0,0 @@
-/var/log/revpipyload
-/var/log/revpipyloadapp
-{
- rotate 6
- weekly
- maxsize 1M
- compress
- delaycompress
- missingok
- notifempty
- sharedscripts
- postrotate
- /bin/kill -s USR1 `cat /var/run/revpipyload.pid` > /dev/null 2>&1 || true
- endscript
-}
diff --git a/docs/Makefile b/docs/Makefile
deleted file mode 100644
index d09b27e..0000000
--- a/docs/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-# Minimal makefile for Sphinx documentation
-#
-
-# You can set these variables from the command line.
-SPHINXOPTS =
-SPHINXBUILD = sphinx-build
-SPHINXPROJ = RevPiPyLoad
-SOURCEDIR = .
-BUILDDIR = _build
-
-# Put it first so that "make" without argument is like "make help".
-help:
- @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
-
-.PHONY: help Makefile
-
-# Catch-all target: route all unknown targets to Sphinx using the new
-# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
-%: Makefile
- @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
\ No newline at end of file
diff --git a/docs/conf.py b/docs/conf.py
deleted file mode 100644
index 4b5eee4..0000000
--- a/docs/conf.py
+++ /dev/null
@@ -1,174 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-#
-# RevPiPyLoad documentation build configuration file, created by
-# sphinx-quickstart on Sun Oct 20 16:27:29 2019.
-#
-# This file is execfile()d with the current directory set to its
-# containing dir.
-#
-# Note that not all possible configuration values are present in this
-# autogenerated file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-#
-import os
-import sys
-sys.path.insert(0, os.path.abspath('../revpipyload'))
-
-from revpipyload import __version__
-
-# -- General configuration ------------------------------------------------
-
-# If your documentation needs a minimal Sphinx version, state it here.
-#
-# needs_sphinx = '1.0'
-
-# Add any Sphinx extension module names here, as strings. They can be
-# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
-# ones.
-extensions = [
- 'sphinx.ext.autodoc',
- 'sphinx.ext.todo',
- 'sphinx.ext.viewcode',
-]
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
-
-# The suffix(es) of source filenames.
-# You can specify multiple suffix as a list of string:
-#
-# source_suffix = ['.rst', '.md']
-source_suffix = '.rst'
-
-# The master toctree document.
-master_doc = 'index'
-
-# General information about the project.
-project = 'RevPiPyLoad'
-copyright = '2019, Sven Sager (NaruX)'
-author = 'Sven Sager (NaruX)'
-
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-# The short X.Y version.
-version = __version__
-# The full version, including alpha/beta/rc tags.
-release = ''
-
-# The language for content autogenerated by Sphinx. Refer to documentation
-# for a list of supported languages.
-#
-# This is also used if you do content translation via gettext catalogs.
-# Usually you set "language" from the command line for these cases.
-language = None
-
-# List of patterns, relative to source directory, that match files and
-# directories to ignore when looking for source files.
-# This patterns also effect to html_static_path and html_extra_path
-exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
-
-# If true, `todo` and `todoList` produce output, else they produce nothing.
-todo_include_todos = True
-
-
-# -- Options for HTML output ----------------------------------------------
-
-# The theme to use for HTML and HTML Help pages. See the documentation for
-# a list of builtin themes.
-#
-html_theme = 'alabaster'
-
-# Theme options are theme-specific and customize the look and feel of a theme
-# further. For a list of options available for each theme, see the
-# documentation.
-#
-# html_theme_options = {}
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
-
-# Custom sidebar templates, must be a dictionary that maps document names
-# to template names.
-#
-# This is required for the alabaster theme
-# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars
-html_sidebars = {
- '**': [
- 'relations.html', # needs 'show_related': True theme option to display
- 'searchbox.html',
- ]
-}
-
-
-# -- Options for HTMLHelp output ------------------------------------------
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'RevPiPyLoaddoc'
-
-
-# -- Options for LaTeX output ---------------------------------------------
-
-latex_elements = {
- # The paper size ('letterpaper' or 'a4paper').
- #
- # 'papersize': 'letterpaper',
-
- # The font size ('10pt', '11pt' or '12pt').
- #
- # 'pointsize': '10pt',
-
- # Additional stuff for the LaTeX preamble.
- #
- # 'preamble': '',
-
- # Latex figure (float) alignment
- #
- # 'figure_align': 'htbp',
-}
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title,
-# author, documentclass [howto, manual, or own class]).
-latex_documents = [
- (master_doc, 'RevPiPyLoad.tex', 'RevPiPyLoad Documentation',
- 'Sven Sager (NaruX)', 'manual'),
-]
-
-
-# -- Options for manual page output ---------------------------------------
-
-# One entry per manual page. List of tuples
-# (source start file, name, description, authors, manual section).
-man_pages = [
- (master_doc, 'revpipyload', 'RevPiPyLoad Documentation',
- [author], 1)
-]
-
-
-# -- Options for Texinfo output -------------------------------------------
-
-# Grouping the document tree into Texinfo files. List of tuples
-# (source start file, target name, title, author,
-# dir menu entry, description, category)
-texinfo_documents = [
- (master_doc, 'RevPiPyLoad', 'RevPiPyLoad Documentation',
- author, 'RevPiPyLoad', 'One line description of project.',
- 'Miscellaneous'),
-]
-
-
-
diff --git a/docs/helper.rst b/docs/helper.rst
deleted file mode 100644
index f282520..0000000
--- a/docs/helper.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-helper module
-=============
-
-.. automodule:: helper
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/docs/index.rst b/docs/index.rst
deleted file mode 100644
index 3dbc6c3..0000000
--- a/docs/index.rst
+++ /dev/null
@@ -1,20 +0,0 @@
-.. RevPiPyLoad documentation master file, created by
- sphinx-quickstart on Sun Oct 20 16:27:29 2019.
- You can adapt this file completely to your liking, but it should at least
- contain the root `toctree` directive.
-
-Welcome to RevPiPyLoad's documentation!
-=======================================
-
-.. toctree::
- :maxdepth: 2
- :caption: Contents:
-
-
-
-Indices and tables
-==================
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
diff --git a/docs/logsystem.rst b/docs/logsystem.rst
deleted file mode 100644
index 0e605a3..0000000
--- a/docs/logsystem.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-logsystem module
-================
-
-.. automodule:: logsystem
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/docs/modules.rst b/docs/modules.rst
deleted file mode 100644
index 0f9d1b2..0000000
--- a/docs/modules.rst
+++ /dev/null
@@ -1,17 +0,0 @@
-revpipyload
-===========
-
-.. toctree::
- :maxdepth: 4
-
- helper
- logsystem
- mqttserver
- picontrolserver
- plcsystem
- procimgserver
- proginit
- revpipyload
- shared
- testsystem
- xrpcserver
diff --git a/docs/mqttserver.rst b/docs/mqttserver.rst
deleted file mode 100644
index fc429de..0000000
--- a/docs/mqttserver.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-mqttserver module
-=================
-
-.. automodule:: mqttserver
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/docs/picontrolserver.rst b/docs/picontrolserver.rst
deleted file mode 100644
index b57830b..0000000
--- a/docs/picontrolserver.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-picontrolserver module
-======================
-
-.. automodule:: picontrolserver
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/docs/plcsystem.rst b/docs/plcsystem.rst
deleted file mode 100644
index 34939ca..0000000
--- a/docs/plcsystem.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-plcsystem module
-================
-
-.. automodule:: plcsystem
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/docs/procimgserver.rst b/docs/procimgserver.rst
deleted file mode 100644
index 4ea471a..0000000
--- a/docs/procimgserver.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-procimgserver module
-====================
-
-.. automodule:: procimgserver
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/docs/proginit.rst b/docs/proginit.rst
deleted file mode 100644
index 2226a87..0000000
--- a/docs/proginit.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-proginit module
-===============
-
-.. automodule:: proginit
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/docs/revpipyload.rst b/docs/revpipyload.rst
deleted file mode 100644
index 9353e88..0000000
--- a/docs/revpipyload.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-revpipyload module
-==================
-
-.. automodule:: revpipyload
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/docs/shared.rst b/docs/shared.rst
deleted file mode 100644
index 6323fbf..0000000
--- a/docs/shared.rst
+++ /dev/null
@@ -1,22 +0,0 @@
-shared package
-==============
-
-Submodules
-----------
-
-shared\.ipaclmanager module
----------------------------
-
-.. automodule:: shared.ipaclmanager
- :members:
- :undoc-members:
- :show-inheritance:
-
-
-Module contents
----------------
-
-.. automodule:: shared
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/docs/testsystem.rst b/docs/testsystem.rst
deleted file mode 100644
index 79288b7..0000000
--- a/docs/testsystem.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-testsystem module
-=================
-
-.. automodule:: testsystem
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/docs/xrpcserver.rst b/docs/xrpcserver.rst
deleted file mode 100644
index 67bf1fe..0000000
--- a/docs/xrpcserver.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-xrpcserver module
-=================
-
-.. automodule:: xrpcserver
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..30de828
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,5 @@
+setuptools>=58.0.4
+wheel
+
+paho-mqtt>=1.4.0
+revpimodio2>=2.6.0rc1
diff --git a/revpipyload/secure_installation.py b/revpipyload/secure_installation.py
deleted file mode 100755
index eb130ba..0000000
--- a/revpipyload/secure_installation.py
+++ /dev/null
@@ -1,182 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-"""
-Secure your installation of RevPiPyLoad.
-
-Exit codes:
- 1: Runtime error
- 2: Program did no changes on files
- 4: No root permissions
- 8: Write error to acl files
-"""
-__author__ = "Sven Sager"
-__copyright__ = "Copyright (C) 2020 Sven Sager"
-__license__ = "GPLv3"
-
-from configparser import ConfigParser
-from os import access, R_OK, system, getuid
-from re import match
-from sys import stdout, stderr
-
-from shared.ipaclmanager import IpAclManager
-
-CONFIG_FILE = "/etc/revpipyload/revpipyload.conf"
-
-if not access(CONFIG_FILE, R_OK):
- raise PermissionError("Can not access {0}".format(CONFIG_FILE))
-
-conf = ConfigParser()
-conf.read(CONFIG_FILE)
-
-aclxmlrpc = conf.get("XMLRPC", "aclfile")
-if not access(aclxmlrpc, R_OK):
- raise PermissionError("Can not access {0}".format(aclxmlrpc))
-
-# Load config values
-xmlrpc = conf.getboolean("XMLRPC", "xmlrpc", fallback=False)
-xmlrpcbindip = conf.get("XMLRPC", "bindip", fallback="127.0.0.1")
-
-# Prepare variables
-xmlrpcacl = IpAclManager(minlevel=0, maxlevel=4)
-xmlrpcacl.loadaclfile(aclxmlrpc)
-xmlrpc_only_localhost = xmlrpcbindip.find("127.") == 0 or xmlrpcbindip == ""
-
-# ----- Print summary of actual configuration
-stdout.write("""
-This will secure your installation of RevPiPyLoad.
-
-We found the following configuration files:
- RevPiPyLoad: {revpipyload}
- XML-RPC ACL: {aclxmlrpc}
-
-Access with RevPiPyControl is {xmlrpc}activated{source}
-""".format(
- revpipyload=CONFIG_FILE,
- aclxmlrpc=aclxmlrpc,
- xmlrpc="" if xmlrpc else "NOT ",
- source="" if not xmlrpc
- else " from this computer only (localhost)." if xmlrpc_only_localhost
- else " from ACL listed remote computers!"
-))
-
-
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-# region # REGION: Shared functions
-def save_xmlrpcacls():
- """Save new acl's to file."""
- if not xmlrpcacl.writeaclfile(aclname="XML-RPC"):
- stderr.write("Error while writing ACL file!\n")
- exit(8)
-
-
-def print_xmlrpcacls():
- """Print a list with all acl."""
- if xmlrpcacl.acl:
- stdout.write("\nThis is the actual ACL file ({0}):".format(aclxmlrpc))
- counter = 0
- for acl in xmlrpcacl.acl.split():
- stdout.write("\n" if counter % 2 == 0 else " | ")
- ip, level = acl.split(",")
- stdout.write("{0:15} - Level: {1:2}".format(ip, level))
- counter += 1
- stdout.write("\n")
- else:
- stderr.write(
- "\nWARNING: NO IP addresses defined in ACL!\n You will "
- "not be able to connect with RevPiPyControl at this moment!\n"
- )
-# endregion # # # # #
-
-
-try:
- if not xmlrpc_only_localhost:
- cmd = input("\nDo you want to check ACL listed computers? (y/N) ").lower()
- if cmd == "y":
- print_xmlrpcacls()
-
- if getuid() != 0:
- stderr.write("\nYou need root permissions to change values (sudo).\n")
- exit(4)
-
- cmd = input("\nDo you want to allow connections from remote hosts? (y/N) ").lower()
- if cmd == "y":
- conf.set("XMLRPC", "xmlrpc", "1")
- conf.set("XMLRPC", "bindip", "*")
-
- cmd = input("Reset the ACL file to allow all private networks? (y/N) ").lower()
- if cmd == "y":
- xmlrpcacl.acl = "127.*.*.*,4 " \
- "169.254.*.*,4 " \
- "10.*.*.*,4 " \
- "172.16.*.*,4 172.17.*.*,4 172.18.*.*,4 172.19.*.*,4 " \
- "172.20.*.*,4 172.21.*.*,4 172.22.*.*,4 172.23.*.*,4 " \
- "172.24.*.*,4 172.25.*.*,4 172.26.*.*,4 172.27.*.*,4 " \
- "172.28.*.*,4 172.29.*.*,4 172.30.*.*,4 172.31.*.*,4 " \
- "192.168.*.*,4"
- save_xmlrpcacls()
-
- else:
- cmd = input("Reset the ACL file by enter individual ip addresses to grant access? (y/N) ").lower()
- if cmd == "y":
- # Always set local host
- lst_ip = ["127.*.*.*,4 "]
- while True:
- cmd = input("Enter single IPv4 address | Press RETURN to complete: ")
- if not cmd:
- xmlrpcacl.acl = " ".join(lst_ip)
- save_xmlrpcacls()
- break
- elif match(r"([\d*]{1,3}\.){3}[\d*]{1,3}", cmd):
- ip_level = "{0},4".format(cmd)
- if ip_level not in lst_ip:
- lst_ip.append(ip_level)
- else:
- stderr.write("Wrong format (0.0.0.0)\n")
-
- else:
- cmd = input("Do you want to allow connections from localhost ONLY? (y/N) ").lower()
- if cmd == "y":
- conf.set("XMLRPC", "xmlrpc", "1")
- conf.set("XMLRPC", "bindip", "127.0.0.1")
-
- cmd = input("Reset the ACL file to allow localhost connections only? (y/N) ").lower()
- if cmd == "y":
- xmlrpcacl.acl = "127.*.*.*,4 "
- save_xmlrpcacls()
-
- else:
- cmd = input(
- "\nWARNING: This will disable the possibility to connect with "
- "RevPiPyControl!\n Are you sure? (y/N) "
- ).lower()
- if cmd == "y":
- conf.set("XMLRPC", "xmlrpc", "0")
- conf.set("XMLRPC", "bindip", "127.0.0.1")
- xmlrpcacl.acl = ""
- save_xmlrpcacls()
- else:
- stdout.write("\nWe did no changes!\n")
- exit(2)
-
- # Write configuration
- with open(CONFIG_FILE, "w") as fh:
- conf.write(fh)
-
- print_xmlrpcacls()
-
-except KeyboardInterrupt:
- stdout.write("\n\nWe did no changes!\n")
- exit(2)
-
-if system("/etc/init.d/revpipyload status > /dev/null") == 0:
- try:
- cmd = input("\nDo you want to apply the new settings now? (Y/n) ").lower()
- if cmd in ("", "y"):
- system("/etc/init.d/revpipyload reload")
- else:
- stderr.write(
- "\nYou have to activate the new settings for RevPiPyLoad!\n"
- " sudo /etc/init.d/revpipyload reload\n"
- )
- except KeyboardInterrupt:
- pass
diff --git a/setup.py b/setup.py
index 755f5dd..6c93093 100644
--- a/setup.py
+++ b/setup.py
@@ -1,79 +1,55 @@
-#! /usr/bin/env python3
# -*- coding: utf-8 -*-
-"""Setupscript fuer RevPiPyLoad."""
+"""Setup script for RevPiPyLoad."""
__author__ = "Sven Sager"
-__copyright__ = "Copyright (C) 2018 Sven Sager"
-__license__ = "GPLv3"
-import distutils.command.install_egg_info
-from glob import glob
-from distutils.core import setup
+__copyright__ = "Copyright (C) 2023 Sven Sager"
+__license__ = "GPLv2"
+from setuptools import find_namespace_packages, setup
-class MyEggInfo(distutils.command.install_egg_info.install_egg_info):
-
- """Disable egg_info installation, seems pointless for a non-library."""
-
- def run(self):
- """just pass egg_info."""
- pass
-
+from src.revpipyload import __version__
setup(
+ name="revpipyload",
+ version=__version__,
+
+ packages=find_namespace_packages("src"),
+ package_dir={'': 'src'},
+ include_package_data=True,
+
+ install_requires=[
+ "paho-mqtt >= 1.4.0",
+ "revpimodio2 >= 2.6.0rc1",
+ ],
+ entry_points={
+ 'console_scripts': [
+ 'revpipyloadd = revpipyload.revpipyload:main',
+ 'revpipyload_secure_installation = revpipyload.secure_installation:main',
+ ],
+ },
+
+ platforms=["revolution pi"],
+
+ url="https://revpimodio.org/revpipyplc/",
+ license="GPLv2",
author="Sven Sager",
author_email="akira@narux.de",
- url="https://revpimodio.org/revpipyplc/",
maintainer="Sven Sager",
maintainer_email="akira@revpimodio.org",
- license="LGPLv3",
- name="revpipyload",
- version="0.9.8a2",
-
- scripts=[
- "data/revpipyload",
- "data/revpipyload_secure_installation",
- ],
- packages=[],
-
- install_requires=["revpimodio2 >= 2.5.0"],
- python_requires=">=3.2",
-
- data_files=[
- ("/etc/avahi/services", [
- "data/etc/avahi/services/revpipyload.service",
- ]),
- ("/etc/revpipyload", [
- "data/etc/revpipyload/aclplcslave.conf",
- "data/etc/revpipyload/aclxmlrpc.conf",
- "data/etc/revpipyload/replace_ios.conf",
- "data/etc/revpipyload/revpipyload.conf",
- ]),
- ("share/revpipyload", glob("revpipyload/*.*")),
- ("share/revpipyload/shared", glob("revpipyload/shared/*.*")),
- ("share/revpipyload/paho", ["lib/paho/__init__.py"]),
- ("share/revpipyload/paho/mqtt", glob("lib/paho/mqtt/*.*")),
- ("/var/lib/revpipyload", [
- "data/var/lib/revpipyload/.placeholder",
- ])
- ],
-
description="PLC Loader für Python-Projekte auf den RevolutionPi",
- long_description=""
- "Dieses Programm startet beim Systemstart ein angegebenes Python PLC \n"
- "Programm. Es überwacht das Programm und startet es im Fehlerfall neu. \n"
- "Bei Absturz kann das gesamte /dev/piControl0 auf 0x00 gesetzt werden. \n"
- "Außerdem stellt es einen XML-RPC Server bereit, über den die Software \n"
- "auf den RevPi geladen werden kann. Das Prozessabbild kann über ein \n"
- "Tool zur Laufzeit überwacht werden.",
-
+ long_description="Dieses Programm startet beim Systemstart ein angegebenes Python PLC \n"
+ "Programm. Es überwacht das Programm und startet es im Fehlerfall neu. \n"
+ "Bei Absturz kann das gesamte /dev/piControl0 auf 0x00 gesetzt werden. \n"
+ "Außerdem stellt es einen XML-RPC Server bereit, über den die Software \n"
+ "auf den RevPi geladen werden kann. Das Prozessabbild kann über ein \n"
+ "Tool zur Laufzeit überwacht werden.",
+ keywords=["revpi", "revolution pi", "revpimodio", "plc"],
classifiers=[
"Development Status :: 5 - Production/Stable",
"Environment :: No Input/Output (Daemon)",
"Intended Audience :: Manufacturing",
- "License :: OSI Approved :: "
- "GNU Lesser General Public License v3 (LGPLv3)",
+ "License :: OSI Approved :: GNU General Public License v2 (GPLv2)",
"Operating System :: POSIX :: Linux",
"Topic :: System :: Operating System",
],
- cmdclass={"install_egg_info": MyEggInfo},
)
diff --git a/src/revpipyload/__init__.py b/src/revpipyload/__init__.py
new file mode 100644
index 0000000..3cc1fe7
--- /dev/null
+++ b/src/revpipyload/__init__.py
@@ -0,0 +1,7 @@
+# -*- coding: utf-8 -*-
+"""Package: RevPiPyLoad."""
+__author__ = "Sven Sager"
+__copyright__ = "Copyright (C) 2023 Sven Sager"
+__license__ = "GPLv2"
+__package__ = "revpipyload"
+__version__ = "0.10.0rc1"
diff --git a/src/revpipyload/__main__.py b/src/revpipyload/__main__.py
new file mode 100644
index 0000000..6c040c1
--- /dev/null
+++ b/src/revpipyload/__main__.py
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+"""Start main application of this package."""
+__author__ = "Sven Sager"
+__copyright__ = "Copyright (C) 2023 Sven Sager"
+__license__ = "GPLv2"
+
+# If we are running from a wheel, add the wheel to sys.path
+if __package__ == "":
+ from os.path import dirname
+ from sys import path
+
+ # __file__ is package-*.whl/package/__main__.py
+ # Resulting path is the name of the wheel itself
+ package_path = dirname(dirname(__file__))
+ path.insert(0, package_path)
+
+if __name__ == "__main__":
+ import sys
+
+ if len(sys.argv) == 2 and "--version" in sys.argv:
+ # Catch --version, if this is the only argument (sys.argv[0] is always the script name)
+ from revpipyload import __version__
+
+ print(__version__)
+ sys.exit(0)
+
+ else:
+ from revpipyload.revpipyload import main
+
+ # Run the main application of this package
+ sys.exit(main())
diff --git a/revpipyload/helper.py b/src/revpipyload/helper.py
similarity index 97%
rename from revpipyload/helper.py
rename to src/revpipyload/helper.py
index 8a7462d..45d0b1a 100644
--- a/revpipyload/helper.py
+++ b/src/revpipyload/helper.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""Helperfunktionen fuer das gesamte RevPiPyLoad-System."""
__author__ = "Sven Sager"
-__copyright__ = "Copyright (C) 2020 Sven Sager"
+__copyright__ = "Copyright (C) 2023 Sven Sager"
__license__ = "GPLv3"
import os
@@ -10,7 +10,7 @@ from json import loads
from re import match as rematch
from subprocess import PIPE, Popen
-import proginit
+from . import proginit
def _setuprt(pid, evt_exit):
@@ -122,7 +122,7 @@ def get_revpiled_address(configrsc_bytes):
if device.get("productType", "0") == "135":
# On the Flat device the LEDs are 2 Bytes (last Bit is wd)
byte_address += 1
- proginit.logger.debug("found revpi_led_address on {0} byte".format(byte_address))
+ proginit.logger.debug("found revpi_led_address on byte {0}".format(byte_address))
except Exception:
pass
break
diff --git a/revpipyload/logsystem.py b/src/revpipyload/logsystem.py
similarity index 98%
rename from revpipyload/logsystem.py
rename to src/revpipyload/logsystem.py
index 4e182eb..4ae39f1 100644
--- a/revpipyload/logsystem.py
+++ b/src/revpipyload/logsystem.py
@@ -1,16 +1,17 @@
# -*- coding: utf-8 -*-
"""Modul fuer die Verwaltung der Logdateien."""
__author__ = "Sven Sager"
-__copyright__ = "Copyright (C) 2018 Sven Sager"
-__license__ = "GPLv3"
+__copyright__ = "Copyright (C) 2023 Sven Sager"
+__license__ = "GPLv2"
+
import os
-import proginit
from threading import Event, Lock, Thread
from xmlrpc.client import Binary
+from . import proginit
+
class LogReader:
-
"""Ermoeglicht den Zugriff auf die Logdateien.
Beinhaltet Funktionen fuer den Abruf der gesamten Logdatei fuer das
@@ -91,7 +92,6 @@ class LogReader:
class PipeLogwriter(Thread):
-
"""File PIPE fuer das Schreiben des APP Log.
Spezieller LogFile-Handler fuer die Ausgabe des subprocess fuer das Python
diff --git a/revpipyload/mqttserver.py b/src/revpipyload/mqttserver.py
similarity index 98%
rename from revpipyload/mqttserver.py
rename to src/revpipyload/mqttserver.py
index 3a97480..dc6e5d4 100644
--- a/revpipyload/mqttserver.py
+++ b/src/revpipyload/mqttserver.py
@@ -1,18 +1,20 @@
# -*- coding: utf-8 -*-
"""Stellt die MQTT Uebertragung fuer IoT-Zwecke bereit."""
__author__ = "Sven Sager"
-__copyright__ = "Copyright (C) 2020 Sven Sager"
-__license__ = "GPLv3"
-import proginit
-import revpimodio2
+__copyright__ = "Copyright (C) 2023 Sven Sager"
+__license__ = "GPLv2"
+
from os.path import join
-from paho.mqtt.client import Client, connack_string
from ssl import CERT_NONE
-from threading import Thread, Event
+from threading import Event, Thread
+
+import revpimodio2
+from paho.mqtt.client import Client, connack_string
+
+from . import proginit
class MqttServer(Thread):
-
"""Server fuer die Uebertragung des Prozessabbilds per MQTT."""
def __init__(
@@ -288,7 +290,8 @@ class MqttServer(Thread):
try:
value = value.to_bytes(io.length, io.byteorder)
except OverflowError:
- proginit.logger.error("can not convert value '{0}' to fitting bytes for output '{1}'".format(value, ioname))
+ proginit.logger.error(
+ "can not convert value '{0}' to fitting bytes for output '{1}'".format(value, ioname))
return
elif value.lower() == "false" and not io_needbytes:
diff --git a/revpipyload/picontrolserver.py b/src/revpipyload/picontrolserver.py
similarity index 99%
rename from revpipyload/picontrolserver.py
rename to src/revpipyload/picontrolserver.py
index bbffaac..715d54b 100644
--- a/revpipyload/picontrolserver.py
+++ b/src/revpipyload/picontrolserver.py
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
"""Modul fuer die Verwaltung der PLC-Slave Funktionen."""
__author__ = "Sven Sager"
-__copyright__ = "Copyright (C) 2018 Sven Sager"
-__license__ = "GPLv3"
+__copyright__ = "Copyright (C) 2023 Sven Sager"
+__license__ = "GPLv2"
import socket
from fcntl import ioctl
@@ -10,8 +10,8 @@ from struct import pack, unpack
from threading import Event, Thread
from timeit import default_timer
-import proginit
-from shared.ipaclmanager import IpAclManager
+from . import proginit
+from .shared.ipaclmanager import IpAclManager
# Hashvalues
HASH_NULL = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
diff --git a/revpipyload/plcsystem.py b/src/revpipyload/plcsystem.py
similarity index 97%
rename from revpipyload/plcsystem.py
rename to src/revpipyload/plcsystem.py
index 30004c0..249d70a 100644
--- a/revpipyload/plcsystem.py
+++ b/src/revpipyload/plcsystem.py
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
"""Modul fuer die Verwaltung der PLC Funktionen."""
__author__ = "Sven Sager"
-__copyright__ = "Copyright (C) 2020 Sven Sager"
-__license__ = "GPLv3"
+__copyright__ = "Copyright (C) 2023 Sven Sager"
+__license__ = "GPLv2"
import os
import shlex
@@ -12,10 +12,10 @@ from sys import stdout as sysstdout
from threading import Event, Thread
from time import asctime, sleep
-import proginit
-from helper import _setuprt, _zeroprocimg
-from logsystem import PipeLogwriter
-from watchdogs import SoftwareWatchdog
+from . import proginit
+from .helper import _setuprt, _zeroprocimg
+from .logsystem import PipeLogwriter
+from .watchdogs import SoftwareWatchdog
class RevPiPlc(Thread):
diff --git a/revpipyload/procimgserver.py b/src/revpipyload/procimgserver.py
similarity index 97%
rename from revpipyload/procimgserver.py
rename to src/revpipyload/procimgserver.py
index eadaa5d..4df4824 100644
--- a/revpipyload/procimgserver.py
+++ b/src/revpipyload/procimgserver.py
@@ -6,18 +6,19 @@ IO-Check bei Inbetriebname durchzufuehren.
"""
__author__ = "Sven Sager"
-__copyright__ = "Copyright (C) 2020 Sven Sager"
-__license__ = "GPLv3"
+__copyright__ = "Copyright (C) 2023 Sven Sager"
+__license__ = "GPLv2"
+
import pickle
-import proginit
-import revpimodio2
from xmlrpc.client import Binary
+import revpimodio2
from revpimodio2.io import StructIO
+from . import proginit
+
class ProcimgServer:
-
"""Serverkomponente fuer zusaetzliche XML-RPC Funktionen.
Diese Klasse registriert zusaetzliche Funktionen an einem besthenden
@@ -152,6 +153,7 @@ class ProcimgServer:
try:
# Neuen Wert übernehmen
+ # fixme: Warum wird hier alles in Bytes umgewandelt?
if type(value) == bytes or type(value) == bool:
self.rpi.io[io].set_value(value)
else:
diff --git a/revpipyload/proginit.py b/src/revpipyload/proginit.py
similarity index 99%
rename from revpipyload/proginit.py
rename to src/revpipyload/proginit.py
index 19ac385..79cebe0 100644
--- a/revpipyload/proginit.py
+++ b/src/revpipyload/proginit.py
@@ -2,7 +2,7 @@
"""Main functions of our program."""
__author__ = "Sven Sager"
__copyright__ = "Copyright (C) 2018 Sven Sager"
-__license__ = "GPLv3"
+__license__ = "GPLv2"
import logging
import os
@@ -82,7 +82,6 @@ def configure():
# Prüfen ob als Daemon ausgeführt werden soll
global forked
pidfile = "/var/run/revpipyload.pid"
- pid = 0
if pargs.daemon and not forked:
# Prüfen ob daemon schon läuft
if os.path.exists(pidfile):
diff --git a/revpipyload/revpipyload.py b/src/revpipyload/revpipyload.py
old mode 100755
new mode 100644
similarity index 94%
rename from revpipyload/revpipyload.py
rename to src/revpipyload/revpipyload.py
index 24391ce..e036224
--- a/revpipyload/revpipyload.py
+++ b/src/revpipyload/revpipyload.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""Revolution Pi Python PLC Loader.
@@ -26,9 +25,8 @@ begrenzt werden!
"""
__author__ = "Sven Sager"
-__copyright__ = "Copyright (C) 2020 Sven Sager"
-__license__ = "GPLv3"
-__version__ = "0.9.8"
+__copyright__ = "Copyright (C) 2023 Sven Sager"
+__license__ = "GPLv2"
import gzip
import os
@@ -38,20 +36,22 @@ import zipfile
from configparser import ConfigParser
from hashlib import md5
from json import loads as jloads
+from re import search
from shutil import rmtree
from tempfile import mkstemp
from threading import Event
from time import asctime, time
from xmlrpc.client import Binary
-import logsystem
-import picontrolserver
-import plcsystem
-import proginit
-from helper import get_revpiled_address, pi_control_reset, refullmatch
-from shared.ipaclmanager import IpAclManager
-from watchdogs import ResetDriverWatchdog
-from xrpcserver import SaveXMLRPCServer
+from . import __version__
+from . import logsystem
+from . import picontrolserver
+from . import plcsystem
+from . import proginit
+from .helper import get_revpiled_address, pi_control_reset, refullmatch
+from .shared.ipaclmanager import IpAclManager
+from .watchdogs import ResetDriverWatchdog
+from .xrpcserver import SaveXMLRPCServer
min_revpimodio = "2.5.0"
@@ -77,6 +77,10 @@ class RevPiPyLoad:
self.xsrv = None
self.xml_ps = None
+ # Generate version number for RevPi Commander, it will parse each part via int()
+ version_match = search(r"(\d+\.){2}\d+", __version__)
+ self._pyload_version = version_match.group(0) if version_match else "0.0.0"
+
# Dateimerker
self.pictorymtime = 0
self.replaceiosmtime = 0
@@ -115,32 +119,18 @@ class RevPiPyLoad:
elif "MQTT" not in self.globalconfig:
return True
else:
- return (
- self.replace_ios_config !=
- self.globalconfig["DEFAULT"].get("replace_ios", "") or
- self.mqtt !=
- self.globalconfig["MQTT"].getboolean("mqtt", False) or
- self.mqttbasetopic !=
- self.globalconfig["MQTT"].get("basetopic", "") or
- self.mqttsendinterval !=
- self.globalconfig["MQTT"].getint("sendinterval", 30) or
- self.mqttbroker_address !=
- self.globalconfig["MQTT"].get("broker_address", "localhost") or
- self.mqttport !=
- self.globalconfig["MQTT"].getint("port", 1883) or
- self.mqtttls_set !=
- self.globalconfig["MQTT"].getboolean("tls_set", False) or
- self.mqttusername !=
- self.globalconfig["MQTT"].get("username", "") or
- self.mqttpassword !=
- self.globalconfig["MQTT"].get("password", "") or
- self.mqttclient_id !=
- self.globalconfig["MQTT"].get("client_id", "") or
- self.mqttsend_on_event !=
- self.globalconfig["MQTT"].getboolean("send_on_event", False) or
- self.mqttwrite_outputs !=
- self.globalconfig["MQTT"].getboolean("write_outputs", False)
- )
+ return self.replace_ios_config != self.globalconfig["DEFAULT"].get("replace_ios", "") \
+ or self.mqtt != self.globalconfig["MQTT"].getboolean("mqtt", False) \
+ or self.mqttbasetopic != self.globalconfig["MQTT"].get("basetopic", "") \
+ or self.mqttsendinterval != self.globalconfig["MQTT"].getint("sendinterval", 30) \
+ or self.mqttbroker_address != self.globalconfig["MQTT"].get("broker_address", "localhost") \
+ or self.mqttport != self.globalconfig["MQTT"].getint("port", 1883) \
+ or self.mqtttls_set != self.globalconfig["MQTT"].getboolean("tls_set", False) \
+ or self.mqttusername != self.globalconfig["MQTT"].get("username", "") \
+ or self.mqttpassword != self.globalconfig["MQTT"].get("password", "") \
+ or self.mqttclient_id != self.globalconfig["MQTT"].get("client_id", "") \
+ or self.mqttsend_on_event != self.globalconfig["MQTT"].getboolean("send_on_event", False) \
+ or self.mqttwrite_outputs != self.globalconfig["MQTT"].getboolean("write_outputs", False)
def _check_mustrestart_plcslave(self):
"""Prueft ob sich kritische Werte veraendert haben.
@@ -157,12 +147,9 @@ class RevPiPyLoad:
ip = "127.0.0.1"
port = self.globalconfig["PLCSLAVE"].getint("port", 55234)
- return (
- self.plcslave !=
- self.globalconfig["PLCSLAVE"].getboolean("plcslave", False) or
- self.plcslavebindip != ip or
- self.plcslaveport != port
- )
+ return self.plcslave != self.globalconfig["PLCSLAVE"].getboolean("plcslave", False) \
+ or self.plcslavebindip != ip \
+ or self.plcslaveport != port
def _check_mustrestart_plcprogram(self):
"""Prueft ob sich kritische Werte veraendert haben.
@@ -170,25 +157,18 @@ class RevPiPyLoad:
if self.plc is None:
return True
else:
- return (
- self.plcworkdir !=
- self.globalconfig["DEFAULT"].get("plcworkdir", ".") or
- self.plcprogram !=
- self.globalconfig["DEFAULT"].get("plcprogram", "none.py") or
- self.plcarguments !=
- self.globalconfig["DEFAULT"].get("plcarguments", "") or
- self.plcuid !=
- self.globalconfig["DEFAULT"].getint("plcuid", 65534) or
- self.plcgid !=
- self.globalconfig["DEFAULT"].getint("plcgid", 65534) or
- self.pythonversion !=
- self.globalconfig["DEFAULT"].getint("pythonversion", 3) or
- self.rtlevel !=
- self.globalconfig["DEFAULT"].getint("rtlevel", 0) or (
- not self.plc.is_alive() and not self.autostart and
- self.globalconfig["DEFAULT"].getboolean("autostart", False)
+ return self.plcworkdir != self.globalconfig["DEFAULT"].get("plcworkdir", ".") \
+ or self.plcprogram != self.globalconfig["DEFAULT"].get("plcprogram", "none.py") \
+ or self.plcarguments != self.globalconfig["DEFAULT"].get("plcarguments", "") \
+ or self.plcuid != self.globalconfig["DEFAULT"].getint("plcuid", 65534) \
+ or self.plcgid != self.globalconfig["DEFAULT"].getint("plcgid", 65534) \
+ or self.pythonversion != self.globalconfig["DEFAULT"].getint("pythonversion", 3) \
+ or self.rtlevel != self.globalconfig["DEFAULT"].getint("rtlevel", 0) \
+ or (
+ not self.plc.is_alive()
+ and not self.autostart
+ and self.globalconfig["DEFAULT"].getboolean("autostart", False)
)
- )
def _loadconfig(self):
"""Load configuration file and setup modul."""
@@ -412,7 +392,7 @@ class RevPiPyLoad:
self.xsrv.register_multicall_functions()
# Allgemeine Funktionen
- self.xsrv.register_function(0, lambda: __version__, "version")
+ self.xsrv.register_function(0, lambda: self._pyload_version, "version")
self.xsrv.register_function(0, lambda acl: acl, "xmlmodus")
# XML Modus 1 Nur Logs lesen und PLC Programm neu starten
@@ -810,7 +790,7 @@ class RevPiPyLoad:
# Dateiveränderungen prüfen mit beiden Funktionen!
if (reset_driver_detected or
- pictory_reset_driver.not_implemented) and \
+ pictory_reset_driver.not_implemented) and \
self.check_pictory_changed():
file_changed = True
@@ -1477,7 +1457,8 @@ class RevPiPyLoad:
return False
-if __name__ == "__main__":
+def main() -> int:
+ """Entry point for RevPiPyLoad."""
# Programmeinstellungen konfigurieren
proginit.configure()
@@ -1493,3 +1474,11 @@ if __name__ == "__main__":
# Aufräumen
proginit.cleanup()
+
+ return 0
+
+
+if __name__ == '__main__':
+ import sys
+
+ sys.exit(main())
diff --git a/src/revpipyload/secure_installation.py b/src/revpipyload/secure_installation.py
new file mode 100644
index 0000000..070650c
--- /dev/null
+++ b/src/revpipyload/secure_installation.py
@@ -0,0 +1,191 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+Secure your installation of RevPiPyLoad.
+
+Exit codes:
+ 1: Runtime error
+ 2: Program did no changes on files
+ 4: No root permissions
+ 8: Write error to acl files
+"""
+__author__ = "Sven Sager"
+__copyright__ = "Copyright (C) 2023 Sven Sager"
+__license__ = "GPLv2"
+
+
+def main() -> int:
+ """Secure installation script to use on Revolution Pi."""
+ from configparser import ConfigParser
+ from os import R_OK, access, getuid, system
+ from re import match
+ from sys import stderr, stdout
+
+ from .shared.ipaclmanager import IpAclManager
+
+ CONFIG_FILE = "/etc/revpipyload/revpipyload.conf"
+
+ if not access(CONFIG_FILE, R_OK):
+ raise PermissionError("Can not access {0}".format(CONFIG_FILE))
+
+ conf = ConfigParser()
+ conf.read(CONFIG_FILE)
+
+ aclxmlrpc = conf.get("XMLRPC", "aclfile")
+ if not access(aclxmlrpc, R_OK):
+ raise PermissionError("Can not access {0}".format(aclxmlrpc))
+
+ # Load config values
+ xmlrpc = conf.getboolean("XMLRPC", "xmlrpc", fallback=False)
+ xmlrpcbindip = conf.get("XMLRPC", "bindip", fallback="127.0.0.1")
+
+ # Prepare variables
+ xmlrpcacl = IpAclManager(minlevel=0, maxlevel=4)
+ xmlrpcacl.loadaclfile(aclxmlrpc)
+ xmlrpc_only_localhost = xmlrpcbindip.find("127.") == 0 or xmlrpcbindip == ""
+
+ # ----- Print summary of actual configuration
+ stdout.write("""
+ This will secure your installation of RevPiPyLoad.
+
+ We found the following configuration files:
+ RevPiPyLoad: {revpipyload}
+ XML-RPC ACL: {aclxmlrpc}
+
+ Access with RevPiPyControl is {xmlrpc}activated{source}
+ """.format(
+ revpipyload=CONFIG_FILE,
+ aclxmlrpc=aclxmlrpc,
+ xmlrpc="" if xmlrpc else "NOT ",
+ source="" if not xmlrpc
+ else " from this computer only (localhost)." if xmlrpc_only_localhost
+ else " from ACL listed remote computers!"
+ ))
+
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # region # REGION: Shared functions
+ def save_xmlrpcacls():
+ """Save new acl's to file."""
+ if not xmlrpcacl.writeaclfile(aclname="XML-RPC"):
+ stderr.write("Error while writing ACL file!\n")
+ return 8
+
+ def print_xmlrpcacls():
+ """Print a list with all acl."""
+ if xmlrpcacl.acl:
+ stdout.write("\nThis is the actual ACL file ({0}):".format(aclxmlrpc))
+ counter = 0
+ for acl in xmlrpcacl.acl.split():
+ stdout.write("\n" if counter % 2 == 0 else " | ")
+ ip, level = acl.split(",")
+ stdout.write("{0:15} - Level: {1:2}".format(ip, level))
+ counter += 1
+ stdout.write("\n")
+ else:
+ stderr.write(
+ "\nWARNING: NO IP addresses defined in ACL!\n You will "
+ "not be able to connect with RevPiPyControl at this moment!\n"
+ )
+
+ # endregion # # # # #
+
+ try:
+ if not xmlrpc_only_localhost:
+ cmd = input("\nDo you want to check ACL listed computers? (y/N) ").lower()
+ if cmd == "y":
+ print_xmlrpcacls()
+
+ if getuid() != 0:
+ stderr.write("\nYou need root permissions to change values (sudo).\n")
+ return 4
+
+ cmd = input("\nDo you want to allow connections from remote hosts? (y/N) ").lower()
+ if cmd == "y":
+ conf.set("XMLRPC", "xmlrpc", "1")
+ conf.set("XMLRPC", "bindip", "*")
+
+ cmd = input("Reset the ACL file to allow all private networks? (y/N) ").lower()
+ if cmd == "y":
+ xmlrpcacl.acl = "127.*.*.*,4 " \
+ "169.254.*.*,4 " \
+ "10.*.*.*,4 " \
+ "172.16.*.*,4 172.17.*.*,4 172.18.*.*,4 172.19.*.*,4 " \
+ "172.20.*.*,4 172.21.*.*,4 172.22.*.*,4 172.23.*.*,4 " \
+ "172.24.*.*,4 172.25.*.*,4 172.26.*.*,4 172.27.*.*,4 " \
+ "172.28.*.*,4 172.29.*.*,4 172.30.*.*,4 172.31.*.*,4 " \
+ "192.168.*.*,4"
+ save_xmlrpcacls()
+
+ else:
+ cmd = input("Reset the ACL file by enter individual ip addresses to grant access? (y/N) ").lower()
+ if cmd == "y":
+ # Always set local host
+ lst_ip = ["127.*.*.*,4 "]
+ while True:
+ cmd = input("Enter single IPv4 address | Press RETURN to complete: ")
+ if not cmd:
+ xmlrpcacl.acl = " ".join(lst_ip)
+ save_xmlrpcacls()
+ break
+ elif match(r"([\d*]{1,3}\.){3}[\d*]{1,3}", cmd):
+ ip_level = "{0},4".format(cmd)
+ if ip_level not in lst_ip:
+ lst_ip.append(ip_level)
+ else:
+ stderr.write("Wrong format (0.0.0.0)\n")
+
+ else:
+ cmd = input("Do you want to allow connections from localhost ONLY? (y/N) ").lower()
+ if cmd == "y":
+ conf.set("XMLRPC", "xmlrpc", "1")
+ conf.set("XMLRPC", "bindip", "127.0.0.1")
+
+ cmd = input("Reset the ACL file to allow localhost connections only? (y/N) ").lower()
+ if cmd == "y":
+ xmlrpcacl.acl = "127.*.*.*,4 "
+ save_xmlrpcacls()
+
+ else:
+ cmd = input(
+ "\nWARNING: This will disable the possibility to connect with "
+ "RevPiPyControl!\n Are you sure? (y/N) "
+ ).lower()
+ if cmd == "y":
+ conf.set("XMLRPC", "xmlrpc", "0")
+ conf.set("XMLRPC", "bindip", "127.0.0.1")
+ xmlrpcacl.acl = ""
+ save_xmlrpcacls()
+ else:
+ stdout.write("\nWe did no changes!\n")
+ return 2
+
+ # Write configuration
+ with open(CONFIG_FILE, "w") as fh:
+ conf.write(fh)
+
+ print_xmlrpcacls()
+
+ except KeyboardInterrupt:
+ stdout.write("\n\nWe did no changes!\n")
+ return 2
+
+ if system("/etc/init.d/revpipyload status > /dev/null") == 0:
+ try:
+ cmd = input("\nDo you want to apply the new settings now? (Y/n) ").lower()
+ if cmd in ("", "y"):
+ system("/etc/init.d/revpipyload reload")
+ else:
+ stderr.write(
+ "\nYou have to activate the new settings for RevPiPyLoad!\n"
+ " sudo /etc/init.d/revpipyload reload\n"
+ )
+ except KeyboardInterrupt:
+ pass
+
+ return 0
+
+
+if __name__ == '__main__':
+ import sys
+
+ sys.exit(main())
diff --git a/revpipyload/shared/__init__.py b/src/revpipyload/shared/__init__.py
similarity index 50%
rename from revpipyload/shared/__init__.py
rename to src/revpipyload/shared/__init__.py
index 1caa366..3cd5999 100644
--- a/revpipyload/shared/__init__.py
+++ b/src/revpipyload/shared/__init__.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
"""Shared modules."""
__author__ = "Sven Sager"
-__copyright__ = "Copyright (C) 2018 Sven Sager"
-__license__ = "GPLv3"
+__copyright__ = "Copyright (C) 2023 Sven Sager"
+__license__ = "GPLv2"
diff --git a/revpipyload/shared/ipaclmanager.py b/src/revpipyload/shared/ipaclmanager.py
similarity index 95%
rename from revpipyload/shared/ipaclmanager.py
rename to src/revpipyload/shared/ipaclmanager.py
index 2568ea8..ba7bc09 100644
--- a/revpipyload/shared/ipaclmanager.py
+++ b/src/revpipyload/shared/ipaclmanager.py
@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
"""Verwaltet IP Adressen und deren ACLs."""
__author__ = "Sven Sager"
-__copyright__ = "Copyright (C) 2018 Sven Sager"
-__license__ = "GPLv3"
+__copyright__ = "Copyright (C) 2023 Sven Sager"
+__license__ = "GPLv2"
__version__ = "0.1.0"
-from os import access, R_OK, W_OK
+
+from os import R_OK, W_OK, access
from re import match as rematch
@@ -21,7 +22,6 @@ def refullmatch(regex, string):
class IpAclManager():
-
"""Verwaltung fuer IP Adressen und deren ACL Level."""
def __init__(self, minlevel, maxlevel, acl=None):
@@ -48,7 +48,7 @@ class IpAclManager():
self.__dict_knownips = {}
self.__filename = None
self.__re_ipacl = "(([\\d\\*]{1,3}\\.){3}[\\d\\*]{1,3},[" \
- + str(minlevel) + "-" + str(maxlevel) + "] ?)*"
+ + str(minlevel) + "-" + str(maxlevel) + "] ?)*"
# Liste erstellen, wenn übergeben
if acl is not None:
@@ -172,8 +172,8 @@ class IpAclManager():
return False
header = "# {0}Access Control List (acl)\n" \
- "# One entry per Line IPADRESS,LEVEL\n" \
- "#\n".format("" if aclname is None else aclname + " ")
+ "# One entry per Line IPADRESS,LEVEL\n" \
+ "#\n".format("" if aclname is None else aclname + " ")
with open(filename, "w") as fh:
fh.write(header)
diff --git a/revpipyload/testsystem.py b/src/revpipyload/testsystem.py
similarity index 97%
rename from revpipyload/testsystem.py
rename to src/revpipyload/testsystem.py
index abb23f2..713ff3a 100644
--- a/revpipyload/testsystem.py
+++ b/src/revpipyload/testsystem.py
@@ -1,16 +1,17 @@
# -*- coding: utf-8 -*-
"""Test all config files and print results."""
__author__ = "Sven Sager"
-__copyright__ = "Copyright (C) 2019 Sven Sager"
-__license__ = "GPLv3"
-import proginit
+__copyright__ = "Copyright (C) 2023 Sven Sager"
+__license__ = "GPLv2"
+
from configparser import ConfigParser
+import proginit
+
newline = "\n------------------------------------------------------------\n"
class TestSystem:
-
"""Main class for test system of revpipyload."""
def __init__(self):
diff --git a/revpipyload/watchdogs.py b/src/revpipyload/watchdogs.py
similarity index 98%
rename from revpipyload/watchdogs.py
rename to src/revpipyload/watchdogs.py
index ac40bff..290d83f 100644
--- a/revpipyload/watchdogs.py
+++ b/src/revpipyload/watchdogs.py
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
"""Watchdog systems to monitor plc program and reset_driver of piCtory."""
__author__ = "Sven Sager"
-__copyright__ = "Copyright (C) 2020 Sven Sager"
-__license__ = "GPLv3"
+__copyright__ = "Copyright (C) 2023 Sven Sager"
+__license__ = "GPLv2"
import os
from fcntl import ioctl
@@ -12,7 +12,7 @@ from subprocess import Popen
from threading import Event, Thread
from time import time
-import proginit as pi
+from . import proginit as pi
class SoftwareWatchdog:
diff --git a/revpipyload/xrpcserver.py b/src/revpipyload/xrpcserver.py
similarity index 93%
rename from revpipyload/xrpcserver.py
rename to src/revpipyload/xrpcserver.py
index f4688ed..9f9a616 100644
--- a/revpipyload/xrpcserver.py
+++ b/src/revpipyload/xrpcserver.py
@@ -1,17 +1,16 @@
# -*- coding: utf-8 -*-
"""XML-RPC Server anpassungen fuer Absicherung."""
__author__ = "Sven Sager"
-__copyright__ = "Copyright (C) 2018 Sven Sager"
-__license__ = "GPLv3"
+__copyright__ = "Copyright (C) 2023 Sven Sager"
+__license__ = "GPLv2"
-from xmlrpc.server import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
+from xmlrpc.server import SimpleXMLRPCRequestHandler, SimpleXMLRPCServer
-import proginit
-from shared.ipaclmanager import IpAclManager
+from . import proginit
+from .shared.ipaclmanager import IpAclManager
class SaveXMLRPCServer(SimpleXMLRPCServer):
-
"""Erstellt einen erweiterten XMLRPCServer."""
def __init__(
@@ -80,7 +79,6 @@ class SaveXMLRPCServer(SimpleXMLRPCServer):
class SaveXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
-
"""Verwaltet die XML-Requests und prueft Berechtigungen."""
timeout = 2.0
diff --git a/stdeb.cfg b/stdeb.cfg
deleted file mode 100644
index 18464ac..0000000
--- a/stdeb.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-[DEFAULT]
-Debian-Version: 1
-Depends3: python3-revpimodio2 (>= 2.5.0)
-Package: revpipyload
-Suite: stable