Skip to content

Commit

Permalink
Dr16issues, some progress (#63)
Browse files Browse the repository at this point in the history
* entered getUnimacroGrammarsDirectory, and a lot of tidying up in natlinkstatus.py
* the buttonclicktest.py shows the bug when natlink.playEvents is called.
  • Loading branch information
quintijn authored Feb 4, 2024
1 parent 0e07c86 commit 0e6e95f
Show file tree
Hide file tree
Showing 4 changed files with 182 additions and 152 deletions.
157 changes: 41 additions & 116 deletions src/natlinkcore/configure/natlinkconfigfunctions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# Quintijn Hoogenboom, January 2008 (...), August 2022
#

#pylint:disable=C0302, W0702, R0904, C0116, W0613, R0914, R0912, C0415, W0611
#pylint:disable=C0302, W0702, R0904, C0116, W0613, R0914, R0912
"""With the functions in this module Natlink can be configured.
These functions are called in different ways:
Expand Down Expand Up @@ -57,13 +57,6 @@ def get_check_config_locations(self):
"""
config_path, fallback_path = loader.config_locations()

if isfile(config_path):
with open(config_path, 'r', encoding='utf-8') as fp:
text = fp.read().strip()
if not text:
print(f'empty natlink.ini file: "{config_path}",\n\tremove, and go back to default')
os.remove(config_path)

if not isfile(config_path):
config_dir = Path(config_path).parent
if not config_dir.is_dir():
Expand All @@ -75,43 +68,7 @@ def check_config(self):
"""check config_file for possibly unwanted settings
"""
self.config_remove(section='directories', option='default_config')
keys = self.config_get('directories')

## check vocola:
if 'vocoladirectory' in keys and 'vocolagrammarsdirectory' in keys:
try:
import vocola2
except ImportError:
# vocola has been gone, remove:
self.disable_vocola()
self.config_remove('vocola', 'vocolauserdirectory')
else:
## just to be sure:
self.config_remove('vocola', 'vocolauserdirectory')
self.config_remove('directories', 'vocoladirectory')
self.config_remove('directories', 'vocolagrammarsdirectory')

if 'unimacrodirectory' in keys and 'unimacrogrammarsdirectory' in keys:
try:
import unimacro
except ImportError:
# unimacro has been gone, remove:
self.disable_unimacro()
self.config_remove('unimacro', 'unimacrouserdirectory')
else:
## just to be sure:
self.config_remove('unimacro', 'unimacrouserdirectory')
self.config_remove('directories', 'unimacrodirectory')
self.config_remove('directories', 'unimacrogrammarsdirectory')


if 'dragonflyuserdirectory' in keys:
try:
import dragonfly
except ImportError:
# dragonfly has been gone, remove:
self.disable_dragonfly()

def getConfig(self):
"""return the config instance
"""
Expand All @@ -122,16 +79,14 @@ def getConfig(self):
self.config_encoding = rwfile.encoding
return _config

def config_get(self, section, option=None):
"""get the section keys or a setting from the natlink ini file
def config_get(self, section, option):
"""set a setting into the natlink ini file
"""
if option:
try:
return self.Config.get(section, option)
except (configparser.NoSectionError, configparser.NoOptionError):
return None
return self.Config.options(section)
try:
return self.Config.get(section, option)
except (configparser.NoSectionError, configparser.NoOptionError):
return None

def config_set(self, section, option, value):
"""set a setting into an inifile (possibly other than natlink.ini)
Expand All @@ -152,7 +107,7 @@ def config_set(self, section, option, value):
value = str(value)
self.Config.set(section, option, str(value))
self.config_write()
self.status.__init__()
self.status = natlinkstatus.NatlinkStatus()
return True

def config_write(self):
Expand Down Expand Up @@ -180,7 +135,7 @@ def config_remove(self, section, option):
if section not in ['directories', 'settings', 'userenglish-directories', 'userspanish-directories']:
self.Config.remove_section(section)
self.config_write()
self.status.__init__()
self.status = natlinkstatus.NatlinkStatus()

# def setUserDirectory(self, arg):
# self.setDirectory('UserDirectory', arg)
Expand All @@ -200,7 +155,7 @@ def setDirectory(self, option, dir_path, section=None):
print('No valid directory specified')
return

dir_path = dir_path.strip().replace('/', '\\')
dir_path = dir_path.strip()
directory = createIfNotThere(dir_path, level_up=1)
if not (directory and Path(directory).is_dir()):
if directory is False:
Expand Down Expand Up @@ -284,26 +239,32 @@ def clearFile(self, option, section):

def setLogging(self, logginglevel):
"""Sets the natlink logging output
logginglevel (str) -- CRITICAL, FATAL, ERROR, WARNING, INFO, DEBUG
This one is used in the natlinkconfig_gui
logginglevel (str) -- Critical, Fatal, Error, Warning, Info, Debug
"""
key = 'log_level'
section = 'settings'
value = logginglevel.upper()
old_value = self.config_get(section, key)
# Config.py handles log level str upper formatting from ini
value = logginglevel.title()
old_value = self.config_get('settings', "log_level")
if old_value == value:
print(f'setLogging, setting is already "{old_value}"')
return True
if value in ["CRITICAL", "FATAL", "ERROR", "WARNING", "INFO", "DEBUG"]:
if value in ["Critical", "Fatal", "Error", "Warning", "Info", "Debug"]:
print(f'setLogging, setting logging to: "{value}"')
self.config_set(section, key, value)
self.config_set('settings', "log_level", value)
if old_value is not None:
self.config_set('previous settings', key, old_value)
self.config_set('previous settings', "log_level", old_value)
return True
print(f'Invalid value for setLogging: "{value}"')
return False

def disableDebugOutput(self):
"""disables the Natlink debug output
"""
key = 'log_level'
# section = 'settings'
old_value = self.config_get('previous settings', key)
if old_value:
self.config_set('settings', key, old_value)
self.config_set('settings', key, 'INFO')

def enable_unimacro(self, arg):
unimacro_user_dir = self.status.getUnimacroUserDirectory()
if unimacro_user_dir and isdir(unimacro_user_dir):
Expand All @@ -313,7 +274,7 @@ def enable_unimacro(self, arg):

uni_dir = self.status.getUnimacroDirectory()
if uni_dir:
print('==== install and/or update unimacro====\n')
print('==== instal and/or update unimacro====\n')
try:
subprocess.check_call([sys.executable, "-m", "pip", "install", "--upgrade", "unimacro"])
except subprocess.CalledProcessError:
Expand Down Expand Up @@ -359,7 +320,7 @@ def enable_vocola(self, arg):

voc_dir = self.status.getVocolaDirectory()
if voc_dir:
print('==== install and/or update vocola2====\n')
print('==== instal and/or update vocola2====\n')
try:
subprocess.check_call([sys.executable, "-m", "pip", "install", "--upgrade", "vocola2"])
except subprocess.CalledProcessError:
Expand Down Expand Up @@ -394,41 +355,6 @@ def disable_vocola(self, arg=None):
self.config_remove('directories', 'vocola')
self.config_remove('directories', 'vocoladirectory') #could still be there...

def enable_dragonfly(self, arg):
"""enable dragonfly, by setting arg (prompting if False), and other settings
"""
key = 'dragonflyuserdirectory'
dragonfly_user_dir = self.status.getDragonflyUserDirectory()
if dragonfly_user_dir and isdir(dragonfly_user_dir):
print(f'dragonflyUserDirectory is already defined: "{dragonfly_user_dir}"\n\tto change, first clear (option "D") and then set again')
print('\nWhen you want to upgrade dragonfly (dragonfly2), also first clear ("D"), then choose this option ("d") again.\n')
return

dfl_prev_dir = self.config_get('previous settings', key)
if dfl_prev_dir:

print('==== install and/or update dragonfly2====\n')
try:
subprocess.check_call([sys.executable, "-m", "pip", "install", "--upgrade", "dragonfly2"])
except subprocess.CalledProcessError:
print('====\ncould not pip install --upgrade dragonfly2\n====\n')
return
else:
try:
subprocess.check_call([sys.executable, "-m", "pip", "install", "dragonfly2"])
except subprocess.CalledProcessError:
print('====\ncould not pip install dragonfly2\n====\n')
return
self.status.refresh() # refresh status

self.setDirectory(key, arg)

def disable_dragonfly(self, arg=None):
"""disable dragonfly, arg not needed/used
"""
key = 'dragonflyuserdirectory'
self.clearDirectory(key)

def copyUnimacroIncludeFile(self):
"""copy Unimacro include file into Vocola user directory
Expand Down Expand Up @@ -525,20 +451,20 @@ def includeUnimacroVchLineInVocolaFiles(self, subDirectory=None):
changed = 0
correct = 0
Output = []
rwfile = readwritefile.ReadWriteFile()
lines = rwfile.readAnything(F).split('\n')
for line in lines:
for line in open(F, 'r'):
if line.strip() == includeLine.strip():
correct = 1
if line.strip() in oldIncludeLines:
changed = 1
continue
Output.append(line)
for oldLine in oldIncludeLines:
if line.strip() == oldLine:
changed = 1
break
else:
Output.append(line)
if changed or not correct:
# changes were made:
if not correct:
Output.insert(0, includeLine)
rwfile.writeAnything(F, Output)
open(F, 'w').write(''.join(Output))
nFiles += 1
elif len(f) == 3 and os.path.isdir(F):
# subdirectory, recursive
Expand Down Expand Up @@ -584,10 +510,7 @@ def removeUnimacroVchLineInVocolaFiles(self, subDirectory=None):
if f.endswith(".vcl"):
changed = 0
Output = []
rwfile = readwritefile.ReadWriteFile()
lines = rwfile.readAnything(F).split('\n')

for line in lines:
for line in open(F, 'r'):
for oldLine in oldIncludeLines:
if line.strip() == oldLine:
changed = 1
Expand All @@ -596,10 +519,11 @@ def removeUnimacroVchLineInVocolaFiles(self, subDirectory=None):
Output.append(line)
if changed:
# had break, so changes were made:
rwfile.writeAnything(F, Output)
open(F, 'w').write(''.join(Output))
nFiles += 1
elif len(f) == 3 and os.path.isdir(F):
self.removeUnimacroVchLineInVocolaFiles(F)
self.disableVocolaTakesUnimacroActions()
mess = f'removed include lines from {nFiles} files in {toFolder}'
print(mess)

Expand Down Expand Up @@ -749,3 +673,4 @@ def createIfNotThere(path_name, level_up=None):
_home_path = _nc.home_path
_natlinkconfig_path = _nc.natlinkconfig_path
print(f'natlinkconfig_path: {_natlinkconfig_path}')
pass
86 changes: 86 additions & 0 deletions src/natlinkcore/natlinkpydebug.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
"""
code to help with debugging including:
- enable python debuggers to attach.
currently on DAP debuggers are supported.
https://microsoft.github.io/debug-adapter-protocol/
There are several, Microsoft Visual Studio COde is known to work.
There are several, Microsoft Visual Studio COde is known to work.
If you know how to add support for another debugger please add it.
Written by Doug Ransom, 2021
"""
#pylint:disable=C0116, W0703
import os
import debugpy
from natlinkcore import natlinkstatus

__status = natlinkstatus.NatlinkStatus()
__natLinkPythonDebugPortEnviornmentVar= "NatlinkPyDebugPort"
__natLinkPythonDebugOnStartupVar="NatlinkPyDebugStartup"

__pyDefaultPythonExecutor = "python.exe"
__debug_started=False
default_debugpy_port=7474
__debugpy_debug_port=default_debugpy_port
__debugger="not configured"
dap="DAP"

#bring a couple functions from DAP and export from our namespace
dap_is_client_connected=debugpy.is_client_connected
dap_breakpoint = debugpy.breakpoint

def dap_info():
return f"""
Debugger: {__debugger} DAP Port:{__debugpy_debug_port} IsClientConnected: {dap_is_client_connected()} Default DAP Port {default_debugpy_port}
Debug Started:{__debug_started}
"""

def start_dap():
#pylint:disable=W0603
global __debug_started,__debugpy_debug_port,__debugger
if __debug_started:
print(f"DAP already started with debugpy for port {__debugpy_debug_port}")
return
try:

if __natLinkPythonDebugPortEnviornmentVar in os.environ:
natLinkPythonPortStringVal = os.environ[__natLinkPythonDebugPortEnviornmentVar]
__debugpy_debug_port = int(natLinkPythonPortStringVal)
print(f"Starting debugpy on port {natLinkPythonPortStringVal}")

python_exec = __pyDefaultPythonExecutor #for now, only the python in system path can be used for natlink and this module
print(f"Python Executable (required for debugging): '{python_exec}'")
debugpy.configure(python=f"{python_exec}")
debugpy.listen(__debugpy_debug_port)
print(f"debugpy listening on port {__debugpy_debug_port}")
__debug_started = True
__debugger = dap

if __natLinkPythonDebugOnStartupVar in os.environ:
dos_str=os.environ[__natLinkPythonDebugOnStartupVar]
dos=len(dos_str)==1 and dos_str in "YyTt"

if dos:
print(f"Waiting for DAP debugger to attach now as {__natLinkPythonDebugOnStartupVar} is set to {dos_str}")
debugpy.wait_for_client()


except Exception as ee:
print(f"""
Exception {ee} while starting debug. Possible cause is incorrect python executable specified {python_exec}
""" )

def debug_check_on_startup():
#pylint:disable=W0603
global __debug_started,__debugpy_debug_port,__debugger
debug_instructions = f"{__status.getCoreDirectory()}\\debugging python instructions.docx"
print(f"Instructions for attaching a python debugger are in {debug_instructions} ")
if __natLinkPythonDebugPortEnviornmentVar in os.environ:
start_dap()






Loading

0 comments on commit 0e6e95f

Please sign in to comment.