-
Notifications
You must be signed in to change notification settings - Fork 26
/
setup.py
233 lines (194 loc) · 7.93 KB
/
setup.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# Copyright 2018-2023 Jetperch LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Joulescope python setuptools module.
See:
https://packaging.python.org/en/latest/distributing.html
https://github.com/pypa/sampleproject
"""
# Always prefer setuptools over distutils
import setuptools
from setuptools.command.sdist import sdist
from setuptools.command.develop import develop
import os
import platform
import sys
import subprocess
import shutil
MYPATH = os.path.abspath(os.path.dirname(__file__))
VERSION_PATH = os.path.join(MYPATH, 'joulescope_ui', 'version.py')
def qt_rcc_path():
# As of PySide 5.15.0, the pySide6-rcc executable ignores the --binary flag
import PySide6
path = os.path.dirname(PySide6.__file__)
fname = [n for n in os.listdir(path) if n.startswith('rcc')]
if len(fname) == 1:
fname = os.path.join(path, fname[0])
if os.path.isfile(fname):
return fname
if platform.system() in ['Darwin', 'Linux']:
fname = os.path.join(path, 'Qt', 'libexec', 'rcc')
if os.path.isfile(fname):
return fname
raise ValueError('Could not find rcc executable')
def convert_qt_ui():
uic_path = shutil.which('pyside6-uic')
rcc_path = qt_rcc_path()
path = os.path.join(MYPATH, 'joulescope_ui')
ignore_filename = os.path.join(path, '.gitignore')
with open(ignore_filename, 'w', encoding='utf-8') as ignore:
ignore.write('# Automatically generated. DO NOT EDIT\n')
for root, d_names, f_names in os.walk(path):
for source in f_names:
_, ext = os.path.splitext(source)
if ext == '.ui':
source = os.path.join(root, source)
target = os.path.splitext(source)[0] + '.py'
print(f'Generate {os.path.relpath(target, MYPATH)}')
rc = subprocess.run([uic_path, source], stdout=subprocess.PIPE)
s = rc.stdout.replace(b'\r\n', b'\n').decode('utf-8')
s = s.replace('\nimport joulescope_rc\n', '\nfrom joulescope_ui import joulescope_rc\n')
with open(target, 'w', encoding='utf-8') as ftarget:
ftarget.write(s)
elif ext == '.qrc':
src = os.path.join(root, source)
target = os.path.join(os.path.dirname(root), source)
target = os.path.splitext(target)[0] + '.rcc'
print(f'Generate {os.path.relpath(target, MYPATH)}')
rc = subprocess.run([rcc_path, src, '--binary', '--threshold', '33', '-o', target])
if rc.returncode:
raise RuntimeError('failed on .qrc file')
else:
continue
ignore_entry = os.path.relpath(target, path).replace('\\', '/')
ignore.write('%s\n' % ignore_entry)
def _version_get():
with open(VERSION_PATH, 'r', encoding='utf-8') as fv:
for line in fv:
if line.startswith('__version__'):
return line.split('=')[-1].strip()[1:-1]
raise RuntimeError('VERSION not found!')
def update_inno_iss():
version = _version_get()
path = os.path.join(MYPATH, 'joulescope.iss')
with open(path, 'r', encoding='utf-8') as fv:
lines = fv.readlines()
version_underscore = version.replace('.', '_')
for idx, line in enumerate(lines):
if line.startswith('#define MyAppVersionUnderscores'):
lines[idx] = f'#define MyAppVersionUnderscores "{version_underscore}"\n'
elif line.startswith('#define MyAppVersion'):
lines[idx] = f'#define MyAppVersion "{version}"\n'
with open(path, 'w', encoding='utf-8') as fv:
fv.write(''.join(lines))
class CustomDevelopCommand(develop):
"""Custom develop command to build Qt resource file and Qt user interface modules."""
def run(self):
develop.run(self)
convert_qt_ui()
class CustomSdistCommand(sdist):
def run(self):
update_inno_iss()
convert_qt_ui()
sdist.run(self)
if sys.platform.startswith('win'):
PLATFORM_INSTALL_REQUIRES = ['pywin32']
else:
PLATFORM_INSTALL_REQUIRES = []
# Get the long description from the README file
with open(os.path.join(MYPATH, 'README.md'), encoding='utf-8') as f:
long_description = f.read()
setuptools.setup(
name='joulescope_ui',
version=_version_get(),
description='Joulescope™ graphical user interface',
long_description=long_description,
long_description_content_type='text/markdown',
url='https://www.joulescope.com',
author='Jetperch LLC',
author_email='[email protected]',
license='Apache 2.0',
cmdclass={
'develop': CustomDevelopCommand,
'sdist': CustomSdistCommand,
},
# Classifiers help users find your project by categorizing it.
#
# For a list of valid classifiers, see https://pypi.org/classifiers/
classifiers=[ # Optional
'Development Status :: 5 - Production/Stable',
# Indicate who your project is intended for
'Intended Audience :: Developers',
'Intended Audience :: End Users/Desktop',
'Intended Audience :: Science/Research',
# Pick your license as you wish
'License :: OSI Approved :: Apache Software License',
# Natural Language
'Natural Language :: English',
# Operating systems
'Operating System :: Microsoft :: Windows :: Windows 10',
'Operating System :: Microsoft :: Windows :: Windows 11',
'Operating System :: MacOS',
'Operating System :: MacOS :: MacOS X',
'Operating System :: POSIX :: Linux',
# Supported Python versions
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
'Programming Language :: Python :: 3.13',
# Topics
'Topic :: Scientific/Engineering',
'Topic :: Software Development :: Embedded Systems',
'Topic :: Software Development :: Testing',
'Topic :: Utilities',
],
keywords='joulescope ui gui "user interface"',
packages=setuptools.find_packages(exclude=['docs', 'test', 'dist', 'build']),
include_package_data=True,
# See https://packaging.python.org/guides/distributing-packages-using-setuptools/#python-requires
python_requires='~=3.10',
# See https://packaging.python.org/en/latest/requirements.html
install_requires=[
'appnope>=0.1.2,<1',
'fs>=2.4.16,<3',
'pyjoulescope_driver>=1.7.0,<2',
'joulescope>=1.2.0,<2',
'markdown>=3,<4',
'psutil>=5,<6',
'pyjls>=0.11.0,<1',
'pyopengl>=3,<4',
"pywin32>=223; platform_system == 'Windows'",
'pyqtgraph>=0.13.6,<1',
'PySide6>=6.8.0,<7',
'PySide6-QtAds>=4.3.1.1,<5',
'python-dateutil>=2.7.3,<3',
'QtPy>=2,<3',
'requests>=2,<3',
'watchdog>=4,<5',
] + PLATFORM_INSTALL_REQUIRES,
extras_require={
'dev': ['check-manifest', 'coverage', 'Cython', 'pyinstaller', 'wheel'],
},
entry_points={
'gui_scripts': [
'joulescope_ui=joulescope_ui.main:run',
],
},
project_urls={
'Bug Reports': 'https://github.com/jetperch/pyjoulescope_ui/issues',
'Funding': 'https://www.joulescope.com',
'Twitter': 'https://twitter.com/joulescope',
'Source': 'https://github.com/jetperch/pyjoulescope_ui/',
},
)