changeset 2103:555defa58203

merged
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Sat, 27 Apr 2013 14:45:34 +0200
parents c99479988451 (current diff) ca5e39389265 (diff)
children 979c2ee641ac
files
diffstat 14 files changed, 51 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/apps/admin/views.py	Sat Apr 27 14:41:02 2013 +0200
+++ b/MoinMoin/apps/admin/views.py	Sat Apr 27 14:45:34 2013 +0200
@@ -61,8 +61,8 @@
     """
     u = user.User(auth_username=user_name)
     if request.method == 'GET':
-        return _(u"User profile of %(username)s: %(email)r", username=user_name,
-                 email=(u.email, u.disabled))
+        return _(u"User profile of %(username)s: %(email)s %(disabled)s", username=user_name,
+                 email=u.email, disabled=u.disabled)
 
     if request.method == 'POST':
         key = request.form.get('key', '')
--- a/MoinMoin/apps/frontend/views.py	Sat Apr 27 14:41:02 2013 +0200
+++ b/MoinMoin/apps/frontend/views.py	Sat Apr 27 14:45:34 2013 +0200
@@ -57,6 +57,7 @@
 from MoinMoin.util import crypto
 from MoinMoin.util.interwiki import url_for_item
 from MoinMoin.search import SearchForm
+from MoinMoin.search.analyzers import item_name_analyzer
 from MoinMoin.security.textcha import TextCha, TextChaizedForm
 from MoinMoin.signalling import item_displayed, item_modified
 from MoinMoin.storage.middleware.protecting import AccessDenied
@@ -141,6 +142,10 @@
     submit_label = L_('Lookup')
 
 
+def analyze(analyzer, text):
+    return [token.text for token in analyzer(text, mode='index')]
+
+
 @frontend.route('/+lookup', methods=['GET', 'POST'])
 def lookup():
     """
@@ -188,27 +193,37 @@
                     term = Term(key, value)
                 terms.append(term)
         if terms:
+            LookupEntry = namedtuple('LookupEntry', 'name revid wikiname')
+            name = lookup_form[NAME].value
+            name_exact = lookup_form[NAME_EXACT].value or u''
             terms.append(Term(WIKINAME, app.cfg.interwikiname))
             q = And(terms)
             with flaskg.storage.indexer.ix[idx_name].searcher() as searcher:
                 flaskg.clock.start('lookup')
                 results = searcher.search(q, limit=100)
                 flaskg.clock.stop('lookup')
-                num_results = results.scored_length()
-                if num_results == 1:
-                    result = results[0]
-                    rev = result[REVID] if history else CURRENT
-                    url = url_for('.show_item', item_name=result[NAME], rev=rev)
+                lookup_results = []
+                for result in results:
+                    analyzer = item_name_analyzer()
+                    lookup_results += [LookupEntry(n, result[REVID], result[WIKINAME])
+                                       for n in result[NAME]
+                                       if not name or name.lower() in analyze(analyzer, n)
+                                       if n.startswith(name_exact)]
+
+                if len(lookup_results) == 1:
+                    result = lookup_results[0]
+                    rev = result.revid if history else CURRENT
+                    url = url_for('.show_item', item_name=result.name, rev=rev)
                     return redirect(url)
                 else:
                     flaskg.clock.start('lookup render')
                     html = render_template('lookup.html',
                                            title_name=title_name,
                                            lookup_form=lookup_form,
-                                           results=results,
+                                           results=lookup_results,
                     )
                     flaskg.clock.stop('lookup render')
