Karima Rafes has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/75326


Change subject: Export table to CSV
......................................................................

Export table to CSV

Change-Id: I9fd6b3b1ad00a45910b7f90018b4849b8f7d278f
---
M LinkedWiki.php
A js/table2CSV.js
A test/README
A test/step_definitions/CSV_steps.rb
M test/step_definitions/sparql_steps.rb
A test/support/pages/LinkedwikiTableBasic.rb
A test/table2CSV.feature
A test/tests.sh
8 files changed, 343 insertions(+), 13 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/LinkedWiki 
refs/changes/26/75326/1

diff --git a/LinkedWiki.php b/LinkedWiki.php
index cb9a842..377e969 100644
--- a/LinkedWiki.php
+++ b/LinkedWiki.php
@@ -33,6 +33,20 @@
    'author' => array( '[http://www.mediawiki.org/wiki/User:Karima_Rafes Karima 
Rafes]' )
 );
 
+$linkedWikiTpl = array(
+       'localBasePath' => dirname( __FILE__ ) . '/js',
+       'remoteExtPath' => 'LinkedWiki/js',
+       'group' => 'ext.LinkedWiki',
+);
+
+$wgResourceModules += array(
+       /* Third-party modules */
+
+       'ext.LinkedWiki.table2CSV' => $linkedWikiTpl + array(
+               'scripts' => 'table2CSV.js',
+       ),
+);
+
 //Paths
 $wgLinkedWikiPath = dirname(__FILE__);
 $wgLinkedWikiClassesPath = $wgLinkedWikiPath . "/class";
@@ -91,6 +105,9 @@
 
 function efSparqlParserFunction_Render( $parser) {
        //global 
$wgLinkedWikiLocalEndPoint,$wgLinkedWikiEndPoint,$wgLinkedWikiGraphWiki;
+       global $wgOut;
+       $wgOut->addModules( 'ext.LinkedWiki.table2CSV' );
+       
        $args = func_get_args(); // $parser, $param1 = '', $param2 = ''
        $countArgs = count($args);
        $query = isset($args[1])? urldecode($args[1]) : "";
@@ -125,7 +142,7 @@
                        if($templates != ""){
                                return 
efSparqlParserFunction_array($query,$endpoint,$classHeaders ,$headers , 
$templates,$footer , $debug);
                        }else{
-                               return 
efSparqlParserFunction_simple($query,$endpoint,$classHeaders,$headers,$footer, 
$debug);
+                               return 
efSparqlParserFunction_simpleHTML($query,$endpoint,$classHeaders,$headers,$footer,
 $debug);
                        }
                }
        }else {
@@ -311,7 +328,7 @@
 
        return array($str, 'noparse' => false, 'isHTML' => false);
 }
