jenkins-bot has submitted this change and it was merged.

Change subject: Implement chronological result formatter (sort edits by date)
......................................................................


Implement chronological result formatter (sort edits by date)

* Also add a fix for T142759 (meta_p.url can be null).

* Current implementation does not leave room for CentralAuth
  and other per-wiki information (editcount, links to logs etc.)
  Except for user-page and talk-page, which are embedded in the
  results.

* Generalise styles for result content from '.wiki' to '.results' since
  the 'wiki' class wrapper doesn't exist in the by-date format.

Bug: T70358
Change-Id: Ia396ea6c1c26a8e1bf9f0e76c2a12b1346ff2e66
---
M index.php
A lb/dateresults.php
M lb/guc.php
M lb/wikicontribs.php
M resources/style.css
M settings.php
6 files changed, 168 insertions(+), 31 deletions(-)

Approvals:
  Krinkle: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/index.php b/index.php
index 5a62b64..499558f 100644
--- a/index.php
+++ b/index.php
@@ -37,10 +37,11 @@
 $data->options = array(
     'isPrefixPattern' => @$_REQUEST['isPrefixPattern'] === '1',
     'src' => @$_REQUEST['src'] ?: 'all',
+    'by' => @$_REQUEST['by'] ?: 'wiki',
 );
 
 // Create app
-$app = $guc = $error = $robotsPolicy = $canonicalUrl = null;
+$app = $guc = $appError = $robotsPolicy = $canonicalUrl = null;
 try {
     $app = new lb_app();
     if ($data->Method === 'POST') {
@@ -55,7 +56,7 @@
         $canonicalUrl = './';
     }
 } catch (Exception $e) {
-    $error = $e;
+    $appError = $e;
 }
 
 $query = $data->options;
@@ -116,13 +117,24 @@
                     $resultSelect->setName('src');
                     print $resultSelect->getHTML();
                 ?></label></p>
+                <p>Sort results:
+                <label><input name="by" type="radio" value="wiki"<?php
+                if ($data->options['by'] !== 'date') {
+                    print ' checked';
+                }
+                ?>> By wiki</label>
+                <label><input name="by" type="radio" value="date"<?php
+                if ($data->options['by'] === 'date') {
+                    print ' checked';
+                }
+                ?>> By date and time</label></p>
                 <input type="submit" value="Search" class="submitbutton" 
id="submitButton">
                 <div id="loadLine" style="display: none;">&nbsp;</div>
             </form>
             <?php
