mirrored from https://projects.blender.org/blender/blender-addons.git
-
Notifications
You must be signed in to change notification settings - Fork 192
/
Copy pathimport_brush_pack.py
147 lines (116 loc) · 5.22 KB
/
import_brush_pack.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
# SPDX-FileCopyrightText: 2020-2023 Blender Foundation
#
# SPDX-License-Identifier: GPL-2.0-or-later
import bpy
import ssl
import urllib.request
import urllib.parse
import zipfile
from pathlib import Path
def unzip(zip_path, extract_dir_path):
'''Get a zip path and a directory path to extract to'''
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
zip_ref.extractall(extract_dir_path)
def simple_dl_url(url, dest, fallback_url=None):
## need to import urlib.request or linux module does not found 'request' using urllib directly
## need to create an SSl context or linux fail returning unverified ssl
# ssl._create_default_https_context = ssl._create_unverified_context
try:
urllib.request.urlretrieve(url, dest)
except Exception as e:
print('Error trying to download\n', e)
if fallback_url:
print('\nDownload page for manual install:', fallback_url)
return e
def get_brushes(blend_fp):
cur_brushes = [b.name for b in bpy.data.brushes]
with bpy.data.libraries.load(str(blend_fp), link=False) as (data_from, data_to):
# load brushes starting with 'tex' prefix if there are not already there
data_to.brushes = [b for b in data_from.brushes if b.startswith('tex_') and not b in cur_brushes]
# Add holdout
if 'z_holdout' in data_from.brushes and not 'z_holdout' in cur_brushes:
data_to.brushes.append('z_holdout')
## force fake user for the brushes
for b in data_to.brushes:
b.use_fake_user = True
return len(data_to.brushes)
class GP_OT_install_brush_pack(bpy.types.Operator):
bl_idname = "gp.import_brush_pack"
bl_label = "Download and import texture brush pack"
bl_description = "Download and import Grease Pencil brush pack from the web (~3.7 Mo)"
bl_options = {"REGISTER", "INTERNAL"}
# @classmethod
# def poll(cls, context):
# return True
def _append_brushes(self, blend_fp):
bct = get_brushes(blend_fp)
if bct:
self.report({'INFO'}, f'{bct} brushes installed')
else:
self.report({'WARNING'}, 'Brushes already loaded')
def _install_from_zip(self):
## get blend file name
blendname = None
with zipfile.ZipFile(self.brushzip, 'r') as zfd:
for f in zfd.namelist():
if f.endswith('.blend'):
blendname = f
break
if not blendname:
self.report({'ERROR'}, f'blend file not found in zip {self.brushzip}')
return
unzip(self.brushzip, self.temp)
self._append_brushes(Path(self.temp) / blendname)
def execute(self, context):
import tempfile
import os
temp = tempfile.gettempdir()
if not temp:
self.report({'ERROR'}, 'no os temporary directory found to download brush pack (using python tempfile.gettempdir())')
return {"CANCELLED"}
self.temp = Path(temp)
dl_url = 'https://download.blender.org/demo/bundles/bundles-3.0/grease-pencil-brush-pack.zip'
## need to create an SSl context or linux fail and raise unverified ssl
ssl._create_default_https_context = ssl._create_unverified_context
file_size = None
try:
with urllib.request.urlopen(dl_url) as response:
file_size = int(response.getheader('Content-Length'))
except:
## try loading from tempdir
packs = [f for f in os.listdir(self.temp) if 'gp_brush_pack' in f.lower() and f.endswith('.blend')]
if packs:
packs.sort()
self._append_brushes(Path(self.temp) / packs[-1])
self.report({'WARNING'}, 'Brushes loaded from temp directory (No download)')
return {"FINISHED"}
self.report({'ERROR'}, f'Check your internet connection, impossible to connect to url: {dl_url}')
return {"CANCELLED"}
if file_size is None:
self.report({'ERROR'}, f'No response read from: {dl_url}')
return {"CANCELLED"}
self.brushzip = self.temp / Path(dl_url).name
### Load existing files instead of redownloading if exists and up to date (same hash)
if self.brushzip.exists():
### compare using file size with size from url header
disk_size = self.brushzip.stat().st_size
if disk_size == file_size:
## is up to date, install
print(f'{self.brushzip} is up do date, appending brushes')
self._install_from_zip()
return {"FINISHED"}
## Download, unzip, use blend
print(f'Downloading brushpack in {self.brushzip}')
fallback_url='https://cloud.blender.org/p/gallery/5f235cc297f8815e74ffb90b'
err = simple_dl_url(dl_url, str(self.brushzip), fallback_url)
if err:
self.report({'ERROR'}, 'Could not download brush pack. Check your internet connection. (see console for detail)')
return {"CANCELLED"}
else:
print('Done')
self._install_from_zip()
return {"FINISHED"}
def register():
bpy.utils.register_class(GP_OT_install_brush_pack)
def unregister():
bpy.utils.unregister_class(GP_OT_install_brush_pack)