def location_breadcrumbs(self, fqname): """ Split the incoming fqname into segments. Reassemble into a list of tuples. If the fqname has a namespace, the first tuple's segment_name will have the namespace as a prefix. :rtype: list :returns: location breadcrumbs items in tuple (segment_name, fq_name, exists) """ breadcrumbs = [] current_item = '' if not isinstance(fqname, CompositeName): fqname = split_fqname(fqname) if fqname.field != NAME_EXACT: return [ (fqname, fqname, bool(self.storage.get_item(**fqname.query))) ] # flaskg.unprotected_storage.get_item(**fqname.query) namespace = segment1_namespace = fqname.namespace item_name = fqname.value if not item_name: return breadcrumbs for segment in item_name.split('/'): current_item += segment fq_current = CompositeName(namespace, NAME_EXACT, current_item) fq_segment = CompositeName(segment1_namespace, NAME_EXACT, segment) breadcrumbs.append( (fq_segment, fq_current, bool(self.storage.get_item(**fq_current.query)))) current_item += '/' segment1_namespace = '' return breadcrumbs
def gen_fqnames(meta): """Generate fqnames from meta data.""" if meta[NAME]: return [ CompositeName(meta[NAMESPACE], NAME_EXACT, name) for name in meta[NAME] ] return [CompositeName(meta[NAMESPACE], ITEMID, meta[ITEMID])]
def item_acl_report(): """ Return a sorted list of all items in the wiki along with the ACL Meta-data. Item names are prefixed with the namespace, if there is a non-default namespace. If there are multiple names, the first name is used for sorting. """ query = And([ Term(WIKINAME, app.cfg.interwikiname), Not(Term(NAMESPACE, NAMESPACE_USERPROFILES)), ]) all_items = flaskg.storage.search_meta(query, idx_name=LATEST_REVS, sortedby=[NAMESPACE, NAME], limit=None) items_acls = [] for item in all_items: item_namespace = item.meta.get(NAMESPACE) item_id = item.meta.get(ITEMID) if item_namespace: item_name = [ item_namespace + '/' + name for name in item.meta.get(NAME) ] else: item_name = item.meta.get(NAME) item_acl = item.meta.get(ACL) acl_default = item_acl is None if acl_default: for namespace, acl_config in app.cfg.acl_mapping: if item_namespace == namespace: item_acl = acl_config['default'] if item.meta.get(NAME): fqnames = [ CompositeName(item.meta[NAMESPACE], NAME_EXACT, name) for name in item.meta[NAME] ] else: fqnames = [ CompositeName(item.meta[NAMESPACE], ITEMID, item.meta[ITEMID]) ] fqname = fqnames[0] items_acls.append({ 'name': item_name, 'name_old': item.meta.get('name_old', []), 'itemid': item_id, 'fqnames': fqnames, 'fqname': fqnames[0], 'acl': item_acl, 'acl_default': acl_default }) # deleted items have no names; this sort places deleted items on top of the report; # the display name may be similar to: "9cf939f ~(DeletedItemName)" items_acls = sorted(items_acls, key=lambda k: (k['name'], k['name_old'])) return render_template('admin/item_acl_report.html', title_name=_('Item ACL Report'), number_items=len(items_acls), items_acls=items_acls)
def make_flat_index(self, subitems, isglobalindex=False): """ Create two IndexEntry lists - ``dirs`` and ``files`` - from a list of subitems. Direct subitems are added to the ``files`` list. For indirect subitems, its ancestor which is a direct subitem is added to the ``dirs`` list. Supposing current index root is 'foo' and when 'foo/bar/la' is encountered, 'foo/bar' is added to ``dirs``. The direct subitem need not exist. When both a subitem itself and some of its subitems are in the subitems list, it appears in both ``files`` and ``dirs``. :param isglobalindex: True if the query is for global indexes. """ prefixes = [u''] if isglobalindex else self.subitem_prefixes # IndexEntry instances of "file" subitems files = [] # IndexEntry instances of "directory" subitems dirs = [] added_dir_relnames = set() for rev in subitems: fullnames = rev.meta[NAME] for fullname in fullnames: prefix = self.get_prefix_match(fullname, prefixes) if prefix is not None: fullname_fqname = CompositeName(rev.meta[NAMESPACE], NAME_EXACT, fullname) relname = fullname[len(prefix):] if '/' in relname: # Find the *direct* subitem that is the ancestor of current # (indirect) subitem. e.g. suppose when the index root is # 'foo', and current item (`rev`) is 'foo/bar/lorem/ipsum', # 'foo/bar' will be found. direct_relname = relname.partition('/')[0] direct_relname_fqname = CompositeName(rev.meta[NAMESPACE], NAME_EXACT, direct_relname) if direct_relname_fqname not in added_dir_relnames: added_dir_relnames.add(direct_relname_fqname) direct_fullname = prefix + direct_relname direct_fullname_fqname = CompositeName(rev.meta[NAMESPACE], NAME_EXACT, direct_fullname) fqname = CompositeName(rev.meta[NAMESPACE], NAME_EXACT, direct_fullname) try: direct_rev = get_storage_revision(fqname) except AccessDenied: continue # user has permission to see parent, but not this subitem dirs.append(IndexEntry(direct_relname, direct_fullname_fqname, direct_rev.meta)) else: files.append(IndexEntry(relname, fullname_fqname, rev.meta)) files.sort() # files with multiple names are not in sequence return dirs, files
def get_namespaces(self, ns=None): """ Return the list of tuples (composite name, namespace) referring to namespaces other than the current namespace. """ if ns is not None and ns.value == '~': ns = u'' namespace_root_mapping = [] for namespace, _unused in app.cfg.namespace_mapping: namespace = namespace.rstrip('/') if ns is None or namespace != ns: fq_namespace = CompositeName(namespace, NAME_EXACT, u'') namespace_root_mapping.append((namespace or '~', fq_namespace.get_root_fqname())) return namespace_root_mapping
def user_acl_report(uid): query = And([ Term(WIKINAME, app.cfg.interwikiname), Not(Term(NAMESPACE, NAMESPACE_USERPROFILES)) ]) all_items = flaskg.storage.search_meta(query, idx_name=LATEST_REVS, sortedby=[NAMESPACE, NAME], limit=None) theuser = user.User(uid=uid) itemwise_acl = [] last_item_acl_parts = (None, None, None) last_item_result = { 'read': False, 'write': False, 'create': False, 'admin': False, 'destroy': False } for item in all_items: if item.meta.get(NAME): fqname = CompositeName(item.meta.get(NAMESPACE), NAME_EXACT, item.meta.get(NAME)[0]) else: fqname = CompositeName(item.meta.get(NAMESPACE), ITEMID, item.meta.get(ITEMID)) this_rev_acl_parts = (item.meta[NAMESPACE], item.meta.get(PARENTNAMES), item.meta.get(ACL)) name_parts = { 'name': item.meta.get(NAME), 'namespace': item.meta.get(NAMESPACE), 'itemid': item.meta.get(ITEMID), 'fqname': fqname } if not last_item_acl_parts == this_rev_acl_parts: last_item_acl_parts = this_rev_acl_parts last_item_result = { 'read': theuser.may.read(fqname), 'write': theuser.may.write(fqname), 'create': theuser.may.create(fqname), 'admin': theuser.may.admin(fqname), 'destroy': theuser.may.destroy(fqname) } itemwise_acl.append({**name_parts, **last_item_result}) return render_template('admin/user_acl_report.html', title_name=_('User ACL Report'), user_names=theuser.name, itemwise_acl=itemwise_acl)
def do_modify(self): """ Process new ticket, changes to ticket meta data, and/or a new comment against original ticket description. User has clicked "Submit ticket" or "Update ticket" button to get here. If user clicks Save button to add a comment to a prior comment it is not processed here - see /+comment in views.py. """ is_new = isinstance(self.content, NonExistentContent) closed = self.meta.get('closed') Form = TicketSubmitForm if is_new else TicketUpdateForm if request.method in ['GET', 'HEAD']: form = Form.from_item(self) elif request.method == 'POST': form = Form.from_request(request) if form.validate(): meta, data, message, data_file = form._dump(self) # saves new ticket revision if ticket meta has changed try: if not is_new and message: # user created a new comment create_comment(self.meta, message) if is_new: self.modify(meta, data) if data_file: file_upload(self, data_file) except AccessDenied: abort(403) else: try: fqname = CompositeName(self.meta[NAMESPACE], ITEMID, self.meta[ITEMID]) except KeyError: fqname = self.fqname return redirect(url_for('.show_item', item_name=fqname)) if is_new: data_rendered = None files = {} roots = [] comments = {} else: data_rendered = Markup(self.content._render_data()) files = get_files(self) comments, roots = get_comments(self) suggested_tags = get_itemtype_specific_tags(ITEMTYPE_TICKET) ordered_comments = [] # list of tuples [(comment, indent),,, ] for root in roots: ordered_comments += [(root, 0), ] + build_tree(comments, root, [], 0) return render_template(self.submit_template if is_new else self.modify_template, is_new=is_new, closed=closed, item_name=self.name, data_rendered=data_rendered, form=form, suggested_tags=suggested_tags, item=self, files=files, datetime=datetime.datetime, ordered_comments=ordered_comments, render_comment_data=render_comment_data, )
def group_acl_report(group_name): """ Display a 2-column table of items and ACLs, where the ACL rule specifies any WikiGroup or ConfigGroup name. """ group = search_group(group_name) all_items = flaskg.storage.documents(wikiname=app.cfg.interwikiname) group_items = [] for item in all_items: acl_iterator = ACLStringIterator(ACL_RIGHTS_CONTENTS, item.meta.get(ACL, '')) for modifier, entries, rights in acl_iterator: if group_name in entries: item_id = item.meta.get(ITEMID) fqname = CompositeName(item.meta.get(NAMESPACE), u'itemid', item_id) group_items.append( dict(name=item.meta.get(NAME), itemid=item_id, fqname=fqname, rights=rights)) return render_template('admin/group_acl_report.html', title_name=_(u'Group ACL Report'), group_items=group_items, group_name=group_name)
def build_dirs_index(basename, relnames): """ Build a list of IndexEntry by hand, useful as a test helper for index testing. Dirs are files with subitems and have meta == {}. """ return [(IndexEntry(relname, CompositeName(NAMESPACE_DEFAULT, NAME_EXACT, '/'.join((basename, relname))), {})) for relname in relnames]
def __init__(self, protector, meta): """ :param protector: protector middleware :param meta: meta data of item to protect """ self.protector = protector self.meta = meta if meta[NAME]: self.fqnames = [ CompositeName(meta[NAMESPACE], NAME_EXACT, name) for name in meta[NAME] ] else: self.fqnames = [ CompositeName(meta[NAMESPACE], ITEMID, meta[ITEMID]) ]
def _rename(self, name, comment, action, delete=False): self._save(self.meta, self.content.data, name=name, action=action, comment=comment, delete=delete) old_prefix = self.subitem_prefixes[0] old_prefixlen = len(old_prefix) if not delete: new_prefix = name + '/' for child in self.get_subitem_revs(): for child_oldname in child.meta[NAME]: if child_oldname.startswith(old_prefix): if delete: child_newname = None else: # rename child_newname = new_prefix + child_oldname[ old_prefixlen:] old_fqname = CompositeName(self.fqname.namespace, self.fqname.field, child_oldname) item = Item.create(old_fqname.fullname) item._save(item.meta, item.content.data, name=child_newname, action=action, comment=comment, delete=delete)
def userbrowser(): """ User Account Browser """ groups = flaskg.groups member_groups = {} # {username: [list of groups], ...} for groupname in groups: group = groups[groupname] for member in group.members: member_groups[member] = member_groups.get(member, []) + [group.name] revs = user.search_users() # all users user_accounts = [] for rev in revs: user_names = rev.meta[NAME] user_groups = member_groups.get(user_names[0], []) for name in user_names[1:]: user_groups = user_groups + member_groups.get(name, []) subscriptions = rev.meta[SUBSCRIPTIONS] user_accounts.append( dict(uid=rev.meta[ITEMID], name=user_names, fqname=CompositeName(NAMESPACE_USERS, NAME_EXACT, rev.name), email=rev.meta[EMAIL] if EMAIL in rev.meta else rev.meta[EMAIL_UNVALIDATED], disabled=rev.meta[DISABLED], groups=user_groups, subscriptions=subscriptions)) return render_template('admin/userbrowser.html', user_accounts=user_accounts, title_name=_("Users"))
def test_validjson(): """ Tests for changes to metadata when modifying an item. Does not apply to usersettings form. """ app.cfg.namespace_mapping = [(u'', 'default_backend'), (u'ns1/', 'default_backend'), (u'users/', 'other_backend')] item = Item.create(u'users/existingname') meta = {NAMESPACE: u'users', CONTENTTYPE: u'text/plain;charset=utf-8'} become_trusted() item._save(meta, data='This is a valid Item.') valid_itemid = 'a1924e3d0a34497eab18563299d32178' # ('names', 'namespace', 'field', 'value', 'result') tests = [([u'somename', u'@revid'], '', '', 'somename', False), # item names cannot begin with @ # TODO for above? - create item @x, get error message, change name in meta to xx, get an item with names @40x and alias of xx ([u'bar', u'ns1'], '', '', 'bar', False), # item names cannot match namespace names ([u'foo', u'foo', u'bar'], '', '', 'foo', False), # names in the name list must be unique. ([u'ns1ns2ns3', u'ns1/subitem'], '', '', 'valid', False), # Item names must not match with existing namespaces; items cannot be in 2 namespaces ([u'foobar', u'validname'], '', ITEMID, valid_itemid + '8080', False), # attempts to change itemid in meta result in "Item(s) named foobar, validname already exist." ([u'barfoo', u'validname'], '', ITEMID, valid_itemid.replace('a', 'y'), False), # similar to above ([], '', 'itemid', valid_itemid, True), # deleting all names from the metadata of an existing item will make it nameless, succeeds ([u'existingname'], 'users', '', 'existingname', False), # item already exists ] for name, namespace, field, value, result in tests: meta = {NAME: name, NAMESPACE: namespace} x = JSON(json.dumps(meta)) y = Names(name) state = dict(fqname=CompositeName(namespace, field, value), itemid=None, meta=meta) value = x.validate(state) and y.validate(state) assert value == result
def test_user(self): meta = { keys.ITEMID: make_uuid(), keys.REVID: make_uuid(), keys.NAME: [ u"user name", ], keys.NAMESPACE: u"userprofiles", keys.EMAIL: u"*****@*****.**", keys.SUBSCRIPTIONS: [ u"{0}:{1}".format(keys.ITEMID, make_uuid()), u"{0}::foo".format(keys.NAME), u"{0}::bar".format(keys.TAGS), u"{0}::".format(keys.NAMERE), u"{0}:userprofiles:a".format(keys.NAMEPREFIX), ] } invalid_meta = { keys.SUBSCRIPTIONS: [ u"", u"unknown_tag:123", u"{0}:123".format(keys.ITEMID), u"{0}:foo".format(keys.NAME), ] } state = { 'trusted': False, # True for loading a serialized representation or other trusted sources keys.NAME: u'somename', # name we decoded from URL path keys.ACTION: keys.ACTION_SAVE, keys.HOSTNAME: u'localhost', keys.ADDRESS: u'127.0.0.1', keys.WIKINAME: u'ThisWiki', keys.NAMESPACE: u'', keys.FQNAME: CompositeName(u'', u'', u'somename') } m = UserMetaSchema(meta) valid = m.validate(state) assert m[keys.CONTENTTYPE].value == CONTENTTYPE_USER if not valid: for e in m.children: print e.valid, e print m.valid, m assert valid m = UserMetaSchema(invalid_meta) valid = m.validate(state) assert not valid for e in m.children: if e.name in (keys.SUBSCRIPTIONS, ): for value in e: assert not value.valid
def build_mixed_index(basename, spec): """ Build a list of MixedIndexEntry by hand, useful as a test helper. :spec is a list of (relname, hassubitem) tuples. """ return [(MixedIndexEntry(relname, CompositeName(NAMESPACE_DEFAULT, NAME_EXACT, '/'.join((basename, relname))), Item.create('/'.join((basename, relname))).meta, hassubitem)) for relname, hassubitem in spec]
def build_index(basename, relnames): """ Build a list of IndexEntry by hand, useful as a test helper for index testing. Files have no subitems, meta content is reduced to required keys. """ files = [(IndexEntry(relname, CompositeName(NAMESPACE_DEFAULT, NAME_EXACT, '/'.join((basename, relname))), Item.create('/'.join((basename, relname))).meta)) for relname in relnames] return [(IndexEntry(f.relname, f.fullname, {key: f.meta[key] for key in (CONTENTTYPE, ITEMTYPE)})) for f in files]
def build_index(basename, relnames): """ Build a list of IndexEntry by hand, useful as a test helper. """ return [(IndexEntry( relname, CompositeName(NAMESPACE_DEFAULT, NAME_EXACT, '/'.join( (basename, relname))), Item.create('/'.join((basename, relname))).meta)) for relname in relnames]
def _trashed(namespace): q = And([Term(WIKINAME, app.cfg.interwikiname), Term(TRASH, True)]) if namespace != NAMESPACE_ALL: q = And([q, Term(NAMESPACE, namespace), ]) trashedEntry = namedtuple('trashedEntry', 'fqname oldname revid rev_number mtime comment editor parentid') results = [] for meta in flaskg.storage.search_meta(q, limit=None): fqname = CompositeName(meta[NAMESPACE], ITEMID, meta[ITEMID]) results.append(trashedEntry(fqname, meta[NAME_OLD], meta[REVID], meta[REV_NUMBER], meta[MTIME], meta[COMMENT], get_editor_info(meta), meta[PARENTID])) return results
def rename(self, name, comment=u''): """ rename this item to item <name> (replace current name by another name in the NAME list) """ fqname = CompositeName(self.fqname.namespace, self.fqname.field, name) if flaskg.storage.get_item(**fqname.query): raise NameNotUniqueError(L_("An item named %s already exists in the namespace %s." % (name, fqname.namespace))) # if this is a subitem, verify all parent items exist _verify_parents(self, name, self.fqname.namespace, old_name=self.fqname.value) return self._rename(name, comment, action=ACTION_RENAME)
def _verify_parents(self, new_name, namespace, old_name=''): """ If this is a subitem, verify all parent items exist. Return None if OK, raise error if not OK. """ name_segments = new_name.split('/') for idx in range(len(name_segments) - 1): root_name = '/'.join(name_segments[:idx + 1]) fqname = CompositeName(namespace, NAME_EXACT, root_name) parent_item = flaskg.unprotected_storage.get_item(**fqname.query) if parent_item.itemid is None: raise MissingParentError(_("Cannot create or rename item '%(new_name)s' because parent '%(parent_name)s' is missing.", new_name=new_name, parent_name=name_segments[idx]))
def split_navilink(self, text): """ Split navibar links into pagename, link to page Admin or user might want to use shorter navibar items by using the [[page|title]] or [[url|title]] syntax. Supported syntax: * PageName * WikiName:PageName * wiki:WikiName:PageName * url * all targets as seen above with title: [[target|title]] :param text: the text used in config or user preferences :rtype: tuple :returns: pagename or url, link to page or url """ title = None wiki_local = '' # means local wiki # Handle [[pagename|title]] or [[url|title]] formats if text.startswith('[[') and text.endswith(']]'): text = text[2:-2] try: target, title = text.split('|', 1) target = target.strip() title = title.strip() except (ValueError, TypeError): # Just use the text as is. target = text.strip() else: target = text if wikiutil.is_URL(target): if not title: title = target return target, title, wiki_local # remove wiki: url prefix if target.startswith("wiki:"): target = target[5:] wiki_name, namespace, field, item_name = split_interwiki(target) if wiki_name == 'Self': wiki_name = '' href = url_for_item(item_name, namespace=namespace, wiki_name=wiki_name, field=field) if not title: title = shorten_fqname(CompositeName(namespace, field, item_name)) return href, title, wiki_name
def build_mixed_index(basename, spec): """ Build a list of MixedIndexEntry by hand, useful as a test helper for index testing. The mixed index is a combo of dirs and files with empty meta (dirs) or reduced meta (files). :spec is a list of (relname, hassubitem) tuples. """ files = [(MixedIndexEntry(relname, CompositeName(NAMESPACE_DEFAULT, NAME_EXACT, '/'.join((basename, relname))), Item.create('/'.join((basename, relname))).meta, hassubitem)) for relname, hassubitem in spec] return [(MixedIndexEntry(f.relname, f.fullname, {} if f.hassubitems else {key: f.meta[key] for key in (CONTENTTYPE, ITEMTYPE)}, f.hassubitems)) for f in files]
def get_subscribers(**meta): """ Get all users that are subscribed to the item :param meta: key/value pairs from item metadata - itemid, name, namespace, tags keys :return: a set of Subscriber objects """ itemid = meta.get(ITEMID) name = meta.get(NAME) namespace = meta.get(NAMESPACE) fqname = CompositeName(namespace, ITEMID, itemid) tags = meta.get(TAGS) terms = [] if itemid is not None: terms.extend( [Term(SUBSCRIPTION_IDS, "{0}:{1}".format(ITEMID, itemid))]) if namespace is not None: if name is not None: terms.extend( Term(SUBSCRIPTION_IDS, "{0}:{1}:{2}".format( NAME, namespace, name_)) for name_ in name) if tags is not None: terms.extend( Term(SUBSCRIPTION_IDS, "{0}:{1}:{2}".format( TAGS, namespace, tag)) for tag in tags) query = Or(terms) with flaskg.storage.indexer.ix[LATEST_REVS].searcher() as searcher: result_iterators = [ searcher.search(query, limit=None), ] subscription_patterns = searcher.lexicon(SUBSCRIPTION_PATTERNS) # looks like whoosh gives us bytes (not str), decode them: subscription_patterns = [ p if isinstance(p, str) else p.decode() for p in subscription_patterns ] patterns = get_matched_subscription_patterns(subscription_patterns, **meta) result_iterators.extend( searcher.documents(subscription_patterns=pattern) for pattern in patterns) subscribers = set() for user in chain.from_iterable(result_iterators): email = user.get(EMAIL) if email: from moin.user import User u = User(uid=user.get(ITEMID)) if u.may.read(fqname): locale = user.get(LOCALE, DEFAULT_LOCALE) subscribers.add( Subscriber(user[ITEMID], user[NAME][0], email, locale)) return subscribers
def itemsize(): """display a table with item sizes""" headings = [ _('Size'), _('Item name'), ] query = And([Term(WIKINAME, app.cfg.interwikiname), Not(Term(NAMESPACE, NAMESPACE_USERPROFILES)), Not(Term(TRASH, True))]) revs = flaskg.storage.search_meta(query, idx_name=LATEST_REVS, sortedby=[NAME], limit=None) rows = [(rev[SIZE], CompositeName(rev[NAMESPACE], NAME_EXACT, rev[NAME][0])) for rev in revs] rows = sorted(rows, reverse=True) return render_template('user/itemsize.html', title_name=_("Item Sizes"), headings=headings, rows=rows)
def group_acl_report(group_name): """ Display a table of items and permissions, where the ACL rule specifies any WikiGroup or ConfigGroup name. """ query = And([ Term(WIKINAME, app.cfg.interwikiname), Not(Term(NAMESPACE, NAMESPACE_USERPROFILES)) ]) all_items = flaskg.storage.search_meta(query, idx_name=LATEST_REVS, sortedby=[NAMESPACE, NAME], limit=None) group_items = [] for item in all_items: acl_iterator = ACLStringIterator(ACL_RIGHTS_CONTENTS, item.meta.get(ACL, '')) for modifier, entries, rights in acl_iterator: if group_name in entries: if item.meta.get(NAME): fqname = CompositeName(item.meta.get(NAMESPACE), NAME_EXACT, item.meta.get(NAME)[0]) else: fqname = CompositeName(item.meta.get(NAMESPACE), ITEMID, item.meta.get(ITEMID)) group_items.append( dict(name=item.meta.get(NAME), itemid=item.meta.get(ITEMID), namespace=item.meta.get(NAMESPACE), fqname=fqname, rights=rights)) return render_template('admin/group_acl_report.html', title_name=_('Group ACL Report'), group_items=group_items, group_name=group_name)
def test_content(self): class REV(dict): """ fake rev """ rev = REV() rev[keys.ITEMID] = make_uuid() rev[keys.REVID] = make_uuid() rev[keys.ACL] = u"All:read" meta = { keys.REVID: make_uuid(), keys.PARENTID: make_uuid(), keys.NAME: [ u"a", ], keys.NAMESPACE: u"", keys.ACL: u"All:read", keys.TAGS: [u"foo", u"bar"], } state = { 'trusted': False, # True for loading a serialized representation or other trusted sources keys.NAME: u'somename', # name we decoded from URL path keys.ACTION: keys.ACTION_SAVE, keys.HOSTNAME: u'localhost', keys.ADDRESS: u'127.0.0.1', keys.USERID: make_uuid(), keys.HASH_ALGORITHM: u'b9064b9a5efd8c6cef2d38a8169a0e1cbfdb41ba', keys.SIZE: 0, keys.WIKINAME: u'ThisWiki', keys.NAMESPACE: u'', 'rev_parent': rev, 'acl_parent': u"All:read", 'contenttype_current': u'text/x.moin.wiki;charset=utf-8', 'contenttype_guessed': u'text/plain;charset=utf-8', keys.FQNAME: CompositeName(u'', u'', u'somename'), } m = ContentMetaSchema(meta) valid = m.validate(state) assert m[keys.CONTENTTYPE].value == u'text/x.moin.wiki;charset=utf-8' if not valid: for e in m.children: print e.valid, e print m.valid, m assert valid
def __call__(self, rev, contenttype=None, arguments=None): fqname = CompositeName(rev.meta[NAMESPACE], NAME_EXACT, rev.meta[NAME][0]) self.fullname = fqname.fullname try: contents = self.list_contents(rev.data) contents = [(self.process_size(size), self.process_datetime(dt), self.process_name(name), ) for size, dt, name in contents] table = self.build_dom_table(contents, head=[_("Size"), _("Timestamp"), _("Name")], cls='zebra') body = moin_page.body(children=(table, )) return moin_page.page(children=(body, )) except ArchiveException as err: logging.exception("An exception within archive file handling occurred:") # XXX we also use a table for error reporting, could be # something more adequate, though: return self.build_dom_table([[str(err)]])
def get_files(self): check_itemid(self) if self.meta.get(ITEMID) and self.meta.get(NAME): refers_to = self.meta[ITEMID] prefix = self.meta[ITEMID] + '/' else: refers_to = self.fqname.value prefix = self.fqname.value + '/' query = And([Term(WIKINAME, app.cfg.interwikiname), Term(REFERS_TO, refers_to), Term(ELEMENT, u'file')]) revs = flaskg.storage.search(query, limit=None) files = [] for rev in revs: names = rev.meta[NAME] for name in names: relname = name[len(prefix):] file_fqname = CompositeName(rev.meta[NAMESPACE], ITEMID, rev.meta[ITEMID]) files.append(IndexEntry(relname, file_fqname, rev.meta)) return files
def user_acl_report(uid): all_items = flaskg.storage.documents(wikiname=app.cfg.interwikiname) groups = flaskg.groups theuser = user.User(uid=uid) itemwise_acl = [] for item in all_items: fqname = CompositeName(item.meta.get(NAMESPACE), 'itemid', item.meta.get(ITEMID)) itemwise_acl.append({'name': item.meta.get(NAME), 'itemid': item.meta.get(ITEMID), 'fqname': fqname, 'read': theuser.may.read(fqname), 'write': theuser.may.write(fqname), 'create': theuser.may.create(fqname), 'admin': theuser.may.admin(fqname), 'destroy': theuser.may.destroy(fqname)}) return render_template('admin/user_acl_report.html', title_name=_('User ACL Report'), user_names=theuser.name, itemwise_acl=itemwise_acl)
def path_breadcrumbs(self): """ Assemble the path breadcrumbs (a.k.a.: trail) :rtype: list :returns: path breadcrumbs items in tuple (wiki_name, item_name, url, exists, err) """ user = self.user breadcrumbs = [] trail = user.get_trail() for interwiki_item_name in trail: wiki_name, namespace, field, item_name = split_interwiki(interwiki_item_name) fqname = CompositeName(namespace, field, item_name) err = not is_known_wiki(wiki_name) href = url_for_item(wiki_name=wiki_name, **fqname.split) if is_local_wiki(wiki_name): exists = bool(self.storage.get_item(**fqname.query)) wiki_name = '' # means "this wiki" for the theme code else: exists = True # we can't detect existance of remote items if item_name: breadcrumbs.append((wiki_name, fqname, href, exists, err)) return breadcrumbs