[74] | 1 | import os, re, string, sets, time |
---|
| 2 | from zope.app import zapi |
---|
[1] | 3 | from App.config import getConfiguration |
---|
| 4 | from Products.CMFCore.utils import getToolByName |
---|
| 5 | |
---|
| 6 | from config import * |
---|
| 7 | from write_utils import writeProps, writeFileContent, writeObjectsMeta |
---|
| 8 | |
---|
[74] | 9 | from zope.interface import providedBy |
---|
| 10 | from zope.schema import getFields |
---|
| 11 | from zope.component import getMultiAdapter, getUtility, getSiteManager |
---|
| 12 | from zope.publisher.interfaces.browser import IBrowserRequest |
---|
| 13 | from five.customerize.interfaces import IViewTemplateContainer, ITTWViewTemplate |
---|
| 14 | from plone.portlets.interfaces import IPortletAssignmentMapping, IPortletManager, IPlacelessPortletManager |
---|
| 15 | from plone.portlets.interfaces import IPortletContext, IPortletDataProvider |
---|
| 16 | from plone.portlets.interfaces import ILocalPortletAssignmentManager |
---|
| 17 | from plone.app.customerize.registration import generateIdFromRegistration, interfaceName |
---|
| 18 | |
---|
| 19 | from Products.GenericSetup.utils import _getDottedName, _resolveDottedName |
---|
| 20 | from Products.GenericSetup.interfaces import IBody |
---|
| 21 | from Products.GenericSetup.context import BaseContext |
---|
| 22 | |
---|
[1] | 23 | CSS_PATTERN = re.compile("^.+\.css$") |
---|
| 24 | JS_PATTERN = re.compile("^.+\.js$") |
---|
| 25 | _write_custom_meta_type_list = [ |
---|
| 26 | 'Controller Page Template', |
---|
| 27 | 'Controller Python Script', |
---|
| 28 | 'Controller Validator', |
---|
| 29 | 'DTML Method', |
---|
| 30 | 'File', |
---|
| 31 | 'Image', |
---|
| 32 | 'Page Template', |
---|
| 33 | 'Script (Python)' ] |
---|
| 34 | _acceptable_meta_types = _write_custom_meta_type_list + ['Folder',] |
---|
| 35 | ospJoin = os.path.join |
---|
| 36 | |
---|
| 37 | def get_product_listdirs(): |
---|
| 38 | """ Return a contents of all plugged in Products directories.""" |
---|
| 39 | products = sets.Set() |
---|
| 40 | [products.update(os.listdir(product_dir)) for product_dir in Products.__path__] |
---|
| 41 | return products |
---|
| 42 | |
---|
| 43 | def get_id(obj): |
---|
| 44 | """ Get real object's id.""" |
---|
| 45 | id = callable(obj.id) and obj.id() or obj.id |
---|
| 46 | assert obj.getId() == id, "expected identical ids: '%s' != '%s'" % (obj.getId(), id) |
---|
| 47 | return id |
---|
| 48 | |
---|
| 49 | def getData(obj, meta_type): |
---|
| 50 | """ Return object's data.""" |
---|
| 51 | return meta_type in ['Image', 'File'] and obj.manage_FTPget() or obj.document_src() |
---|
| 52 | |
---|
[74] | 53 | def dumpPortalViewCustomization(context): |
---|
| 54 | result = [] |
---|
| 55 | |
---|
| 56 | components = getSiteManager(context) |
---|
| 57 | localregs = [reg for reg in components.registeredAdapters() if (len(reg.required) in (2, 4, 5) and |
---|
| 58 | reg.required[1].isOrExtends(IBrowserRequest) and |
---|
| 59 | ITTWViewTemplate.providedBy(reg.factory))] |
---|
| 60 | container = getUtility(IViewTemplateContainer) |
---|
| 61 | # import pdb;pdb.set_trace() |
---|
| 62 | for lreg in localregs: |
---|
| 63 | # ttw_id = generateIdFromRegistration(lreg) |
---|
| 64 | ttw_id = lreg.factory.__name__ |
---|
| 65 | |
---|
| 66 | if ttw_id not in container.objectIds(): |
---|
| 67 | continue |
---|
| 68 | ttw = getattr(container, ttw_id) |
---|
| 69 | ttw_info = {'for_name' : interfaceName(lreg.required[0]), |
---|
| 70 | 'type_name' : interfaceName(lreg.required[-1]), |
---|
| 71 | 'view_name' : lreg.name, |
---|
| 72 | 'kwargs' : {'text' : ttw._text, |
---|
| 73 | 'content_type' : ttw.content_type, |
---|
| 74 | 'encoding' : ttw.output_encoding, |
---|
| 75 | }} |
---|
| 76 | result.append(ttw_info) |
---|
| 77 | |
---|
| 78 | return result |
---|
| 79 | |
---|
| 80 | def extractInfoFromAssignment(name, assignment): |
---|
| 81 | klass = assignment.__class__ |
---|
| 82 | a = {'name' : name, 'class' : '%s' % _getDottedName(klass)} |
---|
| 83 | data = assignment.data |
---|
| 84 | kwargs = {} |
---|
| 85 | for i in list(providedBy(data)): |
---|
| 86 | if i.isOrExtends(IPortletDataProvider): |
---|
| 87 | for field_name, field in getFields(i).items(): |
---|
| 88 | kwargs[field_name] = field.get(assignment) |
---|
| 89 | a['kwargs'] = kwargs |
---|
| 90 | return a |
---|
| 91 | |
---|
| 92 | def extractSiteWidePortlets(context, managers): |
---|
| 93 | """ Extract site-wide portlets |
---|
| 94 | Data structure: |
---|
| 95 | '__site-wide-portlets__', [(<manager1_name>, <manager1_info>), |
---|
| 96 | (<manager2_name>, <manager2_info>), |
---|
| 97 | (<manager3_name>, <manager3_info>)]) |
---|
| 98 | <manager_info>: |
---|
| 99 | {'category1' : <catmapping1>, |
---|
| 100 | 'category2' : <catmapping2>} |
---|
| 101 | <catmapping>: |
---|
| 102 | {'key1' : <mapping1>, |
---|
| 103 | 'key2' : <mapping2>} |
---|
| 104 | <mapping>: |
---|
| 105 | {'assignment_name1' : <assignment1>, |
---|
| 106 | 'assignment_name2' : <assignment2>} |
---|
| 107 | <assignment>: |
---|
| 108 | {'name' : 'Assignment', |
---|
| 109 | 'class' : 'dotted.path.to.assignment.class', |
---|
| 110 | 'kwargs' : {'parameter1' : 'value1', |
---|
| 111 | 'parameter2' : 'value2'} |
---|
| 112 | """ |
---|
| 113 | info = [] |
---|
| 114 | for manager_name, manager in managers: |
---|
| 115 | manager_info = {} |
---|
| 116 | for category, catmapping in manager.items(): |
---|
| 117 | catmapping_info = {} |
---|
| 118 | for key, mapping in catmapping.items(): |
---|
| 119 | mapping_info = {} |
---|
| 120 | for name, assignment in mapping.items(): |
---|
| 121 | mapping_info[name] = extractInfoFromAssignment(name, assignment) |
---|
| 122 | catmapping_info[key] = mapping_info |
---|
| 123 | manager_info[category] = catmapping_info |
---|
| 124 | info.append((manager_name, manager_info)) |
---|
| 125 | return info |
---|
| 126 | |
---|
| 127 | def extractContextPortletsFromManager(context, manager): |
---|
| 128 | """ Extract all contextual portlets from given object and portlet manager, and portlets blacklists |
---|
| 129 | Data structure: |
---|
| 130 | <manager_info> = |
---|
| 131 | {'blacklists' : [(GROUP_CATEGORY, True), |
---|
| 132 | (CONTENT_TYPE_CATEGORY, False), |
---|
| 133 | (CONTEXT_CATEGORY, None)], |
---|
| 134 | 'assignments' : [{'name' : 'Assignment-2', |
---|
| 135 | 'class' : 'dotted.path.to.assignment.class', |
---|
| 136 | 'kwargs' : {'parameter1' : 'value1', |
---|
| 137 | 'parameter2' : 'value2'}}, |
---|
| 138 | {'name' : 'Assignment', |
---|
| 139 | 'class' : 'dotted.path.to.assignment.class', |
---|
| 140 | 'kwargs' : {'parameter1' : 'value1', |
---|
| 141 | 'parameter2' : 'value2'}]} |
---|
| 142 | """ |
---|
| 143 | |
---|
| 144 | info = {} |
---|
| 145 | info['assignments'] = assignments = [] |
---|
| 146 | info['blacklists'] = blacklists = [] |
---|
| 147 | |
---|
| 148 | # Extract contextual portlets |
---|
| 149 | mapping = getMultiAdapter((context, manager), IPortletAssignmentMapping, context=context) |
---|
| 150 | for name, assignment in mapping.items(): |
---|
| 151 | assignments.append(extractInfoFromAssignment(name, assignment)) |
---|
| 152 | |
---|
| 153 | # Extract blacklists for given object and manager |
---|
| 154 | localassignmentmanager = getMultiAdapter((context, manager), ILocalPortletAssignmentManager) |
---|
| 155 | blacklist = localassignmentmanager._getBlacklist() |
---|
| 156 | if blacklist is not None: |
---|
| 157 | for category, key in blacklist.items(): |
---|
| 158 | blacklists.append((category, key)) |
---|
| 159 | |
---|
| 160 | return info |
---|
| 161 | |
---|
| 162 | def extractPortletsFromContext(context, slot_structure, typesToShow, managers): |
---|
| 163 | """ Extract portlets for given object assigned through all portlet managers. |
---|
| 164 | Data structure: |
---|
| 165 | ('unique/path/to/context', [(<manager1_name>, <manager1_info>), |
---|
| 166 | (<manager2_name>, <manager2_info>), |
---|
| 167 | (<manager3_name>, <manager3_info>)]) |
---|
| 168 | """ |
---|
| 169 | |
---|
| 170 | |
---|
| 171 | info = [] |
---|
| 172 | key = '/'.join(context.getPhysicalPath()[2:]) |
---|
| 173 | |
---|
| 174 | for name, manager in managers: |
---|
| 175 | info.append((name, extractContextPortletsFromManager(context, manager))) |
---|
| 176 | |
---|
| 177 | slot_structure.append((key, info)) |
---|
| 178 | |
---|
| 179 | return slot_structure |
---|
| 180 | |
---|
| 181 | def dumpAllPortlets(context, slot_structure, typesToShow, managers): |
---|
| 182 | extractPortletsFromContext(context, slot_structure, typesToShow, managers) |
---|
| 183 | if getattr(context.aq_base, 'isPrincipiaFolderish', 0): |
---|
| 184 | for id, obj in context.contentItems(): |
---|
| 185 | if obj.portal_type in typesToShow: |
---|
| 186 | dumpAllPortlets(obj, slot_structure, typesToShow, managers) |
---|
| 187 | |
---|
| 188 | return slot_structure |
---|
| 189 | |
---|
| 190 | def dumpPortlets(context, dump_policy, dump_portlets_selection): |
---|
| 191 | """ Extract portlets from given set of objects and site-wide portlets too. |
---|
| 192 | Data structure: |
---|
| 193 | SLOT_STRUCTURE = |
---|
| 194 | [(), (), ()] |
---|
| 195 | """ |
---|
| 196 | |
---|
| 197 | portal = getToolByName(context, 'portal_url').getPortalObject() |
---|
| 198 | portal_state = getMultiAdapter((portal, context.REQUEST), name=u'plone_portal_state') |
---|
| 199 | typesToShow = portal_state.friendly_types() |
---|
| 200 | |
---|
| 201 | components = getSiteManager(context) |
---|
| 202 | managers = [r for r in components.registeredUtilities() if r.provided.isOrExtends(IPortletManager)] |
---|
| 203 | context_managers = [(m.name, getUtility(IPortletManager, name=m.name, context=context)) for m in managers |
---|
| 204 | if not IPlacelessPortletManager.providedBy(m.component)] |
---|
| 205 | managers = [(m.name, getUtility(IPortletManager, name=m.name, context=context)) for m in managers] |
---|
| 206 | |
---|
| 207 | slot_structure = [] |
---|
| 208 | if dump_policy == 'root': |
---|
| 209 | extractPortletsFromContext(portal, slot_structure, typesToShow, context_managers) |
---|
| 210 | elif dump_policy == 'all': |
---|
| 211 | dumpAllPortlets(portal, slot_structure, typesToShow, context_managers) |
---|
| 212 | elif dump_policy == 'selection': |
---|
| 213 | for ppath in dump_portlets_selection: |
---|
| 214 | obj = portal.restrictedTraverse(ppath) |
---|
| 215 | extractPortletsFromContext(obj, slot_structure, typesToShow, context_managers) |
---|
| 216 | |
---|
| 217 | slot_structure.append(('__site-wide-portlets__', extractSiteWidePortlets(portal, managers))) |
---|
| 218 | |
---|
| 219 | return slot_structure |
---|
| 220 | |
---|
| 221 | def buildSkinLayers(context, zmi_base_skin_name): |
---|
| 222 | pskins = getToolByName(context,'portal_skins') |
---|
| 223 | layers = (pskins.getSkinPath(zmi_base_skin_name) or '').split(',') |
---|
| 224 | return "\n".join([' <layer name="%s"/>' % l for l in layers]) |
---|
| 225 | |
---|
| 226 | def getFSSkinPath(folder, fs_dest_directory, fs_product_name): |
---|
| 227 | """ Return file system skin path for subdir.""" |
---|
| 228 | |
---|
| 229 | folder_path = '/'.join(folder.getPhysicalPath()[list(folder.getPhysicalPath()).index('portal_skins')+1:]) |
---|
| 230 | skinpath = "%s/%s/skins/%s" % (fs_dest_directory, fs_product_name, folder_path) |
---|
| 231 | |
---|
| 232 | # If in skin's subfolder - get its path |
---|
| 233 | #skinp, subp = [obj.getPhysicalPath() for obj in [skin_obj, subdir]] |
---|
| 234 | #if len(subp) != len(skinp): |
---|
| 235 | ## adapt skinpath for creating directory |
---|
| 236 | #skinpath += '/' + '/'.join( subp[len(skinp):] ) |
---|
| 237 | return skinpath |
---|
| 238 | |
---|
| 239 | def dumpFolder(folder, fs_dest_directory, fs_product_name): |
---|
| 240 | skinpath = getFSSkinPath(folder, fs_dest_directory, fs_product_name) |
---|
[1] | 241 | # Create directory in FS if not yet exist |
---|
[74] | 242 | if not os.path.exists(skinpath): |
---|
| 243 | os.makedirs(skinpath) |
---|
[1] | 244 | # Loop of copying content from ZMIskin-folder to FSskin-folder |
---|
| 245 | obj_meta = {} |
---|
[74] | 246 | for o in folder.objectValues(): |
---|
[1] | 247 | meta_type = o.meta_type |
---|
| 248 | id = get_id(o) |
---|
| 249 | if meta_type in _acceptable_meta_types: |
---|
| 250 | # Adding to .objects all acceptable meta_types. |
---|
| 251 | # Fixing bug of id-meta_type confusing. |
---|
| 252 | obj_meta[id] = meta_type |
---|
| 253 | if meta_type == 'Folder': |
---|
| 254 | # very plone specific |
---|
[74] | 255 | if id in ['stylesheet_properties', 'base_properties'] or id.startswith('base_properties'): |
---|
| 256 | writeProps(o, skinpath, extension = '.props') |
---|
[1] | 257 | else: |
---|
[74] | 258 | dumpFolder(o, fs_product_name, fs_product_name) |
---|
[1] | 259 | elif meta_type in _write_custom_meta_type_list: |
---|
| 260 | #writeProps( o, skinpath ) # write object's properties |
---|
| 261 | # extract content from object(depend on metatype) and write it to the file |
---|
[74] | 262 | writeFileContent(o, skinpath, getData(o, meta_type)) |
---|
[1] | 263 | else: |
---|
| 264 | print 'method ignoring ', meta_type |
---|
| 265 | # write '.objects' file to directory if present objects with id without extension |
---|
| 266 | if obj_meta : |
---|
| 267 | writeObjectsMeta(obj_meta, skinpath) |
---|
| 268 | |
---|
[74] | 269 | def dumpSkin(context, skin_names=['custom',], fs_dest_directory=PRODUCTS_PATH, |
---|
| 270 | fs_product_name='QSkinTemplate', erase_from_skin=0): |
---|
| 271 | """Dump custom information to file.""" |
---|
| 272 | if type(skin_names) not in (type([]), type(())): |
---|
| 273 | skin_names = [skin_names,] |
---|
| 274 | for skin_name in list(skin_names): |
---|
| 275 | folder = getToolByName(context, 'portal_skins')[skin_name] |
---|
| 276 | dumpFolder(folder, fs_dest_directory, fs_product_name) |
---|
| 277 | # delete objects from the skin, if request |
---|
| 278 | if erase_from_skin: |
---|
| 279 | folder.manage_delObjects(ids = folder.objectIds()) |
---|
| 280 | |
---|
[1] | 281 | def fillinFileTemplate(f_path_read, f_path_write=None, dict={}): |
---|
| 282 | """ Fillin file template with data from dictionary.""" |
---|
| 283 | if not f_path_write: |
---|
| 284 | f_path_write = f_path_read |
---|
| 285 | f_tmpl = open(f_path_read, 'r') |
---|
| 286 | tmpl = f_tmpl.read() |
---|
| 287 | f_tmpl.close() |
---|
| 288 | f_tmpl = open(f_path_write, 'w') |
---|
[74] | 289 | try: |
---|
| 290 | f_tmpl.write(tmpl % dict) |
---|
| 291 | except: |
---|
| 292 | raise str(tmpl) |
---|
[1] | 293 | f_tmpl.close() |
---|
| 294 | |
---|
| 295 | def getResourcesList(directory, resources_list, pattern=CSS_PATTERN): |
---|
| 296 | """ Get resources list from 'directory' skin folder.""" |
---|
| 297 | for o in directory.objectValues(): |
---|
| 298 | meta_type = o.meta_type |
---|
| 299 | id = get_id(o) |
---|
| 300 | if meta_type == 'Folder': |
---|
| 301 | # very plone specific |
---|
| 302 | if id not in ['stylesheet_properties', 'base_properties'] \ |
---|
| 303 | and not id.startswith('base_properties'): |
---|
| 304 | css_list = getResourcesList(o, resources_list, pattern) |
---|
| 305 | elif pattern.match(id): |
---|
| 306 | resources_list.append( id ) |
---|
| 307 | return resources_list |
---|
| 308 | |
---|
| 309 | def getResourceProperties(context, regestry_id, prop_list, dflt=''): |
---|
| 310 | """ Return list of dictionaries with all dumped resources properties.""" |
---|
| 311 | properties=[] |
---|
| 312 | resource = getToolByName(context, regestry_id, None) |
---|
| 313 | if resource: |
---|
| 314 | for res in resource.getResources(): |
---|
| 315 | props = {} |
---|
| 316 | for prop in prop_list: |
---|
| 317 | accessor = getattr(res, 'get%s' % prop.capitalize(), None) |
---|
| 318 | if accessor: |
---|
| 319 | props[prop] = accessor() or dflt |
---|
| 320 | properties.append(props) |
---|
| 321 | return properties |
---|
| 322 | |
---|
| 323 | def getResourceListRegdata(context, subdir, rsrc_pattern, rsrc_name, rsrc_reg_props): |
---|
| 324 | rsrc_list = getResourcesList(subdir, resources_list=[], pattern=rsrc_pattern)#---CSS--#000000#aabbcc |
---|
| 325 | result_rsrc_list = [] |
---|
| 326 | [result_rsrc_list.append(item) for item in rsrc_list if item not in result_rsrc_list] |
---|
| 327 | skin_css_regdata = getResourceProperties(context, rsrc_name, rsrc_reg_props) # Get Data from CSS Regestry |
---|
| 328 | return result_rsrc_list, skin_css_regdata |
---|
| 329 | |
---|
| 330 | def copyDir(srcDirectory, dstDirectory, productName): |
---|
| 331 | """Recursive copying from ZMIskin-folder to FS one""" |
---|
| 332 | for item in os.listdir(srcDirectory): |
---|
| 333 | src_path = ospJoin(srcDirectory, item) |
---|
| 334 | dst_path = ospJoin(dstDirectory, item) |
---|
| 335 | if os.path.isfile(src_path): |
---|
| 336 | if os.path.exists(dst_path): |
---|
| 337 | continue |
---|
| 338 | f_sorce = open(src_path,'r') |
---|
| 339 | data = f_sorce.read() |
---|
| 340 | f_sorce.close() |
---|
| 341 | f_dst = open(dst_path,'w') |
---|
| 342 | f_dst.write(data) |
---|
| 343 | f_dst.close() |
---|
[68] | 344 | elif os.path.isdir(src_path) \ |
---|
| 345 | and not ".svn" in src_path: |
---|
[1] | 346 | if not os.path.exists(dst_path): |
---|
| 347 | os.mkdir(dst_path) |
---|
| 348 | copyDir(src_path, dst_path, productName) |
---|
| 349 | |
---|
[74] | 350 | def fsDirectoryViewsXML(folder_names, product_name, remove=False): |
---|
| 351 | pattern = """ <object name="%(folder_name)s" meta_type="Filesystem Directory View" |
---|
| 352 | directory="Products.%(product_name)s:skins/%(folder_name)s" %(remove)s/>\n""" |
---|
| 353 | xml = '' |
---|
| 354 | if type(folder_names) not in (type([]), type(())): |
---|
| 355 | folder_names = [folder_names,] |
---|
| 356 | for name in folder_names: |
---|
| 357 | xml += pattern % {'product_name' : product_name, \ |
---|
| 358 | 'folder_name' : name, \ |
---|
| 359 | 'remove' : remove and 'remove="True"' or '', \ |
---|
| 360 | } |
---|
| 361 | return xml |
---|
| 362 | |
---|
| 363 | def makeNewProduct(context, destinationDir, productName, productSkinName, \ |
---|
| 364 | zmi_skin_names, zmi_base_skin_name, subdir,\ |
---|
[1] | 365 | doesCustomizeSlots, left_slots, right_slots, slot_forming, main_column, \ |
---|
[74] | 366 | doesExportObjects, import_policy, dump_CSS, dump_JS, \ |
---|
| 367 | dump_portlets, dump_policy, dump_portlets_selection, dump_custom_views): |
---|
[1] | 368 | """Create new skin-product's directory and |
---|
[74] | 369 | copy skin-product template with little modification""" |
---|
| 370 | products_path = destinationDir |
---|
[1] | 371 | productPath = ospJoin(products_path, productName) |
---|
[74] | 372 | if not (productName in os.listdir(products_path)): |
---|
[1] | 373 | os.mkdir(productPath) |
---|
[74] | 374 | files_to_remove = [] |
---|
| 375 | files_to_add = [] |
---|
[1] | 376 | # Form CSS and JS importing list and regestry data (looking in subdir too) for Plone 2.1.0+ |
---|
[74] | 377 | stylesheets_xml = '' |
---|
| 378 | javascripts_xml = '' |
---|
| 379 | #subdir = subdir or getToolByName(context, 'portal_skins')[zmi_skin_name] |
---|
| 380 | portal_setup = getToolByName(context, 'portal_setup') |
---|
[1] | 381 | result_css_list = skin_css_regdata = result_js_list = skin_js_regdata = [] |
---|
[74] | 382 | base_context = BaseContext(portal_setup, portal_setup.getEncoding()) |
---|
[1] | 383 | if dump_CSS: |
---|
[74] | 384 | res_reg = getToolByName(context, 'portal_css', None) |
---|
| 385 | exporter = zapi.queryMultiAdapter((res_reg, base_context), IBody) |
---|
| 386 | if exporter is not None: |
---|
| 387 | stylesheets_xml = exporter.body |
---|
| 388 | #result_css_list, skin_css_regdata = getResourceListRegdata(context, subdir, |
---|
| 389 | #CSS_PATTERN, 'portal_css', CSS_REG_PROPS) |
---|
| 390 | if stylesheets_xml == '': |
---|
| 391 | files_to_remove.append(ospJoin('profiles', 'default', 'cssregistry.xml')) |
---|
[1] | 392 | if dump_JS: |
---|
[74] | 393 | res_reg = getToolByName(context, 'portal_javascripts', None) |
---|
| 394 | exporter = zapi.queryMultiAdapter((res_reg, base_context), IBody) |
---|
| 395 | if exporter is not None: |
---|
| 396 | javascripts_xml = exporter.body |
---|
| 397 | #result_js_list, skin_js_regdata = getResourceListRegdata(context, subdir, |
---|
| 398 | #JS_PATTERN, 'portal_javascripts', JS_REG_PROPS) |
---|
| 399 | if javascripts_xml == '': |
---|
| 400 | files_to_remove.append(ospJoin('profiles', 'default', 'jsregistry.xml')) |
---|
| 401 | |
---|
| 402 | slots = () |
---|
| 403 | if dump_portlets: |
---|
| 404 | slots = dumpPortlets(context, dump_policy, dump_portlets_selection) |
---|
| 405 | |
---|
[1] | 406 | # Get Slots customization information |
---|
| 407 | if not doesCustomizeSlots: |
---|
| 408 | left_slots = right_slots = None |
---|
| 409 | slot_forming = main_column = None |
---|
[74] | 410 | |
---|
| 411 | # Prepare XML strings for add to skins.xml |
---|
| 412 | skin_layers = buildSkinLayers(context, zmi_base_skin_name) |
---|
| 413 | |
---|
| 414 | # Prepare profiles |
---|
| 415 | default_marker, afterinstall_marker, uninstall_marker = {}, {}, {} |
---|
| 416 | profiles = ['default', 'afterinstall', 'uninstall'] |
---|
| 417 | profiles_path = ospJoin(products_path, productName, 'profiles') |
---|
| 418 | for profile in profiles: |
---|
| 419 | varname = "%s_marker" % profile |
---|
| 420 | file_name = "%s_%s.txt" % (productName.lower(), profile) |
---|
| 421 | locals()[varname].update({'fname' : file_name, \ |
---|
| 422 | 'fpath' : ospJoin(profiles_path, profile, file_name), \ |
---|
| 423 | 'fdata' : "# Marker file for %s profile of %s skin" % \ |
---|
| 424 | (profile, productName) }) |
---|
| 425 | files_to_add.append(locals()[varname]) |
---|
| 426 | |
---|
| 427 | # dump customized objects from portal_view_customization |
---|
| 428 | custom_views = [] |
---|
| 429 | if dump_custom_views: |
---|
| 430 | custom_views = dumpPortalViewCustomization(context) |
---|
| 431 | |
---|
[1] | 432 | # Copy skin_template to SKIN_PRODUCT directory |
---|
[74] | 433 | templatePath = ospJoin(PRODUCTS_PATH, PROJECTNAME, TEMPLATE_PATH) |
---|
[1] | 434 | copyDir(templatePath, productPath, productName) |
---|
| 435 | # Form data dictionary and form Skin Product's files |
---|
| 436 | conf_dict = {"IMPORT_POLICY" : import_policy \ |
---|
| 437 | ,"GENERATOR_PRODUCT" : PROJECTNAME \ |
---|
| 438 | ,"SKIN_PRODUCT_NAME" : productName \ |
---|
| 439 | ,"SKIN_NAME" : productSkinName \ |
---|
| 440 | ,"BASE_SKIN_NAME" : zmi_base_skin_name \ |
---|
| 441 | ,"DUMP_CSS": not not dump_CSS \ |
---|
| 442 | ,"DUMP_JS": not not dump_JS \ |
---|
| 443 | ,"CSS_LIST" : str(result_css_list) \ |
---|
| 444 | ,"JS_LIST" : str(result_js_list) \ |
---|
| 445 | ,"SKIN_CSS_REGDATA" : str(skin_css_regdata) \ |
---|
| 446 | ,"SKIN_JS_REGDATA" : str(skin_js_regdata) \ |
---|
| 447 | ,"LEFT_SLOTS" : str(left_slots) \ |
---|
| 448 | ,"RIGHT_SLOTS" : str(right_slots) \ |
---|
| 449 | ,"SLOT_FORMING" : slot_forming \ |
---|
| 450 | ,"MAIN_COLUMN" : main_column \ |
---|
[74] | 451 | ,"product_name" : productName \ |
---|
| 452 | ,"skin_name" : productSkinName \ |
---|
| 453 | ,"skin_name_lowercase" : productSkinName.lower() \ |
---|
| 454 | ,"skin_name_capital" : '%s%s' % (productSkinName[0].upper(), productSkinName[1:]) \ |
---|
| 455 | ,"product_name_lowercase" : productName.lower() \ |
---|
| 456 | ,"viewlets_zcml" : '' \ |
---|
| 457 | ,"stylesheets_xml" : stylesheets_xml \ |
---|
| 458 | ,"javascripts_xml" : javascripts_xml \ |
---|
| 459 | ,"version" : time.strftime('%Y%m%d') \ |
---|
| 460 | ,"slot_structure" : str(slots) \ |
---|
| 461 | ,"skin_layers" : skin_layers \ |
---|
| 462 | ,"custom_views" : str(custom_views) \ |
---|
| 463 | ,"directory_views_xml" : fsDirectoryViewsXML(zmi_skin_names, productName) \ |
---|
| 464 | ,"remove_directory_views_xml" : fsDirectoryViewsXML(zmi_skin_names, productName, remove=True) \ |
---|
| 465 | ,"creation_date" : time.strftime('%d/%m/%Y') \ |
---|
| 466 | ,"install_profile_marker" : default_marker['fname'] \ |
---|
| 467 | ,"afterinstall_profile_marker" : afterinstall_marker['fname'] \ |
---|
| 468 | ,"uninstall_profile_marker" : uninstall_marker['fname'] \ |
---|
| 469 | } |
---|
[1] | 470 | sp_updated_files = ['config.py' \ |
---|
| 471 | ,'README.txt' \ |
---|
[74] | 472 | ,'HISTORY.txt' \ |
---|
| 473 | ,'setuphandlers.py' \ |
---|
| 474 | ,'uninstallhandlers.py' \ |
---|
| 475 | ,'profiles.zcml' \ |
---|
| 476 | ,'utils.py' \ |
---|
| 477 | ,'configure.zcml' \ |
---|
| 478 | ,'skins.zcml' \ |
---|
| 479 | ,ospJoin('Extensions', 'Install.py')\ |
---|
| 480 | ,ospJoin('browser', 'interfaces.py')\ |
---|
| 481 | ,ospJoin('browser', 'viewlets.zcml')\ |
---|
| 482 | ,ospJoin('browser', 'configure.zcml')\ |
---|
| 483 | ,ospJoin('profiles', 'default', 'skins.xml')\ |
---|
| 484 | ,ospJoin('profiles', 'default', 'cssregistry.xml')\ |
---|
| 485 | ,ospJoin('profiles', 'default', 'jsregistry.xml')\ |
---|
| 486 | ,ospJoin('profiles', 'default', 'propertiestool.xml')\ |
---|
| 487 | ,ospJoin('profiles', 'afterinstall', 'import_steps.xml')\ |
---|
| 488 | ,ospJoin('profiles', 'uninstall', 'import_steps.xml')\ |
---|
| 489 | ,ospJoin('profiles', 'uninstall', 'skins.xml')\ |
---|
| 490 | ,ospJoin('browser', 'configure.zcml') \ |
---|
| 491 | #,ospJoin('profiles', 'uninstall', 'cssregistry.xml')\ |
---|
| 492 | #,ospJoin('profiles', 'uninstall', 'jsregistry.xml')\ |
---|
| 493 | ] |
---|
[1] | 494 | for fp in sp_updated_files: |
---|
| 495 | fillinFileTemplate(ospJoin(productPath, fp), dict=conf_dict) |
---|
[74] | 496 | for fp in files_to_remove: |
---|
| 497 | os.remove(ospJoin(productPath,fp)) |
---|
| 498 | for data in files_to_add: |
---|
| 499 | f = file(data['fpath'],'w') |
---|
| 500 | f.write(data['fdata']) |
---|
| 501 | f.close() |
---|