changeset 1527:d7ccb653e7aa

Pulled from main repo
author Jaiditya Mathur <jaiditya.mathur@gmail.com>
date Wed, 11 Jul 2012 01:32:16 +0530
parents de029fd0bf9c (current diff) 2a59cb0f0755 (diff)
children 49804b398c8c
files MoinMoin/apps/admin/views.py
diffstat 16 files changed, 177 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/apps/admin/views.py	Wed Jul 11 01:29:00 2012 +0530
+++ b/MoinMoin/apps/admin/views.py	Wed Jul 11 01:32:16 2012 +0530
@@ -81,9 +81,9 @@
         if ok:
             setattr(u, key, val)
             u.save()
-            flash('{0}.{1}: {2} -> {3}'.format(user_name, key, unicode(oldval), unicode(val), ), "info")
+            flash(u'{0}.{1}: {2} -> {3}'.format(user_name, key, unicode(oldval), unicode(val), ), "info")
         else:
-            flash('modifying {0}.{1} failed'.format(user_name, key, ), "error")
+            flash(u'modifying {0}.{1} failed'.format(user_name, key, ), "error")
     return redirect(url_for('.userbrowser'))
 
 
--- a/MoinMoin/apps/frontend/views.py	Wed Jul 11 01:29:00 2012 +0530
+++ b/MoinMoin/apps/frontend/views.py	Wed Jul 11 01:32:16 2012 +0530
@@ -1156,7 +1156,7 @@
             email = form['email'].value
             if form['email'].valid and email:
                 users = user.search_users(email=email)
-                u = users and user.User(users[0][ITEMID])
+                u = users and user.User(users[0].meta[ITEMID])
             if u and u.valid:
                 is_ok, msg = u.mail_password_recovery()
                 if not is_ok:
@@ -1411,6 +1411,9 @@
     )
     forms = dict()
 
+    if not flaskg.user.valid:
+        return redirect(url_for('.login'))
+
     if request.method == 'POST':
         part = request.form.get('part')
         if part not in form_classes:
@@ -1576,7 +1579,7 @@
         # try to find the latest rev1 before bookmark <date>
         revs = sorted([(rev.meta[MTIME], rev.revid) for rev in item.iter_revs()], reverse=True)
         for mtime, revid in revs:
-            if mtime <= bookmark_time:
+            if mtime <= int(bookmark_time):
                 rev1 = revid
                 break
         else:
--- a/MoinMoin/auth/smb_mount.py	Wed Jul 11 01:29:00 2012 +0530
+++ b/MoinMoin/auth/smb_mount.py	Wed Jul 11 01:32:16 2012 +0530
@@ -49,7 +49,7 @@
         self.coding = coding
 
     def do_smb(self, username, password, login):
-        logging.debug("login={0} logout={1}: got name={2}".format(login, not login, username))
+        logging.debug("login={0} logout={1}: got name={2!r}".format(login, not login, username))
 
         import os, pwd, subprocess
         web_username = self.dir_user
--- a/MoinMoin/converter/archive_in.py	Wed Jul 11 01:29:00 2012 +0530
+++ b/MoinMoin/converter/archive_in.py	Wed Jul 11 01:32:16 2012 +0530
@@ -38,7 +38,7 @@
 
     def process_name(self, member_name):
         attrib = {
-            xlink.href: Iri(scheme='wiki', authority='', path='/'+self.item_name, query='do=get&member={0}'.format(member_name)),
+            xlink.href: Iri(scheme='wiki', authority='', path='/'+self.item_name, query=u'do=get&member={0}'.format(member_name)),
         }
         return moin_page.a(attrib=attrib, children=[member_name, ])
 
--- a/MoinMoin/converter/everything.py	Wed Jul 11 01:29:00 2012 +0530
+++ b/MoinMoin/converter/everything.py	Wed Jul 11 01:32:16 2012 +0530
@@ -27,7 +27,7 @@
         attrib = {
             xlink.href: Iri(scheme='wiki', authority='', path='/'+item_name, query='do=get&rev={0}'.format(rev.revid)),
         }
-        return moin_page.a(attrib=attrib, children=["Download {0}.".format(item_name)])
+        return moin_page.a(attrib=attrib, children=[u"Download {0}.".format(item_name)])
 
 
 from . import default_registry
--- a/MoinMoin/converter/html_out.py	Wed Jul 11 01:29:00 2012 +0530
+++ b/MoinMoin/converter/html_out.py	Wed Jul 11 01:32:16 2012 +0530
@@ -367,7 +367,7 @@
 
         if obj_type == "img":
             # Images have alt text
