Skip to content

Commit 38a1ecc

Browse files
quintijndougransom
andauthored
Komodoerror (#28)
* 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 <doug.ransom@gmail.com>
1 parent 0c66eb4 commit 38a1ecc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+2652
-248
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,3 +153,4 @@ cython_debug/
153153
/documentation/.#*
154154
.rst
155155
*.orig
156+
/.merge_file_*

natlink_test/requires_natlink/test_actions.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
import pytest
99

1010
# from dtactions import natlinkclipboard
11-
# from dtactions.unimacro import unimacroactions as actions # old style
12-
from dtactions.unimacro import newactions as actions
13-
from dtactions.unimacro import unimacroutils
11+
# from dtactions import unimacroactions as actions # old style
12+
from dtactions import unimacroactions as actions
13+
from dtactions import unimacroutils
1414

1515
try:
1616
from dtactions.__init__ import getThisDir, checkDirectory
@@ -47,6 +47,7 @@ def xxx_test_keystroke():
4747
keystroke('{shift+left 11}{ctrl+x}')
4848
time.sleep(0.01)
4949
result = unimacroutils.getClipboard()
50+
#Hello world
5051
assert result == 'Hello world'
5152
#
5253
def test_save_return_clipboard():
@@ -73,3 +74,4 @@ def test_save_return_clipboard():
7374

7475
if __name__ == "__main__":
7576
pytest.main(['test_actions.py'])
77+
#

natlink_test/requires_natlink/unittestClipboard.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import win32gui
1818
from dtactions import natlinkclipboard
1919
from dtactions import autohotkeyactions as ahk
20-
from dtactions.unimacro import unimacroutils
20+
from dtactions import unimacroutils
2121
from dtactions.sendkeys import sendkeys
2222
try:
2323
from dtactions.__init__ import getThisDir, checkDirectory

pyproject.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ maintainers = [{name = "Quintijn Hoogenboom", email="q.hoogenboom@antenna.nl"},
99
dynamic = ["description"]
1010
requires-python = ">=3.9"
1111
readme = "README.md"
12-
version="1.6.4.dev2"
12+
version="1.6.4.dev3"
1313
dependencies= [
1414
"pywin32 >= 300",
1515
"debugpy",
@@ -69,3 +69,8 @@ python_files = [
6969
]
7070

7171

72+
[tool.ruff]
73+
include = ["pyproject.toml", "src/**/*.py", "scripts/**/*.py","tests/**/*.py"]
74+
75+
[tool.pyright]
76+
include = ["pyproject.toml", "src/**/*.py", "scripts/**/*.py","tests/**/*.py"]

src/dtactions/__init__.py

Lines changed: 56 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1,162 +1,85 @@
11
"""dtactions __init__
22
3-
including utility functions,
4-
- getThisDir, for getting the calling directory of module (in site-packages, also when this is a valid symlink),
5-
- findInSitePackages, supporting getThisDir
6-
- checkDirectory, check existence of directory, with create=True, do create if directory does not exist yet.
73
84
Note: -as user, having pipped the package, the scripts run from the site-packages directory,
95
no editing in source files is meant to be done
10-
-as developer, you need to clone the package, then `build_package` and,
6+
-as developer, you need to clone the package,
117
after a `pip uninstall dtactions` do: `pip install -e .` from the root of this project.
128
13-
Start with the following lines near the top of your python file:
9+
10+
You can retrieve the DtactionsDirectory and DtactionsUserDirectory from here:
1411
1512
```
16-
try:
17-
from dtactions.__init__ import getThisDir, checkDirectory
18-
except ModuleNotFoundError:
19-
print(f'Run this module after "build_package" and "flit install --symlink"\n')
20-
raise
21-
22-
thisDir = getThisDir(__file__) # optional: ... , warnings=True)
13+
from dtactions import getDtactionsDirectory, getDtactionsUserDirectory
14+
print(f'dtactions_directory: "{getDtactionsDirectory()}"')
15+
print(f'dtactions_user_directory: "{getDtactionsUserDirectory()}"')
16+
2317
```
2418
25-
Also retrieve the DtactionsDirectory and DtactionsUserDirectory from here:
19+
Or with the "Path" versions:
2620
2721
```
28-
from Dtactionscore.__init__ import getDtactionsDirectory, getDtactionsUserDirectory
29-
30-
print(f'DtactionsDirectory: {getDtactionsDirectory()})
31-
print(f'DtactionsUserDirectory: {getDtactionsUserDirectory()})
22+
from dtactions import getDtactionsPath, getDtactionsUserPath
23+
print(f'dtactions_user_path: "{getDtactionsUserPath()}", (type: "{Type}"')
24+
Type = type(getDtactionsPath())
25+
print(f'dtactions_path: "{getDtactionsPath()}", (type: "{Type}")')
3226
```
3327
34-
NOTE: these two directories can also be obtained via Dtactionsstatus:
35-
```
36-
import natlinkstatus
37-
status = natlinkstatus.DtactionsStatus()
38-
status.getDtactionsDirectory()
39-
status.getDtactionsUserDirectory()
40-
```
4128
4229
"""
4330
import importlib.metadata
4431
__version__ = importlib.metadata.version(__package__) #version set in pyproject.toml now.
4532

4633

4734
##----------------------
48-
import sys
4935
import os
5036
from pathlib import Path, WindowsPath
37+
#
38+
# def get_home_path() -> Path:
39+
# """get home path, can be tweaked by pytest testing
40+
# """
41+
# return WindowsPath.home()
5142

52-
def getDtactionsDirectory():
43+
def getDtactionsDirectory() -> str:
5344
"""return the root directory of dtactions
5445
"""
55-
return getThisDir(__file__)
46+
return str(Path(__file__).parent)
5647

57-
def getDtactionsUserDirectory():
58-
"""get the NatlinkUserDirectory
59-
60-
Here are config files, especially .natlink
61-
62-
By default the users home directory is taken. This directory can be overridden by setting
63-
the environment variable DICTATIONTOOLBOXUSER to an existing directory.
64-
Restart then the calling program
65-
"""
66-
# default dtHome:
67-
dictation_toolbox_user = os.getenv("DICTATIONTOOLBOXUSER")
68-
if dictation_toolbox_user:
69-
dtHome = Path(dictation_toolbox_user)
70-
if not dtHome.is_dir():
71-
dtHome = WindowsPath.home()
72-
print(f'dtactions.getDtactionsUserDirectory: environment variable DICTATIONTOOLBOXUSER does not point to a valid directory: "{dictation_toolbox_user}", take "{dtHome}"')
73-
else:
74-
dtHome = WindowsPath.home()
75-
76-
dtactions_ini_folder = dtHome / ".dtactions"
77-
if not dtactions_ini_folder.is_dir():
78-
dtactions_ini_folder.mkdir() #make it if it doesn't exist
79-
return str(dtactions_ini_folder)
80-
81-
def getThisDir(fileOfModule, warnings=False):
82-
"""get directory of calling module, if possible in site-packages
83-
84-
call at top of module with `getThisDir(__file__)`
85-
86-
If you want to get warnings (each one only once, pass `warnings = True`)
87-
88-
More above and in the explanation of findInSitePackages.
48+
def getDtactionsPath() -> Path:
49+
"""return the root directory of dtactions as Path instance
8950
"""
90-
thisFile = Path(fileOfModule)
91-
thisDir = thisFile.parent
92-
thisDir = findInSitePackages(thisDir, warnings=warnings)
93-
return thisDir
51+
return Path(__file__).parent
9452

95-
def findInSitePackages(directory, warnings):
96-
"""get corresponding directory in site-packages
97-
98-
For users, just having pipped this package, the "directory" is returned, assuming it is in
99-
the site-packages.
100-
101-
For developers, the directory is either
102-
--in a clone from github.
103-
The corresponding directory in site-packages should be a symlink,
104-
otherwise there was no "flit install --symlink" yet.
105-
--a directory in the site-packages. This directory should be a symlink to a cloned dir.
106-
107-
The site-packages directory is returned, but the actual files accessed are in the cloned directory.
108-
109-
To get this "GOOD" situation, you perform the steps as pointed out above (or in the README.md file)
53+
def getDtactionsUserDirectory() -> str:
54+
"""get the UserDirectory for Dtactions
11055
111-
When problems arise, set warnings=True, in the call, preferably when calling getThisDir in the calling module.
112-
"""
113-
dirstr = str(directory)
114-
if dirstr.find('\\src\\') < 0:
115-
if warnings:
116-
warning(f'directory {dirstr} not connected to a github clone directory, changes will not persist across updates...')
117-
return directory
118-
119-
commonpart = dirstr.rsplit('\\src\\', maxsplit=1)[-1]
120-
spDir = Path(sys.prefix, 'Lib', 'site-packages', commonpart)
121-
if spDir.is_dir():
122-
spResolve = spDir.resolve()
123-
if spResolve == spDir:
124-
if warnings:
125-
warning(f'corresponding site-packages directory is not a symlink: {spDir}.\nPlease use "flit install --symlink" when you want to test this package')
126-
elif spResolve == directory:
127-
# print(f'directory is symlink: {spDir} and resolves to {directory} all right')
128-
## return the symbolic link in the site-packages directory, that resolves to directory!!
129-
return spDir
130-
else:
131-
if warnings:
132-
warning(f'directory is symlink: {spDir} but does NOT resolve to {directory}, but to {spResolve}')
133-
else:
134-
if warnings:
135-
warning('findInSitePackages, not a valid directory in site-packages, no "flit install --symlink" yet: {spDir}')
136-
return directory
137-
138-
def checkDirectory(directory, create=None):
139-
"""check existence of directory path
140-
141-
create == False, None (default): raise OSError if directory is not there
56+
This is by default your-home-directory/.dtactions (so decoupled from the Natlink user directory)
57+
58+
You can override this by setting environment variable `DTACTIONS_USERDIR`
59+
to a valid directory of your choice
14260
143-
create == True: create if not existent yet...
144-
raise OSError if something strange happens...
145-
returns None
14661
"""
147-
if not isinstance(directory, Path):
148-
directory = Path(directory)
149-
if directory.is_dir():
150-
return
151-
if create is False:
152-
raise OSError(f'Cannot find directory {directory}, but it should be there.')
153-
if directory.exists():
154-
raise OSError(f'path exists, but is not a directory: {directory}')
155-
directory.mkdir(parents=True)
156-
if directory.is_dir():
157-
print('created directory: {directory}')
158-
else:
159-
raise OSError(f'did not manage to create directory: {directory}')
62+
# default dtHome:
63+
dta_user_dir = os.getenv("DTACTIONS_USERDIR")
64+
if dta_user_dir:
65+
if Path(dta_user_dir).is_dir():
66+
return str(dta_user_dir)
67+
print(f'WARNING, dtactions.getDtactionsUserDirectory: environment variable DTACTIONS_USERDIR does not point to a valid directory: "{dta_user_dir}"')
68+
69+
home_path = WindowsPath.home()
70+
71+
dtactions_ini_path = home_path/".dtactions"
72+
if not dtactions_ini_path.is_dir():
73+
dtactions_ini_path.mkdir() #make it if it doesn't exist
74+
if not dtactions_ini_path.is_dir():
75+
raise IOError(f'dtactions.__init__: dtactions_ini_path cannot be created "{dtactions_ini_path}"' )
76+
return str(dtactions_ini_path)
77+
78+
def getDtactionsUserPath() -> Path:
79+
"""the "Path" version of getDtactionsUserDirectory
80+
"""
81+
return Path(getDtactionsUserDirectory())
82+
16083

16184
warningTexts = []
16285
def warning(text):
@@ -172,5 +95,12 @@ def warning(text):
17295

17396

17497
if __name__ == "__main__":
98+
print(f'dtactions_directory: "{getDtactionsDirectory()}"')
17599
print(f'dtactions_user_directory: "{getDtactionsUserDirectory()}"')
100+
101+
Type = type(getDtactionsPath())
102+
print(f'dtactions_path: "{getDtactionsPath()}", (type: "{Type}")')
103+
104+
Type = type(getDtactionsUserPath())
105+
print(f'dtactions_user_path: "{getDtactionsUserPath()}", (type: "{Type}"')
176106

src/dtactions/autohotkeyactions.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
See getProgInfo and getCurrentModule below.
3131
3232
"""
33+
#pylint:disable = W0107
3334
import subprocess
3435
import shutil
3536
import filecmp
@@ -40,16 +41,11 @@
4041
from textwrap import dedent
4142
from dtactions.sendkeys import sendkeys
4243
## get thisDir and other basics...
43-
try:
44-
from dtactions.__init__ import getThisDir, checkDirectory
45-
except ModuleNotFoundError:
46-
print('Run this module after "build_package" and "flit install --symlink"\n')
47-
raise
44+
this_path = Path(__file__).parent
4845

49-
50-
dtactions = thisDir = getThisDir(__file__)
51-
sampleAhkDirectory = dtactions/'samples'/'autohotkey'
52-
checkDirectory(sampleAhkDirectory)
46+
sampleAhkDirectory = this_path/'samples'/'autohotkey'
47+
# TODO: fix this again, but first unimacroactions!
48+
# checkDirectory(sampleAhkDirectory)
5349

5450
ahkexe = None
5551
ahkscriptfolder = None
@@ -603,7 +599,8 @@ def GetAhkScriptFolder():
603599
return ahkscriptfolder
604600

605601
scriptfolder = Path.home()/".autohotkey"
606-
checkDirectory(scriptfolder, create=True)
602+
# TODO: check ahk checkDirectory function
603+
# checkDirectory(scriptfolder, create=True)
607604
ahkscriptfolder = scriptfolder
608605
copySampleAhkScripts(sampleAhkDirectory, ahkscriptfolder)
609606
return scriptfolder
Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,39 @@ def getFolderFromLibraryName(self, name):
121121
if name in ['LOCAL_APPDATA']:
122122
return platformdirs.windows.get_win_folder("CSIDL_LOCAL_APPDATA")
123123

124+
# # General case, try via shellcon! TODO: QH
125+
# try:
126+
# CSIDL_variable = 'CSIDL_%s'% name
127+
# shellnumber = getattr(shellcon,CSIDL_variable, -1)
128+
# print(f'getFolderFromLibraryName, shellnumber of "{CSIDL_variable}": {shellnumber}')
129+
# except:
130+
# print('getExtendedEnv, cannot find CSIDL_variable for: "%s"'% name)
131+
# return ''
132+
# if shellnumber < 0:
133+
# # on some systems have SYSTEMROOT instead of SYSTEM:
134+
# print('getExtendedEnv, cannot find CSIDL_variable for (returns -1): "%s"'% name)
135+
# try:
136+
# csidl_const = shellnumber
137+
# # copied from platformdirs/windows.py:
138+
# buf = ctypes.create_unicode_buffer(1024)
139+
# windll = getattr(ctypes, "windll") # noqa: B009 # using getattr to avoid false positive with mypy type checker
140+
# windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf)
141+
# result = buf.value
142+
# # # result = shell.SHGetFolderPath (0, shellnumber, 0, 0)
143+
# # result = ctypes.windll.shell32.SHGetFolderPathW(0, shellnumber, 0, 0)
144+
# print(f'result from SHGetFolderPathW: {result}')
145+
# except:
146+
# print('getFolderFromLibraryName, cannot path for CSIDL: "%s"'% name)
147+
# return ''
148+
149+
150+
## extra cases:
151+
# if name in ['Quick access', 'Snelle toegang']:
152+
# templatesfolder =self. getExtendedEnv('TEMPLATES')
153+
# if isdir(templatesfolder):
154+
# QuickAccess = normpath(join(templatesfolder, "..", "Libraries"))
155+
# if isdir(QuickAccess):
156+
# return QuickAccess
124157
if name.upper() == 'DROPBOX':
125158
return self.getDropboxFolder()
126159
if name.upper() in ['ONEDRIVE']:
@@ -283,7 +316,7 @@ def getExtendedEnv(self, var, noCache=False, displayMessage=True):
283316
result = buf.value
284317
# # result = shell.SHGetFolderPath (0, shellnumber, 0, 0)
285318
# result = ctypes.windll.shell32.SHGetFolderPathW(0, shellnumber, 0, 0)
286-
# print(f'result for "{var}" via SHGetFolderPathW: {result}')
319+
print(f'result from SHGetFolderPathW: {result}')
287320
except:
288321
if displayMessage:
289322
print('getExtendedEnv, cannot find in os.environ or CSIDL: "%s"'% var)
@@ -304,12 +337,11 @@ def getDirectoryFromNatlinkstatus(self, envvar):
304337
# try if function in natlinkstatus:
305338
if not status:
306339
return None
307-
envvar_capped = envvar.lower()
308-
for extra in ('', 'directory', 'dir'):
309-
var2 = envvar_capped + extra
310-
funcName = f'get{var2}'
311-
func = getattr(status, funcName, None)
312-
if func:
340+
for extra in ('', 'Directory', 'Dir'):
341+
var2 = envvar + extra
342+
if var2 in status.__dict__:
343+
funcName = f'get{var2}'
344+
func = getattr(status, funcName)
313345
result = func()
314346
if result:
315347
return result
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from collections import UserDict
1111
from pathlib import Path
1212

13-
from dtactions.unimacro import utilsqh
13+
from dtactions import utilsqh
1414

1515
from natlinkcore import readwritefile
1616

0 commit comments

Comments
 (0)