Browse Source

Rename error to echo0 and debug to echo1. Add and use main's return in many cases. Remove lint. Move TRY_SHARE_MT_DIRS from deprecated.

master
poikilos 2 years ago
parent
commit
e170a2b123
  1. 1
      .gitignore
  2. 52
      Bucket_Game-base/trimpatchstats.py
  3. 27
      Bucket_Game-branches/remove_not_in.py
  4. 32
      basecompare.py
  5. 17
      buildenliven.py
  6. 61
      deploy.py
  7. 28
      filever.py
  8. 14
      forwardfilesync.py
  9. 10
      generate-mt5-share-fix.py
  10. 44
      headcompare.py
  11. 169
      install-subgametest.py
  12. 31
      install.py
  13. 144
      mtsenliven.py
  14. 11
      notes/continuify.py
  15. 103
      pyenliven/__init__.py
  16. 30
      pyenliven/compatiblizemod.py
  17. 3
      pyenliven/deprecated.py
  18. 77
      setup.py
  19. 17
      uninstall-minetestserver-git.py
  20. 8
      utilities/compatiblizemod.py
  21. 97
      utilities/enissue.py
  22. 39
      utilities/enlynx.py
  23. 29
      utilities/extra/uninstall.py
  24. 23
      utilities/generatemod.py
  25. 13
      utilities/mtcompile-program-local.py
  26. 10
      utilities/mtoldtonew.py
  27. 25
      utilities/showmissing.py

1
.gitignore

@ -18,3 +18,4 @@ linux-minetest-kit.zip
/docker/lmk-libraries.devuan-chimera/install-minetest-build-deps.sh
/docker/libraries-devuan-chimera/install-minetest-build-deps.sh
/docker/libraries-devuan-chimaera/install-minetest-build-deps.sh
/debug.txt

52
Bucket_Game-base/trimpatchstats.py

