-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathinstall.py
173 lines (133 loc) · 9.15 KB
/
install.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
import os
import re
import shutil
import urllib.request
import vs
# DLIBRARY INSTALL FILE ################################################################################################
# You can use this installation file for your own plugins, just fill in the variables in the SETUP part. ###############
# An install script must go at the top level of your .zip file in order for Vectorworks to pick it up. For more ########
# information about install files, see: http://developer.vectorworks.net/index.php/VS:Implementing_Installation_Script #
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #
# VW has a bug, when just started, some vs functions aren't available yet, like vs.GetFolder. To overcome this, the #
# script in the install.vwx file has to be run first, and then the user have to install the plugin without restarting #
# Vectorworks. #
########################################################################################################################
# SETUP ################################################################################################################
plugin_name = 'MyPluginNameAndFolderNameInZipFile'
dlibrary_version = '2016.4.0'
include_choose_custom_install_folder = True
include_update_or_install_dlibrary = True
# SOME COMMON METHODS, AS WE CAN'T RELY ON DLIBRARY YET ################################################################
def get_os_independent_path(path: str) -> str:
"""
Patrick Stanford <[email protected]> on the VectorScript Discussion List:
Since Mac OS 10, as they're rewritten it using UNIX kernel, the mac uses Posix natively.
Since VW predates that, the old calls use HFS paths and need to be converted for newer APIs.
You can ask VW to do the conversion, as simply replacing the characters are not enough (Posix uses volume mounting
instead of drive names). This can be done through vs.ConvertHSF2PosixPath().
"""
major, minor, maintenance, platform = vs.GetVersion()
succeeded, path = vs.ConvertHSF2PosixPath(path) if platform == 1 else (False, path)
return path
def get_folder(initial_folder: str, message: str) -> str:
closed_with, chosen_folder = vs.GetFolder(message)
return get_os_independent_path(chosen_folder) if closed_with == 0 else initial_folder
def get_user_plugin_folder_path() -> str:
return get_os_independent_path(vs.GetFolderPath(-2))
# SET DESTINATION FOLDER ###############################################################################################
def choose_custom_install_folder(plugin_folder_name: str):
def ask_where_to_install() -> int:
return vs.AlertQuestion(
'Vectorworks installed %s in your user folder, is this ok?' % plugin_name, '', 1, 'Yes',
'No, it\'s already installed elsewhere, delete from user folder',
'No, I want to choose a folder to copy %s to.' % plugin_name, '')
def copy_to_custom_folder():
user_plugin_folder = get_user_plugin_folder_path()
custom_folder_path = get_folder(user_plugin_folder, 'Please select your custom installation folder.')
if custom_folder_path != user_plugin_folder: # Only if another folder was chosen, or not cancelled!
custom_folder = os.path.join(custom_folder_path, plugin_folder_name)
shutil.rmtree(custom_folder) if os.path.exists(custom_folder) else None
shutil.move(os.path.join(user_plugin_folder, plugin_folder_name), custom_folder_path)
vs.AlrtDialog('Don\'t forget to tell Vectorworks about your custom folder!')
def delete_from_user_folder():
shutil.rmtree(os.path.join(get_user_plugin_folder_path(), plugin_folder_name))
{
1: lambda : None, # We don't need to do anything if the default is ok.
2: copy_to_custom_folder, # If user want to install in custom folder.
0: delete_from_user_folder # If user already installed the plugin somewhere.
}.get(ask_where_to_install())()
# DLIBRARY INSTALL #####################################################################################################
# Update or install DLibrary and ad it to the Python search paths. Off course we need to check the version that could ##
# be already installed, and only install if a newer version is required. ###############################################
def update_or_install_dlibrary(required_version: str):
class DLibraryProgressBar(object):
def __init__(self, required_version: str):
self.__required_version = required_version
def start(self):
vs.AlrtDialog('We\'ll start installing `dlibrary`. This can take a while.')
vs.ProgressDlgOpen('DLibrary installation', False)
vs.ProgressDlgSetMeter('Installing dlibrary v%s...' % self.__required_version)
def report(self, block_nr, read_size, total_size):
vs.ProgressDlgStart(98, total_size/read_size) if block_nr == 0 else None
vs.ProgressDlgYield(1) if block_nr > 0 else None
def end(self):
vs.ProgressDlgClose()
def get_unzipped_dir(libraries_folder: str):
unzipped_repo_folders = [f for f in os.listdir(libraries_folder) if f.startswith('dlibrary-')]
return unzipped_repo_folders[0] if len(unzipped_repo_folders) > 0 else ''
def install_dlibrary(libraries_folder: str):
dlibrary_url = 'https://github.com/dietergeerts/dlibrary/archive/%s.zip' % required_version
dlibrary_zip = os.path.join(libraries_folder, 'dlibrary_repo.zip')
progress_bar = DLibraryProgressBar(required_version)
# noinspection PyBroadException
try:
progress_bar.start()
urllib.request.urlretrieve(dlibrary_url, dlibrary_zip, progress_bar.report)
shutil.unpack_archive(dlibrary_zip, libraries_folder)
unzipped_dir = get_unzipped_dir(libraries_folder)
shutil.move(os.path.join(libraries_folder, unzipped_dir, 'dlibrary'), libraries_folder)
except:
vs.AlrtDialog('The library `dlibrary` couldn\'t be downloaded. Please install it manually.')
finally:
unzipped_dir = get_unzipped_dir(libraries_folder)
shutil.rmtree(os.path.join(libraries_folder, unzipped_dir)) if unzipped_dir != '' else None
os.remove(dlibrary_zip) if os.path.exists(dlibrary_zip) else None
progress_bar.end()
def update_dlibrary(libraries_folder: str):
shutil.rmtree(os.path.join(libraries_folder, 'dlibrary'))
install_dlibrary(libraries_folder)
def update_dlibrary_needed(libraries_folder: str) -> bool:
with open(os.path.join(libraries_folder, 'dlibrary', '__init__.py')) as package_file:
pkg_info = package_file.read()
version_info = [int(info) for info in re.search(r'__version__ = \'.+?\'', pkg_info).group(0)[15:-1].split('.')]
version_info_needed = [int(info) for info in required_version.split('.')]
# Version info like [2015, 0, 0]
return False if version_info[0] > version_info_needed[0] else (
True if version_info[0] < version_info_needed[0] else (
False if version_info[1] > version_info_needed[1] else (
True if version_info[1] < version_info_needed[1] else (
False if version_info[2] > version_info_needed[2] else (
True if version_info[2] < version_info_needed[2] else False)))))
def try_update(install_path: str):
update_dlibrary(install_path) if update_dlibrary_needed(install_path) else None
def update_or_install(install_path: str):
update = os.path.exists(os.path.join(install_path, 'dlibrary'))
try_update(install_path) if update else install_dlibrary(install_path)
def update_python_search_path(libraries_folder: str):
search_path = vs.PythonGetSearchPath()
library_path = os.path.join(libraries_folder, '')
if library_path not in search_path.split(';'):
vs.PythonSetSearchPath('%s%s' % (search_path, library_path))
# The alert dialog is here because this message in the title of the get folder modal isn't very clear!
vs.AlrtDialog('%s depends on the `dlibrary` library, vesion %s. Please select '
'its parent folder in the next dialog.' % (plugin_name, required_version))
dlibrary_path = get_folder('', '%s depends on the `dlibrary` library, vesion %s. Please select '
'its parent folder.' % (plugin_name, required_version))
# If a folder was chosen or not cancelled!
if dlibrary_path != '':
update_or_install(dlibrary_path)
update_python_search_path(dlibrary_path)
# INSTALLATION STEPS ###################################################################################################
# VW always copies the plugin folder, which is inside the zip file, to the users' plugin folder = initial install step!#
choose_custom_install_folder(plugin_name) if include_choose_custom_install_folder else None
update_or_install_dlibrary(dlibrary_version) if include_update_or_install_dlibrary else None