-                    if not num_results:
+                    if not lookup_results:
                         status = 404
                     return Response(html, status)
     html = render_template('lookup.html',
@@ -1477,7 +1492,7 @@
                             for name in new_names:
                                 if user.search_users(**{NAME_EXACT: name}):
                                     # duplicate name
-                                    response['flash'].append((_("The username %(name)r is already in use.", name=name),
+                                    response['flash'].append((_("The username '%(name)s' is already in use.", name=name),
                                                               "error"))
                                     success = False
                     if part == 'notification':
--- a/MoinMoin/items/__init__.py	Sat Apr 27 14:41:02 2013 +0200
+++ b/MoinMoin/items/__init__.py	Sat Apr 27 14:45:34 2013 +0200
@@ -455,7 +455,7 @@
         """
         raise NotImplementedError
 
-    def _save(self, meta, data=None, name=None, action=u'SAVE', contenttype_guessed=None, comment=u'',
+    def _save(self, meta, data=None, name=None, action=u'SAVE', contenttype_guessed=None, comment=None,
               overwrite=False, delete=False):
         backend = flaskg.storage
         storage_item = backend[self.name]
@@ -490,7 +490,7 @@
         else:
             meta[NAME] = [name]
 
-        if comment:
+        if comment is not None:
             meta[COMMENT] = unicode(comment)
 
         if not overwrite and REVID in meta:
--- a/MoinMoin/security/__init__.py	Sat Apr 27 14:41:02 2013 +0200
+++ b/MoinMoin/security/__init__.py	Sat Apr 27 14:45:34 2013 +0200
@@ -152,7 +152,7 @@
 
             +SomeUser:read -OtherUser:write
 
-        The acl line above will grant SomeUser read right, and OtherUser
+        The acl line above will grant SomeUser read right, and deny OtherUser
         write right, but will NOT block automatically all other rights
         for these users. For example, if SomeUser asks to write, the
         above acl line does not define if he can or can not write. He
--- a/MoinMoin/storage/backends/_tests/__init__.py	Sat Apr 27 14:41:02 2013 +0200
+++ b/MoinMoin/storage/backends/_tests/__init__.py	Sat Apr 27 14:45:34 2013 +0200
@@ -62,7 +62,7 @@
         assert m == meta
         assert d.read() == data
         d.close()
-        self.be.remove(metaid)
+        self.be.remove(metaid, destroy_data=True)
         with pytest.raises(KeyError):
             self.be.retrieve(metaid)
 
--- a/MoinMoin/storage/backends/stores.py	Sat Apr 27 14:41:02 2013 +0200
+++ b/MoinMoin/storage/backends/stores.py	Sat Apr 27 14:45:34 2013 +0200
@@ -168,8 +168,9 @@
     def _del_data(self, dataid):
         del self.data_store[dataid]
 
-    def remove(self, metaid):
+    def remove(self, metaid, destroy_data):
         meta = self._get_meta(metaid)
         dataid = meta[DATAID]
         self._del_meta(metaid)
-        self._del_data(dataid)
+        if destroy_data:
+            self._del_data(dataid)
--- a/MoinMoin/storage/middleware/_tests/test_routing.py	Sat Apr 27 14:41:02 2013 +0200
+++ b/MoinMoin/storage/middleware/_tests/test_routing.py	Sat Apr 27 14:45:34 2013 +0200
@@ -63,8 +63,8 @@
     assert other_name.split(':')[1] == other_meta[NAME][0]
 
     # delete revs:
-    router.remove(default_backend_name, default_revid)
-    router.remove(other_backend_name, other_revid)
+    router.remove(default_backend_name, default_revid, destroy_data=True)
+    router.remove(other_backend_name, other_revid, destroy_data=True)
 
 
 def test_store_readonly_fails(router):
--- a/MoinMoin/storage/middleware/indexing.py	Sat Apr 27 14:41:02 2013 +0200
+++ b/MoinMoin/storage/middleware/indexing.py	Sat Apr 27 14:45:34 2013 +0200
@@ -75,7 +75,7 @@
 from MoinMoin.constants.keys import (WIKINAME, NAMESPACE, NAME, NAME_EXACT, MTIME, CONTENTTYPE, TAGS, LANGUAGE,
                                      USERID, ADDRESS, HOSTNAME, SIZE, ACTION, COMMENT, SUMMARY, CONTENT,
                                      EXTERNALLINKS, ITEMLINKS, ITEMTRANSCLUSIONS, ACL, DISABLED, EMAIL, OPENID,
-                                     ITEMID, REVID, CURRENT, PARENTID, PTIME, LATEST_REVS, ALL_REVS, BACKENDNAME)
+                                     ITEMID, REVID, CURRENT, PARENTID, PTIME, LATEST_REVS, ALL_REVS, BACKENDNAME, DATAID)
 from MoinMoin.constants.contenttypes import CONTENTTYPE_USER
 from MoinMoin.constants.namespaces import NAMESPACE_DEFAULT
 from MoinMoin.constants import keys
@@ -301,6 +301,8 @@
             COMMENT: TEXT(stored=True),
             # SUMMARY from metadata
             SUMMARY: TEXT(stored=True),
+            # DATAID from metadata
+            DATAID: ID(stored=True),
             # data (content), converted to text/plain and tokenized
             CONTENT: TEXT(stored=True),
         }
@@ -1111,7 +1113,10 @@
         Destroy revision <revid>.
         """
         rev = Revision(self, revid)
-        self.backend.remove(rev.backend_name, revid)
+        query = {DATAID: rev.meta[DATAID]}
+        with flaskg.storage.indexer.ix[ALL_REVS].searcher() as searcher:
+            refcount = len(list(searcher.document_numbers(**query)))
+        self.backend.remove(rev.backend_name, revid, destroy_data=refcount == 1)
         self.indexer.remove_revision(revid)
 
     def destroy_all_revisions(self):
--- a/MoinMoin/storage/middleware/routing.py	Sat Apr 27 14:41:02 2013 +0200
+++ b/MoinMoin/storage/middleware/routing.py	Sat Apr 27 14:45:34 2013 +0200
@@ -132,8 +132,8 @@
         meta[BACKENDNAME] = backend_name
         return backend_name, revid
 
-    def remove(self, backend_name, revid):
+    def remove(self, backend_name, revid, destroy_data):
         backend = self.backends[backend_name]
         if not isinstance(backend, MutableBackendBase):
             raise TypeError('backend {0} is readonly'.format(backend_name))
-        backend.remove(revid)
+        backend.remove(revid, destroy_data)
--- a/MoinMoin/templates/destroy.html	Sat Apr 27 14:41:02 2013 +0200
+++ b/MoinMoin/templates/destroy.html	Sat Apr 27 14:45:34 2013 +0200
@@ -17,7 +17,7 @@
     {{ gen.form.close() }}
     </div>
 {% else %}
-    <h1>{{ _("DESTROY REVISION '%(item_name)s' (rev %(rev_id)s)", item_name=item.name, rev_id=rev_id) }}</h1>
+    <h1>{{ _("DESTROY REVISION '%(item_name)s' (rev %(rev_id)s)", item_name=item.name, rev_id=rev_id | shorten_id) }}</h1>
     <div class="moin-form">
     {{ gen.form.open(form, method="post", action=url_for('frontend.destroy_item', item_name=item.name, rev=rev_id)) }}
       {{ forms.render_errors(form) }}
--- a/MoinMoin/templates/lookup.html	Sat Apr 27 14:41:02 2013 +0200
+++ b/MoinMoin/templates/lookup.html	Sat Apr 27 14:45:34 2013 +0200
@@ -35,14 +35,14 @@
             {% for result in results %}
                 {% if result['wikiname'] == cfg.interwikiname %}
                     <tr>
-                        <td class="moin-wordbreak">{{ result.pos + 1 }}
-                        <a href="{{ url_for_item(item_name=result['name'], wiki_name='Self', rev=result['revid']) }}"><b>{{ result['name'] }}</b></a>
+                        <td class="moin-wordbreak">{{ loop.index }}
+                        <a href="{{ url_for_item(item_name=result.name, wiki_name='Self', rev=result.revid) }}"><b>{{ result.name }}</b></a>
                         </td>
                     </tr>
                 {% else %}
                     <tr>
-                        <td class="moin-wordbreak">{{ result.pos + 1 }}
-                        <a class="moin-interwiki" href="{{ url_for_item(item_name=result['name'], wiki_name=result['wikiname'], rev=result['revid']) }}"><b>{{ "%s:%s" % (result['wikiname'], result['name']) }}</b></a>
+                        <td class="moin-wordbreak">{{ loop.index }}
+                        <a class="moin-interwiki" href="{{ url_for_item(item_name=result.name, wiki_name=result.wikiname, rev=result.revid) }}"><b>{{ "%s:%s" % (result.wikiname, result.name) }}</b></a>
                         </td>
                     </tr>
                 {% endif %}
--- a/MoinMoin/templates/meta.html	Sat Apr 27 14:41:02 2013 +0200
+++ b/MoinMoin/templates/meta.html	Sat Apr 27 14:45:34 2013 +0200
@@ -9,7 +9,7 @@
 {% block content_data %}
 <h1>
     {{ title }}
-    {% if show_revision %}({{ _("Revision") }} {{ rev.revid }}){% endif %}
+    {% if show_revision %}({{ _("Revision") }} {{ rev.revid | shorten_id }}){% endif %}
 </h1>
 {% if meta_rendered %}
 <div id="moin-content-meta">
--- a/MoinMoin/templates/revert.html	Sat Apr 27 14:41:02 2013 +0200
+++ b/MoinMoin/templates/revert.html	Sat Apr 27 14:45:34 2013 +0200
@@ -1,7 +1,7 @@
 {% import "forms.html" as forms %}
 {% extends theme("layout.html") %}
 {% block content %}
-<h1>{{ _("Revert '%(item_name)s' (rev %(rev_id)s)", item_name=item.name, rev_id=rev_id) }}</h1>
+<h1>{{ _("Revert '%(item_name)s' (rev %(rev_id)s)", item_name=item.name, rev_id=rev_id | shorten_id) }}</h1>
 <div class="moin-form">
 {{ gen.form.open(form, method="post", action=url_for('frontend.revert_item', item_name=item.name, rev=rev_id)) }}
   {{ forms.render_errors(form) }}
--- a/MoinMoin/templates/search.html	Sat Apr 27 14:41:02 2013 +0200
+++ b/MoinMoin/templates/search.html	Sat Apr 27 14:45:34 2013 +0200
@@ -56,7 +56,7 @@
                             {% endif %}
                             <tr>
                                 <td>
-                                    <p class="info searchhitinfobar">{{ _("Revision: %(revid)s Last Change: %(mtime)s", revid=result['revid'], mtime=result['mtime']|datetimeformat) }}</p>
+                                    <p class="info searchhitinfobar">{{ _("Revision: %(revid)s Last Change: %(mtime)s", revid=result['revid']|shorten_id, mtime=result['mtime']|datetimeformat) }}</p>
                                 </td>
                             </tr>
                             <tr>