def test_sub_directory_permissions(self): directory = Directory(name=os.path.join(self.tempdir, 'root')) directory.fs_mode = 0o777 subdir1 = directory['subdir1'] = Directory() subdir1.fs_mode = 0o770 subdir2 = directory['subdir2'] = Directory() subdir2.fs_mode = 0o755 directory() dir_path = os.path.join(*directory.fs_path) self.assertEqual(os.stat(dir_path).st_mode & 0o777, 0o777) dir_path = os.path.join(*subdir1.fs_path) self.assertEqual(os.stat(dir_path).st_mode & 0o777, 0o770) dir_path = os.path.join(*subdir2.fs_path) self.assertEqual(os.stat(dir_path).st_mode & 0o777, 0o755) directory = Directory(name=os.path.join(self.tempdir, 'root')) self.assertEqual(directory.fs_mode, 0o777) self.assertEqual(directory['subdir1'].fs_mode, 0o770) self.assertEqual(directory['subdir2'].fs_mode, 0o755)
def target(self, path): target = Directory(path) # XXX: hook elsewhere, this ignores are self contained buildout related target.ignores = [ 'eggs', 'devsrc', 'parts', 'bin', 'develop-eggs', 'var', 'env', 'local', 'lib', ] alsoProvides(target, IRoot) alsoProvides(target, ITarget) return target
def test_directory_permissions(self): dirpath = os.path.join(self.tempdir, 'root') directory = Directory(name=dirpath) self.assertEqual(directory.fs_mode, None) directory.fs_mode = 0o750 directory() self.assertEqual(os.stat(dirpath).st_mode & 0o777, 0o750) directory.fs_mode = 0o700 directory() self.assertEqual(os.stat(dirpath).st_mode & 0o777, 0o700) directory = Directory(name=dirpath) self.assertEqual(directory.fs_mode, 0o700)
def resourcedirectory(self, source, target): """Create resource directory and register in ZCML. """ egg = egg_source(source) eggname = egg.name targetdir = read_target_node(source, target.target) if 'resources' not in targetdir.keys(): targetdir['resources'] = Directory() path = targetdir.path path.append('browser.zcml') fullpath = os.path.join(*path) if 'browser.zcml' not in targetdir: zcml = ZCMLFile(fullpath) zcml.nsmap['browser'] = 'http://namespaces.zope.org/browser' targetdir['browser.zcml'] = zcml else: zcml = targetdir['browser.zcml'] addZcmlRef(targetdir, zcml) # add the resourceDirectory stmt zcautils.set_zcml_directive(targetdir, 'browser.zcml', 'include', 'package', "zope.browserresource", file="meta.zcml") if not zcml.filter( tag='browser:resourceDirectory', attr='name', value=eggname): directory = SimpleDirective(name='browser:resourceDirectory', parent=zcml) directory.attrs['name'] = eggname directory.attrs['directory'] = 'resources'
def generate_vanilla_profile(self, source, target): egg = egg_source(source) if not is_generator_egg(egg): return tgv = TaggedValues(source) profilename = tgv.direct('name', 'generator:profile', source.name) basepath = os.path.dirname(agx.generator.generator.__file__) profilepath = os.path.join(basepath, 'resources', 'vanilla_profile') # read the model files model_di = open(os.path.join(profilepath, 'model.profile.di')).read() model_uml = open(os.path.join(profilepath, 'model.profile.uml')).read() model_notation = open( os.path.join(profilepath, 'model.profile.notation')).read() eggdir = read_target_node(egg_source(source), target.target) # create profiles dir if 'profiles' not in eggdir.keys(): profiles = Directory() profiles.__name__ = 'profiles' eggdir['profiles'] = profiles profiles = eggdir['profiles'] # add the model files with correct name and change the references if profilename + '.profile.di' not in profiles.keys(): ff = File() ff._data = model_di.replace( 'model.profile.notation', profilename + '.profile.notation') profiles[profilename + '.profile.di'] = ff if profilename + '.profile.uml' not in profiles.keys(): ff = File() ff._data = model_uml.replace('profilename_changeme', profilename) profiles[profilename + '.profile.uml'] = ff if profilename + '.profile.notation' not in profiles.keys(): ff = File() ff._data = model_notation.replace( 'model.profile.uml', profilename + '.profile.uml') profiles[profilename + '.profile.notation'] = ff
def gsprofiledirectories(self, source, target): """Create GS profile directories. """ package = target.anchor # create profiles directory and subdirectories if not exists if not 'profiles' in package: package['profiles'] = Directory() # create default profile folder if not exists if not 'default' in package['profiles']: package['profiles']['default'] = Directory() # create uninstall profile folder if not exists if not 'uninstall' in package['profiles']: package['profiles']['uninstall'] = Directory() # set child node factories for xml files package['profiles']['default'].factories['.xml'] = DTMLTemplate package['profiles']['uninstall'].factories['.xml'] = DTMLTemplate
def generate_vanilla_profile(self, source, target): egg = egg_source(source) if not is_generator_egg(egg): return tgv = TaggedValues(source) profilename = tgv.direct('name', 'generator:profile', source.name) basepath = os.path.dirname(agx.generator.generator.__file__) profilepath = os.path.join(basepath, 'resources', 'vanilla_profile') # read the model files model_di = open(os.path.join(profilepath, 'model.profile.di')).read() model_uml = open(os.path.join(profilepath, 'model.profile.uml')).read() model_notation = open(os.path.join(profilepath, 'model.profile.notation')).read() eggdir = read_target_node(egg_source(source), target.target) # create profiles dir if 'profiles' not in eggdir.keys(): profiles = Directory() profiles.__name__ = 'profiles' eggdir['profiles'] = profiles profiles = eggdir['profiles'] # add the model files with correct name and change the references if profilename + '.profile.di' not in profiles.keys(): ff = File() ff._data = model_di.replace('model.profile.notation', profilename + '.profile.notation') profiles[profilename + '.profile.di'] = ff if profilename + '.profile.uml' not in profiles.keys(): ff = File() ff._data = model_uml.replace('profilename_changeme', profilename) profiles[profilename + '.profile.uml'] = ff if profilename + '.profile.notation' not in profiles.keys(): ff = File() ff._data = model_notation.replace('model.profile.uml', profilename + '.profile.uml') profiles[profilename + '.profile.notation'] = ff
def typeview(self, source, target): schema = getschemaclass(source, target) klass = read_target_node(source, target.target) module = schema.parent if IModule.providedBy(module): directory = module.parent else: directory = module nsmap = { None: 'http://namespaces.zope.org/zope', 'plone': 'http://namespaces.plone.org/plone', 'grok': 'http://namespaces.zope.org/grok', } zcmlfile = get_zcml(directory, 'configure.zcml', nsmap=nsmap) # include grok:grok directive if not set yet set_zcml_directive(directory, 'configure.zcml', 'grok:grok', 'package', '.') classname = '%sView' % klass.classname if module.classes(classname): view = module.classes(classname)[0] else: view = python.Class() module[uuid.uuid4()] = view view.classname = classname if not 'dexterity.DisplayForm' in view.bases: view.bases.append('dexterity.DisplayForm') context = "grok.context(%s)" % schema.classname require = "grok.require('zope2.View')" context_exists = False require_exists = False for block in view.blocks(): for line in block.lines: if line == context: context_exists = True if line == require: require_exists = True block = python.Block() block.__name__ = str(uuid.uuid4()) if not context_exists: block.lines.append(context) if not require_exists: block.lines.append(require) if block.lines: view.insertfirst(block) template = False for attr in view.attributes(): if 'template' in attr.targets: template = attr break if not template: template = python.Attribute() template.targets = ['template'] view[str(uuid.uuid4())] = template template.value = "PageTemplate('templates/%s.pt')" \ % klass.classname.lower() imp = Imports(module) imp.set('plone.directives', [['dexterity', None]]) imp.set('five', [['grok', None]]) imp.set('grokcore.view.components', [['PageTemplate', None]]) directory = module.parent template_name = '%s.pt' % klass.classname.lower() template = 'templates/%s' % template_name if not 'templates' in directory: directory['templates'] = Directory() templates = directory['templates'] templates.factories['.pt'] = XMLTemplate if template_name not in templates: pt = templates[template_name] = XMLTemplate() pt.template = 'agx.generator.dexterity:templates/displayform.pt'
def gsprofiletypes(self, source, target): """Create or extend types.xml and corresponding TYPENAME.xml. """ egg = egg_source(source) package = read_target_node(egg, target.target) default = package['profiles']['default'] # create types foder if not exists if not 'types' in default: default['types'] = Directory() # read or create types.xml if 'types.xml' in default: types = default['types.xml'] else: types = default['types.xml'] = DTMLTemplate() # set template and params if not done yet if not types.template: types.template = 'agx.generator.plone:templates/types.xml' types.params['portalTypes'] = list() # calculate type name full_name = type_id(source, target.target) # add portal type to types.xml types.params['portalTypes'].append({ 'name': full_name, 'meta_type': 'Dexterity FTI', }) # add TYPENAME.xml to types folder # read or create TYPENAME.xml name = '%s.xml' % full_name if name in default['types']: type = default['types'][name] else: type = default['types'][name] = DTMLTemplate() # set template used for TYPENAME.xml type.template = 'agx.generator.plone:templates/type.xml' # set template params # FTI properties can be added by prefixing param key with 'fti:' # XXX: calculate from model content_icon = '++resource++%s/%s_icon.png' % ( egg.name, source.name.lower()) type.params['ctype'] = dict() # general type.params['ctype']['name'] = full_name type.params['ctype']['meta_type'] = 'Dexterity FTI' type.params['ctype']['i18n_domain'] = egg.name # basic metadata type.params['ctype']['title'] = source.name type.params['ctype']['description'] = source.name type.params['ctype']['content_icon'] = content_icon type.params['ctype']['allow_discussion'] = 'False' type.params['ctype']['global_allow'] = 'True' # XXX: maybe False for non contained ones? type.params['ctype']['filter_content_types'] = 'True' type.params['ctype']['allowed_content_types'] = list() # dexterity specific class_ = read_target_node(source, target.target) schemaclass=getschemaclass(source,target) schema = '%s.%s' % (class_base_name(class_), schemaclass.classname) # XXX: check whether container or leaf if token(str(class_.uuid), False, dont_generate=False).dont_generate: klass = 'plone.dexterity.content.Item' else: klass = '%s.%s' % (class_base_name(class_), class_.classname) type.params['ctype']['schema'] = schema type.params['ctype']['klass'] = klass type.params['ctype']['add_permission'] = 'cmf.AddPortalContent' type.params['ctype']['behaviors'] = list() # View information type.params['ctype']['view_methods'] = ['view'] type.params['ctype']['default_view'] = 'view' type.params['ctype']['default_view_fallback'] = 'False' # Method aliases type.params['ctype']['aliases'] = list() type.params['ctype']['aliases'].append({ 'from': '(Default)', 'to': '(dynamic view)', }) type.params['ctype']['aliases'].append({ 'from': 'view', 'to': '(selected layout)', }) type.params['ctype']['aliases'].append({ 'from': 'edit', 'to': '@@edit', }) type.params['ctype']['aliases'].append({ 'from': 'sharing', 'to': '@@sharing', }) # Actions type.params['ctype']['actions'] = list() type.params['ctype']['actions'].append({ 'action_id': 'edit', 'title': 'Edit', 'category': 'object', 'condition_expr': '', 'url_expr': 'string:${object_url}/edit', 'visible': 'True', 'permissions': ['Modify portal content'], }) type.params['ctype']['actions'].append({ 'action_id': 'view', 'title': 'View', 'category': 'object', 'condition_expr': '', 'url_expr': 'string:${object_url}/view', 'visible': 'True', 'permissions': ['View'], })
def plonebrowserview(self, source, target): view = source if view.stereotype('pyegg:function'): # XXX: <<function>> <<adapter>> on class return tok = token(str(view.uuid), True, browserpages=[]) pack = source.parent target = read_target_node(pack, target.target) targetclass = read_target_node(view, target) if isinstance(target, python.Module): targetdir = target.parent else: targetdir = target path = targetdir.path path.append('browser.zcml') fullpath = os.path.join(*path) if 'browser.zcml' not in targetdir: zcml = ZCMLFile(fullpath) zcml.nsmap['browser'] = 'http://namespaces.zope.org/browser' targetdir['browser.zcml'] = zcml else: zcml = targetdir['browser.zcml'] addZcmlRef(targetdir, zcml) targettok = token(str(targetclass.uuid), True, browserpages=[], provides=None) _for = [token(str(context.supplier.uuid), False).fullpath \ for context in tok.browserpages] or ['*'] classpath = class_full_name(targetclass) tgv = TaggedValues(view) # create the templates dir if 'templates' not in targetdir.keys(): targetdir['templates'] = Directory('templates') templates = targetdir['templates'] templates.factories['.pt'] = XMLTemplate #create the browser:page entries for bp in tok.browserpages or [None]: #name of view: if it should have a constant name, change the last param viewname = tgv.direct('name', 'plone:view', None) or \ tgv.direct('name', 'plone:dynamic_view', view.xminame.lower()) name_raw = tgv.direct('name', 'plone:view', None) or \ tgv.direct('name', 'plone:vdynamic_view', None) name = name_raw or view.xminame.lower() template_name_raw = tgv.direct('template_name', 'plone:view', None) or \ tgv.direct('template_name', 'plone:dynamic_view', None) template_name = template_name_raw or name + '.pt' permission = tgv.direct('permission', 'plone:view', None) or \ tgv.direct('permission', 'plone:dynamic_view', None) layer = tgv.direct('layer', 'plone:view', None) or \ tgv.direct('layer', 'plone:dynamic_view', None) if bp: bptgv = TaggedValues(bp) bptok = token(str(bp.supplier.uuid), False) _for = bptok.fullpath print 'xminame:', bp, bp.xminame # consider uuid as an unset name if bp.xminame is None or re.match( '[\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12}', bp.xminame): bpname = None else: bpname = bp.xminame.lower() if bp.xminame: viewname = bp.xminame viewname = bptgv.direct('name', 'plone:view', None) or \ bptgv.direct('name', 'plone:dynamic_view', viewname) name = bptgv.direct('name', 'plone:view', None) or \ bptgv.direct('name', 'plone:dynamic_view', bpname or name) # override template name template_name = bptgv.direct( 'template_name', 'plone:view', None) or \ bptgv.direct( 'template_name', 'plone:dynamic_view', None) or \ template_name_raw or name + '.pt' permission = bptgv.direct('permission', 'plone:view', None) or \ bptgv.direct('permission', 'plone:dynamic_view', permission) layer = bptgv.direct('layer', 'plone:view', None) or \ bptgv.direct('layer', 'plone:dynamic_view', layer) else: _for = '*' found_browserpages = zcml.filter(tag='browser:page', attr='name', value=viewname) browser = None templatepath = 'templates/' + template_name if found_browserpages: for br in found_browserpages: #check if it really matches if br.attrs.get('class') == classpath and \ _for == br.attrs['for']: browser = br break if not browser: browser = SimpleDirective(name='browser:page', parent=zcml) browser.attrs['for'] = _for if viewname and not viewname is UNSET: browser.attrs['name'] = viewname browser.attrs['class'] = classpath browser.attrs['template'] = templatepath browser.attrs['permission'] = permission or 'zope2.View' if layer: browser.attrs['layer'] = layer # spit out the page vanilla template if template_name not in templates.keys(): pt = XMLTemplate() templates[template_name] = pt # set template for viewtemplate pt.template = 'agx.generator.plone:templates/viewtemplate.pt'
def test_file_factories(self): # Factories. resolved by registration length, shortest last self.check_output("""\ {...} """, str(node.ext.directory.file_factories)) dir = Directory(name=self.tempdir) self.assertEqual(dir.factories, {}) self.assertEqual(dir._factory_for_ending('foo'), None) def dummy_txt_factory(): pass # pragma no cover def dummy_foo_factory(): pass # pragma no cover node.ext.directory.file_factories['.txt'] = dummy_txt_factory node.ext.directory.file_factories['foo.txt'] = dummy_foo_factory self.assertEqual(dir._factory_for_ending('bar.txt'), dummy_txt_factory) self.assertEqual(dir._factory_for_ending('foo.txt'), dummy_foo_factory) def dummy_local_txt_factory(): pass # pragma no cover dir.factories['.txt'] = dummy_local_txt_factory self.assertEqual( dir._factory_for_ending('bar.txt'), dummy_local_txt_factory ) self.assertEqual( dir._factory_for_ending('foo.txt'), dummy_foo_factory ) def dummy_local_foo_factory(): pass # pragma no cover dir.factories['foo.txt'] = dummy_local_foo_factory self.assertEqual( dir._factory_for_ending('foo.txt'), dummy_local_foo_factory ) del node.ext.directory.file_factories['.txt'] del node.ext.directory.file_factories['foo.txt'] del dir.factories['.txt'] # needed? del dir.factories['foo.txt'] # needed? # Factories can be given at directory init time directory = Directory(name=self.tempdir, factories={ '.txt': dummy_txt_factory }) self.assertEqual(directory.factories, {'.txt': dummy_txt_factory}) # Try to read file by broken factory, falls back to ``File`` class SaneFile(File): pass def sane_factory(): return SaneFile() filepath = os.path.join(self.tempdir, 'file.txt') with open(filepath, 'w') as f: f.write('') directory = Directory(name=self.tempdir, factories={ '.txt': sane_factory }) expected = '<SaneFile object \'file.txt\' at ' self.assertTrue(str(directory['file.txt']).startswith(expected)) def broken_factory(param): return SaneFile() # pragma no cover directory = Directory(name=self.tempdir, factories={ '.txt': broken_factory }) expected = '<File object \'file.txt\' at ' self.assertTrue(str(directory['file.txt']).startswith(expected)) expected = ( 'ERROR: File creation by factory failed. Fall back to ``File``. ' 'Reason: {}'.format(( 'broken_factory() takes exactly 1 argument (0 given)' ) if IS_PY2 else ( 'broken_factory() missing 1 required positional argument: ' '\'param\'' )) ) self.assertEqual(dummy_logger.messages, [expected]) # Create directory and read already created file by default factory directory = Directory(name=self.tempdir) self.assertEqual(list(directory.keys()), ['file.txt']) expected = '<File object \'file.txt\' at ' self.assertTrue(str(directory['file.txt']).startswith(expected))