-            if ($error) {
+            if ($appError) {
                 print '<div class="error">';
-                print 'Error: ' . htmlspecialchars($error->getMessage());
+                print 'Error: ' . htmlspecialchars($appError->getMessage());
                 print '</div>';
             }
             if ($guc) {
@@ -142,25 +154,31 @@
                     if (count($hostnames) >= 10) {
                         print '<em>(Limited hostname lookups)</em>';
                     }
-                     print '</div>';
+                    print '</div>';
                 }
-                foreach ($guc->getData() as $data) {
-                    if ($data->error) {
-                        print '<div class="error">';
-                        if (isset($data->wiki->domain)) {
-                            
print'<h1>'.htmlspecialchars($data->wiki->domain).'</h1>';
-                        }
-                        print htmlspecialchars($data->error->getMessage());
-                        print '</div>';
-                    } else {
-                        if ($data->contribs->hasContribs()) {
+                if ($data->options['by'] !== 'date') {
+                    // Sort results by wiki
+                    foreach ($guc->getData() as $data) {
+                        if ($data->error) {
+                            print '<div class="error">';
+                            if (isset($data->wiki->domain)) {
+                                print 
'<h1>'.htmlspecialchars($data->wiki->domain).'</h1>';
+                            }
+                            print htmlspecialchars($data->error->getMessage());
+                            print '</div>';
+                        } elseif ($data->contribs->hasContribs()) {
                             print '<div 
class="wiki'.(($data->contribs->markAsNotUnified())?' noSul':'').'">';
                             print $data->contribs->getDataHtml();
                             print '</div>';
                         }
                     }
+                } else {
+                    // Sort results by date
+                    $formatter = new guc_ChronologyContribs($app, 
$guc->getData());
+                    $formatter->output();
                 }
                 print '</div>';
+                print '<p>Limited to ' . 
intval(lb_wikicontribs::CONTRIB_LIMIT) . ' results per wiki.</p>';
             }
             // print '<pre>';
             // $app->printTimes();
diff --git a/lb/dateresults.php b/lb/dateresults.php
new file mode 100644
index 0000000..f30f2d9
--- /dev/null
+++ b/lb/dateresults.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * Copyright 2016 by Timo Tijhof
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+class guc_ChronologyContribs {
+    private $app;
+    private $datas;
+    private $changes = array();
+    private $prevDate;
+
+    public function __construct(lb_app $app, stdClass $datas) {
+        $this->app = $app;
+        $this->datas = $datas;
+    }
+
+    public function output() {
+        foreach ($this->datas as $key => $data) {
+            if ($data->error) {
+                print '<div class="error">'
+                    . '<strong>'
+                    . htmlspecialchars($data->wiki->domain ?: 
$data->wiki->dbname)
+                    .'</strong><br/>'
+                    . htmlspecialchars($data->error->getMessage())
+                    . '</div>';
+            } else {
+                $this->add($data->wiki, $data->contribs);
+            }
+        }
+        $this->sort();
+        $inList = false;
+        foreach ($this->changes as $rc) {
+            // list($timestamp, $changeHtml) = $rc;
+            // $date = $this->app->formatMwDate($timestamp, 'd M Y');
+            $date = $this->app->formatMwDate($rc->rev_timestamp, 'd M Y');
+            if ($date !== $this->prevDate) {
+                $this->prevDate = $date;
+                if ($inList) {
+                    $inList = false;
+                    print '</ul>';
+                }
+                print $this->makeDateLine($date);
+            }
+            if (!$inList) {
+                $inList = true;
+                print "\n<ul>\n";
+            }
+            print $this->makeChangeLine($rc);
+            // print $changeHtml;
+        }
+    }
+
+    private function add(guc_Wiki $wiki, lb_wikicontribs $contribs) {
+        if ($contribs->hasContribs()) {
+            foreach ($contribs->getContribs() as $rc) {
+                $rc->guc_wiki = $wiki;
+                $this->changes[] = $rc;
+            }
+        }
+    }
+
+    private function sort() {
+        // usort($this->changes, function ($a, $b) {
+        //     if ($a[0] == $b[0]) {
+        //         return 0;
+        //     }
+        //     // DESC
+        //     return $a[0] < $b[0] ? 1 : -1;
+        // });
+        usort($this->changes, function ($a, $b) {
+            if ($a->rev_timestamp == $b->rev_timestamp) {
+                return 0;
+            }
+            // DESC
+            return $a->rev_timestamp < $b->rev_timestamp ? 1 : -1;
+        });
+    }
+
+    private function makeDateLine($date) {
+        return '<h2>' . htmlspecialchars($date) . '</h2>' . "\n";
+    }
+
+    private function makeChangeLine(stdClass $rc) {
+        $chunks = lb_wikicontribs::formatChange($this->app, $rc->guc_wiki, 
$rc);
+        return '<li>' . join('&nbsp;', $chunks) . '</li>';
+    }
+}
diff --git a/lb/guc.php b/lb/guc.php
index b357719..1a34aad 100644
--- a/lb/guc.php
+++ b/lb/guc.php
@@ -31,6 +31,7 @@
         return array(
             'isPrefixPattern' => false,
             'src' => 'all',
+            'by' => 'wiki',
             'includeClosedWikis' => false,
         );
     }
@@ -107,7 +108,6 @@
             } catch (Exception $e) {
                 $data->error = $e;
             }
-            unset($contribs);
             $datas->$dbname = $data;
         }
 
