def _set_message(self, context, source, target=freeze([u'']), comments=freeze([]), reference=None, fuzzy=False): if context is not None and isinstance(context, (str, unicode)): context = [context] if isinstance(source, (str, unicode)): source = [source] if isinstance(target, (str, unicode)): target = [target] # Make the key if context is not None: first_part = ''.join(context) else: first_part = None second_part = ''.join(source) key = (first_part, second_part) # Already this entry ? messages = self.messages if key in messages: unit = messages[key] else: unit = POUnit(comments, context, source, target, {}, fuzzy) messages[key] = unit # Add the reference and return if reference is None: return unit unit.references.setdefault(reference[0], []).append(reference[1]) return unit
def test_multiplication(self): # frozenlist * n alist = freeze([1, 2]) * 2 self.assert_(isinstance(alist, frozenlist)) self.assertEqual(alist, [1, 2, 1, 2]) # n * frozenlist alist = 2 * freeze([1, 2]) self.assert_(isinstance(alist, frozenlist)) self.assertEqual(alist, [1, 2, 1, 2])
def test_concatenation(self): """Like set objects, the concatenation of a frozenlist and a list must preserve the type of the left argument. """ # frozenlist + frozenlist alist = freeze([]) + freeze([]) self.assert_(isinstance(alist, frozenlist)) # frozenlist + list alist = freeze([]) + [] self.assert_(isinstance(alist, frozenlist)) # list + frozenlist alist = [] + freeze([]) self.assert_(not isinstance(alist, frozenlist))
def stl_odf(document=None, namespace=freeze({}), element=None): """Apply the given namespace to the document (or element) where matching "${xxx}" are replaced by their value. Clone of itools.stl for odf_document. Arguments: document -- odf_document namespace -- dict Return: modified "document" argument """ # Input if element is None: element = document.get_body() # Initialize the namespace stacks stack = NamespaceStack() stack.append(namespace) repeat_stack = NamespaceStack() # Process stream = process(element, stack, repeat_stack) # Return return stream
def come_back(self, message, goto=None, keep=freeze([]), **kw): goto = super(CMSContext, self).come_back(message, goto, keep, **kw) # Keep fancybox if 'fancybox' in self.uri.query: goto.query['fancybox'] = '1' # Ok return goto
def _get_schema(self, resource, context): pdm = self.pub_datetime_mandatory return freeze({ 'tags': TagsList(multiple=True, states=[]), 'pub_date': Date(mandatory=pdm), 'pub_time': TimeWithoutSecond(mandatory=pdm), 'thumbnail': URI(multilingual=True)})
def stl(document=None, namespace=freeze({}), prefix=None, events=None, mode='events', skip=(DOCUMENT_TYPE,)): # Input encoding = 'utf-8' if events is None: events = document.events # Prefix if prefix is not None: stream = set_prefix(events, prefix) events = list(stream) elif type(events) in (GeneratorType, XMLParser): events = list(events) # Initialize the namespace stacks stack = NamespaceStack() stack.append(namespace) repeat = NamespaceStack() # Process stream = process(events, 0, len(events), stack, repeat, encoding, skip) # Return if mode == 'events': return stream elif mode == 'xml': return stream_to_str(stream, encoding) elif mode == 'xhtml': return stream_to_str_as_xhtml(stream, encoding) elif mode == 'html': return stream_to_str_as_html(stream, encoding) raise ValueError, 'unexpected mode "%s"' % mode
def _get_schema(self, resource, context): base_schema = DBResource_Edit._get_schema(self, resource, context) return freeze(merge_dicts(base_schema, display_title=Boolean, render=OpenLayerRender(mandatory=True), width=Integer, height=Integer, address=Unicode, latitude=Decimal, longitude=Decimal, zoom=Integer, # Hack gps=String))
def test_incremental_mul(self): a_frozen_list = freeze([1, 2, 3]) try: a_frozen_list *= 2 except TypeError: pass else: self.assert_(False)
def test_incremental_add(self): a_frozen_list = freeze([1, 2, 3]) try: a_frozen_list += [4, 5] except TypeError: pass else: self.assert_(False)
def _get_schema(self, resource, context): return freeze(merge_dicts( BaseTheme_Edit._get_schema(self, resource, context), custom_data=String, banner_title=Multilingual, banner_path=URI(multilingual=True, parameters_schema={'lang': String}), class_skin=NeutralClassSkin(mandatory=True)))
def get_widgets(self, resource, context): proxy = super(EasyNewInstance_WithOrderer, self) addons = [ state_widget, ClassSelectorWidget('class_id', title=MSG(u'Resource type'), has_empty_option=False), RadioWidget('order', title=self.order_widget_title, has_empty_option=False) ] return freeze(proxy.get_widgets(resource, context) + addons)
def __init__(self, comments, context, source, target, references=freeze({}), fuzzy=False): self.comments = comments self.references = references self.context = context self.source = source self.target = target self.fuzzy = fuzzy
def _get_schema(self, resource, context): schema = {'timestamp': DateTime(readonly=True)} # Add edit_schema items schema = merge_dicts(schema, self.edit_schema) # If WorkflowAware we add state if 'state' not in schema and isinstance(resource, WorkflowAware): schema['state'] = StaticStateEnumerate(workflow=resource.workflow) return freeze(schema)
def _get_schema(self, resource, context): tags_schema = TagsAware_Edit._get_schema(self, resource, context) return freeze(merge_dicts( contact_schema, # crm_p_lastname and crm_p_status are mandatory crm_p_lastname=contact_schema['crm_p_lastname']( mandatory=True), crm_p_status=contact_schema['crm_p_status'](mandatory=True), # Tags tags=tags_schema['tags']))
def _get_widgets(self, resource, context): return freeze( [DualSelectWidget('tags', title=MSG(u'Tags'), is_inline=True, has_empty_option=False), ImageSelectorWidget('thumbnail', title=MSG(u'Thumbnail')), DateWidget('pub_date', title=MSG(u'Publication date (used by RSS and tags)')), TextWidget('pub_time', tip=MSG(u'hour:minute'), size=5, maxlength=5, title=MSG(u'Publication time (used by RSS and tags)'))])
def _get_schema(self, resource, context): schema = {} if getattr(resource, 'edit_show_meta', False) is True: schema['description'] = Unicode(multilingual=True) schema['subject'] = Unicode(multilingual=True) schema = merge_dicts(self.base_schema, schema, resource.edit_schema) # FIXME Hide/Show title if getattr(resource, 'display_title', True) is False: del schema['title'] return freeze(schema)
def _get_schema(self, resource, context): schema = merge_dicts( HTMLEditView._get_schema(self, resource, context), # other title_link_schema, display_title=Boolean) # Delete unused description/subject(keywords) del schema['description'] del schema['subject'] return freeze(schema)
def _get_schema(self, resource, context): tags_schema = TagsAware_Edit._get_schema(self, resource, context) return freeze( merge_dicts( company_schema, # title is mandatory title=company_schema["title"](mandatory=True), # Tags tags=tags_schema["tags"], ) )
def _get_widgets(self, resource, context): base_widgets = HTMLEditView._get_widgets(self, resource, context) # Delete unused description/subject(keywords) widgets = [ widget for widget in base_widgets if widget.name not in ('description', 'subject', 'state', 'data') ] return freeze(widgets + [ display_title_widget, PathSelectorWidget('title_link', title=MSG(u'Title link')), RadioWidget('title_link_target', title=MSG(u'Title link target'), has_empty_option=False, oneline=True), advance_rte_widget, state_widget ])
def _get_widgets(self, resource, context): widgets = [timestamp_widget] # Add edit_widgets items widgets.extend(self.edit_widgets) # If workfloware we add state if isinstance(resource, WorkflowAware): for w in widgets: if w.name == 'state': break else: widgets.append(state_widget) return freeze(widgets)
def _get_widgets(self, resource, context): # Remove logo widget return freeze( BaseTheme_Edit._get_widgets(self, resource, context)[:2] + [MultilineWidget('custom_data', title=MSG(u"Custom data"), rows=19, cols=69), TextWidget('banner_title', title=MSG(u'Banner title'), tip=MSG(u'(Use as banner if there is no image banner)')), ImageSelectorWidget('banner_path', title=MSG(u'Banner path'), width=640), SelectWidget('class_skin', title=MSG(u'Skin'), has_empty_option=False)])
def get_query_schema(self): proxy = super(Mission_AddContacts, self) schema = proxy.get_query_schema() context = get_context() company = self.get_default_company(context.resource, context) if company is None: return schema # Just a search term, not hard coded to search contacts from another # company return freeze(merge_dicts( schema, search_term=Unicode(default=company.get_property('title'))))
def get_files_affected(self, revisions): """Get the unordered set of files affected by a list of revisions. """ cmd = ['git', 'show', '--numstat', '--pretty=format:'] + revisions data = send_subprocess(cmd) lines = data.splitlines() files = set() for line in lines: if not line: continue before, after, filename = line.split('\t') files.add(filename) return freeze(files)
def _get_schema(self, resource, context): tags_schema = TagsAware_Edit._get_schema(self, resource, context) return freeze(merge_dicts( mission_schema, # title and crm_m_status are mandatory title=mission_schema['title'](mandatory=True), crm_m_status=mission_schema['crm_m_status'](mandatory=True), # resource needed crm_m_assigned=mission_schema['crm_m_assigned']( resource=resource), crm_m_cc=mission_schema['crm_m_cc'](resource=resource), # Tags tags=tags_schema['tags']))
def __init__(self, story, height=None, width=None, pos_x=None, pos_y=None, frame_attrs=freeze({}), attributes=freeze({}), pto_trailer=None, pto_header=None): Flowable.__init__(self) # get on story self.div_story = story # set frame style self.frame_attrs = {'leftPadding': 0, 'bottomPadding': 0, 'rightPadding': 0, 'topPadding': 0, 'showBoundary': 0} # PTO initialisation self.pto_trailer = pto_trailer self.pto_header = pto_header if frame_attrs is not None: self.frame_attrs.update(frame_attrs) for margin in ('topMargin', 'bottomMargin', 'leftMargin', 'rightMargin'): if margin in self.frame_attrs: del self.frame_attrs[margin] border = self.frame_attrs['showBoundary'] if isinstance(border, ShowBoundaryValue): border = border.width if border: for padding_attr in FRAME_PADDINGS_KEYS: self.frame_attrs[padding_attr] += border self.frame_width = width # Overflow # TODO to improve self.keep_in_frame = None style = attribute_style_to_dict(attributes.get((None, 'style'), '')) self.overflow = style.get('overflow-y', None) if self.overflow == 'hidden': self.overflow = 'truncate' else: self.overflow = None
def _get_widgets(self, resource, context): widgets = [] if getattr(resource, 'edit_show_meta', False) is True: widgets.extend([description_widget, subject_widget]) widgets = self.base_widgets + widgets + resource.edit_widgets # Cast frozen list into list widgets = list(widgets) # Add timestamp_widget widgets.append(timestamp_widget) # FIXME Hide/Show title if getattr(resource, 'display_title', True) is False: to_remove = [ w for w in widgets if w.name == 'title' ] if to_remove: widgets.remove(to_remove[0]) return freeze(widgets)
def _get_widgets(self, resource, context): proxy = super(Contact_AddForm, self) widgets = list(proxy._get_widgets(resource, context)) # Append mission widgets for widget in mission_widgets: name = widget.name if name not in self.mission_fields: continue if name in ('title', 'description', 'comment'): # Prefix double title and description widget = widget(name='mission_' + name) widgets.append(widget) # Existing mission widgets.append(HiddenWidget('mission')) return freeze(widgets)
def _get_widgets(self, resource, context): widgets = HTMLEditView._get_widgets(self, resource, context)[:] # Add display title widget display_title_widget = RadioWidget('display_title', title=MSG(u'Display title on webpage view ?')) widgets.insert(2, display_title_widget) # Tags widgets.extend(TagsAware_Edit._get_widgets(self, resource, context)) # TODO: Add a mechanism in ikaaro that allow to configure RTE new_widgets = [] for w in widgets: if issubclass(w, RTEWidget): w = Advance_RTEWidget(w.name, title=w.title) new_widgets.append(w) return freeze(new_widgets)
def _get_schema(self, resource, context): proxy = super(Contact_AddForm, self) schema = dict(proxy._get_schema(resource, context)) # Append mission schema for name, datatype in mission_schema.iteritems(): if name not in self.mission_fields: continue if name in ('title', 'description', 'comment'): # Prefix double title and description schema['mission_%s' % name] = datatype elif name in ('crm_m_assigned', 'crm_m_cc'): schema[name] = datatype(resource=resource) else: schema[name] = datatype # Existing mission schema['mission'] = String return freeze(schema)
class ConfirmSubscription(AutoForm): access = 'is_allowed_to_view' title = MSG(u"Subscribe") description = MSG( u'By confirming your subscription to this resource you will' u' receive an email every time this resource is modified.') schema = freeze({ 'key': String(mandatory=True), 'email': Email(mandatory=True) }) widgets = freeze([HiddenWidget('key'), ReadOnlyWidget('email')]) actions = [Button(access=True, title=MSG(u'Confirm subscription'))] key_status = 'S' msg_already = MSG_USER_ALREADY_SUBSCRIBED def get_value(self, resource, context, name, datatype): if name in ('key', 'email'): return context.get_query_value(name) proxy = super(ConfirmSubscription, self) return proxy.get_value(resource, context, name, datatype) def get_username(self, resource, context, key): # 1. Get the user email = context.get_form_value('email') user = context.root.get_user_from_login(email) if user is None: return None, MSG(u'Bad email') # 2. Get the user key username = user.name user_key = resource.get_register_key(username, self.key_status) if user_key is None: return username, self.msg_already # 3. Check the key if user_key != key: return username, MSG_BAD_KEY # 4. Ok return username, None def get_namespace(self, resource, context): key = context.get_form_value('key') username, error = self.get_username(resource, context, key) if error: return context.come_back(error, goto='./') proxy = super(ConfirmSubscription, self) return proxy.get_namespace(resource, context) def action(self, resource, context, form): username, error = self.get_username(resource, context, form['key']) if error: context.message = error return # Ok resource.reset_register_key(username) resource.after_register(username) return context.come_back(MSG_USER_SUBSCRIBED, goto='./')
class ConfigAccess(Folder): class_id = 'config-access' class_version = '20110606' class_title = MSG(u'Access Control') class_description = MSG(u'Choose the security policy.') class_icon48 = '/ui/ikaaro/icons/48x48/lock.png' # Configuration config_name = 'access' config_group = 'access' # Initialization _everything = freeze({'path': '/', 'path_depth': '*'}) default_rules = [ # Everybody can see the theme ('everybody', 'view', { 'path': '/config/theme', 'path_depth': '*' }), # Authenticated users can see any content ('authenticated', 'view', _everything), # Members can add new content and edit private content ('/config/groups/members', 'add', _everything), ('/config/groups/members', 'edit', _everything), # Reviewers can add new content, edit any content and publish ('/config/groups/reviewers', 'add', _everything), ('/config/groups/reviewers', 'edit', _everything), ('/config/groups/reviewers', 'share', _everything) ] def init_resource(self, **kw): super(ConfigAccess, self).init_resource(**kw) # Access rules rules = self.default_rules for group, permission, kw in rules: rule = self.make_resource(None, AccessRule, group=group) rule.set_value('permission', permission) for key in kw: rule.set_value('search_%s' % key, kw[key]) # API def _get_user_groups(self, user): user_groups = set(['everybody']) if user: user_groups.add('authenticated') user_groups.update(user.get_value('groups')) return user_groups, '/config/groups/admins' in user_groups def get_search_query(self, user, permission, class_id=None): # Special case: admins can see everything user_groups, is_admin = self._get_user_groups(user) if is_admin: return AllQuery() # 1. Back-office access rules rules_query = OrQuery() for rule in self.get_resources(): if rule.get_value('permission') != permission: continue if rule.get_value('group') not in user_groups: continue if permission == 'add': r_format = rule.get_value('search_format') if class_id and r_format and class_id != r_format: continue rules_query.append(rule.get_search_query()) # Case: anonymous if not user: return AndQuery(rules_query, PhraseQuery('share', 'everybody')) # Case: authenticated share_query = OrQuery(*[PhraseQuery('share', x) for x in user_groups]) share_query.append(PhraseQuery('share', str(user.abspath))) query = AndQuery(rules_query, share_query) if permission != 'share': return OrQuery(PhraseQuery('owner', str(user.abspath)), query) return query def has_permission(self, user, permission, resource, class_id=None): # The query query = AndQuery(self.get_search_query(user, permission, class_id), PhraseQuery('abspath', str(resource.abspath))) # Search results = get_context().search(query, user=user) return len(results) > 0 def get_document_types(self): return [AccessRule] # Views class_views = ['browse_content', 'add_rule', 'edit', 'commit_log'] browse_content = ConfigAccess_Browse add_rule = NewResource_Local(title=MSG(u'Add rule'))
def setup(ext_modules=freeze([])): mname = _getframe(1).f_globals.get('__name__') version = get_version(mname) config = get_config() # Initialize variables package_name = config.get_value('package_name') if package_name is None: package_name = config.get_value('name') packages = [package_name] package_data = {package_name: []} # The sub-packages if config.has_value('packages'): subpackages = config.get_value('packages') for subpackage_name in subpackages: packages.append('%s.%s' % (package_name, subpackage_name)) else: subpackages = [] # Write the manifest file if it does not exist if exists('MANIFEST'): filenames = [ x.strip() for x in open('MANIFEST').readlines() ] else: filenames = get_manifest() lines = [ x + '\n' for x in filenames ] open('MANIFEST', 'w').write(''.join(lines)) # Python files are included by default filenames = [ x for x in filenames if not x.endswith('.py') ] # The data files for line in filenames: path = line.split('/') if path[0] in subpackages: subpackage = '%s.%s' % (package_name, path[0]) files = package_data.setdefault(subpackage, []) files.append(join_path(*path[1:])) elif path[0] not in ('archive', 'docs', 'scripts', 'test'): package_data[package_name].append(line) # The scripts if config.has_value('scripts'): scripts = config.get_value('scripts') scripts = [ join_path(*['scripts', x]) for x in scripts ] else: scripts = [] author_name = config.get_value('author_name') # XXX Workaround buggy distutils ("sdist" don't likes unicode strings, # and "register" don't likes normal strings). if 'register' in argv: author_name = unicode(author_name, 'utf-8') classifiers = [ x for x in config.get_value('classifiers') if x ] core.setup(name = package_name, version = version, # Metadata author = author_name, author_email = config.get_value('author_email'), license = config.get_value('license'), url = config.get_value('url'), description = config.get_value('title'), long_description = config.get_value('description'), classifiers = classifiers, # Packages package_dir = {package_name: '.'}, packages = packages, package_data = package_data, # Requires / Provides requires = config.get_value('requires'), provides = config.get_value('provides'), # Scripts scripts = scripts, cmdclass = {'build_ext': OptionalBuildExt}, # C extensions ext_modules=ext_modules)
def get_list(self, key, default=freeze([])): """Like dict.get, but splits the result as a comma-separated list.""" return [x.strip() for x in self.get(key, default).split(",")]
def setup(ext_modules=freeze([])): config = get_config() package_root = config.get_value('package_root') # Build if any(x in argv for x in ('build', 'install', 'sdist')): version = build(config) else: version = get_package_version(package_root) # Initialize variables package_name = config.get_value('package_name') if package_name is None: package_name = config.get_value('name') packages = [package_name] package_data = {package_name: []} # The sub-packages if config.has_value('packages'): subpackages = config.get_value('packages') for subpackage_name in subpackages: packages.append('%s.%s' % (package_name, subpackage_name)) else: subpackages = [] # Python files are included by default filenames = [x.strip() for x in open('MANIFEST').readlines()] filenames = [x for x in filenames if not x.endswith('.py')] # The data files prefix = '' if package_root == '.' else package_root + '/' prefix_n = len(prefix) for line in filenames: if not line.startswith(prefix): continue line = line[prefix_n:] path = line.split('/') if path[0] in subpackages: subpackage = '%s.%s' % (package_name, path[0]) files = package_data.setdefault(subpackage, []) files.append(join_path(*path[1:])) elif path[0] not in ('archive', 'docs', 'scripts', 'test'): package_data[package_name].append(line) # The scripts if config.has_value('scripts'): scripts = config.get_value('scripts') scripts = [join_path(*['scripts', x]) for x in scripts] else: scripts = [] # Long description if exists('README.rst'): with codecs.open('README.rst', 'r', 'utf-8') as readme: long_description = readme.read() else: long_description = config.get_value('description') author_name = config.get_value('author_name') # Requires install_requires = [] if exists('requirements.txt'): install_requires = parse_requirements('requirements.txt', session=PipSession()) install_requires = [str(ir.req) for ir in install_requires] # XXX Workaround buggy distutils ("sdist" don't likes unicode strings, # and "register" don't likes normal strings). if 'register' in argv: author_name = unicode(author_name, 'utf-8') classifiers = [x for x in config.get_value('classifiers') if x] core.setup( name=package_name, version=version, # Metadata author=author_name, author_email=config.get_value('author_email'), license=config.get_value('license'), url=config.get_value('url'), description=config.get_value('title'), long_description=long_description, classifiers=classifiers, # Packages package_dir={package_name: package_root}, packages=packages, package_data=package_data, # Requires / Provides requires=config.get_value('requires'), provides=config.get_value('provides'), install_requires=install_requires, # Scripts scripts=scripts, cmdclass={'build_ext': OptionalBuildExt}, # C extensions ext_modules=ext_modules)
record_properties = freeze({ 'BEGIN': String(multiple=False), 'END': String(multiple=False), 'VERSION': Unicode(multiple=False), 'PRODID': Unicode(multiple=False), 'METHOD': Unicode(multiple=False), # Component properties 'ATTACH': URI(multiple=True), 'CATEGORY': Unicode(multiple=False), 'CATEGORIES': Unicode(multiple=True), 'CLASS': Unicode(multiple=False), 'COMMENT': Unicode(multiple=True), 'DESCRIPTION': Unicode(multiple=False), 'GEO': Unicode(multiple=False), 'LOCATION': Unicode(multiple=False), 'PERCENT-COMPLETE': Integer(multiple=False), 'PRIORITY': Integer(multiple=False), 'RESOURCES': Unicode(multiple=True), 'STATUS': Unicode(multiple=False), 'SUMMARY': Unicode(multiple=False, is_indexed=True, mandatory=True), # Date & Time component properties 'COMPLETED': DateTime(multiple=False), 'DTEND': DateTime(multiple=False, is_stored=True, is_indexed=True), 'DUE': DateTime(multiple=False), 'DTSTART': DateTime(multiple=False, is_stored=True, is_indexed=True), 'DURATION': Unicode(multiple=False), 'FREEBUSY': Unicode(multiple=False), 'TRANSP': Unicode(multiple=False), # Time Zone component properties 'TZID': Unicode(multiple=False), 'TZNAME': Unicode(multiple=True), 'TZOFFSETFROM': Unicode(multiple=False), 'TZOFFSETTO': Unicode(multiple=False), 'TZURL': URI(multiple=False), # Relationship component properties 'ATTENDEE': URI(multiple=True), 'CONTACT': Unicode(multiple=True), 'ORGANIZER': URI(multiple=False), # Recurrence component properties 'EXDATE': DateTime(multiple=True), 'EXRULE': Unicode(multiple=True), 'RDATE': Unicode(multiple=True), 'RRULE': Unicode(multiple=True), # Alarm component properties 'ACTION': Unicode(multiple=False), 'REPEAT': Integer(multiple=False), 'TRIGGER': Unicode(multiple=False), # Change management component properties 'CREATED': DateTime(multiple=False), 'DTSTAMP': DateTime(multiple=False), 'LAST-MODIFIED': DateTime(multiple=False), 'SEQUENCE': Integer(multiple=False), # Others 'RECURRENCE-ID': DateTime(multiple=False), 'RELATED-TO': Unicode(multiple=False), 'URL': URI(multiple=False), 'UID': String(multiple=False, is_indexed=True) })
class ikaaro(instance): class_title = u'Manage Ikaaro instances' class_actions = freeze(['start', 'stop', 'restart', 'reindex', 'vhosts']) @lazy def pyenv(self): pyenv = self.options['pyenv'] return config.get_section('pyenv', pyenv) @lazy def bin_icms(self): pyenv = self.pyenv prefix = pyenv.options.get('prefix') or pyenv.location[2] return '%s/bin' % prefix def get_host(self): pyenv = self.pyenv host = pyenv.get_host() cwd = pyenv.location[2] host.chdir(cwd) return host def stop(self): path = self.options['path'] host = self.get_host() host.run('%s/icms-stop.py %s' % (self.bin_icms, path)) host.run('%s/icms-stop.py --force %s' % (self.bin_icms, path)) def start(self, readonly=False): path = self.options['path'] cmd = '%s/icms-start.py -d %s' % (self.bin_icms, path) readonly = readonly or self.options.get('readonly', False) if readonly: cmd = cmd + ' -r' host = self.get_host() host.run(cmd) def update_catalog(self): path = self.options['path'] cmd = '{0}/icms-update-catalog.py -y {1} --quiet'.format( self.bin_icms, path) host = self.get_host() host.run(cmd) def vhosts(self): path = self.options['path'] host = self.get_host() cmd = cmd_vhosts % path host.run('./bin/python -c "%s"' % cmd, quiet=True) start_title = u'Start an ikaaro instance' def action_start(self): print '**********************************************************' print ' START' print '**********************************************************' self.start() stop_title = u'Stop an ikaaro instance' def action_stop(self): print '**********************************************************' print ' STOP' print '**********************************************************' self.stop() restart_title = u'(Re)Start an ikaaro instance' def action_restart(self): print '**********************************************************' print ' RESTART' print '**********************************************************' self.stop() self.start() reindex_title = u'Update catalog of an ikaaro instance' def action_reindex(self): print '**********************************************************' print ' REINDEX' print '**********************************************************' self.stop() self.update_catalog() self.start() vhosts_title = u'List vhosts of ikaaro instance' def action_vhosts(self): print '**********************************************************' print ' List Vhosts' print '**********************************************************' self.vhosts()
def get_failed_controls(self, context, pages=freeze([]), exclude=freeze([''])): for control in self.get_controls_namespace(context, levels=['1', '2'], pages=pages, exclude=exclude): yield control
class BaseView(prototype): # Access Control access = False def __init__(self, **kw): for key in kw: setattr(self, key, kw[key]) ####################################################################### # GET ####################################################################### def GET(self, resource, context): raise NotImplementedError ####################################################################### # Query query_schema = {} def get_query_schema(self): return self.query_schema def get_query(self, context): get_value = context.get_query_value schema = self.get_query_schema() return process_form(get_value, schema) ####################################################################### # Caching def get_mtime(self, resource): return None ####################################################################### # View's metadata title = None def get_title(self, context): return self.title ####################################################################### # Canonical URI for search engines # "language" is by default because too widespreaded canonical_query_parameters = freeze(['language']) def get_canonical_uri(self, context): """Return the same URI stripped from redundant view name, if already the default, and query parameters not affecting the resource representation. Search engines will keep this sole URI when crawling different combinations of this view. """ uri = deepcopy(context.uri) query = uri.query # Remove the view name if default name = uri.path.get_name() view_name = name[1:] if name and name[0] == ';' else None if view_name: resource = context.resource if view_name == resource.get_default_view_name(): uri = uri.resolve2('..') view_name = None # Be sure the canonical URL either has a view or ends by an slash if not view_name and uri.path != '/': uri.path.endswith_slash = True # Remove noise from query parameters canonical_query_parameters = self.canonical_query_parameters for parameter in query.keys(): if parameter not in canonical_query_parameters: del query[parameter] uri.query = query # Ok return uri ####################################################################### # POST ####################################################################### schema = {} def get_schema(self, resource, context): # Check for specific schema action = getattr(context, 'form_action', None) if action is not None: schema = getattr(self, '%s_schema' % action, None) if schema is not None: return schema # Default return self.schema def _get_form(self, resource, context): """Form checks the request form and collect inputs consider the schema. This method also checks the request form and raise an FormError if there is something wrong (a mandatory field is missing, or a value is not valid) or None if everything is ok. Its input data is a list (fields) that defines the form variables to {'toto': Unicode(mandatory=True, multiple=False, default=u'toto'), 'tata': Unicode(mandatory=True, multiple=False, default=u'tata')} """ get_value = context.get_form_value schema = self.get_schema(resource, context) return process_form(get_value, schema) def get_value(self, resource, context, name, datatype): return datatype.get_default() def get_action(self, resource, context): """Default function to retrieve the name of the action from a form """ # 1. Get the action name form = context.get_form() action = form.get('action') action = ('action_%s' % action) if action else 'action' # 2. Check whether the action has a query if '?' in action: action, query = action.split('?') # Deserialize query using action specific schema schema = getattr(self, '%s_query_schema' % action, None) context.form_query = decode_query(query, schema) # 3. Save the action name (used by get_schema) context.form_action = action # 4. Return the method return getattr(self, action, None) def on_form_error(self, resource, context): context.message = context.form_error.get_message() return self.GET def POST(self, resource, context): # (1) Find out which button has been pressed, if more than one method = self.get_action(resource, context) if method is None: msg = "POST method not supported because no '%s' defined" raise NotImplementedError, msg % context.form_action # (2) Automatically validate and get the form input (from the schema). try: form = self._get_form(resource, context) except FormError, error: context.form_error = error return self.on_form_error(resource, context) # (3) Action try: goto = method(resource, context, form) except ReadonlyError: context.message = ERROR('This website is under maintenance. ' 'Please try again later.') return self.GET # (4) Return if goto is None: return self.GET return goto
class RegisterForm(AutoForm): access = 'is_allowed_to_view' title = MSG(u"Subscription") schema = freeze({'email': Email(mandatory=True)}) widgets = freeze([TextWidget('email', title=MSG(u"E-mail Address"))]) query_schema = freeze({'email': Email}) actions = [RegisterButton, UnregisterButton] # Messages msg_user_already_subscribed = MSG_USER_ALREADY_SUBSCRIBED msg_confirmation_sent = MSG_CONFIRMATION_SENT msg_user_subscribed = MSG_USER_SUBSCRIBED msg_user_already_unsubscribed = MSG_USER_ALREADY_UNSUBSCRIBED msg_user_unsubscribed = MSG_USER_UNSUBSCRIBED def get_widgets(self, resource, context): widgets = super(RegisterForm, self).get_widgets(resource, context) if context.user: # E-mail becomes hard coded widgets = list(widgets) email = widgets[0] widgets[0] = ReadOnlyWidget(name=email.name, focus=True, title=email.title) return widgets def get_value(self, resource, context, name, datatype): if name == 'email': if context.user: return context.user.get_value('email') return context.query['email'] proxy = super(RegisterForm, self) return proxy.get_value(self, resource, context, name, datatype) def action_register(self, resource, context, form): root = context.root email = form['email'] existing_user = root.get_user_from_login(email) if existing_user is not None: username = existing_user.name if resource.is_subscribed(username, skip_unconfirmed=False): context.message = self.msg_user_already_subscribed return # Create user anyhow user = resource.subscribe_user(email=email, user=existing_user) if context.user is None: # Anonymous subscription resource.send_confirm_register(user, context) context.message = self.msg_confirmation_sent else: resource.after_register(user.name) context.message = self.msg_user_subscribed def action_unregister(self, resource, context, form): user = context.root.get_user_from_login(form['email']) if user is None: context.message = self.msg_user_already_unsubscribed return username = user.name if not resource.is_subscribed(username, skip_unconfirmed=False): context.message = self.msg_user_already_unsubscribed return if context.user is None: # Anonymous subscription resource.send_confirm_register(user, context, unregister=True) context.message = self.msg_confirmation_sent else: resource.unsubscribe_user(username) resource.after_unregister(username) context.message = self.msg_user_unsubscribed
class MassSubscriptionForm(AutoForm): access = 'is_admin' title = MSG(u"Mass Subscription") description = MSG( u"An invitation will be sent to every address typen below, one by" u" line.") schema = freeze({'emails': MultiLinesTokens(mandatory=True)}) widgets = freeze([MultilineWidget( 'emails', focus=False, )]) actions = [MassSubscribeButton, Button] # len(actions) > 1 def get_value(self, resource, context, name, datatype): if name == 'emails': return '' proxy = super(MassSubscriptionForm, self) return proxy.get_value(resource, context, name, datatype) def action_mass_subscribe(self, resource, context, form): root = context.root already = [] unallowed = [] invited = [] invalid = [] subscribed_users = resource.get_subscribed_users() for email in form['emails']: email = email.strip() if not email: continue # Check if email is valid if not Email.is_valid(email): invalid.append(email) continue # Checks user = root.get_user_from_login(email) if user: if user.name in subscribed_users: already.append(user) continue if not resource.is_subscription_allowed(user.name): unallowed.append(user) continue # Subscribe user = resource.subscribe_user(email=email, user=user) key = resource.set_register_key(user.name) # Send invitation subject = resource.invitation_subject.gettext() confirm_url = context.uri.resolve(';accept_invitation') confirm_url.query = {'key': key, 'email': email} text = resource.invitation_text.gettext(uri=confirm_url) root.send_email(email, subject, text=text) invited.append(user) # Ok context.message = [] add_subscribed_message(MSG_ALREADY, already, context) add_subscribed_message(MSG_INVALID, invalid, context, users_is_resources=False) add_subscribed_message(MSG_INVITED, invited, context) add_subscribed_message(MSG_UNALLOWED, unallowed, context)
class Export(STLForm): title = MSG(u'Export') template = '/ui/backoffice/export.xml' file_columns = [] file_schema = freeze({}) filename = None def get_filename(self, resource): filename = self.filename if filename is None: filename = resource.name + ".ods" return filename def get_file_columns(self, resource): return self.file_columns def get_file_schema(self, resource): return merge_dicts(self.export_resource.get_metadata_schema(), self.export_resource.computed_schema, name=Unicode(title=MSG(u'Name'))) def get_header(self, resource, context): file_schema = self.get_file_schema(resource) header = [] for column in self.get_file_columns(resource): title = getattr(file_schema[column], 'title', column) # MSG(u'Unknow')) if isinstance(title, MSG): title = title.gettext() header.append(title) return header def encode(self, resource, column, value, encoding='utf-8'): file_schema = self.get_file_schema(resource) datatype = file_schema[column] data = value # Replace enumerate name by value if issubclass(datatype, Enumerate): data = datatype.get_value(data) if data is None: return '' # Default encoders data_type = type(data) if data_type is XMLParser: return xml_to_text(data) elif data_type is list: return str(data) if isinstance(data, MSG): data = data.gettext() return data def get_row(self, resource, context, item): metadata_schema = self.export_resource.get_metadata_schema() computed_schema = self.export_resource.computed_schema row = [] for column in self.get_file_columns(resource): if column == 'name': value = item.name elif column in metadata_schema: value = item.get_property(column) elif column in computed_schema: value = getattr(item, column) value = self.encode(resource, column, value) row.append(value) return row def action_export(self, resource, context, form): root = context.root results = context.root.search(format=self.export_resource.class_id) if not len(results): context.message = ERR_NO_DATA return context.query['batch_start'] = context.query['batch_size'] = 0 # Create ODS header_style = odf_create_style('table-cell', area='text', bold=True) document = odf_new_document_from_type('spreadsheet') document.insert_style(header_style, automatic=True) body = document.get_body() table = odf_create_table(u'Table') # Add the header row = odf_create_row() line = self.get_header(resource, context) row.set_values(line, style=header_style) table.append_row(row) # Fill content for item_brain in results.get_documents(): item_resource = root.get_resource(item_brain.abspath) line = self.get_row(resource, context, item_resource) row = odf_create_row() try: row.set_values(line) except Exception: context.message = ERROR(u'Error on line %s' % line) return table.append_row(row) body.append(table) # Extport as ODS f = StringIO() document.save(f) content = f.getvalue() f.close() # Return ODS context.set_content_type( 'application/vnd.oasis.opendocument.spreadsheet') context.set_content_disposition('attachment', self.get_filename(resource)) return content
class BaseView(ItoolsView): known_methods = ['GET', 'HEAD', 'POST', 'PUT', 'DELETE'] ####################################################################### # Canonical URI for search engines # "language" is by default because too widespreaded canonical_query_parameters = freeze(['language']) def get_canonical_uri(self, context): """Return the same URI stripped from redundant view name, if already the default, and query parameters not affecting the resource representation. Search engines will keep this sole URI when crawling different combinations of this view. """ uri = deepcopy(context.uri) query = uri.query # Remove the view name if default name = uri.path.get_name() view_name = name[1:] if name and name[0] == ';' else None if view_name: resource = context.resource if view_name == resource.get_default_view_name(): uri = uri.resolve2('..') view_name = None # Be sure the canonical URL either has a view or ends by an slash if not view_name and uri.path != '/': uri.path.endswith_slash = True # Remove noise from query parameters canonical_query_parameters = self.canonical_query_parameters for parameter in query.keys(): if parameter not in canonical_query_parameters: del query[parameter] uri.query = query # Ok return uri def POST(self, resource, context): # Get the method method = getattr(self, context.form_action, None) if method is None: msg = "POST method not supported because no '%s' defined" raise NotImplementedError(msg % context.form_action) # Call method goto = method(resource, context, context.form) # Return if goto is None: return self.GET return goto ####################################################################### # PUT ####################################################################### access_PUT = False # 'is_allowed_to_put' def PUT(self, resource, context): # The resource is not locked, the request must have a correct # "If-Unmodified-Since" header. if_unmodified_since = context.get_header('If-Unmodified-Since') if if_unmodified_since is None: raise Conflict mtime = resource.get_value('mtime').replace(microsecond=0) if mtime > if_unmodified_since: raise Conflict # Check content-range content_range = context.get_header('content-range') if content_range: raise NotImplementedError # Check if handler is a File handler = resource.get_value('data') if not isinstance(handler, File): raise ValueError(u"PUT only allowed on files") # Save the data body = context.get_form_value('body') handler.load_state_from_string(body) context.database.change_resource(resource) # Set the Last-Modified header (if possible) mtime = resource.get_value('mtime') if mtime is not None: mtime = mtime.replace(microsecond=0) context.set_header('Last-Modified', mtime) access_DELETE = False #'is_allowed_to_remove' def DELETE(self, resource, context): name = resource.name parent = resource.parent if parent is None: raise MethodNotAllowed try: parent.del_resource(name) except Exception: # XXX should be ConsistencyError raise Conflict
def get_controls_namespace(self, context, levels=freeze([]), pages=freeze([]), exclude=freeze([''])): schema = self.get_schema() fields = self.get_form_fields(schema) for num, title, expr, level, page, variable in self.get_controls(): if not expr: continue if level not in levels: continue if pages and page not in pages: continue if page in exclude: continue if variable is not None: datatype = schema[variable] if self.is_disabled_by_type(variable, schema, datatype): continue globals_ = self.get_globals() # Précision pour les informations statistiques if level == '0': locals_ = self.get_floating_locals(schema, fields) else: locals_ = self.get_locals(schema, fields) try: value = eval(str(expr), globals_, locals_) except ZeroDivisionError: # Division par zéro toléré value = None except (InvalidOperation, ValueError): # Champs vides tolérés value = None # Passed if value is True and '0' not in levels: continue # Le titre contient des formules if u'[' in title: expanded = [] for is_expr, token in parse_control(title): if not is_expr: expanded.append(token) else: try: value = eval(token, globals_, locals_) except ZeroDivisionError: value = None expanded.append(unicode(value)) title = u"".join(expanded) if value is True: value = MSG(u"True") elif value is False: value = MSG(u"False") elif isinstance(value, NumDecimal): try: value = context.format_number(value.value) except InvalidOperation: value = value.value yield { 'number': num, 'title': title, 'level': level, 'variable': variable, 'page': page, 'value': value, 'debug': u'"{0}" = "{1}"'.format(expr, value)}