-            alt = ''.join(str(e) for e in elem) # XXX handle non-text e
+            alt = ''.join(unicode(e) for e in elem) # XXX handle non-text e
             if alt:
                 attrib[html.alt] = alt
             new_elem = html.img(attrib=attrib)
--- a/MoinMoin/datastruct/backends/__init__.py	Wed Jul 11 01:29:00 2012 +0530
+++ b/MoinMoin/datastruct/backends/__init__.py	Wed Jul 11 01:32:16 2012 +0530
@@ -80,7 +80,7 @@
         raise NotImplementedError()
 
     def __repr__(self):
-        return "<{0} groups={1}>".format(self.__class__, list(self))
+        return "<{0!r} groups={1!r}>".format(self.__class__, list(self))
 
     def _retrieve_members(self, group_name):
         raise NotImplementedError()
@@ -250,7 +250,7 @@
                     yield group_name
 
     def __repr__(self):
-        return "<{0} name={1} members={2} member_groups={3}>".format(self.__class__, self.name, self.members, self.member_groups)
+        return "<{0!r} name={1!r} members={2!r} member_groups={3!r}>".format(self.__class__, self.name, self.members, self.member_groups)
 
 
 class BaseDict(object, DictMixin):
--- a/MoinMoin/script/account/disable.py	Wed Jul 11 01:29:00 2012 +0530
+++ b/MoinMoin/script/account/disable.py	Wed Jul 11 01:32:16 2012 +0530
@@ -37,15 +37,15 @@
             u = user.User(auth_username=name)
 
         if not u.exists():
-            print 'This user "{0}" does not exists!'.format(u.name)
+            print 'This user "{0!r}" does not exists!'.format(u.name)
             return
 
-        print " {0:<20} {1:<25} {2:<35}".format(u.id, u.name, u.email),
+        print " {0:<20} {1:!r<25} {2:<35}".format(u.id, u.name, u.email),
         if not u.disabled: # only disable once
             u.disabled = 1
-            u.name = "{0}-{1}".format(u.name, u.id)
+            u.name = u"{0}-{1}".format(u.name, u.id)
             if u.email:
-                u.email = "{0}-{1}".format(u.email, u.id)
+                u.email = u"{0}-{1}".format(u.email, u.id)
             u.subscribed_items = [] # avoid using email
             u.save()
             print "- disabled."
--- a/MoinMoin/script/account/resetpw.py	Wed Jul 11 01:29:00 2012 +0530
+++ b/MoinMoin/script/account/resetpw.py	Wed Jul 11 01:32:16 2012 +0530
@@ -41,7 +41,7 @@
             u = user.User(auth_username=name)
 
         if not u.exists():
-            print 'This user "{0}" does not exists!'.format(u.name)
+            print 'This user "{0!r}" does not exists!'.format(u.name)
             return
 
         u.enc_password = crypto.crypt_password(password)
--- a/MoinMoin/signalling/log.py	Wed Jul 11 01:29:00 2012 +0530
+++ b/MoinMoin/signalling/log.py	Wed Jul 11 01:32:16 2012 +0530
@@ -15,9 +15,9 @@
 @item_displayed.connect_via(ANY)
 def log_item_displayed(app, item_name):
     wiki_name = app.cfg.interwikiname
-    logging.info("item {0}:{1} displayed".format(wiki_name, item_name))
+    logging.info(u"item {0}:{1} displayed".format(wiki_name, item_name))
 
 @item_modified.connect_via(ANY)
 def log_item_modified(app, item_name):
     wiki_name = app.cfg.interwikiname
-    logging.info("item {0}:{1} modified".format(wiki_name, item_name))
+    logging.info(u"item {0}:{1} modified".format(wiki_name, item_name))
--- a/MoinMoin/storage/stores/_tests/conftest.py	Wed Jul 11 01:29:00 2012 +0530
+++ b/MoinMoin/storage/stores/_tests/conftest.py	Wed Jul 11 01:32:16 2012 +0530
@@ -23,6 +23,13 @@
 except Exception:
     pass
 
+try:
+    # check if we can connect to the mongodb server
+    check_connection(27017)
+    STORES.append('mongodb')
+except Exception:
+    pass
+
 constructors = {
     'memory': lambda store, _: store(),
     'fs': lambda store, tmpdir: store(str(tmpdir.join('store'))),
@@ -32,6 +39,7 @@
                                           'test_table', compression_level=1),
     'kc': lambda store, tmpdir: store(str(tmpdir.join('store.kch'))),
     'kt': lambda store, _: store(),
+    'mongodb': lambda store, _: store(),
     'sqla': lambda store, tmpdir: store('sqlite:///{0!s}'.format(tmpdir.join('store.sqlite')),
                                         'test_table'),
 }
@@ -77,9 +85,10 @@
     store = construct(klass, tmpdir)
     store.create()
     store.open()
-    # no destroy in the normal finalizer
-    # so we can keep the data for example if it's a tmpdir
     request.addfinalizer(store.close)
+    # for debugging, you can disable the next line to see the stuff in the
+    # store and examine it, but usually we want to clean up afterwards:
+    request.addfinalizer(store.destroy)
     return store
 
 
@@ -96,4 +105,5 @@
     storename, kind = request.param
     if kind == 'FileStore':
         store = ByteToStreamWrappingStore(store)
+    # store here always is a ByteStore and can be tested as such
     return store
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/storage/stores/_tests/test_mongodb.py	Wed Jul 11 01:32:16 2012 +0530
@@ -0,0 +1,36 @@
+# Copyright: 2011 MoinMoin:RonnyPfannschmidt
+# Copyright: 2012 Ionut Artarisi <ionut@artarisi.eu>
+# Copyright: 2012 MoinMoin:ThomasWaldmann
+# License: GNU GPL v2 (or any later version), see LICENSE.txt for details.
+
+"""
+MoinMoin - mongodb store tests
+"""
+
+import pytest
+pytest.importorskip('MoinMoin.storage.stores.mongodb')
+from ..mongodb import BytesStore, FileStore
+
+from MoinMoin._tests import check_connection
+try:
+    check_connection(27017)
+except Exception as err:
+    pytest.skip(str(err))
+
+
+@pytest.mark.multi(Store=[BytesStore, FileStore])
+def test_create(Store):
+    store = Store()
+    store.create()
+    return store
+
+@pytest.mark.multi(Store=[BytesStore, FileStore])
+def test_destroy(Store):
+    store = Store()
+    store.destroy()
+
+@pytest.mark.multi(Store=[BytesStore, FileStore])
+def test_from_uri(Store):
+    store = Store.from_uri("mongodb://localhost/test_base::test_coll")
+    assert store.uri == 'mongodb://localhost/test_base'
+    assert store.collection_name == 'test_coll'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/storage/stores/mongodb.py	Wed Jul 11 01:32:16 2012 +0530
@@ -0,0 +1,100 @@
+# Copyright: 2012 Ionut Artarisi <ionut@artarisi.eu>
+# Copyright: 2012 MoinMoin:ThomasWaldmann
+# License: GNU GPL v2 (or any later version), see LICENSE.txt for details.
+
+"""
+MoinMoin - mongodb store
+
+Stores k/v pairs into a MongoDB server using pymongo.
+"""
+
+from __future__ import absolute_import, division
+
+import pymongo, gridfs
+
+from . import MutableStoreBase, BytesMutableStoreBase, FileMutableStoreBase
+
+
+class _Store(MutableStoreBase):
+    """
+    MongoDB based store.
+    """
+    @classmethod
+    def from_uri(cls, uri):
+        params = uri.split('::') # moin_uri -> mongodb_uri::collection_name
+        return cls(*params)
+
+    def __init__(self, uri='mongodb://127.0.0.1/moin_db', collection_name='moin_coll'):
+        """
+        Store params for .open().
+
+        :param uri: MongoDB server uri
+        """
+        self.uri = uri
+        self.dbname = uri.rsplit('/', 1)[-1]
+        self.collection_name = collection_name
+
+    def create(self):
+        pass
+
+    def open(self):
+        self.conn = pymongo.Connection(self.uri)
+        self.db = self.conn[self.dbname]
+        self.coll = self.db[self.collection_name]
+
+    def close(self):
+        self.conn.close()
+
+
+class BytesStore(_Store, BytesMutableStoreBase):
+    def destroy(self):
+        self.open()
+        self.db.drop_collection(self.coll)
+        self.close()
+
+    def __getitem__(self, key):
+        d = self.coll.find_one(dict(key=key))
+        if d is None:
+            raise KeyError(key)
+        return d['value']
+
+    def __setitem__(self, key, value):
+        self.coll.insert(dict(key=key, value=value))
+
+    def __delitem__(self, key):
+        self.coll.remove(dict(key=key))
+
+    def __iter__(self):
+        for result in self.coll.find(fields=['key']):
+            yield result['key']
+
+
+class FileStore(_Store, FileMutableStoreBase):
+    def open(self):
+        super(FileStore, self).open()
+        self.gridfs = gridfs.GridFS(self.db, self.collection_name)
+
+    def destroy(self):
+        self.open()
+        self.db.drop_collection(self.coll.files)
+        self.db.drop_collection(self.coll.chunks)
+        self.db.drop_collection(self.coll)
+        self.close()
+
+    def __getitem__(self, key):
+        try:
+            value = self.gridfs.get(key)
+        except gridfs.NoFile:
+            raise KeyError(key)
+        return value
+
+    def __setitem__(self, key, stream):
+        self.gridfs.delete(key)
+        self.gridfs.put(stream, _id=key)
+
+    def __delitem__(self, key):
+        self.gridfs.delete(key)
+
+    def __iter__(self):
+        for result in self.coll.files.find(fields=['_id']):
+            yield result['_id']
--- a/MoinMoin/themes/__init__.py	Wed Jul 11 01:29:00 2012 +0530
+++ b/MoinMoin/themes/__init__.py	Wed Jul 11 01:32:16 2012 +0530
@@ -40,7 +40,7 @@
     try:
         return get_theme(theme_name)
     except KeyError:
-        logging.warning("Theme {0} was not found; using default of {1} instead.".format(theme_name, app.cfg.theme_default))
+        logging.warning("Theme {0!r} was not found; using default of {1!r} instead.".format(theme_name, app.cfg.theme_default))
         theme_name = app.cfg.theme_default
         return get_theme(theme_name)
 
@@ -144,7 +144,7 @@
             aliasname = name
 
         wikiname, itemname = getInterwikiHome(name)
-        title = "{0} @ {1}".format(aliasname, wikiname)
+        title = u"{0} @ {1}".format(aliasname, wikiname)
         # link to (interwiki) user homepage
         if is_local_wiki(wikiname):
             exists = self.storage.has_item(itemname)
@@ -245,10 +245,10 @@
                                 pass # ignore invalid lines
                         f.close()
                         app.cache.set(cid, sisteritems)
-                        logging.info("Site: {0} Status: Updated. Pages: {1}".format(sistername, len(sisteritems)))
+                        logging.info("Site: {0!r} Status: Updated. Pages: {1}".format(sistername, len(sisteritems)))
                     except IOError as err:
                         (title, code, msg, headers) = err.args # code e.g. 304
-                        logging.warning("Site: {0} Status: Not updated.".format(sistername))
+                        logging.warning("Site: {0!r} Status: Not updated.".format(sistername))
                         logging.exception("exception was:")
                 if current in sisteritems:
                     url = sisteritems[current]
@@ -299,11 +299,11 @@
         # only tell ip / hostname if show_hosts is True
         if hostname:
             text = hostname[:15]  # 15 = len(ipaddr)
-            name = title = '{0}[{1}]'.format(hostname, addr)
+            name = title = u'{0}[{1}]'.format(hostname, addr)
             css = 'editor host'
         else:
             name = text = addr
-            title = '[{0}]'.format(addr)
+            title = u'[{0}]'.format(addr)
             css = 'editor ip'
 
     userid = meta.get(USERID)
@@ -316,7 +316,7 @@
             aliasname = name
         if title:
             # we already have some address info
-            title = "{0} @ {1}".format(aliasname, title)
+            title = u"{0} @ {1}".format(aliasname, title)
         else:
             title = aliasname
         if u.mailto_author and u.email:
--- a/MoinMoin/util/interwiki.py	Wed Jul 11 01:29:00 2012 +0530
+++ b/MoinMoin/util/interwiki.py	Wed Jul 11 01:32:16 2012 +0530
@@ -132,7 +132,7 @@
     :rtype: unicode
     :returns: wiki_name:item_name
     """
-    return "{0}:{1}".format(app.cfg.interwikiname, item_name)
+    return u"{0}:{1}".format(app.cfg.interwikiname, item_name)
 
 
 def getInterwikiHome(username):
--- a/setup.py	Wed Jul 11 01:29:00 2012 +0530
+++ b/setup.py	Wed Jul 11 01:32:16 2012 +0530
@@ -117,6 +117,7 @@
         'ldap': ["python-ldap>=2.0.0"], # used by ldap auth
         'openid': ["python-openid>=2.2.4"], # used by openid rp auth
         'sqla': ["sqlalchemy>=0.7.1"], # used by sqla store
+        'mongodb': ["pymongo"], # used by mongodb store
     },
     entry_points=dict(
         console_scripts=['moin = MoinMoin.script:main'],