@@ -281,9 +281,14 @@
     }
 
     /**
-     * Get collected data
+     * Get collected data grouped by wiki
      *
-     * @return array
+     * Each entry will contain:
+     * - {string} wiki
+     * - {null|Exception} error
+     * - {null|lb_wikicontribs} contribs
+     *
+     * @return array[]
      */
     public function getData() {
         return $this->datas;
diff --git a/lb/wikicontribs.php b/lb/wikicontribs.php
index fc02df9..93c433c 100644
--- a/lb/wikicontribs.php
+++ b/lb/wikicontribs.php
@@ -15,6 +15,11 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+/**
+ * Represents the contributions query and results for one wiki.
+ *
+ * @class
+ */
 class lb_wikicontribs {
     const CONTRIB_LIMIT = 20;
     const MW_DATE_FORMAT = 'YmdHis';
@@ -358,8 +363,8 @@
     }
 
     public function getDataHtml() {
-        $return = '';
-        $return .= '<h1>'.$this->wiki->domain.'</h1>';
+        $html = '';
+        $html .= '<h1>'.$this->wiki->domain.'</h1>';
         $userinfo = array();
         if (!$this->options['isPrefixPattern']) {
             $userinfo[] = $this->getUserTools($this->user);
@@ -382,18 +387,19 @@
             $userinfo[] = 'SUL: Account not attached.';
         }
         if ($userinfo) {
-            $return .= '<p class="wikiinfo">' . join(' | ', $userinfo) . 
'</p>';
+            $html .= '<p class="wikiinfo">' . join(' | ', $userinfo) . '</p>';
         }
-        $return .= '<ul>';
+        $html .= '<ul>';
         foreach ($this->getContribs() as $rc) {
-            $return .= $this->formatChangeLine($rc);
+            $html .= $this->formatChangeLine($rc);
         }
-        $return .= '</ul>';
-        return $return;
+        $html .= '</ul>';
+        return $html;
     }
 
     protected function formatChangeLine($rc) {
         $chunks = self::formatChange($this->app, $this->wiki, $rc);
+        unset($chunks['wiki']);
         if (!$this->options['isPrefixPattern']) {
             unset($chunks['user']);
         }
@@ -402,6 +408,7 @@
 
     public static function formatChange(lb_app $app, guc_Wiki $wiki, stdClass 
$rc) {
         $item = array();
+
         // Diff and history
         $item[] =
             '(<a 
href="'.htmlspecialchars($wiki->getLongUrl('title='._wpurlencode($rc->guc_pagename).'&diff=prev&oldid='.urlencode($rc->rev_id))).'">diff</a>'
@@ -412,12 +419,15 @@
         // Date
         $item[] = $app->formatMwDate($rc->rev_timestamp);
 
+        // Wiki (used by guc_ChronologyContribs)
+        $item['wiki'] = '. .&nbsp;' . $wiki->domain . '&nbsp;. .';
+
         // When using isPrefixPattern, different edits may be from different 
users.
         // Show user name and basic tools for each entry.
         $item['user'] = '<a 
href="'.htmlspecialchars($wiki->getUrl("User:{$rc->rev_user_text}")).'">'
             . htmlspecialchars($rc->rev_user_text).'</a>'
             . '&nbsp;(<a 
href="'.htmlspecialchars($wiki->getUrl("User_talk:{$rc->rev_user_text}")).'">talk</a>&nbsp;|
 '
-            . '<a 
href="'.htmlspecialchars($wiki->getUrl("Special:Contributions/{$rc->rev_user_text}")).'"
 title="Special:Contributions">contribs</a>)&nbsp;. .&nbsp;';
+            . '<a 
href="'.htmlspecialchars($wiki->getUrl("Special:Contributions/{$rc->rev_user_text}")).'"
 title="Special:Contributions">contribs</a>)&nbsp;. .';
 
         // Minor edit
         if ($rc->rev_minor_edit) {
diff --git a/resources/style.css b/resources/style.css
index d7d4ec8..e624576 100644
--- a/resources/style.css
+++ b/resources/style.css
@@ -75,11 +75,15 @@
     background-repeat: no-repeat;
     padding-left: 21px;
 }
-.maincontent h1 {
+.maincontent h1,
+.maincontent h2 {
     font-size: 20px;
     font-weight: 700;
     border-bottom: 1px solid grey;
     margin-bottom: 2px;
+}
+.maincontent h2 {
+    font-size: 15px;
 }
 
 .maincontent .results .noSul {
@@ -92,16 +96,16 @@
     margin-top: 0;
 }
 
-.wiki .minor,
-.wiki .rev_cur {
+.results .minor,
+.results .rev_cur {
     font-weight: bold;
 }
 
-.comment {
+.results .comment {
     font-style: italic;;
 }
 
-.wiki .autocomment {
+.results .autocomment {
     color: #999;
 }
 
diff --git a/settings.php b/settings.php
index 25ebf03..001c57b 100644
--- a/settings.php
+++ b/settings.php
@@ -20,6 +20,7 @@
 
                     // Components
                     'components' => array(
+                        'dateresults',
                         'guc',
                         'wiki',
                         'wikicontribs',

-- 
To view, visit https://gerrit.wikimedia.org/r/323495
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ia396ea6c1c26a8e1bf9f0e76c2a12b1346ff2e66
Gerrit-PatchSet: 4
Gerrit-Project: labs/tools/guc
Gerrit-Branch: master
Gerrit-Owner: Krinkle <[email protected]>
Gerrit-Reviewer: Krinkle <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to