@ -1,13 +1,15 @@
#!/usr/bin/env python3
'''
Remove the lines from the from the input file in Bucket_Game-base that are not in the matching list file in Bucket_Game-branches.
Remove the lines from the from the input file in Bucket_Game-base that
are not in the matching list file in Bucket_Game-branches.
The resulting modified list is written to standard output.
The provided filename must exist in both the Bucket_Game-base directory and the parallel Bucket_Game-branches directory.
The provided filename must exist in both the Bucket_Game-base directory
and the parallel Bucket_Game-branches directory.
The file must contain output such as from ls or find executing ls. Examples:
find -type f -name "*.ogg" -exec ls -lh {} \;
find -type f -exec ls -lh {} \;
find -type f -name "*.ogg" -exec ls -lh {} \\;
find -type f -exec ls -lh {} \\;
Usage:
./trimpatchstats.py <filename>
@ -16,15 +18,16 @@ import sys
import os
import json
def error(msg):
sys.stderr.write("{}\n".format(msg))
sys.stderr.flush()
def echo0(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
def usage():
error("")
error("trimpatchstats.py")
error("-----------------")
error(__doc__)
echo0("")
echo0("trimpatchstats.py")
echo0("-----------------")
echo0(__doc__)
def splitFirst(line, delimiter):
@ -196,6 +199,7 @@ class LSFileInfo:
def __str__(self):
return json.dumps(self.to_dict())
def getFileNumber(path, num):
'''
Get a file from a listfile that contains ls -l or ls -n output.
@ -251,7 +255,7 @@ def printOnlyPatched(baseListPath):
if fid is None:
print("Error: \"{}\" contained no filenames."
"".format(patchedListPath))
exit(1)
return 1
tryFilePath = os.path.join(targetDirPath, fid['name'])
if not os.path.isfile(tryFilePath):
print("Error: \"{}\" doesn't exist. Run again from the"
@ -260,9 +264,9 @@ def printOnlyPatched(baseListPath):
" directory name in the \"{}\" directory and run in a"
" directory parallel to that."
"".format(tryFilePath, fid['name'], patchedPath))
exit(1)
return 2
error("* analyzing \"{}\"".format(patchedListPath))
echo0("* analyzing \"{}\"".format(patchedListPath))
patchedFIs = []
rawNames = []
with open(patchedListPath, 'r') as ins:
@ -279,9 +283,9 @@ def printOnlyPatched(baseListPath):
fid = parse_ls(line)
rawNames.append(fid['name'])
# fill_file_dict_path(fid, targetDirPath)
# error(fid)
# echo0(fid)
error("* analyzing \"{}\"".format(baseListPath))
echo0("* analyzing \"{}\"".format(baseListPath))
allCount = 0
matchCount = 0
with open(baseListPath, 'r') as ins:
@ -300,13 +304,19 @@ def printOnlyPatched(baseListPath):
if fid['name'] in rawNames:
print(line)
matchCount += 1
error("{} of {} in {} were also in {}"
echo0("{} of {} in {} were also in {}"
"".format(matchCount, allCount, baseListPath,
patchedListPath))
return 0
if __name__ == "__main__":
def main():
if len(sys.argv) < 2:
usage()
error("Error: You are missing the required list filename argument.\n")
exit(1)
printOnlyPatched(sys.argv[1])
echo0("Error: You are missing the required list filename argument.\n")
return 1
return printOnlyPatched(sys.argv[1])
if __name__ == "__main__":
sys.exit(main())

27
Bucket_Game-branches/remove_not_in.py

@ -11,9 +11,8 @@ else:
profile = os.environ['HOME']
def error(msg):
sys.stderr.write("{}\n".format(msg))
sys.stderr.flush()
def echo0(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
def showNotInOriginal(patched, original, root=None, ignores=[]):
@ -34,7 +33,8 @@ def showNotInOriginal(patched, original, root=None, ignores=[]):
if sub in ignores:
continue
if os.path.isdir(patchedPath):
showNotInOriginal(patchedPath, originalPath, root=root, ignores=ignores)
showNotInOriginal(patchedPath, originalPath, root=root,
ignores=ignores)
continue
if not os.path.isfile(originalPath):
relPath = patchedPath[len(root):]
@ -47,17 +47,24 @@ def showNotInOriginal(patched, original, root=None, ignores=[]):
print("rm {}".format(dotPathShell))
if __name__ == "__main__":
def main():
original = os.path.join(profile, "minetest", "games", "Bucket_Game")
patched = os.path.abspath(".")
originalMods = os.path.join(original, "mods")
patchedMods = os.path.join(patched, "mods")
if not os.path.isdir(originalMods):
error("Error: \"{}\" doesn't seem to be a game since it doesn't have a \"mods\" directory.".format(original))
exit(1)
echo0("Error: \"{}\" doesn't seem to be a game since it doesn't"
" have a \"mods\" directory.".format(original))
return 1
if not os.path.isdir(patchedMods):
error("Error: \"{}\" doesn't seem to be a game since it doesn't have a \"mods\" directory.".format(patched))
exit(1)
echo0("Error: \"{}\" doesn't seem to be a game since it doesn't"
" have a \"mods\" directory.".format(patched))
return 2
myName = os.path.split(sys.argv[0])[1]
# error("myName:{}".format(myName))
# echo0("myName:{}".format(myName))
showNotInOriginal(patched, original, None, ignores=[myName])
return 0
if __name__ == "__main__":
sys.exit(main())

32
basecompare.py

@ -3,8 +3,11 @@ from __future__ import print_function
import sys
import os
from pyenliven import (
echo0,
)
from headcompare import (
error,
compareBranch,
defaultVirtualReposDir,
minetestPath,
@ -15,45 +18,48 @@ from headcompare import (
me = os.path.basename(__file__)
def usage():
error("Usage:")
echo0("Usage:")
sys.stderr.write("Specify a branch")
parent = "Bucket_Game-base"
if os.path.isdir(parent):
error(" from Bucket_Game-base:")
echo0(" from Bucket_Game-base:")
for sub in os.listdir(parent):
subPath = os.path.join(parent, sub)
if sub.startswith("."):
continue
if os.path.isdir(subPath):
error(subPath)
echo0(subPath)
else:
error(" from Bucket_Game-base.")
echo0(" from Bucket_Game-base.")
echo0("{} <branch name (see above)> [<bucket_game path>]".format(me))
echo0("")
error("{} <branch name (see above)> [<bucket_game path>]".format(me))
error("")
def main():
global defaultGamePath
defaultGamePath = None
if len(sys.argv) < 2:
usage()
error("Error: You must provide a branch name.\n")
exit(1)
echo0("Error: You must provide a branch name.\n")
return 1
if len(sys.argv) > 3:
usage()
error("Error: There are too many arguments: {}.\n"
echo0("Error: There are too many arguments: {}.\n"
"".format(sys.argv))
exit(1)
return 1
if len(sys.argv) > 2:
defaultGamePath = sys.argv[2]
results = compareBranch(sys.argv[1], gamePath=defaultGamePath,
compareOld=True)
error("# ^ Do that to verify: they MUST match, and the first"
echo0("# ^ Do that to verify: they MUST match, and the first"
" directory must be unmodified from the original"
" release package.")
return 0
if __name__ == "__main__":
main()
sys.exit(main())

17
buildenliven.py

@ -9,9 +9,10 @@ import os
import configparser
from pyenliven import (
error,
echo0,
getSGPath,
profile,
MODS_STOPGAP_DIR,
)
gamespec = {}
@ -27,6 +28,7 @@ gamespec['remove_mods'] = [
gamespec['local_mods_paths'] = []
gamespec['local_mods_paths'].append("mods_stopgap")
# ^ See also MODS_STOPGAP_DIR (full path) in pyenliven
gamespec['add_mods'] = [
# {'repo': "https://github.com/poikilos/homedecor_ua"},
@ -166,12 +168,13 @@ WARNINGS:
warnings = []
valid_bases = ['Bucket_Game', "bucket_game"]
def main():
for warning in warnings:
error(warning)
echo0(warning)
tryGameDir = os.getcwd()
error('* examining "{}"'.format(tryGameDir))
echo0('* examining "{}"'.format(tryGameDir))
gameConfName = "game.conf"
gameConfPath = os.path.join(tryGameDir, gameConfName)
if not os.path.isfile(gameConfPath):
@ -185,7 +188,7 @@ def main():
config.read_string('[top]\n' + ins.read())
# ^ insert a section since ConfigParser requires sections.
gameName = config['top'].get("name")
error(' * detected {} from {}'
echo0(' * detected "{}" from "{}"'
''.format(gameName, gameConfName))
if gameName not in valid_bases:
raise ValueError(
@ -200,8 +203,10 @@ def main():
# ^ TODO: Get this from mtanalyze?
targetGames = os.path.join(targetMT, "games")
target = os.path.join(targetGames, "ENLIVEN")
centerOfTheSunTarget =
centerOfTheSunTarget = None
raise NotImplementedError("pyenliven build")
return 0
if __name__ == "__main__":
main()
sys.exit(main())

61
deploy.py

@ -1,17 +1,29 @@
#!/usr/bin/env python
import os
import sys
import shutil
from forwardfilesync import *
# import filever
try:
input = raw_input
except NameError:
from pyenliven import (
echo0,
)
if sys.version_info.major >= 3:
pass
else:
input = raw_input
def rm_sub(bad_sub):
bad_path = path_join_all(deploy_path, bad_sub)
if os.path.isfile(bad_path):
os.remove(bad_path)
def main():
warnings = list()
print("")
print("This script is NOT YET IMPLEMENTED")
echo0("")
echo0("This script is NOT YET IMPLEMENTED")
# TODO: Scrape https://minetest.kitsunemimi.pw/builds/ (NOTE: stable is
@ -19,7 +31,7 @@ print("This script is NOT YET IMPLEMENTED")
# "minetest-0.4.15-win64.7z")
print("This script patches minetest and minetest_game with ENLIVEN\n" +
echo0("This script patches minetest and minetest_game with ENLIVEN\n" +
"(such as launcher and subgame) and creates a Windows installer.")
script_dir_path = os.path.dirname(os.path.abspath(__file__))
@ -35,7 +47,7 @@ else:
if not os.path.isdir(try_path):
try_path = "C:\\Users\\Owner"
print("WARNING: no HOME or USERPROFILE found, reverting to '" +
echo0("WARNING: no HOME or USERPROFILE found, reverting to '" +
try_path + "'")
profile_path = try_path
# TODO: Make a settings file for values in the next region.
@ -52,7 +64,7 @@ installer_name = "install-ENLIVEN.exe"
installer_path = os.path.join(installer_deploy_path, installer_name)
if not os.path.isdir(installer_deploy_path):
print("#WARNING: does not exist:")
echo0("#WARNING: does not exist:")
print("installer_deploy_path: " + installer_deploy_path)
# this is a waste--it just shows 0.0.0.0 though iss file has version
@ -67,23 +79,23 @@ games_path = os.path.join(deploy_path, "games")
minetest_game_path = os.path.join(games_path, "minetest_game")
minetest_game_mods_path = os.path.join(minetest_game_path, "mods")
if not os.path.isdir(minetest_game_path):
print("This deploy script requires an unmodified build of minetest and\n" +
echo0("This deploy script requires an unmodified build of minetest and\n" +
" minetest_game. Please place an unmodified build of minetest in\n" +
" " + deploy_path + " so that minetest_game is at: \n\n" +
" " + minetest_game_path + "\n\n")
exit(1)
return 1
game_path = os.path.join(games_path, "ENLIVEN")
# NOTE: remove this case, and instead: copy minetest_game, download ENLIVEN
# automatically
if not os.path.isdir(game_path):
print("")
print("ERROR: ENLIVEN must first be installed from web sources" +
echo0("")
echo0("ERROR: ENLIVEN must first be installed from web sources" +
" using the provided 'install' script in the etc/change*" +
" folder (run on linux then copy to a Windows machine" +
" in " + game_path)
# exit(2)
# return 2
else:
print("game_path: " + game_path)
mods_path = os.path.join(game_path, "mods")
@ -113,13 +125,6 @@ else:
shutil.copyfile(server_devel_minetest_conf_path,
server_minetest_conf_path)
def rm_sub(bad_sub):
bad_path = path_join_all(deploy_path, bad_sub)
if os.path.isfile(bad_path):
os.remove(bad_path)
rm_sub(["CC-BY-SA 3.0 Unported (fallback license for ENLIVEN assets)"
".txt"])
rm_sub(["MIT LICENSE (fallback license for ENLIVEN code).txt"])
@ -130,12 +135,16 @@ rm_sub(["MIT LICENSE (fallback license for ENLIVEN code).txt"])
# rm_sub(["games", "ENLIVEN", "LICENSE.txt"])
# rm_sub(["games", "ENLIVEN", "README.txt"])
print("")
echo0("")
if len(warnings) > 0:
print(str(len(warnings)) + " warning(s):")
echo0(str(len(warnings)) + " warning(s):")
for warning in warnings:
print(warning)
echo0(warning)
else:
print("0 warnings.")
print("\n")
input("press enter to exit...")
echo0("0 warnings.")
echo0()
return 0
if __name__ == "__main__":
sys.exit(main())

28
filever.py

@ -1,5 +1,7 @@
#!/usr/bin/env python
# by Jamie at <http://stackoverflow.com/questions/580924/python-windows-
import sys
# based on code by Jamie at
# <http://stackoverflow.com/questions/580924/python-windows-
# file-version-attribute>
try:
from win32api import GetFileVersionInfo, LOWORD, HIWORD
@ -7,7 +9,7 @@ except ImportError:
print("you need to install win32api such as with the command:")
print("sudo python2 -m pip install --upgrade pip")
print("sudo python -m pip install pypiwin32")
exit(1)
sys.exit(1)
from win32api import GetFileVersionInfo, LOWORD, HIWORD
@ -23,15 +25,25 @@ def get_version_number(filename):
return 0, 0, 0, 0
if __name__ == '__main__':
API_USAGE = '''
# API Usage:
import filever
parts = filever.get_version_number(filename)
major,minor,subminor,revision = parts
print(".".join([str (i) for i in parts]))
'''
def main():
import os
if "COMSPEC" in os.environ:
filename = os.environ["COMSPEC"]
this_delimiter = "."
print(str(filename) + " version:")
print(".".join([str(i) for i in get_version_number(filename)]))
print("Running filever directly doesn't do much.\n\n#Usage:\n" +
"import filever\n" +
"parts = filever.get_version_number(filename)\n" +
"major,minor,subminor,revision = parts\n" +
"print(\".\".join([str (i) for i in parts]))\n\n")
print("Running filever directly doesn't do much\n\n"+API_USAGE)
return 0
if __name__ == '__main__':
sys.exit(main())

14
forwardfilesync.py

@ -24,6 +24,7 @@ if platform.system() == "Windows":
CMD_CP = "COPY"
CMD_MKDIR = "MD"
def path_join_all(names):
result = names[0]
for i in range(1, len(names)):
@ -122,6 +123,7 @@ def update_tree(src, dst, level=0, do_trim=False, dot_hidden=False,
"".format(CMD_CP, sub_path, dst_sub_path))
pass
USAGE = '''
Syntax:
forwardfilesync.py <source> <destination> [options]
@ -131,9 +133,11 @@ forwardfilesync.py <source> <destination> [options]
'''
def usage():
print(USAGE)
def main():
flags = {}
flags["hidden"] = False
@ -142,7 +146,7 @@ def main():
if len(sys.argv) < 3:
usage()
print("Error: You must provide at least a source and destination.")
exit(1)
return 1
src = sys.argv[1]
dst = sys.argv[2]
@ -155,14 +159,14 @@ def main():
" since it doesn't start with \"--\". If it is part"
" of a path with spaces, put the path in quotes."
"".format(sys.argv[argI]))
exit(1)
return 1
name = arg[2:]
if name not in flags:
usage()
print("Error: There is no option \"{}\". If it is part of a"
" path with spaces, put the path in quotes."
"".format(sys.argv[argI]))
exit(1)
return 1
flags[name] = True
print(CMD_COMMENT + "Using options:")
for k, v in flags.items():
@ -175,8 +179,8 @@ def main():
dot_hidden=flags["hidden"] is True,
)
print(CMD_COMMENT + "Done.")
return 0
if __name__ == "__main__":
main()
sys.exit(main())

10
generate-mt5-share-fix.py

@ -1,10 +1,14 @@
#!/usr/bin/env python3
import os
import shutil
import sys
actions = {"-- Up-to-date: ": "move", "-- Installing: ": "move"}
changes = {
"/usr/local/./": "/usr/local/share/minetest/"
}
def main():
count = 0
command_count = 0
in_path = "bad_mt5_make_install_output.txt"
@ -142,3 +146,9 @@ with open(in_path) as ins:
print('Added {} line(s) to "{}" (including {} command(s))'
''.format(count, out_path, command_count))
return 0
if __name__ == "__main__":
sys.exit(main())

44
headcompare.py

@ -4,45 +4,46 @@ import sys
import os
import platform
from pyenliven import (
echo0,
)
me = os.path.basename(__file__)
myDir = os.path.dirname(os.path.abspath(__file__))
defaultVirtualReposDir = myDir
def error(msg):
sys.stderr.write("{}\n".format(msg))
sys.stderr.flush()
def usage():
error("Usage:")
echo0("Usage:")
sys.stderr.write("Specify a branch")
parent = "Bucket_Game-branches"
if os.path.isdir(parent):
error(" from Bucket_Game-branches:")
echo0(" from Bucket_Game-branches:")
for sub in os.listdir(parent):
subPath = os.path.join(parent, sub)
if sub.startswith("."):
continue
if os.path.isdir(subPath):
error(subPath)
echo0(subPath)
else:
error(" from Bucket_Game-branches.")
echo0(" from Bucket_Game-branches.")
error("{} <branch name (see above)> [<bucket_game path>]".format(me))
error("")
echo0("{} <branch name (see above)> [<bucket_game path>]".format(me))
echo0("")
profile = None
if platform.system() == "Windows":
profile = os.environ.get('USERPROFILE')
if profile is None:
error("Error: USERPROFILE is not set.")
exit(1)
echo0("Error: USERPROFILE is not set.")
sys.exit(1)
else:
profile = os.environ.get('HOME')
if profile is None:
error("Error: HOME is not set.")
exit(1)
echo0("Error: HOME is not set.")
sys.exit(1)
minetestPath = os.path.join(profile, "minetest")
gamesPath = os.path.join(minetestPath, "games")
@ -153,7 +154,6 @@ def compareBranch(branchName, gamePath=None, bgVersion=None,
if branchPathRel.startswith(myDirSlash):
branchPathRel = branchPathRel[len(myDirSlash):]
print("meld \"{}\" \"{}\"".format(gamePath, branchPath))
patchFilePath = branchPath+".patch"
print("diff -ru \"{}\" \"{}\" > \"{}\""
@ -166,26 +166,28 @@ def compareBranch(branchName, gamePath=None, bgVersion=None,
}
return results
def main():
global defaultGamePath
defaultGamePath = None
if len(sys.argv) < 2:
usage()
error("Error: You must provide a branch name.\n")
exit(1)
echo0("Error: You must provide a branch name.\n")
return 1
if len(sys.argv) > 3:
usage()
error("Error: There are too many arguments: {}.\n"
echo0("Error: There are too many arguments: {}.\n"
"".format(sys.argv))
exit(1)
return 1
if len(sys.argv) > 2:
defaultGamePath = sys.argv[2]
results = compareBranch(sys.argv[1], gamePath=defaultGamePath)
error("# ^ Do that to see the difference or generate a patch,"
echo0("# ^ Do that to see the difference or generate a patch,"
" but the first directory must be unmodified from the"
" original release package.")
return 0
if __name__ == "__main__":
main()
sys.exit(main())

169
install-subgametest.py

@ -9,10 +9,12 @@ from forwardfilesync import *
force_update_mtg_enable = False # first delete subgametest then remake
# endregion options
try:
input = raw_input
except NameError:
'''
if sys.version_info.major >= 3:
pass
else:
input = raw_input
'''
gitpython_msg = """
You do not have gitpython installed.
@ -42,22 +44,30 @@ try:
except ImportError:
print(gitpython_msg)
print("")
input("press enter to close...")
exit(1)
sys.exit(1)
from pyenliven import (
echo0,
)
from mtanalyze import(
TRY_SHARE_MT_DIRS,
get_var_and_check,
)
profile_path = None
if 'HOME' in os.environ: # if os.name=="windows":
if 'HOME' in os.environ:
profile_path = os.environ['HOME']
else:
else: # if platform.system() == "Windows"
profile_path = os.environ['USERPROFILE']
def main():
if not os.path.isdir(profile_path):
print("")
print("Failed to get existing home path--tried HOME & USERPROFILE")
print("")
input("press enter to close")
exit(2)
echo0("")
echo0("Failed to get existing home path--tried HOME & USERPROFILE")
echo0("")
return 2
configs_path = os.path.join(profile_path, ".config")
if os.name == "windows":
@ -83,36 +93,44 @@ if not os.path.isdir(GIT_REPOS_PATH):
if not os.path.isdir(GIT_BRANCHES_PATH):
os.makedirs(GIT_BRANCHES_PATH)
USR_SHARE_MINETEST = "/usr/share/games/minetest"
if not os.path.isdir(USR_SHARE_MINETEST):
if os.path.isdir("/usr/local/share/minetest"):
# IF git version is installed:
USR_SHARE_MINETEST = "/usr/local/share/minetest"
if os.path.isdir("/usr/share/minetest"):
USR_SHARE_MINETEST = "/usr/share/minetest"
if not os.path.isdir(USR_SHARE_MINETEST):
print("Minetest could not be found in any known location."
'''
USR_SHARE_MINETEST = None
for try_share_mt in TRY_SHARE_MT_DIRS:
if os.path.isdir(try_share_mt):
USR_SHARE_MINETEST = try_share_mt
break
if USR_SHARE_MINETEST is None:
echo0("Minetest could not be found in any known location ({})."
" Try installing minetest or compiling from source or"
" editing value of USR_SHARE_MINETEST in this script."
" The script ended early.")
input("press enter to close...")
exit(3)
" The script ended early.".format(TRY_SHARE_MT_DIRS))
return 3
'''
USR_SHARE_MINETEST, code = get_var_and_check('shared_minetest_path', 3)
if code != 0:
return code
MT_GAMES_DIR = os.path.join(USR_SHARE_MINETEST, "games")
MT_MYGAME_NAME = "subgametest"
MT_MYGAME_DIR = os.path.join(MT_GAMES_DIR, MT_MYGAME_NAME)
mtg_game_name = "minetest_game"
MTG_PATH = os.path.join(MT_GAMES_DIR, mtg_game_name)
folder_path = MTG_PATH
MTG_MODS_PATH = os.path.join(MTG_PATH, "mods")
MTG_PATH = None
mtg_game_name = None
base_game_path = None
base_games = ["amhi_game", "minetest_game"]
for try_game_name in base_games:
MTG_PATH = os.path.join(MT_GAMES_DIR, try_game_name)
base_game_path = MTG_PATH
if os.path.isdir(base_game_path):
mtg_game_name = try_game_name
if mtg_game_name is None:
echo0("Could not find \"" + base_game_path + "\". Script ended early.")
echo0("Set shared_minetest_path to the path containing a")
echo0(" games folder with one of the following: {}".format(base_games))
return 4
if not os.path.isdir(folder_path):
print("Could not find \"" + folder_path + "\". Script ended early.")
input("press enter to close...")
exit(4)
MTG_MODS_PATH = os.path.join(MTG_PATH, "mods")
if force_update_mtg_enable:
shutil.rmtree(MT_MYGAME_DIR)
@ -122,16 +140,15 @@ if force_update_mtg_enable:
try:
# DOES update minetest_game, but does NOT delete extra mods:
update_tree(folder_path, MT_MYGAME_DIR)
print("Updated \"" + MT_MYGAME_DIR + "\"...")
update_tree(base_game_path, MT_MYGAME_DIR)
echo0("Updated \"" + MT_MYGAME_DIR + "\"...")
except PermissionError:
print(str(sys.exc_info()))
print("")
print("You must run " + __file__ + " as a user that can write to "
echo0(str(sys.exc_info()))
echo0("")
echo0("You must run " + __file__ + " as a user that can write to "
"\"" + MT_MYGAME_DIR + "\"")
print("")
input("press enter to close...")
exit(5)
echo0("")
return 5
try:
# cd $HOME
@ -140,76 +157,72 @@ try:
outs.write("name = subgametest")
outs.close()
except PermissionError:
print(str(sys.exc_info()))
print("")
print("You must run " + __file__ + " as a user that can write to "
echo0(str(sys.exc_info()))
echo0("")
echo0("You must run " + __file__ + " as a user that can write to "
"\"" + MT_MYGAME_DIR + "\"")
print("")
input("press enter to close...")
exit(6)
echo0("")
return 6
# cmd_string = "sudo mv -f game.conf \MT_MYGAME_DIR\""
# shutil.move(tmp_game_conf_path, os.path.join(MT_MYGAME_DIR, "game.conf"))
if os.path.isdir(os.path.join(MT_MYGAME_DIR, "mods")):
print("Copied subgame to " + MT_MYGAME_DIR)
good_dir = os.path.join(MT_MYGAME_DIR, "mods")
if os.path.isdir(good_dir):
echo0("Copied subgame to " + MT_MYGAME_DIR)
else:
print("FAILED to copy subgame to " + MT_MYGAME_DIR)
input("press enter to close...")
exit(7)
echo0('FAILED to copy subgame to "{}" ("{}" is missing)'
''.format(MT_MYGAME_DIR, good_dir))
return 7
MT_MYGAME_MODS_PATH = os.path.join(MT_MYGAME_DIR, "mods")
MTMOD_DEST_NAME = "minigamer"
MTMOD_DEST_PATH = os.path.join(MT_MYGAME_MODS_PATH, MTMOD_DEST_NAME)
# if force_update_mtg_mods_enable:
# for sub_name in os.listdir(folder_path):
# sub_path = os.path.join(folder_path, sub_name)
# for sub_name in os.listdir(base_game_path):
# sub_path = os.path.join(base_game_path, sub_name)
# dst_path = os.path.join(MT_MYGAME_DIR, sub_name)
# if sub_name[:1]!="." and os.path.isdir(sub_path):
# if os.path.isdir(dst_path):
# shutil.rmtree(dst_path)
if not os.path.isdir(GIT_REPOS_PATH):
print("Cannot create " + GIT_REPOS_PATH + " so cannot continue.")
input("press enter to close...")
exit(8)
echo0("Cannot create " + GIT_REPOS_PATH + " so cannot continue.")
return 8
# TODO: actually install something (from spreadsheet maybe)
mtg_mods_list = list()
folder_path = MTG_MODS_PATH
if os.path.isdir(folder_path):
for sub_name in os.listdir(folder_path):
sub_path = os.path.join(folder_path, sub_name)
src_mods_path = MTG_MODS_PATH
if os.path.isdir(src_mods_path):
for sub_name in os.listdir(src_mods_path):
sub_path = os.path.join(src_mods_path, sub_name)
if sub_name[:1] != "." and os.path.isdir(sub_path):
mtg_mods_list.append(sub_name)
mods_installed_list = list()
mods_added_list = list()
folder_path = MT_MYGAME_MODS_PATH
if os.path.isdir(folder_path):
for sub_name in os.listdir(folder_path):
sub_path = os.path.join(folder_path, sub_name)
dst_mods_path = MT_MYGAME_MODS_PATH
if os.path.isdir(dst_mods_path):
for sub_name in os.listdir(dst_mods_path):
sub_path = os.path.join(dst_mods_path, sub_name)
if sub_name[:1] != "." and os.path.isdir(sub_path):
mods_installed_list.append(sub_name)
if sub_name not in mtg_mods_list:
mods_added_list.append(sub_name)
else:
print("Missing '" + folder_path + "'")
echo0("Missing '" + dst_mods_path + "'")
print("")
print("")
print("Installed " + str(len(mods_installed_list)) + " mod(s)" +
echo0("")
echo0("")
echo0("Installed " + str(len(mods_installed_list)) + " mod(s)" +
" (" + str(len(mtg_mods_list)) + " from " + mtg_game_name + ").")
if len(mods_added_list) > 0:
print("Added:")
for mod_name in mods_added_list:
print(" - " + mod_name)
print("")
input("press enter to close...")
echo0("")
# cd $TMP_DIR
# git clone https://github.com/tenplus1/mobs_redo.git
# git clone https://github.com/tenplus1/mobs_animal.git
@ -220,3 +233,11 @@ input("press enter to close...")
# git clone https://github.com/poikilos/birthstones.git
# Repo.clone_from(git_url, repo_dir)
return 0
if __name__ == "__main__":
code = main()
# if code != 0:
# input("press enter to close...")
sys.exit(code)

31
install.py

@ -11,9 +11,10 @@ if platform.system() == "Windows":
else:
profile = os.environ.get('HOME')
def error(msg):
sys.stderr.write("{}\n".format(msg))
sys.stderr.flush()
def echo0(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
try:
import mtanalyze
@ -23,12 +24,20 @@ except ModuleNotFoundError as ex:
sys.path.append(tryMTA)
import mtanalyze
else:
error("")
error("You must install mtanalyze in the directory alongside")
error("EnlivenMinetest or as ~/git/mtanalize")
error("such as via:")
error("git clone https://github.com/poikilos/mtanalyze ~/git/mtanalize")
error("")
echo0("")
echo0("You must install mtanalyze in the directory alongside")
echo0("EnlivenMinetest or as ~/git/mtanalize")
echo0("such as via:")
echo0("git clone https://github.com/poikilos/mtanalyze ~/git/mtanalize")
echo0("")
# raise tryMTA
exit(1)
print("This doesn't work (not yet implemented). See build.py.")
sys.exit(1)
def main():
echo0("This doesn't work (not yet implemented). See build.py.")
return 1
if __name__ == "__main__":
sys.exit(main())

144
mtsenliven.py

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
from __future__ import print_function
# runs minetestserver using the paths defined by minetestinfo
@ -7,7 +7,7 @@ from __future__ import print_function
# dr4Ke on
# https://forum.minetest.net/viewtopic.php?f=11&t=13138&start=50
import os
from mtanalyze.minetestinfo import *
import sys
import subprocess
import signal
try:
@ -20,55 +20,26 @@ try:
except ImportError:
from queue import Queue # Python 3
key_exit_msg = "SIGINT should shut down server safely...\n"
game_id = "ENLIVEN"
# screen -S MinetestServer $mts --gameid ENLIVEN --worldname ...
print()
print()
print()
if not minetestinfo.contains("minetestserver_path"):
print("[ mtsenliven.py ] ERROR: minetestserver_path"
" was not found in your version of minetestinfo.py")
exit(1)
mts = minetestinfo.get_var("minetestserver_path")
if not minetestinfo.contains("primary_world_path"):
print("[ mtsenliven.py ] ERROR: primary_world_path"
"was selected by minetestinfo.py")
exit(2)
wp = minetestinfo.get_var("primary_world_path")
wn = os.path.basename(wp)
print("Using minetestserver: " + mts)
print("Using primary_world_path: " + wp)
print("Using world_name: " + wn)
print()
process = None
try:
# get both stdout and stderr (see
# https://www.saltycrane.com/blog/2008/09/how-get-stdout-and-
# stderr-using-python-subprocess-module/)
process = subprocess.Popen(
[mts, '--gameid', game_id, '--worldname', wn],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
bufsize=1
REPO_PATH = os.path.dirname(os.path.realpath(__file__))
# ^ realpath follows symlinks
REPOS_PATH = os.path.dirname(REPO_PATH)
TRY_REPO_PATH = os.path.join(REPOS_PATH, "mtanalyze")
if os.path.isfile(os.path.join(TRY_REPO_PATH, "mtanalyze", "__init__.py")):
# ^ Yes, it is 2 mtanalyze deep,
# such as "$HOME/git/mtanalyze/mtanalyze/__init__.py"
sys.path.insert(0, TRY_REPO_PATH)
from pyenliven import (
echo0,
echo1,
)
# from mtanalyze.minetestinfo import *
from mtanalyze import (
mti,
get_var_and_check,
)
# bufsize=1 as per jfs on <https://stackoverflow.com/questions/
# 31833897/python-read-from-subprocess-stdout-and-stderr-
# separately-while-preserving-order>
except Exception as e:
print(mts + " could not be executed. Try installing the "
" minetest-server package or compiling from git instructions"
" on minetest.net")
print(e)
exit(1)
msgprefix_flags = ["WARNING[Server]: ", "ACTION[Server]: "]
msgprefix_lists = {} # where flag is key
for flag in msgprefix_flags:
msgprefix_lists[flag] = []
# see https://www.endpoint.com/blog/2015/01/28/getting-realtime-output-
# using-python
non_unique_wraps = []
non_unique_wraps.append(
@ -83,6 +54,11 @@ unique_flags = [
"joins game"
]
msgprefix_flags = ["WARNING[Server]: ", "ACTION[Server]: "]
msgprefix_lists = {} # where flag is key
for flag in msgprefix_flags:
msgprefix_lists[flag] = []
def print_unique_only(output, err_flag=False):
output_strip = output.strip()
@ -124,7 +100,7 @@ def print_unique_only(output, err_flag=False):
if show_enable:
print(output_strip)
if found_flag is not None:
print(" [ mtsenliven.py ] " + msg_msg
echo0(" [ mtsenliven.py ] " + msg_msg
+ " will be suppressed")
@ -158,7 +134,7 @@ def reader(pipe, q):
finally:
q.put(None)
except KeyboardInterrupt:
print("[ mtsenliven.py ] " + key_exit_msg)
echo0("[ mtsenliven.py ] " + key_exit_msg)
pass
@ -167,9 +143,59 @@ def decode_safe(b):
s = b.decode()
except UnicodeDecodeError:
s = b.decode('utf-8')
'''
except AttributeError as ex:
if "'str' object has no attribute" in str(ex):
return b
raise ex
'''
return s
def main():
key_exit_msg = "SIGINT should shut down server safely...\n"
game_id = "ENLIVEN"
# screen -S MinetestServer $mts --gameid ENLIVEN --worldname ...
echo0()
echo0()
echo0()
mts, code = get_var_and_check("minetestserver_path", code=1)
if code != 0:
return code
wp, code = get_var_and_check("primary_world_path", code=1)
if code != 0:
return code
wn = os.path.basename(wp)
echo0("Using minetestserver: " + mts)
echo0("Using primary_world_path: " + wp)
echo0("Using world_name: " + wn)
echo0()
process = None
try:
# get both stdout and stderr (see
# https://www.saltycrane.com/blog/2008/09/how-get-stdout-and-
# stderr-using-python-subprocess-module/)
process = subprocess.Popen(
[mts, '--gameid', game_id, '--worldname', wn],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
bufsize=1
)
# bufsize=1 as per jfs on <https://stackoverflow.com/questions/
# 31833897/python-read-from-subprocess-stdout-and-stderr-
# separately-while-preserving-order>
except Exception as e:
echo0(mts + " could not be executed. Try installing the "
" minetest-server package or compiling from git instructions"
" on minetest.net")
echo0(e)
return 2
# see https://www.endpoint.com/blog/2015/01/28/getting-realtime-output-
# using-python
q = Queue()
Thread(target=reader, args=[process.stdout, q]).start()
Thread(target=reader, args=[process.stderr, q]).start()
@ -181,14 +207,14 @@ try:
l_s = line
# NOTE: source is a string such as
# "<_io.BufferedReader name=5>"
l_s = decode_safe("utf-8")
l_s = decode_safe(line) # line.decode("utf-8")
process_msg("%s: %s" % (s, l_s))
except KeyboardInterrupt:
print("[ mtsenliven.py ] " + key_exit_msg)
pass
exit(0)
return 0
'''
while True:
try:
# can deadlock on high volume--use communicate instead
@ -205,6 +231,12 @@ while True:
# process_msg(err_bytes)
rc = process.poll()
except KeyboardInterrupt:
print("[ mtsenliven.py ] " + key_exit_msg)
echo0("[ mtsenliven.py ] " + key_exit_msg)
break
# process.kill()
return 0
'''
if __name__ == "__main__":
sys.exit(main())

11
notes/continuify.py

@ -9,6 +9,7 @@ comparison purposes and link.txt files).
import sys
import os
def continuify(inPath, outPath, continueStr=" \\", indent=" ",
sep=" "):
with open(outPath, 'w') as outs:
@ -28,21 +29,23 @@ def continuify(inPath, outPath, continueStr=" \\", indent=" ",
if i >= 0:
starter = indent
def main():
if len(sys.argv) < 2:
print("You must specify file(s).")
exit(1)
return 1
for i in range(1, len(sys.argv)):
arg = sys.argv[i]
if not os.path.isfile(arg):
print("ERROR: {} is not a file.".format(arg))
exit(1)
return 2
# parts = os.path.splitext(arg)
# outPath = parts[0] + ".tmp" + parts[1]
outPath = arg + ".continuified.tmp"
continuify(arg, outPath)
print("* wrote \"{}\"".format(outPath))
pass
return 0
if __name__ == "__main__":
main()
sys.exit(main())

103
pyenliven/__init__.py

@ -0,0 +1,103 @@
#!/usr/bin/env python
'''
This module assists with building games from other games, mods, and
patches.
'''
from __future__ import print_function
import sys
import platform
import os
profile = None
if platform.system() == "Windows":
profile = os.environ.get('USERPROFILE')
else:
profile = os.environ.get('HOME')
verbosity = 0
max_verbosity = 2
def echo0(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
def echo1(*args, **kwargs):
if verbosity < 1:
return False
print(*args, file=sys.stderr, **kwargs)
return True
def echo2(*args, **kwargs):
if verbosity < 2:
return False
print(*args, file=sys.stderr, **kwargs)
return True
def get_verbosity():
return verbosity
def set_verbosity(level):
if level is True:
verbosity = 1
elif level is False:
verbosity = 0
elif level in range(max_verbosity+1):
verbosity = level
raise ValueError(
"verbosity must be {} at maximum.".format(max_verbosity)
)
try:
import mtanalyze
except ModuleNotFoundError as ex:
# tryMTA = os.path.join(profile, "git", "mtanalyze")
moduleDir = os.path.dirname(os.path.realpath(__file__))
REPO_DIR = os.path.dirname(moduleDir)
modulesDir = os.path.dirname(REPO_DIR)
echo0("* looking for mtanalyze in modulesDir \"{}\""
"".format(modulesDir))
tryMTA = os.path.abspath(os.path.join(modulesDir, "mtanalyze"))
if os.path.isdir(tryMTA):
sys.path.append(tryMTA)
import mtanalyze
# ^ import mtanalyze/mtanalyze purposely since the main
# mtanalyze/ directory is a setuptools package not a module.
else:
echo0("")
echo0("You must install mtanalyze alongside")
echo0("EnlivenMinetest such that ../mtanalize/mtanalize exists")
echo0("such as via:")
echo0(" git clone https://github.com/poikilos/mtanalyze {}"
"".format(tryMTA))
echo0("")
# raise tryMTA
exit(1)
# from mtanalyze import profile_path
MY_MODULE_DIR = os.path.dirname(os.path.realpath(__file__))
# ^ realpath follows symlinks
REPO_DIR = os.path.dirname(MY_MODULE_DIR)
MODS_STOPGAP_DIR = os.path.join(REPO_DIR, "patches", "mods-stopgap")
if not os.path.isdir(MODS_STOPGAP_DIR):
echo0("Error: \"{}\" is missing.".format(MODS_STOPGAP_DIR))
exit(1)
BASE_DIR = os.path.join(REPO_DIR, "Bucket_Game-base")
if not os.path.isdir(BASE_DIR):
echo0("Error: \"{}\" is missing.".format(BASE_DIR))
exit(1)
BRANCHES_DIR = os.path.join(REPO_DIR, "Bucket_Game-branches")
if not os.path.isdir(BRANCHES_DIR):
echo0("Error: \"{}\" is missing.".format(BRANCHES_DIR))
exit(1)
# NOTE: get a git repo's origin via: git remote show origin
def getSGPath(stopgap_mod_name):
return os.path.join(MODS_STOPGAP_DIR, stopgap_mod_name)

30
pyenliven/compatiblizemod.py

@ -4,9 +4,10 @@ import sys
import os
import shutil
def error(msg):
sys.stderr.write("{}\n".format(msg))
sys.stderr.flush()
def echo0(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
def add_depends(mod_path):
mod_dir_name = os.path.basename(mod_path)
@ -41,10 +42,10 @@ def add_depends(mod_path):
print("* created {}/modpack.txt"
"".format(mod_dir_name))
else:
error("{}/modpack.txt already exists for compatibility."
echo0("{}/modpack.txt already exists for compatibility."
"".format(mod_dir_name))
if os.path.isfile(modpack_txt):
error("{}/{} indicates it is a modpack."
echo0("{}/{} indicates it is a modpack."
"".format(mod_dir_name, found_modpack_file))
for sub in os.listdir(mod_path):
if sub.startswith('.'):
@ -52,19 +53,19 @@ def add_depends(mod_path):
subPath = os.path.join(mod_path, sub)
add_depends(subPath)
# It must be a modpack, so return after doing subdirectories.
return
return 1
depends_path = os.path.join(mod_path, "depends.txt")
description_path = os.path.join(mod_path, "description.txt")
if os.path.isfile(depends_path):
error("WARNING: Writing {} will be skipped since it exists."
echo0("WARNING: Writing {} will be skipped since it exists."
"".format(depends_path))
return
return 0
mod_conf = os.path.join(mod_path, "mod.conf")
if not os.path.isfile(mod_conf):
error("WARNING: Writing {} will be skipped since {} does"
echo0("WARNING: Writing {} will be skipped since {} does"
" not exist."
"".format(depends_path, mod_conf))
return
return 1
optional_depends = None
depends = None
description = None
@ -117,14 +118,17 @@ def add_depends(mod_path):
if os.path.isfile(description_path):
print("* INFO: There is already a description.txt so it"
" will be left intact.")
return
return 0
with open(description_path, 'w') as outs:
outs.write("{}\n".format(description))
print("* wrote {}/description.txt".format(mod_dir_name))
return 0
def main():
parent = os.path.realpath(".")
add_depends(parent)
return add_depends(parent)
if __name__ == "__main__":
main()
sys.exit(main())

3
pyenliven/deprecated.py

@ -1,4 +1,4 @@
#!/usr/bin/env
#!/usr/bin/env python3
class Repo:
'''
WARNING: The real Repo class is in enliven.py
@ -6,6 +6,7 @@ class Repo:
print(__doc__)
pass
class GiteaRepo(Repo):
'''
This class is deprecated since the "options" sequential argument

77
setup.py

@ -0,0 +1,77 @@
#!/usr/bin/env python
import setuptools
import sys
import os
# - For the example on which this was based, see
# https://github.com/poikilos/linux-preinstall/blob/main/setup.py
# which is based on
# https://github.com/poikilos/world_clock/blob/main/setup.py
# which is based on
# https://github.com/poikilos/nopackage/blob/main/setup.py
# which is based on
# https://github.com/poikilos/pypicolcd/blob/master/setup.py
# - For nose, see https://github.com/poikilos/mgep/blob/master/setup.py
# python_mr = sys.version_info.major
# versionedModule = {}
# versionedModule['urllib'] = 'urllib'
# if python_mr == 2:
# versionedModule['urllib'] = 'urllib2'
install_requires = []
if os.path.isfile("requirements.txt"):
with open("requirements.txt", "r") as ins:
for rawL in ins:
line = rawL.strip()
if len(line) < 1:
continue
install_requires.append(line)
description = '''Manage Minetest using Python.'''
long_description = description
if os.path.isfile("readme.md"):
with open("readme.md", "r") as fh:
long_description = fh.read()
setuptools.setup(
name='pyenliven',
version='0.3.0',
description=description,
long_description=long_description,
long_description_content_type="text/markdown",
classifiers=[
'Development Status :: 3 - Alpha',
'Programming Language :: Python :: 3',
('License :: OSI Approved ::'
' GNU General Public License v2 or later (GPLv2+)'),
'Operating System :: POSIX :: Linux',
'Topic :: Software Development :: Version Control',
],
keywords=('minetest repo management commit data analyzer'
' meld merge compare files diff'),
url="https://github.com/poikilos/EnlivenMinetest",
author="Jake Gustafson",
author_email='7557867+poikilos@users.noreply.github.com',
license='GPLv2.1',
# packages=setuptools.find_packages(),
packages=['pyenliven'],
# include_package_data=True, # look for MANIFEST.in
# scripts=['example'] ,
# See <https://stackoverflow.com/questions/27784271/
# how-can-i-use-setuptools-to-generate-a-console-scripts-entry-
# point-which-calls>
entry_points={
'console_scripts': [
'compatiblizemod=pyenliven.compatiblizemod:main',
],
},
install_requires=install_requires,
# versionedModule['urllib'],
# ^ "ERROR: Could not find a version that satisfies the requirement
# urllib (from nopackage) (from versions: none)
# ERROR: No matching distribution found for urllib"
test_suite='nose.collector',
tests_require=['nose', 'nose-cover3'],
zip_safe=False, # It can't run zipped due to needing data files.
)

17
uninstall-minetestserver-git.py

@ -1,6 +1,9 @@
#!/usr/bin/env python3
import os
import sys
import platform
def main():
CMD_REM = "#"
CMD_RM = "rm "
CMD_RMDIR = "rmdir "
@ -22,7 +25,7 @@ if platform.system() == "Windows":
# print("ERROR: Nothing done since there is no minetest sourcecode"
# " folder in " + downloads_path
# + " (nor " + profile_path + ")")
# exit(1)
# return 1
install_manifest_name = "install_manifest.txt"
# install_manifest_path = os.path.join(repo_path, install_manifest_name)
# if not os.path.isfile(install_manifest_path):
@ -31,14 +34,14 @@ install_manifest_name = "install_manifest.txt"
# "'. The file would only be present if you " +
# "installed minetest from sourcecode" +
# "(otherwise this uninstaller is not for you).")
# exit(2)
# return 2
if not os.path.isfile(install_manifest_name):
print("ERROR: nothing done since there is no " +
install_manifest_name + " in the current " +
"directory. You must run: ")
print(" sudo python3 "+os.path.abspath(__file__))
print("from the minetest sourcecode (repo) directory.")
exit(2)
return 2
directories = []
print("Removing files...")
f_removed_count = 0
@ -156,6 +159,7 @@ print("Removed " + str(d_removed_count) + " folder(s) (skipped not"
" present:" +
str(d_skipped_count) + "; failed:" + str(d_failed_count) + ")")
code = 0
if f_failed_count+d_failed_count+ed_failed_count <= 0:
print("")
if f_removed_count+d_removed_count <= 0:
@ -177,7 +181,14 @@ else:
"If any more remain, you may have to remove them manually.")
print("")
print("")
code = 1
if not ins.closed:
print("ERROR: ins was not closed (this should never happen)--"
"closing manually...")
ins.close()
code = 1
return code
if __name__ == "__main__":
sys.exit(main())

8
utilities/compatiblizemod.py

@ -8,13 +8,13 @@ import re
import sys
import os
myDir = os.path.dirname(os.path.realpath(__file__))
repoDir = os.path.dirname(myDir)
UTILITIES_DIR = os.path.dirname(os.path.realpath(__file__))
REPO_DIR = os.path.dirname(UTILITIES_DIR)
# try:
# from pyenliven.compatiblizemod import main
# except ModuleNotFoundError:
if os.path.isdir(os.path.join(repoDir, "pyenliven")):
sys.path.append(repoDir)
if os.path.isfile(os.path.join(REPO_DIR, "pyenliven", "__init__.py")):
sys.path.append(REPO_DIR)
from pyenliven.compatiblizemod import main

97
utilities/enissue.py

@ -93,7 +93,7 @@ except ImportError:
# see <https://stackoverflow.com/questions/5574702/how-to-print-to-stderr-in-python>
def error(*args, **kwargs):
def echo0(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
@ -261,7 +261,7 @@ def debug(*args, **kwargs):
if verbose:
if len(args) > 0:
msg = args[0]
error("[debug] " + msg)
echo0("[debug] " + msg)
def set_verbose(on):
@ -353,6 +353,8 @@ match_all_labels = []
trues = ["true", "on", "yes"]
falses = ["false", "off", "no"]
# TODO: Consider from pycodetool import to_syntax_error
# (to replace instances of {}:{}: formatted by `path, line` below).
def str_to_value(valueStr, typeName=None, lineN=-1, path="(generated)"):
'''
@ -387,7 +389,7 @@ def str_to_value(valueStr, typeName=None, lineN=-1, path="(generated)"):
if typeName is not None:
if valueStr == "None":
error("{}:{}: WARNING: The program expected a(n) '{}' but"
echo0("{}:{}: WARNING: The program expected a(n) '{}' but"
" the value was 'None' and will become"
" None."
"".format(conf_path, lineN, typeName))
@ -490,7 +492,7 @@ def modify_dict_by_conf(options, conf_path, always_lower=False,
continue
signI = line.find("=")
if signI < 1:
error("{}:{}: A value is expected before '='."
echo0("{}:{}: A value is expected before '='."
"".format(conf_path, lineN))
name = line[:signI].strip()
valueStr = line[signI+1:].strip()
@ -499,11 +501,11 @@ def modify_dict_by_conf(options, conf_path, always_lower=False,
value = None
if always_lower:
if name.lower() != name:
error("{}:{}: A lowercase name is expected."
echo0("{}:{}: A lowercase name is expected."
"".format(conf_path, lineN))
continue
if (valueStr is None) and no_value_error:
error("{}:{}: A value is expected."
echo0("{}:{}: A value is expected."
"".format(conf_path, lineN))
else:
typeName = None
@ -514,11 +516,11 @@ def modify_dict_by_conf(options, conf_path, always_lower=False,
path=conf_path, lineN=lineN)
options[name] = value
if not quiet:
error("[settings] {}: Set {} to {}"
echo0("[settings] {}: Set {} to {}"
"".format(conf_name, name, value))
else:
if no_file_error:
error("Error: \"{}\" Doesn't exist"
echo0("Error: \"{}\" Doesn't exist"
"".format(conf_path, lineN))
@ -664,7 +666,7 @@ class Repo:
self.remote_user = "almikes@aol.com" # Wuzzy2
if self.api_id is not None:
if self.api_id != 'git_instaweb':
error("WARNING: URL has [] but self.api_id was {}"
echo0("WARNING: URL has [] but self.api_id was {}"
"".format(urlParts[-2], self.api_id))
self.api_id = "git_instaweb"
# Such as https://repo.or.cz/minetest_treasurer.git
@ -701,8 +703,8 @@ class Repo:
if self.api_id is None:
self.api_id = "Gitea"
if "github.com" in repo_url.lower():
error("WARNING: assuming Gitea but URL has github.com.")
error(" * assuming API is {} for {}"
echo0("WARNING: assuming Gitea but URL has github.com.")
echo0(" * assuming API is {} for {}"
"".format(self.api_id, ))
if self.api_id is None:
raise RuntimeError("api_id is not set")
@ -1113,7 +1115,7 @@ class Repo:
results = result
err = to_error(result)
if err is not None:
error("WARNING: a website error was saved"
echo0("WARNING: a website error was saved"
" as an issue, so it will be deleted:"
" \"{}\""
"".format(c_path))
@ -1126,7 +1128,7 @@ class Repo:
"".format(results_key))
results = results[results_key]
else:
error("WARNING: expected {} in dict"
echo0("WARNING: expected {} in dict"
"".format(results_key))
if result is not None:
if hasattr(results, 'keys'):
@ -1461,9 +1463,9 @@ class Repo:
fn += ".json"
c_path += ".json"
else:
error("url: {}".format(url))
error("self.labels_url: {}".format(self.labels_url))
error("self.issues_url: {}".format(self.issues_url))
echo0("url: {}".format(url))
echo0("self.labels_url: {}".format(self.labels_url))
echo0("self.issues_url: {}".format(self.issues_url))
raise NotImplementedError("getCachedJsonDict"
" doesn't have a cache directory"
" for {}. Try --refresh"
@ -1494,8 +1496,8 @@ class Repo:
try:
result = json.load(json_file)
except json.decoder.JSONDecodeError as ex:
error("")
error(p+"The file {} isn't valid JSON"
echo0("")
echo0(p+"The file {} isn't valid JSON"
" and will be overwritten if loads"
"".format(c_path))
result = None
@ -1505,7 +1507,7 @@ class Repo:
err = to_error(result)
if err is not None:
result = None
error("Error: An error was saved as an issue"
echo0("Error: An error was saved as an issue"
" so it will be deleted: {}"
"".format(c_path))
os.remove(c_path)
@ -1691,8 +1693,8 @@ class Repo:
msg = ("WARNING: comments={} but there is no"
" comments_url in:"
"".format(comments))
# error(msg)
# error(json.dumps(issue_data, indent=4, sort_keys=True))
# echo0(msg)
# echo0(json.dumps(issue_data, indent=4, sort_keys=True))
for evt in data:
user = evt.get('user')
@ -1784,7 +1786,7 @@ class Repo:
never_expire=never_expire,
)
if err is not None:
error("Accessing the reactions URL failed: {}"
echo0("Accessing the reactions URL failed: {}"
"".format(err.get('reason')))
if reac_data is not None:
for reac in reac_data:
@ -2009,10 +2011,10 @@ class Repo:
if results is None:
if err is not None:
if err.get('code') == 410:
# error("The issue was deleted")
# echo0("The issue was deleted")
pass
elif err.get('code') == 404:
# error("The issue doesn't exist")
# echo0("The issue doesn't exist")
pass
return None, err
else:
@ -2111,10 +2113,10 @@ def main(custom_args=None):
else:
if issue_no is not None:
usage()
error("Error: Only one issue number can be"
echo0("Error: Only one issue number can be"
" specified but you also specified"
" {}.".format(arg))
exit(1)
return 1
issue_no = i
is_text = False
except ValueError:
@ -2129,15 +2131,15 @@ def main(custom_args=None):
state = 'closed'
elif arg == "--test":
tests()
error("All tests passed.")
sys.exit(0)
echo0("All tests passed.")
return 0
elif arg == "--verbose":
verbose = True
elif arg == "--debug":
verbose = True
elif arg == "--help":
usage()
exit(0)
return 0
elif arg in collect_logic:
save_key = arg.strip("-").replace("-", "_")
elif arg in collect_options:
@ -2149,9 +2151,9 @@ def main(custom_args=None):
# else: the next arg will be the value.
elif arg.startswith("--"):
usage()
error("Error: The argument \"{}\" is not valid"
echo0("Error: The argument \"{}\" is not valid"
"".format(arg))
exit(1)
return 2
elif prev_arg in SEARCH_COMMANDS:
search_terms.append(arg)
isValue = True
@ -2162,15 +2164,15 @@ def main(custom_args=None):
# print("* adding criteria: {}".format(arg))
if len(search_terms) < 1:
usage()
error("You can only specify \"AND\" after"
echo0("You can only specify \"AND\" after"
" the \"find\" command. To literally"
" search for the word \"AND\", place"
" the \"find\" command before it."
" Examples:")
for andI in modes['find']['AND_EXAMPLES']:
error(me
echo0(me
+ modes['find']['examples'][andI])
exit(1)
return 3
mode = "list"
elif save_key is not None:
logic[save_key] = arg
@ -2220,7 +2222,7 @@ def main(custom_args=None):
usage()
print()
print()
sys.exit(0)
return 0
elif mode not in valid_modes:
print()
print()
@ -2229,12 +2231,12 @@ def main(custom_args=None):
print(mode + " is not a valid command.")
print()
print()
sys.exit(0)
return 0
elif mode == "list":
if issue_no is not None:
print("Error: You must specify either an issue number"
" or query criteria, not both.")
sys.exit(1)
return 4
print("")
if caches_path is not None:
@ -2287,12 +2289,12 @@ def main(custom_args=None):
db_type = logic.get('db-type')
if db_type is None:
db_type = "PostgresQL"
error("WARNING: No db-type was specified, so db-type was"
echo0("WARNING: No db-type was specified, so db-type was"
" set to the default: {}".format(db_type))
db_u = logic.get("db-user")
if db_u is None:
db_u = Repo.os_user
error("WARNING: No db-type was specified, so db-user was"
echo0("WARNING: No db-type was specified, so db-user was"
" set to the default: {}".format(db_u))
pass
db_p = logic.get('db-password')
@ -2301,7 +2303,7 @@ def main(custom_args=None):
if "deleted" in msg:
is_deleted = True
if db_p is None:
error("WARNING: No db-password was specified, so the db"
echo0("WARNING: No db-password was specified, so the db"
" operation will be attempted without it."
" Success will depend on your database type and"
" settings.")
@ -2309,14 +2311,14 @@ def main(custom_args=None):
'repo_url': dstRepoUrl,
})
# print("* rewriting Gitea issue {}...".format(issue_no))
sys.exit(0) # Change based on return of the method.
return 5 # TODO: Change based on return of the method.
if msg is not None:
error(msg)
echo0(msg)
if "deleted" in msg:
sys.exit(0)
return 0
else:
sys.exit(1)
return 6
total_count = 0
print()
# ^ This blank line goes after "@ Cache" messages and before
@ -2324,11 +2326,11 @@ def main(custom_args=None):
if mode == "labels":
if repo.labels is None:
print("There were no labels.")
sys.exit(0)
return 0
else:
if repo.issues is None:
print("There were no issues.")
sys.exit(0)
return 0
match_all_labels_lower = []
p = repo.log_prefix
@ -2494,7 +2496,8 @@ def main(custom_args=None):
else:
debug("There is no summary output due to mode={}".format(mode))
print("")
return 0
if __name__ == "__main__":
main()
sys.exit(main())

39
utilities/enlynx.py

@ -30,31 +30,31 @@ Examples:
'''
import sys
import subprocess
me = "enlynx.py"
browserPath = "lynx"
sessionPath = "/tmp/enlynx.lynx-session"
import sys
import subprocess
enc = {} # URL Encoded single characters
enc[':'] = '%3A'
# ^ Do this with urllib if there are many more
# see <https://stackoverflow.com/questions/5574702/how-to-print-to-stderr-in-python>
def error(*args, **kwargs):
verbose = True
def echo0(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
verbose = True
def debug(msg):
def echo1(*args, **kwargs):
if not verbose:
return
sys.stderr.write("{}\n".format(msg))
sys.stderr.flush()
print(*args, file=sys.stderr, **kwargs)
def usage():
error(__doc__)
echo0(__doc__)
def toSubQueryValue(value):
@ -83,7 +83,8 @@ any_q = "?q=" + toSubQuery("is", "issue")
closed_q = "?q=" + toSubQuery("is", "issue") + '+' + toSubQuery("is", "closed")
if __name__ == "__main__":
def main():
global browserPath
prev_arg = None
findStrings = []
base_q = open_q + "+"
@ -115,31 +116,31 @@ if __name__ == "__main__":
elif arg == "AND":
if len(findStrings) == 0:
usage()
error("Error: You can only use AND after find"
echo0("Error: You can only use AND after find"
" and after another keyword. To literally"
" search for the word \"AND\" itself,"
" say find before the word:\n"
" {} find CREEPS find AND find WEIRDOS\n"
"".format(me))
exit(1)
return 1
prev_arg = arg
elif arg == "page":
prev_arg = arg
else:
encArg = toSubQueryValue(arg)
# if encArg != arg:
# debug("* encoding label as '{}'".format(encArg))
# echo1("* encoding label as '{}'".format(encArg))
# else:
debug("* adding label {}".format(encArg))
echo1("* adding label {}".format(encArg))
labels_subqueries += toSubQuery('label', encArg) + "+"
# Ensure there aren't any dangling commands *after* the loop:
if prev_arg is not None:
usage()
error("Error: You must specify a search term after {}."
echo0("Error: You must specify a search term after {}."
"".format(prev_arg))
exit(1)
return 1
if (_closed is True) and (_open is True):
base_q = any_q + '+'
@ -148,8 +149,6 @@ if __name__ == "__main__":
elif _closed is True:
base_q = closed_q + '+'
for find_str in findStrings:
base_q += find_str + "+"
# else: (dangling '+' at the end when labels_subqueries=="" is ok)
@ -159,3 +158,7 @@ if __name__ == "__main__":
print("URL: {}".format(url))
subprocess.call([browserPath, '-session=' + sessionPath, url])
return 0
if __name__ == "__main__":
sys.exit(main())

29
utilities/extra/uninstall.py

@ -1,16 +1,18 @@
#!/usr/bin/env python
import os
import sys
import platform
def doDie(msg, error_code=1):
def show_error(msg, error_code=1):
print()
print(msg)
print()
print()
exit(error_code)
return error_code
def main():
rem_cmd = "#"
rm_cmd = "rm "
rmdir_cmd = "rmdir "
@ -28,8 +30,9 @@ if profile_path2 is not None:
+ profile_path + "' is being used.")
else:
if profile_path1 is None:
doDie(rem_cmd + "ERROR: There is nothing to do since neither"
+ " HOME nor USERPROFILE is present.")
return show_error(rem_cmd + "ERROR: There is nothing to do"
" since neither"
" HOME nor USERPROFILE is present.")
mnf_name = "install_manifest.txt"
mnf_path = os.path.join(profile_path, mnf_name)
@ -37,8 +40,8 @@ mnf_path = os.path.join(profile_path, mnf_name)
unsorted_list = []
if not os.path.isfile(mnf_path):
doDie(rem_cmd + "Uninstall cannot continue since '" + mnf_path
+ "' is missing.")
return show_error(rem_cmd + "Uninstall cannot continue since '"
+ mnf_path + "' is missing.")
with open(mnf_path) as fp:
for cnt, line_original in enumerate(fp):
@ -48,8 +51,8 @@ with open(mnf_path) as fp:
unsorted_list.append(line)
if len(unsorted_list) < 1:
doDie(rem_cmd + "ERROR: There are no files in the manifest '"
+ mnf_path + "'")
return show_error(rem_cmd + "ERROR: There are no files in the manifest"
" '"+ mnf_path + "'")
# See https://stackoverflow.com/questions/4659524/\
# how-to-sort-by-length-of-string-followed-by-alphabetical-order
@ -90,8 +93,9 @@ for path in sorted_list:
if len(does_not_exist) > 0:
if len(does_not_exist) == len(sorted_list):
doDie(" " + rem_cmd + " The program is not installed such as"
+ " at '" + sorted_list[-1] + "'.")
return show_error(rem_cmd + 'The program is not installed such as'
' at "{}".'
''.format(sorted_list[-1]))
show_dot_warning = True
print(rem_cmd + "Uninstall is complete.")
@ -115,3 +119,8 @@ if (len(not_removed_files) + len(not_removed_dirs)) > 0:
print("")
print("")
return 0
if __name__ == "__main__":
sys.exit(main())

23
utilities/generatemod.py

@ -7,13 +7,13 @@ myPath = os.path.realpath(__file__)
myDir = os.path.dirname(myPath)
def customExit(msg, code=1):
def show_error(msg, code=1):
print("")
print("ERROR:")
print(msg)
print("")
print("")
exit(code)
return code
def usage():
@ -44,6 +44,7 @@ def usage():
print("")
def main():
licSrc = "example_license.txt"
licDestName = "LICENSE.txt"
licDesc = "MIT License"
@ -51,7 +52,7 @@ if not os.path.isfile(licSrc):
tryLicSrc = os.path.join(myDir, licSrc)
if not os.path.isfile(tryLicSrc):
print("ERROR: missing " + licSrc)
exit(1)
return 1
else:
licSrc = tryLicSrc
toMod = None
@ -67,11 +68,12 @@ for i in range(1, len(sys.argv)):
else:
if (len(sys.argv[i]) >= 2) and (sys.argv[i][:2] == "--"):
usage()
customExit("Invalid option: " + sys.argv[i])
return show_error("Invalid option: " + sys.argv[i],
code=2)
options.append(sys.argv[i])
if (len(options) != 1) and (len(options) != 3):
usage()
exit(1)
return 3
thisName = options[0]
if os.path.isdir(thisName):
if not enableFill:
@ -79,7 +81,7 @@ if os.path.isdir(thisName):
print("ERROR: A mod named " + thisName + " cannot be ")
print("generated when the directory already exists.")
print("")
exit(1)
return 4
else:
os.mkdir(thisName)
if (len(options) == 3):
@ -90,8 +92,8 @@ if (len(options) == 3):
toMod = toName[:delimI]
if toMod.find(":") > -1:
usage()
customExit("Your modname contains too many colons.")
exit(1)
return show_error("Your modname contains too many colons.",
code=5)
else:
toMod = "default"
@ -196,3 +198,8 @@ print(
)
print("")
print("")
return 0
if __name__ == "__main__":
sys.exit(main())

13
utilities/mtcompile-program-local.py

@ -39,13 +39,13 @@ import platform
import os
def error(msg):
sys.stderr.write(msg + "\n")
def echo0(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
def customExit(msg):
error(msg)
exit(1)
echo0(msg)
sys.exit(1)
def isExecutableFile(path):
@ -575,7 +575,7 @@ def main():
# Confirm that script is running in the right place.
if not os.path.isdir('mtsrc'):
error("""
echo0("""
Error: This script should be stored, and executed, in the directory
which contains the "mtsrc" directory.
""")
@ -1237,7 +1237,8 @@ again.
print("Done\n")
# end main
return 0
if __name__ == "__main__":
main()
sys.exit(main())

10
utilities/mtoldtonew.py

@ -92,20 +92,28 @@ def oldToNew(path, quotechar='"'):
print("* wrote '%s'" % newName)
if __name__ == "__main__":
def main():
for i in range(1, len(sys.argv)):
try_path = sys.argv[i]
if os.path.isfile(try_path):
files.append(try_path)
else:
print("MISSING file: '" + try_path + "'")
return 1
if len(files) < 1:
usage()
print("")
print("You must specify a plain-text schem such as a\n"
".we file, or any file containing double-quoted node names.")
return 2
for oldName in files:
print("Processing %s..." % oldName)
oldToNew(oldName)
return 0
if __name__ == "__main__":
sys.exit(main())

25
utilities/showmissing.py

@ -11,16 +11,6 @@ def usage():
print("")
argCount = len(sys.argv) - 1
if argCount < 2:
usage()
exit(1)
oldPath = sys.argv[1]
newPath = sys.argv[2]
def getStrings(path, delimiter='"', unique=True):
ret = []
got = ""
@ -46,8 +36,23 @@ def getStrings(path, delimiter='"', unique=True):
return ret
def main():
argCount = len(sys.argv) - 1
if argCount < 2:
usage()
return 1
oldPath = sys.argv[1]
newPath = sys.argv[2]
olds = getStrings(oldPath)
news = getStrings(newPath)
for v in olds:
if v not in news:
print(v)
return 0
if __name__ == "__main__":
sys.exit(main())

Loading…
Cancel
Save