| 1 |
import os, re, string, sets |
|---|
| 2 |
from App.config import getConfiguration |
|---|
| 3 |
from Products.CMFCore.utils import getToolByName |
|---|
| 4 |
|
|---|
| 5 |
from config import * |
|---|
| 6 |
from write_utils import writeProps, writeFileContent, writeObjectsMeta |
|---|
| 7 |
from Products.qPloneSkinDump.generatingTemplate import p_sheet_id, p_id |
|---|
| 8 |
|
|---|
| 9 |
CSS_PATTERN = re.compile("^.+\.css$") |
|---|
| 10 |
JS_PATTERN = re.compile("^.+\.js$") |
|---|
| 11 |
_write_custom_meta_type_list = [ |
|---|
| 12 |
'Controller Page Template', |
|---|
| 13 |
'Controller Python Script', |
|---|
| 14 |
'Controller Validator', |
|---|
| 15 |
'DTML Method', |
|---|
| 16 |
'File', |
|---|
| 17 |
'Image', |
|---|
| 18 |
'Page Template', |
|---|
| 19 |
'Script (Python)' ] |
|---|
| 20 |
_acceptable_meta_types = _write_custom_meta_type_list + ['Folder',] |
|---|
| 21 |
ospJoin = os.path.join |
|---|
| 22 |
|
|---|
| 23 |
def get_product_listdirs(): |
|---|
| 24 |
""" Return a contents of all plugged in Products directories.""" |
|---|
| 25 |
products = sets.Set() |
|---|
| 26 |
[products.update(os.listdir(product_dir)) for product_dir in Products.__path__] |
|---|
| 27 |
return products |
|---|
| 28 |
|
|---|
| 29 |
def getFSSkinPath(fs_product_name, fs_skin_directory, skin_obj, subdir): |
|---|
| 30 |
""" Return file system skin path for subdir.""" |
|---|
| 31 |
skinpath = "%s/%s/skins/%s" % (PRODUCTS_PATH \ |
|---|
| 32 |
,fs_product_name \ |
|---|
| 33 |
,fs_skin_directory) |
|---|
| 34 |
|
|---|
| 35 |
skinp, subp = [obj.getPhysicalPath() for obj in [skin_obj, subdir]] |
|---|
| 36 |
if len(subp) != len(skinp): |
|---|
| 37 |
|
|---|
| 38 |
skinpath += '/' + '/'.join( subp[len(skinp):] ) |
|---|
| 39 |
return skinpath |
|---|
| 40 |
|
|---|
| 41 |
def get_id(obj): |
|---|
| 42 |
""" Get real object's id.""" |
|---|
| 43 |
id = callable(obj.id) and obj.id() or obj.id |
|---|
| 44 |
assert obj.getId() == id, "expected identical ids: '%s' != '%s'" % (obj.getId(), id) |
|---|
| 45 |
return id |
|---|
| 46 |
|
|---|
| 47 |
def getData(obj, meta_type): |
|---|
| 48 |
""" Return object's data.""" |
|---|
| 49 |
return meta_type in ['Image', 'File'] and obj.manage_FTPget() or obj.document_src() |
|---|
| 50 |
|
|---|
| 51 |
def dumpSkin(context, \ |
|---|
| 52 |
skin_name='custom', \ |
|---|
| 53 |
subdir=None, \ |
|---|
| 54 |
fs_skin_directory='custom', \ |
|---|
| 55 |
fs_product_name='QSkinTemplate', \ |
|---|
| 56 |
erase_from_skin=0): |
|---|
| 57 |
"""Dump custom information to file.""" |
|---|
| 58 |
|
|---|
| 59 |
skin_obj = getToolByName( context, 'portal_skins' )[skin_name] |
|---|
| 60 |
subdir = subdir or skin_obj |
|---|
| 61 |
skinpath = getFSSkinPath(fs_product_name, fs_skin_directory, skin_obj, subdir) |
|---|
| 62 |
|
|---|
| 63 |
if not os.path.exists( skinpath ): |
|---|
| 64 |
os.makedirs( skinpath ) |
|---|
| 65 |
|
|---|
| 66 |
deletelist = [] |
|---|
| 67 |
obj_meta = {} |
|---|
| 68 |
for o in subdir.objectValues(): |
|---|
| 69 |
meta_type = o.meta_type |
|---|
| 70 |
id = get_id(o) |
|---|
| 71 |
if meta_type in _acceptable_meta_types: |
|---|
| 72 |
|
|---|
| 73 |
|
|---|
| 74 |
obj_meta[id] = meta_type |
|---|
| 75 |
if meta_type == 'Folder': |
|---|
| 76 |
|
|---|
| 77 |
if id in ['stylesheet_properties', 'base_properties'] \ |
|---|
| 78 |
or id.startswith('base_properties'): |
|---|
| 79 |
writeProps( o, skinpath, extension = '.props' ) |
|---|
| 80 |
else: |
|---|
| 81 |
dumpSkin( context, skin_name, subdir = o,\ |
|---|
| 82 |
fs_skin_directory=fs_skin_directory,\ |
|---|
| 83 |
fs_product_name=fs_product_name,\ |
|---|
| 84 |
erase_from_skin = erase_from_skin ) |
|---|
| 85 |
deletelist.append( o.getId() ) |
|---|
| 86 |
elif meta_type in _write_custom_meta_type_list: |
|---|
| 87 |
|
|---|
| 88 |
|
|---|
| 89 |
writeFileContent( o, skinpath, getData(o, meta_type) ) |
|---|
| 90 |
deletelist.append( o.getId() ) |
|---|
| 91 |
else: |
|---|
| 92 |
print 'method ignoring ', meta_type |
|---|
| 93 |
|
|---|
| 94 |
if obj_meta : |
|---|
| 95 |
writeObjectsMeta(obj_meta, skinpath) |
|---|
| 96 |
|
|---|
| 97 |
if erase_from_skin: |
|---|
| 98 |
subdir.manage_delObjects( ids = deletelist ) |
|---|
| 99 |
|
|---|
| 100 |
def fillinFileTemplate(f_path_read, f_path_write=None, dict={}): |
|---|
| 101 |
""" Fillin file template with data from dictionary.""" |
|---|
| 102 |
if not f_path_write: |
|---|
| 103 |
f_path_write = f_path_read |
|---|
| 104 |
f_tmpl = open(f_path_read, 'r') |
|---|
| 105 |
tmpl = f_tmpl.read() |
|---|
| 106 |
f_tmpl.close() |
|---|
| 107 |
f_tmpl = open(f_path_write, 'w') |
|---|
| 108 |
f_tmpl.write(tmpl % dict) |
|---|
| 109 |
f_tmpl.close() |
|---|
| 110 |
|
|---|
| 111 |
def getResourcesList(directory, resources_list, pattern=CSS_PATTERN): |
|---|
| 112 |
""" Get resources list from 'directory' skin folder.""" |
|---|
| 113 |
for o in directory.objectValues(): |
|---|
| 114 |
meta_type = o.meta_type |
|---|
| 115 |
id = get_id(o) |
|---|
| 116 |
if meta_type == 'Folder': |
|---|
| 117 |
|
|---|
| 118 |
if id not in ['stylesheet_properties', 'base_properties'] \ |
|---|
| 119 |
and not id.startswith('base_properties'): |
|---|
| 120 |
css_list = getResourcesList(o, resources_list, pattern) |
|---|
| 121 |
elif pattern.match(id): |
|---|
| 122 |
resources_list.append( id ) |
|---|
| 123 |
return resources_list |
|---|
| 124 |
|
|---|
| 125 |
def getResourceProperties(context, regestry_id, prop_list, dflt=''): |
|---|
| 126 |
""" Return list of dictionaries with all dumped resources properties.""" |
|---|
| 127 |
properties=[] |
|---|
| 128 |
resource = getToolByName(context, regestry_id, None) |
|---|
| 129 |
if resource: |
|---|
| 130 |
for res in resource.getResources(): |
|---|
| 131 |
props = {} |
|---|
| 132 |
for prop in prop_list: |
|---|
| 133 |
accessor = getattr(res, 'get%s' % prop.capitalize(), None) |
|---|
| 134 |
if accessor: |
|---|
| 135 |
props[prop] = accessor() or dflt |
|---|
| 136 |
properties.append(props) |
|---|
| 137 |
return properties |
|---|
| 138 |
|
|---|
| 139 |
def getResourceListRegdata(context, subdir, rsrc_pattern, rsrc_name, rsrc_reg_props): |
|---|
| 140 |
rsrc_list = getResourcesList(subdir, resources_list=[], pattern=rsrc_pattern) |
|---|
| 141 |
result_rsrc_list = [] |
|---|
| 142 |
[result_rsrc_list.append(item) for item in rsrc_list if item not in result_rsrc_list] |
|---|
| 143 |
skin_css_regdata = getResourceProperties(context, rsrc_name, rsrc_reg_props) |
|---|
| 144 |
return result_rsrc_list, skin_css_regdata |
|---|
| 145 |
|
|---|
| 146 |
def copyDir(srcDirectory, dstDirectory, productName): |
|---|
| 147 |
"""Recursive copying from ZMIskin-folder to FS one""" |
|---|
| 148 |
for item in os.listdir(srcDirectory): |
|---|
| 149 |
src_path = ospJoin(srcDirectory, item) |
|---|
| 150 |
dst_path = ospJoin(dstDirectory, item) |
|---|
| 151 |
if os.path.isfile(src_path): |
|---|
| 152 |
if os.path.exists(dst_path): |
|---|
| 153 |
continue |
|---|
| 154 |
f_sorce = open(src_path,'r') |
|---|
| 155 |
data = f_sorce.read() |
|---|
| 156 |
f_sorce.close() |
|---|
| 157 |
f_dst = open(dst_path,'w') |
|---|
| 158 |
f_dst.write(data) |
|---|
| 159 |
f_dst.close() |
|---|
| 160 |
elif os.path.isdir(src_path): |
|---|
| 161 |
if not os.path.exists(dst_path): |
|---|
| 162 |
os.mkdir(dst_path) |
|---|
| 163 |
copyDir(src_path, dst_path, productName) |
|---|
| 164 |
|
|---|
| 165 |
def makeNewProduct(context, productName, productSkinName, \ |
|---|
| 166 |
zmi_skin_name, zmi_base_skin_name, subdir,\ |
|---|
| 167 |
doesCustomizeSlots, left_slots, right_slots, slot_forming, main_column, \ |
|---|
| 168 |
doesExportObjects, import_policy, dump_CSS, dump_JS): |
|---|
| 169 |
"""Create new skin-product's directory and |
|---|
| 170 |
copy skin-product template with little modification""" |
|---|
| 171 |
products_path = PRODUCTS_PATH |
|---|
| 172 |
productPath = ospJoin(products_path, productName) |
|---|
| 173 |
if not ( productName in os.listdir(products_path) ): |
|---|
| 174 |
os.mkdir(productPath) |
|---|
| 175 |
|
|---|
| 176 |
subdir = subdir or getToolByName( context, 'portal_skins' )[zmi_skin_name] |
|---|
| 177 |
result_css_list = skin_css_regdata = result_js_list = skin_js_regdata = [] |
|---|
| 178 |
if dump_CSS: |
|---|
| 179 |
result_css_list, skin_css_regdata = getResourceListRegdata(context, subdir, |
|---|
| 180 |
CSS_PATTERN, 'portal_css', CSS_REG_PROPS) |
|---|
| 181 |
if dump_JS: |
|---|
| 182 |
result_js_list, skin_js_regdata = getResourceListRegdata(context, subdir, |
|---|
| 183 |
JS_PATTERN, 'portal_javascripts', JS_REG_PROPS) |
|---|
| 184 |
|
|---|
| 185 |
if not doesCustomizeSlots: |
|---|
| 186 |
left_slots = right_slots = None |
|---|
| 187 |
slot_forming = main_column = None |
|---|
| 188 |
|
|---|
| 189 |
templatePath = ospJoin(products_path, PROJECTNAME, TEMPLATE_PATH) |
|---|
| 190 |
copyDir(templatePath, productPath, productName) |
|---|
| 191 |
|
|---|
| 192 |
|
|---|
| 193 |
pp = getToolByName(context, 'portal_properties') |
|---|
| 194 |
if p_sheet_id in pp.objectIds(): |
|---|
| 195 |
generated_subfolder = pp[p_sheet_id].getProperty(p_id, '') |
|---|
| 196 |
|
|---|
| 197 |
|
|---|
| 198 |
conf_dict = {"IMPORT_POLICY" : import_policy \ |
|---|
| 199 |
,"GENERATOR_PRODUCT" : PROJECTNAME \ |
|---|
| 200 |
,"SKIN_PRODUCT_NAME" : productName \ |
|---|
| 201 |
,"SKIN_NAME" : productSkinName \ |
|---|
| 202 |
,"BASE_SKIN_NAME" : zmi_base_skin_name \ |
|---|
| 203 |
,"DUMP_CSS": not not dump_CSS \ |
|---|
| 204 |
,"DUMP_JS": not not dump_JS \ |
|---|
| 205 |
,"CSS_LIST" : str(result_css_list) \ |
|---|
| 206 |
,"JS_LIST" : str(result_js_list) \ |
|---|
| 207 |
,"SKIN_CSS_REGDATA" : str(skin_css_regdata) \ |
|---|
| 208 |
,"SKIN_JS_REGDATA" : str(skin_js_regdata) \ |
|---|
| 209 |
,"LEFT_SLOTS" : str(left_slots) \ |
|---|
| 210 |
,"RIGHT_SLOTS" : str(right_slots) \ |
|---|
| 211 |
,"SLOT_FORMING" : slot_forming \ |
|---|
| 212 |
,"MAIN_COLUMN" : main_column \ |
|---|
| 213 |
,"GENERATED_SUBFOLDER" : generated_subfolder \ |
|---|
| 214 |
} |
|---|
| 215 |
sp_updated_files = ['config.py' \ |
|---|
| 216 |
,'README.txt' \ |
|---|
| 217 |
,ospJoin('Extensions', 'utils.py')\ |
|---|
| 218 |
,ospJoin('Extensions', 'Install.py')] |
|---|
| 219 |
for fp in sp_updated_files: |
|---|
| 220 |
fillinFileTemplate(ospJoin(productPath, fp), dict=conf_dict) |
|---|