changeset 324:5f809e691124

More page lists.
author Ludovic Chabant <ludovic@chabant.com>
date Mon, 13 Oct 2014 22:41:21 -0700
parents 8ea76932ea3a
children 8b45c5ba5d47
files wikked/assets/json/special-pagelists.json wikked/assets/json/special-sections.json wikked/views/__init__.py wikked/views/special.py
diffstat 4 files changed, 95 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/wikked/assets/json/special-pagelists.json	Sat Oct 11 22:06:41 2014 -0700
+++ b/wikked/assets/json/special-pagelists.json	Mon Oct 13 22:41:21 2014 -0700
@@ -1,12 +1,18 @@
 {
     "titles": {
         "orphans": "Orphaned Pages",
-        "broken-redirects": "Broken Redirects"
+        "broken-redirects": "Broken Redirects",
+        "double-redirects": "Double Redirects",
+        "dead-ends": "Dead-Ends"
     },
     "messages": {
         "orphans": "Here is a list of pages that don't have any pages linking to them. This means user will only be able to find them by searching for them, or by getting a direct link.",
         "broken-redirects":
-            "Here is a list of pages that redirect to a non-existing page."
+            "Here is a list of pages that redirect to a non-existing page.",
+        "double-redirects":
+            "Here is a list of pages that redirect twice or more.",
+        "dead-ends":
+            "Here is a list of pages that don't have any outgoing links."
     },
     "asides": {
         "orphans":
@@ -14,7 +20,9 @@
     },
     "empties": {
         "orphans": "No orphaned pages!",
-        "broken-redirects": "No broken redirects!"
+        "broken-redirects": "No broken redirects!",
+        "double-redirects": "No double redirects!",
+        "dead-ends": "No dead-end pages!"
     },
     "url_suffixes": {
         "broken-redirects": "?no_redirect"
--- a/wikked/assets/json/special-sections.json	Sat Oct 11 22:06:41 2014 -0700
+++ b/wikked/assets/json/special-sections.json	Mon Oct 13 22:41:21 2014 -0700
@@ -22,6 +22,16 @@
                     "title": "Broken Redirects",
                     "url": "/#/special/list/broken-redirects",
                     "description": "Lists pages that redirect to a missing page."
+                },
+                {
+                    "title": "Double Redirects",
+                    "url": "/#/special/list/double-redirects",
+                    "description": "Lists pages that redirect twice or more."
+                },
+                {
+                    "title": "Dead-End Pages",
+                    "url": "/#/special/list/dead-ends",
+                    "description": "Lists pages that don't have any outgoing links."
                 }
             ]
         },
--- a/wikked/views/__init__.py	Sat Oct 11 22:06:41 2014 -0700
+++ b/wikked/views/__init__.py	Mon Oct 13 22:41:21 2014 -0700
@@ -184,7 +184,7 @@
     wiki = get_wiki()
     build_inline = not app.config['WIKI_ASYNC_UPDATE']
     page_list = wiki.db.getPageListOrNone(list_name, fields=fields,
-                                            valid_only=build_inline)
+                                          valid_only=build_inline)
     if page_list is None and build_inline:
         app.logger.info("Regenerating list: %s" % list_name)
         page_list = builder()
@@ -193,15 +193,17 @@
     return page_list
 
 
-def get_generic_pagelist_builder(filter_func):
+def get_generic_pagelist_builder(filter_func, fields=None):
+    fields = fields or ['url', 'title', 'meta']
     def builder():
         # Make sure all pages have been resolved.
         wiki = get_wiki()
         wiki.resolve()
 
         pages = []
-        for page in wiki.getPages(no_endpoint_only=True,
-                                    fields=['url', 'title', 'meta']):
+        for page in wiki.getPages(
+                no_endpoint_only=True,
+                fields=fields):
             try:
                 if filter_func(page):
                     pages.append(page)
--- a/wikked/views/special.py	Sat Oct 11 22:06:41 2014 -0700
+++ b/wikked/views/special.py	Mon Oct 13 22:41:21 2014 -0700
@@ -7,24 +7,50 @@
 from wikked.web import app, get_wiki
 
 
-def generic_pagelist_view(list_name, filter_func):
-    pages = get_or_build_pagelist(
-            list_name,
-            get_generic_pagelist_builder(filter_func),
-            fields=['url', 'title', 'meta'])
+def build_pagelist_view_data(pages):
+    pages = sorted(pages, key=lambda p: p.url)
     data = [get_page_meta(p) for p in pages if is_page_readable(p)]
     result = {'pages': data}
     return jsonify(result)
 
 
+def generic_pagelist_view(list_name, filter_func, fields=None):
+    fields = fields or ['url', 'title', 'meta']
+    pages = get_or_build_pagelist(
+            list_name,
+            get_generic_pagelist_builder(filter_func, fields),
+            fields=fields)
+    return build_pagelist_view_data(pages)
+
+
 @app.route('/api/orphans')
 def api_special_orphans():
-    def filter_func(page):
-        for link in page.getIncomingLinks():
-            return False
-        return True
+    def builder_func():
+        wiki = get_wiki()
+        wiki.resolve()
+
+        pages = {}
+        rev_links = {}
+        for p in wiki.getPages(
+                no_endpoint_only=True,
+                fields=['url', 'title', 'meta', 'links']):
+            pages[p.url] = p
+            rev_links[p.url] = 0
 
-    return generic_pagelist_view('orphans', filter_func)
+            for l in p.links:
+                abs_l = get_absolute_url(p.url, l)
+                cnt = rev_links.get(abs_l, 0)
+                rev_links[abs_l] = cnt + 1
+
+        or_pages = []
+        for tgt, cnt in rev_links.iteritems():
+            if cnt == 0:
+                or_pages.append(pages[tgt])
+        return or_pages
+
+    fields = ['url', 'title', 'meta', 'links']
+    pages = get_or_build_pagelist('orphans', builder_func, fields)
+    return build_pagelist_view_data(pages)
 
 
 @app.route('/api/broken-redirects')
@@ -48,12 +74,43 @@
     return generic_pagelist_view('broken_redirects', filter_func)
 
 
+@app.route('/api/double-redirects')
+def api_special_double_redirects():
+    def builder_func():
+        wiki = get_wiki()
+        wiki.resolve()
+
+        pages = {}
+        redirs = {}
+        for p in wiki.getPages(
+                no_endpoint_only=True,
+                fields=['url', 'title', 'meta']):
+            pages[p.url] = p
+
+            target = p.getMeta('redirect')
+            if target:
+                target = get_absolute_url(p.url, target)
+                redirs[p.url] = target
+
+        dr_pages = []
+        for src, tgt in redirs.iteritems():
+            if tgt in redirs:
+                dr_pages.append(pages[src])
+        return dr_pages
+
+    fields = ['url', 'title', 'meta']
+    pages = get_or_build_pagelist('double_redirects', builder_func, fields)
+    return build_pagelist_view_data(pages)
+
+
 @app.route('/api/dead-ends')
 def api_special_dead_ends():
     def filter_func(page):
         return len(page.links) == 0
 
-    return generic_pagelist_view('dead_ends', filter_func)
+    return generic_pagelist_view(
+            'dead_ends', filter_func,
+            fields=['url', 'title', 'meta', 'links'])
 
 
 @app.route('/api/search')