diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | .travis.yml | 8 | ||||
-rw-r--r-- | README.md | 1 | ||||
-rwxr-xr-x | mcwrapper/__init__.py | 76 | ||||
-rw-r--r-- | mcwrapper/prints.py | 32 | ||||
-rw-r--r--[-rwxr-xr-x] | mcwrapper/wrapper.py (renamed from mcwrapper) | 123 | ||||
-rwxr-xr-x | setup.py | 35 | ||||
-rwxr-xr-x | tests/all.sh | 5 | ||||
-rwxr-xr-x | tests/prepare.sh | 27 | ||||
-rwxr-xr-x | tests/t_codingstandard.sh | 24 |
10 files changed, 157 insertions, 175 deletions
@@ -1,6 +1,7 @@ *~ .* __*__ +*.egg-info !.gitignore !.travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 3831523..0000000 --- a/.travis.yml +++ /dev/null @@ -1,8 +0,0 @@ -language: python -python: "3.5" -install: - - "pip install pep8" - - "pip install pyflakes" - - "sudo apt-get install openjdk-7-jre" - -script: tests/all.sh @@ -1,6 +1,5 @@ MCSERVER-WRAPPER ================ -[![Build Status](https://travis-ci.org/Cynerd/minecraft-wrapper.svg?branch=master)](https://travis-ci.org/Cynerd/minecraft-wrapper) Minecraft server wrapper written in Python3 that extracts server status and list of online players. diff --git a/mcwrapper/__init__.py b/mcwrapper/__init__.py new file mode 100755 index 0000000..a1fed68 --- /dev/null +++ b/mcwrapper/__init__.py @@ -0,0 +1,76 @@ +# vim: expandtab ft=python ts=4 sw=4 sts=4: +import os +import sys +import subprocess +import signal +import time +import atexit +import argparse +from threading import Thread + +from . import prints +from . import wrapper +from .wrapper import MCWrapper + +mcserver_wrapper = None + + +def __wrapper_atexit__(): + "This is called when wrapper is exiting" + mcserver_wrapper.clean() + + +def __wrapper_toexit__(): + "This function is called when system signalizes that mcwrapper should exit" + mcserver_wrapper.stop() + + +def __signal_term__(_signo, _stack_frame): + __wrapper_toexit__() + + +__HELP_DESC__ = """ + This script is executing Minecraft server and reads its output. From output + is extracted server status and list of online players. And standard input + can be accessed by fifo file. + """ + + +def main(): + "Main function" + global verbose_level + parser = argparse.ArgumentParser(description=__HELP_DESC__) + parser.add_argument('--verbose', '-v', action='count', default=0, + help="Increase verbose level of output") + parser.add_argument('--quiet', '-q', action='count', default=0, + help="Decrease verbose level of output") + parser.add_argument('--status-file', '-s', action='store_true', + help="Outputs server status to file \"status\"") + parser.add_argument('--players-file', '-p', action='store_true', + help="""Outputs list of online players to file + \"players\" """) + parser.add_argument('command', nargs=argparse.REMAINDER, + help="""Command to be executed to start Minecraft + server.""") + args = parser.parse_args() + + prints.verbose_level = args.verbose - args.quiet + command = args.command + sfile = args.status_file + pfile = args.players_file + + if not command: + parser.print_help() + if 'nogui' not in command: + command.append('nogui') + + global mcserver_wrapper + mcserver_wrapper = MCWrapper(command, pfile, sfile) + signal.signal(signal.SIGTERM, __signal_term__) + signal.signal(signal.SIGINT, __signal_term__) + atexit.register(__wrapper_atexit__) + + mcserver_wrapper.execstart() + +if __name__ == '__main__': + main() diff --git a/mcwrapper/prints.py b/mcwrapper/prints.py new file mode 100644 index 0000000..cb19358 --- /dev/null +++ b/mcwrapper/prints.py @@ -0,0 +1,32 @@ +# vim: expandtab ft=python ts=4 sw=4 sts=4: +import sys +import time + +verbose_level = 0 + + +def __print_message__(message, file=sys.stdout, notime=False): + if notime: + print(message, file=file) + else: + print('[' + time.strftime('%H:%M:%S') + '] ' + message, file=file) + + +def info(message, minverbose=0, notime=False): + "Prints message to stdout if minverbose >= verbose_level" + if verbose_level >= minverbose: + __print_message__(message, notime=notime) + + +def warning(message, minverbose=-1, notime=False): + "Prints message to stderr if minverbose >= verbose_level" + if verbose_level >= minverbose: + __print_message__(message, file=sys.stderr, notime=notime) + + +def error(message, minverbose=-2, errcode=-1, notime=False): + "Prints message to stderr if minverbose >= verbose_level" + if verbose_level >= minverbose: + __print_message__(message, file=sys.stderr, notime=notime) + sys.exit(errcode) + diff --git a/mcwrapper b/mcwrapper/wrapper.py index e65a0f5..1896266 100755..100644 --- a/mcwrapper +++ b/mcwrapper/wrapper.py @@ -1,44 +1,11 @@ -#!/usr/bin/env python3 # vim: expandtab ft=python ts=4 sw=4 sts=4: import os import sys import subprocess -import signal import time -import atexit -import argparse from threading import Thread -############################################################################### -# Exit codes and prints helpers -verbose_level = 0 - -def __print_message__(message, file=sys.stdout, notime=False): - if notime: - print(message, file=file) - else: - print('[' + time.strftime('%H:%M:%S') + '] ' + message, file=file) - - -def info(message, minverbose=0, notime=False): - "Prints message to stdout if minverbose >= verbose_level" - if verbose_level >= minverbose: - __print_message__(message, notime=notime) - - -def warning(message, minverbose=-1, notime=False): - "Prints message to stderr if minverbose >= verbose_level" - if verbose_level >= minverbose: - __print_message__(message, file=sys.stderr, notime=notime) - - -def error(message, minverbose=-2, errcode=-1, notime=False): - "Prints message to stderr if minverbose >= verbose_level" - if verbose_level >= minverbose: - __print_message__(message, file=sys.stderr, notime=notime) - sys.exit(errcode) - -############################################################################### +from .import prints __STATUSSTRINGS__ = { 0: "Not running", @@ -53,7 +20,7 @@ __PLAYERSFILE__ = 'players' __PIDFILE__ = 'server.pid' -class MCServer: +class MCWrapper: "Minecraft server wrapper class" def __init__(self, command, statusfile=False, playersfile=False): self.players = set() @@ -62,17 +29,17 @@ class MCServer: self.command = command self.statusfile = statusfile self.plaersfile = playersfile - info("Server wrapper initializing") + prints.info("Server wrapper initializing") if os.path.isfile(__PIDFILE__): with open(__PIDFILE__) as file: lpid = int(file.readline()) try: os.kill(lpid, 0) except OSError: - warning("Detected forced termination of previous server " + prints.warning("Detected forced termination of previous server " "wrapper instance.") else: - error("Another wrapper is running with given identifier.", + prints.error("Another wrapper is running with given identifier.", -1, 1) try: os.mkfifo(__INPUTPIPE__, 0o640) @@ -90,13 +57,13 @@ class MCServer: def clean(self): "Cleans files generated by wrapper" - info("Server wrapper clean.") + prints.info("Server wrapper clean.") try: os.remove(__INPUTPIPE__) except FileNotFoundError: pass try: - os.path.isfile(__PIDFILE__) + os.remove(__PIDFILE__) except FileNotFoundError: pass try: @@ -144,7 +111,7 @@ class MCServer: def write_to_terminal(self, text): "Write to server terminal. If server not running it does nothing" if self.status == 2: - info("Input: " + text, 1) + prints.info("Input: " + text, 1) self.process.stdin.write(bytes(text, sys.getdefaultencoding())) self.process.stdin.flush() return True @@ -152,14 +119,14 @@ class MCServer: return False def __user_join__(self, username): - info("User '" + username + "' joined server.") + prints.info("User '" + username + "' joined server.") self.players.add(username) if self.plaersfile: with open(__PLAYERSFILE__, 'a') as file: file.write(username + '\n') def __user_leave__(self, username): - info("User '" + username + "' left server.") + prints.info("User '" + username + "' left server.") self.players.remove(username) if self.plaersfile: with open(__PLAYERSFILE__, 'w') as file: @@ -169,13 +136,13 @@ class MCServer: def __parse_line__(self, line): if ': Done' in line: - info("Server start.") + prints.info("Server start.") self.status = 2 if self.statusfile: with open(__STATUSFILE__, 'w') as file: file.write(__STATUSSTRINGS__[2] + '\n') elif ': Stopping the server' in line: - info("Server stop.") + prints.info("Server stop.") self.status = 3 if self.statusfile: with open(__STATUSFILE__, 'w') as file: @@ -192,7 +159,7 @@ class MCServer: def __output_thread__(self): for linen in self.process.stdout: line = linen.decode(sys.getdefaultencoding()) - info(line.rstrip(), 2, notime=True) + prints.info(line.rstrip(), 2, notime=True) self.__parse_line__(line.rstrip()) if self.statusfile: with open(__STATUSFILE__, 'w') as file: @@ -206,67 +173,3 @@ class MCServer: self.write_to_terminal(line + "\n") else: time.sleep(3) - -############################################################################### -mcserver = None - - -def __wrapper_atexit__(): - "This is called when wrapper is exiting" - mcserver.clean() - - -def __wrapper_toexit__(): - "This function is called when system signalizes that mcwrapper should exit" - mcserver.stop() - - -def __signal_term__(_signo, _stack_frame): - __wrapper_toexit__() - - -__HELP_DESC__ = """ - This script is executing Minecraft server and reads its output. From output - is extracted server status and list of online players. And standard input - can be accessed by fifo file. - """ - - -def main(): - "Main function" - global verbose_level - parser = argparse.ArgumentParser(description=__HELP_DESC__) - parser.add_argument('--verbose', '-v', action='count', default=0, - help="Increase verbose level of output") - parser.add_argument('--quiet', '-q', action='count', default=0, - help="Decrease verbose level of output") - parser.add_argument('--status-file', '-s', action='store_true', - help="Outputs server status to file \"status\"") - parser.add_argument('--players-file', '-p', action='store_true', - help="""Outputs list of online players to file - \"players\" """) - parser.add_argument('command', nargs=argparse.REMAINDER, - help="""Command to be executed to start Minecraft - server.""") - args = parser.parse_args() - - verbose_level = args.verbose - args.quiet - command = args.command - sfile = args.status_file - pfile = args.players_file - - if not command: - parser.print_help() - if 'nogui' not in command: - command.append('nogui') - - global mcserver - mcserver = MCServer(command, pfile, sfile) - signal.signal(signal.SIGTERM, __signal_term__) - signal.signal(signal.SIGINT, __signal_term__) - atexit.register(__wrapper_atexit__) - - mcserver.execstart() - -if __name__ == '__main__': - main() diff --git a/setup.py b/setup.py new file mode 100755 index 0000000..d2a6baa --- /dev/null +++ b/setup.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 +from setuptools import setup, find_packages +from os import path + +here = path.abspath(path.dirname(__file__)) +with open(path.join(here, 'README.md'), encoding='utf-8') as f: + long_description = f.read() + + +setup( + name='mcserver-wrapper', + version='0.3.0', + description="Minecraft server wrapper", + long_description=long_description, + url="https://github.com/Cynerd/mcserver-wrapper", + author="Cynerd", + author_email="cynerd@email.cz", + license="GPLv2", + + clasifiers=[ + 'Development Status :: 3 - Alpha', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.2', + 'Programming Language :: Python :: 3.3', + 'Programming Language :: Python :: 3.4', + ], + keywords='Minecraft wrapper server', + + packages=['mcwrapper'], + entry_points={ + 'console_scripts': [ + 'mcwrapper=mcwrapper:main' + ] + } + ) diff --git a/tests/all.sh b/tests/all.sh deleted file mode 100755 index 1237154..0000000 --- a/tests/all.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -cd "$( dirname "${BASH_SOURCE[0]}" )" - -./t_codingstandard.sh -[[ ! $? -ne 0 ]] || exit 1 diff --git a/tests/prepare.sh b/tests/prepare.sh deleted file mode 100755 index 17e466d..0000000 --- a/tests/prepare.sh +++ /dev/null @@ -1,27 +0,0 @@ -#~/bin/bash -if [[ "$(basename -- "$0")" = "prepare.sh" ]]; then - echo "Please only source this script" - exit 1 -fi - -if [[ $PREPARED != "y" ]]; then - # Move to known directory - cd "$( readlink -f "${BASH_SOURCE[0]}" )" - - if [[ $MCSERVERS == "y" ]]; then - mkdir -p minecraft-server - echo "eula=true" > minecraft-server/eula.txt - # Get Minecraft 1.8.8 - [ -f minecraft-server/minecraft_server.1.8.8.jar ] || \ - wget https://s3.amazonaws.com/Minecraft.Download/versions/1.8.8/minecraft_server.1.8.8.jar -O minecraft-server/minecraft_server.1.8.8.jar - # Get Minecraft 1.9 - [ -f minecraft-server/minecraft_server.1.9.jar ] || \ - wget https://s3.amazonaws.com/Minecraft.Download/versions/1.9/minecraft_server.1.9.jar -O minecraft-server/minecraft_server.1.9.jar - function mcservers_clean { - find minecraft-server | tail -n +2 | egrep -v "minecraft_server.*jar" | egrep -v "eula.txt" | xargs rm -rf - } - fi - - export PATH=$( realpath .. ):$PATH - export PREPARED="y" -fi diff --git a/tests/t_codingstandard.sh b/tests/t_codingstandard.sh deleted file mode 100755 index 1b472b4..0000000 --- a/tests/t_codingstandard.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash -cd "$( dirname "${BASH_SOURCE[0]}" )" -source prepare.sh - -echo "Checking code style using pep8" -pep8 ../mcwrapper -if [[ $? == 0 ]]; then - echo "Ok" -else - exit 1 -fi - -echo "Checking for common errors" -pyflakes ../mcwrapper -if [[ $? == 0 ]]; then - echo "Ok" -else - exit 1 -fi - -# This test is not part of standard check because of errors caused by dynamic variable -# loading to configuration. But it should be run from time to time to found other mistakes -#echo "Checking bugs and poor quality" -#pylint --reports=n ../mcwrapper |