From 668dda4e160ebcf72ac6f5beaafd58c5baba7e91 Mon Sep 17 00:00:00 2001 From: poikilos <7557867+poikilos@users.noreply.github.com> Date: Wed, 11 Mar 2020 05:43:49 -0400 Subject: [PATCH] Conform EnlivenMinetest scripts to PEP8 fully. --- deploy.py | 65 ++++---- filever.py | 28 ++-- forwardfilesync.py | 16 +- install-subgametest.py | 140 +++++++++--------- mtsenliven.py | 77 ++++++---- quality.sh | 46 ++++++ uninstall-minetestserver-git.py | 102 +++++++------ .../blender/generate_lua_collisionbox.py | 103 +++++++------ utilities/enissue.py | 19 ++- utilities/extra/uninstall.py | 17 ++- utilities/gimp/plug-ins/remove_halo.md | 7 +- utilities/mtoldtonew.py | 10 +- utilities/showmissing.py | 4 +- 13 files changed, 387 insertions(+), 247 deletions(-) create mode 100755 quality.sh diff --git a/deploy.py b/deploy.py index 7c7ffb0..8e32909 100644 --- a/deploy.py +++ b/deploy.py @@ -2,20 +2,21 @@ import os import shutil from forwardfilesync import * -#import filever +# import filever try: input = raw_input except NameError: pass - + warnings = list() print("") print("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" + @@ -31,20 +32,22 @@ elif "USERPROFILE" in os.environ: profile_path = os.environ["USERPROFILE"] else: try_path = "C:\\Users\\jgustafson" - if not os.path.isdir(try_path): try_path = "C:\\Users\\Owner" - + if not os.path.isdir(try_path): + try_path = "C:\\Users\\Owner" + print("WARNING: no HOME or USERPROFILE found, reverting to '" + - try_path + "'") + try_path + "'") profile_path = try_path -#region user settings +# 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", - "expertmultimedia", "downloads"] ) +installer_deploy_path = path_join_all([profile_path, "ownCloud", "www", + "expertmultimedia", "downloads"]) installer_name = "install-ENLIVEN.exe" -#endregion user settings +# endregion user settings installer_path = os.path.join(installer_deploy_path, installer_name) @@ -52,11 +55,11 @@ if not os.path.isdir(installer_deploy_path): print("#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): os.makedirs(deploy_path) @@ -69,7 +72,7 @@ if not os.path.isdir(minetest_game_path): " " + deploy_path + " so that minetest_game is at: \n\n" + " " + minetest_game_path + "\n\n") exit(1) - + game_path = os.path.join(games_path, "ENLIVEN") # NOTE: remove this case, and instead: copy minetest_game, download ENLIVEN @@ -80,7 +83,7 @@ if not os.path.isdir(game_path): " using the provided 'install' script in the etc/change*" + " folder (run on linux then copy to a Windows machine" + " in " + game_path) - #exit(2) + # exit(2) else: print("game_path: " + game_path) mods_path = os.path.join(game_path, "mods") @@ -92,14 +95,16 @@ 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): + if sub_name[:1] != "." and os.path.isdir(sub_path): mtg_list_out.write(sub_name + "\n") mtg_list_out.close() -#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(game_path, - "minetest.conf.ENLIVEN-server") +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") if not os.path.isfile(server_devel_minetest_conf_path): @@ -108,18 +113,22 @@ else: shutil.copyfile(server_devel_minetest_conf_path, server_minetest_conf_path) -def rm_sub(bad_sub) + +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(["CC-BY-SA 3.0 Unported (fallback license for ENLIVEN assets)" + ".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: diff --git a/filever.py b/filever.py index 1f66ad8..d710a8c 100644 --- a/filever.py +++ b/filever.py @@ -1,8 +1,9 @@ #!/usr/bin/env python -#by Jamie at http://stackoverflow.com/questions/580924/python-windows-file-version-attribute +# by Jamie at try: from win32api import GetFileVersionInfo, LOWORD, HIWORD -except: +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") @@ -10,14 +11,17 @@ except: from win32api import GetFileVersionInfo, LOWORD, HIWORD -def get_version_number (filename): + +def get_version_number(filename): try: - info = GetFileVersionInfo (filename, "\\") + info = GetFileVersionInfo(filename, "\\") ms = info['FileVersionMS'] ls = info['FileVersionLS'] - return HIWORD (ms), LOWORD (ms), HIWORD (ls), LOWORD (ls) - except: - return 0,0,0,0 + return HIWORD(ms), LOWORD(ms), HIWORD(ls), LOWORD(ls) + except IndexError: + # FIXME: test this and find out what exception can occur. + return 0, 0, 0, 0 + if __name__ == '__main__': import os @@ -25,9 +29,9 @@ if __name__ == '__main__': filename = os.environ["COMSPEC"] this_delimiter = "." print(str(filename) + " version:") - print(".".join ([str (i) for i in get_version_number (filename)])) + 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") + "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") diff --git a/forwardfilesync.py b/forwardfilesync.py index f7ea88d..a399068 100644 --- a/forwardfilesync.py +++ b/forwardfilesync.py @@ -3,7 +3,8 @@ import os import shutil copy_dot_hidden_enable = False -# NOT YET IMPEMENTED: delete_if_not_on_src_enable = True +# TODO: NOT YET IMPEMENTED: delete_if_not_on_src_enable = True + def path_join_all(names): result = names[0] @@ -11,8 +12,12 @@ def path_join_all(names): result = os.path.join(result, names[i]) return result -# Creates dst if not present, then copies everything from src to dst recursively + def update_tree(src, dst, level=0): + """ + Creates dst if not present, then copies everything from src to dst + recursively. + """ folder_path = src if level <= 1: print("#" + " "*level + "synchronizing with \"" + dst + "\"") @@ -22,7 +27,10 @@ def update_tree(src, dst, level=0): for sub_name in os.listdir(folder_path): sub_path = os.path.join(folder_path, sub_name) dst_sub_path = os.path.join(dst, sub_name) - if (copy_dot_hidden_enable or sub_name[:1]!=".") and os.path.isdir(sub_path): + allow_copy = True + if not copy_dot_hidden_enable: + allow_copy = not sub_name.startswith(".") + if allow_copy and os.path.isdir(sub_path): update_tree(sub_path, dst_sub_path, level+1) - if (copy_dot_hidden_enable or sub_name[:1]!=".") and os.path.isfile(sub_path): + if allow_copy and os.path.isfile(sub_path): shutil.copyfile(sub_path, dst_sub_path) diff --git a/install-subgametest.py b/install-subgametest.py index c3509a1..beebe41 100755 --- a/install-subgametest.py +++ b/install-subgametest.py @@ -1,46 +1,50 @@ #!/usr/bin/env python -#region options +import os +import shutil +import sys +from forwardfilesync import * + +# region options force_update_mtg_enable = False # first delete subgametest then remake -#endregion options +# endregion options try: input = raw_input except NameError: pass +gitpython_msg = """ +You do not have gitpython installed. +Please run the following commands in terminal +For installing Python in Windows, the most usable option + is CUSTOM install, then change System Path to + 'install to hard drive' + (otherwise first cd C:\\Python27 [or your Python folder], + but if in *nix-like environment first 'su -', and if no + pip, use your software manager to install: + python-pip or python2-pip or python3-pip) +sudo python3 -m pip install --upgrade pip +sudo python3 -m pip install --upgrade pip wheel +sudo python3 -m pip install gitpython +# Possible commands: +# sudo pkg install -y python3-pip python2-pip +# sudo apt install -y python3-pip python2-pip +# sudo pacman -Syuu python2-pip python-pip +# #("Passing two --refresh or -y flags forces pacman to refresh +# #all package lists even if they are considered to be up to +# #date.") + +""" + try: from git import Repo -except: - print("You do not have gitpython installed.\n" - "Please run the following commands in terminal\n" - "For installing Python in Windows, the most usable option\n" - " is CUSTOM install, then change System Path to\n" - " 'install to hard drive'" - " (otherwise first cd C:\Python27 [or your Python folder],\n" - " but if in *nix-like environment first 'su -', and if no\n" - " pip, use your software manager to install:\n" - " python-pip or python2-pip or python3-pip)\n" - "sudo python3 -m pip install --upgrade pip\n" - "sudo python3 -m pip install --upgrade pip wheel\n" - "sudo python3 -m pip install gitpython\n") - #Possible commands: - # pkg install -y python3-pip python2-pip - # apt-get install -y python3-pip python2-pip - # pacman -Syuu python2-pip python-pip - #("Passing two --refresh or -y flags forces pacman to refresh - # all package lists even if they are considered to be up to - # date.") +except ImportError: + print(gitpython_msg) print("") input("press enter to close...") exit(1) - -import os -import shutil -import sys -from forwardfilesync import * - profile_path = None if 'HOME' in os.environ: # if os.name=="windows": profile_path = os.environ['HOME'] @@ -48,7 +52,6 @@ else: profile_path = os.environ['USERPROFILE'] - if not os.path.isdir(profile_path): print("") print("Failed to get existing home path--tried HOME & USERPROFILE") @@ -65,7 +68,7 @@ CONFIG_PATH = os.path.join(configs_path, "EnlivenMinetest") if not os.path.isdir(CONFIG_PATH): os.makedirs(CONFIG_PATH) -#NOTE: not using /var/cache +# 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") @@ -83,20 +86,23 @@ if not os.path.isdir(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 git version is installed: + USR_SHARE_MINETEST = "/usr/local/share/minetest" if os.path.isdir("/usr/share/minetest"): - USR_SHARE_MINETEST="/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. Try installing minetest or compiling from source or editing value of USR_SHARE_MINETEST in this script. Script ended early.") + print("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_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) +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) @@ -111,14 +117,14 @@ if not os.path.isdir(folder_path): 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: - #DOES update minetest_game, but does NOT delete extra mods: + # DOES update minetest_game, but does NOT delete extra mods: update_tree(folder_path, MT_MYGAME_DIR) print("Updated \"" + MT_MYGAME_DIR + "\"...") -except: +except PermissionError: print(str(sys.exc_info())) print("") print("You must run " + __file__ + " as a user that can write to " @@ -128,12 +134,12 @@ except: exit(5) try: - #cd $HOME - #tmp_game_conf_path = os.path.join(profile_path, "game.conf") + # 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: +except PermissionError: print(str(sys.exc_info())) print("") print("You must run " + __file__ + " as a user that can write to " @@ -141,10 +147,10 @@ except: 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")) +# 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")): +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) @@ -152,17 +158,17 @@ else: exit(7) -MT_MYGAME_MODS_PATH = os.path.join(MT_MYGAME_DIR,"mods") +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 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): @@ -177,7 +183,7 @@ 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) - if sub_name[:1]!="." and os.path.isdir(sub_path): + if sub_name[:1] != "." and os.path.isdir(sub_path): mtg_mods_list.append(sub_name) mods_installed_list = list() @@ -187,7 +193,7 @@ 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) - if sub_name[:1]!="." and os.path.isdir(sub_path): + 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) @@ -204,15 +210,13 @@ if len(mods_added_list) > 0: 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) - - +# 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) diff --git a/mtsenliven.py b/mtsenliven.py index 7b2e1a2..18107ea 100644 --- a/mtsenliven.py +++ b/mtsenliven.py @@ -5,21 +5,23 @@ # shuts down properly (makes sure all processes finish) according to # dr4Ke on # https://forum.minetest.net/viewtopic.php?f=11&t=13138&start=50 -key_exit_msg = "SIGINT should shut down server safely...\n" import os from mtanalyze.minetestinfo import * +import subprocess +import signal try: - from Threading import thread as Thread # Python 2 -except: - from threading import Thread # Python 3 + from Threading import thread as Thread # Python 2 +except ImportError: + from threading import Thread # Python 3 # if sys.version[0] == '2': try: - from Queue import Queue # Python 2 -except: - from queue import Queue # Python 3 -import subprocess, signal + from Queue import Queue # Python 2 +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 FCAGameAWorld +# screen -S MinetestServer $mts --gameid ENLIVEN --worldname ... print() print() print() @@ -51,11 +53,14 @@ try: 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: + # bufsize=1 as per jfs on +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 @@ -67,8 +72,8 @@ for flag in msgprefix_flags: non_unique_wraps = [] non_unique_wraps.append( { - "opener":"active block modifiers took ", - "closer":"ms (longer than 200ms)" + "opener": "active block modifiers took ", + "closer": "ms (longer than 200ms)" } ) @@ -77,6 +82,7 @@ unique_flags = [ "joins game" ] + def print_unique_only(output, err_flag=False): output_strip = output.strip() u_prefix = "active block modifiers took " @@ -91,9 +97,13 @@ def print_unique_only(output, err_flag=False): if flag in output: always_show_enable = True if not always_show_enable: + # Look for flags to identify lines such as + # '2018-02-06 21:08:06: WARNING[Server]: Deprecated call + # to get_look_yaw, use get_look_horizontal instead' + # or 2018-02-06 21:08:05: ACTION[Server]: [playereffects] Wrote + # playereffects data into /home/owner/.minetest/worlds/ + # .../playereffects.mt. for flag in msgprefix_flags: - # such as '2018-02-06 21:08:06: WARNING[Server]: Deprecated call to get_look_yaw, use get_look_horizontal instead' - # or 2018-02-06 21:08:05: ACTION[Server]: [playereffects] Wrote playereffects data into /home/owner/.minetest/worlds/FCAGameAWorld/playereffects.mt. f_i = output.find(flag) if f_i >= 0: found_flag = flag @@ -101,7 +111,8 @@ def print_unique_only(output, err_flag=False): if found_flag: sub_msg = output[f_i+len(flag):].strip() for wrap in non_unique_wraps: - if wrap["opener"] in sub_msg and wrap["closer"] in sub_msg: + if (wrap["opener"] in sub_msg and + wrap["closer"] in sub_msg): sub_msg = wrap["opener"] + "..." + wrap["closer"] msg_msg = "similar messages" break @@ -115,12 +126,13 @@ def print_unique_only(output, err_flag=False): print(" [ mtsenliven.py ] " + msg_msg + " will be suppressed") + def process_msg(bstring): output = bstring err_flag = False try: output = bstring.decode("utf-8") - # works on python2 or 3 + # works on python2 or 3 except AttributeError: output = bstring if output[:1] == "<": @@ -132,7 +144,10 @@ def process_msg(bstring): output = output[next_i:] print_unique_only(output, err_flag=err_flag) -# see jfs's answer on https://stackoverflow.com/questions/31833897/python-read-from-subprocess-stdout-and-stderr-separately-while-preserving-order + +# See jfs's answer on def reader(pipe, q): try: try: @@ -145,6 +160,15 @@ def reader(pipe, q): print("[ mtsenliven.py ] " + key_exit_msg) pass + +def decode_safe(b): + try: + s = b.decode() + except UnicodeDecodeError: + s = b.decode('utf-8') + return s + + q = Queue() Thread(target=reader, args=[process.stdout, q]).start() Thread(target=reader, args=[process.stderr, q]).start() @@ -153,14 +177,11 @@ try: for source, line in iter(q.get, None): # print "%s: %s" % (source, line), s = source - l = line - # NOTE: source is a string such as "<_io.BufferedReader name=5>" - try: - l = line.decode("utf-8") - except: - # this should never happen but doesn't matter anyway - pass - process_msg("%s: %s" % (s, l)) + l_s = line + # NOTE: source is a string such as + # "<_io.BufferedReader name=5>" + l_s = decode_safe("utf-8") + process_msg("%s: %s" % (s, l_s)) except KeyboardInterrupt: print("[ mtsenliven.py ] " + key_exit_msg) pass @@ -173,14 +194,14 @@ while True: # as per https://docs.python.org/2/library/subprocess.html out_bytes = process.stdout.readline() # err_bytes = process.stderr.readline() - # (err_bytes == '') and \ + # (err_bytes == '') and \ if (out_bytes == '') and \ (process.poll() is not None): break if out_bytes: process_msg(out_bytes) # if err_bytes: - # process_msg(err_bytes) + # process_msg(err_bytes) rc = process.poll() except KeyboardInterrupt: print("[ mtsenliven.py ] " + key_exit_msg) diff --git a/quality.sh b/quality.sh new file mode 100755 index 0000000..168dd02 --- /dev/null +++ b/quality.sh @@ -0,0 +1,46 @@ +#!/bin/sh +if [ ! -f "`command -v pycodestyle-3`" ]; then + echo "You must install the python3-pycodestyle package before using the quality script." + exit 1 +fi +# target="__init__.py" +# if [ ! -z "$1" ]; then +# target="$1" +# fi +if [ -f err.txt ]; then + rm err.txt +fi +ext="py" +files="" +for var in "$@"; do + files="$files $var" +done +if [ -z "$files" ]; then + files="`find . -iname "*.$ext"`" +fi +if [ -f "`command -v outputinspector`" ]; then + # for f in *.$ext; do + # for f in find . -iname "*.$ext"; do + for f in $files; do + echo "* checking $f..." + pycodestyle-3 "$f" >> err.txt + done + # For one-liner, would use `||` not `&&`, because pycodestyle-3 returns nonzero (error state) if there are any errors + if [ -s "err.txt" ]; then + # -s: exists and >0 bytes + outputinspector + else + echo "No quality issues were detected." + rm err.txt + # echo "Deleted empty 'err.txt'." + fi +else + # for f in *.$ext; do + for f in $files; do + echo "* checking $f..." + pycodestyle-3 "$f" >> err.txt + done + echo + echo "If you install outputinspector, this output can be examined automatically, allowing double-click to skip to line in Geany/Kate" + echo +fi diff --git a/uninstall-minetestserver-git.py b/uninstall-minetestserver-git.py index 992a800..4197b6f 100755 --- a/uninstall-minetestserver-git.py +++ b/uninstall-minetestserver-git.py @@ -8,31 +8,34 @@ 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) + +# 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) +# 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): print("ERROR: nothing done since there is no " + - install_manifest_name + " in the current " + - "directory. You must run: ") + 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) @@ -48,7 +51,7 @@ with open(install_manifest_name, 'r') as ins: original_line = ins.readline() if original_line: line = original_line.rstrip() # remove trailing newline - if len(line)>0: + if len(line) > 0: d_path = os.path.dirname(line) if d_path not in directories: if "minetest" in d_path: @@ -65,25 +68,29 @@ with open(install_manifest_name, 'r') as ins: else: f_skipped_count += 1 -print("Removed " + str(f_removed_count) + " file(s) (skipped not present:" + - str(f_skipped_count) + "; failed:" + str(f_failed_count) + ")") +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 = [(x, len(x)) for x in sorted(directories, key = len)] +# 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: +# NOTE: they are sorted ASCENDING so start at end: d_removed_count = 0 d_skipped_count = 0 d_failed_count = 0 -#still leaves: +# 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_files = ["depends.txt", "down_arrow.png", "left_arrow.png", + "right_arrow.png", "up_arrow.png"] try_dirs = ["mods"] extra_dirs = [] @@ -94,28 +101,31 @@ 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: try_path = os.path.join(d_path, try_name) if os.path.isfile(try_path): extra_files.append(try_path) - print('Removing known extra file: "' + try_path + '"') + print('Removing known extra file: "' + try_path + + '"') try: os.remove(try_path) e_removed_count += 1 except Exception as e: e_failed_count += 1 - retry_lines.append(CMD_RM+'"'+try_path+'"') + retry_lines.append(CMD_RM + '"' + try_path + + '"') print(str(e)) for try_name in try_dirs: try_path = os.path.join(d_path, try_name) if os.path.isdir(try_path): extra_dirs.append(try_path) - print('Removing known extra folder: "' + try_path + '"') + print('Removing known extra folder: "' + try_path + + '"') try: os.rmdir(try_path) ed_removed_count += 1 @@ -133,21 +143,25 @@ 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 present:" + - str(d_skipped_count) + "; failed:" + str(d_failed_count) + ")") +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: - print("(failed to remove " + e_failed_count + " known extra file(s) " + - "(will be shown under FAILURES below)") + print("(failed to remove " + e_failed_count + " known extra file(s)" + " (will be shown under FAILURES below)") 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 present:" + + 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" + " present:" + str(d_skipped_count) + "; failed:" + str(d_failed_count) + ")") 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 on system--you apparently already uninstalled the local version that was installed using 'sudo make install')") + print("Nothing to do (minetest+minetestserver has 0 known files" + " on system--you apparently already uninstalled the local" + " version that was installed using 'sudo make install')") else: print("OK [finished uninstalling all installed files]") print("") diff --git a/utilities/blender/generate_lua_collisionbox.py b/utilities/blender/generate_lua_collisionbox.py index fd52fd6..7d1e3d5 100644 --- a/utilities/blender/generate_lua_collisionbox.py +++ b/utilities/blender/generate_lua_collisionbox.py @@ -22,6 +22,9 @@ How to use: Paste this script into a Blender" Text Editor panel, select an object," press the 'Run Script' button") """ +# from mathutils import Matrix +from mathutils import Vector +# from mathutils import Euler print(""" STARTING generate_lua_collisionbox... @@ -37,17 +40,15 @@ if enable_minetest: hs = (0, 1) # horizontal axis indices v = 2 # vertical axis index # Do NOT swap until end. -#if y_up: -# hs = (0, 2) -# v = 1 +# if y_up: +# hs = (0, 2) +# v = 1 try: import bpy except ImportError: print(__doc__) exit(1) -# from mathutils import Matrix -from mathutils import Vector -# from mathutils import Euler + def calculate_one(): ob1 = None @@ -59,9 +60,9 @@ class MessageBox(bpy.types.Operator): bl_idname = "message.messagebox" bl_label = "" message = bpy.props.StringProperty( - name = "message", - description = "message", - default = '' + name="message", + description="message", + default='' ) def execute(self, context): @@ -79,10 +80,12 @@ class MessageBox(bpy.types.Operator): # col = self.layout.column(align = True) # col.prop(context.scene, "my_string_prop") + bpy.utils.register_class(MessageBox) msgSuffix = "" + def calculate_collisionbox(ob1): global msgSuffix mesh = None @@ -93,25 +96,28 @@ def calculate_collisionbox(ob1): mesh = ob1.data if ob1 is None: msg = "Nothing is selected." - bpy.ops.message.messagebox('INVOKE_DEFAULT', message = msg) + bpy.ops.message.messagebox('INVOKE_DEFAULT', message=msg) elif (mesh is not None) and (not hasattr(mesh, 'vertices')): msg = ("A collision box cannot be calculated for a non-mesh" " object.") - bpy.ops.message.messagebox('INVOKE_DEFAULT', message = msg) + bpy.ops.message.messagebox('INVOKE_DEFAULT', message=msg) else: # extents1 = ob1.dimensions.copy() obj1Loc = ob1.location - # See https://blender.stackexchange.com/questions/8459/get-blender-x-y-z-and-bounding-box-with-script - # bbox_corners = [ob1.matrix_world * Vector(corner) for corner in ob1.bound_box] + # See + # bbox_corners = [(ob1.matrix_world + # * Vector(corner)) for corner in ob1.bound_box] - - # See https://blender.stackexchange.com/questions/6139/how-to-iterate-through-all-vertices-of-an-object-that-contains-multiple-meshes + # See # print("mesh:" + str(mesh)) # print("hasattr(mesh, 'vertices'):" - # + str(hasattr(mesh, 'vertices')))] - mins = [None, None, None] # minimums; in outer scope for checks. - maxes = [None, None, None] # minimums; in outer scope for checks. + # + str(hasattr(mesh, 'vertices')))] + mins = [None, None, None] # minimums; in outer scope for check + maxes = [None, None, None] # minimums; in outer scope for check if mesh is not None: wm = ob1.matrix_world for vert in mesh.vertices: @@ -129,9 +135,10 @@ def calculate_collisionbox(ob1): maxes[i] = coords[i] # print(str(extents1)) # print("--by vertices (raw):") - # print(" collisionbox = {{{:.2f}, {:.2f}, {:.2f}, {:.2f}," - # " {:.2f}, {:.2f}}}".format(mins[0], mins[2], mins[1], - # maxes[0], maxes[2], maxes[1])) + # print(" collisionbox = {{{:.2f}, {:.2f}, {:.2f}," + # " {:.2f}, {:.2f}, {:.2f}}}".format(mins[0], mins[2], + # mins[1], maxes[0], + # maxes[2], maxes[1])) # Use ob1.matrix_world (above) instead of incrementing # ob1.location.x, y, and z @@ -140,28 +147,30 @@ def calculate_collisionbox(ob1): # i = 0 # wm = ob1.matrix_world # for vert in mesh.vertices: - # newName = newNamePrefix + "." + str(i) - # # This matrix multiplication is NOT transitive. - # try: - # loc = wm @ vert.co - # except TypeError: - # loc = wm * vert.co # Blender <2.8 - # isFar = False - # if loc.x == maxes[0] or loc.y == maxes[1] or loc.z == maxes[2]: - # isFar = True - # elif loc.x == mins[0] or loc.y == mins[1] or loc.z == mins[2]: - # isFar = True - # if isFar: - # pass - # # result = bpy.ops.object.add(type='EMPTY', radius=.25, - # # location=loc) - # # NOTE: result is merely {'FINISHED'} - # # print("{:.2f}, {:.2f}, {:.2f}".format(loc.x, loc.y, - # # loc.z)) + # newName = newNamePrefix + "." + str(i) + # # This matrix multiplication is NOT transitive. + # try: + # loc = wm @ vert.co + # except TypeError: + # loc = wm * vert.co # Blender <2.8 + # isFar = False + # if (loc.x == maxes[0] or loc.y == maxes[1] or + # loc.z == maxes[2]): + # isFar = True + # elif (loc.x == mins[0] or loc.y == mins[1] or + # loc.z == mins[2]): + # isFar = True + # if isFar: + # pass + # # result = bpy.ops.object.add(type='EMPTY', radius=.25, + # # location=loc) + # # NOTE: result is merely {'FINISHED'} + # # print("{:.2f}, {:.2f}, {:.2f}".format(loc.x, loc.y, + # # loc.z)) - # bpy.ops.object.add_named(name=newName, type='EMPTY', - # radius=.25, location=loc) - # i += 1 + # bpy.ops.object.add_named(name=newName, type='EMPTY', + # radius=.25, location=loc) + # i += 1 else: extents1 = ob1.scale.copy() print(dir(ob1)) @@ -189,8 +198,10 @@ def calculate_collisionbox(ob1): # maxes[1] -= mins[1] # mins[1] = 0.0 - # print(" collisionbox = {{{:.2f}, {:.2f}, {:.2f}, {:.2f}, {:.2f}," - # " {:.2f}}}".format(mins[0], mins[1], mins[2], maxes[0], maxes[1], maxes[2])) + # print(" collisionbox = {{{:.2f}, {:.2f}, {:.2f}, {:.2f}," + # " {:.2f}, {:.2f}}}".format(mins[0], mins[1], mins[2], + # maxes[0], maxes[1], + # maxes[2])) sizes = [None, None, None] centers = [None, None, None] for i in range(3): @@ -266,12 +277,12 @@ def calculate_collisionbox(ob1): bpy.context.window_manager.clipboard = msg + msgSuffix msg += " --copied to clipboard" # if enable_minetest: - # msg += " -- *10" + # msg += " -- *10" print(msg) bpy.ops.message.messagebox('INVOKE_DEFAULT', message=msg) + # Unregistering before user clicks the MessageBox will crash Blender! # bpy.utils.unregister_class(MessageBox) - calculate_one() diff --git a/utilities/enissue.py b/utilities/enissue.py index f04611b..4bf4e75 100755 --- a/utilities/enissue.py +++ b/utilities/enissue.py @@ -8,7 +8,7 @@ from datetime import datetime, timedelta try: import urllib.request request = urllib.request -except: +except ImportError: # python2 python_mr = 2 import urllib2 as urllib @@ -25,6 +25,7 @@ except ImportError: import urllib + def decode_safe(b): try: s = b.decode() @@ -32,6 +33,7 @@ def decode_safe(b): s = b.decode('utf-8') return s + cmd = None # me = sys.argv[0] me = os.path.basename(__file__) @@ -62,6 +64,7 @@ cmds = { } match_all_labels = [] + def usage(): print("") print("Commands:") @@ -78,6 +81,7 @@ def usage(): print("") print("") + page = None prev_arg = None match_number = None @@ -105,7 +109,7 @@ for i in range(1, len(sys.argv)): cmd = arg else: if arg != "page": - print("* adding criteria: {}".format(arg)) + # print("* adding criteria: {}".format(arg)) cmd = "list" match_all_labels.append(arg) prev_arg = arg @@ -150,6 +154,8 @@ issues_url = repo_url + "/issues" labels_url = repo_url + "/labels" page_size = 30 # The GitHub API only lists 30 issues per page. p = "@ " + + def get_issues(): query_s = issues_url c_issues_name_fmt = "issues_page={}{}.json" @@ -173,7 +179,7 @@ def get_issues(): print(p+"Loading cache: \"{}\"".format(c_issues_path)) # print(p+"Cache time limit: {}".format(max_cache_delta) print(p+"Cache expires: {}".format(filetime - + max_cache_delta)) + + max_cache_delta)) with open(c_issues_path) as json_file: results = json.load(json_file) # print(p+"The cache file has" @@ -213,6 +219,7 @@ def get_issues(): results = json.loads(response_s) return results + # TODO: get labels another way, and make this conditional: # if cmd == "list": issues = get_issues() @@ -247,7 +254,7 @@ for issue in issues: if label_s not in labels: labels.append(label_s) else: - raise ValueError("The url '{}' does not start with" + raise ValueError(p+"ERROR: The url '{}' does not start with" " '{}'".format(label["url"], labels_url)) if len(match_all_labels) > 0: this_issue_match_count = 0 @@ -255,7 +262,7 @@ for issue in issues: if try_label in this_issue_labels_lower: this_issue_match_count += 1 # else: - # print("#{} is not a match ({} is not in" + # print(p+"{} is not a match ({} is not in" # " {})".format(issue["number"], try_label, # this_issue_labels_lower)) if this_issue_match_count == len(match_all_labels): @@ -350,6 +357,7 @@ def show_issue(issue): print("") return True + if matching_issue is not None: show_issue(matching_issue) @@ -407,4 +415,3 @@ elif cmd == "list": print(" ./" + me) print("followed by a number.") print("") - diff --git a/utilities/extra/uninstall.py b/utilities/extra/uninstall.py index f45e932..c370eb6 100644 --- a/utilities/extra/uninstall.py +++ b/utilities/extra/uninstall.py @@ -2,6 +2,7 @@ import os import platform + def doDie(msg, error_code=1): print() print(msg) @@ -9,6 +10,7 @@ def doDie(msg, error_code=1): print() exit(error_code) + rem_cmd = "#" rm_cmd = "rm " rmdir_cmd = "rmdir " @@ -71,7 +73,7 @@ for path in sorted_list: try: os.remove(path) file_count += 1 - except: + except PermissionError: not_removed_files.append(path) elif os.path.isdir(path): if path[0:1] == ".": @@ -81,7 +83,7 @@ for path in sorted_list: try: os.rmdir(path) dir_count += 1 - except: + except PermissionError: not_removed_dirs.append(path) else: does_not_exist.append(path) @@ -100,15 +102,16 @@ if (len(not_removed_files) + len(not_removed_dirs)) > 0: for path in not_removed_files: if path[0:1] == ".": if show_dot_warning: - print(rem_cmd + "Paths starting with '.' are not yet implemented." + print(rem_cmd + "Paths starting with '.' are not yet" + " implemented.") show_dot_warning = False print(rm_cmd + "\"" + path + "\"") for path in not_removed_dirs: print(rmdir_cmd + "\"" + path + "\"") print(rem_cmd + "Deleting items above FAILED:") print(" " + rem_cmd + "- files: " + str(not_removed_file_count)) - print(" " + rem_cmd + "- directories: " + str(not_removed_dir_count)) - + print(" " + rem_cmd + "- directories: " + + str(not_removed_dir_count)) -print() -print() +print("") +print("") diff --git a/utilities/gimp/plug-ins/remove_halo.md b/utilities/gimp/plug-ins/remove_halo.md index 552e34d..f8ae171 100644 --- a/utilities/gimp/plug-ins/remove_halo.md +++ b/utilities/gimp/plug-ins/remove_halo.md @@ -1,10 +1,12 @@ # Channel Tools +The remove halo feature is now at: https://github.com/poikilos/channel_tools.git ## [git] - 2020-02-19 ### Removed -- This may have worked after additoinal fixes. +- This may have worked after additional fixes. I thought this was the + fault but it apparently was not. - https://www.youtube.com/watch?v=YHXX3KuB23Q (outdated) - https://jacksonbates.wordpress.com/2015/09/14/python-fu-6-accepting-user-input/ ```python @@ -26,7 +28,8 @@ register( ) ``` -- This may be deprecated, even though it matches the docs. +- This kind of register call may be deprecated, even though it matches + the docs. - https://www.gimp.org/docs/python/index.html ```python register( diff --git a/utilities/mtoldtonew.py b/utilities/mtoldtonew.py index e606e2c..b4436b4 100644 --- a/utilities/mtoldtonew.py +++ b/utilities/mtoldtonew.py @@ -6,7 +6,7 @@ import sys mtdeltas_csv = "mtoldtonew.csv" if not os.path.isfile(mtdeltas_csv): print("ERROR: missing " + mtdeltas_csv) - #exit(1) + # exit(1) files = [] @@ -32,25 +32,31 @@ Examples: ''' usageStr += "edit '%s' as needed (old name in column 1, new name in 2)" + def usage(): print(usageStr) + mtdeltas = {} + def stripQuotes(s, quotechar='"'): if (len(s) >= 2) and (s[0] == quotechar) and (s[-1] == quotechar): s = s[1:-1] return s + def quoted(str1, quotechar='"'): return(quotechar + str1 + quotechar) + def replaceQuoted(str1, deltas, quotechar='"'): ret = str1 for k, v in deltas.items(): ret = ret.replace(quoted(k, quotechar), quoted(v, quotechar)) return ret + with open(mtdeltas_csv) as csvfile: ins = csv.reader(csvfile, delimiter=',', quotechar='"') lineI = 0 @@ -69,6 +75,7 @@ with open(mtdeltas_csv) as csvfile: print("Skipped empty destination for '" + oldStr + " on line " + str(lineI) + " in " + csvfile) + def oldToNew(path, quotechar='"'): newName = path.replace("old", "new") if newName == path: @@ -84,6 +91,7 @@ def oldToNew(path, quotechar='"'): outs.write(replaceQuoted(oldLine, mtdeltas) + "\n") print("* wrote '%s'" % newName) + if __name__ == "__main__": for i in range(1, len(sys.argv)): try_path = sys.argv[i] diff --git a/utilities/showmissing.py b/utilities/showmissing.py index 1f0f241..a75dde2 100755 --- a/utilities/showmissing.py +++ b/utilities/showmissing.py @@ -1,6 +1,7 @@ #!/usr/bin/env python import sys + def usage(): print("") print(sys.argv[0] + " ") @@ -9,6 +10,7 @@ def usage(): print("") print("") + argCount = len(sys.argv) - 1 if argCount < 2: @@ -19,7 +21,6 @@ oldPath = sys.argv[1] newPath = sys.argv[2] - def getStrings(path, delimiter='"', unique=True): ret = [] got = "" @@ -44,6 +45,7 @@ def getStrings(path, delimiter='"', unique=True): i += 1 return ret + olds = getStrings(oldPath) news = getStrings(newPath) for v in olds: