Commits

hacklab  committed 0fa27fa

save/retrieve or items considers namespace

  • Participants
  • Parent commits 73d9dbe
  • Branches namespaces

Comments (0)

Files changed (3)

File MoinMoin/items/__init__.py

                             CONTENTTYPE, SIZE, LANGUAGE, ITEMLINKS, ITEMTRANSCLUSIONS, \
                             TAGS, ACTION, ADDRESS, HOSTNAME, USERID, EXTRA, COMMENT, \
                             HASH_ALGORITHM, CONTENTTYPE_GROUPS, ITEMID, REVID, DATAID, \
-                            CURRENT, PARENTID
+                            CURRENT, PARENTID, NAMESPACE
 
 COLS = 80
 ROWS_DATA = 20
             self.content_type = content_type
             self.priority = priority
 
-        def __call__(self, name, content_type, kw):
+        def __call__(self, name, content_type, namespace, kw):
             if self.content_type.issupertype(content_type):
-                return self.factory(name, content_type, **kw)
+                return self.factory(name, content_type, namespace=namespace, **kw)
 
         def __eq__(self, other):
             if isinstance(other, self.__class__):
             return NotImplemented
 
         def __repr__(self):
-            return '<{0}: {1}, prio {2} [{3!r}]>' % (self.__class__.__name__,
-                    self.content_type,
-                    self.priority,
-                    self.factory)
+            return '<{0}: {1}, prio {2} [{3!r}]>'.format(self.__class__.__name__,
+                                                         self.content_type,
+                                                         self.priority,
+                                                         self.factory,
+                                                         )
 
-    def get(self, name, content_type, **kw):
+    def get(self, name, content_type, namespace, **kw):
         for entry in self._entries:
-            item = entry(name, content_type, kw)
+            item = entry(name, content_type, namespace, kw)
             if item is not None:
                 return item
 
             if item is None:
                 item = flaskg.storage[name]
             else:
-                name = item.name
+                local_name = item.name
         if not item: # except NoSuchItemError:
             logging.debug("No such item: {0!r}".format(name))
             item = DummyItem(local_name)
         contenttype = rev.meta.get(CONTENTTYPE) or contenttype # use contenttype in case our metadata does not provide CONTENTTYPE
         logging.debug("Item {0!r}, got contenttype {1!r} from revision meta".format(name, contenttype))
         #logging.debug("Item %r, rev meta dict: %r" % (name, dict(rev.meta)))
-        item = item_registry.get(name, Type(contenttype), rev=rev)
+        item = item_registry.get(local_name, Type(contenttype), namespace=namespace, rev=rev)
         logging.debug("ItemClass {0!r} handles {1!r}".format(item.__class__, contenttype))
         return item
 
-    def __init__(self, name, rev=None, contenttype=None):
+    def __init__(self, name, rev=None, contenttype=None, namespace=""):
         self.name = name
         self.rev = rev
         self.contenttype = contenttype
+        self.namespace = namespace
 
     def get_meta(self):
         return self.rev.meta
         comment = request.form.get('comment')
         return self._save(meta, data, contenttype_guessed=contenttype_guessed, comment=comment)
 
+    @property
+    def qualified_name(self):
+        # TODO handle external wiki items
+        if self.namespace:
+            return ':'.join([self.namespace, self.name])
+        return self.name
+
     def _save(self, meta, data=None, name=None, action=u'SAVE', contenttype_guessed=None, comment=u'',
               overwrite=False, delete=False):
         backend = flaskg.storage
-        storage_item = backend[self.name]
+        storage_item = backend[self.qualified_name]
         try:
             currentrev = storage_item.get_revision(CURRENT)
             rev_id = currentrev.revid
         if CONTENTTYPE not in meta:
             # make sure we have CONTENTTYPE
             meta[CONTENTTYPE] = unicode(contenttype_current or contenttype_guessed or 'application/octet-stream')
+        if NAMESPACE not in meta:
+            meta[NAMESPACE] = self.namespace
 
         if ADDRESS not in meta:
             meta[ADDRESS] = u'0.0.0.0' # TODO

File MoinMoin/items/_tests/test_Item.py

 
 from MoinMoin._tests import become_trusted, update_item
 from MoinMoin.items import Item, ApplicationXTar, NonExistent, Binary, Text, Image, TransformableBitmapImage, MarkupItem
-from MoinMoin.config import CONTENTTYPE, ADDRESS, COMMENT, HOSTNAME, USERID, ACTION, NAME
+from MoinMoin.config import CONTENTTYPE, ADDRESS, COMMENT, HOSTNAME, USERID, ACTION, NAME, NAMESPACE
 
 class TestItem(object):
 
         with pytest.raises(KeyError):
             item.meta['test_key']
 
+    def test_item_is_saved_in_proper_namespace(self):
+        name = u'userprofiles:JohnDoe'
+        contenttype = u'application/moin'
+        data = u"John Doe's profile"
+        meta = {CONTENTTYPE: contenttype}
+
+        comment = 'saved'
+        item = Item.create(name)
+        assert item.name == 'JohnDoe'
+        assert item.namespace == 'userprofiles'
+        item._save(meta, data, comment=comment)
+
+        # Now let's look for JohnDoe out of the namespace, shouldn't find
+        item = Item.create('JohnDoe')
+        assert item.meta[CONTENTTYPE] == 'application/x-nonexistent'
+
+        item = Item.create(name)
+        assert item.meta[CONTENTTYPE] == contenttype
 
 class TestBinary(object):
     """ Test for arbitrary binary items """

File MoinMoin/storage/middleware/indexing.py

         if self._name:
             _, namespace, name = split_interwiki(self._name)
             self._name = name
+            self.namespace = namespace
         if latest_doc is None:
 #            if namespace:
 #                import ipdb;ipdb.set_trace()
             if self._name:
                 query[NAMESPACE] = namespace
-#                query[NAME_EXACT] = name
+                query[NAME_EXACT] = name
             # we need to call the method without acl check to avoid endless recursion:
             latest_doc = self.indexer._document(**query) or {}
         self._current = latest_doc