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. 43
      buildenliven.py
  6. 177
      deploy.py
  7. 28
      filever.py
  8. 16
      forwardfilesync.py
  9. 34
      generate-mt5-share-fix.py
  10. 44
      headcompare.py
  11. 291
      install-subgametest.py
  12. 31
      install.py
  13. 160
      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. 151
      uninstall-minetestserver-git.py
  20. 8
      utilities/compatiblizemod.py
  21. 97
      utilities/enissue.py
  22. 41
      utilities/enlynx.py
  23. 109
      utilities/extra/uninstall.py
  24. 125
      utilities/generatemod.py
  25. 13
      utilities/mtcompile-program-local.py
  26. 10
      utilities/mtoldtonew.py
  27. 31
      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())

43
buildenliven.py

@ -9,9 +9,10 @@ import os
import configparser
from pyenliven import (
error,
echo0,
getSGPath,
profile,
MODS_STOPGAP_DIR,
)
gamespec = {}
@ -27,25 +28,26 @@ 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"},
# {'repo': "https://github.com/poikilos/homedecor_ua"},
{'name': "animal_materials_legacy"},
{'repo':"https://github.com/minetest-mods/ccompass.git"},
{'repo':"https://github.com/octacian/chat3.git"},
{'repo':"https://github.com/poikilos/compassgps.git"},
{'repo': "https://github.com/minetest-mods/ccompass.git"},
{'repo': "https://github.com/octacian/chat3.git"},
{'repo': "https://github.com/poikilos/compassgps.git"},
{'name': "elk_legacy"},
{'repo':"https://github.com/MinetestForFun/fishing.git"},
{'repo': "https://github.com/MinetestForFun/fishing.git"},
{'name': "glooptest_missing"},
{'repo':"https://github.com/minetest-mods/item_drop.git"},
{'repo':"https://github.com/poikilos/metatools.git"},
{'repo': "https://github.com/minetest-mods/item_drop.git"},
{'repo': "https://github.com/poikilos/metatools.git"},
{'name': "nftools_legacy"},
{'name': "glooptest_missing"},
{'repo':"https://github.com/poikilos/slimenodes.git"},
{'repo':"https://github.com/BenjieFiftysix/sponge.git"},
{'repo':"https://github.com/poikilos/throwing.git"}, # Can utilize toolranks, toolranks_extras, wielded_light
{'repo':"https://github.com/poikilos/throwing_arrows.git"}, # Can utilize mesecons, mesecons_button
{'repo':"https://github.com/mt-mods/biome_lib.git"},
{'repo': "https://github.com/poikilos/slimenodes.git"},
{'repo': "https://github.com/BenjieFiftysix/sponge.git"},
{'repo': "https://github.com/poikilos/throwing.git"}, # Can utilize toolranks, toolranks_extras, wielded_light
{'repo': "https://github.com/poikilos/throwing_arrows.git"}, # Can utilize mesecons, mesecons_button
{'repo': "https://github.com/mt-mods/biome_lib.git"},
{
'repo': "https://github.com/Poikilos/vines.git",
'branch': "Bucket_Game", # git clone <url> --branch <branch>
@ -164,14 +166,15 @@ WARNINGS:
'''
"""
warnings = []
valid_bases = ['Bucket_Game', "bucket_ game"]
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())

177
deploy.py

@ -1,141 +1,150 @@
#!/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
warnings = list()
print("")
print("This script is NOT YET IMPLEMENTED")
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()
echo0("")
echo0("This script is NOT YET IMPLEMENTED")
# TODO: Scrape https://minetest.kitsunemimi.pw/builds/ (NOTE: stable is
# always "https://minetest.kitsunemimi.pw/builds/win64/"
# "minetest-0.4.15-win64.7z")
# TODO: Scrape https://minetest.kitsunemimi.pw/builds/ (NOTE: stable is
# always "https://minetest.kitsunemimi.pw/builds/win64/"
# "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__))
enliven_project_path = os.path.dirname(script_dir_path)
script_dir_path = os.path.dirname(os.path.abspath(__file__))
enliven_project_path = os.path.dirname(script_dir_path)
profile_path = None
if "HOME" in os.environ:
profile_path = None
if "HOME" in os.environ:
profile_path = os.environ["HOME"]
elif "USERPROFILE" in os.environ:
elif "USERPROFILE" in os.environ:
profile_path = os.environ["USERPROFILE"]
else:
else:
try_path = "C:\\Users\\jgustafson"
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.
# region user settings
deploy_path = "C:\\Games\\ENLIVEN-deploy"
try_path = "C:\\Games\\Minetest"
if (not os.path.isdir(deploy_path)) and os.path.isdir(try_path):
# TODO: Make a settings file for values in the next region.
# region user settings
deploy_path = "C:\\Games\\ENLIVEN-deploy"
try_path = "C:\\Games\\Minetest"
if (not os.path.isdir(deploy_path)) and os.path.isdir(try_path):
deploy_path = try_path
installer_deploy_path = path_join_all([profile_path, "ownCloud", "www",
installer_deploy_path = path_join_all([profile_path, "ownCloud", "www",
"expertmultimedia", "downloads"])
installer_name = "install-ENLIVEN.exe"
# endregion user settings
installer_name = "install-ENLIVEN.exe"
# endregion user settings
installer_path = os.path.join(installer_deploy_path, installer_name)
installer_path = os.path.join(installer_deploy_path, installer_name)
if not os.path.isdir(installer_deploy_path):
print("#WARNING: does not exist:")
print("installer_deploy_path: " + installer_deploy_path)
if not os.path.isdir(installer_deploy_path):
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
# if os.path.isfile(installer_path):
# numbers=filever.get_version_number(installer_path)
# major,minor,subminor,revision = numbers
# print(".".join([str (i) for i in numbers]))
# this is a waste--it just shows 0.0.0.0 though iss file has version
# if os.path.isfile(installer_path):
# numbers=filever.get_version_number(installer_path)
# major,minor,subminor,revision = numbers
# print(".".join([str (i) for i in numbers]))
if not os.path.isdir(deploy_path):
if not os.path.isdir(deploy_path):
os.makedirs(deploy_path)
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" +
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):
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")
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" +
# NOTE: remove this case, and instead: copy minetest_game, download ENLIVEN
# automatically
if not os.path.isdir(game_path):
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)
else:
# return 2
else:
print("game_path: " + game_path)
mods_path = os.path.join(game_path, "mods")
if not os.path.isdir(mods_path):
mods_path = os.path.join(game_path, "mods")
if not os.path.isdir(mods_path):
os.makedirs(mods_path)
mtg_list_path = os.path.join(game_path, "minetest_game-mod-list.txt")
mtg_list_out = open(mtg_list_path, 'w')
folder_path = minetest_game_mods_path
if os.path.isdir(folder_path):
mtg_list_path = os.path.join(game_path, "minetest_game-mod-list.txt")
mtg_list_out = open(mtg_list_path, 'w')
folder_path = minetest_game_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)
if sub_name[:1] != "." and os.path.isdir(sub_path):
mtg_list_out.write(sub_name + "\n")
mtg_list_out.close()
mtg_list_out.close()
# TODO: uncomment this: update_tree(minetest_game_path, game_path)
# TODO: uncomment this: update_tree(minetest_game_path, game_path)
server_devel_minetest_conf_path = os.path.join(
server_devel_minetest_conf_path = os.path.join(
game_path,
"minetest.conf.ENLIVEN-server"
)
server_minetest_conf_path = os.path.join(game_path, "minetest.conf")
)
server_minetest_conf_path = os.path.join(game_path, "minetest.conf")
if not os.path.isfile(server_devel_minetest_conf_path):
if not os.path.isfile(server_devel_minetest_conf_path):
warnings.append(server_devel_minetest_conf_path + " was not found")
else:
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)"
rm_sub(["CC-BY-SA 3.0 Unported (fallback license for ENLIVEN assets)"
".txt"])
rm_sub(["MIT LICENSE (fallback license for ENLIVEN code).txt"])
rm_sub(["MIT LICENSE (fallback license for ENLIVEN code).txt"])
# NOTE: At this point, the following LICENSE and README files are
# minetest_game's and the following are intentionally looking in
# C:\games\ENLIVEN\games\ENLIVEN:
# rm_sub(["games", "ENLIVEN", "LICENSE.txt"])
# rm_sub(["games", "ENLIVEN", "README.txt"])
# NOTE: At this point, the following LICENSE and README files are
# minetest_game's and the following are intentionally looking in
# C:\games\ENLIVEN\games\ENLIVEN:
# rm_sub(["games", "ENLIVEN", "LICENSE.txt"])
# rm_sub(["games", "ENLIVEN", "README.txt"])
print("")
if len(warnings) > 0:
print(str(len(warnings)) + " warning(s):")
echo0("")
if len(warnings) > 0:
echo0(str(len(warnings)) + " warning(s):")
for warning in warnings:
print(warning)
else:
print("0 warnings.")
print("\n")
input("press enter to exit...")
echo0(warning)
else:
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())

16
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,17 +159,17 @@ 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():
for k, v in flags.items():
print(CMD_COMMENT + "{}: {}".format(k, v))
update_tree(
@ -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())

34
generate-mt5-share-fix.py

@ -1,21 +1,25 @@
#!/usr/bin/env python3
import os
import shutil
import sys
actions = {"-- Up-to-date: ": "move", "-- Installing: ": "move"}
changes = {
"/usr/local/./": "/usr/local/share/minetest/"
}
count = 0
command_count = 0
in_path = "bad_mt5_make_install_output.txt"
outs_path = os.path.dirname(os.path.realpath(__file__))
out_path = os.path.join(outs_path, "install-fix-minetest5-share.sh")
file_commands = []
rmd_cmds = []
mkdir_commands = []
made_dirs = []
mtg_mod_dirs = ["games//minetest_game/mods", "games/minetest_game/mods"]
with open(in_path) as ins:
def main():
count = 0
command_count = 0
in_path = "bad_mt5_make_install_output.txt"
outs_path = os.path.dirname(os.path.realpath(__file__))
out_path = os.path.join(outs_path, "install-fix-minetest5-share.sh")
file_commands = []
rmd_cmds = []
mkdir_commands = []
made_dirs = []
mtg_mod_dirs = ["games//minetest_game/mods", "games/minetest_game/mods"]
with open(in_path) as ins:
with open(out_path, 'w') as outs:
outs.write("#!/bin/sh\n")
count += 1
@ -140,5 +144,11 @@ with open(in_path) as ins:
count += 1
command_count += 1
print('Added {} line(s) to "{}" (including {} command(s))'
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())

291
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,181 +44,200 @@ 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']
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)
def main():
if not os.path.isdir(profile_path):
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":
configs_path = os.path.join(profile_path, ".config")
if os.name == "windows":
base_path = os.path.join(profile_path, "AppData")
configs_path = os.path.join(base_path, "Local")
CONFIG_PATH = os.path.join(configs_path, "EnlivenMinetest")
if not os.path.isdir(CONFIG_PATH):
CONFIG_PATH = os.path.join(configs_path, "EnlivenMinetest")
if not os.path.isdir(CONFIG_PATH):
os.makedirs(CONFIG_PATH)
# NOTE: not using /var/cache
caches_path = os.path.join(CONFIG_PATH, "cache")
RELEASES_PATH = os.path.join(caches_path, "releases")
GIT_REPOS_PATH = os.path.join(caches_path, "git")
GIT_BRANCHES_PATH = os.path.join(caches_path, "git-branches")
# NOTE: not using /var/cache
caches_path = os.path.join(CONFIG_PATH, "cache")
RELEASES_PATH = os.path.join(caches_path, "releases")
GIT_REPOS_PATH = os.path.join(caches_path, "git")
GIT_BRANCHES_PATH = os.path.join(caches_path, "git-branches")
if not os.path.isdir(RELEASES_PATH):
if not os.path.isdir(RELEASES_PATH):
os.makedirs(RELEASES_PATH)
if not os.path.isdir(GIT_REPOS_PATH):
if not os.path.isdir(GIT_REPOS_PATH):
os.makedirs(GIT_REPOS_PATH)
if not os.path.isdir(GIT_BRANCHES_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)
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")
if not os.path.isdir(folder_path):
print("Could not find \"" + folder_path + "\". Script ended early.")
input("press enter to close...")
exit(4)
if force_update_mtg_enable:
" 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_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
MTG_MODS_PATH = os.path.join(MTG_PATH, "mods")
if force_update_mtg_enable:
shutil.rmtree(MT_MYGAME_DIR)
# yes | cp -rf $MT_GAMES_DIR/minetest_game/* MT_MYGAME_DIR"
# sudo rsync -a $MT_GAMES_DIR/minetest_game/* MT_MYGAME_DIR"
# yes | cp -rf $MT_GAMES_DIR/minetest_game/* MT_MYGAME_DIR"
# sudo rsync -a $MT_GAMES_DIR/minetest_game/* MT_MYGAME_DIR"
try:
try:
# DOES update minetest_game, but does NOT delete extra mods:
update_tree(folder_path, MT_MYGAME_DIR)
print("Updated \"" + MT_MYGAME_DIR + "\"...")
except PermissionError:
print(str(sys.exc_info()))
print("")
print("You must run " + __file__ + " as a user that can write to "
update_tree(base_game_path, MT_MYGAME_DIR)
echo0("Updated \"" + MT_MYGAME_DIR + "\"...")
except PermissionError:
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:
try:
# cd $HOME
# tmp_game_conf_path = os.path.join(profile_path, "game.conf")
outs = open(os.path.join(MT_MYGAME_DIR, "game.conf"), 'w')
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 "
except PermissionError:
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)
# 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)
else:
print("FAILED to copy subgame to " + MT_MYGAME_DIR)
input("press enter to close...")
exit(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)
# 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)
# 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)
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"))
good_dir = os.path.join(MT_MYGAME_DIR, "mods")
if os.path.isdir(good_dir):
echo0("Copied subgame to " + MT_MYGAME_DIR)
else:
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(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):
echo0("Cannot create " + GIT_REPOS_PATH + " so cannot continue.")
return 8
# TODO: actually install something (from spreadsheet maybe)
mtg_mods_list = list()
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()
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 + "'")
else:
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:
if len(mods_added_list) > 0:
print("Added:")
for mod_name in mods_added_list:
print(" - " + mod_name)
print("")
input("press enter to close...")
# cd $TMP_DIR
# git clone https://github.com/tenplus1/mobs_redo.git
# git clone https://github.com/tenplus1/mobs_animal.git
# git clone https://github.com/tenplus1/mobs_monster.git
# git clone https://github.com/tenplus1/mobs_npc.git
# but not:
# git clone https://github.com/poikilos/minetest-minigamer.git
# git clone https://github.com/poikilos/birthstones.git
# Repo.clone_from(git_url, repo_dir)
echo0("")
# cd $TMP_DIR
# git clone https://github.com/tenplus1/mobs_redo.git
# git clone https://github.com/tenplus1/mobs_animal.git
# git clone https://github.com/tenplus1/mobs_monster.git
# git clone https://github.com/tenplus1/mobs_npc.git
# but not:
# git clone https://github.com/poikilos/minetest-minigamer.git
# 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())

160
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
)
# 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
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,
)
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,13 +143,63 @@ 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
q = Queue()
Thread(target=reader, args=[process.stdout, q]).start()
Thread(target=reader, args=[process.stderr, q]).start()
try:
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()
try:
for _ in range(2):
for source, line in iter(q.get, None):
# print "%s: %s" % (source, line),
@ -181,15 +207,15 @@ 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:
except KeyboardInterrupt:
print("[ mtsenliven.py ] " + key_exit_msg)
pass
exit(0)
while True:
return 0
'''
while True:
try:
# can deadlock on high volume--use communicate instead
# as per https://docs.python.org/2/library/subprocess.html
@ -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()
# 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.
)