-
+/*
 function efSparqlParserFunction_simple( $querySparqlWiki,$endpoint 
,$classHeaders = '',$headers = '',$footer = '', $debug = null){
        $specialC = array("'");
        $replaceC = array("'");
@@ -396,6 +413,98 @@
        }
 
        return array($str, 'noparse' => false, 'isHTML' => false);
+}*/
+
+function efSparqlParserFunction_simpleHTML( $querySparqlWiki,$endpoint 
,$classHeaders = '',$headers = '',$footer = '', $debug = null){
+       $specialC = array("'");
+       $replaceC = array("'");
+       $querySparql  = str_replace($specialC ,$replaceC , $querySparqlWiki);
+
+       $str = "";
+       $sp = new Endpoint($endpoint);
+       $rs = $sp->query($querySparqlWiki);
+       $errs = $sp->getErrors();
+       if ($errs) {
+               $strerr = "";
+               foreach ($errs as $err) {
+                       $strerr .= "'''Error #sparql :". $err ."'''<br/>";
+               }
+               return $strerr;
+       }
+
+       $lignegrise = false;
+       $variables = $rs['result']['variables'];
+       $str = "<table class='wikitable sortable'>\n";
+       if( $headers !='' ){
+               $TableTitleHeaders = explode(",",$headers);
+               $TableClassHeaders = explode(",",$classHeaders);
+               $classStr = "";
+               $lineTD = "";
+               for ($i = 0; $i < count($TableClassHeaders) ; $i++) {
+                       if(!isset($TableClassHeaders[$i]) || 
$TableClassHeaders[$i] == ""){
+                               $classStr = "";
+                       }else{
+                               $classStr =  " class=\"".$TableClassHeaders[$i] 
. "\"";
+                       }
+                       $TableTitleHeaders[$i] = "<th".$classStr.">" . 
$TableTitleHeaders[$i]."</th>";
+               }
+               $str .= "<tr>";
+               $str .= implode("\n",$TableTitleHeaders );
+               $str .= "</tr>\n";
+       }else{
+               $TableClassHeaders = explode(",",$classHeaders);
+               $classStr = "";
+               for ($i = 0; $i < count($variables) ; $i++) {
+                       if(!isset($TableClassHeaders[$i]) || 
$TableClassHeaders[$i] == "")
+                       $classStr = "";
+                       else
+                       $classStr =  " class=\"".$TableClassHeaders[$i] . "\"";
+                       $TableTitleHeaders[$i] = 
"<th".$classStr.">".$variables[$i]."</th>";
+               }
+
+               $str .= "<tr>\n";
+               $str .= implode("\n",$TableTitleHeaders );
+               $str .= "</tr>\n";
+       }
+       
+       
+       foreach ( $rs['result']['rows'] as $row) {
+       
+               $str .= "<tr";
+               if($lignegrise)
+                       $str .= " bgcolor=\"#f5f5f5\" ";                
+               $str .= ">\n";
+               $lignegrise = !$lignegrise;
+               foreach ( $variables as $variable) {
+                     $str .= "<td>";
+                     
+                       if($row[$variable." type"] == "uri" ){
+                               $str .=  
efSparqlParserFunction_uri2Link($row[$variable]) ;
+                       }else{
+                               $str .= $row[$variable] ;
+                       }
+                       $str .= "</td>\n";
+               }
+               $str .= "</tr>\n";
+       }
+
+       if($footer != "NO"){
+               $str .= "<tr style=\"font-size:80%\" align=\"right\">\n";
+               $str .= "<td colspan=\"".count($variables)."\">". 
efSparqlParserFunction_footerHTML($rs['query_time'],$querySparqlWiki,$endpoint 
,$classHeaders,$headers)."</td>\n";
+               $str .= "</tr>\n";
+       }
+       
+       $str .= "</table>\n";
+
+       if ($debug != null  &&  $debug == "YES"){
+               $str .= "INPUT WIKI : ".$querySparqlWiki."\n";
+               $str .= "Query : ".$querySparql."\n";
+               $str .= print_r($rs, true);
+               $str .= print_r($rs, true);
+               return  array("<pre>".$str."</pre>",'noparse' => true, 'isHTML' 
=> false);
+       }
+
+       return array($str, 'noparse' => false, 'isHTML' => true);
 }
 
 function efSparqlParserFunction_tableCell( $querySparqlWiki,$endpoint ,$debug 
= null){
@@ -447,10 +556,30 @@
        $today = date(wfMessage( 'linkedwiki-date' )->text());
        return $today ." -- [{{fullurl:{{FULLPAGENAME}}|action=purge}} 
".wfMessage( 'linkedwiki-refresh' )->text()."] -- ".
         wfMessage( 'linkedwiki-durate' )->text()." :".
-        round($duration, 3) ."s";
+        round($duration, 3) ."s"  ;
         //"Version : 
[{{canonicalurl:Special:Specialexportcsv}}?query={{urlencode:$querySparqlWiki}}&$endpoint={{urlencode:$querySparqlWiki}}&classHeaders={{urlencode:$querySparqlWiki}}&headers={{urlencode:$querySparqlWiki}}
 CSV] ";
 }
 
