1 | """ |
||
2 | Install skin is the plugin to handle the installation of skins. |
||
3 | |||
4 | This can be done various providers; from basic local folders, |
||
5 | up to server-side providers like DeviantArt or GitHub. |
||
6 | """ |
||
7 | |||
8 | |||
9 | import os.path |
||
10 | # import shutil |
||
11 | # import tempfile |
||
12 | # import zipfile |
||
13 | |||
14 | import sublime |
||
15 | import sublime_plugin |
||
16 | |||
17 | # from .logger import info, error |
||
18 | |||
19 | from .web.online_checker import is_gh_online |
||
20 | # from .web.content_downloader import download_from_to |
||
21 | from .install import from_folder |
||
22 | from .install import from_zip |
||
23 | # from .path.skin_path_provider import get_cached_skin_path |
||
24 | |||
25 | |||
26 | GITHUB_ACCESS_TOKEN = "3e2e92777aab20a3352c058f9a8eb10e5ff5fd61" |
||
27 | |||
28 | |||
29 | # def install_zip_into_skins_folder(zip_file): |
||
30 | # with zipfile.ZipFile(zip_file) as zipped_skin: |
||
31 | # skins_path = get_cached_skin_path() |
||
32 | # info("Found skins path in '" + skins_path + "'.") |
||
33 | |||
34 | # zip_name = zip_file.rsplit('/', 1)[-1] |
||
35 | |||
36 | # folder_name, dummy_ext = os.path.splitext(zip_name) |
||
37 | # info("Skin folder name will be '" + folder_name + "'.") |
||
38 | |||
39 | # skin_path = os.path.join(skins_path, folder_name) |
||
40 | # skin_path = minify_folder(skin_path) |
||
41 | # info("Extracting zip from '" + zip_file + "' to '" + skin_path + "'.") |
||
42 | |||
43 | # zipped_skin.extractall(skin_path) |
||
44 | |||
45 | # sublime.message_dialog("Successfully installed skin into '" + skin_path + "'!") |
||
46 | |||
47 | # return True |
||
48 | |||
49 | |||
50 | # def minify_folder(folder_path): |
||
51 | # """ |
||
52 | # Reduce unnecessary depth of folder structures for skins. |
||
53 | |||
54 | # If you install a skin via a ZIP if could be that in the zip |
||
55 | # an additional folder is already wrapped around like via Github |
||
56 | # and thus we can remove that layer to reduce the depth to the real skin files. |
||
57 | # """ |
||
58 | # content_names = os.listdir(folder_path) |
||
59 | # while len(content_names) == 1: |
||
60 | # content_path = os.path.join(folder_path, content_names[0]) |
||
61 | |||
62 | # if os.path.isdir(content_path): |
||
63 | # content_paths = [os.path.join(content_path, file_name) for file_name in os.listdir(content_path)] |
||
64 | |||
65 | # for f in content_paths: |
||
66 | # shutil.move(f, folder_path) |
||
67 | |||
68 | # os.rmdir(content_path) |
||
69 | |||
70 | # # reset for while recursion |
||
71 | # content_names = os.listdir(folder_path) |
||
72 | |||
73 | # return folder_path |
||
74 | |||
75 | |||
76 | # def count_folders_in_folder(folder_path): |
||
77 | # """Non-recursive version of os.walk for directories.""" |
||
78 | # return sum(os.path.isdir(os.path.join(folder_path, f)) for f in os.listdir(folder_path)) |
||
79 | |||
80 | |||
81 | # def count_files_in_folder(folder_path): |
||
82 | # """Non-recursive version of os.walk for files.""" |
||
83 | # return sum(os.path.isfile(os.path.join(folder_path, f)) for f in os.listdir(folder_path)) |
||
84 | |||
85 | |||
86 | # class InstallSkinCommand(sublime_plugin.ApplicationCommand): |
||
87 | |||
88 | # def run(self): |
||
89 | # """ |
||
90 | # Could install from direct repo URL, zip file or github release or even branch.""" |
||
91 | # pass |
||
92 | |||
93 | |||
94 | # class RainmeterInstallSkinFromZipCommand(sublime_plugin.ApplicationCommand): |
||
95 | |||
96 | # def on_zipped_skin_url_entered(self, url): |
||
97 | # info("Found url '" + url + "' of zip.") |
||
98 | # sublime.set_timeout_async(lambda: self.on_zipped_skin_url_entered_async(url), 0) |
||
99 | |||
100 | # def on_zipped_skin_url_entered_async(self, url): |
||
101 | # with tempfile.TemporaryDirectory() as temp_path: |
||
102 | # info("Downloading zip to temp folder '" + temp_path + "'.") |
||
103 | # zip_name = url.rsplit('/', 1)[-1] |
||
104 | |||
105 | # temp_file = os.path.join(temp_path, zip_name) |
||
106 | # download_from_to(url, temp_file) |
||
107 | # info("Downloaded zip to temp file '" + temp_file + "'.") |
||
108 | |||
109 | # if not zipfile.is_zipfile(temp_file): |
||
110 | # message = "The file from '" + |
||
111 | # url + |
||
112 | # "' is not a valid ZIP file. Invalid files can not be extracted. Aborting Operation." |
||
113 | |||
114 | # error(message) |
||
115 | # sublime.error_message(message) |
||
116 | |||
117 | # return False |
||
118 | |||
119 | # return install_zip_into_skins_folder(temp_file) |
||
120 | |||
121 | # def run(self): |
||
122 | # maybe_clipboard = sublime.get_clipboard() |
||
123 | # default_url = maybe_clipboard if maybe_clipboard else "https://skin.zip" |
||
124 | |||
125 | # sublime.active_window().show_input_panel( |
||
126 | # "Enter URL to zipped Skin:", |
||
127 | # default_url, |
||
128 | # self.on_zipped_skin_url_entered, None, None |
||
129 | # ) |
||
130 | |||
131 | |||
132 | # class InstallSkinFromGithubCommand(sublime_plugin.ApplicationCommand): |
||
133 | |||
134 | # def on_github_skin_url_entered(self, url): |
||
135 | # # skin_path = get_cached_skin_path() |
||
136 | |||
137 | # with tempfile.TemporaryDirectory() as temp_path: |
||
138 | # zip_name = url.rsplit('/', 1)[-1] |
||
139 | |||
140 | # temp_file = os.path.join(temp_path, zip_name) |
||
141 | # download_from_to(url, temp_file) |
||
142 | # print(temp_file) |
||
143 | |||
144 | # print(url) |
||
145 | |||
146 | # def run(self): |
||
147 | # if not is_gh_online(): |
||
148 | # message = "Could not access github.com. "+ |
||
149 | # "Please check your connection and try again or look if github.com is down." |
||
150 | |||
151 | # error(message) |
||
152 | # sublime.error_message(message) |
||
153 | |||
154 | # sublime.active_window().show_input_panel( |
||
155 | # "Enter Github Project URL to Rainmeter Skin:", |
||
156 | # "https://github.com/<user>/<project>", |
||
157 | # self.on_github_skin_url_entered, None, None |
||
158 | # ) |
||
159 | |||
160 | |||
161 | View Code Duplication | class RainmeterInstallSkinFromFolderCommand(sublime_plugin.ApplicationCommand): # pylint: disable=R0903; commands |
|
0 ignored issues
–
show
Duplication
introduced
by
Loading history...
|
|||
162 | """ |
||
163 | Command to install skin from a folder. |
||
164 | |||
165 | Command String is rainmeter_install_skin_from_folder_command. |
||
166 | """ |
||
167 | |||
168 | def run(self): |
||
169 | """Automatically executed upon calling this command.""" |
||
170 | # check cache first to determine the default path shown to the user |
||
171 | install_cache_path = os.path.join(sublime.cache_path(), "Rainmeter", "install", "last_entered_folder.cache") |
||
172 | if os.path.exists(install_cache_path) and os.path.isfile(install_cache_path): |
||
173 | with open(install_cache_path, 'r') as cache_handler: |
||
174 | cache_content = cache_handler.read() |
||
175 | default_path = cache_content |
||
176 | |||
177 | else: |
||
178 | user = os.path.expanduser("~") |
||
179 | downloads = os.path.join(user, "Downloads") |
||
180 | |||
181 | if os.path.exists(downloads) and os.path.isdir(downloads): |
||
182 | default_path = downloads |
||
183 | else: |
||
184 | default_path = None |
||
185 | |||
186 | sublime.active_window().show_input_panel( |
||
187 | "Enter skin folder location:", |
||
188 | default_path, |
||
189 | self.__on_folder_path_entered, None, None |
||
190 | ) |
||
191 | |||
192 | @classmethod |
||
193 | def __on_folder_path_entered(cls, path): |
||
194 | """ |
||
195 | Executed after a path is entered. |
||
196 | |||
197 | Checks the given user input to verify some basic requirements like that it is a directory. |
||
198 | """ |
||
199 | if not os.path.exists(path): |
||
200 | sublime.error_message("The entered path '" + path + "' is not valid. Please check your input.") |
||
201 | return |
||
202 | |||
203 | if not os.path.isdir(path): |
||
204 | sublime.error_message("The entered path '" + path + "' is not a directory. Please check your input.") |
||
205 | return |
||
206 | |||
207 | if not from_folder.find_inis_in_folder(path): |
||
208 | message = "The entered path '" + path + "' is not a valid Rainmeter skin. Please check your input." |
||
209 | sublime.error_message(message) |
||
210 | return |
||
211 | |||
212 | # we expect the user to enter a new path which we need to persist |
||
213 | install_cache_path = os.path.join(sublime.cache_path(), "Rainmeter", "install", "last_entered_folder.cache") |
||
214 | if os.path.exists(install_cache_path): |
||
215 | write_mode = 'w' |
||
216 | else: |
||
217 | write_mode = 'x' |
||
218 | os.makedirs(os.path.dirname(install_cache_path)) |
||
219 | |||
220 | with open(install_cache_path, write_mode) as cache_handler: |
||
221 | cache_handler.write(path) |
||
222 | |||
223 | dest_folder = from_folder.install_into_skins_folder(path) |
||
224 | sublime.message_dialog("Skin was successfully installed into \n\n" + dest_folder) |
||
225 | |||
226 | |||
227 | View Code Duplication | class RainmeterInstallSkinFromZipCommand(sublime_plugin.ApplicationCommand): # pylint: disable=R0903; commands |
|
0 ignored issues
–
show
|
|||
228 | """ |
||
229 | Class extending the ApplicationCommand from ST3. |
||
230 | |||
231 | Command string is rainmeter_install_skin_from_zip_command. |
||
232 | """ |
||
233 | |||
234 | def run(self): |
||
235 | """Automatically executed upon calling this command.""" |
||
236 | # check cache first to determine the default path shown to the user |
||
237 | install_cache_path = os.path.join(sublime.cache_path(), "Rainmeter", "install", "last_entered_zip.cache") |
||
238 | if os.path.exists(install_cache_path) and os.path.isfile(install_cache_path): |
||
239 | with open(install_cache_path, 'r') as cache_handler: |
||
240 | cache_content = cache_handler.read() |
||
241 | default_path = cache_content |
||
242 | |||
243 | else: |
||
244 | # show some default location from which the user can search from |
||
245 | user = os.path.expanduser("~") |
||
246 | downloads = os.path.join(user, "Downloads") |
||
247 | |||
248 | if os.path.exists(downloads) and os.path.isdir(downloads): |
||
249 | default_path = downloads |
||
250 | else: |
||
251 | default_path = None |
||
252 | |||
253 | sublime.active_window().show_input_panel( |
||
254 | "Enter skin zip location:", |
||
255 | default_path, |
||
256 | self.__on_zip_path_entered, None, None |
||
257 | ) |
||
258 | |||
259 | @classmethod |
||
260 | def __on_zip_path_entered(cls, path): |
||
261 | """Executed after a zip path is entered.""" |
||
262 | if not os.path.exists(path): |
||
263 | sublime.error_message("The entered path '" + path + "' is not valid. Please check your input.") |
||
264 | return |
||
265 | |||
266 | if not os.path.isfile(path): |
||
267 | sublime.error_message("The entered path '" + path + "' is not a file. Please check your input.") |
||
268 | return |
||
269 | |||
270 | if not path.endswith(".zip"): |
||
271 | sublime.error_message("The entered path '" + path + "' is not a zip file. Please check your input.") |
||
272 | return |
||
273 | |||
274 | # we expect the user to enter a new path which we need to persist |
||
275 | install_cache_path = os.path.join(sublime.cache_path(), "Rainmeter", "install", "last_entered_zip.cache") |
||
276 | if os.path.exists(install_cache_path): |
||
277 | write_mode = 'w' |
||
278 | else: |
||
279 | write_mode = 'x' |
||
280 | os.makedirs(os.path.dirname(install_cache_path)) |
||
281 | |||
282 | with open(install_cache_path, write_mode) as cache_handler: |
||
283 | cache_handler.write(path) |
||
284 | |||
285 | from_zip.install_skin_zip(path) |
||
286 | sublime.status_message("Skin was successfully installed!") |
||
287 | |||
288 | |||
289 | class RainmeterInstallSkinFromGitCommand(sublime_plugin.ApplicationCommand): # pylint: disable=R0903; commands |
||
290 | """ |
||
291 | Class extending the ApplicationCommand from ST3. |
||
292 | |||
293 | Command String is rainmeter_install_skin_from_git_command. |
||
294 | """ |
||
295 | |||
296 | def run(self): |
||
297 | """Executed after this command is triggered from the ST3 API.""" |
||
298 | pass |
||
299 | |||
300 | @classmethod |
||
301 | def __on_git_path_entered(cls, path): |
||
302 | """Executed after a Git path is entered.""" |
||
303 | print(path) |
||
304 | |||
305 | |||
306 | class RainmeterInstallSkinFromGithubCommand(sublime_plugin.ApplicationCommand): # pylint: disable=R0903; commands |
||
307 | """ |
||
308 | Class extending the ApplicationCommand from ST3. |
||
309 | |||
310 | Command string is rainmeter_install_skin_from_github. |
||
311 | """ |
||
312 | |||
313 | def run(self): |
||
314 | """Executed after this command is triggered from the ST3 API.""" |
||
315 | default_path = "https://github.com/<user>/<repository>" |
||
316 | sublime.active_window().show_input_panel( |
||
317 | "Enter skin zip location:", |
||
318 | default_path, |
||
319 | self.__on_github_path_entered, None, None |
||
320 | ) |
||
321 | |||
322 | @classmethod |
||
323 | def __on_github_path_entered(cls, path): |
||
324 | """Executed after a GitHub path is entered.""" |
||
325 | |||
326 | if is_gh_online(): |
||
327 | print("Github is online:", path) |
||
328 |