root/qPloneSkinDump/branches/multipleslots/utils.py

Revision 936 (checked in by koval, 1 year ago)

now dumped skin product will add layer with generated main_template.pt after custom if required

  • Property svn:eol-style set to native
Line 
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     # If in skin's subfolder - get its path
35     skinp, subp = [obj.getPhysicalPath() for obj in [skin_obj, subdir]]
36     if len(subp) != len(skinp):
37         # adapt skinpath for creating directory
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     # In case of recursable call go into subdir in skin folder.
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     # Create directory in FS if not yet exist
63     if not os.path.exists( skinpath ):
64         os.makedirs( skinpath )
65     # Loop of copying content from ZMIskin-folder to FSskin-folder
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             # Adding to .objects all acceptable meta_types.
73             # Fixing bug of id-meta_type confusing.
74             obj_meta[id] = meta_type
75         if meta_type == 'Folder':
76             # very plone specific
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             #writeProps( o, skinpath )      # write object's properties
88             # extract content from object(depend on metatype) and write it to the file
89             writeFileContent( o, skinpath, getData(o, meta_type) )
90             deletelist.append( o.getId() )
91         else:
92             print 'method ignoring ', meta_type
93     # write '.objects' file to directory if present objects with id without extension
94     if obj_meta :
95         writeObjectsMeta(obj_meta, skinpath)
96     # delete objects from the skin, if request
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             # very plone specific
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)#---CSS--#000000#aabbcc
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)   # Get Data from CSS Regestry
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     # Form CSS and JS importing list and regestry data (looking in subdir too) for Plone 2.1.0+
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     # Get Slots customization information
185     if not doesCustomizeSlots:
186         left_slots = right_slots = None
187         slot_forming = main_column = None
188     # Copy skin_template to SKIN_PRODUCT directory
189     templatePath = ospJoin(products_path, PROJECTNAME, TEMPLATE_PATH)
190     copyDir(templatePath, productPath, productName)
191
192     # get name of the subfolder where generated template was placed
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     # Form data dictionary and form Skin Product's files
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)
Note: See TracBrowser for help on using the browser.