+function  
efSparqlParserFunction_footerHTML($duration,$querySparqlWiki,$endpoint 
,$classHeaders = '',$headers = ''){
+       global $wgRequest;
+       $today = date(wfMessage( 'linkedwiki-date' )->text());
+       
+       $subject = $wgRequest->getRequestURL();
+$url ="";      
+$pattern = '/\?.*(title=[^&]*).*$/';
+if(preg_match($pattern, $subject) == 1)
+  $url = preg_replace($pattern, "?\${1}&action=purge",$subject) ;
+  else
+$url = $subject . "?action=purge";
+
+       
+       //$url = preg_replace( '/(\?[^\?]*$)/i', 
"",$wgRequest->getRequestURL()) . "?action=purge";
+       //$url = $wgRequest->getRequestURL() . "?action=purge";
+       return $today ." -- <a href=\"".$url."\">".wfMessage( 
'linkedwiki-refresh' )->text()."</a> -- ".
+        wfMessage( 'linkedwiki-durate' )->text()." :".
+        round($duration, 3) ."s -- <a class=\"csv\" style=\"cursor: pointer;\" 
>CSV</a>";
+       }
+
 function  efSparqlParserFunction_uri2Link($uri,$nowiki = false){
        //TODO : $title ??? CLEAN ?
        global $wgServer;
diff --git a/js/table2CSV.js b/js/table2CSV.js
new file mode 100644
index 0000000..b520a18
--- /dev/null
+++ b/js/table2CSV.js
@@ -0,0 +1,103 @@
+jQuery.fn.table2CSV = function(options) {
+    var options = jQuery.extend({
+        separator: ',',
+        header: [],
+        delivery: 'popup' // popup, value
+    },
+    options);
+
+    var csvData = [];
+    var headerArr = [];
+    var el = this;
+
+    //header
+    var numCols = options.header.length;
+    var tmpRow = []; // construct header avalible array
+
+    if (numCols > 0) {
+        for (var i = 0; i < numCols; i++) {
+            tmpRow[tmpRow.length] = formatData(options.header[i]);
+        }
+    } else {
+        $(el).filter(':visible').find('th').each(function() {
+            if ($(this).css('display') != 'none') tmpRow[tmpRow.length] = 
formatData($(this).html());
+        });
+    }
+
+    row2CSV(tmpRow);
+
+    // actual data
+    $(el).find('tr').each(function() {
+        var tmpRow = [];
+        $(this).filter(':visible').find('td').each(function() {
+            if ($(this).css('display') != 'none') tmpRow[tmpRow.length] = 
formatData($(this).html());
+        });
+        row2CSV(tmpRow);
+    });
+    if (options.delivery == 'popup') {
+        var mydata = csvData.join('\n');
+        return popup(mydata);
+    } else {
+        var mydata = csvData.join('\n');
+        return mydata;
+    }
+
+    function row2CSV(tmpRow) {
+        var tmp = tmpRow.join('') // to remove any blank rows
+        // alert(tmp);
+        if (tmpRow.length > 0 && tmp != '') {
+            var mystr = tmpRow.join(options.separator);
+            csvData[csvData.length] = mystr;
+        }
+    }
+    function formatData(input) {
+        // replace " with “
+        var regexp = new RegExp(/["]/g);
+        var output = input.replace(regexp, "“");
+        //HTML
+        var regexp = new RegExp(/\<[^\<]+\>/g);
+        var output = output.replace(regexp, "");
+        if (output == "") return '';
+        return '"' + output + '"';
+    }
+    function popup(data) {
+        var generator = window.open('', 'csv', 'height=400,width=600');
+        generator.document.write('<html><head><title>CSV</title>');
+        generator.document.write('</head><body >');
+        generator.document.write('<textArea cols=70 rows=15 wrap="off" >');
+        generator.document.write(data);
+        generator.document.write('</textArea>');
+        generator.document.write('</body></html>');
+        generator.document.close();
+        return true;
+    }
+};
+
+$( function () {
+    // This code must not be executed before the document is loaded. 
+    
+ //$("div").css("border","9px solid purple");
+ 
+  $('table').each(function() {
+    var $table = $(this);
+    var $l = $table.find(".csv");
+    $l.click(function() {
+         var csv = $table.table2CSV({delivery:'value'});
+         window.location.href = 'data:text/csv;charset=UTF-8,'
+                               + encodeURIComponent(csv);
+           });
+    
+//$('#example1').table2CSV({
+
+//separator : ';',
+
+//delivery:'value',
+
+//header:['prefix','Employee Name','Contact']
+
+//}));
+    
+
+  });
+ 
+});
diff --git a/test/README b/test/README
new file mode 100644
index 0000000..89e1455
--- /dev/null
+++ b/test/README
@@ -0,0 +1,14 @@
+== Tests with browsertests == 
+
+You have :
+* insert the lines in browsertests/Gemfile :
+gem 'nokogiri'
+gem 'curb' 
+gem 'fastercsv'
+* execute "bundle install"   in browsertests
+* insert the lines in browsertests/features/support/env.rb :
+require 'nokogiri
+require 'curb'
+require 'fastercsv'
+* create the file browsertests/config/secret.yml and insert 
"mediawiki_password: vagrant"
+* insert the user in the wiki of tests  : Selenium user / vagrant
diff --git a/test/step_definitions/CSV_steps.rb 
b/test/step_definitions/CSV_steps.rb
new file mode 100644
index 0000000..5ba9102
--- /dev/null
+++ b/test/step_definitions/CSV_steps.rb
@@ -0,0 +1,22 @@
+When(/^I click link export CSV$/) do
+    on(LinkedwikiTableBasic).CSV
+end
+
+When(/^I click link refresh$/) do
+    on(LinkedwikiTableBasic).refresh
+end
+
+#When /^I confirm popup$/ do
+#  @browser.driver.browser.switch_to.alert.accept    
+#end
+
+#When /^I dismiss popup$/ do
+#  @browser.driver.browser.switch_to.alert.dismiss
+#end
+
+#Then(/^file CSV should be there:$/) do |table|
+  # table is a Cucumber::Ast::Table
+ # FasterCSV.foreach(@browser.html) do |row|
+ #    puts row[0]
+ # end
+#end
diff --git a/test/step_definitions/sparql_steps.rb 
b/test/step_definitions/sparql_steps.rb
index 9d304c1..64f17ad 100644
--- a/test/step_definitions/sparql_steps.rb
+++ b/test/step_definitions/sparql_steps.rb
@@ -1,14 +1,14 @@
-#When(/^I enter the wikitext:$/) do |wikiText|  
-#  on(EditPage).article_text = wikiText
-#end
+When(/^I enter the wikitext:$/) do |wikiText|  
+  on(EditPage).article_text = wikiText
+end
 
-#Then(/^table should be there:$/) do |table|
-#   nodesTR = Nokogiri::HTML(@browser.html).css(".wikitable tr")
-#   tableResult = nodesTR.map {|tr| tr.css("th,td").map {|cell| 
cell.text.strip}}
-##   p tableResult
-##   p table.raw()
-#   table.diff!(tableResult)
-#end
+Then(/^table should be there:$/) do |table|
+   nodesTR = Nokogiri::HTML(@browser.html).css(".wikitable tr")
+   tableResult = nodesTR.map {|tr| tr.css("th,td").map {|cell| 
cell.text.strip}}
+#   p tableResult
+#   p table.raw()
+   table.diff!(tableResult)
+end
 
 Given /^I has a empty graph ([^ ]*) in the triplestore ([^ ]*)$/ do 
|graph,endpoint|
   c = Curl::Easy.http_delete("#{endpoint}/data/?graph=#{graph}")
diff --git a/test/support/pages/LinkedwikiTableBasic.rb 
b/test/support/pages/LinkedwikiTableBasic.rb
new file mode 100644
index 0000000..e44f82d
--- /dev/null
+++ b/test/support/pages/LinkedwikiTableBasic.rb
@@ -0,0 +1,11 @@
+require 'page-object'
+
+class LinkedwikiTableBasic
+  include PageObject
+
+  include URL
+  page_url URL.url('<%=params[:page_name]%>')
+
+  a(:CSV, text: 'CSV')
+  a(:refresh, text: 'Refresh')
+end
diff --git a/test/table2CSV.feature b/test/table2CSV.feature
new file mode 100644
index 0000000..df87e09
--- /dev/null
+++ b/test/table2CSV.feature
@@ -0,0 +1,44 @@
+@login
+Feature: table2CSV
+  Background:
+    Given I am logged in
+      And I has a empty graph http://example.com/data in the triplestore 
http://192.168.1.100:8181
+      And I do this SPARQL query in the triplestore http://192.168.1.100:8181:
+        """
+PREFIX dc: <http://purl.org/dc/elements/1.1/>
+INSERT DATA
+{ GRAPH <http://example.com/data> {
+  <http://example/book1> dc:title "Book 1" ;
+                         dc:creator "A.N.Other1" .
+  <http://example/book2> dc:title "Book 2" ;
+                         dc:creator "A.N.Other2" .
+}}
+        """
+     
+#Check export CSV  
+Scenario: Export CSV file of LinkedWiki's table
+    Given I am at page that does not exist
+    When I click link Create source
+      And I enter the wikitext:
+        """
+{{#sparql:
+PREFIX dc: <http://purl.org/dc/elements/1.1/>
+SELECT ?title ?creator WHERE {
+GRAPH <http://example.com/data> 
+{ ?x dc:title ?title ;
+     dc:creator ?creator .
+} 
+} ORDER BY  ?title ?creator
+|endpoint=http://192.168.1.100:8181/sparql/
+}}
+        """
+      And I click Save page button
+      And I click link refresh
+      And I click link export CSV
+      And I confirm popup
+    Then file CSV should be there:
+        | title | creator |
+        | Book 1 | A.N.Other1 |
+        | Book 2 | A.N.Other2 |
+      
+      
diff --git a/test/tests.sh b/test/tests.sh
new file mode 100755
index 0000000..73ebd3d
--- /dev/null
+++ b/test/tests.sh
@@ -0,0 +1,7 @@
+export MEDIAWIKI_URL=http://127.0.0.1:8080/wiki/
+
+cp -R * ~/git/browsertests/features/
+cd ~/git/browsertests
+bundle exec cucumber -v -b ./features/sparqlbasic.feature 
+bundle exec cucumber -v -b ./features/table2CSV.feature
+cd ~/git/vagrant/mediawiki/extensions/LinkedWiki/test/
\ No newline at end of file

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I9fd6b3b1ad00a45910b7f90018b4849b8f7d278f
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/LinkedWiki
Gerrit-Branch: master
Gerrit-Owner: Karima Rafes <[email protected]>

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

Reply via email to