149 lines
4.4 KiB
Python
149 lines
4.4 KiB
Python
# This file is part of the Minecraft Overviewer.
|
|
#
|
|
# Minecraft Overviewer 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 3 of the License, or (at
|
|
# your option) any later version.
|
|
#
|
|
# Minecraft Overviewer 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 the Overviewer. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
"""
|
|
Misc utility routines used by multiple files that don't belong anywhere else
|
|
"""
|
|
|
|
import errno
|
|
import imp
|
|
import os.path
|
|
import platform
|
|
import sys
|
|
from itertools import cycle, islice, product
|
|
from string import hexdigits
|
|
from subprocess import PIPE, Popen
|
|
|
|
|
|
def get_program_path():
|
|
if hasattr(sys, "frozen") or imp.is_frozen("__main__"):
|
|
return os.path.dirname(sys.executable)
|
|
else:
|
|
try:
|
|
# normally, we're in ./overviewer_core/util.py
|
|
# we want ./
|
|
return os.path.dirname(os.path.dirname(__file__))
|
|
except NameError:
|
|
return os.path.dirname(sys.argv[0])
|
|
|
|
|
|
def findGitHash():
|
|
try:
|
|
p = Popen('git rev-parse HEAD', stdout=PIPE, stderr=PIPE, shell=True)
|
|
p.stderr.close()
|
|
line = p.stdout.readlines()[0].decode('utf-8').strip()
|
|
if line and len(line) == 40 and all(c in hexdigits for c in line):
|
|
return line
|
|
except Exception:
|
|
try:
|
|
from . import overviewer_version
|
|
return overviewer_version.HASH
|
|
except Exception:
|
|
pass
|
|
return "unknown"
|
|
|
|
|
|
def findGitVersion():
|
|
try:
|
|
p = Popen('git describe --tags --match "v*.*.*"', stdout=PIPE, stderr=PIPE, shell=True)
|
|
p.stderr.close()
|
|
line = p.stdout.readlines()[0].decode('utf-8')
|
|
if line.startswith('release-'):
|
|
line = line.split('-', 1)[1]
|
|
if line.startswith('v'):
|
|
line = line[1:]
|
|
# turn 0.1.0-50-somehash into 0.1.50
|
|
# and 0.1.0 into 0.1.0
|
|
line = line.strip().replace('-', '.').split('.')
|
|
if len(line) == 5:
|
|
del line[4]
|
|
del line[2]
|
|
else:
|
|
assert len(line) == 3
|
|
line[2] = '0'
|
|
line = '.'.join(line)
|
|
return line
|
|
except Exception:
|
|
try:
|
|
from . import overviewer_version
|
|
return overviewer_version.VERSION
|
|
except Exception:
|
|
return "unknown"
|
|
|
|
|
|
def is_bare_console():
|
|
"""Returns true if Overviewer is running in a bare console in
|
|
Windows, that is, if overviewer wasn't started in a cmd.exe
|
|
session.
|
|
"""
|
|
if platform.system() == 'Windows':
|
|
try:
|
|
import ctypes
|
|
GetConsoleProcessList = ctypes.windll.kernel32.GetConsoleProcessList
|
|
num = GetConsoleProcessList(ctypes.byref(ctypes.c_int(0)), ctypes.c_int(1))
|
|
if (num == 1):
|
|
return True
|
|
|
|
except Exception:
|
|
pass
|
|
return False
|
|
|
|
|
|
def nice_exit(ret=0):
|
|
"""Drop-in replacement for sys.exit that will automatically detect
|
|
bare consoles and wait for user input before closing.
|
|
"""
|
|
if ret and is_bare_console():
|
|
print("")
|
|
print("Press [Enter] to close this window.")
|
|
input()
|
|
sys.exit(ret)
|
|
|
|
|
|
# http://docs.python.org/library/itertools.html
|
|
def roundrobin(iterables):
|
|
"roundrobin('ABC', 'D', 'EF') --> A D E B F C"
|
|
# Recipe credited to George Sakkis
|
|
pending = len(iterables)
|
|
nexts = cycle(iter(it).__next__ for it in iterables)
|
|
while pending:
|
|
try:
|
|
for next in nexts:
|
|
yield next()
|
|
except StopIteration:
|
|
pending -= 1
|
|
nexts = cycle(islice(nexts, pending))
|
|
|
|
|
|
def dict_subset(d, keys):
|
|
"Return a new dictionary that is built from copying select keys from d"
|
|
n = dict()
|
|
for key in keys:
|
|
if key in d:
|
|
n[key] = d[key]
|
|
return n
|
|
|
|
|
|
def pid_exists(pid): # http://stackoverflow.com/a/6940314/1318435
|
|
"""Check whether pid exists in the current process table."""
|
|
if pid < 0:
|
|
return False
|
|
try:
|
|
os.kill(pid, 0)
|
|
except OSError as e:
|
|
return e.errno != errno.ESRCH
|
|
else:
|
|
return True
|