Skip to content

Commit

Permalink
Komodoerror (#28)
Browse files Browse the repository at this point in the history
* Vocola_compatibility moved from Unimacro to Dtactions repository
* rename test directory to tests and rename alltests.py
* working on extenvvars.py and testing them
* and comment added in autohotkeyactions.py
* testing mouse actions in unimacroutils.py... work in progress...
* unimacroutils.py set_mouse_position
* move unimacroactions.py to dtactions directly
* move unimacroutils.py to dtactions directory directly
* simplified and improved basic test (tmp_path instead of tmp_path_factory)
* version # now in pyproject.toml

---------

Co-authored-by: Doug Ransom <[email protected]>
  • Loading branch information
quintijn and dougransom authored Nov 23, 2024
1 parent 0c66eb4 commit 38a1ecc
Show file tree
Hide file tree
Showing 46 changed files with 2,652 additions and 248 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,4 @@ cython_debug/
/documentation/.#*
.rst
*.orig
/.merge_file_*
8 changes: 5 additions & 3 deletions natlink_test/requires_natlink/test_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
import pytest

# from dtactions import natlinkclipboard
# from dtactions.unimacro import unimacroactions as actions # old style
from dtactions.unimacro import newactions as actions
from dtactions.unimacro import unimacroutils
# from dtactions import unimacroactions as actions # old style
from dtactions import unimacroactions as actions
from dtactions import unimacroutils

try:
from dtactions.__init__ import getThisDir, checkDirectory
Expand Down Expand Up @@ -47,6 +47,7 @@ def xxx_test_keystroke():
keystroke('{shift+left 11}{ctrl+x}')
time.sleep(0.01)
result = unimacroutils.getClipboard()
#Hello world
assert result == 'Hello world'
#
def test_save_return_clipboard():
Expand All @@ -73,3 +74,4 @@ def test_save_return_clipboard():

if __name__ == "__main__":
pytest.main(['test_actions.py'])
#
2 changes: 1 addition & 1 deletion natlink_test/requires_natlink/unittestClipboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import win32gui
from dtactions import natlinkclipboard
from dtactions import autohotkeyactions as ahk
from dtactions.unimacro import unimacroutils
from dtactions import unimacroutils
from dtactions.sendkeys import sendkeys
try:
from dtactions.__init__ import getThisDir, checkDirectory
Expand Down
7 changes: 6 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ maintainers = [{name = "Quintijn Hoogenboom", email="[email protected]"},
dynamic = ["description"]
requires-python = ">=3.9"
readme = "README.md"
version="1.6.4.dev2"
version="1.6.4.dev3"
dependencies= [
"pywin32 >= 300",
"debugpy",
Expand Down Expand Up @@ -69,3 +69,8 @@ python_files = [
]


[tool.ruff]
include = ["pyproject.toml", "src/**/*.py", "scripts/**/*.py","tests/**/*.py"]

[tool.pyright]
include = ["pyproject.toml", "src/**/*.py", "scripts/**/*.py","tests/**/*.py"]
182 changes: 56 additions & 126 deletions src/dtactions/__init__.py
Original file line number Diff line number Diff line change
@@ -1,162 +1,85 @@
"""dtactions __init__
including utility functions,
- getThisDir, for getting the calling directory of module (in site-packages, also when this is a valid symlink),
- findInSitePackages, supporting getThisDir
- checkDirectory, check existence of directory, with create=True, do create if directory does not exist yet.
Note: -as user, having pipped the package, the scripts run from the site-packages directory,
no editing in source files is meant to be done
-as developer, you need to clone the package, then `build_package` and,
-as developer, you need to clone the package,
after a `pip uninstall dtactions` do: `pip install -e .` from the root of this project.
Start with the following lines near the top of your python file:
You can retrieve the DtactionsDirectory and DtactionsUserDirectory from here:
```
try:
from dtactions.__init__ import getThisDir, checkDirectory
except ModuleNotFoundError:
print(f'Run this module after "build_package" and "flit install --symlink"\n')
raise
thisDir = getThisDir(__file__) # optional: ... , warnings=True)
from dtactions import getDtactionsDirectory, getDtactionsUserDirectory
print(f'dtactions_directory: "{getDtactionsDirectory()}"')
print(f'dtactions_user_directory: "{getDtactionsUserDirectory()}"')
```
Also retrieve the DtactionsDirectory and DtactionsUserDirectory from here:
Or with the "Path" versions:
```
from Dtactionscore.__init__ import getDtactionsDirectory, getDtactionsUserDirectory
print(f'DtactionsDirectory: {getDtactionsDirectory()})
print(f'DtactionsUserDirectory: {getDtactionsUserDirectory()})
from dtactions import getDtactionsPath, getDtactionsUserPath
print(f'dtactions_user_path: "{getDtactionsUserPath()}", (type: "{Type}"')
Type = type(getDtactionsPath())
print(f'dtactions_path: "{getDtactionsPath()}", (type: "{Type}")')
```
NOTE: these two directories can also be obtained via Dtactionsstatus:
```
import natlinkstatus
status = natlinkstatus.DtactionsStatus()
status.getDtactionsDirectory()
status.getDtactionsUserDirectory()
```
"""
import importlib.metadata
__version__ = importlib.metadata.version(__package__) #version set in pyproject.toml now.


##----------------------
import sys
import os
from pathlib import Path, WindowsPath
#
# def get_home_path() -> Path:
# """get home path, can be tweaked by pytest testing
# """
# return WindowsPath.home()

def getDtactionsDirectory():
def getDtactionsDirectory() -> str:
"""return the root directory of dtactions
"""
return getThisDir(__file__)
return str(Path(__file__).parent)

def getDtactionsUserDirectory():
"""get the NatlinkUserDirectory
Here are config files, especially .natlink
By default the users home directory is taken. This directory can be overridden by setting
the environment variable DICTATIONTOOLBOXUSER to an existing directory.
Restart then the calling program
"""
# default dtHome:
dictation_toolbox_user = os.getenv("DICTATIONTOOLBOXUSER")
if dictation_toolbox_user:
dtHome = Path(dictation_toolbox_user)
if not dtHome.is_dir():
dtHome = WindowsPath.home()
print(f'dtactions.getDtactionsUserDirectory: environment variable DICTATIONTOOLBOXUSER does not point to a valid directory: "{dictation_toolbox_user}", take "{dtHome}"')
else:
dtHome = WindowsPath.home()

dtactions_ini_folder = dtHome / ".dtactions"
if not dtactions_ini_folder.is_dir():
dtactions_ini_folder.mkdir() #make it if it doesn't exist
return str(dtactions_ini_folder)

def getThisDir(fileOfModule, warnings=False):
"""get directory of calling module, if possible in site-packages
call at top of module with `getThisDir(__file__)`
If you want to get warnings (each one only once, pass `warnings = True`)
More above and in the explanation of findInSitePackages.
def getDtactionsPath() -> Path:
"""return the root directory of dtactions as Path instance
"""
thisFile = Path(fileOfModule)
thisDir = thisFile.parent
thisDir = findInSitePackages(thisDir, warnings=warnings)
return thisDir
return Path(__file__).parent

def findInSitePackages(directory, warnings):
"""get corresponding directory in site-packages
For users, just having pipped this package, the "directory" is returned, assuming it is in
the site-packages.
For developers, the directory is either
--in a clone from github.
The corresponding directory in site-packages should be a symlink,
otherwise there was no "flit install --symlink" yet.
--a directory in the site-packages. This directory should be a symlink to a cloned dir.
The site-packages directory is returned, but the actual files accessed are in the cloned directory.
To get this "GOOD" situation, you perform the steps as pointed out above (or in the README.md file)
def getDtactionsUserDirectory() -> str:
"""get the UserDirectory for Dtactions
When problems arise, set warnings=True, in the call, preferably when calling getThisDir in the calling module.
"""
dirstr = str(directory)
if dirstr.find('\\src\\') < 0:
if warnings:
warning(f'directory {dirstr} not connected to a github clone directory, changes will not persist across updates...')
return directory

commonpart = dirstr.rsplit('\\src\\', maxsplit=1)[-1]
spDir = Path(sys.prefix, 'Lib', 'site-packages', commonpart)
if spDir.is_dir():
spResolve = spDir.resolve()
if spResolve == spDir:
if warnings:
warning(f'corresponding site-packages directory is not a symlink: {spDir}.\nPlease use "flit install --symlink" when you want to test this package')
elif spResolve == directory:
# print(f'directory is symlink: {spDir} and resolves to {directory} all right')
## return the symbolic link in the site-packages directory, that resolves to directory!!
return spDir
else:
if warnings:
warning(f'directory is symlink: {spDir} but does NOT resolve to {directory}, but to {spResolve}')
else:
if warnings:
warning('findInSitePackages, not a valid directory in site-packages, no "flit install --symlink" yet: {spDir}')
return directory

def checkDirectory(directory, create=None):
"""check existence of directory path
create == False, None (default): raise OSError if directory is not there
This is by default your-home-directory/.dtactions (so decoupled from the Natlink user directory)
You can override this by setting environment variable `DTACTIONS_USERDIR`
to a valid directory of your choice
create == True: create if not existent yet...
raise OSError if something strange happens...
returns None
"""
if not isinstance(directory, Path):
directory = Path(directory)
if directory.is_dir():
return
if create is False:
raise OSError(f'Cannot find directory {directory}, but it should be there.')
if directory.exists():
raise OSError(f'path exists, but is not a directory: {directory}')
directory.mkdir(parents=True)
if directory.is_dir():
print('created directory: {directory}')
else:
raise OSError(f'did not manage to create directory: {directory}')
# default dtHome:
dta_user_dir = os.getenv("DTACTIONS_USERDIR")
if dta_user_dir:
if Path(dta_user_dir).is_dir():
return str(dta_user_dir)
print(f'WARNING, dtactions.getDtactionsUserDirectory: environment variable DTACTIONS_USERDIR does not point to a valid directory: "{dta_user_dir}"')

home_path = WindowsPath.home()

dtactions_ini_path = home_path/".dtactions"
if not dtactions_ini_path.is_dir():
dtactions_ini_path.mkdir() #make it if it doesn't exist
if not dtactions_ini_path.is_dir():
raise IOError(f'dtactions.__init__: dtactions_ini_path cannot be created "{dtactions_ini_path}"' )
return str(dtactions_ini_path)

def getDtactionsUserPath() -> Path:
"""the "Path" version of getDtactionsUserDirectory
"""
return Path(getDtactionsUserDirectory())


warningTexts = []
def warning(text):
Expand All @@ -172,5 +95,12 @@ def warning(text):


if __name__ == "__main__":
print(f'dtactions_directory: "{getDtactionsDirectory()}"')
print(f'dtactions_user_directory: "{getDtactionsUserDirectory()}"')

Type = type(getDtactionsPath())
print(f'dtactions_path: "{getDtactionsPath()}", (type: "{Type}")')

Type = type(getDtactionsUserPath())
print(f'dtactions_user_path: "{getDtactionsUserPath()}", (type: "{Type}"')

17 changes: 7 additions & 10 deletions src/dtactions/autohotkeyactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
See getProgInfo and getCurrentModule below.
"""
#pylint:disable = W0107
import subprocess
import shutil
import filecmp
Expand All @@ -40,16 +41,11 @@
from textwrap import dedent
from dtactions.sendkeys import sendkeys
## get thisDir and other basics...
try:
from dtactions.__init__ import getThisDir, checkDirectory
except ModuleNotFoundError:
print('Run this module after "build_package" and "flit install --symlink"\n')
raise
this_path = Path(__file__).parent


dtactions = thisDir = getThisDir(__file__)
sampleAhkDirectory = dtactions/'samples'/'autohotkey'
checkDirectory(sampleAhkDirectory)
sampleAhkDirectory = this_path/'samples'/'autohotkey'
# TODO: fix this again, but first unimacroactions!
# checkDirectory(sampleAhkDirectory)

ahkexe = None
ahkscriptfolder = None
Expand Down Expand Up @@ -603,7 +599,8 @@ def GetAhkScriptFolder():
return ahkscriptfolder

scriptfolder = Path.home()/".autohotkey"
checkDirectory(scriptfolder, create=True)
# TODO: check ahk checkDirectory function
# checkDirectory(scriptfolder, create=True)
ahkscriptfolder = scriptfolder
copySampleAhkScripts(sampleAhkDirectory, ahkscriptfolder)
return scriptfolder
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,39 @@ def getFolderFromLibraryName(self, name):
if name in ['LOCAL_APPDATA']:
return platformdirs.windows.get_win_folder("CSIDL_LOCAL_APPDATA")

# # General case, try via shellcon! TODO: QH
# try:
# CSIDL_variable = 'CSIDL_%s'% name
# shellnumber = getattr(shellcon,CSIDL_variable, -1)
# print(f'getFolderFromLibraryName, shellnumber of "{CSIDL_variable}": {shellnumber}')
# except:
# print('getExtendedEnv, cannot find CSIDL_variable for: "%s"'% name)
# return ''
# if shellnumber < 0:
# # on some systems have SYSTEMROOT instead of SYSTEM:
# print('getExtendedEnv, cannot find CSIDL_variable for (returns -1): "%s"'% name)
# try:
# csidl_const = shellnumber
# # copied from platformdirs/windows.py:
# buf = ctypes.create_unicode_buffer(1024)
# windll = getattr(ctypes, "windll") # noqa: B009 # using getattr to avoid false positive with mypy type checker
# windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf)
# result = buf.value
# # # result = shell.SHGetFolderPath (0, shellnumber, 0, 0)
# # result = ctypes.windll.shell32.SHGetFolderPathW(0, shellnumber, 0, 0)
# print(f'result from SHGetFolderPathW: {result}')
# except:
# print('getFolderFromLibraryName, cannot path for CSIDL: "%s"'% name)
# return ''


## extra cases:
# if name in ['Quick access', 'Snelle toegang']:
# templatesfolder =self. getExtendedEnv('TEMPLATES')
# if isdir(templatesfolder):
# QuickAccess = normpath(join(templatesfolder, "..", "Libraries"))
# if isdir(QuickAccess):
# return QuickAccess
if name.upper() == 'DROPBOX':
return self.getDropboxFolder()
if name.upper() in ['ONEDRIVE']:
Expand Down Expand Up @@ -283,7 +316,7 @@ def getExtendedEnv(self, var, noCache=False, displayMessage=True):
result = buf.value
# # result = shell.SHGetFolderPath (0, shellnumber, 0, 0)
# result = ctypes.windll.shell32.SHGetFolderPathW(0, shellnumber, 0, 0)
# print(f'result for "{var}" via SHGetFolderPathW: {result}')
print(f'result from SHGetFolderPathW: {result}')
except:
if displayMessage:
print('getExtendedEnv, cannot find in os.environ or CSIDL: "%s"'% var)
Expand All @@ -304,12 +337,11 @@ def getDirectoryFromNatlinkstatus(self, envvar):
# try if function in natlinkstatus:
if not status:
return None
envvar_capped = envvar.lower()
for extra in ('', 'directory', 'dir'):
var2 = envvar_capped + extra
funcName = f'get{var2}'
func = getattr(status, funcName, None)
if func:
for extra in ('', 'Directory', 'Dir'):
var2 = envvar + extra
if var2 in status.__dict__:
funcName = f'get{var2}'
func = getattr(status, funcName)
result = func()
if result:
return result
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from collections import UserDict
from pathlib import Path

from dtactions.unimacro import utilsqh
from dtactions import utilsqh

from natlinkcore import readwritefile

Expand Down
Loading

0 comments on commit 38a1ecc

Please sign in to comment.