151
uninstall-minetestserver-git.py

@ -1,51 +1,54 @@
#!/usr/bin/env python3
import os
import sys
import platform
CMD_REM = "#"
CMD_RM = "rm "
CMD_RMDIR = "rmdir "
if platform.system() == "Windows":
def main():
CMD_REM = "#"
CMD_RM = "rm "
CMD_RMDIR = "rmdir "
if platform.system() == "Windows":
CMD_REM = "REM "
CMD_RM = "del "
CMD_RMDIR = "rd "
# profile_path = None
# if 'HOME' in os.environ:
# profile_path = os.environ['HOME']
# elif 'USERPROFILE' in os.environ:
# profile_path = os.environ['USERPROFILE']
# downloads_path = os.path.join(profile_path, "Downloads")
# repo_path = os.path.join(downloads_path, "minetest")
# if not os.path.isdir(repo_path):
# repo_path = os.path.join(profile_path, "minetest")
# if not os.path.isdir(repo_path):
# print("ERROR: Nothing done since there is no minetest sourcecode"
# " folder in " + downloads_path
# + " (nor " + profile_path + ")")
# exit(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):
# print("ERROR: nothing done since there is no " +
# install_manifest_name + " in '" + repo_path +
# "'. The file would only be present if you " +
# "installed minetest from sourcecode" +
# "(otherwise this uninstaller is not for you).")
# exit(2)
if not os.path.isfile(install_manifest_name):
# profile_path = None
# if 'HOME' in os.environ:
# profile_path = os.environ['HOME']
# elif 'USERPROFILE' in os.environ:
# profile_path = os.environ['USERPROFILE']
# downloads_path = os.path.join(profile_path, "Downloads")
# repo_path = os.path.join(downloads_path, "minetest")
# if not os.path.isdir(repo_path):
# repo_path = os.path.join(profile_path, "minetest")
# if not os.path.isdir(repo_path):
# print("ERROR: Nothing done since there is no minetest sourcecode"
# " folder in " + downloads_path
# + " (nor " + profile_path + ")")
# 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):
# print("ERROR: nothing done since there is no " +
# install_manifest_name + " in '" + repo_path +
# "'. The file would only be present if you " +
# "installed minetest from sourcecode" +
# "(otherwise this uninstaller is not for you).")
# 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)
directories = []
print("Removing files...")
f_removed_count = 0
f_skipped_count = 0
f_failed_count = 0
retry_lines = []
with open(install_manifest_name, 'r') as ins:
return 2
directories = []
print("Removing files...")
f_removed_count = 0
f_skipped_count = 0
f_failed_count = 0
retry_lines = []
with open(install_manifest_name, 'r') as ins:
original_line = True
while original_line:
original_line = ins.readline()
@ -68,42 +71,42 @@ with open(install_manifest_name, 'r') as ins:
else:
f_skipped_count += 1
print("Removed " + str(f_removed_count) + " file(s) (skipped not"
print("Removed " + str(f_removed_count) + " file(s) (skipped not"
" present:" + str(f_skipped_count) + "; failed:"
+ str(f_failed_count) + ")")
# NOTE: the next line makes ASCENDING (by len) list of TUPLES (name,len)
sorted_directories = [
# NOTE: the next line makes ASCENDING (by len) list of TUPLES (name,len)
sorted_directories = [
(x, len(x)) for x in sorted(directories, key=len)
]
]
print("Removing folders...")
# NOTE: they are sorted ASCENDING so start at end:
d_removed_count = 0
d_skipped_count = 0
d_failed_count = 0
print("Removing folders...")
# NOTE: they are sorted ASCENDING so start at end:
d_removed_count = 0
d_skipped_count = 0
d_failed_count = 0
# still leaves:
# /usr/local/share/minetest/games/minetest_game/mods
# /usr/local/share/minetest/textures/base/pack/:
# down_arrow.png left_arrow.png right_arrow.png up_arrow.png
# /usr/local/share/minetest/games/minimal/mods
# so:
try_files = ["depends.txt", "down_arrow.png", "left_arrow.png",
# still leaves:
# /usr/local/share/minetest/games/minetest_game/mods
# /usr/local/share/minetest/textures/base/pack/:
# down_arrow.png left_arrow.png right_arrow.png up_arrow.png
# /usr/local/share/minetest/games/minimal/mods
# so:
try_files = ["depends.txt", "down_arrow.png", "left_arrow.png",
"right_arrow.png", "up_arrow.png"]
try_dirs = ["mods"]
try_dirs = ["mods"]
extra_dirs = []
ed_failed_count = 0
ed_removed_count = 0
extra_files = []
e_failed_count = 0
e_removed_count = 0
for i in reversed(range(len(sorted_directories))):
extra_dirs = []
ed_failed_count = 0
ed_removed_count = 0
extra_files = []
e_failed_count = 0
e_removed_count = 0
for i in reversed(range(len(sorted_directories))):
d_path = sorted_directories[i][0]
# for d in reversed(sorted_directories):
# d_path = d[0]
# print("checking "+str(d_path))
# for d in reversed(sorted_directories):
# d_path = d[0]
# print("checking "+str(d_path))
if os.path.isdir(d_path):
try:
for try_name in try_files:
@ -143,20 +146,21 @@ for i in reversed(range(len(sorted_directories))):
d_removed_count += 1
else:
d_skipped_count += 1
print("Removed " + str(d_removed_count) + " folder(s) (skipped not"
print("Removed " + str(d_removed_count) + " folder(s) (skipped not"
" present:" + str(d_skipped_count) + "; failed:"
+ str(d_failed_count) + ")")
if e_failed_count > 0:
if e_failed_count > 0:
print("(failed to remove " + e_failed_count + " known extra file(s)"
" (will be shown under FAILURES below)")
if ed_failed_count > 0:
if ed_failed_count > 0:
print("(failed to remove " + ed_failed_count + " known extra"
" folder(s) (will be shown under FAILURES below)")
print("Removed " + str(d_removed_count) + " folder(s) (skipped not"
print("Removed " + str(d_removed_count) + " folder(s) (skipped not"
" present:" +
str(d_skipped_count) + "; failed:" + str(d_failed_count) + ")")
if f_failed_count+d_failed_count+ed_failed_count <= 0:
code = 0
if f_failed_count+d_failed_count+ed_failed_count <= 0:
print("")
if f_removed_count+d_removed_count <= 0:
print("Nothing to do (minetest+minetestserver has 0 known files"
@ -165,7 +169,7 @@ if f_failed_count+d_failed_count+ed_failed_count <= 0:
else:
print("OK [finished uninstalling all installed files]")
print("")
else:
else:
print("")
print("")
print(CMD_REM+"FAILURES:")
@ -177,7 +181,14 @@ else:
"If any more remain, you may have to remove them manually.")
print("")
print("")
if not ins.closed:
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())

41
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 + "+"
@ -101,7 +102,7 @@ if __name__ == "__main__":
elif prev_arg == "--browser":
browserPath = arg
elif prev_arg == "page":
page_param="&page=2"
page_param = "&page=2"
prev_arg = None
else:
if arg == "--closed":
@ -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())

109
utilities/extra/uninstall.py

@ -1,70 +1,73 @@
#!/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
rem_cmd = "#"
rm_cmd = "rm "
rmdir_cmd = "rmdir "
if platform.system() == "Windows":
def main():
rem_cmd = "#"
rm_cmd = "rm "
rmdir_cmd = "rmdir "
if platform.system() == "Windows":
rm_cmd = "DEL "
rmdir_cmd = "RD "
rem_cmd = "REM "
profile_path1 = os.environ.get('HOME')
profile_path = profile_path1
profile_path2 = os.environ.get('USERPROFILE')
if profile_path2 is not None:
profile_path1 = os.environ.get('HOME')
profile_path = profile_path1
profile_path2 = os.environ.get('USERPROFILE')
if profile_path2 is not None:
profile_path = profile_path2
if profile_path1 is not None:
print(rem_cmd + "WARNING: HOME is present, but USERPROFILE '"
+ profile_path + "' is being used.")
else:
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)
mnf_name = "install_manifest.txt"
mnf_path = os.path.join(profile_path, mnf_name)
unsorted_list = []
unsorted_list = []
if not os.path.isfile(mnf_path):
doDie(rem_cmd + "Uninstall cannot continue since '" + mnf_path
+ "' is missing.")
if not os.path.isfile(mnf_path):
return show_error(rem_cmd + "Uninstall cannot continue since '"
+ mnf_path + "' is missing.")
with open(mnf_path) as fp:
with open(mnf_path) as fp:
for cnt, line_original in enumerate(fp):
# print("Line {}: {}".format(cnt, line))
line = line_original.strip()
if len(line) > 0:
unsorted_list.append(line)
if len(unsorted_list) < 1:
doDie(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
sorted_list = sorted(unsorted_list, key=len, reverse=True)
# reverse: descending
# or (also reverse):
# the_list.sort(key=lambda item: (-len(item), item))
print(rem_cmd + "Uninstalling...")
not_removed_files = []
not_removed_dirs = []
does_not_exist = []
file_count = 0
dir_count = 0
for path in sorted_list:
if len(unsorted_list) < 1:
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
sorted_list = sorted(unsorted_list, key=len, reverse=True)
# reverse: descending
# or (also reverse):
# the_list.sort(key=lambda item: (-len(item), item))
print(rem_cmd + "Uninstalling...")
not_removed_files = []
not_removed_dirs = []
does_not_exist = []
file_count = 0
dir_count = 0
for path in sorted_list:
if os.path.isfile(path):
if path[0:1] == ".":
print(rm_cmd + "\"" + path + "\"")
@ -88,17 +91,18 @@ for path in sorted_list:
else:
does_not_exist.append(path)
if len(does_not_exist) > 0:
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] + "'.")
show_dot_warning = True
print(rem_cmd + "Uninstall is complete.")
print(rem_cmd + "- files: " + str(file_count))
print(rem_cmd + "- directories: " + str(dir_count))
print(rem_cmd + "- missing: " + len(does_not_exist))
if (len(not_removed_files) + len(not_removed_dirs)) > 0:
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.")
print(rem_cmd + "- files: " + str(file_count))
print(rem_cmd + "- directories: " + str(dir_count))
print(rem_cmd + "- missing: " + len(does_not_exist))
if (len(not_removed_files) + len(not_removed_dirs)) > 0:
for path in not_removed_files:
if path[0:1] == ".":
if show_dot_warning:
@ -113,5 +117,10 @@ if (len(not_removed_files) + len(not_removed_dirs)) > 0:
print(" " + rem_cmd + "- directories: "
+ str(not_removed_dir_count))
print("")
print("")
print("")
print("")
return 0
if __name__ == "__main__":
sys.exit(main())

