Skip to content

Instantly share code, notes, and snippets.

@caspark
Created February 19, 2020 04:40
Show Gist options
  • Save caspark/04f6c590a4fa7558157a4f0a4fedc7eb to your computer and use it in GitHub Desktop.
Save caspark/04f6c590a4fa7558157a4f0a4fedc7eb to your computer and use it in GitHub Desktop.
Script to reload all natlink grammars
from __future__ import print_function
import datetime
import os
import sys
import traceback
import dragonfly
try:
# Internal NatLink module for reloading grammars.
import natlinkmain
except ImportError:
natlinkmain = None
print('Failed to import natlinkmain - reloading may not work!')
def topy(path):
if path.endswith == ".pyc":
return path[:-1]
return path
def reload_all_grammars():
print('Reloader: starting reload')
start_time = datetime.datetime.now()
# Do not reload anything in these directories or their subdirectories.
dir_reload_blacklist = set(["core"])
macro_dir = "C:\\NatLink\\NatLink\\MacroSystem"
natlink_user_dir = os.path.dirname(os.path.realpath(__file__))
# Unload all grammars if natlinkmain is available.
if natlinkmain:
natlinkmain.unloadEverything()
# Unload all modules in macro_dir except for those in directories on the
# blacklist.
# Consider them in sorted order to try to make things as predictable as possible to ease debugging.
for name, module in sorted(sys.modules.items()):
if module and hasattr(module, "__file__"):
# Some builtin modules only have a name so module is None or
# do not have a __file__ attribute. We skip these.
path = module.__file__
# Convert .pyc paths to .py paths.
path = topy(path)
# Do not unimport modules on the blacklist! This will cause major problems!
if ((path.startswith(macro_dir) or path.startswith(natlink_user_dir)) and
not bool(set(path.split(os.path.sep)) & dir_reload_blacklist)
and path != topy(os.path.abspath(__file__))):
# print("Reloader: removing module '%s' from cache" % name)
# Remove the module from the cache so that it will be reloaded
# the next time # that it is imported. The paths for packages
# end with __init__.pyc so this # takes care of them as well.
del sys.modules[name]
# touch each auto loaded file in natlink user directory in order to make sure that it gets reloaded
for f in os.listdir(natlink_user_dir):
if f.startswith('_') and f.endswith('.py'):
full_name = os.path.join(natlink_user_dir, f)
try:
os.utime(full_name, None)
except Exception:
# file has been deleted since the time we found it
print('failed to touch ' + full_name)
traceback.print_exc()
try:
# Reload the top-level modules in macro_dir if natlinkmain is available.
if natlinkmain:
natlinkmain.findAndLoadFiles()
except Exception as e:
print("Reloader: reloading failed: {}".format(e))
else:
print("Reloader: finished reloading in %s" % (
datetime.datetime.now() - start_time))
def reload_and_show_natlink():
reload_all_grammars()
# activate the messages window
try:
dragonfly.FocusWindow(
title="Messages from Python Macros V15").execute()
except Exception:
traceback.print_exc()
# Note that you do not need to turn mic off and then on after saying this. This
# also unloads all modules and packages in the macro directory so that they will
# be reloaded the next time that they are imported. It even reloads Aenea!
class ReloadGrammarsRule(dragonfly.MappingRule):
mapping = {
'format mainframe': dragonfly.Function(reload_and_show_natlink)
}
grammar = dragonfly.Grammar('reloader')
grammar.add_rule(ReloadGrammarsRule())
grammar.load()
print('Reloader grammar: loaded at ' + str(datetime.datetime.now()))
# Unload function which will be called at unload time.
def unload():
global grammar
if grammar:
grammar.unload()
print('Reloader grammar: unloaded')
grammar = None
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment