source: products/qPloneSkinDump/trunk/utils.py @ 1

Last change on this file since 1 was 1, checked in by myroslav, 18 years ago

Building directory structure

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