125
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,45 +44,47 @@ def usage():
print("")
licSrc = "example_license.txt"
licDestName = "LICENSE.txt"
licDesc = "MIT License"
if not os.path.isfile(licSrc):
def main():
licSrc = "example_license.txt"
licDestName = "LICENSE.txt"
licDesc = "MIT License"
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
fromName = None
toName = None
extraArgCount = 0
enableFill = False
options = []
for i in range(1, len(sys.argv)):
toMod = None
fromName = None
toName = None
extraArgCount = 0
enableFill = False
options = []
for i in range(1, len(sys.argv)):
if sys.argv[i] == "--fill":
extraArgCount += 1
enableFill = True
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):
if (len(options) != 1) and (len(options) != 3):
usage()
exit(1)
thisName = options[0]
if os.path.isdir(thisName):
return 3
thisName = options[0]
if os.path.isdir(thisName):
if not enableFill:
print("")
print("ERROR: A mod named " + thisName + " cannot be ")
print("generated when the directory already exists.")
print("")
exit(1)
else:
return 4
else:
os.mkdir(thisName)
if (len(options) == 3):
if (len(options) == 3):
fromName = options[1]
toName = options[2]
delimI = toName.rfind(":")
@ -90,13 +92,13 @@ 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"
mobAPI = None
if toMod is not None:
mobAPI = None
if toMod is not None:
if not os.path.isfile(os.path.join(thisName, "depends.txt")):
dependsOut = open(os.path.join(thisName, "depends.txt"), 'w')
dependsOut.write(toMod+"\n")
@ -104,17 +106,17 @@ if toMod is not None:
if toMod.find("mob") > -1:
mobAPI = toMod
if not os.path.isfile(os.path.join(thisName, "description.txt")):
if not os.path.isfile(os.path.join(thisName, "description.txt")):
descOut = open(os.path.join(thisName, "description.txt"), 'w')
descOut.write("\n")
descOut.close()
if not os.path.isfile(os.path.join(thisName, "mod.conf")):
if not os.path.isfile(os.path.join(thisName, "mod.conf")):
confOut = open(os.path.join(thisName, "mod.conf"), 'w')
confOut.write("name = "+thisName+"\n")
confOut.close()
if not os.path.isfile(os.path.join(thisName, "readme.md")):
if not os.path.isfile(os.path.join(thisName, "readme.md")):
readmeOut = open(os.path.join(thisName, "readme.md"), 'w')
readmeLine1 = thisName + " Minetest Mod"
readmeOut.write(readmeLine1+"\n")
@ -125,19 +127,19 @@ if not os.path.isfile(os.path.join(thisName, "readme.md")):
readmeOut.write("See " + licDestName + "\n")
readmeOut.close()
licDest = os.path.join(thisName, licDestName)
if not os.path.isfile(licDest):
licDest = os.path.join(thisName, licDestName)
if not os.path.isfile(licDest):
shutil.copyfile(licSrc, licDest)
luaOut = None
if not os.path.isfile(os.path.join(thisName, "init.lua")):
luaOut = None
if not os.path.isfile(os.path.join(thisName, "init.lua")):
luaOut = open(os.path.join(thisName, "init.lua"), 'w')
# luaOut.write("#!/usr/bin/env lua\n")
luaOut.write("-- " + sys.argv[0] + " (EnlivenMinetest) generated\n")
luaOut.write("-- the original version of this file.\n")
fromMod = None # not required
step0 = ""
fromMod = None # not required
step0 = ""
if (len(options) == 3):
if (len(options) == 3):
delimI = fromName.find(":")
if delimI > -1:
fromMod = fromName[:delimI]
@ -159,31 +161,31 @@ if (len(options) == 3):
+ fromName + '", "' + toName + '")' + "\n")
luaOut.write(apiLinePrefix + 'minetest.register_alias("'
+ fromName + '", "' + toName + '")' + "\n")
else:
else:
step0 = "Add your code init.lua."
if luaOut is not None:
if luaOut is not None:
luaOut.write("\n")
luaOut.close()
print("")
print("")
print(step0)
print("The new mod is the " + thisName + " folder. Remember to:")
ender = "."
if (toMod is not None) and (len(toMod) > 0):
print("")
print("")
print(step0)
print("The new mod is the " + thisName + " folder. Remember to:")
ender = "."
if (toMod is not None) and (len(toMod) > 0):
ender = ""
print("1. Edit depends.txt if your mod requires some mod" + ender)
if (toMod is not None) and (len(toMod) > 0):
print("1. Edit depends.txt if your mod requires some mod" + ender)
if (toMod is not None) and (len(toMod) > 0):
print(" other than '" + toMod + "'.")
print("")
print("2. Edit description.txt to contain a brief description of")
print(" your mod (less than 100 characters).")
print("")
print("3. Edit LICENSE.txt and add the year and the name of all ")
print(" authors, and change the license if desired (The included")
print(" " + licSrc)
print(" should be the " + licDesc + ".")
print(
print("")
print("2. Edit description.txt to contain a brief description of")
print(" your mod (less than 100 characters).")
print("")
print("3. Edit LICENSE.txt and add the year and the name of all ")
print(" authors, and change the license if desired (The included")
print(" " + licSrc)
print(" should be the " + licDesc + ".")
print(
''' The MIT License is good for Minetest mods so they can be used
most widely such as on app stores where replacing the program as per
the GPL v3 is not compliant with mobile OS security--the license of
@ -192,7 +194,12 @@ print(
others to copy your work and claim it as their own especially if they
modify it in any way. They would just be doing what you said they
could do!
'''
)
print("")
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())

31
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
olds = getStrings(oldPath)
news = getStrings(newPath)
for v in olds:
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