Spaces:
Paused
Paused
FranklinWillemen
commited on
Commit
•
59cd50e
1
Parent(s):
6d7aca3
intial commit
Browse files- .gitignore +131 -0
- README.md +6 -1
- TARS-discourse.py +38 -0
- requirements.txt +2 -0
- tars-env/Scripts/Activate.ps1 +502 -0
- tars-env/Scripts/activate +69 -0
- tars-env/Scripts/activate.bat +34 -0
- tars-env/Scripts/clear_comtypes_cache.py +57 -0
- tars-env/Scripts/deactivate.bat +22 -0
- tars-env/Scripts/f2py.exe +0 -0
- tars-env/Scripts/fonttools.exe +0 -0
- tars-env/Scripts/gradio.exe +0 -0
- tars-env/Scripts/httpx.exe +0 -0
- tars-env/Scripts/huggingface-cli.exe +0 -0
- tars-env/Scripts/jsonschema.exe +0 -0
- tars-env/Scripts/markdown-it.exe +0 -0
- tars-env/Scripts/normalizer.exe +0 -0
- tars-env/Scripts/openai.exe +0 -0
- tars-env/Scripts/pip.exe +0 -0
- tars-env/Scripts/pip3.11.exe +0 -0
- tars-env/Scripts/pip3.exe +0 -0
- tars-env/Scripts/pyftmerge.exe +0 -0
- tars-env/Scripts/pyftsubset.exe +0 -0
- tars-env/Scripts/python.exe +0 -0
- tars-env/Scripts/pythonw.exe +0 -0
- tars-env/Scripts/pywin32_postinstall.py +783 -0
- tars-env/Scripts/pywin32_testall.py +124 -0
- tars-env/Scripts/tqdm.exe +0 -0
- tars-env/Scripts/ttx.exe +0 -0
- tars-env/Scripts/upload_theme.exe +0 -0
- tars-env/Scripts/uvicorn.exe +0 -0
- tars-env/pyvenv.cfg +5 -0
- tars-env/share/man/man1/ttx.1 +225 -0
.gitignore
ADDED
@@ -0,0 +1,131 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
config.py
|
2 |
+
|
3 |
+
# Byte-compiled / optimized / DLL files
|
4 |
+
__pycache__/
|
5 |
+
*.py[cod]
|
6 |
+
*$py.class
|
7 |
+
|
8 |
+
# C extensions
|
9 |
+
*.so
|
10 |
+
|
11 |
+
# Distribution / packaging
|
12 |
+
.Python
|
13 |
+
build/
|
14 |
+
develop-eggs/
|
15 |
+
dist/
|
16 |
+
downloads/
|
17 |
+
eggs/
|
18 |
+
.eggs/
|
19 |
+
lib/
|
20 |
+
lib64/
|
21 |
+
parts/
|
22 |
+
sdist/
|
23 |
+
var/
|
24 |
+
wheels/
|
25 |
+
pip-wheel-metadata/
|
26 |
+
share/python-wheels/
|
27 |
+
*.egg-info/
|
28 |
+
.installed.cfg
|
29 |
+
*.egg
|
30 |
+
MANIFEST
|
31 |
+
|
32 |
+
# PyInstaller
|
33 |
+
# Usually these files are written by a python script from a template
|
34 |
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
35 |
+
*.manifest
|
36 |
+
*.spec
|
37 |
+
|
38 |
+
# Installer logs
|
39 |
+
pip-log.txt
|
40 |
+
pip-delete-this-directory.txt
|
41 |
+
|
42 |
+
# Unit test / coverage reports
|
43 |
+
htmlcov/
|
44 |
+
.tox/
|
45 |
+
.nox/
|
46 |
+
.coverage
|
47 |
+
.coverage.*
|
48 |
+
.cache
|
49 |
+
nosetests.xml
|
50 |
+
coverage.xml
|
51 |
+
*.cover
|
52 |
+
*.py,cover
|
53 |
+
.hypothesis/
|
54 |
+
.pytest_cache/
|
55 |
+
|
56 |
+
# Translations
|
57 |
+
*.mo
|
58 |
+
*.pot
|
59 |
+
|
60 |
+
# Django stuff:
|
61 |
+
*.log
|
62 |
+
local_settings.py
|
63 |
+
db.sqlite3
|
64 |
+
db.sqlite3-journal
|
65 |
+
|
66 |
+
# Flask stuff:
|
67 |
+
instance/
|
68 |
+
.webassets-cache
|
69 |
+
|
70 |
+
# Scrapy stuff:
|
71 |
+
.scrapy
|
72 |
+
|
73 |
+
# Sphinx documentation
|
74 |
+
docs/_build/
|
75 |
+
|
76 |
+
# PyBuilder
|
77 |
+
target/
|
78 |
+
|
79 |
+
# Jupyter Notebook
|
80 |
+
.ipynb_checkpoints
|
81 |
+
|
82 |
+
# IPython
|
83 |
+
profile_default/
|
84 |
+
ipython_config.py
|
85 |
+
|
86 |
+
# pyenv
|
87 |
+
.python-version
|
88 |
+
|
89 |
+
# pipenv
|
90 |
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
91 |
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
92 |
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
93 |
+
# install all needed dependencies.
|
94 |
+
#Pipfile.lock
|
95 |
+
|
96 |
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
97 |
+
__pypackages__/
|
98 |
+
|
99 |
+
# Celery stuff
|
100 |
+
celerybeat-schedule
|
101 |
+
celerybeat.pid
|
102 |
+
|
103 |
+
# SageMath parsed files
|
104 |
+
*.sage.py
|
105 |
+
|
106 |
+
# Environments
|
107 |
+
.env
|
108 |
+
.venv
|
109 |
+
env/
|
110 |
+
venv/
|
111 |
+
ENV/
|
112 |
+
env.bak/
|
113 |
+
venv.bak/
|
114 |
+
|
115 |
+
# Spyder project settings
|
116 |
+
.spyderproject
|
117 |
+
.spyproject
|
118 |
+
|
119 |
+
# Rope project settings
|
120 |
+
.ropeproject
|
121 |
+
|
122 |
+
# mkdocs documentation
|
123 |
+
/site
|
124 |
+
|
125 |
+
# mypy
|
126 |
+
.mypy_cache/
|
127 |
+
.dmypy.json
|
128 |
+
dmypy.json
|
129 |
+
|
130 |
+
# Pyre type checker
|
131 |
+
.pyre/
|
README.md
CHANGED
@@ -1 +1,6 @@
|
|
1 |
-
# TARS
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# TARS Discourse
|
2 |
+
Playground for a discourse bot based on SOTA (State Of The Art) AIAAS (AI As A Service).
|
3 |
+
|
4 |
+
Starting point is a fork of the "chatgpt api and whisper api tutorial - voice conversation with therapist".
|
5 |
+
|
6 |
+
## Setup
|
TARS-discourse.py
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import openai
|
3 |
+
import config
|
4 |
+
import os
|
5 |
+
import pyttsx3
|
6 |
+
openai.api_key = config.OPENAI_API_KEY
|
7 |
+
|
8 |
+
messages = [{"role": "system", "content": 'You are a therapist. Respond to all input in 25 words or less.'}]
|
9 |
+
|
10 |
+
def transcribe(audio: str):
|
11 |
+
global messages
|
12 |
+
|
13 |
+
audio_filename_with_extension = audio + '.wav'
|
14 |
+
os.rename(audio, audio_filename_with_extension)
|
15 |
+
|
16 |
+
audio_file = open(audio_filename_with_extension, "rb")
|
17 |
+
transcript = openai.Audio.transcribe("whisper-1", audio_file)
|
18 |
+
|
19 |
+
messages.append({"role": "user", "content": transcript["text"]})
|
20 |
+
|
21 |
+
response = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=messages)
|
22 |
+
|
23 |
+
system_message = response["choices"][0]["message"]
|
24 |
+
messages.append(system_message)
|
25 |
+
|
26 |
+
# subprocess.call(["say", system_message['content']])
|
27 |
+
engine = pyttsx3.init()
|
28 |
+
engine.say(system_message['content'])
|
29 |
+
engine.runAndWait()
|
30 |
+
|
31 |
+
chat_transcript = ""
|
32 |
+
for message in messages:
|
33 |
+
if message['role'] != 'system':
|
34 |
+
chat_transcript += message['role'] + ": " + message['content'] + "\n\n"
|
35 |
+
|
36 |
+
return chat_transcript
|
37 |
+
|
38 |
+
ui = gr.Interface(fn=transcribe, inputs=gr.Audio(source="microphone", type="filepath"), outputs="text").launch()
|
requirements.txt
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
openai
|
2 |
+
gradio
|
tars-env/Scripts/Activate.ps1
ADDED
@@ -0,0 +1,502 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<#
|
2 |
+
.Synopsis
|
3 |
+
Activate a Python virtual environment for the current PowerShell session.
|
4 |
+
|
5 |
+
.Description
|
6 |
+
Pushes the python executable for a virtual environment to the front of the
|
7 |
+
$Env:PATH environment variable and sets the prompt to signify that you are
|
8 |
+
in a Python virtual environment. Makes use of the command line switches as
|
9 |
+
well as the `pyvenv.cfg` file values present in the virtual environment.
|
10 |
+
|
11 |
+
.Parameter VenvDir
|
12 |
+
Path to the directory that contains the virtual environment to activate. The
|
13 |
+
default value for this is the parent of the directory that the Activate.ps1
|
14 |
+
script is located within.
|
15 |
+
|
16 |
+
.Parameter Prompt
|
17 |
+
The prompt prefix to display when this virtual environment is activated. By
|
18 |
+
default, this prompt is the name of the virtual environment folder (VenvDir)
|
19 |
+
surrounded by parentheses and followed by a single space (ie. '(.venv) ').
|
20 |
+
|
21 |
+
.Example
|
22 |
+
Activate.ps1
|
23 |
+
Activates the Python virtual environment that contains the Activate.ps1 script.
|
24 |
+
|
25 |
+
.Example
|
26 |
+
Activate.ps1 -Verbose
|
27 |
+
Activates the Python virtual environment that contains the Activate.ps1 script,
|
28 |
+
and shows extra information about the activation as it executes.
|
29 |
+
|
30 |
+
.Example
|
31 |
+
Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv
|
32 |
+
Activates the Python virtual environment located in the specified location.
|
33 |
+
|
34 |
+
.Example
|
35 |
+
Activate.ps1 -Prompt "MyPython"
|
36 |
+
Activates the Python virtual environment that contains the Activate.ps1 script,
|
37 |
+
and prefixes the current prompt with the specified string (surrounded in
|
38 |
+
parentheses) while the virtual environment is active.
|
39 |
+
|
40 |
+
.Notes
|
41 |
+
On Windows, it may be required to enable this Activate.ps1 script by setting the
|
42 |
+
execution policy for the user. You can do this by issuing the following PowerShell
|
43 |
+
command:
|
44 |
+
|
45 |
+
PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
|
46 |
+
|
47 |
+
For more information on Execution Policies:
|
48 |
+
https://go.microsoft.com/fwlink/?LinkID=135170
|
49 |
+
|
50 |
+
#>
|
51 |
+
Param(
|
52 |
+
[Parameter(Mandatory = $false)]
|
53 |
+
[String]
|
54 |
+
$VenvDir,
|
55 |
+
[Parameter(Mandatory = $false)]
|
56 |
+
[String]
|
57 |
+
$Prompt
|
58 |
+
)
|
59 |
+
|
60 |
+
<# Function declarations --------------------------------------------------- #>
|
61 |
+
|
62 |
+
<#
|
63 |
+
.Synopsis
|
64 |
+
Remove all shell session elements added by the Activate script, including the
|
65 |
+
addition of the virtual environment's Python executable from the beginning of
|
66 |
+
the PATH variable.
|
67 |
+
|
68 |
+
.Parameter NonDestructive
|
69 |
+
If present, do not remove this function from the global namespace for the
|
70 |
+
session.
|
71 |
+
|
72 |
+
#>
|
73 |
+
function global:deactivate ([switch]$NonDestructive) {
|
74 |
+
# Revert to original values
|
75 |
+
|
76 |
+
# The prior prompt:
|
77 |
+
if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) {
|
78 |
+
Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt
|
79 |
+
Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT
|
80 |
+
}
|
81 |
+
|
82 |
+
# The prior PYTHONHOME:
|
83 |
+
if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) {
|
84 |
+
Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME
|
85 |
+
Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME
|
86 |
+
}
|
87 |
+
|
88 |
+
# The prior PATH:
|
89 |
+
if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) {
|
90 |
+
Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH
|
91 |
+
Remove-Item -Path Env:_OLD_VIRTUAL_PATH
|
92 |
+
}
|
93 |
+
|
94 |
+
# Just remove the VIRTUAL_ENV altogether:
|
95 |
+
if (Test-Path -Path Env:VIRTUAL_ENV) {
|
96 |
+
Remove-Item -Path env:VIRTUAL_ENV
|
97 |
+
}
|
98 |
+
|
99 |
+
# Just remove VIRTUAL_ENV_PROMPT altogether.
|
100 |
+
if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) {
|
101 |
+
Remove-Item -Path env:VIRTUAL_ENV_PROMPT
|
102 |
+
}
|
103 |
+
|
104 |
+
# Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether:
|
105 |
+
if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) {
|
106 |
+
Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force
|
107 |
+
}
|
108 |
+
|
109 |
+
# Leave deactivate function in the global namespace if requested:
|
110 |
+
if (-not $NonDestructive) {
|
111 |
+
Remove-Item -Path function:deactivate
|
112 |
+
}
|
113 |
+
}
|
114 |
+
|
115 |
+
<#
|
116 |
+
.Description
|
117 |
+
Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the
|
118 |
+
given folder, and returns them in a map.
|
119 |
+
|
120 |
+
For each line in the pyvenv.cfg file, if that line can be parsed into exactly
|
121 |
+
two strings separated by `=` (with any amount of whitespace surrounding the =)
|
122 |
+
then it is considered a `key = value` line. The left hand string is the key,
|
123 |
+
the right hand is the value.
|
124 |
+
|
125 |
+
If the value starts with a `'` or a `"` then the first and last character is
|
126 |
+
stripped from the value before being captured.
|
127 |
+
|
128 |
+
.Parameter ConfigDir
|
129 |
+
Path to the directory that contains the `pyvenv.cfg` file.
|
130 |
+
#>
|
131 |
+
function Get-PyVenvConfig(
|
132 |
+
[String]
|
133 |
+
$ConfigDir
|
134 |
+
) {
|
135 |
+
Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg"
|
136 |
+
|
137 |
+
# Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue).
|
138 |
+
$pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue
|
139 |
+
|
140 |
+
# An empty map will be returned if no config file is found.
|
141 |
+
$pyvenvConfig = @{ }
|
142 |
+
|
143 |
+
if ($pyvenvConfigPath) {
|
144 |
+
|
145 |
+
Write-Verbose "File exists, parse `key = value` lines"
|
146 |
+
$pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath
|
147 |
+
|
148 |
+
$pyvenvConfigContent | ForEach-Object {
|
149 |
+
$keyval = $PSItem -split "\s*=\s*", 2
|
150 |
+
if ($keyval[0] -and $keyval[1]) {
|
151 |
+
$val = $keyval[1]
|
152 |
+
|
153 |
+
# Remove extraneous quotations around a string value.
|
154 |
+
if ("'""".Contains($val.Substring(0, 1))) {
|
155 |
+
$val = $val.Substring(1, $val.Length - 2)
|
156 |
+
}
|
157 |
+
|
158 |
+
$pyvenvConfig[$keyval[0]] = $val
|
159 |
+
Write-Verbose "Adding Key: '$($keyval[0])'='$val'"
|
160 |
+
}
|
161 |
+
}
|
162 |
+
}
|
163 |
+
return $pyvenvConfig
|
164 |
+
}
|
165 |
+
|
166 |
+
|
167 |
+
<# Begin Activate script --------------------------------------------------- #>
|
168 |
+
|
169 |
+
# Determine the containing directory of this script
|
170 |
+
$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition
|
171 |
+
$VenvExecDir = Get-Item -Path $VenvExecPath
|
172 |
+
|
173 |
+
Write-Verbose "Activation script is located in path: '$VenvExecPath'"
|
174 |
+
Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)"
|
175 |
+
Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)"
|
176 |
+
|
177 |
+
# Set values required in priority: CmdLine, ConfigFile, Default
|
178 |
+
# First, get the location of the virtual environment, it might not be
|
179 |
+
# VenvExecDir if specified on the command line.
|
180 |
+
if ($VenvDir) {
|
181 |
+
Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values"
|
182 |
+
}
|
183 |
+
else {
|
184 |
+
Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir."
|
185 |
+
$VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/")
|
186 |
+
Write-Verbose "VenvDir=$VenvDir"
|
187 |
+
}
|
188 |
+
|
189 |
+
# Next, read the `pyvenv.cfg` file to determine any required value such
|
190 |
+
# as `prompt`.
|
191 |
+
$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir
|
192 |
+
|
193 |
+
# Next, set the prompt from the command line, or the config file, or
|
194 |
+
# just use the name of the virtual environment folder.
|
195 |
+
if ($Prompt) {
|
196 |
+
Write-Verbose "Prompt specified as argument, using '$Prompt'"
|
197 |
+
}
|
198 |
+
else {
|
199 |
+
Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value"
|
200 |
+
if ($pyvenvCfg -and $pyvenvCfg['prompt']) {
|
201 |
+
Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'"
|
202 |
+
$Prompt = $pyvenvCfg['prompt'];
|
203 |
+
}
|
204 |
+
else {
|
205 |
+
Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)"
|
206 |
+
Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'"
|
207 |
+
$Prompt = Split-Path -Path $venvDir -Leaf
|
208 |
+
}
|
209 |
+
}
|
210 |
+
|
211 |
+
Write-Verbose "Prompt = '$Prompt'"
|
212 |
+
Write-Verbose "VenvDir='$VenvDir'"
|
213 |
+
|
214 |
+
# Deactivate any currently active virtual environment, but leave the
|
215 |
+
# deactivate function in place.
|
216 |
+
deactivate -nondestructive
|
217 |
+
|
218 |
+
# Now set the environment variable VIRTUAL_ENV, used by many tools to determine
|
219 |
+
# that there is an activated venv.
|
220 |
+
$env:VIRTUAL_ENV = $VenvDir
|
221 |
+
|
222 |
+
if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) {
|
223 |
+
|
224 |
+
Write-Verbose "Setting prompt to '$Prompt'"
|
225 |
+
|
226 |
+
# Set the prompt to include the env name
|
227 |
+
# Make sure _OLD_VIRTUAL_PROMPT is global
|
228 |
+
function global:_OLD_VIRTUAL_PROMPT { "" }
|
229 |
+
Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT
|
230 |
+
New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt
|
231 |
+
|
232 |
+
function global:prompt {
|
233 |
+
Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) "
|
234 |
+
_OLD_VIRTUAL_PROMPT
|
235 |
+
}
|
236 |
+
$env:VIRTUAL_ENV_PROMPT = $Prompt
|
237 |
+
}
|
238 |
+
|
239 |
+
# Clear PYTHONHOME
|
240 |
+
if (Test-Path -Path Env:PYTHONHOME) {
|
241 |
+
Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME
|
242 |
+
Remove-Item -Path Env:PYTHONHOME
|
243 |
+
}
|
244 |
+
|
245 |
+
# Add the venv to the PATH
|
246 |
+
Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH
|
247 |
+
$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH"
|
248 |
+
|
249 |
+
# SIG # Begin signature block
|
250 |
+
# MIIvIQYJKoZIhvcNAQcCoIIvEjCCLw4CAQExDzANBglghkgBZQMEAgEFADB5Bgor
|
251 |
+
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
|
252 |
+
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBnL745ElCYk8vk
|
253 |
+
# dBtMuQhLeWJ3ZGfzKW4DHCYzAn+QB6CCE8MwggWQMIIDeKADAgECAhAFmxtXno4h
|
254 |
+
# MuI5B72nd3VcMA0GCSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK
|
255 |
+
# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV
|
256 |
+
# BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0xMzA4MDExMjAwMDBaFw0z
|
257 |
+
# ODAxMTUxMjAwMDBaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ
|
258 |
+
# bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0
|
259 |
+
# IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
|
260 |
+
# AL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/z
|
261 |
+
# G6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZ
|
262 |
+
# anMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7s
|
263 |
+
# Wxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL
|
264 |
+
# 2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfb
|
265 |
+
# BHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3
|
266 |
+
# JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3c
|
267 |
+
# AORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqx
|
268 |
+
# YxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0
|
269 |
+
# viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aL
|
270 |
+
# T8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjQjBAMA8GA1Ud
|
271 |
+
# EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTs1+OC0nFdZEzf
|
272 |
+
# Lmc/57qYrhwPTzANBgkqhkiG9w0BAQwFAAOCAgEAu2HZfalsvhfEkRvDoaIAjeNk
|
273 |
+
# aA9Wz3eucPn9mkqZucl4XAwMX+TmFClWCzZJXURj4K2clhhmGyMNPXnpbWvWVPjS
|
274 |
+
# PMFDQK4dUPVS/JA7u5iZaWvHwaeoaKQn3J35J64whbn2Z006Po9ZOSJTROvIXQPK
|
275 |
+
# 7VB6fWIhCoDIc2bRoAVgX+iltKevqPdtNZx8WorWojiZ83iL9E3SIAveBO6Mm0eB
|
276 |
+
# cg3AFDLvMFkuruBx8lbkapdvklBtlo1oepqyNhR6BvIkuQkRUNcIsbiJeoQjYUIp
|
277 |
+
# 5aPNoiBB19GcZNnqJqGLFNdMGbJQQXE9P01wI4YMStyB0swylIQNCAmXHE/A7msg
|
278 |
+
# dDDS4Dk0EIUhFQEI6FUy3nFJ2SgXUE3mvk3RdazQyvtBuEOlqtPDBURPLDab4vri
|
279 |
+
# RbgjU2wGb2dVf0a1TD9uKFp5JtKkqGKX0h7i7UqLvBv9R0oN32dmfrJbQdA75PQ7
|
280 |
+
# 9ARj6e/CVABRoIoqyc54zNXqhwQYs86vSYiv85KZtrPmYQ/ShQDnUBrkG5WdGaG5
|
281 |
+
# nLGbsQAe79APT0JsyQq87kP6OnGlyE0mpTX9iV28hWIdMtKgK1TtmlfB2/oQzxm3
|
282 |
+
# i0objwG2J5VT6LaJbVu8aNQj6ItRolb58KaAoNYes7wPD1N1KarqE3fk3oyBIa0H
|
283 |
+
# EEcRrYc9B9F1vM/zZn4wggawMIIEmKADAgECAhAIrUCyYNKcTJ9ezam9k67ZMA0G
|
284 |
+
# CSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ
|
285 |
+
# bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0
|
286 |
+
# IFRydXN0ZWQgUm9vdCBHNDAeFw0yMTA0MjkwMDAwMDBaFw0zNjA0MjgyMzU5NTla
|
287 |
+
# MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE
|
288 |
+
# AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz
|
289 |
+
# ODQgMjAyMSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDVtC9C
|
290 |
+
# 0CiteLdd1TlZG7GIQvUzjOs9gZdwxbvEhSYwn6SOaNhc9es0JAfhS0/TeEP0F9ce
|
291 |
+
# 2vnS1WcaUk8OoVf8iJnBkcyBAz5NcCRks43iCH00fUyAVxJrQ5qZ8sU7H/Lvy0da
|
292 |
+
# E6ZMswEgJfMQ04uy+wjwiuCdCcBlp/qYgEk1hz1RGeiQIXhFLqGfLOEYwhrMxe6T
|
293 |
+
# SXBCMo/7xuoc82VokaJNTIIRSFJo3hC9FFdd6BgTZcV/sk+FLEikVoQ11vkunKoA
|
294 |
+
# FdE3/hoGlMJ8yOobMubKwvSnowMOdKWvObarYBLj6Na59zHh3K3kGKDYwSNHR7Oh
|
295 |
+
# D26jq22YBoMbt2pnLdK9RBqSEIGPsDsJ18ebMlrC/2pgVItJwZPt4bRc4G/rJvmM
|
296 |
+
# 1bL5OBDm6s6R9b7T+2+TYTRcvJNFKIM2KmYoX7BzzosmJQayg9Rc9hUZTO1i4F4z
|
297 |
+
# 8ujo7AqnsAMrkbI2eb73rQgedaZlzLvjSFDzd5Ea/ttQokbIYViY9XwCFjyDKK05
|
298 |
+
# huzUtw1T0PhH5nUwjewwk3YUpltLXXRhTT8SkXbev1jLchApQfDVxW0mdmgRQRNY
|
299 |
+
# mtwmKwH0iU1Z23jPgUo+QEdfyYFQc4UQIyFZYIpkVMHMIRroOBl8ZhzNeDhFMJlP
|
300 |
+
# /2NPTLuqDQhTQXxYPUez+rbsjDIJAsxsPAxWEQIDAQABo4IBWTCCAVUwEgYDVR0T
|
301 |
+
# AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHwYD
|
302 |
+
# VR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMG
|
303 |
+
# A1UdJQQMMAoGCCsGAQUFBwMDMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYY
|
304 |
+
# aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2Fj
|
305 |
+
# ZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNV
|
306 |
+
# HR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRU
|
307 |
+
# cnVzdGVkUm9vdEc0LmNybDAcBgNVHSAEFTATMAcGBWeBDAEDMAgGBmeBDAEEATAN
|
308 |
+
# BgkqhkiG9w0BAQwFAAOCAgEAOiNEPY0Idu6PvDqZ01bgAhql+Eg08yy25nRm95Ry
|
309 |
+
# sQDKr2wwJxMSnpBEn0v9nqN8JtU3vDpdSG2V1T9J9Ce7FoFFUP2cvbaF4HZ+N3HL
|
310 |
+
# IvdaqpDP9ZNq4+sg0dVQeYiaiorBtr2hSBh+3NiAGhEZGM1hmYFW9snjdufE5Btf
|
311 |
+
# Q/g+lP92OT2e1JnPSt0o618moZVYSNUa/tcnP/2Q0XaG3RywYFzzDaju4ImhvTnh
|
312 |
+
# OE7abrs2nfvlIVNaw8rpavGiPttDuDPITzgUkpn13c5UbdldAhQfQDN8A+KVssIh
|
313 |
+
# dXNSy0bYxDQcoqVLjc1vdjcshT8azibpGL6QB7BDf5WIIIJw8MzK7/0pNVwfiThV
|
314 |
+
# 9zeKiwmhywvpMRr/LhlcOXHhvpynCgbWJme3kuZOX956rEnPLqR0kq3bPKSchh/j
|
315 |
+
# wVYbKyP/j7XqiHtwa+aguv06P0WmxOgWkVKLQcBIhEuWTatEQOON8BUozu3xGFYH
|
316 |
+
# Ki8QxAwIZDwzj64ojDzLj4gLDb879M4ee47vtevLt/B3E+bnKD+sEq6lLyJsQfmC
|
317 |
+
# XBVmzGwOysWGw/YmMwwHS6DTBwJqakAwSEs0qFEgu60bhQjiWQ1tygVQK+pKHJ6l
|
318 |
+
# /aCnHwZ05/LWUpD9r4VIIflXO7ScA+2GRfS0YW6/aOImYIbqyK+p/pQd52MbOoZW
|
319 |
+
# eE4wggd3MIIFX6ADAgECAhAHHxQbizANJfMU6yMM0NHdMA0GCSqGSIb3DQEBCwUA
|
320 |
+
# MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE
|
321 |
+
# AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz
|
322 |
+
# ODQgMjAyMSBDQTEwHhcNMjIwMTE3MDAwMDAwWhcNMjUwMTE1MjM1OTU5WjB8MQsw
|
323 |
+
# CQYDVQQGEwJVUzEPMA0GA1UECBMGT3JlZ29uMRIwEAYDVQQHEwlCZWF2ZXJ0b24x
|
324 |
+
# IzAhBgNVBAoTGlB5dGhvbiBTb2Z0d2FyZSBGb3VuZGF0aW9uMSMwIQYDVQQDExpQ
|
325 |
+
# eXRob24gU29mdHdhcmUgRm91bmRhdGlvbjCCAiIwDQYJKoZIhvcNAQEBBQADggIP
|
326 |
+
# ADCCAgoCggIBAKgc0BTT+iKbtK6f2mr9pNMUTcAJxKdsuOiSYgDFfwhjQy89koM7
|
327 |
+
# uP+QV/gwx8MzEt3c9tLJvDccVWQ8H7mVsk/K+X+IufBLCgUi0GGAZUegEAeRlSXx
|
328 |
+
# xhYScr818ma8EvGIZdiSOhqjYc4KnfgfIS4RLtZSrDFG2tN16yS8skFa3IHyvWdb
|
329 |
+
# D9PvZ4iYNAS4pjYDRjT/9uzPZ4Pan+53xZIcDgjiTwOh8VGuppxcia6a7xCyKoOA
|
330 |
+
# GjvCyQsj5223v1/Ig7Dp9mGI+nh1E3IwmyTIIuVHyK6Lqu352diDY+iCMpk9Zanm
|
331 |
+
# SjmB+GMVs+H/gOiofjjtf6oz0ki3rb7sQ8fTnonIL9dyGTJ0ZFYKeb6BLA66d2GA
|
332 |
+
# LwxZhLe5WH4Np9HcyXHACkppsE6ynYjTOd7+jN1PRJahN1oERzTzEiV6nCO1M3U1
|
333 |
+
# HbPTGyq52IMFSBM2/07WTJSbOeXjvYR7aUxK9/ZkJiacl2iZI7IWe7JKhHohqKuc
|
334 |
+
# eQNyOzxTakLcRkzynvIrk33R9YVqtB4L6wtFxhUjvDnQg16xot2KVPdfyPAWd81w
|
335 |
+
# tZADmrUtsZ9qG79x1hBdyOl4vUtVPECuyhCxaw+faVjumapPUnwo8ygflJJ74J+B
|
336 |
+
# Yxf6UuD7m8yzsfXWkdv52DjL74TxzuFTLHPyARWCSCAbzn3ZIly+qIqDAgMBAAGj
|
337 |
+
# ggIGMIICAjAfBgNVHSMEGDAWgBRoN+Drtjv4XxGG+/5hewiIZfROQjAdBgNVHQ4E
|
338 |
+
# FgQUt/1Teh2XDuUj2WW3siYWJgkZHA8wDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQM
|
339 |
+
# MAoGCCsGAQUFBwMDMIG1BgNVHR8Ega0wgaowU6BRoE+GTWh0dHA6Ly9jcmwzLmRp
|
340 |
+
# Z2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNI
|
341 |
+
# QTM4NDIwMjFDQTEuY3JsMFOgUaBPhk1odHRwOi8vY3JsNC5kaWdpY2VydC5jb20v
|
342 |
+
# RGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIxQ0Ex
|
343 |
+
# LmNybDA+BgNVHSAENzA1MDMGBmeBDAEEATApMCcGCCsGAQUFBwIBFhtodHRwOi8v
|
344 |
+
# d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgZQGCCsGAQUFBwEBBIGHMIGEMCQGCCsGAQUF
|
345 |
+
# BzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wXAYIKwYBBQUHMAKGUGh0dHA6
|
346 |
+
# Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWdu
|
347 |
+
# aW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZI
|
348 |
+
# hvcNAQELBQADggIBABxv4AeV/5ltkELHSC63fXAFYS5tadcWTiNc2rskrNLrfH1N
|
349 |
+
# s0vgSZFoQxYBFKI159E8oQQ1SKbTEubZ/B9kmHPhprHya08+VVzxC88pOEvz68nA
|
350 |
+
# 82oEM09584aILqYmj8Pj7h/kmZNzuEL7WiwFa/U1hX+XiWfLIJQsAHBla0i7QRF2
|
351 |
+
# de8/VSF0XXFa2kBQ6aiTsiLyKPNbaNtbcucaUdn6vVUS5izWOXM95BSkFSKdE45O
|
352 |
+
# q3FForNJXjBvSCpwcP36WklaHL+aHu1upIhCTUkzTHMh8b86WmjRUqbrnvdyR2yd
|
353 |
+
# I5l1OqcMBjkpPpIV6wcc+KY/RH2xvVuuoHjlUjwq2bHiNoX+W1scCpnA8YTs2d50
|
354 |
+
# jDHUgwUo+ciwpffH0Riq132NFmrH3r67VaN3TuBxjI8SIZM58WEDkbeoriDk3hxU
|
355 |
+
# 8ZWV7b8AW6oyVBGfM06UgkfMb58h+tJPrFx8VI/WLq1dTqMfZOm5cuclMnUHs2uq
|
356 |
+
# rRNtnV8UfidPBL4ZHkTcClQbCoz0UbLhkiDvIS00Dn+BBcxw/TKqVL4Oaz3bkMSs
|
357 |
+
# M46LciTeucHY9ExRVt3zy7i149sd+F4QozPqn7FrSVHXmem3r7bjyHTxOgqxRCVa
|
358 |
+
# 18Vtx7P/8bYSBeS+WHCKcliFCecspusCDSlnRUjZwyPdP0VHxaZg2unjHY3rMYIa
|
359 |
+
# tDCCGrACAQEwfTBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIElu
|
360 |
+
# Yy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgQ29kZSBTaWduaW5nIFJT
|
361 |
+
# QTQwOTYgU0hBMzg0IDIwMjEgQ0ExAhAHHxQbizANJfMU6yMM0NHdMA0GCWCGSAFl
|
362 |
+
# AwQCAQUAoIHIMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcC
|
363 |
+
# AQsxDjAMBgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEiBCBnAZ6P7YvTwq0fbF62
|
364 |
+
# o7E75R0LxsW5OtyYiFESQckLhjBcBgorBgEEAYI3AgEMMU4wTKBGgEQAQgB1AGkA
|
365 |
+
# bAB0ADoAIABSAGUAbABlAGEAcwBlAF8AdgAzAC4AMQAxAC4AMwBfADIAMAAyADMA
|
366 |
+
# MAA0ADAANAAuADAAMaECgAAwDQYJKoZIhvcNAQEBBQAEggIAbmsoeVnvqR4l7EsR
|
367 |
+
# nUNDQhIoOsioPo5dRYtGRoY3gWX6NnIWzyYo3nlX//xY6JbfZ8oyaqLZULFMkLWm
|
368 |
+
# +c70FKdQS5yI9auu/DOqmZ0AcPsLXEc7rJZagpBDgi6xCvAyvpAHj1FUcGGzWsE+
|
369 |
+
# Qp8LkKU5AApLcHpBci3eZYUpiwoTNvDCQLYIv5j5mh8Fb8j2D/sUt2coONsqLllY
|
370 |
+
# BB1Cpko4g9CEfJKtXKb8g0U8+giDAxt/0r6AMdeqlx9ysFB0Nil+tneagBTQ4vQl
|
371 |
+
# pl5mztf7JVkzasgDNvNcFMo04crUW5g5oErl3e/bO63v1duN7ZuJBJvKs9aDrogI
|
372 |
+
# KOLwYbTYa1Y5wHCsz8HCgd3pfRxQgwWL0+zx7+MKpqlvo20JmFG5H8wj3tcdc1FW
|
373 |
+
# QeOVYzVijkeGqRb21HTNHKuTfV4Gw3cLdT4oOENY3JdkJ+oqnAiSwC1p/Fm3pizG
|
374 |
+
# wkc3D+JjNYg6UT+9PdWqLtsjaBODM1lB22Bpx/nnPCnUG8WEx9cwi39zJdV+atcZ
|
375 |
+
# eTKc+Ahpyxot3az6yv9w83+7wIdnSWBWQwAHonjwx1jjMiiDpLyHblqxt/jgejkV
|
376 |
+
# VQEam7XX3KOKI3CHDC8k3M4V6QTnCTIX/WLslIO57hwUGtOAGmww6/q2NOqKeqpH
|
377 |
+
# 1B6f/CLtXwSh0d4raerISKVQjYChghc9MIIXOQYKKwYBBAGCNwMDATGCFykwghcl
|
378 |
+
# BgkqhkiG9w0BBwKgghcWMIIXEgIBAzEPMA0GCWCGSAFlAwQCAQUAMHcGCyqGSIb3
|
379 |
+
# DQEJEAEEoGgEZjBkAgEBBglghkgBhv1sBwEwMTANBglghkgBZQMEAgEFAAQgkIZK
|
380 |
+
# LoYk5fC9ubz0LiZd/QHnskSNa7ucOHGD7CWySe4CEHn5OnRbrbmQtyWnJjmOhREY
|
381 |
+
# DzIwMjMwNDA1MDAwMjQ1WqCCEwcwggbAMIIEqKADAgECAhAMTWlyS5T6PCpKPSkH
|
382 |
+
# gD1aMA0GCSqGSIb3DQEBCwUAMGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdp
|
383 |
+
# Q2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2
|
384 |
+
# IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0EwHhcNMjIwOTIxMDAwMDAwWhcNMzMxMTIx
|
385 |
+
# MjM1OTU5WjBGMQswCQYDVQQGEwJVUzERMA8GA1UEChMIRGlnaUNlcnQxJDAiBgNV
|
386 |
+
# BAMTG0RpZ2lDZXJ0IFRpbWVzdGFtcCAyMDIyIC0gMjCCAiIwDQYJKoZIhvcNAQEB
|
387 |
+
# BQADggIPADCCAgoCggIBAM/spSY6xqnya7uNwQ2a26HoFIV0MxomrNAcVR4eNm28
|
388 |
+
# klUMYfSdCXc9FZYIL2tkpP0GgxbXkZI4HDEClvtysZc6Va8z7GGK6aYo25BjXL2J
|
389 |
+
# U+A6LYyHQq4mpOS7eHi5ehbhVsbAumRTuyoW51BIu4hpDIjG8b7gL307scpTjUCD
|
390 |
+
# HufLckkoHkyAHoVW54Xt8mG8qjoHffarbuVm3eJc9S/tjdRNlYRo44DLannR0hCR
|
391 |
+
# RinrPibytIzNTLlmyLuqUDgN5YyUXRlav/V7QG5vFqianJVHhoV5PgxeZowaCiS+
|
392 |
+
# nKrSnLb3T254xCg/oxwPUAY3ugjZNaa1Htp4WB056PhMkRCWfk3h3cKtpX74LRsf
|
393 |
+
# 7CtGGKMZ9jn39cFPcS6JAxGiS7uYv/pP5Hs27wZE5FX/NurlfDHn88JSxOYWe1p+
|
394 |
+
# pSVz28BqmSEtY+VZ9U0vkB8nt9KrFOU4ZodRCGv7U0M50GT6Vs/g9ArmFG1keLuY
|
395 |
+
# /ZTDcyHzL8IuINeBrNPxB9ThvdldS24xlCmL5kGkZZTAWOXlLimQprdhZPrZIGwY
|
396 |
+
# UWC6poEPCSVT8b876asHDmoHOWIZydaFfxPZjXnPYsXs4Xu5zGcTB5rBeO3GiMiw
|
397 |
+
# bjJ5xwtZg43G7vUsfHuOy2SJ8bHEuOdTXl9V0n0ZKVkDTvpd6kVzHIR+187i1Dp3
|
398 |
+
# AgMBAAGjggGLMIIBhzAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAWBgNV
|
399 |
+
# HSUBAf8EDDAKBggrBgEFBQcDCDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgB
|
400 |
+
# hv1sBwEwHwYDVR0jBBgwFoAUuhbZbU2FL3MpdpovdYxqII+eyG8wHQYDVR0OBBYE
|
401 |
+
# FGKK3tBh/I8xFO2XC809KpQU31KcMFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9j
|
402 |
+
# cmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZU
|
403 |
+
# aW1lU3RhbXBpbmdDQS5jcmwwgZAGCCsGAQUFBwEBBIGDMIGAMCQGCCsGAQUFBzAB
|
404 |
+
# hhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wWAYIKwYBBQUHMAKGTGh0dHA6Ly9j
|
405 |
+
# YWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEy
|
406 |
+
# NTZUaW1lU3RhbXBpbmdDQS5jcnQwDQYJKoZIhvcNAQELBQADggIBAFWqKhrzRvN4
|
407 |
+
# Vzcw/HXjT9aFI/H8+ZU5myXm93KKmMN31GT8Ffs2wklRLHiIY1UJRjkA/GnUypsp
|
408 |
+
# +6M/wMkAmxMdsJiJ3HjyzXyFzVOdr2LiYWajFCpFh0qYQitQ/Bu1nggwCfrkLdcJ
|
409 |
+
# iXn5CeaIzn0buGqim8FTYAnoo7id160fHLjsmEHw9g6A++T/350Qp+sAul9Kjxo6
|
410 |
+
# UrTqvwlJFTU2WZoPVNKyG39+XgmtdlSKdG3K0gVnK3br/5iyJpU4GYhEFOUKWaJr
|
411 |
+
# 5yI+RCHSPxzAm+18SLLYkgyRTzxmlK9dAlPrnuKe5NMfhgFknADC6Vp0dQ094XmI
|
412 |
+
# vxwBl8kZI4DXNlpflhaxYwzGRkA7zl011Fk+Q5oYrsPJy8P7mxNfarXH4PMFw1nf
|
413 |
+
# J2Ir3kHJU7n/NBBn9iYymHv+XEKUgZSCnawKi8ZLFUrTmJBFYDOA4CPe+AOk9kVH
|
414 |
+
# 5c64A0JH6EE2cXet/aLol3ROLtoeHYxayB6a1cLwxiKoT5u92ByaUcQvmvZfpyeX
|
415 |
+
# upYuhVfAYOd4Vn9q78KVmksRAsiCnMkaBXy6cbVOepls9Oie1FqYyJ+/jbsYXEP1
|
416 |
+
# 0Cro4mLueATbvdH7WwqocH7wl4R44wgDXUcsY6glOJcB0j862uXl9uab3H4szP8X
|
417 |
+
# TE0AotjWAQ64i+7m4HJViSwnGWH2dwGMMIIGrjCCBJagAwIBAgIQBzY3tyRUfNhH
|
418 |
+
# rP0oZipeWzANBgkqhkiG9w0BAQsFADBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMM
|
419 |
+
# RGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQD
|
420 |
+
# ExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMjIwMzIzMDAwMDAwWhcNMzcw
|
421 |
+
# MzIyMjM1OTU5WjBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIElu
|
422 |
+
# Yy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYg
|
423 |
+
# VGltZVN0YW1waW5nIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA
|
424 |
+
# xoY1BkmzwT1ySVFVxyUDxPKRN6mXUaHW0oPRnkyibaCwzIP5WvYRoUQVQl+kiPNo
|
425 |
+
# +n3znIkLf50fng8zH1ATCyZzlm34V6gCff1DtITaEfFzsbPuK4CEiiIY3+vaPcQX
|
426 |
+
# f6sZKz5C3GeO6lE98NZW1OcoLevTsbV15x8GZY2UKdPZ7Gnf2ZCHRgB720RBidx8
|
427 |
+
# ald68Dd5n12sy+iEZLRS8nZH92GDGd1ftFQLIWhuNyG7QKxfst5Kfc71ORJn7w6l
|
428 |
+
# Y2zkpsUdzTYNXNXmG6jBZHRAp8ByxbpOH7G1WE15/tePc5OsLDnipUjW8LAxE6lX
|
429 |
+
# KZYnLvWHpo9OdhVVJnCYJn+gGkcgQ+NDY4B7dW4nJZCYOjgRs/b2nuY7W+yB3iIU
|
430 |
+
# 2YIqx5K/oN7jPqJz+ucfWmyU8lKVEStYdEAoq3NDzt9KoRxrOMUp88qqlnNCaJ+2
|
431 |
+
# RrOdOqPVA+C/8KI8ykLcGEh/FDTP0kyr75s9/g64ZCr6dSgkQe1CvwWcZklSUPRR
|
432 |
+
# 8zZJTYsg0ixXNXkrqPNFYLwjjVj33GHek/45wPmyMKVM1+mYSlg+0wOI/rOP015L
|
433 |
+
# dhJRk8mMDDtbiiKowSYI+RQQEgN9XyO7ZONj4KbhPvbCdLI/Hgl27KtdRnXiYKNY
|
434 |
+
# CQEoAA6EVO7O6V3IXjASvUaetdN2udIOa5kM0jO0zbECAwEAAaOCAV0wggFZMBIG
|
435 |
+
# A1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFLoW2W1NhS9zKXaaL3WMaiCPnshv
|
436 |
+
# MB8GA1UdIwQYMBaAFOzX44LScV1kTN8uZz/nupiuHA9PMA4GA1UdDwEB/wQEAwIB
|
437 |
+
# hjATBgNVHSUEDDAKBggrBgEFBQcDCDB3BggrBgEFBQcBAQRrMGkwJAYIKwYBBQUH
|
438 |
+
# MAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBBBggrBgEFBQcwAoY1aHR0cDov
|
439 |
+
# L2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcnQw
|
440 |
+
# QwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lD
|
441 |
+
# ZXJ0VHJ1c3RlZFJvb3RHNC5jcmwwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZI
|
442 |
+
# AYb9bAcBMA0GCSqGSIb3DQEBCwUAA4ICAQB9WY7Ak7ZvmKlEIgF+ZtbYIULhsBgu
|
443 |
+
# EE0TzzBTzr8Y+8dQXeJLKftwig2qKWn8acHPHQfpPmDI2AvlXFvXbYf6hCAlNDFn
|
444 |
+
# zbYSlm/EUExiHQwIgqgWvalWzxVzjQEiJc6VaT9Hd/tydBTX/6tPiix6q4XNQ1/t
|
445 |
+
# YLaqT5Fmniye4Iqs5f2MvGQmh2ySvZ180HAKfO+ovHVPulr3qRCyXen/KFSJ8NWK
|
446 |
+
# cXZl2szwcqMj+sAngkSumScbqyQeJsG33irr9p6xeZmBo1aGqwpFyd/EjaDnmPv7
|
447 |
+
# pp1yr8THwcFqcdnGE4AJxLafzYeHJLtPo0m5d2aR8XKc6UsCUqc3fpNTrDsdCEkP
|
448 |
+
# lM05et3/JWOZJyw9P2un8WbDQc1PtkCbISFA0LcTJM3cHXg65J6t5TRxktcma+Q4
|
449 |
+
# c6umAU+9Pzt4rUyt+8SVe+0KXzM5h0F4ejjpnOHdI/0dKNPH+ejxmF/7K9h+8kad
|
450 |
+
# dSweJywm228Vex4Ziza4k9Tm8heZWcpw8De/mADfIBZPJ/tgZxahZrrdVcA6KYaw
|
451 |
+
# mKAr7ZVBtzrVFZgxtGIJDwq9gdkT/r+k0fNX2bwE+oLeMt8EifAAzV3C+dAjfwAL
|
452 |
+
# 5HYCJtnwZXZCpimHCUcr5n8apIUP/JiW9lVUKx+A+sDyDivl1vupL0QVSucTDh3b
|
453 |
+
# NzgaoSv27dZ8/DCCBY0wggR1oAMCAQICEA6bGI750C3n79tQ4ghAGFowDQYJKoZI
|
454 |
+
# hvcNAQEMBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
|
455 |
+
# MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
|
456 |
+
# dXJlZCBJRCBSb290IENBMB4XDTIyMDgwMTAwMDAwMFoXDTMxMTEwOTIzNTk1OVow
|
457 |
+
# YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
|
458 |
+
# d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgVHJ1c3RlZCBSb290
|
459 |
+
# IEc0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAv+aQc2jeu+RdSjww
|
460 |
+
# IjBpM+zCpyUuySE98orYWcLhKac9WKt2ms2uexuEDcQwH/MbpDgW61bGl20dq7J5
|
461 |
+
# 8soR0uRf1gU8Ug9SH8aeFaV+vp+pVxZZVXKvaJNwwrK6dZlqczKU0RBEEC7fgvMH
|
462 |
+
# hOZ0O21x4i0MG+4g1ckgHWMpLc7sXk7Ik/ghYZs06wXGXuxbGrzryc/NrDRAX7F6
|
463 |
+
# Zu53yEioZldXn1RYjgwrt0+nMNlW7sp7XeOtyU9e5TXnMcvak17cjo+A2raRmECQ
|
464 |
+
# ecN4x7axxLVqGDgDEI3Y1DekLgV9iPWCPhCRcKtVgkEy19sEcypukQF8IUzUvK4b
|
465 |
+
# A3VdeGbZOjFEmjNAvwjXWkmkwuapoGfdpCe8oU85tRFYF/ckXEaPZPfBaYh2mHY9
|
466 |
+
# WV1CdoeJl2l6SPDgohIbZpp0yt5LHucOY67m1O+SkjqePdwA5EUlibaaRBkrfsCU
|
467 |
+
# tNJhbesz2cXfSwQAzH0clcOP9yGyshG3u3/y1YxwLEFgqrFjGESVGnZifvaAsPvo
|
468 |
+
# ZKYz0YkH4b235kOkGLimdwHhD5QMIR2yVCkliWzlDlJRR3S+Jqy2QXXeeqxfjT/J
|
469 |
+
# vNNBERJb5RBQ6zHFynIWIgnffEx1P2PsIV/EIFFrb7GrhotPwtZFX50g/KEexcCP
|
470 |
+
# orF+CiaZ9eRpL5gdLfXZqbId5RsCAwEAAaOCATowggE2MA8GA1UdEwEB/wQFMAMB
|
471 |
+
# Af8wHQYDVR0OBBYEFOzX44LScV1kTN8uZz/nupiuHA9PMB8GA1UdIwQYMBaAFEXr
|
472 |
+
# oq/0ksuCMS1Ri6enIZ3zbcgPMA4GA1UdDwEB/wQEAwIBhjB5BggrBgEFBQcBAQRt
|
473 |
+
# MGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBDBggrBgEF
|
474 |
+
# BQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJl
|
475 |
+
# ZElEUm9vdENBLmNydDBFBgNVHR8EPjA8MDqgOKA2hjRodHRwOi8vY3JsMy5kaWdp
|
476 |
+
# Y2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMBEGA1UdIAQKMAgw
|
477 |
+
# BgYEVR0gADANBgkqhkiG9w0BAQwFAAOCAQEAcKC/Q1xV5zhfoKN0Gz22Ftf3v1cH
|
478 |
+
# vZqsoYcs7IVeqRq7IviHGmlUIu2kiHdtvRoU9BNKei8ttzjv9P+Aufih9/Jy3iS8
|
479 |
+
# UgPITtAq3votVs/59PesMHqai7Je1M/RQ0SbQyHrlnKhSLSZy51PpwYDE3cnRNTn
|
480 |
+
# f+hZqPC/Lwum6fI0POz3A8eHqNJMQBk1RmppVLC4oVaO7KTVPeix3P0c2PR3WlxU
|
481 |
+
# jG/voVA9/HYJaISfb8rbII01YBwCA8sgsKxYoA5AY8WYIsGyWfVVa88nq2x2zm8j
|
482 |
+
# LfR+cWojayL/ErhULSd+2DrZ8LaHlv1b0VysGMNNn3O3AamfV6peKOK5lDGCA3Yw
|
483 |
+
# ggNyAgEBMHcwYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMu
|
484 |
+
# MTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRp
|
485 |
+
# bWVTdGFtcGluZyBDQQIQDE1pckuU+jwqSj0pB4A9WjANBglghkgBZQMEAgEFAKCB
|
486 |
+
# 0TAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwHAYJKoZIhvcNAQkFMQ8XDTIz
|
487 |
+
# MDQwNTAwMDI0NVowKwYLKoZIhvcNAQkQAgwxHDAaMBgwFgQU84ciTYYzgpI1qZS8
|
488 |
+
# vY+W6f4cfHMwLwYJKoZIhvcNAQkEMSIEIJBlriw3QJw5qq5ADo60uCRAA2a3vjKn
|
489 |
+
# zaGl8ppJqVo5MDcGCyqGSIb3DQEJEAIvMSgwJjAkMCIEIMf04b4yKIkgq+ImOr4a
|
490 |
+
# xPxP5ngcLWTQTIB1V6Ajtbb6MA0GCSqGSIb3DQEBAQUABIICADC4cqKeH7lb0Ll+
|
491 |
+
# iZIDw+mU6vcA3C8vUPR4KdqQmVlEkjfKdHBpHOI1eRkXwesD+BkrXpRX/NMNKm5w
|
492 |
+
# eKlymuuS70/NOX03BgnP4A9p4TqSZJcLvrP5VUc7VlMaVwkNj47vft4OF9A7PFs4
|
493 |
+
# 3e8BJmhhkXDh1j+MdQ5URPGsla8uYm74Cn/T2WPNZ5FFQ8nkoVz93x1c5wUYEruB
|
494 |
+
# uIyFKwZshDnsYsHetZoBMpWDspcXj0kKAplBW0hUw6kgX7qBKX7doTcZPXP00VM8
|
495 |
+
# vYnpQkJPGrTZ4S/cN0D5k0ZTXTCTDtOpFaZLbG29OgSFxD/TslfXkf1t8GiuzXvk
|
496 |
+
# u6xLEPxBW9N4yrun+jUjXr0921HEg7BKRr77bGS9v9b4mfzThomjtdcL3bweU5RE
|
497 |
+
# 3Bg4qVrgNF9Io8L/n39U7Zd5LG4Nacd+Uv+B1x6sfyQP+vGvY0UEiJUhkGy0ymzm
|
498 |
+
# RBtsPmJanvIovpkYebSccueoeC08/AUf2LxZ6lfGxkJp95vNj4pWToYRXY2dj5JE
|
499 |
+
# 6nX7mLYn3mWMbXniPhtpnYJeDahE2cuB3pqbhZSlGpOtF7fEPSCBq9P3YMnuyRun
|
500 |
+
# thsRTf8xc30muj6bRejnUJj0bNQaByZKAhEENnqH0TXBF7yasT1H3/PyC1pgyzx8
|
501 |
+
# swIsvJFXCqG2u9lftpHuQYmHPDoq
|
502 |
+
# SIG # End signature block
|
tars-env/Scripts/activate
ADDED
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# This file must be used with "source bin/activate" *from bash*
|
2 |
+
# you cannot run it directly
|
3 |
+
|
4 |
+
deactivate () {
|
5 |
+
# reset old environment variables
|
6 |
+
if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then
|
7 |
+
PATH="${_OLD_VIRTUAL_PATH:-}"
|
8 |
+
export PATH
|
9 |
+
unset _OLD_VIRTUAL_PATH
|
10 |
+
fi
|
11 |
+
if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then
|
12 |
+
PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}"
|
13 |
+
export PYTHONHOME
|
14 |
+
unset _OLD_VIRTUAL_PYTHONHOME
|
15 |
+
fi
|
16 |
+
|
17 |
+
# This should detect bash and zsh, which have a hash command that must
|
18 |
+
# be called to get it to forget past commands. Without forgetting
|
19 |
+
# past commands the $PATH changes we made may not be respected
|
20 |
+
if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
|
21 |
+
hash -r 2> /dev/null
|
22 |
+
fi
|
23 |
+
|
24 |
+
if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then
|
25 |
+
PS1="${_OLD_VIRTUAL_PS1:-}"
|
26 |
+
export PS1
|
27 |
+
unset _OLD_VIRTUAL_PS1
|
28 |
+
fi
|
29 |
+
|
30 |
+
unset VIRTUAL_ENV
|
31 |
+
unset VIRTUAL_ENV_PROMPT
|
32 |
+
if [ ! "${1:-}" = "nondestructive" ] ; then
|
33 |
+
# Self destruct!
|
34 |
+
unset -f deactivate
|
35 |
+
fi
|
36 |
+
}
|
37 |
+
|
38 |
+
# unset irrelevant variables
|
39 |
+
deactivate nondestructive
|
40 |
+
|
41 |
+
VIRTUAL_ENV="C:\Users\Frank\TARS\tars-env"
|
42 |
+
export VIRTUAL_ENV
|
43 |
+
|
44 |
+
_OLD_VIRTUAL_PATH="$PATH"
|
45 |
+
PATH="$VIRTUAL_ENV/Scripts:$PATH"
|
46 |
+
export PATH
|
47 |
+
|
48 |
+
# unset PYTHONHOME if set
|
49 |
+
# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
|
50 |
+
# could use `if (set -u; : $PYTHONHOME) ;` in bash
|
51 |
+
if [ -n "${PYTHONHOME:-}" ] ; then
|
52 |
+
_OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}"
|
53 |
+
unset PYTHONHOME
|
54 |
+
fi
|
55 |
+
|
56 |
+
if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then
|
57 |
+
_OLD_VIRTUAL_PS1="${PS1:-}"
|
58 |
+
PS1="(tars-env) ${PS1:-}"
|
59 |
+
export PS1
|
60 |
+
VIRTUAL_ENV_PROMPT="(tars-env) "
|
61 |
+
export VIRTUAL_ENV_PROMPT
|
62 |
+
fi
|
63 |
+
|
64 |
+
# This should detect bash and zsh, which have a hash command that must
|
65 |
+
# be called to get it to forget past commands. Without forgetting
|
66 |
+
# past commands the $PATH changes we made may not be respected
|
67 |
+
if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
|
68 |
+
hash -r 2> /dev/null
|
69 |
+
fi
|
tars-env/Scripts/activate.bat
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@echo off
|
2 |
+
|
3 |
+
rem This file is UTF-8 encoded, so we need to update the current code page while executing it
|
4 |
+
for /f "tokens=2 delims=:." %%a in ('"%SystemRoot%\System32\chcp.com"') do (
|
5 |
+
set _OLD_CODEPAGE=%%a
|
6 |
+
)
|
7 |
+
if defined _OLD_CODEPAGE (
|
8 |
+
"%SystemRoot%\System32\chcp.com" 65001 > nul
|
9 |
+
)
|
10 |
+
|
11 |
+
set VIRTUAL_ENV=C:\Users\Frank\TARS\tars-env
|
12 |
+
|
13 |
+
if not defined PROMPT set PROMPT=$P$G
|
14 |
+
|
15 |
+
if defined _OLD_VIRTUAL_PROMPT set PROMPT=%_OLD_VIRTUAL_PROMPT%
|
16 |
+
if defined _OLD_VIRTUAL_PYTHONHOME set PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%
|
17 |
+
|
18 |
+
set _OLD_VIRTUAL_PROMPT=%PROMPT%
|
19 |
+
set PROMPT=(tars-env) %PROMPT%
|
20 |
+
|
21 |
+
if defined PYTHONHOME set _OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME%
|
22 |
+
set PYTHONHOME=
|
23 |
+
|
24 |
+
if defined _OLD_VIRTUAL_PATH set PATH=%_OLD_VIRTUAL_PATH%
|
25 |
+
if not defined _OLD_VIRTUAL_PATH set _OLD_VIRTUAL_PATH=%PATH%
|
26 |
+
|
27 |
+
set PATH=%VIRTUAL_ENV%\Scripts;%PATH%
|
28 |
+
set VIRTUAL_ENV_PROMPT=(tars-env)
|
29 |
+
|
30 |
+
:END
|
31 |
+
if defined _OLD_CODEPAGE (
|
32 |
+
"%SystemRoot%\System32\chcp.com" %_OLD_CODEPAGE% > nul
|
33 |
+
set _OLD_CODEPAGE=
|
34 |
+
)
|
tars-env/Scripts/clear_comtypes_cache.py
ADDED
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import sys
|
3 |
+
import shutil
|
4 |
+
|
5 |
+
def get_next_cache_dir():
|
6 |
+
work_dir = os.getcwd()
|
7 |
+
try:
|
8 |
+
# change working directory to avoid import from local folder
|
9 |
+
# during installation process
|
10 |
+
os.chdir(os.path.dirname(sys.executable))
|
11 |
+
import comtypes.client
|
12 |
+
return comtypes.client._code_cache._find_gen_dir()
|
13 |
+
except ImportError:
|
14 |
+
return None
|
15 |
+
finally:
|
16 |
+
os.chdir(work_dir)
|
17 |
+
|
18 |
+
|
19 |
+
def _remove(directory):
|
20 |
+
shutil.rmtree(directory)
|
21 |
+
print('Removed directory "%s"' % directory)
|
22 |
+
|
23 |
+
|
24 |
+
def remove_directory(directory, silent):
|
25 |
+
if directory:
|
26 |
+
if silent:
|
27 |
+
_remove(directory)
|
28 |
+
else:
|
29 |
+
try:
|
30 |
+
confirm = raw_input('Remove comtypes cache directories? (y/n): ')
|
31 |
+
except NameError:
|
32 |
+
confirm = input('Remove comtypes cache directories? (y/n): ')
|
33 |
+
if confirm.lower() == 'y':
|
34 |
+
_remove(directory)
|
35 |
+
else:
|
36 |
+
print('Directory "%s" NOT removed' % directory)
|
37 |
+
return False
|
38 |
+
return True
|
39 |
+
|
40 |
+
|
41 |
+
if len(sys.argv) > 1 and "-y" in sys.argv[1:]:
|
42 |
+
silent = True
|
43 |
+
else:
|
44 |
+
silent = False
|
45 |
+
|
46 |
+
|
47 |
+
# First iteration may get folder with restricted rights.
|
48 |
+
# Second iteration always gets temp cache folder (writable for all).
|
49 |
+
directory = get_next_cache_dir()
|
50 |
+
removed = remove_directory(directory, silent)
|
51 |
+
|
52 |
+
if removed:
|
53 |
+
directory = get_next_cache_dir()
|
54 |
+
|
55 |
+
# do not request the second confirmation
|
56 |
+
# if the first folder was already removed
|
57 |
+
remove_directory(directory, silent=removed)
|
tars-env/Scripts/deactivate.bat
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@echo off
|
2 |
+
|
3 |
+
if defined _OLD_VIRTUAL_PROMPT (
|
4 |
+
set "PROMPT=%_OLD_VIRTUAL_PROMPT%"
|
5 |
+
)
|
6 |
+
set _OLD_VIRTUAL_PROMPT=
|
7 |
+
|
8 |
+
if defined _OLD_VIRTUAL_PYTHONHOME (
|
9 |
+
set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%"
|
10 |
+
set _OLD_VIRTUAL_PYTHONHOME=
|
11 |
+
)
|
12 |
+
|
13 |
+
if defined _OLD_VIRTUAL_PATH (
|
14 |
+
set "PATH=%_OLD_VIRTUAL_PATH%"
|
15 |
+
)
|
16 |
+
|
17 |
+
set _OLD_VIRTUAL_PATH=
|
18 |
+
|
19 |
+
set VIRTUAL_ENV=
|
20 |
+
set VIRTUAL_ENV_PROMPT=
|
21 |
+
|
22 |
+
:END
|
tars-env/Scripts/f2py.exe
ADDED
Binary file (108 kB). View file
|
|
tars-env/Scripts/fonttools.exe
ADDED
Binary file (108 kB). View file
|
|
tars-env/Scripts/gradio.exe
ADDED
Binary file (108 kB). View file
|
|
tars-env/Scripts/httpx.exe
ADDED
Binary file (108 kB). View file
|
|
tars-env/Scripts/huggingface-cli.exe
ADDED
Binary file (108 kB). View file
|
|
tars-env/Scripts/jsonschema.exe
ADDED
Binary file (108 kB). View file
|
|
tars-env/Scripts/markdown-it.exe
ADDED
Binary file (108 kB). View file
|
|
tars-env/Scripts/normalizer.exe
ADDED
Binary file (108 kB). View file
|
|
tars-env/Scripts/openai.exe
ADDED
Binary file (108 kB). View file
|
|
tars-env/Scripts/pip.exe
ADDED
Binary file (108 kB). View file
|
|
tars-env/Scripts/pip3.11.exe
ADDED
Binary file (108 kB). View file
|
|
tars-env/Scripts/pip3.exe
ADDED
Binary file (108 kB). View file
|
|
tars-env/Scripts/pyftmerge.exe
ADDED
Binary file (108 kB). View file
|
|
tars-env/Scripts/pyftsubset.exe
ADDED
Binary file (108 kB). View file
|
|
tars-env/Scripts/python.exe
ADDED
Binary file (271 kB). View file
|
|
tars-env/Scripts/pythonw.exe
ADDED
Binary file (259 kB). View file
|
|
tars-env/Scripts/pywin32_postinstall.py
ADDED
@@ -0,0 +1,783 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# postinstall script for pywin32
|
2 |
+
#
|
3 |
+
# copies PyWinTypesxx.dll and PythonCOMxx.dll into the system directory,
|
4 |
+
# and creates a pth file
|
5 |
+
import glob
|
6 |
+
import os
|
7 |
+
import shutil
|
8 |
+
import sys
|
9 |
+
import sysconfig
|
10 |
+
|
11 |
+
try:
|
12 |
+
import winreg as winreg
|
13 |
+
except:
|
14 |
+
import winreg
|
15 |
+
|
16 |
+
# Send output somewhere so it can be found if necessary...
|
17 |
+
import tempfile
|
18 |
+
|
19 |
+
tee_f = open(os.path.join(tempfile.gettempdir(), "pywin32_postinstall.log"), "w")
|
20 |
+
|
21 |
+
|
22 |
+
class Tee:
|
23 |
+
def __init__(self, file):
|
24 |
+
self.f = file
|
25 |
+
|
26 |
+
def write(self, what):
|
27 |
+
if self.f is not None:
|
28 |
+
try:
|
29 |
+
self.f.write(what.replace("\n", "\r\n"))
|
30 |
+
except IOError:
|
31 |
+
pass
|
32 |
+
tee_f.write(what)
|
33 |
+
|
34 |
+
def flush(self):
|
35 |
+
if self.f is not None:
|
36 |
+
try:
|
37 |
+
self.f.flush()
|
38 |
+
except IOError:
|
39 |
+
pass
|
40 |
+
tee_f.flush()
|
41 |
+
|
42 |
+
|
43 |
+
# For some unknown reason, when running under bdist_wininst we will start up
|
44 |
+
# with sys.stdout as None but stderr is hooked up. This work-around allows
|
45 |
+
# bdist_wininst to see the output we write and display it at the end of
|
46 |
+
# the install.
|
47 |
+
if sys.stdout is None:
|
48 |
+
sys.stdout = sys.stderr
|
49 |
+
|
50 |
+
sys.stderr = Tee(sys.stderr)
|
51 |
+
sys.stdout = Tee(sys.stdout)
|
52 |
+
|
53 |
+
com_modules = [
|
54 |
+
# module_name, class_names
|
55 |
+
("win32com.servers.interp", "Interpreter"),
|
56 |
+
("win32com.servers.dictionary", "DictionaryPolicy"),
|
57 |
+
("win32com.axscript.client.pyscript", "PyScript"),
|
58 |
+
]
|
59 |
+
|
60 |
+
# Is this a 'silent' install - ie, avoid all dialogs.
|
61 |
+
# Different than 'verbose'
|
62 |
+
silent = 0
|
63 |
+
|
64 |
+
# Verbosity of output messages.
|
65 |
+
verbose = 1
|
66 |
+
|
67 |
+
root_key_name = "Software\\Python\\PythonCore\\" + sys.winver
|
68 |
+
|
69 |
+
try:
|
70 |
+
# When this script is run from inside the bdist_wininst installer,
|
71 |
+
# file_created() and directory_created() are additional builtin
|
72 |
+
# functions which write lines to Python23\pywin32-install.log. This is
|
73 |
+
# a list of actions for the uninstaller, the format is inspired by what
|
74 |
+
# the Wise installer also creates.
|
75 |
+
file_created
|
76 |
+
is_bdist_wininst = True
|
77 |
+
except NameError:
|
78 |
+
is_bdist_wininst = False # we know what it is not - but not what it is :)
|
79 |
+
|
80 |
+
def file_created(file):
|
81 |
+
pass
|
82 |
+
|
83 |
+
def directory_created(directory):
|
84 |
+
pass
|
85 |
+
|
86 |
+
def get_root_hkey():
|
87 |
+
try:
|
88 |
+
winreg.OpenKey(
|
89 |
+
winreg.HKEY_LOCAL_MACHINE, root_key_name, 0, winreg.KEY_CREATE_SUB_KEY
|
90 |
+
)
|
91 |
+
return winreg.HKEY_LOCAL_MACHINE
|
92 |
+
except OSError:
|
93 |
+
# Either not exist, or no permissions to create subkey means
|
94 |
+
# must be HKCU
|
95 |
+
return winreg.HKEY_CURRENT_USER
|
96 |
+
|
97 |
+
|
98 |
+
try:
|
99 |
+
create_shortcut
|
100 |
+
except NameError:
|
101 |
+
# Create a function with the same signature as create_shortcut provided
|
102 |
+
# by bdist_wininst
|
103 |
+
def create_shortcut(
|
104 |
+
path, description, filename, arguments="", workdir="", iconpath="", iconindex=0
|
105 |
+
):
|
106 |
+
import pythoncom
|
107 |
+
from win32com.shell import shell
|
108 |
+
|
109 |
+
ilink = pythoncom.CoCreateInstance(
|
110 |
+
shell.CLSID_ShellLink,
|
111 |
+
None,
|
112 |
+
pythoncom.CLSCTX_INPROC_SERVER,
|
113 |
+
shell.IID_IShellLink,
|
114 |
+
)
|
115 |
+
ilink.SetPath(path)
|
116 |
+
ilink.SetDescription(description)
|
117 |
+
if arguments:
|
118 |
+
ilink.SetArguments(arguments)
|
119 |
+
if workdir:
|
120 |
+
ilink.SetWorkingDirectory(workdir)
|
121 |
+
if iconpath or iconindex:
|
122 |
+
ilink.SetIconLocation(iconpath, iconindex)
|
123 |
+
# now save it.
|
124 |
+
ipf = ilink.QueryInterface(pythoncom.IID_IPersistFile)
|
125 |
+
ipf.Save(filename, 0)
|
126 |
+
|
127 |
+
# Support the same list of "path names" as bdist_wininst.
|
128 |
+
def get_special_folder_path(path_name):
|
129 |
+
from win32com.shell import shell, shellcon
|
130 |
+
|
131 |
+
for maybe in """
|
132 |
+
CSIDL_COMMON_STARTMENU CSIDL_STARTMENU CSIDL_COMMON_APPDATA
|
133 |
+
CSIDL_LOCAL_APPDATA CSIDL_APPDATA CSIDL_COMMON_DESKTOPDIRECTORY
|
134 |
+
CSIDL_DESKTOPDIRECTORY CSIDL_COMMON_STARTUP CSIDL_STARTUP
|
135 |
+
CSIDL_COMMON_PROGRAMS CSIDL_PROGRAMS CSIDL_PROGRAM_FILES_COMMON
|
136 |
+
CSIDL_PROGRAM_FILES CSIDL_FONTS""".split():
|
137 |
+
if maybe == path_name:
|
138 |
+
csidl = getattr(shellcon, maybe)
|
139 |
+
return shell.SHGetSpecialFolderPath(0, csidl, False)
|
140 |
+
raise ValueError("%s is an unknown path ID" % (path_name,))
|
141 |
+
|
142 |
+
|
143 |
+
def CopyTo(desc, src, dest):
|
144 |
+
import win32api
|
145 |
+
import win32con
|
146 |
+
|
147 |
+
while 1:
|
148 |
+
try:
|
149 |
+
win32api.CopyFile(src, dest, 0)
|
150 |
+
return
|
151 |
+
except win32api.error as details:
|
152 |
+
if details.winerror == 5: # access denied - user not admin.
|
153 |
+
raise
|
154 |
+
if silent:
|
155 |
+
# Running silent mode - just re-raise the error.
|
156 |
+
raise
|
157 |
+
full_desc = (
|
158 |
+
"Error %s\n\n"
|
159 |
+
"If you have any Python applications running, "
|
160 |
+
"please close them now\nand select 'Retry'\n\n%s"
|
161 |
+
% (desc, details.strerror)
|
162 |
+
)
|
163 |
+
rc = win32api.MessageBox(
|
164 |
+
0, full_desc, "Installation Error", win32con.MB_ABORTRETRYIGNORE
|
165 |
+
)
|
166 |
+
if rc == win32con.IDABORT:
|
167 |
+
raise
|
168 |
+
elif rc == win32con.IDIGNORE:
|
169 |
+
return
|
170 |
+
# else retry - around we go again.
|
171 |
+
|
172 |
+
|
173 |
+
# We need to import win32api to determine the Windows system directory,
|
174 |
+
# so we can copy our system files there - but importing win32api will
|
175 |
+
# load the pywintypes.dll already in the system directory preventing us
|
176 |
+
# from updating them!
|
177 |
+
# So, we pull the same trick pywintypes.py does, but it loads from
|
178 |
+
# our pywintypes_system32 directory.
|
179 |
+
def LoadSystemModule(lib_dir, modname):
|
180 |
+
# See if this is a debug build.
|
181 |
+
import importlib.machinery
|
182 |
+
import importlib.util
|
183 |
+
|
184 |
+
suffix = "_d" if "_d.pyd" in importlib.machinery.EXTENSION_SUFFIXES else ""
|
185 |
+
filename = "%s%d%d%s.dll" % (
|
186 |
+
modname,
|
187 |
+
sys.version_info[0],
|
188 |
+
sys.version_info[1],
|
189 |
+
suffix,
|
190 |
+
)
|
191 |
+
filename = os.path.join(lib_dir, "pywin32_system32", filename)
|
192 |
+
loader = importlib.machinery.ExtensionFileLoader(modname, filename)
|
193 |
+
spec = importlib.machinery.ModuleSpec(name=modname, loader=loader, origin=filename)
|
194 |
+
mod = importlib.util.module_from_spec(spec)
|
195 |
+
spec.loader.exec_module(mod)
|
196 |
+
|
197 |
+
|
198 |
+
def SetPyKeyVal(key_name, value_name, value):
|
199 |
+
root_hkey = get_root_hkey()
|
200 |
+
root_key = winreg.OpenKey(root_hkey, root_key_name)
|
201 |
+
try:
|
202 |
+
my_key = winreg.CreateKey(root_key, key_name)
|
203 |
+
try:
|
204 |
+
winreg.SetValueEx(my_key, value_name, 0, winreg.REG_SZ, value)
|
205 |
+
if verbose:
|
206 |
+
print("-> %s\\%s[%s]=%r" % (root_key_name, key_name, value_name, value))
|
207 |
+
finally:
|
208 |
+
my_key.Close()
|
209 |
+
finally:
|
210 |
+
root_key.Close()
|
211 |
+
|
212 |
+
|
213 |
+
def UnsetPyKeyVal(key_name, value_name, delete_key=False):
|
214 |
+
root_hkey = get_root_hkey()
|
215 |
+
root_key = winreg.OpenKey(root_hkey, root_key_name)
|
216 |
+
try:
|
217 |
+
my_key = winreg.OpenKey(root_key, key_name, 0, winreg.KEY_SET_VALUE)
|
218 |
+
try:
|
219 |
+
winreg.DeleteValue(my_key, value_name)
|
220 |
+
if verbose:
|
221 |
+
print("-> DELETE %s\\%s[%s]" % (root_key_name, key_name, value_name))
|
222 |
+
finally:
|
223 |
+
my_key.Close()
|
224 |
+
if delete_key:
|
225 |
+
winreg.DeleteKey(root_key, key_name)
|
226 |
+
if verbose:
|
227 |
+
print("-> DELETE %s\\%s" % (root_key_name, key_name))
|
228 |
+
except OSError as why:
|
229 |
+
winerror = getattr(why, "winerror", why.errno)
|
230 |
+
if winerror != 2: # file not found
|
231 |
+
raise
|
232 |
+
finally:
|
233 |
+
root_key.Close()
|
234 |
+
|
235 |
+
|
236 |
+
def RegisterCOMObjects(register=True):
|
237 |
+
import win32com.server.register
|
238 |
+
|
239 |
+
if register:
|
240 |
+
func = win32com.server.register.RegisterClasses
|
241 |
+
else:
|
242 |
+
func = win32com.server.register.UnregisterClasses
|
243 |
+
flags = {}
|
244 |
+
if not verbose:
|
245 |
+
flags["quiet"] = 1
|
246 |
+
for module, klass_name in com_modules:
|
247 |
+
__import__(module)
|
248 |
+
mod = sys.modules[module]
|
249 |
+
flags["finalize_register"] = getattr(mod, "DllRegisterServer", None)
|
250 |
+
flags["finalize_unregister"] = getattr(mod, "DllUnregisterServer", None)
|
251 |
+
klass = getattr(mod, klass_name)
|
252 |
+
func(klass, **flags)
|
253 |
+
|
254 |
+
|
255 |
+
def RegisterHelpFile(register=True, lib_dir=None):
|
256 |
+
if lib_dir is None:
|
257 |
+
lib_dir = sysconfig.get_paths()["platlib"]
|
258 |
+
if register:
|
259 |
+
# Register the .chm help file.
|
260 |
+
chm_file = os.path.join(lib_dir, "PyWin32.chm")
|
261 |
+
if os.path.isfile(chm_file):
|
262 |
+
# This isn't recursive, so if 'Help' doesn't exist, we croak
|
263 |
+
SetPyKeyVal("Help", None, None)
|
264 |
+
SetPyKeyVal("Help\\Pythonwin Reference", None, chm_file)
|
265 |
+
return chm_file
|
266 |
+
else:
|
267 |
+
print("NOTE: PyWin32.chm can not be located, so has not " "been registered")
|
268 |
+
else:
|
269 |
+
UnsetPyKeyVal("Help\\Pythonwin Reference", None, delete_key=True)
|
270 |
+
return None
|
271 |
+
|
272 |
+
|
273 |
+
def RegisterPythonwin(register=True, lib_dir=None):
|
274 |
+
"""Add (or remove) Pythonwin to context menu for python scripts.
|
275 |
+
??? Should probably also add Edit command for pys files also.
|
276 |
+
Also need to remove these keys on uninstall, but there's no function
|
277 |
+
like file_created to add registry entries to uninstall log ???
|
278 |
+
"""
|
279 |
+
import os
|
280 |
+
|
281 |
+
if lib_dir is None:
|
282 |
+
lib_dir = sysconfig.get_paths()["platlib"]
|
283 |
+
classes_root = get_root_hkey()
|
284 |
+
## Installer executable doesn't seem to pass anything to postinstall script indicating if it's a debug build,
|
285 |
+
pythonwin_exe = os.path.join(lib_dir, "Pythonwin", "Pythonwin.exe")
|
286 |
+
pythonwin_edit_command = pythonwin_exe + ' -edit "%1"'
|
287 |
+
|
288 |
+
keys_vals = [
|
289 |
+
(
|
290 |
+
"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\Pythonwin.exe",
|
291 |
+
"",
|
292 |
+
pythonwin_exe,
|
293 |
+
),
|
294 |
+
(
|
295 |
+
"Software\\Classes\\Python.File\\shell\\Edit with Pythonwin",
|
296 |
+
"command",
|
297 |
+
pythonwin_edit_command,
|
298 |
+
),
|
299 |
+
(
|
300 |
+
"Software\\Classes\\Python.NoConFile\\shell\\Edit with Pythonwin",
|
301 |
+
"command",
|
302 |
+
pythonwin_edit_command,
|
303 |
+
),
|
304 |
+
]
|
305 |
+
|
306 |
+
try:
|
307 |
+
if register:
|
308 |
+
for key, sub_key, val in keys_vals:
|
309 |
+
## Since winreg only uses the character Api functions, this can fail if Python
|
310 |
+
## is installed to a path containing non-ascii characters
|
311 |
+
hkey = winreg.CreateKey(classes_root, key)
|
312 |
+
if sub_key:
|
313 |
+
hkey = winreg.CreateKey(hkey, sub_key)
|
314 |
+
winreg.SetValueEx(hkey, None, 0, winreg.REG_SZ, val)
|
315 |
+
hkey.Close()
|
316 |
+
else:
|
317 |
+
for key, sub_key, val in keys_vals:
|
318 |
+
try:
|
319 |
+
if sub_key:
|
320 |
+
hkey = winreg.OpenKey(classes_root, key)
|
321 |
+
winreg.DeleteKey(hkey, sub_key)
|
322 |
+
hkey.Close()
|
323 |
+
winreg.DeleteKey(classes_root, key)
|
324 |
+
except OSError as why:
|
325 |
+
winerror = getattr(why, "winerror", why.errno)
|
326 |
+
if winerror != 2: # file not found
|
327 |
+
raise
|
328 |
+
finally:
|
329 |
+
# tell windows about the change
|
330 |
+
from win32com.shell import shell, shellcon
|
331 |
+
|
332 |
+
shell.SHChangeNotify(
|
333 |
+
shellcon.SHCNE_ASSOCCHANGED, shellcon.SHCNF_IDLIST, None, None
|
334 |
+
)
|
335 |
+
|
336 |
+
|
337 |
+
def get_shortcuts_folder():
|
338 |
+
if get_root_hkey() == winreg.HKEY_LOCAL_MACHINE:
|
339 |
+
try:
|
340 |
+
fldr = get_special_folder_path("CSIDL_COMMON_PROGRAMS")
|
341 |
+
except OSError:
|
342 |
+
# No CSIDL_COMMON_PROGRAMS on this platform
|
343 |
+
fldr = get_special_folder_path("CSIDL_PROGRAMS")
|
344 |
+
else:
|
345 |
+
# non-admin install - always goes in this user's start menu.
|
346 |
+
fldr = get_special_folder_path("CSIDL_PROGRAMS")
|
347 |
+
|
348 |
+
try:
|
349 |
+
install_group = winreg.QueryValue(
|
350 |
+
get_root_hkey(), root_key_name + "\\InstallPath\\InstallGroup"
|
351 |
+
)
|
352 |
+
except OSError:
|
353 |
+
vi = sys.version_info
|
354 |
+
install_group = "Python %d.%d" % (vi[0], vi[1])
|
355 |
+
return os.path.join(fldr, install_group)
|
356 |
+
|
357 |
+
|
358 |
+
# Get the system directory, which may be the Wow64 directory if we are a 32bit
|
359 |
+
# python on a 64bit OS.
|
360 |
+
def get_system_dir():
|
361 |
+
import win32api # we assume this exists.
|
362 |
+
|
363 |
+
try:
|
364 |
+
import pythoncom
|
365 |
+
import win32process
|
366 |
+
from win32com.shell import shell, shellcon
|
367 |
+
|
368 |
+
try:
|
369 |
+
if win32process.IsWow64Process():
|
370 |
+
return shell.SHGetSpecialFolderPath(0, shellcon.CSIDL_SYSTEMX86)
|
371 |
+
return shell.SHGetSpecialFolderPath(0, shellcon.CSIDL_SYSTEM)
|
372 |
+
except (pythoncom.com_error, win32process.error):
|
373 |
+
return win32api.GetSystemDirectory()
|
374 |
+
except ImportError:
|
375 |
+
return win32api.GetSystemDirectory()
|
376 |
+
|
377 |
+
|
378 |
+
def fixup_dbi():
|
379 |
+
# We used to have a dbi.pyd with our .pyd files, but now have a .py file.
|
380 |
+
# If the user didn't uninstall, they will find the .pyd which will cause
|
381 |
+
# problems - so handle that.
|
382 |
+
import win32api
|
383 |
+
import win32con
|
384 |
+
|
385 |
+
pyd_name = os.path.join(os.path.dirname(win32api.__file__), "dbi.pyd")
|
386 |
+
pyd_d_name = os.path.join(os.path.dirname(win32api.__file__), "dbi_d.pyd")
|
387 |
+
py_name = os.path.join(os.path.dirname(win32con.__file__), "dbi.py")
|
388 |
+
for this_pyd in (pyd_name, pyd_d_name):
|
389 |
+
this_dest = this_pyd + ".old"
|
390 |
+
if os.path.isfile(this_pyd) and os.path.isfile(py_name):
|
391 |
+
try:
|
392 |
+
if os.path.isfile(this_dest):
|
393 |
+
print(
|
394 |
+
"Old dbi '%s' already exists - deleting '%s'"
|
395 |
+
% (this_dest, this_pyd)
|
396 |
+
)
|
397 |
+
os.remove(this_pyd)
|
398 |
+
else:
|
399 |
+
os.rename(this_pyd, this_dest)
|
400 |
+
print("renamed '%s'->'%s.old'" % (this_pyd, this_pyd))
|
401 |
+
file_created(this_pyd + ".old")
|
402 |
+
except os.error as exc:
|
403 |
+
print("FAILED to rename '%s': %s" % (this_pyd, exc))
|
404 |
+
|
405 |
+
|
406 |
+
def install(lib_dir):
|
407 |
+
import traceback
|
408 |
+
|
409 |
+
# The .pth file is now installed as a regular file.
|
410 |
+
# Create the .pth file in the site-packages dir, and use only relative paths
|
411 |
+
# We used to write a .pth directly to sys.prefix - clobber it.
|
412 |
+
if os.path.isfile(os.path.join(sys.prefix, "pywin32.pth")):
|
413 |
+
os.unlink(os.path.join(sys.prefix, "pywin32.pth"))
|
414 |
+
# The .pth may be new and therefore not loaded in this session.
|
415 |
+
# Setup the paths just in case.
|
416 |
+
for name in "win32 win32\\lib Pythonwin".split():
|
417 |
+
sys.path.append(os.path.join(lib_dir, name))
|
418 |
+
# It is possible people with old versions installed with still have
|
419 |
+
# pywintypes and pythoncom registered. We no longer need this, and stale
|
420 |
+
# entries hurt us.
|
421 |
+
for name in "pythoncom pywintypes".split():
|
422 |
+
keyname = "Software\\Python\\PythonCore\\" + sys.winver + "\\Modules\\" + name
|
423 |
+
for root in winreg.HKEY_LOCAL_MACHINE, winreg.HKEY_CURRENT_USER:
|
424 |
+
try:
|
425 |
+
winreg.DeleteKey(root, keyname + "\\Debug")
|
426 |
+
except WindowsError:
|
427 |
+
pass
|
428 |
+
try:
|
429 |
+
winreg.DeleteKey(root, keyname)
|
430 |
+
except WindowsError:
|
431 |
+
pass
|
432 |
+
LoadSystemModule(lib_dir, "pywintypes")
|
433 |
+
LoadSystemModule(lib_dir, "pythoncom")
|
434 |
+
import win32api
|
435 |
+
|
436 |
+
# and now we can get the system directory:
|
437 |
+
files = glob.glob(os.path.join(lib_dir, "pywin32_system32\\*.*"))
|
438 |
+
if not files:
|
439 |
+
raise RuntimeError("No system files to copy!!")
|
440 |
+
# Try the system32 directory first - if that fails due to "access denied",
|
441 |
+
# it implies a non-admin user, and we use sys.prefix
|
442 |
+
for dest_dir in [get_system_dir(), sys.prefix]:
|
443 |
+
# and copy some files over there
|
444 |
+
worked = 0
|
445 |
+
try:
|
446 |
+
for fname in files:
|
447 |
+
base = os.path.basename(fname)
|
448 |
+
dst = os.path.join(dest_dir, base)
|
449 |
+
CopyTo("installing %s" % base, fname, dst)
|
450 |
+
if verbose:
|
451 |
+
print("Copied %s to %s" % (base, dst))
|
452 |
+
# Register the files with the uninstaller
|
453 |
+
file_created(dst)
|
454 |
+
worked = 1
|
455 |
+
# Nuke any other versions that may exist - having
|
456 |
+
# duplicates causes major headaches.
|
457 |
+
bad_dest_dirs = [
|
458 |
+
os.path.join(sys.prefix, "Library\\bin"),
|
459 |
+
os.path.join(sys.prefix, "Lib\\site-packages\\win32"),
|
460 |
+
]
|
461 |
+
if dest_dir != sys.prefix:
|
462 |
+
bad_dest_dirs.append(sys.prefix)
|
463 |
+
for bad_dest_dir in bad_dest_dirs:
|
464 |
+
bad_fname = os.path.join(bad_dest_dir, base)
|
465 |
+
if os.path.exists(bad_fname):
|
466 |
+
# let exceptions go here - delete must succeed
|
467 |
+
os.unlink(bad_fname)
|
468 |
+
if worked:
|
469 |
+
break
|
470 |
+
except win32api.error as details:
|
471 |
+
if details.winerror == 5:
|
472 |
+
# access denied - user not admin - try sys.prefix dir,
|
473 |
+
# but first check that a version doesn't already exist
|
474 |
+
# in that place - otherwise that one will still get used!
|
475 |
+
if os.path.exists(dst):
|
476 |
+
msg = (
|
477 |
+
"The file '%s' exists, but can not be replaced "
|
478 |
+
"due to insufficient permissions. You must "
|
479 |
+
"reinstall this software as an Administrator" % dst
|
480 |
+
)
|
481 |
+
print(msg)
|
482 |
+
raise RuntimeError(msg)
|
483 |
+
continue
|
484 |
+
raise
|
485 |
+
else:
|
486 |
+
raise RuntimeError(
|
487 |
+
"You don't have enough permissions to install the system files"
|
488 |
+
)
|
489 |
+
|
490 |
+
# Pythonwin 'compiles' config files - record them for uninstall.
|
491 |
+
pywin_dir = os.path.join(lib_dir, "Pythonwin", "pywin")
|
492 |
+
for fname in glob.glob(os.path.join(pywin_dir, "*.cfg")):
|
493 |
+
file_created(fname[:-1] + "c") # .cfg->.cfc
|
494 |
+
|
495 |
+
# Register our demo COM objects.
|
496 |
+
try:
|
497 |
+
try:
|
498 |
+
RegisterCOMObjects()
|
499 |
+
except win32api.error as details:
|
500 |
+
if details.winerror != 5: # ERROR_ACCESS_DENIED
|
501 |
+
raise
|
502 |
+
print("You do not have the permissions to install COM objects.")
|
503 |
+
print("The sample COM objects were not registered.")
|
504 |
+
except Exception:
|
505 |
+
print("FAILED to register the Python COM objects")
|
506 |
+
traceback.print_exc()
|
507 |
+
|
508 |
+
# There may be no main Python key in HKCU if, eg, an admin installed
|
509 |
+
# python itself.
|
510 |
+
winreg.CreateKey(get_root_hkey(), root_key_name)
|
511 |
+
|
512 |
+
chm_file = None
|
513 |
+
try:
|
514 |
+
chm_file = RegisterHelpFile(True, lib_dir)
|
515 |
+
except Exception:
|
516 |
+
print("Failed to register help file")
|
517 |
+
traceback.print_exc()
|
518 |
+
else:
|
519 |
+
if verbose:
|
520 |
+
print("Registered help file")
|
521 |
+
|
522 |
+
# misc other fixups.
|
523 |
+
fixup_dbi()
|
524 |
+
|
525 |
+
# Register Pythonwin in context menu
|
526 |
+
try:
|
527 |
+
RegisterPythonwin(True, lib_dir)
|
528 |
+
except Exception:
|
529 |
+
print("Failed to register pythonwin as editor")
|
530 |
+
traceback.print_exc()
|
531 |
+
else:
|
532 |
+
if verbose:
|
533 |
+
print("Pythonwin has been registered in context menu")
|
534 |
+
|
535 |
+
# Create the win32com\gen_py directory.
|
536 |
+
make_dir = os.path.join(lib_dir, "win32com", "gen_py")
|
537 |
+
if not os.path.isdir(make_dir):
|
538 |
+
if verbose:
|
539 |
+
print("Creating directory %s" % (make_dir,))
|
540 |
+
directory_created(make_dir)
|
541 |
+
os.mkdir(make_dir)
|
542 |
+
|
543 |
+
try:
|
544 |
+
# create shortcuts
|
545 |
+
# CSIDL_COMMON_PROGRAMS only available works on NT/2000/XP, and
|
546 |
+
# will fail there if the user has no admin rights.
|
547 |
+
fldr = get_shortcuts_folder()
|
548 |
+
# If the group doesn't exist, then we don't make shortcuts - its
|
549 |
+
# possible that this isn't a "normal" install.
|
550 |
+
if os.path.isdir(fldr):
|
551 |
+
dst = os.path.join(fldr, "PythonWin.lnk")
|
552 |
+
create_shortcut(
|
553 |
+
os.path.join(lib_dir, "Pythonwin\\Pythonwin.exe"),
|
554 |
+
"The Pythonwin IDE",
|
555 |
+
dst,
|
556 |
+
"",
|
557 |
+
sys.prefix,
|
558 |
+
)
|
559 |
+
file_created(dst)
|
560 |
+
if verbose:
|
561 |
+
print("Shortcut for Pythonwin created")
|
562 |
+
# And the docs.
|
563 |
+
if chm_file:
|
564 |
+
dst = os.path.join(fldr, "Python for Windows Documentation.lnk")
|
565 |
+
doc = "Documentation for the PyWin32 extensions"
|
566 |
+
create_shortcut(chm_file, doc, dst)
|
567 |
+
file_created(dst)
|
568 |
+
if verbose:
|
569 |
+
print("Shortcut to documentation created")
|
570 |
+
else:
|
571 |
+
if verbose:
|
572 |
+
print("Can't install shortcuts - %r is not a folder" % (fldr,))
|
573 |
+
except Exception as details:
|
574 |
+
print(details)
|
575 |
+
|
576 |
+
# importing win32com.client ensures the gen_py dir created - not strictly
|
577 |
+
# necessary to do now, but this makes the installation "complete"
|
578 |
+
try:
|
579 |
+
import win32com.client # noqa
|
580 |
+
except ImportError:
|
581 |
+
# Don't let this error sound fatal
|
582 |
+
pass
|
583 |
+
print("The pywin32 extensions were successfully installed.")
|
584 |
+
|
585 |
+
if is_bdist_wininst:
|
586 |
+
# Open a web page with info about the .exe installers being deprecated.
|
587 |
+
import webbrowser
|
588 |
+
|
589 |
+
try:
|
590 |
+
webbrowser.open("https://mhammond.github.io/pywin32_installers.html")
|
591 |
+
except webbrowser.Error:
|
592 |
+
print("Please visit https://mhammond.github.io/pywin32_installers.html")
|
593 |
+
|
594 |
+
|
595 |
+
def uninstall(lib_dir):
|
596 |
+
# First ensure our system modules are loaded from pywin32_system, so
|
597 |
+
# we can remove the ones we copied...
|
598 |
+
LoadSystemModule(lib_dir, "pywintypes")
|
599 |
+
LoadSystemModule(lib_dir, "pythoncom")
|
600 |
+
|
601 |
+
try:
|
602 |
+
RegisterCOMObjects(False)
|
603 |
+
except Exception as why:
|
604 |
+
print("Failed to unregister COM objects: %s" % (why,))
|
605 |
+
|
606 |
+
try:
|
607 |
+
RegisterHelpFile(False, lib_dir)
|
608 |
+
except Exception as why:
|
609 |
+
print("Failed to unregister help file: %s" % (why,))
|
610 |
+
else:
|
611 |
+
if verbose:
|
612 |
+
print("Unregistered help file")
|
613 |
+
|
614 |
+
try:
|
615 |
+
RegisterPythonwin(False, lib_dir)
|
616 |
+
except Exception as why:
|
617 |
+
print("Failed to unregister Pythonwin: %s" % (why,))
|
618 |
+
else:
|
619 |
+
if verbose:
|
620 |
+
print("Unregistered Pythonwin")
|
621 |
+
|
622 |
+
try:
|
623 |
+
# remove gen_py directory.
|
624 |
+
gen_dir = os.path.join(lib_dir, "win32com", "gen_py")
|
625 |
+
if os.path.isdir(gen_dir):
|
626 |
+
shutil.rmtree(gen_dir)
|
627 |
+
if verbose:
|
628 |
+
print("Removed directory %s" % (gen_dir,))
|
629 |
+
|
630 |
+
# Remove pythonwin compiled "config" files.
|
631 |
+
pywin_dir = os.path.join(lib_dir, "Pythonwin", "pywin")
|
632 |
+
for fname in glob.glob(os.path.join(pywin_dir, "*.cfc")):
|
633 |
+
os.remove(fname)
|
634 |
+
|
635 |
+
# The dbi.pyd.old files we may have created.
|
636 |
+
try:
|
637 |
+
os.remove(os.path.join(lib_dir, "win32", "dbi.pyd.old"))
|
638 |
+
except os.error:
|
639 |
+
pass
|
640 |
+
try:
|
641 |
+
os.remove(os.path.join(lib_dir, "win32", "dbi_d.pyd.old"))
|
642 |
+
except os.error:
|
643 |
+
pass
|
644 |
+
|
645 |
+
except Exception as why:
|
646 |
+
print("Failed to remove misc files: %s" % (why,))
|
647 |
+
|
648 |
+
try:
|
649 |
+
fldr = get_shortcuts_folder()
|
650 |
+
for link in ("PythonWin.lnk", "Python for Windows Documentation.lnk"):
|
651 |
+
fqlink = os.path.join(fldr, link)
|
652 |
+
if os.path.isfile(fqlink):
|
653 |
+
os.remove(fqlink)
|
654 |
+
if verbose:
|
655 |
+
print("Removed %s" % (link,))
|
656 |
+
except Exception as why:
|
657 |
+
print("Failed to remove shortcuts: %s" % (why,))
|
658 |
+
# Now remove the system32 files.
|
659 |
+
files = glob.glob(os.path.join(lib_dir, "pywin32_system32\\*.*"))
|
660 |
+
# Try the system32 directory first - if that fails due to "access denied",
|
661 |
+
# it implies a non-admin user, and we use sys.prefix
|
662 |
+
try:
|
663 |
+
for dest_dir in [get_system_dir(), sys.prefix]:
|
664 |
+
# and copy some files over there
|
665 |
+
worked = 0
|
666 |
+
for fname in files:
|
667 |
+
base = os.path.basename(fname)
|
668 |
+
dst = os.path.join(dest_dir, base)
|
669 |
+
if os.path.isfile(dst):
|
670 |
+
try:
|
671 |
+
os.remove(dst)
|
672 |
+
worked = 1
|
673 |
+
if verbose:
|
674 |
+
print("Removed file %s" % (dst))
|
675 |
+
except Exception:
|
676 |
+
print("FAILED to remove %s" % (dst,))
|
677 |
+
if worked:
|
678 |
+
break
|
679 |
+
except Exception as why:
|
680 |
+
print("FAILED to remove system files: %s" % (why,))
|
681 |
+
|
682 |
+
|
683 |
+
# NOTE: If this script is run from inside the bdist_wininst created
|
684 |
+
# binary installer or uninstaller, the command line args are either
|
685 |
+
# '-install' or '-remove'.
|
686 |
+
|
687 |
+
# Important: From inside the binary installer this script MUST NOT
|
688 |
+
# call sys.exit() or raise SystemExit, otherwise not only this script
|
689 |
+
# but also the installer will terminate! (Is there a way to prevent
|
690 |
+
# this from the bdist_wininst C code?)
|
691 |
+
|
692 |
+
|
693 |
+
def verify_destination(location):
|
694 |
+
if not os.path.isdir(location):
|
695 |
+
raise argparse.ArgumentTypeError('Path "{}" does not exist!'.format(location))
|
696 |
+
return location
|
697 |
+
|
698 |
+
|
699 |
+
def main():
|
700 |
+
import argparse
|
701 |
+
|
702 |
+
parser = argparse.ArgumentParser(
|
703 |
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
704 |
+
description="""A post-install script for the pywin32 extensions.
|
705 |
+
|
706 |
+
* Typical usage:
|
707 |
+
|
708 |
+
> python pywin32_postinstall.py -install
|
709 |
+
|
710 |
+
If you installed pywin32 via a .exe installer, this should be run
|
711 |
+
automatically after installation, but if it fails you can run it again.
|
712 |
+
|
713 |
+
If you installed pywin32 via PIP, you almost certainly need to run this to
|
714 |
+
setup the environment correctly.
|
715 |
+
|
716 |
+
Execute with script with a '-install' parameter, to ensure the environment
|
717 |
+
is setup correctly.
|
718 |
+
""",
|
719 |
+
)
|
720 |
+
parser.add_argument(
|
721 |
+
"-install",
|
722 |
+
default=False,
|
723 |
+
action="store_true",
|
724 |
+
help="Configure the Python environment correctly for pywin32.",
|
725 |
+
)
|
726 |
+
parser.add_argument(
|
727 |
+
"-remove",
|
728 |
+
default=False,
|
729 |
+
action="store_true",
|
730 |
+
help="Try and remove everything that was installed or copied.",
|
731 |
+
)
|
732 |
+
parser.add_argument(
|
733 |
+
"-wait",
|
734 |
+
type=int,
|
735 |
+
help="Wait for the specified process to terminate before starting.",
|
736 |
+
)
|
737 |
+
parser.add_argument(
|
738 |
+
"-silent",
|
739 |
+
default=False,
|
740 |
+
action="store_true",
|
741 |
+
help='Don\'t display the "Abort/Retry/Ignore" dialog for files in use.',
|
742 |
+
)
|
743 |
+
parser.add_argument(
|
744 |
+
"-quiet",
|
745 |
+
default=False,
|
746 |
+
action="store_true",
|
747 |
+
help="Don't display progress messages.",
|
748 |
+
)
|
749 |
+
parser.add_argument(
|
750 |
+
"-destination",
|
751 |
+
default=sysconfig.get_paths()["platlib"],
|
752 |
+
type=verify_destination,
|
753 |
+
help="Location of the PyWin32 installation",
|
754 |
+
)
|
755 |
+
|
756 |
+
args = parser.parse_args()
|
757 |
+
|
758 |
+
if not args.quiet:
|
759 |
+
print("Parsed arguments are: {}".format(args))
|
760 |
+
|
761 |
+
if not args.install ^ args.remove:
|
762 |
+
parser.error("You need to either choose to -install or -remove!")
|
763 |
+
|
764 |
+
if args.wait is not None:
|
765 |
+
try:
|
766 |
+
os.waitpid(args.wait, 0)
|
767 |
+
except os.error:
|
768 |
+
# child already dead
|
769 |
+
pass
|
770 |
+
|
771 |
+
silent = args.silent
|
772 |
+
verbose = not args.quiet
|
773 |
+
|
774 |
+
if args.install:
|
775 |
+
install(args.destination)
|
776 |
+
|
777 |
+
if args.remove:
|
778 |
+
if not is_bdist_wininst:
|
779 |
+
uninstall(args.destination)
|
780 |
+
|
781 |
+
|
782 |
+
if __name__ == "__main__":
|
783 |
+
main()
|
tars-env/Scripts/pywin32_testall.py
ADDED
@@ -0,0 +1,124 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""A test runner for pywin32"""
|
2 |
+
import os
|
3 |
+
import site
|
4 |
+
import subprocess
|
5 |
+
import sys
|
6 |
+
|
7 |
+
# locate the dirs based on where this script is - it may be either in the
|
8 |
+
# source tree, or in an installed Python 'Scripts' tree.
|
9 |
+
this_dir = os.path.dirname(__file__)
|
10 |
+
site_packages = [
|
11 |
+
site.getusersitepackages(),
|
12 |
+
] + site.getsitepackages()
|
13 |
+
|
14 |
+
failures = []
|
15 |
+
|
16 |
+
|
17 |
+
# Run a test using subprocess and wait for the result.
|
18 |
+
# If we get an returncode != 0, we know that there was an error, but we don't
|
19 |
+
# abort immediately - we run as many tests as we can.
|
20 |
+
def run_test(script, cmdline_extras):
|
21 |
+
dirname, scriptname = os.path.split(script)
|
22 |
+
# some tests prefer to be run from their directory.
|
23 |
+
cmd = [sys.executable, "-u", scriptname] + cmdline_extras
|
24 |
+
print("--- Running '%s' ---" % script)
|
25 |
+
sys.stdout.flush()
|
26 |
+
result = subprocess.run(cmd, check=False, cwd=dirname)
|
27 |
+
print("*** Test script '%s' exited with %s" % (script, result.returncode))
|
28 |
+
sys.stdout.flush()
|
29 |
+
if result.returncode:
|
30 |
+
failures.append(script)
|
31 |
+
|
32 |
+
|
33 |
+
def find_and_run(possible_locations, extras):
|
34 |
+
for maybe in possible_locations:
|
35 |
+
if os.path.isfile(maybe):
|
36 |
+
run_test(maybe, extras)
|
37 |
+
break
|
38 |
+
else:
|
39 |
+
raise RuntimeError(
|
40 |
+
"Failed to locate a test script in one of %s" % possible_locations
|
41 |
+
)
|
42 |
+
|
43 |
+
|
44 |
+
def main():
|
45 |
+
import argparse
|
46 |
+
|
47 |
+
code_directories = [this_dir] + site_packages
|
48 |
+
|
49 |
+
parser = argparse.ArgumentParser(
|
50 |
+
description="A script to trigger tests in all subprojects of PyWin32."
|
51 |
+
)
|
52 |
+
parser.add_argument(
|
53 |
+
"-no-user-interaction",
|
54 |
+
default=False,
|
55 |
+
action="store_true",
|
56 |
+
help="(This is now the default - use `-user-interaction` to include them)",
|
57 |
+
)
|
58 |
+
|
59 |
+
parser.add_argument(
|
60 |
+
"-user-interaction",
|
61 |
+
action="store_true",
|
62 |
+
help="Include tests which require user interaction",
|
63 |
+
)
|
64 |
+
|
65 |
+
parser.add_argument(
|
66 |
+
"-skip-adodbapi",
|
67 |
+
default=False,
|
68 |
+
action="store_true",
|
69 |
+
help="Skip the adodbapi tests; useful for CI where there's no provider",
|
70 |
+
)
|
71 |
+
|
72 |
+
args, remains = parser.parse_known_args()
|
73 |
+
|
74 |
+
# win32, win32ui / Pythonwin
|
75 |
+
|
76 |
+
extras = []
|
77 |
+
if args.user_interaction:
|
78 |
+
extras += ["-user-interaction"]
|
79 |
+
extras.extend(remains)
|
80 |
+
scripts = [
|
81 |
+
"win32/test/testall.py",
|
82 |
+
"Pythonwin/pywin/test/all.py",
|
83 |
+
]
|
84 |
+
for script in scripts:
|
85 |
+
maybes = [os.path.join(directory, script) for directory in code_directories]
|
86 |
+
find_and_run(maybes, extras)
|
87 |
+
|
88 |
+
# win32com
|
89 |
+
maybes = [
|
90 |
+
os.path.join(directory, "win32com", "test", "testall.py")
|
91 |
+
for directory in [
|
92 |
+
os.path.join(this_dir, "com"),
|
93 |
+
]
|
94 |
+
+ site_packages
|
95 |
+
]
|
96 |
+
extras = remains + ["1"] # only run "level 1" tests in CI
|
97 |
+
find_and_run(maybes, extras)
|
98 |
+
|
99 |
+
# adodbapi
|
100 |
+
if not args.skip_adodbapi:
|
101 |
+
maybes = [
|
102 |
+
os.path.join(directory, "adodbapi", "test", "adodbapitest.py")
|
103 |
+
for directory in code_directories
|
104 |
+
]
|
105 |
+
find_and_run(maybes, remains)
|
106 |
+
# This script has a hard-coded sql server name in it, (and markh typically
|
107 |
+
# doesn't have a different server to test on) but there is now supposed to be a server out there on the Internet
|
108 |
+
# just to run these tests, so try it...
|
109 |
+
maybes = [
|
110 |
+
os.path.join(directory, "adodbapi", "test", "test_adodbapi_dbapi20.py")
|
111 |
+
for directory in code_directories
|
112 |
+
]
|
113 |
+
find_and_run(maybes, remains)
|
114 |
+
|
115 |
+
if failures:
|
116 |
+
print("The following scripts failed")
|
117 |
+
for failure in failures:
|
118 |
+
print(">", failure)
|
119 |
+
sys.exit(1)
|
120 |
+
print("All tests passed \\o/")
|
121 |
+
|
122 |
+
|
123 |
+
if __name__ == "__main__":
|
124 |
+
main()
|
tars-env/Scripts/tqdm.exe
ADDED
Binary file (108 kB). View file
|
|
tars-env/Scripts/ttx.exe
ADDED
Binary file (108 kB). View file
|
|
tars-env/Scripts/upload_theme.exe
ADDED
Binary file (108 kB). View file
|
|
tars-env/Scripts/uvicorn.exe
ADDED
Binary file (108 kB). View file
|
|
tars-env/pyvenv.cfg
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
home = C:\Users\Frank\AppData\Local\Programs\Python\Python311
|
2 |
+
include-system-site-packages = false
|
3 |
+
version = 3.11.3
|
4 |
+
executable = C:\Users\Frank\AppData\Local\Programs\Python\Python311\python.exe
|
5 |
+
command = C:\Users\Frank\AppData\Local\Programs\Python\Python311\python.exe -m venv C:\Users\Frank\TARS\tars-env
|
tars-env/share/man/man1/ttx.1
ADDED
@@ -0,0 +1,225 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.Dd May 18, 2004
|
2 |
+
.\" ttx is not specific to any OS, but contrary to what groff_mdoc(7)
|
3 |
+
.\" seems to imply, entirely omitting the .Os macro causes 'BSD' to
|
4 |
+
.\" be used, so I give a zero-width space as its argument.
|
5 |
+
.Os \&
|
6 |
+
.\" The "FontTools Manual" argument apparently has no effect in
|
7 |
+
.\" groff 1.18.1. I think it is a bug in the -mdoc groff package.
|
8 |
+
.Dt TTX 1 "FontTools Manual"
|
9 |
+
.Sh NAME
|
10 |
+
.Nm ttx
|
11 |
+
.Nd tool for manipulating TrueType and OpenType fonts
|
12 |
+
.Sh SYNOPSIS
|
13 |
+
.Nm
|
14 |
+
.Bk
|
15 |
+
.Op Ar option ...
|
16 |
+
.Ek
|
17 |
+
.Bk
|
18 |
+
.Ar file ...
|
19 |
+
.Ek
|
20 |
+
.Sh DESCRIPTION
|
21 |
+
.Nm
|
22 |
+
is a tool for manipulating TrueType and OpenType fonts. It can convert
|
23 |
+
TrueType and OpenType fonts to and from an
|
24 |
+
.Tn XML Ns -based format called
|
25 |
+
.Tn TTX .
|
26 |
+
.Tn TTX
|
27 |
+
files have a
|
28 |
+
.Ql .ttx
|
29 |
+
extension.
|
30 |
+
.Pp
|
31 |
+
For each
|
32 |
+
.Ar file
|
33 |
+
argument it is given,
|
34 |
+
.Nm
|
35 |
+
detects whether it is a
|
36 |
+
.Ql .ttf ,
|
37 |
+
.Ql .otf
|
38 |
+
or
|
39 |
+
.Ql .ttx
|
40 |
+
file and acts accordingly: if it is a
|
41 |
+
.Ql .ttf
|
42 |
+
or
|
43 |
+
.Ql .otf
|
44 |
+
file, it generates a
|
45 |
+
.Ql .ttx
|
46 |
+
file; if it is a
|
47 |
+
.Ql .ttx
|
48 |
+
file, it generates a
|
49 |
+
.Ql .ttf
|
50 |
+
or
|
51 |
+
.Ql .otf
|
52 |
+
file.
|
53 |
+
.Pp
|
54 |
+
By default, every output file is created in the same directory as the
|
55 |
+
corresponding input file and with the same name except for the
|
56 |
+
extension, which is substituted appropriately.
|
57 |
+
.Nm
|
58 |
+
never overwrites existing files; if necessary, it appends a suffix to
|
59 |
+
the output file name before the extension, as in
|
60 |
+
.Pa Arial#1.ttf .
|
61 |
+
.Ss "General options"
|
62 |
+
.Bl -tag -width ".Fl t Ar table"
|
63 |
+
.It Fl h
|
64 |
+
Display usage information.
|
65 |
+
.It Fl d Ar dir
|
66 |
+
Write the output files to directory
|
67 |
+
.Ar dir
|
68 |
+
instead of writing every output file to the same directory as the
|
69 |
+
corresponding input file.
|
70 |
+
.It Fl o Ar file
|
71 |
+
Write the output to
|
72 |
+
.Ar file
|
73 |
+
instead of writing it to the same directory as the
|
74 |
+
corresponding input file.
|
75 |
+
.It Fl v
|
76 |
+
Be verbose. Write more messages to the standard output describing what
|
77 |
+
is being done.
|
78 |
+
.It Fl a
|
79 |
+
Allow virtual glyphs ID's on compile or decompile.
|
80 |
+
.El
|
81 |
+
.Ss "Dump options"
|
82 |
+
The following options control the process of dumping font files
|
83 |
+
(TrueType or OpenType) to
|
84 |
+
.Tn TTX
|
85 |
+
files.
|
86 |
+
.Bl -tag -width ".Fl t Ar table"
|
87 |
+
.It Fl l
|
88 |
+
List table information. Instead of dumping the font to a
|
89 |
+
.Tn TTX
|
90 |
+
file, display minimal information about each table.
|
91 |
+
.It Fl t Ar table
|
92 |
+
Dump table
|
93 |
+
.Ar table .
|
94 |
+
This option may be given multiple times to dump several tables at
|
95 |
+
once. When not specified, all tables are dumped.
|
96 |
+
.It Fl x Ar table
|
97 |
+
Exclude table
|
98 |
+
.Ar table
|
99 |
+
from the list of tables to dump. This option may be given multiple
|
100 |
+
times to exclude several tables from the dump. The
|
101 |
+
.Fl t
|
102 |
+
and
|
103 |
+
.Fl x
|
104 |
+
options are mutually exclusive.
|
105 |
+
.It Fl s
|
106 |
+
Split tables. Dump each table to a separate
|
107 |
+
.Tn TTX
|
108 |
+
file and write (under the name that would have been used for the output
|
109 |
+
file if the
|
110 |
+
.Fl s
|
111 |
+
option had not been given) one small
|
112 |
+
.Tn TTX
|
113 |
+
file containing references to the individual table dump files. This
|
114 |
+
file can be used as input to
|
115 |
+
.Nm
|
116 |
+
as long as the referenced files can be found in the same directory.
|
117 |
+
.It Fl i
|
118 |
+
.\" XXX: I suppose OpenType programs (exist and) are also affected.
|
119 |
+
Don't disassemble TrueType instructions. When this option is specified,
|
120 |
+
all TrueType programs (glyph programs, the font program and the
|
121 |
+
pre-program) are written to the
|
122 |
+
.Tn TTX
|
123 |
+
file as hexadecimal data instead of
|
124 |
+
assembly. This saves some time and results in smaller
|
125 |
+
.Tn TTX
|
126 |
+
files.
|
127 |
+
.It Fl y Ar n
|
128 |
+
When decompiling a TrueType Collection (TTC) file,
|
129 |
+
decompile font number
|
130 |
+
.Ar n ,
|
131 |
+
starting from 0.
|
132 |
+
.El
|
133 |
+
.Ss "Compilation options"
|
134 |
+
The following options control the process of compiling
|
135 |
+
.Tn TTX
|
136 |
+
files into font files (TrueType or OpenType):
|
137 |
+
.Bl -tag -width ".Fl t Ar table"
|
138 |
+
.It Fl m Ar fontfile
|
139 |
+
Merge the input
|
140 |
+
.Tn TTX
|
141 |
+
file
|
142 |
+
.Ar file
|
143 |
+
with
|
144 |
+
.Ar fontfile .
|
145 |
+
No more than one
|
146 |
+
.Ar file
|
147 |
+
argument can be specified when this option is used.
|
148 |
+
.It Fl b
|
149 |
+
Don't recalculate glyph bounding boxes. Use the values in the
|
150 |
+
.Tn TTX
|
151 |
+
file as is.
|
152 |
+
.El
|
153 |
+
.Sh "THE TTX FILE FORMAT"
|
154 |
+
You can find some information about the
|
155 |
+
.Tn TTX
|
156 |
+
file format in
|
157 |
+
.Pa documentation.html .
|
158 |
+
In particular, you will find in that file the list of tables understood by
|
159 |
+
.Nm
|
160 |
+
and the relations between TrueType GlyphIDs and the glyph names used in
|
161 |
+
.Tn TTX
|
162 |
+
files.
|
163 |
+
.Sh EXAMPLES
|
164 |
+
In the following examples, all files are read from and written to the
|
165 |
+
current directory. Additionally, the name given for the output file
|
166 |
+
assumes in every case that it did not exist before
|
167 |
+
.Nm
|
168 |
+
was invoked.
|
169 |
+
.Pp
|
170 |
+
Dump the TrueType font contained in
|
171 |
+
.Pa FreeSans.ttf
|
172 |
+
to
|
173 |
+
.Pa FreeSans.ttx :
|
174 |
+
.Pp
|
175 |
+
.Dl ttx FreeSans.ttf
|
176 |
+
.Pp
|
177 |
+
Compile
|
178 |
+
.Pa MyFont.ttx
|
179 |
+
into a TrueType or OpenType font file:
|
180 |
+
.Pp
|
181 |
+
.Dl ttx MyFont.ttx
|
182 |
+
.Pp
|
183 |
+
List the tables in
|
184 |
+
.Pa FreeSans.ttf
|
185 |
+
along with some information:
|
186 |
+
.Pp
|
187 |
+
.Dl ttx -l FreeSans.ttf
|
188 |
+
.Pp
|
189 |
+
Dump the
|
190 |
+
.Sq cmap
|
191 |
+
table from
|
192 |
+
.Pa FreeSans.ttf
|
193 |
+
to
|
194 |
+
.Pa FreeSans.ttx :
|
195 |
+
.Pp
|
196 |
+
.Dl ttx -t cmap FreeSans.ttf
|
197 |
+
.Sh NOTES
|
198 |
+
On MS\-Windows and MacOS,
|
199 |
+
.Nm
|
200 |
+
is available as a graphical application to which files can be dropped.
|
201 |
+
.Sh SEE ALSO
|
202 |
+
.Pa documentation.html
|
203 |
+
.Pp
|
204 |
+
.Xr fontforge 1 ,
|
205 |
+
.Xr ftinfo 1 ,
|
206 |
+
.Xr gfontview 1 ,
|
207 |
+
.Xr xmbdfed 1 ,
|
208 |
+
.Xr Font::TTF 3pm
|
209 |
+
.Sh AUTHORS
|
210 |
+
.Nm
|
211 |
+
was written by
|
212 |
+
.An -nosplit
|
213 |
+
.An "Just van Rossum" Aq just@letterror.com .
|
214 |
+
.Pp
|
215 |
+
This manual page was written by
|
216 |
+
.An "Florent Rougon" Aq f.rougon@free.fr
|
217 |
+
for the Debian GNU/Linux system based on the existing FontTools
|
218 |
+
documentation. It may be freely used, modified and distributed without
|
219 |
+
restrictions.
|
220 |
+
.\" For Emacs:
|
221 |
+
.\" Local Variables:
|
222 |
+
.\" fill-column: 72
|
223 |
+
.\" sentence-end: "[.?!][]\"')}]*\\($\\| $\\| \\| \\)[ \n]*"
|
224 |
+
.\" sentence-end-double-space: t
|
225 |
+
.\" End:
|